aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2011-02-03 02:08:44 +0000
committerAnders Carlsson <andersca@mac.com>2011-02-03 02:08:44 +0000
commitaedd9d5ad3cc776fd61457050bcd54cac4c5ea66 (patch)
treee87d32a8c47c8825b7774c82088568999cb01285 /lib
parentb51eee43676c2f4b7c4e1fa1648b438051b2b098 (diff)
Don't try to mark virtual members referenced for classes where the key function
is not defined in the current translation unit. Doing so lead to compile errors such as PR9114. Instead, when CodeGen is building the vtable, don't try to emit a definition for functions that aren't marked used in the current translation unit. Fixes PR9114. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124768 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/CGCXX.cpp6
-rw-r--r--lib/CodeGen/CGVTables.cpp4
-rw-r--r--lib/CodeGen/CodeGenModule.cpp23
-rw-r--r--lib/CodeGen/CodeGenModule.h6
-rw-r--r--lib/Sema/SemaDeclCXX.cpp7
5 files changed, 25 insertions, 21 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index a4145675b3..f2128792f8 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -227,7 +227,8 @@ CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D,
const llvm::FunctionType *FTy =
getTypes().GetFunctionType(getTypes().getFunctionInfo(D, Type),
FPT->isVariadic());
- return cast<llvm::Function>(GetOrCreateLLVMFunction(Name, FTy, GD));
+ return cast<llvm::Function>(GetOrCreateLLVMFunction(Name, FTy, GD,
+ /*ForVTable=*/false));
}
void CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) {
@@ -284,7 +285,8 @@ CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D,
const llvm::FunctionType *FTy =
getTypes().GetFunctionType(getTypes().getFunctionInfo(D, Type), false);
- return cast<llvm::Function>(GetOrCreateLLVMFunction(Name, FTy, GD));
+ return cast<llvm::Function>(GetOrCreateLLVMFunction(Name, FTy, GD,
+ /*ForVTable=*/false));
}
static llvm::Value *BuildVirtualCall(CodeGenFunction &CGF, uint64_t VTableIndex,
diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp
index de6cbf52f3..eadfe9f146 100644
--- a/lib/CodeGen/CGVTables.cpp
+++ b/lib/CodeGen/CGVTables.cpp
@@ -2463,7 +2463,7 @@ llvm::Constant *CodeGenModule::GetAddrOfThunk(GlobalDecl GD,
getCXXABI().getMangleContext().mangleThunk(MD, Thunk, Name);
const llvm::Type *Ty = getTypes().GetFunctionTypeForVTable(GD);
- return GetOrCreateLLVMFunction(Name, Ty, GD);
+ return GetOrCreateLLVMFunction(Name, Ty, GD, /*ForVTable=*/false);
}
static llvm::Value *PerformTypeAdjustment(CodeGenFunction &CGF,
@@ -2918,7 +2918,7 @@ CodeGenVTables::CreateVTableInitializer(const CXXRecordDecl *RD,
} else {
const llvm::Type *Ty = CGM.getTypes().GetFunctionTypeForVTable(GD);
- Init = CGM.GetAddrOfFunction(GD, Ty);
+ Init = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true);
}
Init = llvm::ConstantExpr::getBitCast(Init, Int8PtrTy);
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index b8f91b464d..0c541b9670 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -650,7 +650,8 @@ llvm::Constant *CodeGenModule::GetWeakRefReference(const ValueDecl *VD) {
llvm::Constant *Aliasee;
if (isa<llvm::FunctionType>(DeclTy))
- Aliasee = GetOrCreateLLVMFunction(AA->getAliasee(), DeclTy, GlobalDecl());
+ Aliasee = GetOrCreateLLVMFunction(AA->getAliasee(), DeclTy, GlobalDecl(),
+ /*ForVTable=*/false);
else
Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(),
llvm::PointerType::getUnqual(DeclTy), 0);
@@ -782,7 +783,7 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) {
llvm::Constant *
CodeGenModule::GetOrCreateLLVMFunction(llvm::StringRef MangledName,
const llvm::Type *Ty,
- GlobalDecl D) {
+ GlobalDecl D, bool ForVTable) {
// Lookup the entry, lazily creating it if necessary.
llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
if (Entry) {
@@ -840,7 +841,11 @@ CodeGenModule::GetOrCreateLLVMFunction(llvm::StringRef MangledName,
// - special member functions with implicit definitions
// If we ever change our AST traversal to walk into class methods,
// this will be unnecessary.
- } else if (getLangOptions().CPlusPlus && D.getDecl()) {
+ //
+ // We also don't emit a definition for a function if it's going to be an entry
+ // in a vtable, unless it's already marked as used.
+ } else if (getLangOptions().CPlusPlus && D.getDecl() &&
+ !(ForVTable && !D.getDecl()->isUsed())) {
// Look for a declaration that's lexically in a record.
const FunctionDecl *FD = cast<FunctionDecl>(D.getDecl());
do {
@@ -872,13 +877,14 @@ CodeGenModule::GetOrCreateLLVMFunction(llvm::StringRef MangledName,
/// non-null, then this function will use the specified type if it has to
/// create it (this occurs when we see a definition of the function).
llvm::Constant *CodeGenModule::GetAddrOfFunction(GlobalDecl GD,
- const llvm::Type *Ty) {
+ const llvm::Type *Ty,
+ bool ForVTable) {
// If there was no specific requested type, just convert it now.
if (!Ty)
Ty = getTypes().ConvertType(cast<ValueDecl>(GD.getDecl())->getType());
llvm::StringRef MangledName = getMangledName(GD);
- return GetOrCreateLLVMFunction(MangledName, Ty, GD);
+ return GetOrCreateLLVMFunction(MangledName, Ty, GD, ForVTable);
}
/// CreateRuntimeFunction - Create a new runtime function with the specified
@@ -886,7 +892,7 @@ llvm::Constant *CodeGenModule::GetAddrOfFunction(GlobalDecl GD,
llvm::Constant *
CodeGenModule::CreateRuntimeFunction(const llvm::FunctionType *FTy,
llvm::StringRef Name) {
- return GetOrCreateLLVMFunction(Name, FTy, GlobalDecl());
+ return GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(), /*ForVTable=*/false);
}
static bool DeclIsConstantGlobal(ASTContext &Context, const VarDecl *D) {
@@ -1445,7 +1451,8 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
// if a deferred decl.
llvm::Constant *Aliasee;
if (isa<llvm::FunctionType>(DeclTy))
- Aliasee = GetOrCreateLLVMFunction(AA->getAliasee(), DeclTy, GlobalDecl());
+ Aliasee = GetOrCreateLLVMFunction(AA->getAliasee(), DeclTy, GlobalDecl(),
+ /*ForVTable=*/false);
else
Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(),
llvm::PointerType::getUnqual(DeclTy), 0);
@@ -1511,7 +1518,7 @@ llvm::Value *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD,
const llvm::FunctionType *Ty =
cast<llvm::FunctionType>(getTypes().ConvertType(FD->getType()));
- return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl(FD));
+ return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl(FD), /*ForVTable=*/false);
}
llvm::Function *CodeGenModule::getIntrinsic(unsigned IID,const llvm::Type **Tys,
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 7652b88fdc..00f88f6f5a 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -317,7 +317,8 @@ public:
/// non-null, then this function will use the specified type if it has to
/// create it.
llvm::Constant *GetAddrOfFunction(GlobalDecl GD,
- const llvm::Type *Ty = 0);
+ const llvm::Type *Ty = 0,
+ bool ForVTable = false);
/// GetAddrOfRTTIDescriptor - Get the address of the RTTI descriptor
/// for the given type.
@@ -541,7 +542,8 @@ private:
llvm::Constant *GetOrCreateLLVMFunction(llvm::StringRef MangledName,
const llvm::Type *Ty,
- GlobalDecl D);
+ GlobalDecl D,
+ bool ForVTable);
llvm::Constant *GetOrCreateLLVMGlobal(llvm::StringRef MangledName,
const llvm::PointerType *PTy,
const VarDecl *D,
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index b4c375d638..0565a7fef9 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -7118,13 +7118,6 @@ bool Sema::DefineUsedVTables() {
switch (KeyFunction->getTemplateSpecializationKind()) {
case TSK_Undeclared:
case TSK_ExplicitSpecialization:
- // The key function is in another translation unit. Mark all of the
- // virtual members of this class as referenced so that we can build a
- // vtable anyway (in order to do devirtualization when optimizations
- // are turned on for example.
- MarkVirtualMembersReferenced(Loc, Class);
- continue;
-
case TSK_ExplicitInstantiationDeclaration:
// The key function is in another translation unit.
continue;