summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/CodeGen/CGVTables.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2014-11-24 18:11:16 +0000
committerdim <dim@FreeBSD.org>2014-11-24 18:11:16 +0000
commit6148c19c738a92f344008aa3f88f4e008bada0ee (patch)
treed4426858455f04d0d8c25a2f9eb9ea5582ffe1b6 /contrib/llvm/tools/clang/lib/CodeGen/CGVTables.cpp
parent2c8643c6396b0a3db33430cf9380e70bbb9efce0 (diff)
parent173a4f43a911175643bda81ee675e8d9269056ea (diff)
downloadFreeBSD-src-6148c19c738a92f344008aa3f88f4e008bada0ee.zip
FreeBSD-src-6148c19c738a92f344008aa3f88f4e008bada0ee.tar.gz
Merge clang 3.5.0 release from ^/vendor/clang/dist, resolve conflicts,
and preserve our customizations, where necessary.
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CGVTables.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGVTables.cpp175
1 files changed, 70 insertions, 105 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGVTables.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGVTables.cpp
index f28d9b6..0df2c43 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGVTables.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGVTables.cpp
@@ -30,14 +30,7 @@ using namespace clang;
using namespace CodeGen;
CodeGenVTables::CodeGenVTables(CodeGenModule &CGM)
- : CGM(CGM), ItaniumVTContext(CGM.getContext()) {
- if (CGM.getTarget().getCXXABI().isMicrosoft()) {
- // FIXME: Eventually, we should only have one of V*TContexts available.
- // Today we use both in the Microsoft ABI as MicrosoftVFTableContext
- // is not completely supported in CodeGen yet.
- MicrosoftVTContext.reset(new MicrosoftVTableContext(CGM.getContext()));
- }
-}
+ : CGM(CGM), VTContext(CGM.getContext().getVTableContext()) {}
llvm::Constant *CodeGenModule::GetAddrOfThunk(GlobalDecl GD,
const ThunkInfo &Thunk) {
@@ -54,54 +47,13 @@ llvm::Constant *CodeGenModule::GetAddrOfThunk(GlobalDecl GD,
Out.flush();
llvm::Type *Ty = getTypes().GetFunctionTypeForVTable(GD);
- return GetOrCreateLLVMFunction(Name, Ty, GD, /*ForVTable=*/true);
+ return GetOrCreateLLVMFunction(Name, Ty, GD, /*ForVTable=*/true,
+ /*DontDefer*/ true);
}
static void setThunkVisibility(CodeGenModule &CGM, const CXXMethodDecl *MD,
const ThunkInfo &Thunk, llvm::Function *Fn) {
CGM.setGlobalVisibility(Fn, MD);
-
- if (!CGM.getCodeGenOpts().HiddenWeakVTables)
- return;
-
- // If the thunk has weak/linkonce linkage, but the function must be
- // emitted in every translation unit that references it, then we can
- // emit its thunks with hidden visibility, since its thunks must be
- // emitted when the function is.
-
- // This follows CodeGenModule::setTypeVisibility; see the comments
- // there for explanation.
-
- if ((Fn->getLinkage() != llvm::GlobalVariable::LinkOnceODRLinkage &&
- Fn->getLinkage() != llvm::GlobalVariable::WeakODRLinkage) ||
- Fn->getVisibility() != llvm::GlobalVariable::DefaultVisibility)
- return;
-
- if (MD->getExplicitVisibility(ValueDecl::VisibilityForValue))
- return;
-
- switch (MD->getTemplateSpecializationKind()) {
- case TSK_ExplicitInstantiationDefinition:
- case TSK_ExplicitInstantiationDeclaration:
- return;
-
- case TSK_Undeclared:
- break;
-
- case TSK_ExplicitSpecialization:
- case TSK_ImplicitInstantiation:
- return;
- break;
- }
-
- // If there's an explicit definition, and that definition is
- // out-of-line, then we can't assume that all users will have a
- // definition to emit.
- const FunctionDecl *Def = 0;
- if (MD->hasBody(Def) && Def->isOutOfLine())
- return;
-
- Fn->setVisibility(llvm::GlobalValue::HiddenVisibility);
}
#ifndef NDEBUG
@@ -119,11 +71,11 @@ static RValue PerformReturnAdjustment(CodeGenFunction &CGF,
const ThunkInfo &Thunk) {
// Emit the return adjustment.
bool NullCheckValue = !ResultType->isReferenceType();
-
- llvm::BasicBlock *AdjustNull = 0;
- llvm::BasicBlock *AdjustNotNull = 0;
- llvm::BasicBlock *AdjustEnd = 0;
-
+
+ llvm::BasicBlock *AdjustNull = nullptr;
+ llvm::BasicBlock *AdjustNotNull = nullptr;
+ llvm::BasicBlock *AdjustEnd = nullptr;
+
llvm::Value *ReturnValue = RV.getScalarVal();
if (NullCheckValue) {
@@ -177,7 +129,7 @@ void CodeGenFunction::GenerateVarArgsThunk(
GlobalDecl GD, const ThunkInfo &Thunk) {
const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
- QualType ResultType = FPT->getResultType();
+ QualType ResultType = FPT->getReturnType();
// Get the original function
assert(FnInfo.isVariadic());
@@ -207,7 +159,7 @@ void CodeGenFunction::GenerateVarArgsThunk(
// with "this".
llvm::Value *ThisPtr = &*AI;
llvm::BasicBlock *EntryBB = Fn->begin();
- llvm::Instruction *ThisStore = 0;
+ llvm::Instruction *ThisStore = nullptr;
for (llvm::BasicBlock::iterator I = EntryBB->begin(), E = EntryBB->end();
I != E; I++) {
if (isa<llvm::StoreInst>(I) && I->getOperand(0) == ThisPtr) {
@@ -248,11 +200,11 @@ void CodeGenFunction::StartThunk(llvm::Function *Fn, GlobalDecl GD,
QualType ThisType = MD->getThisType(getContext());
const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
QualType ResultType =
- CGM.getCXXABI().HasThisReturn(GD) ? ThisType : FPT->getResultType();
+ CGM.getCXXABI().HasThisReturn(GD) ? ThisType : FPT->getReturnType();
FunctionArgList FunctionArgs;
// Create the implicit 'this' parameter declaration.
- CGM.getCXXABI().BuildInstanceFunctionParams(*this, ResultType, FunctionArgs);
+ CGM.getCXXABI().buildThisParam(*this, FunctionArgs);
// Add the rest of the parameters.
for (FunctionDecl::param_const_iterator I = MD->param_begin(),
@@ -260,9 +212,12 @@ void CodeGenFunction::StartThunk(llvm::Function *Fn, GlobalDecl GD,
I != E; ++I)
FunctionArgs.push_back(*I);
+ if (isa<CXXDestructorDecl>(MD))
+ CGM.getCXXABI().addImplicitStructorParams(*this, ResultType, FunctionArgs);
+
// Start defining the function.
StartFunction(GlobalDecl(), ResultType, Fn, FnInfo, FunctionArgs,
- SourceLocation());
+ MD->getLocation(), SourceLocation());
// Since we didn't pass a GlobalDecl to StartFunction, do this ourselves.
CGM.getCXXABI().EmitInstanceFunctionProlog(*this);
@@ -316,7 +271,7 @@ void CodeGenFunction::EmitCallAndReturnForThunk(GlobalDecl GD,
// Determine whether we have a return value slot to use.
QualType ResultType =
- CGM.getCXXABI().HasThisReturn(GD) ? ThisType : FPT->getResultType();
+ CGM.getCXXABI().HasThisReturn(GD) ? ThisType : FPT->getReturnType();
ReturnValueSlot Slot;
if (!ResultType->isVoidType() &&
CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect &&
@@ -366,27 +321,30 @@ void CodeGenVTables::emitThunk(GlobalDecl GD, const ThunkInfo &Thunk,
const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeGlobalDeclaration(GD);
// FIXME: re-use FnInfo in this computation.
- llvm::Constant *Entry = CGM.GetAddrOfThunk(GD, Thunk);
-
+ llvm::Constant *C = CGM.GetAddrOfThunk(GD, Thunk);
+ llvm::GlobalValue *Entry;
+
// Strip off a bitcast if we got one back.
- if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Entry)) {
+ if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(C)) {
assert(CE->getOpcode() == llvm::Instruction::BitCast);
- Entry = CE->getOperand(0);
+ Entry = cast<llvm::GlobalValue>(CE->getOperand(0));
+ } else {
+ Entry = cast<llvm::GlobalValue>(C);
}
-
+
// There's already a declaration with the same name, check if it has the same
// type or if we need to replace it.
- if (cast<llvm::GlobalValue>(Entry)->getType()->getElementType() !=
+ if (Entry->getType()->getElementType() !=
CGM.getTypes().GetFunctionTypeForVTable(GD)) {
- llvm::GlobalValue *OldThunkFn = cast<llvm::GlobalValue>(Entry);
-
+ llvm::GlobalValue *OldThunkFn = Entry;
+
// If the types mismatch then we have to rewrite the definition.
assert(OldThunkFn->isDeclaration() &&
"Shouldn't replace non-declaration");
// Remove the name from the old thunk function and get a new thunk.
OldThunkFn->setName(StringRef());
- Entry = CGM.GetAddrOfThunk(GD, Thunk);
+ Entry = cast<llvm::GlobalValue>(CGM.GetAddrOfThunk(GD, Thunk));
// If needed, replace the old thunk with a bitcast.
if (!OldThunkFn->use_empty()) {
@@ -424,12 +382,14 @@ void CodeGenVTables::emitThunk(GlobalDecl GD, const ThunkInfo &Thunk,
// FIXME: Do something better here; GenerateVarArgsThunk is extremely ugly.
if (!UseAvailableExternallyLinkage) {
CodeGenFunction(CGM).GenerateVarArgsThunk(ThunkFn, FnInfo, GD, Thunk);
- CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable);
+ CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable, GD,
+ !Thunk.Return.isEmpty());
}
} else {
// Normal thunk body generation.
CodeGenFunction(CGM).GenerateThunk(ThunkFn, FnInfo, GD, Thunk);
- CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable);
+ CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable, GD,
+ !Thunk.Return.isEmpty());
}
}
@@ -461,12 +421,8 @@ void CodeGenVTables::EmitThunks(GlobalDecl GD)
if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
return;
- const VTableContextBase::ThunkInfoVectorTy *ThunkInfoVector;
- if (MicrosoftVTContext.isValid()) {
- ThunkInfoVector = MicrosoftVTContext->getThunkInfo(GD);
- } else {
- ThunkInfoVector = ItaniumVTContext.getThunkInfo(GD);
- }
+ const VTableContextBase::ThunkInfoVectorTy *ThunkInfoVector =
+ VTContext->getThunkInfo(GD);
if (!ThunkInfoVector)
return;
@@ -475,12 +431,10 @@ void CodeGenVTables::EmitThunks(GlobalDecl GD)
emitThunk(GD, (*ThunkInfoVector)[I], /*ForVTable=*/false);
}
-llvm::Constant *
-CodeGenVTables::CreateVTableInitializer(const CXXRecordDecl *RD,
- const VTableComponent *Components,
- unsigned NumComponents,
- const VTableLayout::VTableThunkTy *VTableThunks,
- unsigned NumVTableThunks) {
+llvm::Constant *CodeGenVTables::CreateVTableInitializer(
+ const CXXRecordDecl *RD, const VTableComponent *Components,
+ unsigned NumComponents, const VTableLayout::VTableThunkTy *VTableThunks,
+ unsigned NumVTableThunks, llvm::Constant *RTTI) {
SmallVector<llvm::Constant *, 64> Inits;
llvm::Type *Int8PtrTy = CGM.Int8PtrTy;
@@ -488,17 +442,14 @@ CodeGenVTables::CreateVTableInitializer(const CXXRecordDecl *RD,
llvm::Type *PtrDiffTy =
CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
- QualType ClassType = CGM.getContext().getTagDeclType(RD);
- llvm::Constant *RTTI = CGM.GetAddrOfRTTIDescriptor(ClassType);
-
unsigned NextVTableThunkIndex = 0;
-
- llvm::Constant *PureVirtualFn = 0, *DeletedVirtualFn = 0;
+
+ llvm::Constant *PureVirtualFn = nullptr, *DeletedVirtualFn = nullptr;
for (unsigned I = 0; I != NumComponents; ++I) {
VTableComponent Component = Components[I];
- llvm::Constant *Init = 0;
+ llvm::Constant *Init = nullptr;
switch (Component.getKind()) {
case VTableComponent::CK_VCallOffset:
@@ -603,8 +554,8 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD,
if (CGDebugInfo *DI = CGM.getModuleDebugInfo())
DI->completeClassData(Base.getBase());
- OwningPtr<VTableLayout> VTLayout(
- ItaniumVTContext.createConstructionVTableLayout(
+ std::unique_ptr<VTableLayout> VTLayout(
+ getItaniumVTableContext().createConstructionVTableLayout(
Base.getBase(), Base.getBaseOffset(), BaseIsVirtual, RD));
// Add the address points.
@@ -633,18 +584,19 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD,
// Create the variable that will hold the construction vtable.
llvm::GlobalVariable *VTable =
CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType, Linkage);
- CGM.setTypeVisibility(VTable, RD, CodeGenModule::TVK_ForConstructionVTable);
+ CGM.setGlobalVisibility(VTable, RD);
// V-tables are always unnamed_addr.
VTable->setUnnamedAddr(true);
+ llvm::Constant *RTTI = CGM.GetAddrOfRTTIDescriptor(
+ CGM.getContext().getTagDeclType(Base.getBase()));
+
// Create and set the initializer.
- llvm::Constant *Init =
- CreateVTableInitializer(Base.getBase(),
- VTLayout->vtable_component_begin(),
- VTLayout->getNumVTableComponents(),
- VTLayout->vtable_thunk_begin(),
- VTLayout->getNumVTableThunks());
+ llvm::Constant *Init = CreateVTableInitializer(
+ Base.getBase(), VTLayout->vtable_component_begin(),
+ VTLayout->getNumVTableComponents(), VTLayout->vtable_thunk_begin(),
+ VTLayout->getNumVTableThunks(), RTTI);
VTable->setInitializer(Init);
return VTable;
@@ -663,7 +615,7 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) {
if (const CXXMethodDecl *keyFunction = Context.getCurrentKeyFunction(RD)) {
// If this class has a key function, use that to determine the
// linkage of the vtable.
- const FunctionDecl *def = 0;
+ const FunctionDecl *def = nullptr;
if (keyFunction->hasBody(def))
keyFunction = cast<CXXMethodDecl>(def);
@@ -697,18 +649,31 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) {
// internal linkage.
if (Context.getLangOpts().AppleKext)
return llvm::Function::InternalLinkage;
-
+
+ llvm::GlobalVariable::LinkageTypes DiscardableODRLinkage =
+ llvm::GlobalValue::LinkOnceODRLinkage;
+ llvm::GlobalVariable::LinkageTypes NonDiscardableODRLinkage =
+ llvm::GlobalValue::WeakODRLinkage;
+ if (RD->hasAttr<DLLExportAttr>()) {
+ // Cannot discard exported vtables.
+ DiscardableODRLinkage = NonDiscardableODRLinkage;
+ } else if (RD->hasAttr<DLLImportAttr>()) {
+ // Imported vtables are available externally.
+ DiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;
+ NonDiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;
+ }
+
switch (RD->getTemplateSpecializationKind()) {
case TSK_Undeclared:
case TSK_ExplicitSpecialization:
case TSK_ImplicitInstantiation:
- return llvm::GlobalVariable::LinkOnceODRLinkage;
+ return DiscardableODRLinkage;
case TSK_ExplicitInstantiationDeclaration:
llvm_unreachable("Should not have been asked to emit this");
case TSK_ExplicitInstantiationDefinition:
- return llvm::GlobalVariable::WeakODRLinkage;
+ return NonDiscardableODRLinkage;
}
llvm_unreachable("Invalid TemplateSpecializationKind!");
@@ -752,7 +717,7 @@ CodeGenVTables::GenerateClassData(const CXXRecordDecl *RD) {
/// strongly elsewhere. Otherwise, we'd just like to avoid emitting
/// v-tables when unnecessary.
bool CodeGenVTables::isVTableExternal(const CXXRecordDecl *RD) {
- assert(RD->isDynamicClass() && "Non dynamic classes have no VTable.");
+ assert(RD->isDynamicClass() && "Non-dynamic classes have no VTable.");
// If we have an explicit instantiation declaration (and not a
// definition), the v-table is defined elsewhere.
OpenPOWER on IntegriCloud