From dd0cb22bd62e1e835327f478a2dbf0b8fa439713 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Wed, 29 Sep 2010 18:20:25 +0000 Subject: [PATCH] Add support for attribute((naked)), patch by Zoxc on cfe-commits! - Minor style tweaks by me. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@115056 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/Attr.td | 4 ++++ include/clang/Sema/AttributeList.h | 1 + lib/CodeGen/CodeGenModule.cpp | 3 +++ lib/Sema/AttributeList.cpp | 1 + lib/Sema/SemaDeclAttr.cpp | 24 +++++++++++++++++++++--- test/CodeGen/attr-naked.c | 9 +++++++++ test/Sema/attr-naked.c | 8 ++++++++ 7 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 test/CodeGen/attr-naked.c create mode 100644 test/Sema/attr-naked.c diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index 2f2267f7f7..ae533372ad 100644 --- a/include/clang/Basic/Attr.td +++ b/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/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h index 53316477e1..5cdfb9484e 100644 --- a/include/clang/Sema/AttributeList.h +++ b/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/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 805b33e324..12c8f7919f 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -457,6 +457,9 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, if (D->hasAttr()) F->addFnAttr(llvm::Attribute::AlwaysInline); + if (D->hasAttr()) + F->addFnAttr(llvm::Attribute::Naked); + if (D->hasAttr()) F->addFnAttr(llvm::Attribute::NoInline); diff --git a/lib/Sema/AttributeList.cpp b/lib/Sema/AttributeList.cpp index 8ccb2ca586..c23e1ddfb0 100644 --- a/lib/Sema/AttributeList.cpp +++ b/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/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 682a430ee4..9800db09e3 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/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(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(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/test/CodeGen/attr-naked.c b/test/CodeGen/attr-naked.c new file mode 100644 index 0000000000..bccacc9916 --- /dev/null +++ b/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/test/Sema/attr-naked.c b/test/Sema/attr-naked.c new file mode 100644 index 0000000000..7f181981f3 --- /dev/null +++ b/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)}} + -- 2.40.0