More vtable work; preparations for moving over to the new vtable layout code (finally).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99381 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp
index 4d5fdfe..af84632 100644
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
@@ -1560,9 +1560,10 @@
if (!ClassDecl->isDynamicClass())
return;
- llvm::Constant *VTable = CGM.getVTables().getVtable(ClassDecl);
- CodeGenVTables::AddrSubMap_t& AddressPoints =
- *(*CGM.getVTables().AddressPoints[ClassDecl])[ClassDecl];
+ llvm::Constant *VTable = CGM.getVTables().getAddrOfVTable(ClassDecl);
+ const CodeGenVTables::AddrSubMap_t& AddressPoints =
+ CGM.getVTables().getAddressPoints(ClassDecl);
+
llvm::Value *ThisPtr = LoadCXXThis();
const ASTRecordLayout &Layout = getContext().getASTRecordLayout(ClassDecl);
@@ -1584,7 +1585,7 @@
void CodeGenFunction::InitializeVtablePtrsRecursive(
const CXXRecordDecl *ClassDecl,
llvm::Constant *Vtable,
- CodeGenVTables::AddrSubMap_t& AddressPoints,
+ const CodeGenVTables::AddrSubMap_t& AddressPoints,
llvm::Value *ThisPtr,
uint64_t Offset) {
if (!ClassDecl->isDynamicClass())
@@ -1607,7 +1608,8 @@
// Compute the address point
assert(AddressPoints.count(std::make_pair(ClassDecl, Offset)) &&
"Missing address point for class");
- uint64_t AddressPoint = AddressPoints[std::make_pair(ClassDecl, Offset)];
+ uint64_t AddressPoint =
+ AddressPoints.lookup(std::make_pair(ClassDecl, Offset));
llvm::Value *VtableAddressPoint =
Builder.CreateConstInBoundsGEP2_64(Vtable, 0, AddressPoint);
diff --git a/lib/CodeGen/CGVTT.cpp b/lib/CodeGen/CGVTT.cpp
index 990a5f6..b7b24b8 100644
--- a/lib/CodeGen/CGVTT.cpp
+++ b/lib/CodeGen/CGVTT.cpp
@@ -268,7 +268,7 @@
GenerateDefinition(GenerateDefinition) {
// First comes the primary virtual table pointer for the complete class...
- ClassVtbl = GenerateDefinition ? CGM.getVTables().getVtable(Class) : 0;
+ ClassVtbl = GenerateDefinition ? CGM.getVTables().getAddrOfVTable(Class) :0;
llvm::Constant *Init = BuildVtablePtr(ClassVtbl, Class, Class, 0);
Inits.push_back(Init);
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp
index f492169..c9b099b 100644
--- a/lib/CodeGen/CGVtable.cpp
+++ b/lib/CodeGen/CGVtable.cpp
@@ -3551,6 +3551,19 @@
return I->second;
}
+const CodeGenVTables::AddrSubMap_t &
+CodeGenVTables::getAddressPoints(const CXXRecordDecl *RD) {
+ if (!AddressPoints[RD]) {
+ AddressPointsMapTy AddressPoints;
+ OldVtableBuilder b(RD, RD, 0, CGM, false, AddressPoints);
+
+ b.GenerateVtableForBase(RD, 0);
+ b.GenerateVtableForVBases(RD, 0);
+ }
+
+ return *(*AddressPoints[RD])[RD];
+}
+
llvm::GlobalVariable *
CodeGenVTables::GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage,
bool GenerateDefinition,
@@ -3583,8 +3596,7 @@
llvm::StringRef Name = OutName.str();
llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
- if (GV == 0 || CGM.getVTables().AddressPoints[LayoutClass] == 0 ||
- GV->isDeclaration()) {
+ if (GV == 0 || GV->isDeclaration()) {
OldVtableBuilder b(RD, LayoutClass, Offset, CGM, GenerateDefinition,
AddressPoints);
@@ -3906,17 +3918,26 @@
GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD);
}
-llvm::GlobalVariable *CodeGenVTables::getVtable(const CXXRecordDecl *RD) {
- llvm::GlobalVariable *Vtable = Vtables.lookup(RD);
-
- if (!Vtable) {
- AddressPointsMapTy AddressPoints;
- Vtable = GenerateVtable(llvm::GlobalValue::ExternalLinkage,
- /*GenerateDefinition=*/false, RD, RD, 0,
- /*IsVirtual=*/false, AddressPoints);
- }
+llvm::Constant *CodeGenVTables::getAddrOfVTable(const CXXRecordDecl *RD) {
+ llvm::SmallString<256> OutName;
+ CGM.getMangleContext().mangleCXXVtable(RD, OutName);
+ llvm::StringRef Name = OutName.str();
- return Vtable;
+ const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
+ llvm::ArrayType *ArrayType = llvm::ArrayType::get(Int8PtrTy, 0);
+
+ llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
+ if (GV) {
+ if (!GV->isDeclaration() || GV->getType()->getElementType() == ArrayType)
+ return GV;
+
+ return llvm::ConstantExpr::getBitCast(GV, ArrayType->getPointerTo());
+ }
+
+ GV = new llvm::GlobalVariable(CGM.getModule(), ArrayType, /*isConstant=*/true,
+ llvm::GlobalValue::ExternalLinkage, 0, Name);
+
+ return GV;
}
void CodeGenVTables::EmitVTableRelatedData(GlobalDecl GD) {
diff --git a/lib/CodeGen/CGVtable.h b/lib/CodeGen/CGVtable.h
index ebccb51..a38153b 100644
--- a/lib/CodeGen/CGVtable.h
+++ b/lib/CodeGen/CGVtable.h
@@ -222,13 +222,17 @@
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;
+ const CodeGenVTables::AddrSubMap_t& getAddressPoints(const CXXRecordDecl *RD);
+
+ llvm::DenseMap<const CXXRecordDecl *, AddrMap_t*> AddressPoints;
+
private:
CodeGenModule &CGM;
+
/// MethodVtableIndices - Contains the index (relative to the vtable address
/// point) where the function pointer for a virtual function is stored.
typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVtableIndicesTy;
@@ -312,8 +316,9 @@
int64_t getVirtualBaseOffsetOffset(const CXXRecordDecl *RD,
const CXXRecordDecl *VBase);
- llvm::GlobalVariable *getVtable(const CXXRecordDecl *RD);
-
+ /// getAddrOfVTable - Get the address of the vtable for the given record decl.
+ llvm::Constant *getAddrOfVTable(const CXXRecordDecl *RD);
+
/// CtorVtableInfo - Information about a constructor vtable.
struct CtorVtableInfo {
/// Vtable - The vtable itself.
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index cc51045..f5c25b2 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -513,7 +513,7 @@
void InitializeVtablePtrsRecursive(const CXXRecordDecl *ClassDecl,
llvm::Constant *Vtable,
- CodeGenVTables::AddrSubMap_t& AddressPoints,
+ const CodeGenVTables::AddrSubMap_t& AddressPoints,
llvm::Value *ThisPtr,
uint64_t Offset);
diff --git a/test/CodeGenCXX/copy-constructor-synthesis-2.cpp b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
index 2f7c79b..4d40372 100644
--- a/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
+++ b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
@@ -4,4 +4,4 @@
A x(A& y) { return y; }
// CHECK: define linkonce_odr void @_ZN1AC1ERKS_(
-// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2)
+// CHECK: store i8** getelementptr inbounds ([0 x i8*]* @_ZTV1A, i64 0, i64 2)
diff --git a/test/CodeGenCXX/vtable-pointer-initialization.cpp b/test/CodeGenCXX/vtable-pointer-initialization.cpp
index 75620ab..bf8575a 100644
--- a/test/CodeGenCXX/vtable-pointer-initialization.cpp
+++ b/test/CodeGenCXX/vtable-pointer-initialization.cpp
@@ -21,13 +21,13 @@
// CHECK: define void @_ZN1AC2Ev(
// CHECK: call void @_ZN4BaseC2Ev(
-// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2)
+// CHECK: store i8** getelementptr inbounds ([0 x i8*]* @_ZTV1A, i64 0, i64 2)
// CHECK: call void @_ZN5FieldC1Ev(
// CHECK: ret void
A::A() { }
// CHECK: define void @_ZN1AD2Ev(
-// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2)
+// CHECK: store i8** getelementptr inbounds ([0 x i8*]* @_ZTV1A, i64 0, i64 2)
// CHECK: call void @_ZN5FieldD1Ev(
// CHECK: call void @_ZN4BaseD2Ev(
// CHECK: ret void
@@ -45,13 +45,13 @@
// CHECK: call void @_ZN1BC2Ev(
// CHECK: define linkonce_odr void @_ZN1BD1Ev(
-// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2)
+// CHECK: store i8** getelementptr inbounds ([0 x i8*]* @_ZTV1B, i64 0, i64 2)
// CHECK: call void @_ZN5FieldD1Ev(
// CHECK: call void @_ZN4BaseD2Ev(
// CHECK: ret void
// CHECK: define linkonce_odr void @_ZN1BC2Ev(
// CHECK: call void @_ZN4BaseC2Ev(
-// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2)
+// CHECK: store i8** getelementptr inbounds ([0 x i8*]* @_ZTV1B, i64 0, i64 2)
// CHECK: call void @_ZN5FieldC1Ev
// CHECK: ret void