Set the correct linkage for VTTs as well.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90689 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Anders Carlsson 2009-12-06 01:09:21 +00:00
Родитель d76fbda5da
Коммит c3a46ef9f8
3 изменённых файлов: 42 добавлений и 61 удалений

Просмотреть файл

@ -28,9 +28,10 @@ public:
typedef uint64_t Index_t;
private:
// Vtable - The components of the vtable being built.
typedef llvm::SmallVector<llvm::Constant *, 64> VtableVectorTy;
VtableVectorTy Vtable;
// VtableComponents - The components of the vtable being built.
typedef llvm::SmallVector<llvm::Constant *, 64> VtableComponentsVectorTy;
VtableComponentsVectorTy VtableComponents;
const bool BuildVtable;
llvm::Type *Ptr8Ty;
@ -193,9 +194,9 @@ public:
rtti = cgm.GenerateRTTIRef(MostDerivedClass);
}
// getVtable - Returns a reference to the vtable components.
const VtableVectorTy &getVtable() const {
return Vtable;
// getVtableComponents - Returns a reference to the vtable components.
const VtableComponentsVectorTy &getVtableComponents() const {
return VtableComponents;
}
llvm::DenseMap<const CXXRecordDecl *, Index_t> &getVBIndex()
@ -425,13 +426,14 @@ public:
D(VCalls.insert(VCalls.begin(), 673));
D(VCalls.push_back(672));
Vtable.insert(Vtable.begin() + InsertionPoint, VCalls.size(), 0);
VtableComponents.insert(VtableComponents.begin() + InsertionPoint,
VCalls.size(), 0);
if (BuildVtable) {
// The vcalls come first...
for (std::vector<Index_t>::reverse_iterator i = VCalls.rbegin(),
e = VCalls.rend();
i != e; ++i)
Vtable[InsertionPoint++] = wrap((0?600:0) + *i);
VtableComponents[InsertionPoint++] = wrap((0?600:0) + *i);
}
VCalls.clear();
VCall.clear();
@ -479,7 +481,7 @@ public:
StartNewTable();
extra = 0;
bool DeferVCalls = MorallyVirtual || ForVirtualBase;
int VCallInsertionPoint = Vtable.size();
int VCallInsertionPoint = VtableComponents.size();
if (!DeferVCalls) {
insertVCalls(VCallInsertionPoint);
} else
@ -487,12 +489,12 @@ public:
extra = -VCalls.size();
// Add the offset to top.
Vtable.push_back(BuildVtable ? wrap(-((Offset-LayoutOffset)/8)) : 0);
VtableComponents.push_back(BuildVtable ? wrap(-((Offset-LayoutOffset)/8)) : 0);
// Add the RTTI information.
Vtable.push_back(rtti);
VtableComponents.push_back(rtti);
Index_t AddressPoint = Vtable.size();
Index_t AddressPoint = VtableComponents.size();
AppendMethodsToVtable();
@ -840,7 +842,8 @@ bool VtableBuilder::OverrideMethod(GlobalDecl GD, bool MorallyVirtual,
void VtableBuilder::AppendMethodsToVtable() {
if (!BuildVtable) {
Vtable.insert(Vtable.end(), Methods.size(), (llvm::Constant*)0);
VtableComponents.insert(VtableComponents.end(), Methods.size(),
(llvm::Constant *)0);
ThisAdjustments.clear();
BaseReturnTypes.clear();
Methods.clear();
@ -848,7 +851,7 @@ void VtableBuilder::AppendMethodsToVtable() {
}
// Reserve room in the vtable for our new methods.
Vtable.reserve(Vtable.size() + Methods.size());
VtableComponents.reserve(VtableComponents.size() + Methods.size());
for (unsigned i = 0, e = Methods.size(); i != e; ++i) {
GlobalDecl GD = Methods[i];
@ -892,7 +895,7 @@ void VtableBuilder::AppendMethodsToVtable() {
}
// Add the method to the vtable.
Vtable.push_back(Method);
VtableComponents.push_back(Method);
}
@ -1082,35 +1085,6 @@ uint64_t CGVtableInfo::getVtableAddressPoint(const CXXRecordDecl *RD) {
return AddressPoint;
}
/// createGlobalVariable - Create a global variable to be used for storing
/// either a vtable, a construction vtable or a VTT. The returned global
// variable will have the correct linkage set based on the given record decl.
static llvm::GlobalVariable *
createGlobalVariable(CodeGenModule &CGM, const CXXRecordDecl *RD,
const llvm::Type *Type, llvm::Constant *Init,
const llvm::Twine &Name) {
// Figure out the right linkage.
llvm::GlobalVariable::LinkageTypes Linkage =
llvm::GlobalValue::WeakODRLinkage;
if (!Init)
Linkage = llvm::GlobalValue::ExternalLinkage;
else if (RD->isInAnonymousNamespace())
Linkage = llvm::GlobalValue::InternalLinkage;
// Create the variable.
llvm::GlobalVariable *V =
new llvm::GlobalVariable(CGM.getModule(), Type, /*isConstant=*/true,
Linkage, Init, Name);
bool Hidden = CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
if (Hidden)
V->setVisibility(llvm::GlobalVariable::HiddenVisibility);
return V;
}
llvm::GlobalVariable *
CGVtableInfo::GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage,
bool GenerateDefinition,
@ -1147,17 +1121,18 @@ CGVtableInfo::GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage,
llvm::Constant *Init = 0;
const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
llvm::ArrayType *ArrayType =
llvm::ArrayType::get(Int8PtrTy, b.getVtable().size());
llvm::ArrayType::get(Int8PtrTy, b.getVtableComponents().size());
if (GenerateDefinition)
Init = llvm::ConstantArray::get(ArrayType, &b.getVtable()[0],
b.getVtable().size());
Init = llvm::ConstantArray::get(ArrayType, &b.getVtableComponents()[0],
b.getVtableComponents().size());
llvm::GlobalVariable *OGV = GV;
GV = new llvm::GlobalVariable(CGM.getModule(), ArrayType,
/*isConstant=*/true, Linkage, Init, Name);
CGM.setGlobalVisibility(GV, RD);
if (OGV) {
GV->takeName(OGV);
llvm::Constant *NewPtr =
@ -1345,39 +1320,43 @@ public:
};
}
llvm::Constant *CodeGenModule::GenerateVTT(const CXXRecordDecl *RD) {
llvm::GlobalVariable *
CGVtableInfo::GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
const CXXRecordDecl *RD) {
// Only classes that have virtual bases need a VTT.
if (RD->getNumVBases() == 0)
return 0;
llvm::SmallString<256> OutName;
getMangleContext().mangleCXXVTT(RD, OutName);
CGM.getMangleContext().mangleCXXVTT(RD, OutName);
llvm::StringRef Name = OutName.str();
D1(printf("vtt %s\n", RD->getNameAsCString()));
std::vector<llvm::Constant *> inits;
VTTBuilder b(inits, RD, *this);
VTTBuilder b(inits, RD, CGM);
const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
const llvm::ArrayType *Type = llvm::ArrayType::get(Int8PtrTy, inits.size());
llvm::Constant *Init = llvm::ConstantArray::get(Type, inits);
llvm::GlobalVariable *VTT =
createGlobalVariable(*this, RD, Type, Init, Name);
new llvm::GlobalVariable(CGM.getModule(), Type, /*isConstant=*/true,
Linkage, Init, Name);
CGM.setGlobalVisibility(VTT, RD);
return llvm::ConstantExpr::getBitCast(VTT, Int8PtrTy);
return VTT;
}
void CGVtableInfo::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
const CXXRecordDecl *RD) {
assert(!Vtables.count(RD) && "Vtable has already been generated!");
Vtables[RD] = GenerateVtable(Linkage, /*GenerateDefinition=*/true, RD, RD, 0);
CGM.GenerateRTTI(RD);
CGM.GenerateVTT(RD);
GenerateVTT(Linkage, RD);
}
llvm::GlobalVariable *CGVtableInfo::getVtable(const CXXRecordDecl *RD) {

Просмотреть файл

@ -101,7 +101,10 @@ class CGVtableInfo {
GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage,
bool GenerateDefinition, const CXXRecordDecl *LayoutClass,
const CXXRecordDecl *RD, uint64_t Offset);
llvm::GlobalVariable *GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
const CXXRecordDecl *RD);
public:
CGVtableInfo(CodeGenModule &CGM)
: CGM(CGM) { }

Просмотреть файл

@ -212,15 +212,14 @@ public:
llvm::Constant *GetAddrOfFunction(GlobalDecl GD,
const llvm::Type *Ty = 0);
/// GenerateVTT - Generate the VTT for the given type.
llvm::Constant *GenerateVTT(const CXXRecordDecl *RD);
/// GenerateRTTI - Generate the rtti information for the given type.
llvm::Constant *GenerateRTTI(const CXXRecordDecl *RD);
/// GenerateRTTIRef - Generate a reference to the rtti information for the
/// given type.
llvm::Constant *GenerateRTTIRef(const CXXRecordDecl *RD);
/// GenerateRTTINonClass - Generate the rtti information for the given
/// GenerateRTTI - Generate the rtti information for the given
/// non-class type.
llvm::Constant *GenerateRTTI(QualType Ty);