diff options
author | Dmitry Polukhin <dmitry.polukhin@gmail.com> | 2016-04-11 07:48:59 +0000 |
---|---|---|
committer | Dmitry Polukhin <dmitry.polukhin@gmail.com> | 2016-04-11 07:48:59 +0000 |
commit | 85eda12d093714bfc9f266d50254e82888c9e8c3 (patch) | |
tree | 9216c6a571a665d295ab1d8f783c27e121c349a4 /clang/lib/Sema | |
parent | bbffeac569e89a61201ce159790f68b8493042b6 (diff) | |
download | bcm5719-llvm-85eda12d093714bfc9f266d50254e82888c9e8c3.tar.gz bcm5719-llvm-85eda12d093714bfc9f266d50254e82888c9e8c3.zip |
[GCC] Attribute ifunc support in clang
This patch add support for GCC attribute((ifunc("resolver"))) for
targets that use ELF as object file format. In general ifunc is a
special kind of function alias with type @gnu_indirect_function. LLVM
patch http://reviews.llvm.org/D15525
Differential Revision: http://reviews.llvm.org/D15524
llvm-svn: 265917
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 29 |
2 files changed, 29 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 35682943907..b0e79f6f0e7 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2299,7 +2299,7 @@ static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) { for (unsigned I = 0, E = NewAttributes.size(); I != E;) { const Attr *NewAttribute = NewAttributes[I]; - if (isa<AliasAttr>(NewAttribute)) { + if (isa<AliasAttr>(NewAttribute) || isa<IFuncAttr>(NewAttribute)) { if (FunctionDecl *FD = dyn_cast<FunctionDecl>(New)) { Sema::SkipBodyInfo SkipBody; S.CheckForFunctionRedefinition(FD, cast<FunctionDecl>(Def), &SkipBody); @@ -5464,7 +5464,7 @@ static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) { if (const auto *Attr = VD->getAttr<AliasAttr>()) { assert(VD->isThisDeclarationADefinition() && !VD->isExternallyVisible() && "Broken AliasAttr handled late!"); - S.Diag(Attr->getLocation(), diag::err_alias_is_definition) << VD; + S.Diag(Attr->getLocation(), diag::err_alias_is_definition) << VD << 0; VD->dropAttr<AliasAttr>(); } } diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 9066e761ad6..0ba9799d042 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -1548,6 +1548,28 @@ static void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) { Attr.getAttributeSpellingListIndex())); } +static void handleIFuncAttr(Sema &S, Decl *D, const AttributeList &Attr) { + StringRef Str; + if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str)) + return; + + // Aliases should be on declarations, not definitions. + const auto *FD = cast<FunctionDecl>(D); + if (FD->isThisDeclarationADefinition()) { + S.Diag(Attr.getLoc(), diag::err_alias_is_definition) << FD << 1; + return; + } + // FIXME: it should be handled as a target specific attribute. + if (S.Context.getTargetInfo().getTriple().getObjectFormat() != + llvm::Triple::ELF) { + S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); + return; + } + + D->addAttr(::new (S.Context) IFuncAttr(Attr.getRange(), S.Context, Str, + Attr.getAttributeSpellingListIndex())); +} + static void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { StringRef Str; if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str)) @@ -1564,13 +1586,13 @@ static void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { // Aliases should be on declarations, not definitions. if (const auto *FD = dyn_cast<FunctionDecl>(D)) { if (FD->isThisDeclarationADefinition()) { - S.Diag(Attr.getLoc(), diag::err_alias_is_definition) << FD; + S.Diag(Attr.getLoc(), diag::err_alias_is_definition) << FD << 0; return; } } else { const auto *VD = cast<VarDecl>(D); if (VD->isThisDeclarationADefinition() && VD->isExternallyVisible()) { - S.Diag(Attr.getLoc(), diag::err_alias_is_definition) << VD; + S.Diag(Attr.getLoc(), diag::err_alias_is_definition) << VD << 0; return; } } @@ -5373,6 +5395,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case AttributeList::AT_IBOutletCollection: handleIBOutletCollection(S, D, Attr); break; + case AttributeList::AT_IFunc: + handleIFuncAttr(S, D, Attr); + break; case AttributeList::AT_Alias: handleAliasAttr(S, D, Attr); break; |