summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CGVtable.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGVtable.h')
-rw-r--r--lib/CodeGen/CGVtable.h110
1 files changed, 104 insertions, 6 deletions
diff --git a/lib/CodeGen/CGVtable.h b/lib/CodeGen/CGVtable.h
index eed5b64..471d638 100644
--- a/lib/CodeGen/CGVtable.h
+++ b/lib/CodeGen/CGVtable.h
@@ -61,11 +61,83 @@ public:
ThunkAdjustment ReturnAdjustment;
};
+// BaseSubobject - Uniquely identifies a direct or indirect base class.
+// Stores both the base class decl and the offset from the most derived class to
+// the base class.
+class BaseSubobject {
+ /// Base - The base class declaration.
+ const CXXRecordDecl *Base;
+
+ /// BaseOffset - The offset from the most derived class to the base class.
+ uint64_t BaseOffset;
+
+public:
+ BaseSubobject(const CXXRecordDecl *Base, uint64_t BaseOffset)
+ : Base(Base), BaseOffset(BaseOffset) { }
+
+ /// getBase - Returns the base class declaration.
+ const CXXRecordDecl *getBase() const { return Base; }
+
+ /// getBaseOffset - Returns the base class offset.
+ uint64_t getBaseOffset() const { return BaseOffset; }
+
+ friend bool operator==(const BaseSubobject &LHS, const BaseSubobject &RHS) {
+ return LHS.Base == RHS.Base && LHS.BaseOffset == RHS.BaseOffset;
+ }
+};
+
+} // end namespace CodeGen
+} // end namespace clang
+
+namespace llvm {
+
+template<> struct DenseMapInfo<clang::CodeGen::BaseSubobject> {
+ static clang::CodeGen::BaseSubobject getEmptyKey() {
+ return clang::CodeGen::BaseSubobject(
+ DenseMapInfo<const clang::CXXRecordDecl *>::getEmptyKey(),
+ DenseMapInfo<uint64_t>::getEmptyKey());
+ }
+
+ static clang::CodeGen::BaseSubobject getTombstoneKey() {
+ return clang::CodeGen::BaseSubobject(
+ DenseMapInfo<const clang::CXXRecordDecl *>::getTombstoneKey(),
+ DenseMapInfo<uint64_t>::getTombstoneKey());
+ }
+
+ static unsigned getHashValue(const clang::CodeGen::BaseSubobject &Base) {
+ return
+ DenseMapInfo<const clang::CXXRecordDecl *>::getHashValue(Base.getBase()) ^
+ DenseMapInfo<uint64_t>::getHashValue(Base.getBaseOffset());
+ }
+
+ static bool isEqual(const clang::CodeGen::BaseSubobject &LHS,
+ const clang::CodeGen::BaseSubobject &RHS) {
+ return LHS == RHS;
+ }
+};
+
+// It's OK to treat BaseSubobject as a POD type.
+template <> struct isPodLike<clang::CodeGen::BaseSubobject> {
+ static const bool value = true;
+};
+
+}
+
+namespace clang {
+namespace CodeGen {
+
class CGVtableInfo {
public:
typedef std::vector<std::pair<GlobalDecl, ThunkAdjustment> >
AdjustmentVectorTy;
+ typedef std::pair<const CXXRecordDecl *, uint64_t> CtorVtable_t;
+ typedef llvm::DenseMap<CtorVtable_t, int64_t> AddrSubMap_t;
+ typedef llvm::DenseMap<const CXXRecordDecl *, AddrSubMap_t *> AddrMap_t;
+ llvm::DenseMap<const CXXRecordDecl *, AddrMap_t*> AddressPoints;
+
+ typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
+
private:
CodeGenModule &CGM;
@@ -93,6 +165,9 @@ private:
SavedAdjustmentsTy SavedAdjustments;
llvm::DenseSet<const CXXRecordDecl*> SavedAdjustmentRecords;
+ typedef llvm::DenseMap<ClassPairTy, uint64_t> SubVTTIndiciesTy;
+ SubVTTIndiciesTy SubVTTIndicies;
+
/// getNumVirtualFunctionPointers - Return the number of virtual function
/// pointers in the vtable for a given record decl.
uint64_t getNumVirtualFunctionPointers(const CXXRecordDecl *RD);
@@ -110,15 +185,26 @@ private:
llvm::GlobalVariable *
GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage,
bool GenerateDefinition, const CXXRecordDecl *LayoutClass,
- const CXXRecordDecl *RD, uint64_t Offset);
+ const CXXRecordDecl *RD, uint64_t Offset,
+ AddressPointsMapTy& AddressPoints);
llvm::GlobalVariable *GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
+ bool GenerateDefinition,
const CXXRecordDecl *RD);
public:
CGVtableInfo(CodeGenModule &CGM)
: CGM(CGM) { }
+ /// needsVTTParameter - Return whether the given global decl needs a VTT
+ /// parameter, which it does if it's a base constructor or destructor with
+ /// virtual bases.
+ static bool needsVTTParameter(GlobalDecl GD);
+
+ /// getSubVTTIndex - Return the index of the sub-VTT for the base class of the
+ /// given record decl.
+ uint64_t getSubVTTIndex(const CXXRecordDecl *RD, const CXXRecordDecl *Base);
+
/// getMethodVtableIndex - Return the index (relative to the vtable address
/// point) where the function pointer for the given virtual function is
/// stored.
@@ -140,14 +226,26 @@ public:
uint64_t getVtableAddressPoint(const CXXRecordDecl *RD);
llvm::GlobalVariable *getVtable(const CXXRecordDecl *RD);
- llvm::GlobalVariable *getCtorVtable(const CXXRecordDecl *RD,
- const CXXRecordDecl *Class,
- uint64_t Offset);
+ /// CtorVtableInfo - Information about a constructor vtable.
+ struct CtorVtableInfo {
+ /// Vtable - The vtable itself.
+ llvm::GlobalVariable *Vtable;
+
+ /// AddressPoints - The address points in this constructor vtable.
+ AddressPointsMapTy AddressPoints;
+
+ CtorVtableInfo() : Vtable(0) { }
+ };
+
+ CtorVtableInfo getCtorVtable(const CXXRecordDecl *RD,
+ const BaseSubobject &Base);
+
+ llvm::GlobalVariable *getVTT(const CXXRecordDecl *RD);
void MaybeEmitVtable(GlobalDecl GD);
};
-}
-}
+} // end namespace CodeGen
+} // end namespace clang
#endif
OpenPOWER on IntegriCloud