mirror of
https://github.com/intel/llvm.git
synced 2026-01-26 03:56:16 +08:00
Support __attribute__(section(<name>))
llvm-svn: 64380
This commit is contained in:
@@ -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) {}
|
||||
|
||||
@@ -65,6 +65,7 @@ public:
|
||||
AT_overloadable, // Clang-specific
|
||||
AT_packed,
|
||||
AT_pure,
|
||||
AT_section,
|
||||
AT_stdcall,
|
||||
AT_transparent_union,
|
||||
AT_unavailable,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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, "nonnull", 7)) return AT_nonnull;
|
||||
if (!memcmp(Str, "objc_gc", 7)) return AT_objc_gc;
|
||||
if (!memcmp(Str, "stdcall", 7)) return AT_stdcall;
|
||||
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;
|
||||
break;
|
||||
case 8:
|
||||
if (!memcmp(Str, "annotate", 8)) return AT_annotate;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 };
|
||||
|
||||
Reference in New Issue
Block a user