diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-02-12 17:28:23 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-02-12 17:28:23 +0000 |
commit | 648bf78333bac59a3e5106a87324952b9cfa70cb (patch) | |
tree | d81ffaac99e5c2efbb877fcaf426e4e467ec551a /clang | |
parent | 90880e2598ec267d85e7b8cb90f65a9b42dc3c99 (diff) | |
download | bcm5719-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.h | 15 | ||||
-rw-r--r-- | clang/include/clang/Parse/AttributeList.h | 1 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Parse/AttributeList.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 21 | ||||
-rw-r--r-- | clang/test/CodeGen/attributes.c | 14 |
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 }; |