diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/Basic/Attr.td | 4 | ||||
| -rw-r--r-- | clang/include/clang/Sema/AttributeList.h | 1 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/AttributeList.cpp | 1 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 24 | ||||
| -rw-r--r-- | clang/test/CodeGen/attr-naked.c | 9 | ||||
| -rw-r--r-- | clang/test/Sema/attr-naked.c | 8 | 
7 files changed, 47 insertions, 3 deletions
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 2f2267f7f79..ae533372ad9 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -245,6 +245,10 @@ def MSP430Interrupt : Attr {    let Args = [UnsignedArgument<"Number">];  } +def Naked : Attr { +  let Spellings = ["naked"]; +} +  def NoDebug : Attr {    let Spellings = ["nodebug"];  } diff --git a/clang/include/clang/Sema/AttributeList.h b/clang/include/clang/Sema/AttributeList.h index 53316477e1c..5cdfb9484e2 100644 --- a/clang/include/clang/Sema/AttributeList.h +++ b/clang/include/clang/Sema/AttributeList.h @@ -83,6 +83,7 @@ public:      AT_hiding,      AT_malloc,      AT_mode, +    AT_naked,      AT_nodebug,      AT_noinline,      AT_no_instrument_function, diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 805b33e3247..12c8f7919fa 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -457,6 +457,9 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,    if (D->hasAttr<AlwaysInlineAttr>())      F->addFnAttr(llvm::Attribute::AlwaysInline); +  if (D->hasAttr<NakedAttr>()) +    F->addFnAttr(llvm::Attribute::Naked); +    if (D->hasAttr<NoInlineAttr>())      F->addFnAttr(llvm::Attribute::NoInline); diff --git a/clang/lib/Sema/AttributeList.cpp b/clang/lib/Sema/AttributeList.cpp index 8ccb2ca586e..c23e1ddfb09 100644 --- a/clang/lib/Sema/AttributeList.cpp +++ b/clang/lib/Sema/AttributeList.cpp @@ -73,6 +73,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {      .Case("unused", AT_unused)      .Case("aligned", AT_aligned)      .Case("cleanup", AT_cleanup) +    .Case("naked", AT_naked)      .Case("nodebug", AT_nodebug)      .Case("nonnull", AT_nonnull)      .Case("nothrow", AT_nothrow) diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 682a430ee40..9800db09e30 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -650,9 +650,26 @@ static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {    d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, Str->getString()));  } +static void HandleNakedAttr(Decl *d, const AttributeList &Attr, +                                   Sema &S) { +  // Check the attribute arguments. +  if (Attr.getNumArgs() != 0) { +    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; +    return; +  } + +  if (!isa<FunctionDecl>(d)) { +    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) +      << Attr.getName() << 0 /*function*/; +    return; +  } + +  d->addAttr(::new (S.Context) NakedAttr(Attr.getLoc(), S.Context)); +} +  static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,                                     Sema &S) { -  // check the attribute arguments. +  // Check the attribute arguments.    if (Attr.getNumArgs() != 0) {      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;      return; @@ -660,7 +677,7 @@ static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,    if (!isa<FunctionDecl>(d)) {      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) -    << Attr.getName() << 0 /*function*/; +      << Attr.getName() << 0 /*function*/;      return;    } @@ -668,7 +685,7 @@ static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,  }  static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) { -  // check the attribute arguments. +  // Check the attribute arguments.    if (Attr.getNumArgs() != 0) {      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;      return; @@ -2281,6 +2298,7 @@ static void ProcessDeclAttribute(Scope *scope, Decl *D,    case AttributeList::AT_ownership_takes:    case AttributeList::AT_ownership_holds:        HandleOwnershipAttr     (D, Attr, S); break; +  case AttributeList::AT_naked:       HandleNakedAttr       (D, Attr, S); break;    case AttributeList::AT_noreturn:    HandleNoReturnAttr    (D, Attr, S); break;    case AttributeList::AT_nothrow:     HandleNothrowAttr     (D, Attr, S); break;    case AttributeList::AT_override:    HandleOverrideAttr    (D, Attr, S); break; diff --git a/clang/test/CodeGen/attr-naked.c b/clang/test/CodeGen/attr-naked.c new file mode 100644 index 00000000000..bccacc9916f --- /dev/null +++ b/clang/test/CodeGen/attr-naked.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -g -emit-llvm -o %t %s +// RUN: grep 'naked' %t + +void t1() __attribute__((naked)); + +void t1() +{ +} + diff --git a/clang/test/Sema/attr-naked.c b/clang/test/Sema/attr-naked.c new file mode 100644 index 00000000000..7f181981f32 --- /dev/null +++ b/clang/test/Sema/attr-naked.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -verify -fsyntax-only + +int a __attribute__((naked)); // expected-warning {{'naked' attribute only applies to function types}} + +void t1() __attribute__((naked)); + +void t2() __attribute__((naked(2))); // expected-error {{attribute requires 0 argument(s)}} +  | 

