[cfe-commits] r89289 - in /cfe/trunk/lib/CodeGen: CGRtti.cpp CGVtable.cpp CGVtable.h CodeGenModule.cpp
Mike Stump
mrs at apple.com
Wed Nov 18 17:08:19 PST 2009
Author: mrs
Date: Wed Nov 18 19:08:19 2009
New Revision: 89289
URL: http://llvm.org/viewvc/llvm-project?rev=89289&view=rev
Log:
Improve instantiation control for rtti data and allow key functions to
instantiate a class. WIP.
Modified:
cfe/trunk/lib/CodeGen/CGRtti.cpp
cfe/trunk/lib/CodeGen/CGVtable.cpp
cfe/trunk/lib/CodeGen/CGVtable.h
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
Modified: cfe/trunk/lib/CodeGen/CGRtti.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGRtti.cpp?rev=89289&r1=89288&r2=89289&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGRtti.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGRtti.cpp Wed Nov 18 19:08:19 2009
@@ -47,21 +47,35 @@
return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
}
- llvm::Constant *BuildName(QualType Ty, bool Hidden) {
+ llvm::Constant *BuildName(QualType Ty, bool Hidden, bool Extern) {
llvm::SmallString<256> OutName;
llvm::raw_svector_ostream Out(OutName);
mangleCXXRttiName(CGM.getMangleContext(), Ty, Out);
+ llvm::StringRef Name = Out.str();
llvm::GlobalVariable::LinkageTypes linktype;
linktype = llvm::GlobalValue::LinkOnceODRLinkage;
+ if (!Extern)
+ linktype = llvm::GlobalValue::InternalLinkage;
+
+ llvm::GlobalVariable *GV;
+ GV = CGM.getModule().getGlobalVariable(Name);
+ if (GV && !GV->isDeclaration())
+ return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
llvm::Constant *C;
- C = llvm::ConstantArray::get(VMContext, Out.str().substr(4));
+ C = llvm::ConstantArray::get(VMContext, Name.substr(4));
- llvm::GlobalVariable * GV = new llvm::GlobalVariable(CGM.getModule(),
- C->getType(),
- true, linktype, C,
- Out.str());
+ llvm::GlobalVariable *OGV = GV;
+ GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, linktype,
+ C, Name);
+ if (OGV) {
+ GV->takeName(OGV);
+ llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
+ OGV->getType());
+ OGV->replaceAllUsesWith(NewPtr);
+ OGV->eraseFromParent();
+ }
if (Hidden)
GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
@@ -87,8 +101,9 @@
llvm::SmallString<256> OutName;
llvm::raw_svector_ostream Out(OutName);
mangleCXXRtti(CGM.getMangleContext(), Ty, Out);
+ llvm::StringRef Name = Out.str();
- C = CGM.getModule().getGlobalVariable(Out.str());
+ C = CGM.getModule().getGlobalVariable(Name);
if (C)
return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
@@ -96,7 +111,7 @@
linktype = llvm::GlobalValue::ExternalLinkage;;
C = new llvm::GlobalVariable(CGM.getModule(), Int8PtrTy, true, linktype,
- 0, Out.str());
+ 0, Name);
return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
}
@@ -147,20 +162,19 @@
llvm::Constant *finish(std::vector<llvm::Constant *> &info,
llvm::GlobalVariable *GV,
- llvm::StringRef Name, bool Hidden) {
+ llvm::StringRef Name, bool Hidden, bool Extern) {
llvm::GlobalVariable::LinkageTypes linktype;
linktype = llvm::GlobalValue::LinkOnceODRLinkage;
+ if (!Extern)
+ linktype = llvm::GlobalValue::InternalLinkage;
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);
+ llvm::GlobalVariable *OGV = GV;
+ GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, linktype,
+ C, Name);
+ if (OGV) {
GV->takeName(OGV);
llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
OGV->getType());
@@ -183,15 +197,17 @@
llvm::raw_svector_ostream Out(OutName);
mangleCXXRtti(CGM.getMangleContext(), CGM.getContext().getTagDeclType(RD),
Out);
+ llvm::StringRef Name = Out.str();
llvm::GlobalVariable *GV;
- GV = CGM.getModule().getGlobalVariable(Out.str());
+ GV = CGM.getModule().getGlobalVariable(Name);
if (GV && !GV->isDeclaration())
return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
std::vector<llvm::Constant *> info;
bool Hidden = CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
+ bool Extern = !RD->isInAnonymousNamespace();
bool simple = false;
if (RD->getNumBases() == 0)
@@ -202,7 +218,8 @@
} else
C = BuildVtableRef("_ZTVN10__cxxabiv121__vmi_class_type_infoE");
info.push_back(C);
- info.push_back(BuildName(CGM.getContext().getTagDeclType(RD), Hidden));
+ info.push_back(BuildName(CGM.getContext().getTagDeclType(RD), Hidden,
+ Extern));
// If we have no bases, there are no more fields.
if (RD->getNumBases()) {
@@ -235,7 +252,7 @@
}
}
- return finish(info, GV, Out.str(), Hidden);
+ return finish(info, GV, Name, Hidden, Extern);
}
/// - BuildFlags - Build a __flags value for __pbase_type_info.
@@ -250,23 +267,49 @@
return BuildType(Ty);
}
+ bool DecideExtern(QualType Ty) {
+ // For this type, see if all components are never in an anonymous namespace.
+ if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
+ return (DecideExtern(MPT->getPointeeType())
+ && DecideExtern(QualType(MPT->getClass(), 0)));
+ if (const PointerType *PT = Ty->getAs<PointerType>())
+ return DecideExtern(PT->getPointeeType());
+ if (const RecordType *RT = Ty->getAs<RecordType>())
+ if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
+ return !RD->isInAnonymousNamespace();
+ return true;
+ }
+
+ bool DecideHidden(QualType Ty) {
+ // For this type, see if all components are never hidden.
+ if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
+ return (DecideHidden(MPT->getPointeeType())
+ && DecideHidden(QualType(MPT->getClass(), 0)));
+ if (const PointerType *PT = Ty->getAs<PointerType>())
+ return DecideHidden(PT->getPointeeType());
+ if (const RecordType *RT = Ty->getAs<RecordType>())
+ if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
+ return CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
+ return false;
+ }
+
llvm::Constant *BuildPointerType(QualType Ty) {
llvm::Constant *C;
llvm::SmallString<256> OutName;
llvm::raw_svector_ostream Out(OutName);
mangleCXXRtti(CGM.getMangleContext(), Ty, Out);
+ llvm::StringRef Name = Out.str();
llvm::GlobalVariable *GV;
- GV = CGM.getModule().getGlobalVariable(Out.str());
+ GV = CGM.getModule().getGlobalVariable(Name);
if (GV && !GV->isDeclaration())
return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
std::vector<llvm::Constant *> info;
- // FIXME: pointer to hidden should be hidden, we should be able to
- // grab a bit off the type for this.
- bool Hidden = false;
+ bool Extern = DecideExtern(Ty);
+ bool Hidden = DecideHidden(Ty);
QualType PTy = Ty->getPointeeType();
QualType BTy;
@@ -282,7 +325,7 @@
else
C = BuildVtableRef("_ZTVN10__cxxabiv119__pointer_type_infoE");
info.push_back(C);
- info.push_back(BuildName(Ty, Hidden));
+ info.push_back(BuildName(Ty, Hidden, Extern));
Qualifiers Q = PTy.getQualifiers();
PTy = CGM.getContext().getCanonicalType(PTy).getUnqualifiedType();
int flags = 0;
@@ -300,7 +343,8 @@
if (PtrMem)
info.push_back(BuildType2(BTy));
- return finish(info, GV, Out.str(), true);
+ // We always generate these as hidden, only the name isn't hidden.
+ return finish(info, GV, Name, true, Extern);
}
llvm::Constant *BuildSimpleType(QualType Ty, const char *vtbl) {
@@ -309,23 +353,24 @@
llvm::SmallString<256> OutName;
llvm::raw_svector_ostream Out(OutName);
mangleCXXRtti(CGM.getMangleContext(), Ty, Out);
+ llvm::StringRef Name = Out.str();
llvm::GlobalVariable *GV;
- GV = CGM.getModule().getGlobalVariable(Out.str());
+ GV = CGM.getModule().getGlobalVariable(Name);
if (GV && !GV->isDeclaration())
return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
std::vector<llvm::Constant *> info;
- // FIXME: pointer to hidden should be hidden, we should be able to
- // grab a bit off the type for this.
- bool Hidden = false;
+ bool Extern = DecideExtern(Ty);
+ bool Hidden = DecideHidden(Ty);
C = BuildVtableRef(vtbl);
info.push_back(C);
- info.push_back(BuildName(Ty, Hidden));
+ info.push_back(BuildName(Ty, Hidden, Extern));
- return finish(info, GV, Out.str(), true);
+ // We always generate these as hidden, only the name isn't hidden.
+ return finish(info, GV, Name, true, Extern);
}
llvm::Constant *BuildType(QualType Ty) {
Modified: cfe/trunk/lib/CodeGen/CGVtable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVtable.cpp?rev=89289&r1=89288&r2=89289&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Wed Nov 18 19:08:19 2009
@@ -1021,6 +1021,12 @@
return llvm::ConstantExpr::getBitCast(vtt, Ptr8Ty);
}
+void CGVtableInfo::GenerateClassData(const CXXRecordDecl *RD) {
+ Vtables[RD] = CGM.GenerateVtable(RD, RD);
+ CGM.GenerateRtti(RD);
+ CGM.GenerateVTT(RD);
+}
+
llvm::Constant *CGVtableInfo::getVtable(const CXXRecordDecl *RD) {
llvm::Constant *&vtbl = Vtables[RD];
if (vtbl)
Modified: cfe/trunk/lib/CodeGen/CGVtable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVtable.h?rev=89289&r1=89288&r2=89289&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.h (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.h Wed Nov 18 19:08:19 2009
@@ -61,6 +61,10 @@
llvm::Constant *getVtable(const CXXRecordDecl *RD);
llvm::Constant *getCtorVtable(const CXXRecordDecl *RD,
const CXXRecordDecl *Class, uint64_t Offset);
+ /// GenerateClassData - Generate all the class data requires to be generated
+ /// upon definition of a KeyFunction. This includes the vtable, the
+ /// rtti data structure and the VTT.
+ void GenerateClassData(const CXXRecordDecl *RD);
};
}
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=89289&r1=89288&r2=89289&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Wed Nov 18 19:08:19 2009
@@ -616,6 +616,16 @@
Context.getSourceManager(),
"Generating code for declaration");
+ if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
+ const CXXRecordDecl *RD = MD->getParent();
+ // We have to convert it to have a record layout.
+ Types.ConvertTagDeclType(RD);
+ const CGRecordLayout &CGLayout = Types.getCGRecordLayout(RD);
+ // A definition of a KeyFunction, generates all the class data, such
+ // as vtable, rtti and the VTT.
+ if (CGLayout.getKeyFunction() == MD)
+ getVtableInfo().GenerateClassData(RD);
+ }
if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(D))
EmitCXXConstructor(CD, GD.getCtorType());
else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(D))
More information about the cfe-commits
mailing list