summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-02-12 17:28:23 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-02-12 17:28:23 +0000
commit648bf78333bac59a3e5106a87324952b9cfa70cb (patch)
treed81ffaac99e5c2efbb877fcaf426e4e467ec551a /clang
parent90880e2598ec267d85e7b8cb90f65a9b42dc3c99 (diff)
downloadbcm5719-llvm-648bf78333bac59a3e5106a87324952b9cfa70cb.tar.gz
bcm5719-llvm-648bf78333bac59a3e5106a87324952b9cfa70cb.zip
Support __attribute__(section(<name>))
llvm-svn: 64380
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/AST/Attr.h15
-rw-r--r--clang/include/clang/Parse/AttributeList.h1
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp6
-rw-r--r--clang/lib/Parse/AttributeList.cpp5
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp21
-rw-r--r--clang/test/CodeGen/attributes.c14
6 files changed, 59 insertions, 3 deletions
diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h
index d446a352fb1..328ba5764ad 100644
--- a/clang/include/clang/AST/Attr.h
+++ b/clang/include/clang/AST/Attr.h
@@ -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) {}
diff --git a/clang/include/clang/Parse/AttributeList.h b/clang/include/clang/Parse/AttributeList.h
index 147fa1bd56c..56f30d38f43 100644
--- a/clang/include/clang/Parse/AttributeList.h
+++ b/clang/include/clang/Parse/AttributeList.h
@@ -65,6 +65,7 @@ public:
AT_overloadable, // Clang-specific
AT_packed,
AT_pure,
+ AT_section,
AT_stdcall,
AT_transparent_union,
AT_unavailable,
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 7b939e29706..7192e9db2f2 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -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) {
diff --git a/clang/lib/Parse/AttributeList.cpp b/clang/lib/Parse/AttributeList.cpp
index 954e93e056a..c540da74f15 100644
--- a/clang/lib/Parse/AttributeList.cpp
+++ b/clang/lib/Parse/AttributeList.cpp
@@ -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;
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index b4e3dd99ac7..c27df2bdeb1 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -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;
diff --git a/clang/test/CodeGen/attributes.c b/clang/test/CodeGen/attributes.c
index 45b0cebf792..aa4e3efb1d5 100644
--- a/clang/test/CodeGen/attributes.c
+++ b/clang/test/CodeGen/attributes.c
@@ -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 };
OpenPOWER on IntegriCloud