From bf17ecf59a9bdfe00a5cb25fe59c9617f42ca79d Mon Sep 17 00:00:00 2001 From: Dmitry Polukhin Date: Wed, 9 Mar 2016 15:30:53 +0000 Subject: [GCC] PR23529 Sema part of attrbute abi_tag support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Original patch by Stefan Bühler http://reviews.llvm.org/D12834 Difference between original and this one: - fixed all comments in original code review - added more tests, all new diagnostics now covered by tests - moved abi_tag on re-declaration checks to Sema::mergeDeclAttributes where they actually may work as designed - clang-format + other stylistic changes Mangle part will be sent for review as a separate patch. Differential Revision: http://reviews.llvm.org/D17567 llvm-svn: 263015 --- clang/lib/Sema/SemaDecl.cpp | 18 ++++++++++++++++++ clang/lib/Sema/SemaDeclAttr.cpp | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) (limited to 'clang/lib') 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()) { + if (const auto *OldAbiTagAttr = Old->getAttr()) { + 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 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(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: -- cgit v1.2.3