]> granicus.if.org Git - clang/commitdiff
Support __attribute__(section(<name>))
authorDaniel Dunbar <daniel@zuster.org>
Thu, 12 Feb 2009 17:28:23 +0000 (17:28 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Thu, 12 Feb 2009 17:28:23 +0000 (17:28 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64380 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Attr.h
include/clang/Parse/AttributeList.h
lib/CodeGen/CodeGenModule.cpp
lib/Parse/AttributeList.cpp
lib/Sema/SemaDeclAttr.cpp
test/CodeGen/attributes.c

index d446a352fb1ed84a78e99601e282cff9866e134f..328ba5764ad994cd8d322bc579e9d2a0fb26ea32 100644 (file)
@@ -45,6 +45,7 @@ public:
     ObjCNSObject,
     Overloadable, // Clang-specific
     Packed,
+    Section,
     StdCall,
     TransparentUnion,
     Unavailable,
@@ -227,6 +228,20 @@ public:
   static bool classof(const DeprecatedAttr *A) { return true; }
 };
 
+class SectionAttr : public Attr {
+  std::string Name;
+public:
+  SectionAttr(const std::string &N) : Attr(Section), Name(N) {}
+  
+  const std::string& getName() const { return Name; }
+  
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) {
+    return A->getKind() == Section;
+  }
+  static bool classof(const SectionAttr *A) { return true; }
+};
+
 class UnavailableAttr : public Attr {
 public:
   UnavailableAttr() : Attr(Unavailable) {}
index 147fa1bd56ce141230dcdf791138524267d48d2d..56f30d38f437027d8238d8f3265841ee6e56989c 100644 (file)
@@ -65,6 +65,7 @@ public:
     AT_overloadable,      // Clang-specific
     AT_packed,
     AT_pure,
+    AT_section,
     AT_stdcall,
     AT_transparent_union,
     AT_unavailable,
index 7b939e29706fb29949671f5d74519bc616675d42..7192e9db2f257a2646848650c031273c9314bd05 100644 (file)
@@ -259,6 +259,9 @@ static void SetGlobalValueAttributes(const Decl *D,
     // should not be munged.
     GV->setName("\01" + ALA->getLabel());
   }
+
+  if (const SectionAttr *SA = D->getAttr<SectionAttr>())
+    GV->setSection(SA->getName());
 }
 
 void CodeGenModule::SetFunctionAttributes(const Decl *D,
@@ -653,6 +656,9 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
     }
   }
 
+  if (const SectionAttr *SA = D->getAttr<SectionAttr>())
+    GV->setSection(SA->getName());
+
   // Emit global variable debug information.
   CGDebugInfo *DI = getDebugInfo();
   if(DI) {
index 954e93e056a97ee74674991869492f7ffaa18ddc..c540da74f15465ad4d535859adef0cc0501c976e 100644 (file)
@@ -69,11 +69,12 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
     break;
   case 7:
     if (!memcmp(Str, "aligned", 7)) return AT_aligned;
-    if (!memcmp(Str, "nothrow", 7)) return AT_nothrow;
+    if (!memcmp(Str, "cleanup", 7)) return AT_cleanup;
     if (!memcmp(Str, "nonnull", 7)) return AT_nonnull;
+    if (!memcmp(Str, "nothrow", 7)) return AT_nothrow;
     if (!memcmp(Str, "objc_gc", 7)) return AT_objc_gc;
+    if (!memcmp(Str, "section", 7)) return AT_section;
     if (!memcmp(Str, "stdcall", 7)) return AT_stdcall;
-    if (!memcmp(Str, "cleanup", 7)) return AT_cleanup;
     break;
   case 8:
     if (!memcmp(Str, "annotate", 8)) return AT_annotate;
index b4e3dd99ac7747194e07e533072965f37b60aed3..c27df2bdeb1e89a2ebb485239a74b3d2c41658b4 100644 (file)
@@ -784,6 +784,26 @@ static void HandleDLLExportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   d->addAttr(new DLLExportAttr());
 }
 
+static void HandleSectionAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // Attribute has no arguments.
+  if (Attr.getNumArgs() != 1) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+    return;
+  }
+
+  // Make sure that there is a string literal as the sections's single
+  // argument.
+  StringLiteral *SE = 
+    dyn_cast<StringLiteral>(static_cast<Expr *>(Attr.getArg(0)));
+  if (!SE) {
+    // FIXME
+    S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
+    return;
+  }
+  d->addAttr(new SectionAttr(std::string(SE->getStrData(),
+                                         SE->getByteLength())));
+}
+
 static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   // Attribute has no arguments.
   if (Attr.getNumArgs() != 0) {
@@ -1306,6 +1326,7 @@ static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
   case AttributeList::AT_noreturn:    HandleNoReturnAttr  (D, Attr, S); break;
   case AttributeList::AT_nothrow:     HandleNothrowAttr   (D, Attr, S); break;
   case AttributeList::AT_packed:      HandlePackedAttr    (D, Attr, S); break;
+  case AttributeList::AT_section:     HandleSectionAttr   (D, Attr, S); break;
   case AttributeList::AT_stdcall:     HandleStdCallAttr   (D, Attr, S); break;
   case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break;
   case AttributeList::AT_unused:      HandleUnusedAttr    (D, Attr, S); break;
index 45b0cebf792b56e0a15aa294f4ea7c957b448561..aa4e3efb1d50ebedae9ae34d50f0d0c3112f425c 100644 (file)
@@ -7,7 +7,11 @@
 // RUN: grep 't6.*protected' %t &&
 // RUN: grep 't7.*noreturn' %t &&
 // RUN: grep 't7.*nounwind' %t &&
-// RUN: grep 't9.*alias.*weak.*t8' %t
+// RUN: grep 't9.*alias.*weak.*t8' %t &&
+// RUN: grep '@t10().*section "SECT"' %t &&
+// RUN: grep '@t11().*section "SECT"' %t &&
+// RUN: grep '@t12 =.*section "SECT"' %t &&
+// RUN: grep '@t13 =.*section "SECT"' %t
 
 void t1() __attribute__((noreturn));
 void t1() {}
@@ -30,3 +34,11 @@ void t7() {}
 
 void __t8() {}
 void t9() __attribute__((weak, alias("__t8")));
+
+void t10(void) __attribute__((section("SECT")));
+void t10(void) {}
+void __attribute__((section("SECT"))) t11(void) {}
+
+int t12 __attribute__((section("SECT")));
+struct s0 { int x; };
+struct s0 t13 __attribute__ ((section ("SECT"))) = { 0 };