From 789b385fd15c27c91e621faf571e2f6ff060208c Mon Sep 17 00:00:00 2001 From: Erich Keane Date: Wed, 14 Feb 2018 00:14:07 +0000 Subject: [PATCH] Implement function attribute artificial Added support in clang for GCC function attribute 'artificial'. This attribute is used to control stepping behavior of debugger with respect to inline functions. Patch By: Elizabeth Andrews (eandrews) Differential Revision: https://reviews.llvm.org/D43259 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@325081 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/Attr.td | 9 +++++++++ include/clang/Basic/AttrDocs.td | 10 ++++++++++ lib/CodeGen/CGDebugInfo.cpp | 2 +- lib/Sema/SemaDeclAttr.cpp | 3 +++ test/CodeGen/artificial.c | 10 ++++++++++ test/Sema/artificial.c | 4 ++++ 6 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 test/CodeGen/artificial.c create mode 100644 test/Sema/artificial.c diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index c3a4d4b058..3e72700d33 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -111,6 +111,9 @@ def SharedVar : SubsetSubjecthasGlobalStorage()}], "global variables">; +def InlineFunction : SubsetSubjectisInlineSpecified()}], "inline functions">; + // FIXME: this hack is needed because DeclNodes.td defines the base Decl node // type to be a class, not a definition. This makes it impossible to create an // attribute subject which accepts a Decl. Normally, this is not a problem, @@ -588,6 +591,12 @@ def AlwaysInline : InheritableAttr { let Documentation = [Undocumented]; } +def Artificial : InheritableAttr { + let Spellings = [GCC<"artificial">]; + let Subjects = SubjectList<[InlineFunction], WarnDiag>; + let Documentation = [ArtificialDocs]; +} + def XRayInstrument : InheritableAttr { let Spellings = [Clang<"xray_always_instrument">, Clang<"xray_never_instrument">]; diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td index fcb716a97c..881c9b6daf 100644 --- a/include/clang/Basic/AttrDocs.td +++ b/include/clang/Basic/AttrDocs.td @@ -3273,3 +3273,13 @@ For more information see or `msvc documentation `_. }]; } + +def ArtificialDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +The ``artificial`` attribute is used with inline functions to treat the inline +function as a unit while debugging. For more information see GCC_ documentation. + +.. _GCC: https://gcc.gnu.org/onlinedocs/gcc-4.6.4/gcc/Function-Attributes.html + }]; +} diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 412570b0d8..bed531eac3 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -3235,7 +3235,7 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, SourceLocation Loc, if (Name.startswith("\01")) Name = Name.substr(1); - if (!HasDecl || D->isImplicit()) { + if (!HasDecl || D->isImplicit() || D->hasAttr()) { Flags |= llvm::DINode::FlagArtificial; // Artificial functions should not silently reuse CurLoc. CurLoc = SourceLocation(); diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index a5eade8a84..cb6b030b71 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -6057,6 +6057,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case AttributeList::AT_AlwaysInline: handleAlwaysInlineAttr(S, D, Attr); break; + case AttributeList::AT_Artificial: + handleSimpleAttribute(S, D, Attr); + break; case AttributeList::AT_AnalyzerNoReturn: handleAnalyzerNoReturnAttr(S, D, Attr); break; diff --git a/test/CodeGen/artificial.c b/test/CodeGen/artificial.c new file mode 100644 index 0000000000..5db6a67194 --- /dev/null +++ b/test/CodeGen/artificial.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s + +extern void foo(); +// CHECK: !DISubprogram(name: "foo" +// CHECK-SAME: flags: DIFlagArtificial +inline void __attribute__((artificial)) foo() {} + +void baz() { + foo(); +} diff --git a/test/Sema/artificial.c b/test/Sema/artificial.c new file mode 100644 index 0000000000..076a61ca0f --- /dev/null +++ b/test/Sema/artificial.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +inline void __attribute__((artificial)) foo() {} +void __attribute__((artificial)) bar() {} // expected-warning {{'artificial' attribute only applies to inline functions}} -- 2.50.1