augusto2112 updated this revision to Diff 507422.
augusto2112 added a comment.
Herald added a subscriber: jdoerfert.
Fix pragma-attribute-supported-attributes-list.test
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D146595/new/
https://reviews.llvm.org/D146595
Files:
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/include/clang/Sema/Sema.h
clang/lib/CodeGen/CGDebugInfo.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaDeclAttr.cpp
clang/test/CodeGen/attr-trampoline-method.cpp
clang/test/CodeGen/attr-trampoline.c
clang/test/Misc/pragma-attribute-supported-attributes-list.test
llvm/include/llvm/IR/DIBuilder.h
llvm/lib/CodeGen/MachineOutliner.cpp
llvm/lib/IR/DIBuilder.cpp
Index: llvm/lib/IR/DIBuilder.cpp
===================================================================
--- llvm/lib/IR/DIBuilder.cpp
+++ llvm/lib/IR/DIBuilder.cpp
@@ -881,7 +881,7 @@
unsigned LineNo, DISubroutineType *Ty, unsigned VIndex, int ThisAdjustment,
DIType *VTableHolder, DINode::DIFlags Flags,
DISubprogram::DISPFlags SPFlags, DITemplateParameterArray TParams,
- DITypeArray ThrownTypes) {
+ DITypeArray ThrownTypes, StringRef TargetFuncName) {
assert(getNonCompileUnitScope(Context) &&
"Methods should have both a Context and a context that isn't "
"the compile unit.");
@@ -891,7 +891,7 @@
/*IsDistinct=*/IsDefinition, VMContext, cast<DIScope>(Context), Name,
LinkageName, F, LineNo, Ty, LineNo, VTableHolder, VIndex, ThisAdjustment,
Flags, SPFlags, IsDefinition ? CUNode : nullptr, TParams, nullptr,
- nullptr, ThrownTypes);
+ nullptr, ThrownTypes, nullptr, TargetFuncName);
if (IsDefinition)
AllSubprograms.push_back(SP);
Index: llvm/lib/CodeGen/MachineOutliner.cpp
===================================================================
--- llvm/lib/CodeGen/MachineOutliner.cpp
+++ llvm/lib/CodeGen/MachineOutliner.cpp
@@ -799,7 +799,8 @@
0, /* Line 0 is reserved for compiler-generated code. */
DINode::DIFlags::FlagArtificial /* Compiler-generated code. */,
/* Outlined code is optimized code by definition. */
- DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized);
+ DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized, nullptr,
+ nullptr, nullptr, nullptr, SP->getTargetFuncName());
// Don't add any new variables to the subprogram.
DB.finalizeSubprogram(OutlinedSP);
Index: llvm/include/llvm/IR/DIBuilder.h
===================================================================
--- llvm/include/llvm/IR/DIBuilder.h
+++ llvm/include/llvm/IR/DIBuilder.h
@@ -790,15 +790,16 @@
/// \param SPFlags Additional flags specific to subprograms.
/// \param TParams Function template parameters.
/// \param ThrownTypes Exception types this function may throw.
- DISubprogram *
- createMethod(DIScope *Scope, StringRef Name, StringRef LinkageName,
- DIFile *File, unsigned LineNo, DISubroutineType *Ty,
- unsigned VTableIndex = 0, int ThisAdjustment = 0,
- DIType *VTableHolder = nullptr,
- DINode::DIFlags Flags = DINode::FlagZero,
- DISubprogram::DISPFlags SPFlags = DISubprogram::SPFlagZero,
- DITemplateParameterArray TParams = nullptr,
- DITypeArray ThrownTypes = nullptr);
+ /// \param TargetFuncName The name of the target function if this is
+ /// a trampoline.
+ DISubprogram *createMethod(
+ DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File,
+ unsigned LineNo, DISubroutineType *Ty, unsigned VTableIndex = 0,
+ int ThisAdjustment = 0, DIType *VTableHolder = nullptr,
+ DINode::DIFlags Flags = DINode::FlagZero,
+ DISubprogram::DISPFlags SPFlags = DISubprogram::SPFlagZero,
+ DITemplateParameterArray TParams = nullptr,
+ DITypeArray ThrownTypes = nullptr, StringRef TargetFuncName = "");
/// Create common block entry for a Fortran common block.
/// \param Scope Scope of this common block.
Index: clang/test/Misc/pragma-attribute-supported-attributes-list.test
===================================================================
--- clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -185,6 +185,7 @@
// CHECK-NEXT: TargetClones (SubjectMatchRule_function)
// CHECK-NEXT: TargetVersion (SubjectMatchRule_function)
// CHECK-NEXT: TestTypestate (SubjectMatchRule_function_is_member)
+// CHECK-NEXT: Trampoline (SubjectMatchRule_function, SubjectMatchRule_objc_method)
// CHECK-NEXT: TrivialABI (SubjectMatchRule_record)
// CHECK-NEXT: Uninitialized (SubjectMatchRule_variable_is_local)
// CHECK-NEXT: UnsafeBufferUsage (SubjectMatchRule_function)
Index: clang/test/CodeGen/attr-trampoline.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/attr-trampoline.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -debug-info-kind=limited -emit-llvm -o - %s | FileCheck %s
+
+void bar(void) {}
+
+__attribute__((trampoline("bar")))
+void foo(void) {
+ bar();
+}
+
+// CHECK: DISubprogram(name: "foo"{{.*}} targetFuncName: "bar"
Index: clang/test/CodeGen/attr-trampoline-method.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGen/attr-trampoline-method.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -debug-info-kind=limited -emit-llvm -o - %s | FileCheck %s
+
+void bar(void) {}
+
+struct A {
+__attribute__((trampoline("bar")))
+void foo(void) {
+ bar();
+}
+};
+
+int main() {
+ A().foo();
+}
+
+// CHECK: DISubprogram(name: "foo"{{.*}} targetFuncName: "bar"
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -4879,6 +4879,20 @@
return ::new (Context) SwiftNameAttr(Context, SNA, Name);
}
+TrampolineAttr *Sema::mergeTrampolineAttr(Decl *D, const TrampolineAttr &TA,
+ StringRef Name) {
+ if (const auto *PrevSNA = D->getAttr<TrampolineAttr>()) {
+ if (PrevSNA->getName() != Name && !PrevSNA->isImplicit()) {
+ Diag(PrevSNA->getLocation(), diag::err_attributes_are_not_compatible)
+ << PrevSNA << &TA;
+ Diag(TA.getLoc(), diag::note_conflicting_attribute);
+ }
+
+ D->dropAttr<TrampolineAttr>();
+ }
+ return ::new (Context) TrampolineAttr(Context, TA, Name);
+}
+
OptimizeNoneAttr *Sema::mergeOptimizeNoneAttr(Decl *D,
const AttributeCommonInfo &CI) {
if (AlwaysInlineAttr *Inline = D->getAttr<AlwaysInlineAttr>()) {
@@ -6758,6 +6772,15 @@
D->addAttr(::new (S.Context) SwiftNameAttr(S.Context, AL, Name));
}
+static void handleTrampoline(Sema &S, Decl *D, const ParsedAttr &AL) {
+ StringRef Name;
+ SourceLocation Loc;
+ if (!S.checkStringLiteralArgumentAttr(AL, 0, Name, &Loc))
+ return;
+
+ D->addAttr(::new (S.Context) TrampolineAttr(S.Context, AL, Name));
+}
+
static void handleSwiftAsyncName(Sema &S, Decl *D, const ParsedAttr &AL) {
StringRef Name;
SourceLocation Loc;
@@ -9294,6 +9317,10 @@
handleSwiftAsyncError(S, D, AL);
break;
+ case ParsedAttr::AT_Trampoline:
+ handleTrampoline(S, D, AL);
+ break;
+
// XRay attributes.
case ParsedAttr::AT_XRayLogArgs:
handleXRayLogArgsAttr(S, D, AL);
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -2927,6 +2927,8 @@
NewAttr = S.mergeMinSizeAttr(D, *MA);
else if (const auto *SNA = dyn_cast<SwiftNameAttr>(Attr))
NewAttr = S.mergeSwiftNameAttr(D, *SNA, SNA->getName());
+ else if (const auto *TA = dyn_cast<TrampolineAttr>(Attr))
+ NewAttr = S.mergeTrampolineAttr(D, *TA, TA->getName());
else if (const auto *OA = dyn_cast<OptimizeNoneAttr>(Attr))
NewAttr = S.mergeOptimizeNoneAttr(D, *OA);
else if (const auto *InternalLinkageA = dyn_cast<InternalLinkageAttr>(Attr))
Index: clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.cpp
+++ clang/lib/CodeGen/CGDebugInfo.cpp
@@ -68,6 +68,14 @@
return D->hasAttr<AlignedAttr>() ? D->getMaxAlignment() : 0;
}
+static StringRef getTargetFuncName(const Decl *D) {
+ if (!D)
+ return {};
+ if (auto *Trampoline = D->getAttr<TrampolineAttr>())
+ return Trampoline->getName();
+ return {};
+}
+
CGDebugInfo::CGDebugInfo(CodeGenModule &CGM)
: CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()),
DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs),
@@ -1918,10 +1926,11 @@
completeUnusedClass(*CD->getParent());
llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(Method, Unit);
+ StringRef TargetFuncName = getTargetFuncName(Method);
llvm::DISubprogram *SP = DBuilder.createMethod(
RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine,
MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags,
- TParamsArray.get());
+ TParamsArray.get(), nullptr, TargetFuncName);
SPCache[Method->getCanonicalDecl()].reset(SP);
@@ -3849,10 +3858,12 @@
if (Stub) {
Flags |= getCallSiteRelatedAttrs();
SPFlags |= llvm::DISubprogram::SPFlagDefinition;
+ StringRef TargetFuncName = getTargetFuncName(FD);
return DBuilder.createFunction(
DContext, Name, LinkageName, Unit, Line,
getOrCreateFunctionType(GD.getDecl(), FnType, Unit), 0, Flags, SPFlags,
- TParamsArray.get(), getFunctionDeclaration(FD));
+ TParamsArray.get(), getFunctionDeclaration(FD), nullptr, nullptr,
+ TargetFuncName);
}
llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
@@ -3998,9 +4009,11 @@
if (It == TypeCache.end())
return nullptr;
auto *InterfaceType = cast<llvm::DICompositeType>(It->second);
+ StringRef TargetFuncName = getTargetFuncName(D);
llvm::DISubprogram *FD = DBuilder.createFunction(
InterfaceType, getObjCMethodName(OMD), StringRef(),
- InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
+ InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags, nullptr,
+ nullptr, nullptr, nullptr, TargetFuncName);
DBuilder.finalizeSubprogram(FD);
ObjCMethodCache[ID].push_back({FD, OMD->isDirectMethod()});
return FD;
@@ -4182,6 +4195,8 @@
Annotations = CollectBTFDeclTagAnnotations(D);
}
+ StringRef TargetFuncName = getTargetFuncName(D);
+
// FIXME: The function declaration we're constructing here is mostly reusing
// declarations from CXXMethodDecl and not constructing new ones for arbitrary
// FunctionDecls. When/if we fix this we can have FDContext be TheCU/null for
@@ -4190,7 +4205,7 @@
llvm::DISubprogram *SP = DBuilder.createFunction(
FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
FlagsForDef, SPFlagsForDef, TParamsArray.get(), Decl, nullptr,
- Annotations);
+ Annotations, TargetFuncName);
Fn->setSubprogram(SP);
// We might get here with a VarDecl in the case we're generating
// code for the initialization of globals. Do not record these decls
@@ -4251,9 +4266,11 @@
llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
- llvm::DISubprogram *SP = DBuilder.createFunction(
- FDContext, Name, LinkageName, Unit, LineNo, STy, ScopeLine, Flags,
- SPFlags, TParamsArray.get(), nullptr, nullptr, Annotations);
+ StringRef TargetFuncName = getTargetFuncName(D);
+ llvm::DISubprogram *SP =
+ DBuilder.createFunction(FDContext, Name, LinkageName, Unit, LineNo, STy,
+ ScopeLine, Flags, SPFlags, TParamsArray.get(),
+ nullptr, nullptr, Annotations, TargetFuncName);
// Preserve btf_decl_tag attributes for parameters of extern functions
// for BPF target. The parameters created in this loop are attached as
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -3668,6 +3668,8 @@
MinSizeAttr *mergeMinSizeAttr(Decl *D, const AttributeCommonInfo &CI);
SwiftNameAttr *mergeSwiftNameAttr(Decl *D, const SwiftNameAttr &SNA,
StringRef Name);
+ TrampolineAttr *mergeTrampolineAttr(Decl *D, const TrampolineAttr &TA,
+ StringRef Name);
OptimizeNoneAttr *mergeOptimizeNoneAttr(Decl *D,
const AttributeCommonInfo &CI);
InternalLinkageAttr *mergeInternalLinkageAttr(Decl *D, const ParsedAttr &AL);
Index: clang/include/clang/Basic/AttrDocs.td
===================================================================
--- clang/include/clang/Basic/AttrDocs.td
+++ clang/include/clang/Basic/AttrDocs.td
@@ -6900,6 +6900,31 @@
}];
}
+def TrampolineDocs : Documentation {
+ let Category = DocCatFunction;
+ let Heading = "trampoline";
+ let Content = [{
+The ``trampoline`` attribute indicates that the current function is a trampoline.
+The argument is the mangled name of the symbol that debuggers should jump to instead
+when entering the trampoline function.
+
+For example:
+
+.. code-block:: c
+
+ int bar(void) {
+ return 42;
+ }
+
+ __attribute__((trampoline("bar")))
+ int foo(void) {
+ return bar();
+ }
+
+Indicates to debuggers that stepping into ``foo`` should jump directly to ``bar`` instead.
+ }];
+}
+
def ReadOnlyPlacementDocs : Documentation {
let Category = DocCatType;
let Content = [{This attribute is attached to a structure, class or union declaration.
@@ -6947,3 +6972,5 @@
its underlying representation to be a WebAssembly ``funcref``.
}];
}
+
+
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -770,6 +770,13 @@
let SimpleHandler = 1;
}
+def Trampoline : InheritableAttr {
+ let Spellings = [GNU<"trampoline">];
+ let Subjects = SubjectList<[Function, ObjCMethod]>;
+ let Args = [StringArgument<"Name">];
+ let Documentation = [TrampolineDocs];
+}
+
def XRayInstrument : InheritableAttr {
let Spellings = [Clang<"xray_always_instrument">,
Clang<"xray_never_instrument">];
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits