Author: aaronballman Date: Wed Oct 24 05:26:23 2018 New Revision: 345132 URL: http://llvm.org/viewvc/llvm-project?rev=345132&view=rev Log: Support accepting __gnu__ as a scoped attribute namespace that aliases to gnu.
This is useful in libstdc++ to avoid clashes with identifiers in the user's namespace. Modified: cfe/trunk/include/clang/Sema/ParsedAttr.h cfe/trunk/lib/Basic/Attributes.cpp cfe/trunk/lib/Parse/ParseDeclCXX.cpp cfe/trunk/lib/Sema/ParsedAttr.cpp cfe/trunk/lib/Sema/SemaDeclAttr.cpp cfe/trunk/lib/Sema/SemaType.cpp cfe/trunk/test/Preprocessor/has_attribute.cpp cfe/trunk/test/SemaCXX/attr-gnu.cpp cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Modified: cfe/trunk/include/clang/Sema/ParsedAttr.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ParsedAttr.h?rev=345132&r1=345131&r2=345132&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/ParsedAttr.h (original) +++ cfe/trunk/include/clang/Sema/ParsedAttr.h Wed Oct 24 05:26:23 2018 @@ -383,6 +383,11 @@ public: IdentifierInfo *getScopeName() const { return ScopeName; } SourceLocation getScopeLoc() const { return ScopeLoc; } + bool isGNUScope() const { + return ScopeName && + (ScopeName->isStr("gnu") || ScopeName->isStr("__gnu__")); + } + bool hasParsedType() const { return HasParsedType; } /// Is this the Microsoft __declspec(property) attribute? Modified: cfe/trunk/lib/Basic/Attributes.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Attributes.cpp?rev=345132&r1=345131&r2=345132&view=diff ============================================================================== --- cfe/trunk/lib/Basic/Attributes.cpp (original) +++ cfe/trunk/lib/Basic/Attributes.cpp Wed Oct 24 05:26:23 2018 @@ -9,12 +9,17 @@ int clang::hasAttribute(AttrSyntax Synta const LangOptions &LangOpts) { StringRef Name = Attr->getName(); // Normalize the attribute name, __foo__ becomes foo. - if (Name.size() >= 4 && Name.startswith("__") && Name.endswith("__")) - Name = Name.substr(2, Name.size() - 4); - -#include "clang/Basic/AttrHasAttributeImpl.inc" - - return 0; + if (Name.size() >= 4 && Name.startswith("__") && Name.endswith("__")) + Name = Name.substr(2, Name.size() - 4); + + // Normalize the scope name, but only for gnu attributes. + StringRef ScopeName = Scope ? Scope->getName() : ""; + if (ScopeName == "__gnu__") + ScopeName = ScopeName.slice(2, ScopeName.size() - 2); + +#include "clang/Basic/AttrHasAttributeImpl.inc" + + return 0; } const char *attr::getSubjectMatchRuleSpelling(attr::SubjectMatchRule Rule) { Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=345132&r1=345131&r2=345132&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original) +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Wed Oct 24 05:26:23 2018 @@ -3865,13 +3865,14 @@ bool Parser::ParseCXX11AttributeArgs(Ide // Eat the left paren, then skip to the ending right paren. ConsumeParen(); SkipUntil(tok::r_paren); - return false; - } - - if (ScopeName && ScopeName->getName() == "gnu") { - // GNU-scoped attributes have some special cases to handle GNU-specific - // behaviors. - ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName, + return false; + } + + if (ScopeName && + (ScopeName->getName() == "gnu" || ScopeName->getName() == "__gnu__")) { + // GNU-scoped attributes have some special cases to handle GNU-specific + // behaviors. + ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName, ScopeLoc, Syntax, nullptr); return true; } Modified: cfe/trunk/lib/Sema/ParsedAttr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/ParsedAttr.cpp?rev=345132&r1=345131&r2=345132&view=diff ============================================================================== --- cfe/trunk/lib/Sema/ParsedAttr.cpp (original) +++ cfe/trunk/lib/Sema/ParsedAttr.cpp Wed Oct 24 05:26:23 2018 @@ -103,14 +103,25 @@ void AttributePool::takePool(AttributePo #include "clang/Sema/AttrParsedAttrKinds.inc" -static StringRef normalizeAttrName(StringRef AttrName, StringRef ScopeName, +static StringRef normalizeAttrScopeName(StringRef ScopeName, + ParsedAttr::Syntax SyntaxUsed) { + // We currently only normalize the "__gnu__" scope name to be "gnu". + if ((SyntaxUsed == ParsedAttr::AS_CXX11 || + SyntaxUsed == ParsedAttr::AS_C2x) && + ScopeName == "__gnu__") + ScopeName = ScopeName.slice(2, ScopeName.size() - 2); + return ScopeName; +} + +static StringRef normalizeAttrName(StringRef AttrName, + StringRef NormalizedScopeName, ParsedAttr::Syntax SyntaxUsed) { // Normalize the attribute name, __foo__ becomes foo. This is only allowable - // for GNU attributes. + // for GNU attributes, and attributes using the double square bracket syntax. bool IsGNU = SyntaxUsed == ParsedAttr::AS_GNU || ((SyntaxUsed == ParsedAttr::AS_CXX11 || SyntaxUsed == ParsedAttr::AS_C2x) && - ScopeName == "gnu"); + NormalizedScopeName == "gnu"); if (IsGNU && AttrName.size() >= 4 && AttrName.startswith("__") && AttrName.endswith("__")) AttrName = AttrName.slice(2, AttrName.size() - 2); @@ -125,7 +136,7 @@ ParsedAttr::Kind ParsedAttr::getKind(con SmallString<64> FullName; if (ScopeName) - FullName += ScopeName->getName(); + FullName += normalizeAttrScopeName(ScopeName->getName(), SyntaxUsed); AttrName = normalizeAttrName(AttrName, FullName, SyntaxUsed); @@ -141,9 +152,10 @@ ParsedAttr::Kind ParsedAttr::getKind(con unsigned ParsedAttr::getAttributeSpellingListIndex() const { // Both variables will be used in tablegen generated // attribute spell list index matching code. - StringRef Scope = ScopeName ? ScopeName->getName() : ""; - StringRef Name = normalizeAttrName(AttrName->getName(), Scope, - (ParsedAttr::Syntax)SyntaxUsed); + auto Syntax = static_cast<ParsedAttr::Syntax>(SyntaxUsed); + StringRef Scope = + ScopeName ? normalizeAttrScopeName(ScopeName->getName(), Syntax) : ""; + StringRef Name = normalizeAttrName(AttrName->getName(), Scope, Syntax); #include "clang/Sema/AttrSpellingListIndex.inc" Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=345132&r1=345131&r2=345132&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Wed Oct 24 05:26:23 2018 @@ -5831,16 +5831,14 @@ static void handleDeprecatedAttr(Sema &S if (AL.isDeclspecAttribute() || AL.isCXX11Attribute()) checkAttributeAtMostNumArgs(S, AL, 1); else if (AL.isArgExpr(1) && AL.getArgAsExpr(1) && - !S.checkStringLiteralArgumentAttr(AL, 1, Replacement)) - return; - - if (!S.getLangOpts().CPlusPlus14) - if (AL.isCXX11Attribute() && - !(AL.hasScope() && AL.getScopeName()->isStr("gnu"))) - S.Diag(AL.getLoc(), diag::ext_cxx14_attr) << AL; - - D->addAttr(::new (S.Context) - DeprecatedAttr(AL.getRange(), S.Context, Str, Replacement, + !S.checkStringLiteralArgumentAttr(AL, 1, Replacement)) + return; + + if (!S.getLangOpts().CPlusPlus14 && AL.isCXX11Attribute() && !AL.isGNUScope()) + S.Diag(AL.getLoc(), diag::ext_cxx14_attr) << AL; + + D->addAttr(::new (S.Context) + DeprecatedAttr(AL.getRange(), S.Context, Str, Replacement, AL.getAttributeSpellingListIndex())); } Modified: cfe/trunk/lib/Sema/SemaType.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=345132&r1=345131&r2=345132&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaType.cpp (original) +++ cfe/trunk/lib/Sema/SemaType.cpp Wed Oct 24 05:26:23 2018 @@ -7273,7 +7273,7 @@ static void processTypeAttrs(TypeProcess // not appertain to a DeclaratorChunk. If we handle them as type // attributes, accept them in that position and diagnose the GCC // incompatibility. - if (attr.getScopeName() && attr.getScopeName()->isStr("gnu")) { + if (attr.isGNUScope()) { bool IsTypeAttr = attr.isTypeAttr(); if (TAL == TAL_DeclChunk) { state.getSema().Diag(attr.getLoc(), Modified: cfe/trunk/test/Preprocessor/has_attribute.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/has_attribute.cpp?rev=345132&r1=345131&r2=345132&view=diff ============================================================================== --- cfe/trunk/test/Preprocessor/has_attribute.cpp (original) +++ cfe/trunk/test/Preprocessor/has_attribute.cpp Wed Oct 24 05:26:23 2018 @@ -18,17 +18,21 @@ // The attribute name can be bracketed with double underscores. // CHECK: has_clang_fallthrough_2 #if __has_cpp_attribute(clang::__fallthrough__) - int has_clang_fallthrough_2(); -#endif - -// The scope cannot be bracketed with double underscores. -// CHECK: does_not_have___clang___fallthrough -#if !__has_cpp_attribute(__clang__::fallthrough) - int does_not_have___clang___fallthrough(); -#endif - -// Test that C++11, target-specific attributes behave properly. - + int has_clang_fallthrough_2(); +#endif + +// The scope cannot be bracketed with double underscores unless it is for gnu. +// CHECK: does_not_have___clang___fallthrough +#if !__has_cpp_attribute(__clang__::fallthrough) + int does_not_have___clang___fallthrough(); +#endif +// CHECK: has_gnu_const +#if __has_cpp_attribute(__gnu__::__const__) + int has_gnu_const(); +#endif + +// Test that C++11, target-specific attributes behave properly. + // CHECK: does_not_have_mips16 #if !__has_cpp_attribute(gnu::mips16) int does_not_have_mips16(); Modified: cfe/trunk/test/SemaCXX/attr-gnu.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-gnu.cpp?rev=345132&r1=345131&r2=345132&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/attr-gnu.cpp (original) +++ cfe/trunk/test/SemaCXX/attr-gnu.cpp Wed Oct 24 05:26:23 2018 @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -std=gnu++11 -fsyntax-only -fms-compatibility -verify %s - -void f() { - // GNU-style attributes are prohibited in this position. +// RUN: %clang_cc1 -std=gnu++17 -fsyntax-only -fms-compatibility -verify %s + +void f() { + // GNU-style attributes are prohibited in this position. auto P = new int * __attribute__((vector_size(8))); // expected-error {{an attribute list cannot appear here}} \ // expected-error {{invalid vector element type 'int *'}} @@ -40,6 +40,13 @@ void tuTest1(Tu<int> u); // expected-not void tuTest2(Tu3 u); // expected-note {{candidate function not viable: no known conversion from 'int' to 'Tu3' for 1st argument}} void tu() { int x = 2; - tuTest1(x); // expected-error {{no matching function for call to 'tuTest1'}} - tuTest2(x); // expected-error {{no matching function for call to 'tuTest2'}} -} + tuTest1(x); // expected-error {{no matching function for call to 'tuTest1'}} + tuTest2(x); // expected-error {{no matching function for call to 'tuTest2'}} +} + +[[gnu::__const__]] int f2() { return 12; } +[[__gnu__::__const__]] int f3() { return 12; } +[[using __gnu__ : __const__]] int f4() { return 12; } + +static_assert(__has_cpp_attribute(gnu::__const__)); +static_assert(__has_cpp_attribute(__gnu__::__const__)); Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=345132&r1=345131&r2=345132&view=diff ============================================================================== --- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original) +++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Wed Oct 24 05:26:23 2018 @@ -2932,15 +2932,15 @@ void EmitClangAttrHasAttrImpl(RecordKeep OS << "case AttrSyntax::" << Variety << ": {\n"; // C++11-style attributes are further split out based on the Scope. for (auto I = List.cbegin(), E = List.cend(); I != E; ++I) { - if (I != List.cbegin()) - OS << " else "; - if (I->first.empty()) - OS << "if (!Scope || Scope->getName() == \"\") {\n"; - else - OS << "if (Scope->getName() == \"" << I->first << "\") {\n"; - OS << " return llvm::StringSwitch<int>(Name)\n"; - GenerateHasAttrSpellingStringSwitch(I->second, OS, Spelling, I->first); - OS << "}"; + if (I != List.cbegin()) + OS << " else "; + if (I->first.empty()) + OS << "if (ScopeName == \"\") {\n"; + else + OS << "if (ScopeName == \"" << I->first << "\") {\n"; + OS << " return llvm::StringSwitch<int>(Name)\n"; + GenerateHasAttrSpellingStringSwitch(I->second, OS, Spelling, I->first); + OS << "}"; } OS << "\n} break;\n"; }; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits