clang API Documentation

VTTBuilder.h
Go to the documentation of this file.
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