summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorDmitry Polukhin <dmitry.polukhin@gmail.com>2016-04-11 07:48:59 +0000
committerDmitry Polukhin <dmitry.polukhin@gmail.com>2016-04-11 07:48:59 +0000
commit85eda12d093714bfc9f266d50254e82888c9e8c3 (patch)
tree9216c6a571a665d295ab1d8f783c27e121c349a4 /clang/lib/Sema
parentbbffeac569e89a61201ce159790f68b8493042b6 (diff)
downloadbcm5719-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.cpp4
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp29
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;
OpenPOWER on IntegriCloud