clang API Documentation
00001 //===--- VTTBuilder.h - C++ VTT layout builder --------------------*- C++ -*-=// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This contains code dealing with generation of the layout of virtual table 00011 // tables (VTT). 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_CLANG_AST_VTTBUILDER_H 00016 #define LLVM_CLANG_AST_VTTBUILDER_H 00017 00018 #include "clang/AST/BaseSubobject.h" 00019 #include "clang/AST/CXXInheritance.h" 00020 #include "clang/AST/GlobalDecl.h" 00021 #include "clang/AST/RecordLayout.h" 00022 #include "clang/Basic/ABI.h" 00023 #include "llvm/ADT/SetVector.h" 00024 #include <utility> 00025 00026 namespace clang { 00027 00028 class VTTVTable { 00029 llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> BaseAndIsVirtual; 00030 CharUnits BaseOffset; 00031 00032 public: 00033 VTTVTable() {} 00034 VTTVTable(const CXXRecordDecl *Base, CharUnits BaseOffset, bool BaseIsVirtual) 00035 : BaseAndIsVirtual(Base, BaseIsVirtual), BaseOffset(BaseOffset) {} 00036 VTTVTable(BaseSubobject Base, bool BaseIsVirtual) 00037 : BaseAndIsVirtual(Base.getBase(), BaseIsVirtual), 00038 BaseOffset(Base.getBaseOffset()) {} 00039 00040 const CXXRecordDecl *getBase() const { 00041 return BaseAndIsVirtual.getPointer(); 00042 } 00043 00044 CharUnits getBaseOffset() const { 00045 return BaseOffset; 00046 } 00047 00048 bool isVirtual() const { 00049 return BaseAndIsVirtual.getInt(); 00050 } 00051 00052 BaseSubobject getBaseSubobject() const { 00053 return BaseSubobject(getBase(), getBaseOffset()); 00054 } 00055 }; 00056 00057 struct VTTComponent { 00058 uint64_t VTableIndex; 00059 BaseSubobject VTableBase; 00060 00061 VTTComponent() {} 00062 VTTComponent(uint64_t VTableIndex, BaseSubobject VTableBase) 00063 : VTableIndex(VTableIndex), VTableBase(VTableBase) {} 00064 }; 00065 00066 /// \brief Class for building VTT layout information. 00067 class VTTBuilder { 00068 00069 ASTContext &Ctx; 00070 00071 /// \brief The most derived class for which we're building this vtable. 00072 const CXXRecordDecl *MostDerivedClass; 00073 00074 typedef SmallVector<VTTVTable, 64> VTTVTablesVectorTy; 00075 00076 /// \brief The VTT vtables. 00077 VTTVTablesVectorTy VTTVTables; 00078 00079 typedef SmallVector<VTTComponent, 64> VTTComponentsVectorTy; 00080 00081 /// \brief The VTT components. 00082 VTTComponentsVectorTy VTTComponents; 00083 00084 /// \brief The AST record layout of the most derived class. 00085 const ASTRecordLayout &MostDerivedClassLayout; 00086 00087 typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy; 00088 00089 typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy; 00090 00091 /// \brief The sub-VTT indices for the bases of the most derived class. 00092 llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndicies; 00093 00094 /// \brief The secondary virtual pointer indices of all subobjects of 00095 /// the most derived class. 00096 llvm::DenseMap<BaseSubobject, uint64_t> SecondaryVirtualPointerIndices; 00097 00098 /// \brief Whether the VTT builder should generate LLVM IR for the VTT. 00099 bool GenerateDefinition; 00100 00101 /// \brief Add a vtable pointer to the VTT currently being built. 00102 void AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex, 00103 const CXXRecordDecl *VTableClass); 00104 00105 /// \brief Lay out the secondary VTTs of the given base subobject. 00106 void LayoutSecondaryVTTs(BaseSubobject Base); 00107 00108 /// \brief Lay out the secondary virtual pointers for the given base 00109 /// subobject. 00110 /// 00111 /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base 00112 /// or a direct or indirect base of a virtual base. 00113 void LayoutSecondaryVirtualPointers(BaseSubobject Base, 00114 bool BaseIsMorallyVirtual, 00115 uint64_t VTableIndex, 00116 const CXXRecordDecl *VTableClass, 00117 VisitedVirtualBasesSetTy &VBases); 00118 00119 /// \brief Lay out the secondary virtual pointers for the given base 00120 /// subobject. 00121 void LayoutSecondaryVirtualPointers(BaseSubobject Base, 00122 uint64_t VTableIndex); 00123 00124 /// \brief Lay out the VTTs for the virtual base classes of the given 00125 /// record declaration. 00126 void LayoutVirtualVTTs(const CXXRecordDecl *RD, 00127 VisitedVirtualBasesSetTy &VBases); 00128 00129 /// \brief Lay out the VTT for the given subobject, including any 00130 /// secondary VTTs, secondary virtual pointers and virtual VTTs. 00131 void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual); 00132 00133 public: 00134 VTTBuilder(ASTContext &Ctx, const CXXRecordDecl *MostDerivedClass, 00135 bool GenerateDefinition); 00136 00137 // \brief Returns a reference to the VTT components. 00138 const VTTComponentsVectorTy &getVTTComponents() const { 00139 return VTTComponents; 00140 } 00141 00142 // \brief Returns a reference to the VTT vtables. 00143 const VTTVTablesVectorTy &getVTTVTables() const { 00144 return VTTVTables; 00145 } 00146 00147 /// \brief Returns a reference to the sub-VTT indices. 00148 const llvm::DenseMap<BaseSubobject, uint64_t> &getSubVTTIndicies() const { 00149 return SubVTTIndicies; 00150 } 00151 00152 /// \brief Returns a reference to the secondary virtual pointer indices. 00153 const llvm::DenseMap<BaseSubobject, uint64_t> & 00154 getSecondaryVirtualPointerIndices() const { 00155 return SecondaryVirtualPointerIndices; 00156 } 00157 00158 }; 00159 00160 } 00161 00162 #endif