]> granicus.if.org Git - clang/commitdiff
Add support for attribute((naked)), patch by Zoxc on cfe-commits!
authorDaniel Dunbar <daniel@zuster.org>
Wed, 29 Sep 2010 18:20:25 +0000 (18:20 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Wed, 29 Sep 2010 18:20:25 +0000 (18:20 +0000)
 - 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
include/clang/Sema/AttributeList.h
lib/CodeGen/CodeGenModule.cpp
lib/Sema/AttributeList.cpp
lib/Sema/SemaDeclAttr.cpp
test/CodeGen/attr-naked.c [new file with mode: 0644]
test/Sema/attr-naked.c [new file with mode: 0644]

index 2f2267f7f79f148a28f250820ff5e3a3f48fc40f..ae533372ad9a252bf8c347a3707efc7d2d76ac0a 100644 (file)
@@ -245,6 +245,10 @@ def MSP430Interrupt : Attr {
   let Args = [UnsignedArgument<"Number">];
 }
 
+def Naked : Attr {
+  let Spellings = ["naked"];
+}
+
 def NoDebug : Attr {
   let Spellings = ["nodebug"];
 }
index 53316477e1c5243238eaeb9989c03d202d013274..5cdfb9484e2ea371afad544e5c8426cf5fbbf4df 100644 (file)
@@ -83,6 +83,7 @@ public:
     AT_hiding,
     AT_malloc,
     AT_mode,
+    AT_naked,
     AT_nodebug,
     AT_noinline,
     AT_no_instrument_function,
index 805b33e32472ff6a772c6acf3687e0c09ff825cb..12c8f7919fa7b704efaddff7b94187e19048a253 100644 (file)
@@ -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);
 
index 8ccb2ca586eb49703920c084cba1231f283d716d..c23e1ddfb09450ecccf64b2d0ff73eb0db57f0b2 100644 (file)
@@ -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)
index 682a430ee40638c217d24039338db0a6e608f769..9800db09e30251a2a1b21e339ed00f7d4db2bbbe 100644 (file)
@@ -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/test/CodeGen/attr-naked.c b/test/CodeGen/attr-naked.c
new file mode 100644 (file)
index 0000000..bccacc9
--- /dev/null
@@ -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 (file)
index 0000000..7f18198
--- /dev/null
@@ -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)}}
+