Add rtti info for function prototypes and refactor. This allows

pointer to member functions to work.  WIP.

llvm-svn: 89161
This commit is contained in:
Mike Stump 2009-11-17 23:11:22 +00:00
parent 707ece6025
commit 96b96d5f2e
2 changed files with 78 additions and 49 deletions

View File

@ -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 *C;
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);
}
}
};

View File

@ -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;
}