summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp18
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp39
2 files changed, 57 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index db741bc6e30..0c3c4399f6e 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2398,6 +2398,24 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old,
}
}
+ // Re-declaration cannot add abi_tag's.
+ if (const auto *NewAbiTagAttr = New->getAttr<AbiTagAttr>()) {
+ if (const auto *OldAbiTagAttr = Old->getAttr<AbiTagAttr>()) {
+ for (const auto &NewTag : NewAbiTagAttr->tags()) {
+ if (std::find(OldAbiTagAttr->tags_begin(), OldAbiTagAttr->tags_end(),
+ NewTag) == OldAbiTagAttr->tags_end()) {
+ Diag(NewAbiTagAttr->getLocation(),
+ diag::err_new_abi_tag_on_redeclaration)
+ << NewTag;
+ Diag(OldAbiTagAttr->getLocation(), diag::note_previous_declaration);
+ }
+ }
+ } else {
+ Diag(NewAbiTagAttr->getLocation(), diag::err_abi_tag_on_redeclaration);
+ Diag(Old->getLocation(), diag::note_previous_declaration);
+ }
+ }
+
if (!Old->hasAttrs())
return;
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 1fca27f8b95..f8cec752041 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -4615,6 +4615,42 @@ static void handleDeclspecThreadAttr(Sema &S, Decl *D,
Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex()));
}
+static void handleAbiTagAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+ SmallVector<StringRef, 4> Tags;
+ for (unsigned I = 0, E = Attr.getNumArgs(); I != E; ++I) {
+ StringRef Tag;
+ if (!S.checkStringLiteralArgumentAttr(Attr, I, Tag))
+ return;
+ Tags.push_back(Tag);
+ }
+
+ if (const auto *NS = dyn_cast<NamespaceDecl>(D)) {
+ if (!NS->isInline()) {
+ S.Diag(Attr.getLoc(), diag::warn_attr_abi_tag_namespace) << 0;
+ return;
+ }
+ if (NS->isAnonymousNamespace()) {
+ S.Diag(Attr.getLoc(), diag::warn_attr_abi_tag_namespace) << 1;
+ return;
+ }
+ if (Attr.getNumArgs() == 0)
+ Tags.push_back(NS->getName());
+ } else if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
+ return;
+
+ // Store tags sorted and without duplicates.
+ std::sort(Tags.begin(), Tags.end());
+ Tags.erase(std::unique(Tags.begin(), Tags.end()), Tags.end());
+
+ D->addAttr(::new (S.Context)
+ AbiTagAttr(Attr.getRange(), S.Context, Tags.data(), Tags.size(),
+ Attr.getAttributeSpellingListIndex()));
+
+ // FIXME: remove this warning as soon as mangled part is ready.
+ S.Diag(Attr.getRange().getBegin(), diag::warn_attribute_ignored)
+ << Attr.getName();
+}
+
static void handleARMInterruptAttr(Sema &S, Decl *D,
const AttributeList &Attr) {
// Check the attribute arguments.
@@ -5637,6 +5673,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case AttributeList::AT_Thread:
handleDeclspecThreadAttr(S, D, Attr);
break;
+ case AttributeList::AT_AbiTag:
+ handleAbiTagAttr(S, D, Attr);
+ break;
// Thread safety attributes:
case AttributeList::AT_AssertExclusiveLock:
OpenPOWER on IntegriCloud