1//===--- VTTBuilder.h - C++ VTT layout builder --------------------*- C++ -*-=// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This contains code dealing with generation of the layout of virtual table 11// tables (VTT). 12// 13//===----------------------------------------------------------------------===// 14 15#ifndef LLVM_CLANG_AST_VTTBUILDER_H 16#define LLVM_CLANG_AST_VTTBUILDER_H 17 18#include "clang/AST/BaseSubobject.h" 19#include "clang/AST/CXXInheritance.h" 20#include "clang/AST/GlobalDecl.h" 21#include "clang/AST/RecordLayout.h" 22#include "clang/Basic/ABI.h" 23#include <utility> 24 25namespace clang { 26 27class VTTVTable { 28 llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> BaseAndIsVirtual; 29 CharUnits BaseOffset; 30 31public: 32 VTTVTable() {} 33 VTTVTable(const CXXRecordDecl *Base, CharUnits BaseOffset, bool BaseIsVirtual) 34 : BaseAndIsVirtual(Base, BaseIsVirtual), BaseOffset(BaseOffset) {} 35 VTTVTable(BaseSubobject Base, bool BaseIsVirtual) 36 : BaseAndIsVirtual(Base.getBase(), BaseIsVirtual), 37 BaseOffset(Base.getBaseOffset()) {} 38 39 const CXXRecordDecl *getBase() const { 40 return BaseAndIsVirtual.getPointer(); 41 } 42 43 CharUnits getBaseOffset() const { 44 return BaseOffset; 45 } 46 47 bool isVirtual() const { 48 return BaseAndIsVirtual.getInt(); 49 } 50 51 BaseSubobject getBaseSubobject() const { 52 return BaseSubobject(getBase(), getBaseOffset()); 53 } 54}; 55 56struct VTTComponent { 57 uint64_t VTableIndex; 58 BaseSubobject VTableBase; 59 60 VTTComponent() {} 61 VTTComponent(uint64_t VTableIndex, BaseSubobject VTableBase) 62 : VTableIndex(VTableIndex), VTableBase(VTableBase) {} 63}; 64 65/// \brief Class for building VTT layout information. 66class VTTBuilder { 67 68 ASTContext &Ctx; 69 70 /// \brief The most derived class for which we're building this vtable. 71 const CXXRecordDecl *MostDerivedClass; 72 73 typedef SmallVector<VTTVTable, 64> VTTVTablesVectorTy; 74 75 /// \brief The VTT vtables. 76 VTTVTablesVectorTy VTTVTables; 77 78 typedef SmallVector<VTTComponent, 64> VTTComponentsVectorTy; 79 80 /// \brief The VTT components. 81 VTTComponentsVectorTy VTTComponents; 82 83 /// \brief The AST record layout of the most derived class. 84 const ASTRecordLayout &MostDerivedClassLayout; 85 86 typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy; 87 88 typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy; 89 90 /// \brief The sub-VTT indices for the bases of the most derived class. 91 llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndicies; 92 93 /// \brief The secondary virtual pointer indices of all subobjects of 94 /// the most derived class. 95 llvm::DenseMap<BaseSubobject, uint64_t> SecondaryVirtualPointerIndices; 96 97 /// \brief Whether the VTT builder should generate LLVM IR for the VTT. 98 bool GenerateDefinition; 99 100 /// \brief Add a vtable pointer to the VTT currently being built. 101 void AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex, 102 const CXXRecordDecl *VTableClass); 103 104 /// \brief Lay out the secondary VTTs of the given base subobject. 105 void LayoutSecondaryVTTs(BaseSubobject Base); 106 107 /// \brief Lay out the secondary virtual pointers for the given base 108 /// subobject. 109 /// 110 /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base 111 /// or a direct or indirect base of a virtual base. 112 void LayoutSecondaryVirtualPointers(BaseSubobject Base, 113 bool BaseIsMorallyVirtual, 114 uint64_t VTableIndex, 115 const CXXRecordDecl *VTableClass, 116 VisitedVirtualBasesSetTy &VBases); 117 118 /// \brief Lay out the secondary virtual pointers for the given base 119 /// subobject. 120 void LayoutSecondaryVirtualPointers(BaseSubobject Base, 121 uint64_t VTableIndex); 122 123 /// \brief Lay out the VTTs for the virtual base classes of the given 124 /// record declaration. 125 void LayoutVirtualVTTs(const CXXRecordDecl *RD, 126 VisitedVirtualBasesSetTy &VBases); 127 128 /// \brief Lay out the VTT for the given subobject, including any 129 /// secondary VTTs, secondary virtual pointers and virtual VTTs. 130 void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual); 131 132public: 133 VTTBuilder(ASTContext &Ctx, const CXXRecordDecl *MostDerivedClass, 134 bool GenerateDefinition); 135 136 // \brief Returns a reference to the VTT components. 137 const VTTComponentsVectorTy &getVTTComponents() const { 138 return VTTComponents; 139 } 140 141 // \brief Returns a reference to the VTT vtables. 142 const VTTVTablesVectorTy &getVTTVTables() const { 143 return VTTVTables; 144 } 145 146 /// \brief Returns a reference to the sub-VTT indices. 147 const llvm::DenseMap<BaseSubobject, uint64_t> &getSubVTTIndicies() const { 148 return SubVTTIndicies; 149 } 150 151 /// \brief Returns a reference to the secondary virtual pointer indices. 152 const llvm::DenseMap<BaseSubobject, uint64_t> & 153 getSecondaryVirtualPointerIndices() const { 154 return SecondaryVirtualPointerIndices; 155 } 156 157}; 158 159} 160 161#endif 162