reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
//===- VTTBuilder.h - C++ VTT layout builder --------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This contains code dealing with generation of the layout of virtual table
// tables (VTT).
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_VTTBUILDER_H
#define LLVM_CLANG_AST_VTTBUILDER_H

#include "clang/AST/BaseSubobject.h"
#include "clang/AST/CharUnits.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include <cstdint>

namespace clang {

class ASTContext;
class ASTRecordLayout;
class CXXRecordDecl;

class VTTVTable {
  llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> BaseAndIsVirtual;
  CharUnits BaseOffset;

public:
  VTTVTable() = default;
  VTTVTable(const CXXRecordDecl *Base, CharUnits BaseOffset, bool BaseIsVirtual)
      : BaseAndIsVirtual(Base, BaseIsVirtual), BaseOffset(BaseOffset) {}
  VTTVTable(BaseSubobject Base, bool BaseIsVirtual)
      : BaseAndIsVirtual(Base.getBase(), BaseIsVirtual),
        BaseOffset(Base.getBaseOffset()) {}

  const CXXRecordDecl *getBase() const {
    return BaseAndIsVirtual.getPointer();
  }

  CharUnits getBaseOffset() const {
    return BaseOffset;
  }

  bool isVirtual() const {
    return BaseAndIsVirtual.getInt();
  }

  BaseSubobject getBaseSubobject() const {
    return BaseSubobject(getBase(), getBaseOffset());
  }
};

struct VTTComponent {
  uint64_t VTableIndex;
  BaseSubobject VTableBase;

  VTTComponent() = default;
  VTTComponent(uint64_t VTableIndex, BaseSubobject VTableBase)
     : VTableIndex(VTableIndex), VTableBase(VTableBase) {}
};

/// Class for building VTT layout information.
class VTTBuilder {
  ASTContext &Ctx;

  /// The most derived class for which we're building this vtable.
  const CXXRecordDecl *MostDerivedClass;

  using VTTVTablesVectorTy = SmallVector<VTTVTable, 64>;

  /// The VTT vtables.
  VTTVTablesVectorTy VTTVTables;

  using VTTComponentsVectorTy = SmallVector<VTTComponent, 64>;

  /// The VTT components.
  VTTComponentsVectorTy VTTComponents;

  /// The AST record layout of the most derived class.
  const ASTRecordLayout &MostDerivedClassLayout;

  using VisitedVirtualBasesSetTy = llvm::SmallPtrSet<const CXXRecordDecl *, 4>;

  using AddressPointsMapTy = llvm::DenseMap<BaseSubobject, uint64_t>;

  /// The sub-VTT indices for the bases of the most derived class.
  llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndicies;

  /// The secondary virtual pointer indices of all subobjects of
  /// the most derived class.
  llvm::DenseMap<BaseSubobject, uint64_t> SecondaryVirtualPointerIndices;

  /// Whether the VTT builder should generate LLVM IR for the VTT.
  bool GenerateDefinition;

  /// Add a vtable pointer to the VTT currently being built.
  void AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex,
                        const CXXRecordDecl *VTableClass);

  /// Lay out the secondary VTTs of the given base subobject.
  void LayoutSecondaryVTTs(BaseSubobject Base);

  /// Lay out the secondary virtual pointers for the given base
  /// subobject.
  ///
  /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
  /// or a direct or indirect base of a virtual base.
  void LayoutSecondaryVirtualPointers(BaseSubobject Base,
                                      bool BaseIsMorallyVirtual,
                                      uint64_t VTableIndex,
                                      const CXXRecordDecl *VTableClass,
                                      VisitedVirtualBasesSetTy &VBases);

  /// Lay out the secondary virtual pointers for the given base
  /// subobject.
  void LayoutSecondaryVirtualPointers(BaseSubobject Base,
                                      uint64_t VTableIndex);

  /// Lay out the VTTs for the virtual base classes of the given
  /// record declaration.
  void LayoutVirtualVTTs(const CXXRecordDecl *RD,
                         VisitedVirtualBasesSetTy &VBases);

  /// Lay out the VTT for the given subobject, including any
  /// secondary VTTs, secondary virtual pointers and virtual VTTs.
  void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual);

public:
  VTTBuilder(ASTContext &Ctx, const CXXRecordDecl *MostDerivedClass,
             bool GenerateDefinition);

  // Returns a reference to the VTT components.
  const VTTComponentsVectorTy &getVTTComponents() const {
    return VTTComponents;
  }

  // Returns a reference to the VTT vtables.
  const VTTVTablesVectorTy &getVTTVTables() const {
    return VTTVTables;
  }

  /// Returns a reference to the sub-VTT indices.
  const llvm::DenseMap<BaseSubobject, uint64_t> &getSubVTTIndicies() const {
    return SubVTTIndicies;
  }

  /// Returns a reference to the secondary virtual pointer indices.
  const llvm::DenseMap<BaseSubobject, uint64_t> &
  getSecondaryVirtualPointerIndices() const {
    return SecondaryVirtualPointerIndices;
  }
};

} // namespace clang

#endif // LLVM_CLANG_AST_VTTBUILDER_H