mirror of https://github.com/microsoft/clang.git
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
This commit is contained in:
parent
a701b12944
commit
789b385fd1
|
@ -111,6 +111,9 @@ def SharedVar : SubsetSubject<Var,
|
|||
def GlobalVar : SubsetSubject<Var,
|
||||
[{S->hasGlobalStorage()}], "global variables">;
|
||||
|
||||
def InlineFunction : SubsetSubject<Function,
|
||||
[{S->isInlineSpecified()}], "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">];
|
||||
|
|
|
@ -3273,3 +3273,13 @@ For more information see
|
|||
or `msvc documentation <https://docs.microsoft.com/pl-pl/cpp/cpp/selectany>`_.
|
||||
}];
|
||||
}
|
||||
|
||||
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
|
||||
}];
|
||||
}
|
||||
|
|
|
@ -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<ArtificialAttr>()) {
|
||||
Flags |= llvm::DINode::FlagArtificial;
|
||||
// Artificial functions should not silently reuse CurLoc.
|
||||
CurLoc = SourceLocation();
|
||||
|
|
|
@ -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<ArtificialAttr>(S, D, Attr);
|
||||
break;
|
||||
case AttributeList::AT_AnalyzerNoReturn:
|
||||
handleAnalyzerNoReturnAttr(S, D, Attr);
|
||||
break;
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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}}
|
Loading…
Reference in New Issue