diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2086,6 +2086,13 @@ let Documentation = [NoThrowDocs]; } +def NoUwtable : InheritableAttr { + let Spellings = [Clang<"nouwtable">]; + let Subjects = SubjectList<[FunctionLike]>; + let Documentation = [NoUwtableDocs]; + let SimpleHandler = 1; +} + def NvWeak : IgnoredAttr { // No Declspec spelling of this attribute; the CUDA headers use // __attribute__((nv_weak)) unconditionally. Does not receive an [[]] diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -4537,6 +4537,16 @@ }]; } +def NoUwtableDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +Clang supports the ``nouwtable`` attribute which skips emitting +the unwind table entry for the specified function. This attribute is useful for +selectively emitting the unwind table entry on some functions when building with +``-funwind-tables`` compiler option. + }]; +} + def InternalLinkageDocs : Documentation { let Category = DocCatFunction; let Content = [{ diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1942,7 +1942,7 @@ llvm::Function *F) { llvm::AttrBuilder B(F->getContext()); - if (CodeGenOpts.UnwindTables) + if ((!D || !D->hasAttr()) && CodeGenOpts.UnwindTables) B.addUWTableAttr(llvm::UWTableKind(CodeGenOpts.UnwindTables)); if (CodeGenOpts.StackClashProtector) diff --git a/clang/test/CodeGen/attr-nouwtable.c b/clang/test/CodeGen/attr-nouwtable.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/attr-nouwtable.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -funwind-tables=2 -S -emit-llvm %s -o - | FileCheck %s + +__attribute__((nouwtable)) +int test1(void) { return 0; } + +// CHECK: @test1{{.*}}[[ATTR1:#[0-9]+]] +// CHECK: attributes [[ATTR1]] = { +// CHECK-NOT: uwtable +// CHECK: } diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -114,6 +114,7 @@ // CHECK-NEXT: NoStackProtector (SubjectMatchRule_function) // CHECK-NEXT: NoThreadSafetyAnalysis (SubjectMatchRule_function) // CHECK-NEXT: NoThrow (SubjectMatchRule_hasType_functionType) +// CHECK-NEXT: NoUwtable (SubjectMatchRule_hasType_functionType) // CHECK-NEXT: NotTailCalled (SubjectMatchRule_function) // CHECK-NEXT: OSConsumed (SubjectMatchRule_variable_is_parameter) // CHECK-NEXT: OSReturnsNotRetained (SubjectMatchRule_function, SubjectMatchRule_objc_method, SubjectMatchRule_objc_property, SubjectMatchRule_variable_is_parameter)