aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2009-11-17 23:11:22 +0000
committerMike Stump <mrs@apple.com>2009-11-17 23:11:22 +0000
commit64989f04d13d9a4a62cc7ebee6351b7c4dbe2e74 (patch)
tree6eaa617a05290f8c59a2472384ed2de0bd895bc2
parentc32b1d82c1f6d0f0d6c615beb3b6bdfbfbea7098 (diff)
Add rtti info for function prototypes and refactor. This allows
pointer to member functions to work. WIP. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89161 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CGRtti.cpp107
-rw-r--r--test/CodeGenCXX/rtti.cpp18
2 files changed, 77 insertions, 48 deletions
diff --git a/lib/CodeGen/CGRtti.cpp b/lib/CodeGen/CGRtti.cpp
index 901c34a281..46d7b67efb 100644
--- a/lib/CodeGen/CGRtti.cpp
+++ b/lib/CodeGen/CGRtti.cpp
@@ -76,7 +76,6 @@ public:
}
llvm::Constant *BuildTypeRef(QualType Ty) {
- const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
llvm::Constant *C;
if (!CGM.getContext().getLangOptions().Rtti)
@@ -143,13 +142,38 @@ public:
return true;
}
- llvm::Constant *Buildclass_type_info(const CXXRecordDecl *RD) {
- const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
+ llvm::Constant *finish(std::vector<llvm::Constant *> &info,
+ llvm::GlobalVariable *GV,
+ llvm::StringRef Name) {
+ llvm::GlobalVariable::LinkageTypes linktype;
+ linktype = llvm::GlobalValue::LinkOnceODRLinkage;
+
llvm::Constant *C;
+ C = llvm::ConstantStruct::get(VMContext, &info[0], info.size(), false);
+
+ if (GV == 0)
+ GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true,
+ linktype, C, Name);
+ else {
+ llvm::GlobalVariable *OGV = GV;
+ GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true,
+ linktype, C, Name);
+ GV->takeName(OGV);
+ llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
+ OGV->getType());
+ OGV->replaceAllUsesWith(NewPtr);
+ OGV->eraseFromParent();
+ }
+ return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
+ }
+
+ llvm::Constant *Buildclass_type_info(const CXXRecordDecl *RD) {
if (!CGM.getContext().getLangOptions().Rtti)
return llvm::Constant::getNullValue(Int8PtrTy);
+ llvm::Constant *C;
+
llvm::SmallString<256> OutName;
llvm::raw_svector_ostream Out(OutName);
mangleCXXRtti(CGM.getMangleContext(), CGM.getContext().getTagDeclType(RD),
@@ -160,8 +184,6 @@ public:
if (GV && !GV->isDeclaration())
return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
- llvm::GlobalVariable::LinkageTypes linktype;
- linktype = llvm::GlobalValue::LinkOnceODRLinkage;
std::vector<llvm::Constant *> info;
bool simple = false;
@@ -206,31 +228,7 @@ public:
}
}
- C = llvm::ConstantStruct::get(VMContext, &info[0], info.size(), false);
-
- if (GV == 0)
- GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, linktype,
- C, Out.str());
- else {
- llvm::GlobalVariable *OGV = GV;
- GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, linktype,
- C, Out.str());
- GV->takeName(OGV);
- llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV, OGV->getType());
- OGV->replaceAllUsesWith(NewPtr);
- OGV->eraseFromParent();
- }
- return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
-
-#if 0
- llvm::ArrayType *type = llvm::ArrayType::get(Int8PtrTy, info.size());
- C = llvm::ConstantArray::get(type, info);
- llvm::Constant *Rtti =
- new llvm::GlobalVariable(CGM.getModule(), type, true, linktype, C,
- Out.str());
- Rtti = llvm::ConstantExpr::getBitCast(Rtti, Int8PtrTy);
- return Rtti;
-#endif
+ return finish(info, GV, Out.str());
}
/// - BuildFlags - Build a __flags value for __pbase_type_info.
@@ -246,7 +244,6 @@ public:
}
llvm::Constant *BuildPointerType(QualType Ty) {
- const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
llvm::Constant *C;
llvm::SmallString<256> OutName;
@@ -294,22 +291,37 @@ public:
if (PtrMem)
info.push_back(BuildType2(BTy));
- C = llvm::ConstantStruct::get(VMContext, &info[0], info.size(), false);
+ return finish(info, GV, Out.str());
+ }
- if (GV == 0)
- GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true,
- linktype, C, Out.str());
- else {
- llvm::GlobalVariable *OGV = GV;
- GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true,
- linktype, C, Out.str());
- GV->takeName(OGV);
- llvm::Constant *NewPtr
- = llvm::ConstantExpr::getBitCast(GV, OGV->getType());
- OGV->replaceAllUsesWith(NewPtr);
- OGV->eraseFromParent();
+ llvm::Constant *BuildFunctionType(QualType Ty) {
+ llvm::Constant *C;
+
+ llvm::SmallString<256> OutName;
+ llvm::raw_svector_ostream Out(OutName);
+ mangleCXXRtti(CGM.getMangleContext(), Ty, Out);
+
+ llvm::GlobalVariable *GV;
+ GV = CGM.getModule().getGlobalVariable(Out.str());
+ if (GV && !GV->isDeclaration())
+ return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
+
+ std::vector<llvm::Constant *> info;
+
+ QualType PTy = Ty->getPointeeType();
+ QualType BTy;
+ bool PtrMem = false;
+ if (const MemberPointerType *MPT = dyn_cast<MemberPointerType>(Ty)) {
+ PtrMem = true;
+ BTy = QualType(MPT->getClass(), 0);
+ PTy = MPT->getPointeeType();
}
- return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
+
+ C = BuildVtableRef("_ZTVN10__cxxabiv120__function_type_infoE");
+ info.push_back(C);
+ info.push_back(BuildName(Ty));
+
+ return finish(info, GV, Out.str());
}
llvm::Constant *BuildType(QualType Ty) {
@@ -317,9 +329,8 @@ public:
= *CGM.getContext().getCanonicalType(Ty).getTypePtr();
switch (Type.getTypeClass()) {
default: {
- // FIXME: Add all the missing types, such as pointer, array...
+ // FIXME: Add all the missing types, such as array...
assert(0 && "typeid expression");
- const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
return llvm::Constant::getNullValue(Int8PtrTy);
}
@@ -340,6 +351,8 @@ public:
}
case Type::MemberPointer:
return BuildPointerType(Ty);
+ case Type::FunctionProto:
+ return BuildFunctionType(Ty);
}
}
};
diff --git a/test/CodeGenCXX/rtti.cpp b/test/CodeGenCXX/rtti.cpp
index 3d8f116fc1..a673544ace 100644
--- a/test/CodeGenCXX/rtti.cpp
+++ b/test/CodeGenCXX/rtti.cpp
@@ -49,7 +49,7 @@ class test1_D : public test1_B7 {
// CHECK-NEXT: .quad __ZTIi
// CHECK-NEXT: .quad __ZTI7test3_A
-// CHECK:__ZTIM7test3_Ii:
+// CHECK: __ZTIM7test3_Ii:
// CHECK-NEXT: .quad (__ZTVN10__cxxabiv129__pointer_to_member_type_infoE) + 16
// CHECK-NEXT: .quad __ZTSM7test3_Ii
// CHECK-NEXT: .long 16
@@ -57,6 +57,19 @@ class test1_D : public test1_B7 {
// CHECK-NEXT: .quad __ZTIi
// CHECK-NEXT: .quad __ZTI7test3_I
+// CHECK: __ZTIFvvE:
+// CHECK-NEXT: .quad (__ZTVN10__cxxabiv120__function_type_infoE) + 16
+// CHECK-NEXT: .quad __ZTSFvvE
+
+// CHECK: __ZTIM7test3_AFvvE:
+// CHECK-NEXT: .quad (__ZTVN10__cxxabiv129__pointer_to_member_type_infoE) + 16
+// CHECK-NEXT: .quad __ZTSM7test3_AFvvE
+// CHECK-NEXT: .space 4
+// CHECK-NEXT: .space 4
+// CHECK-NEXT: .quad __ZTIFvvE
+// CHECK-NEXT: .quad __ZTI7test3_A
+
+
// CHECK:__ZTI7test1_D:
// CHECK-NEXT: .quad (__ZTVN10__cxxabiv120__si_class_type_infoE) + 16
@@ -167,10 +180,13 @@ class test3_A { };
class test3_I;
int (test3_A::*pmd);
int (test3_I::*i_pmd);
+void (test3_A::*pmf)();
int test3() {
if (typeid(volatile int *) == typeid(int *))
return 1;
if (typeid(pmd) == typeid(i_pmd))
return 1;
+ if (typeid(pmd) == typeid(pmf))
+ return 1;
return 0;
}