aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/CodeGen/CGVTables.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/CodeGen/CGVTables.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGVTables.cpp119
1 files changed, 81 insertions, 38 deletions
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGVTables.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGVTables.cpp
index 8dee3f74b44b..267bdf098297 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CGVTables.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CGVTables.cpp
@@ -95,7 +95,7 @@ static RValue PerformReturnAdjustment(CodeGenFunction &CGF,
CGF,
Address(ReturnValue, CGF.ConvertTypeForMem(ResultType->getPointeeType()),
ClassAlign),
- Thunk.Return);
+ ClassDecl, Thunk.Return);
if (NullCheckValue) {
CGF.Builder.CreateBr(AdjustEnd);
@@ -131,6 +131,12 @@ static void resolveTopLevelMetadata(llvm::Function *Fn,
// they are referencing.
for (auto &BB : *Fn) {
for (auto &I : BB) {
+ for (llvm::DbgVariableRecord &DVR :
+ llvm::filterDbgVars(I.getDbgRecordRange())) {
+ auto *DILocal = DVR.getVariable();
+ if (!DILocal->isResolved())
+ DILocal->resolve();
+ }
if (auto *DII = dyn_cast<llvm::DbgVariableIntrinsic>(&I)) {
auto *DILocal = DII->getVariable();
if (!DILocal->isResolved())
@@ -201,21 +207,22 @@ CodeGenFunction::GenerateVarArgsThunk(llvm::Function *Fn,
// Find the first store of "this", which will be to the alloca associated
// with "this".
- Address ThisPtr =
- Address(&*AI, ConvertTypeForMem(MD->getFunctionObjectParameterType()),
- CGM.getClassPointerAlignment(MD->getParent()));
+ Address ThisPtr = makeNaturalAddressForPointer(
+ &*AI, MD->getFunctionObjectParameterType(),
+ CGM.getClassPointerAlignment(MD->getParent()));
llvm::BasicBlock *EntryBB = &Fn->front();
llvm::BasicBlock::iterator ThisStore =
llvm::find_if(*EntryBB, [&](llvm::Instruction &I) {
- return isa<llvm::StoreInst>(I) &&
- I.getOperand(0) == ThisPtr.getPointer();
+ return isa<llvm::StoreInst>(I) && I.getOperand(0) == &*AI;
});
assert(ThisStore != EntryBB->end() &&
"Store of this should be in entry block?");
// Adjust "this", if necessary.
Builder.SetInsertPoint(&*ThisStore);
- llvm::Value *AdjustedThisPtr =
- CGM.getCXXABI().performThisAdjustment(*this, ThisPtr, Thunk.This);
+
+ const CXXRecordDecl *ThisValueClass = Thunk.ThisType->getPointeeCXXRecordDecl();
+ llvm::Value *AdjustedThisPtr = CGM.getCXXABI().performThisAdjustment(
+ *this, ThisPtr, ThisValueClass, Thunk);
AdjustedThisPtr = Builder.CreateBitCast(AdjustedThisPtr,
ThisStore->getOperand(0)->getType());
ThisStore->setOperand(0, AdjustedThisPtr);
@@ -302,10 +309,15 @@ void CodeGenFunction::EmitCallAndReturnForThunk(llvm::FunctionCallee Callee,
const CXXMethodDecl *MD = cast<CXXMethodDecl>(CurGD.getDecl());
// Adjust the 'this' pointer if necessary
+ const CXXRecordDecl *ThisValueClass =
+ MD->getThisType()->getPointeeCXXRecordDecl();
+ if (Thunk)
+ ThisValueClass = Thunk->ThisType->getPointeeCXXRecordDecl();
+
llvm::Value *AdjustedThisPtr =
- Thunk ? CGM.getCXXABI().performThisAdjustment(
- *this, LoadCXXThisAddress(), Thunk->This)
- : LoadCXXThis();
+ Thunk ? CGM.getCXXABI().performThisAdjustment(*this, LoadCXXThisAddress(),
+ ThisValueClass, *Thunk)
+ : LoadCXXThis();
// If perfect forwarding is required a variadic method, a method using
// inalloca, or an unprototyped thunk, use musttail. Emit an error if this
@@ -499,10 +511,22 @@ llvm::Constant *CodeGenVTables::maybeEmitThunk(GlobalDecl GD,
SmallString<256> Name;
MangleContext &MCtx = CGM.getCXXABI().getMangleContext();
llvm::raw_svector_ostream Out(Name);
- if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD))
- MCtx.mangleCXXDtorThunk(DD, GD.getDtorType(), TI.This, Out);
- else
- MCtx.mangleThunk(MD, TI, Out);
+
+ if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
+ MCtx.mangleCXXDtorThunk(DD, GD.getDtorType(), TI,
+ /* elideOverrideInfo */ false, Out);
+ } else
+ MCtx.mangleThunk(MD, TI, /* elideOverrideInfo */ false, Out);
+
+ if (CGM.getContext().useAbbreviatedThunkName(GD, Name.str())) {
+ Name = "";
+ if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD))
+ MCtx.mangleCXXDtorThunk(DD, GD.getDtorType(), TI,
+ /* elideOverrideInfo */ true, Out);
+ else
+ MCtx.mangleThunk(MD, TI, /* elideOverrideInfo */ true, Out);
+ }
+
llvm::Type *ThunkVTableTy = CGM.getTypes().GetFunctionTypeForVTable(GD);
llvm::Constant *Thunk = CGM.GetAddrOfThunk(Name, ThunkVTableTy, GD);
@@ -814,11 +838,17 @@ void CodeGenVTables::addVTableComponent(ConstantArrayBuilder &builder,
nextVTableThunkIndex++;
fnPtr = maybeEmitThunk(GD, thunkInfo, /*ForVTable=*/true);
+ if (CGM.getCodeGenOpts().PointerAuth.CXXVirtualFunctionPointers) {
+ assert(thunkInfo.Method && "Method not set");
+ GD = GD.getWithDecl(thunkInfo.Method);
+ }
// Otherwise we can use the method definition directly.
} else {
llvm::Type *fnTy = CGM.getTypes().GetFunctionTypeForVTable(GD);
fnPtr = CGM.GetAddrOfFunction(GD, fnTy, /*ForVTable=*/true);
+ if (CGM.getCodeGenOpts().PointerAuth.CXXVirtualFunctionPointers)
+ GD = getItaniumVTableContext().findOriginalMethod(GD);
}
if (useRelativeLayout()) {
@@ -836,6 +866,9 @@ void CodeGenVTables::addVTableComponent(ConstantArrayBuilder &builder,
if (FnAS != GVAS)
fnPtr =
llvm::ConstantExpr::getAddrSpaceCast(fnPtr, CGM.GlobalsInt8PtrTy);
+ if (const auto &Schema =
+ CGM.getCodeGenOpts().PointerAuth.CXXVirtualFunctionPointers)
+ return builder.addSignedPointer(fnPtr, Schema, GD, QualType());
return builder.add(fnPtr);
}
}
@@ -1045,29 +1078,41 @@ llvm::GlobalVariable::LinkageTypes
CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) {
if (!RD->isExternallyVisible())
return llvm::GlobalVariable::InternalLinkage;
-
- // We're at the end of the translation unit, so the current key
- // function is fully correct.
- const CXXMethodDecl *keyFunction = Context.getCurrentKeyFunction(RD);
- if (keyFunction && !RD->hasAttr<DLLImportAttr>()) {
+
+ // In windows, the linkage of vtable is not related to modules.
+ bool IsInNamedModule = !getTarget().getCXXABI().isMicrosoft() &&
+ RD->isInNamedModule();
+ // If the CXXRecordDecl is not in a module unit, we need to get
+ // its key function. We're at the end of the translation unit, so the current
+ // key function is fully correct.
+ const CXXMethodDecl *keyFunction =
+ IsInNamedModule ? nullptr : Context.getCurrentKeyFunction(RD);
+ if (IsInNamedModule || (keyFunction && !RD->hasAttr<DLLImportAttr>())) {
// If this class has a key function, use that to determine the
// linkage of the vtable.
const FunctionDecl *def = nullptr;
- if (keyFunction->hasBody(def))
+ if (keyFunction && keyFunction->hasBody(def))
keyFunction = cast<CXXMethodDecl>(def);
- switch (keyFunction->getTemplateSpecializationKind()) {
- case TSK_Undeclared:
- case TSK_ExplicitSpecialization:
+ bool IsExternalDefinition =
+ IsInNamedModule ? RD->shouldEmitInExternalSource() : !def;
+
+ TemplateSpecializationKind Kind =
+ IsInNamedModule ? RD->getTemplateSpecializationKind()
+ : keyFunction->getTemplateSpecializationKind();
+
+ switch (Kind) {
+ case TSK_Undeclared:
+ case TSK_ExplicitSpecialization:
assert(
- (def || CodeGenOpts.OptimizationLevel > 0 ||
+ (IsInNamedModule || def || CodeGenOpts.OptimizationLevel > 0 ||
CodeGenOpts.getDebugInfo() != llvm::codegenoptions::NoDebugInfo) &&
- "Shouldn't query vtable linkage without key function, "
- "optimizations, or debug info");
- if (!def && CodeGenOpts.OptimizationLevel > 0)
+ "Shouldn't query vtable linkage without the class in module units, "
+ "key function, optimizations, or debug info");
+ if (IsExternalDefinition && CodeGenOpts.OptimizationLevel > 0)
return llvm::GlobalVariable::AvailableExternallyLinkage;
- if (keyFunction->isInlined())
+ if (keyFunction && keyFunction->isInlined())
return !Context.getLangOpts().AppleKext
? llvm::GlobalVariable::LinkOnceODRLinkage
: llvm::Function::InternalLinkage;
@@ -1086,7 +1131,7 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) {
case TSK_ExplicitInstantiationDeclaration:
llvm_unreachable("Should not have been asked to emit this");
- }
+ }
}
// -fapple-kext mode does not support weak linkage, so we must use
@@ -1180,22 +1225,20 @@ bool CodeGenVTables::isVTableExternal(const CXXRecordDecl *RD) {
TSK == TSK_ExplicitInstantiationDefinition)
return false;
+ // Otherwise, if the class is attached to a module, the tables are uniquely
+ // emitted in the object for the module unit in which it is defined.
+ if (RD->isInNamedModule())
+ return RD->shouldEmitInExternalSource();
+
// Otherwise, if the class doesn't have a key function (possibly
// anymore), the vtable must be defined here.
const CXXMethodDecl *keyFunction = CGM.getContext().getCurrentKeyFunction(RD);
if (!keyFunction)
return false;
- const FunctionDecl *Def;
// Otherwise, if we don't have a definition of the key function, the
// vtable must be defined somewhere else.
- if (!keyFunction->hasBody(Def))
- return true;
-
- assert(Def && "The body of the key function is not assigned to Def?");
- // If the non-inline key function comes from another module unit, the vtable
- // must be defined there.
- return Def->isInAnotherModuleUnit() && !Def->isInlineSpecified();
+ return !keyFunction->hasBody();
}
/// Given that we're currently at the end of the translation unit, and