Thanks for pointing the breakage out -- it should be fixed with r316075. ~Aaron
On Wed, Oct 18, 2017 at 7:50 AM, Aaron Ballman <aa...@aaronballman.com> wrote: > I'll take a look, thank you for pointing it out (and sorry for the trouble)! > > ~Aaron > > On Tue, Oct 17, 2017 at 9:56 PM, Galina Kistanova <gkistan...@gmail.com> > wrote: >> Hello Aaron, >> >> This commit broke one our builders: >> >> http://lab.llvm.org:8011/builders/ubuntu-gcc7.1-werror/builds/2272 >> >> . . . >> FAILED: /usr/local/gcc-7.1/bin/g++-7.1 -DGTEST_HAS_RTTI=0 -D_DEBUG >> -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS >> -D__STDC_LIMIT_MACROS -Itools/clang/lib/Basic >> -I/home/buildslave/am1i-slv2/ubuntu-gcc7.1-werror/llvm/tools/clang/lib/Basic >> -I/home/buildslave/am1i-slv2/ubuntu-gcc7.1-werror/llvm/tools/clang/include >> -Itools/clang/include -Iinclude >> -I/home/buildslave/am1i-slv2/ubuntu-gcc7.1-werror/llvm/include >> -Wno-noexcept-type -fPIC -fvisibility-inlines-hidden -Werror >> -Werror=date-time -std=c++11 -Wall -W -Wno-unused-parameter -Wwrite-strings >> -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long >> -Wno-maybe-uninitialized -Wdelete-non-virtual-dtor -Wno-comment >> -ffunction-sections -fdata-sections -fno-common -Woverloaded-virtual >> -fno-strict-aliasing -O3 -fPIC -UNDEBUG -fno-exceptions -fno-rtti -MD >> -MT tools/clang/lib/Basic/CMakeFiles/clangBasic.dir/Attributes.cpp.o -MF >> tools/clang/lib/Basic/CMakeFiles/clangBasic.dir/Attributes.cpp.o.d -o >> tools/clang/lib/Basic/CMakeFiles/clangBasic.dir/Attributes.cpp.o -c >> /home/buildslave/am1i-slv2/ubuntu-gcc7.1-werror/llvm/tools/clang/lib/Basic/Attributes.cpp >> In file included from >> /home/buildslave/am1i-slv2/ubuntu-gcc7.1-werror/llvm/tools/clang/lib/Basic/Attributes.cpp:15:0: >> tools/clang/include/clang/Basic/AttrHasAttributeImpl.inc: In function ‘int >> clang::hasAttribute(clang::AttrSyntax, const clang::IdentifierInfo*, const >> clang::IdentifierInfo*, const clang::TargetInfo&, const >> clang::LangOptions&)’: >> tools/clang/include/clang/Basic/AttrHasAttributeImpl.inc:526:8: error: this >> statement may fall through [-Werror=implicit-fallthrough=] >> } else if (Scope->getName() == "gsl") { >> ^~ >> tools/clang/include/clang/Basic/AttrHasAttributeImpl.inc:532:1: note: here >> case AttrSyntax::C: { >> ^~~~ >> cc1plus: all warnings being treated as errors >> >> Please have a look? >> >> Thanks >> >> Galina >> >> On Sun, Oct 15, 2017 at 8:01 AM, Aaron Ballman via cfe-commits >> <cfe-commits@lists.llvm.org> wrote: >>> >>> Author: aaronballman >>> Date: Sun Oct 15 08:01:42 2017 >>> New Revision: 315856 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=315856&view=rev >>> Log: >>> Add -f[no-]double-square-bracket-attributes as new driver options to >>> control use of [[]] attributes in all language modes. This is the initial >>> implementation of WG14 N2165, which is a proposal to add [[]] attributes to >>> C2x, but also allows you to enable these attributes in C++98, or disable >>> them in C++11 or later. >>> >>> Added: >>> cfe/trunk/test/Misc/ast-dump-c-attr.c >>> cfe/trunk/test/Parser/c2x-attributes.c >>> cfe/trunk/test/Parser/c2x-attributes.m >>> cfe/trunk/test/Sema/attr-deprecated-c2x.c >>> Modified: >>> cfe/trunk/include/clang/Basic/Attr.td >>> cfe/trunk/include/clang/Basic/Attributes.h >>> cfe/trunk/include/clang/Basic/LangOptions.def >>> cfe/trunk/include/clang/Driver/Options.td >>> cfe/trunk/include/clang/Parse/Parser.h >>> cfe/trunk/include/clang/Sema/AttributeList.h >>> cfe/trunk/lib/Frontend/CompilerInvocation.cpp >>> cfe/trunk/lib/Lex/Lexer.cpp >>> cfe/trunk/lib/Parse/ParseDecl.cpp >>> cfe/trunk/lib/Parse/ParseDeclCXX.cpp >>> cfe/trunk/lib/Sema/AttributeList.cpp >>> cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp >>> >>> Modified: cfe/trunk/include/clang/Basic/Attr.td >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=315856&r1=315855&r2=315856&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/include/clang/Basic/Attr.td (original) >>> +++ cfe/trunk/include/clang/Basic/Attr.td Sun Oct 15 08:01:42 2017 >>> @@ -210,6 +210,10 @@ class CXX11<string namespace, string nam >>> string Namespace = namespace; >>> int Version = version; >>> } >>> +class C2x<string namespace, string name> : Spelling<name, "C2x"> { >>> + string Namespace = namespace; >>> +} >>> + >>> class Keyword<string name> : Spelling<name, "Keyword">; >>> class Pragma<string namespace, string name> : Spelling<name, "Pragma"> { >>> string Namespace = namespace; >>> @@ -958,7 +962,7 @@ def RenderScriptKernel : Attr { >>> >>> def Deprecated : InheritableAttr { >>> let Spellings = [GCC<"deprecated">, Declspec<"deprecated">, >>> - CXX11<"","deprecated", 201309>]; >>> + CXX11<"","deprecated", 201309>, C2x<"", >>> "deprecated">]; >>> let Args = [StringArgument<"Message", 1>, >>> // An optional string argument that enables us to provide a >>> // Fix-It. >>> >>> Modified: cfe/trunk/include/clang/Basic/Attributes.h >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attributes.h?rev=315856&r1=315855&r2=315856&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/include/clang/Basic/Attributes.h (original) >>> +++ cfe/trunk/include/clang/Basic/Attributes.h Sun Oct 15 08:01:42 2017 >>> @@ -26,6 +26,8 @@ enum class AttrSyntax { >>> Microsoft, >>> // Is the identifier known as a C++-style attribute? >>> CXX, >>> + // Is the identifier known as a C-style attribute? >>> + C, >>> // Is the identifier known as a pragma attribute? >>> Pragma >>> }; >>> >>> Modified: cfe/trunk/include/clang/Basic/LangOptions.def >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/LangOptions.def?rev=315856&r1=315855&r2=315856&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/include/clang/Basic/LangOptions.def (original) >>> +++ cfe/trunk/include/clang/Basic/LangOptions.def Sun Oct 15 08:01:42 2017 >>> @@ -137,6 +137,8 @@ LANGOPT(GNUAsm , 1, 1, "GNU-s >>> LANGOPT(CoroutinesTS , 1, 0, "C++ coroutines TS") >>> LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of >>> template template arguments") >>> >>> +LANGOPT(DoubleSquareBracketAttributes, 1, 0, "'[[]]' attributes extension >>> for all language standard modes") >>> + >>> BENIGN_LANGOPT(ThreadsafeStatics , 1, 1, "thread-safe static >>> initializers") >>> LANGOPT(POSIXThreads , 1, 0, "POSIX thread support") >>> LANGOPT(Blocks , 1, 0, "blocks extension to C") >>> >>> Modified: cfe/trunk/include/clang/Driver/Options.td >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=315856&r1=315855&r2=315856&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/include/clang/Driver/Options.td (original) >>> +++ cfe/trunk/include/clang/Driver/Options.td Sun Oct 15 08:01:42 2017 >>> @@ -606,6 +606,13 @@ def fastf : Flag<["-"], "fastf">, Group< >>> def fast : Flag<["-"], "fast">, Group<f_Group>; >>> def fasynchronous_unwind_tables : Flag<["-"], >>> "fasynchronous-unwind-tables">, Group<f_Group>; >>> >>> +def fdouble_square_bracket_attributes : Flag<[ "-" ], >>> "fdouble-square-bracket-attributes">, >>> + Group<f_Group>, Flags<[DriverOption, CC1Option]>, >>> + HelpText<"Enable '[[]]' attributes in all C and C++ language modes">; >>> +def fno_double_square_bracket_attributes : Flag<[ "-" ], >>> "fno-fdouble-square-bracket-attributes">, >>> + Group<f_Group>, Flags<[DriverOption]>, >>> + HelpText<"Disable '[[]]' attributes in all C and C++ language modes">; >>> + >>> def fautolink : Flag <["-"], "fautolink">, Group<f_Group>; >>> def fno_autolink : Flag <["-"], "fno-autolink">, Group<f_Group>, >>> Flags<[DriverOption, CC1Option]>, >>> >>> Modified: cfe/trunk/include/clang/Parse/Parser.h >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=315856&r1=315855&r2=315856&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/include/clang/Parse/Parser.h (original) >>> +++ cfe/trunk/include/clang/Parse/Parser.h Sun Oct 15 08:01:42 2017 >>> @@ -2163,18 +2163,25 @@ public: >>> private: >>> void ParseBlockId(SourceLocation CaretLoc); >>> >>> - // Check for the start of a C++11 attribute-specifier-seq in a context >>> where >>> - // an attribute is not allowed. >>> + /// Are [[]] attributes enabled? >>> + bool standardAttributesAllowed() const { >>> + const LangOptions &LO = getLangOpts(); >>> + return LO.DoubleSquareBracketAttributes; >>> + } >>> + >>> + // Check for the start of an attribute-specifier-seq in a context where >>> an >>> + // attribute is not allowed. >>> bool CheckProhibitedCXX11Attribute() { >>> assert(Tok.is(tok::l_square)); >>> - if (!getLangOpts().CPlusPlus11 || NextToken().isNot(tok::l_square)) >>> + if (!standardAttributesAllowed() || NextToken().isNot(tok::l_square)) >>> return false; >>> return DiagnoseProhibitedCXX11Attribute(); >>> } >>> + >>> bool DiagnoseProhibitedCXX11Attribute(); >>> void CheckMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs, >>> SourceLocation CorrectLocation) { >>> - if (!getLangOpts().CPlusPlus11) >>> + if (!standardAttributesAllowed()) >>> return; >>> if ((Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square)) && >>> Tok.isNot(tok::kw_alignas)) >>> @@ -2194,17 +2201,18 @@ private: >>> } >>> void DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs); >>> >>> - // Forbid C++11 attributes that appear on certain syntactic >>> - // locations which standard permits but we don't supported yet, >>> - // for example, attributes appertain to decl specifiers. >>> + // Forbid C++11 and C2x attributes that appear on certain syntactic >>> locations >>> + // which standard permits but we don't supported yet, for example, >>> attributes >>> + // appertain to decl specifiers. >>> void ProhibitCXX11Attributes(ParsedAttributesWithRange &Attrs, >>> unsigned DiagID); >>> >>> - /// \brief Skip C++11 attributes and return the end location of the >>> last one. >>> + /// \brief Skip C++11 and C2x attributes and return the end location of >>> the >>> + /// last one. >>> /// \returns SourceLocation() if there are no attributes. >>> SourceLocation SkipCXX11Attributes(); >>> >>> - /// \brief Diagnose and skip C++11 attributes that appear in syntactic >>> + /// \brief Diagnose and skip C++11 and C2x attributes that appear in >>> syntactic >>> /// locations where attributes are not allowed. >>> void DiagnoseAndSkipCXX11Attributes(); >>> >>> @@ -2254,7 +2262,7 @@ private: >>> AttributeList::Syntax Syntax); >>> >>> void MaybeParseCXX11Attributes(Declarator &D) { >>> - if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) { >>> + if (standardAttributesAllowed() && isCXX11AttributeSpecifier()) { >>> ParsedAttributesWithRange attrs(AttrFactory); >>> SourceLocation endLoc; >>> ParseCXX11Attributes(attrs, &endLoc); >>> @@ -2263,7 +2271,7 @@ private: >>> } >>> void MaybeParseCXX11Attributes(ParsedAttributes &attrs, >>> SourceLocation *endLoc = nullptr) { >>> - if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) { >>> + if (standardAttributesAllowed() && isCXX11AttributeSpecifier()) { >>> ParsedAttributesWithRange attrsWithRange(AttrFactory); >>> ParseCXX11Attributes(attrsWithRange, endLoc); >>> attrs.takeAllFrom(attrsWithRange); >>> @@ -2272,8 +2280,8 @@ private: >>> void MaybeParseCXX11Attributes(ParsedAttributesWithRange &attrs, >>> SourceLocation *endLoc = nullptr, >>> bool OuterMightBeMessageSend = false) { >>> - if (getLangOpts().CPlusPlus11 && >>> - isCXX11AttributeSpecifier(false, OuterMightBeMessageSend)) >>> + if (standardAttributesAllowed() && >>> + isCXX11AttributeSpecifier(false, OuterMightBeMessageSend)) >>> ParseCXX11Attributes(attrs, endLoc); >>> } >>> >>> @@ -2281,8 +2289,8 @@ private: >>> SourceLocation *EndLoc = nullptr); >>> void ParseCXX11Attributes(ParsedAttributesWithRange &attrs, >>> SourceLocation *EndLoc = nullptr); >>> - /// \brief Parses a C++-style attribute argument list. Returns true if >>> this >>> - /// results in adding an attribute to the ParsedAttributes list. >>> + /// \brief Parses a C++11 (or C2x)-style attribute argument list. >>> Returns true >>> + /// if this results in adding an attribute to the ParsedAttributes >>> list. >>> bool ParseCXX11AttributeArgs(IdentifierInfo *AttrName, >>> SourceLocation AttrNameLoc, >>> ParsedAttributes &Attrs, SourceLocation >>> *EndLoc, >>> >>> Modified: cfe/trunk/include/clang/Sema/AttributeList.h >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?rev=315856&r1=315855&r2=315856&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/include/clang/Sema/AttributeList.h (original) >>> +++ cfe/trunk/include/clang/Sema/AttributeList.h Sun Oct 15 08:01:42 2017 >>> @@ -100,6 +100,8 @@ public: >>> AS_GNU, >>> /// [[...]] >>> AS_CXX11, >>> + /// [[...]] >>> + AS_C2x, >>> /// __declspec(...) >>> AS_Declspec, >>> /// [uuid("...")] class Foo >>> @@ -378,6 +380,9 @@ public: >>> bool isCXX11Attribute() const { >>> return SyntaxUsed == AS_CXX11 || isAlignasAttribute(); >>> } >>> + bool isC2xAttribute() const { >>> + return SyntaxUsed == AS_C2x; >>> + } >>> bool isKeywordAttribute() const { >>> return SyntaxUsed == AS_Keyword || SyntaxUsed == >>> AS_ContextSensitiveKeyword; >>> } >>> >>> Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=315856&r1=315855&r2=315856&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original) >>> +++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Sun Oct 15 08:01:42 2017 >>> @@ -2138,6 +2138,12 @@ static void ParseLangArgs(LangOptions &O >>> && Opts.OpenCLVersion >= 200); >>> Opts.BlocksRuntimeOptional = Args.hasArg(OPT_fblocks_runtime_optional); >>> Opts.CoroutinesTS = Args.hasArg(OPT_fcoroutines_ts); >>> + >>> + // Enable [[]] attributes in C++11 by default. >>> + Opts.DoubleSquareBracketAttributes = >>> + Args.hasFlag(OPT_fdouble_square_bracket_attributes, >>> + OPT_fno_double_square_bracket_attributes, >>> Opts.CPlusPlus11); >>> + >>> Opts.ModulesTS = Args.hasArg(OPT_fmodules_ts); >>> Opts.Modules = Args.hasArg(OPT_fmodules) || Opts.ModulesTS; >>> Opts.ModulesStrictDeclUse = Args.hasArg(OPT_fmodules_strict_decluse); >>> >>> Modified: cfe/trunk/lib/Lex/Lexer.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Lexer.cpp?rev=315856&r1=315855&r2=315856&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/lib/Lex/Lexer.cpp (original) >>> +++ cfe/trunk/lib/Lex/Lexer.cpp Sun Oct 15 08:01:42 2017 >>> @@ -3612,7 +3612,9 @@ LexNextToken: >>> if (LangOpts.Digraphs && Char == '>') { >>> Kind = tok::r_square; // ':>' -> ']' >>> CurPtr = ConsumeChar(CurPtr, SizeTmp, Result); >>> - } else if (LangOpts.CPlusPlus && Char == ':') { >>> + } else if ((LangOpts.CPlusPlus || >>> + LangOpts.DoubleSquareBracketAttributes) && >>> + Char == ':') { >>> Kind = tok::coloncolon; >>> CurPtr = ConsumeChar(CurPtr, SizeTmp, Result); >>> } else { >>> >>> Modified: cfe/trunk/lib/Parse/ParseDecl.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=315856&r1=315855&r2=315856&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/lib/Parse/ParseDecl.cpp (original) >>> +++ cfe/trunk/lib/Parse/ParseDecl.cpp Sun Oct 15 08:01:42 2017 >>> @@ -1562,7 +1562,7 @@ void Parser::DiagnoseProhibitedAttribute >>> void Parser::ProhibitCXX11Attributes(ParsedAttributesWithRange &Attrs, >>> unsigned DiagID) { >>> for (AttributeList *Attr = Attrs.getList(); Attr; Attr = >>> Attr->getNext()) { >>> - if (!Attr->isCXX11Attribute()) >>> + if (!Attr->isCXX11Attribute() && !Attr->isC2xAttribute()) >>> continue; >>> if (Attr->getKind() == AttributeList::UnknownAttribute) >>> Diag(Attr->getLoc(), diag::warn_unknown_attribute_ignored) >>> @@ -2925,7 +2925,7 @@ void Parser::ParseDeclarationSpecifiers( >>> >>> case tok::l_square: >>> case tok::kw_alignas: >>> - if (!getLangOpts().CPlusPlus11 || !isCXX11AttributeSpecifier()) >>> + if (!standardAttributesAllowed() || !isCXX11AttributeSpecifier()) >>> goto DoneWithDeclSpec; >>> >>> ProhibitAttributes(attrs); >>> @@ -3778,7 +3778,8 @@ void Parser::ParseDeclarationSpecifiers( >>> /// semicolon. >>> /// >>> /// struct-declaration: >>> -/// specifier-qualifier-list struct-declarator-list >>> +/// [C2x] attributes-specifier-seq[opt] >>> +/// specifier-qualifier-list struct-declarator-list >>> /// [GNU] __extension__ struct-declaration >>> /// [GNU] specifier-qualifier-list >>> /// struct-declarator-list: >>> @@ -3802,6 +3803,11 @@ void Parser::ParseStructDeclaration( >>> return ParseStructDeclaration(DS, FieldsCallback); >>> } >>> >>> + // Parse leading attributes. >>> + ParsedAttributesWithRange Attrs(AttrFactory); >>> + MaybeParseCXX11Attributes(Attrs); >>> + DS.takeAttributesFrom(Attrs); >>> + >>> // Parse the common specifier-qualifiers-list piece. >>> ParseSpecifierQualifierList(DS); >>> >>> @@ -4412,11 +4418,12 @@ void Parser::ParseEnumBody(SourceLocatio >>> ParsedAttributesWithRange attrs(AttrFactory); >>> MaybeParseGNUAttributes(attrs); >>> ProhibitAttributes(attrs); // GNU-style attributes are prohibited. >>> - if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) { >>> - Diag(Tok.getLocation(), getLangOpts().CPlusPlus1z >>> - ? >>> diag::warn_cxx14_compat_ns_enum_attribute >>> - : diag::ext_ns_enum_attribute) >>> - << 1 /*enumerator*/; >>> + if (standardAttributesAllowed() && isCXX11AttributeSpecifier()) { >>> + if (getLangOpts().CPlusPlus) >>> + Diag(Tok.getLocation(), getLangOpts().CPlusPlus1z >>> + ? >>> diag::warn_cxx14_compat_ns_enum_attribute >>> + : diag::ext_ns_enum_attribute) >>> + << 1 /*enumerator*/; >>> ParseCXX11Attributes(attrs); >>> } >>> >>> @@ -5025,7 +5032,7 @@ void Parser::ParseTypeQualifierListOpt( >>> DeclSpec &DS, unsigned AttrReqs, bool AtomicAllowed, >>> bool IdentifierRequired, >>> Optional<llvm::function_ref<void()>> CodeCompletionHandler) { >>> - if (getLangOpts().CPlusPlus11 && (AttrReqs & AR_CXX11AttributesParsed) >>> && >>> + if (standardAttributesAllowed() && (AttrReqs & >>> AR_CXX11AttributesParsed) && >>> isCXX11AttributeSpecifier()) { >>> ParsedAttributesWithRange attrs(AttrFactory); >>> ParseCXX11Attributes(attrs); >>> @@ -5962,7 +5969,7 @@ void Parser::ParseFunctionDeclarator(Dec >>> SmallVector<SourceRange, 2> DynamicExceptionRanges; >>> ExprResult NoexceptExpr; >>> CachedTokens *ExceptionSpecTokens = nullptr; >>> - ParsedAttributes FnAttrs(AttrFactory); >>> + ParsedAttributesWithRange FnAttrs(AttrFactory); >>> TypeResult TrailingReturnType; >>> >>> /* LocalEndLoc is the end location for the local FunctionTypeLoc. >>> @@ -5983,6 +5990,11 @@ void Parser::ParseFunctionDeclarator(Dec >>> RParenLoc = Tracker.getCloseLocation(); >>> LocalEndLoc = RParenLoc; >>> EndLoc = RParenLoc; >>> + >>> + // If there are attributes following the identifier list, parse them >>> and >>> + // prohibit them. >>> + MaybeParseCXX11Attributes(FnAttrs); >>> + ProhibitAttributes(FnAttrs); >>> } else { >>> if (Tok.isNot(tok::r_paren)) >>> ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, >>> @@ -6089,6 +6101,8 @@ void Parser::ParseFunctionDeclarator(Dec >>> TrailingReturnType = ParseTrailingReturnType(Range); >>> EndLoc = Range.getEnd(); >>> } >>> + } else if (standardAttributesAllowed()) { >>> + MaybeParseCXX11Attributes(FnAttrs); >>> } >>> } >>> >>> >>> Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=315856&r1=315855&r2=315856&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original) >>> +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Sun Oct 15 08:01:42 2017 >>> @@ -3814,7 +3814,7 @@ IdentifierInfo *Parser::TryParseCXX11Att >>> } >>> >>> static bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName, >>> - IdentifierInfo *ScopeName) >>> { >>> + IdentifierInfo *ScopeName) >>> { >>> switch (AttributeList::getKind(AttrName, ScopeName, >>> AttributeList::AS_CXX11)) { >>> case AttributeList::AT_CarriesDependency: >>> @@ -3853,11 +3853,14 @@ bool Parser::ParseCXX11AttributeArgs(Ide >>> SourceLocation ScopeLoc) { >>> assert(Tok.is(tok::l_paren) && "Not a C++11 attribute argument list"); >>> SourceLocation LParenLoc = Tok.getLocation(); >>> + const LangOptions &LO = getLangOpts(); >>> + AttributeList::Syntax Syntax = >>> + LO.CPlusPlus ? AttributeList::AS_CXX11 : AttributeList::AS_C2x; >>> >>> // If the attribute isn't known, we will not attempt to parse any >>> // arguments. >>> - if (!hasAttribute(AttrSyntax::CXX, ScopeName, AttrName, >>> - getTargetInfo(), getLangOpts())) { >>> + if (!hasAttribute(LO.CPlusPlus ? AttrSyntax::CXX : AttrSyntax::C, >>> ScopeName, >>> + AttrName, getTargetInfo(), getLangOpts())) { >>> // Eat the left paren, then skip to the ending right paren. >>> ConsumeParen(); >>> SkipUntil(tok::r_paren); >>> @@ -3868,7 +3871,7 @@ bool Parser::ParseCXX11AttributeArgs(Ide >>> // GNU-scoped attributes have some special cases to handle >>> GNU-specific >>> // behaviors. >>> ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, >>> ScopeName, >>> - ScopeLoc, AttributeList::AS_CXX11, nullptr); >>> + ScopeLoc, Syntax, nullptr); >>> return true; >>> } >>> >>> @@ -3877,11 +3880,11 @@ bool Parser::ParseCXX11AttributeArgs(Ide >>> if (ScopeName && ScopeName->getName() == "clang") >>> NumArgs = >>> ParseClangAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, >>> ScopeName, >>> - ScopeLoc, AttributeList::AS_CXX11); >>> + ScopeLoc, Syntax); >>> else >>> NumArgs = >>> ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, >>> - ScopeName, ScopeLoc, >>> AttributeList::AS_CXX11); >>> + ScopeName, ScopeLoc, Syntax); >>> >>> const AttributeList *Attr = Attrs.getList(); >>> if (Attr && IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName)) { >>> @@ -3907,7 +3910,7 @@ bool Parser::ParseCXX11AttributeArgs(Ide >>> return true; >>> } >>> >>> -/// ParseCXX11AttributeSpecifier - Parse a C++11 attribute-specifier. >>> +/// ParseCXX11AttributeSpecifier - Parse a C++11 or C2x >>> attribute-specifier. >>> /// >>> /// [C++11] attribute-specifier: >>> /// '[' '[' attribute-list ']' ']' >>> @@ -3939,8 +3942,8 @@ void Parser::ParseCXX11AttributeSpecifie >>> return; >>> } >>> >>> - assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square) >>> - && "Not a C++11 attribute list"); >>> + assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square) && >>> + "Not a double square bracket attribute list"); >>> >>> Diag(Tok.getLocation(), diag::warn_cxx98_compat_attribute); >>> >>> @@ -4016,10 +4019,12 @@ void Parser::ParseCXX11AttributeSpecifie >>> ScopeName, ScopeLoc); >>> >>> if (!AttrParsed) >>> - attrs.addNew(AttrName, >>> - SourceRange(ScopeLoc.isValid() ? ScopeLoc : AttrLoc, >>> - AttrLoc), >>> - ScopeName, ScopeLoc, nullptr, 0, >>> AttributeList::AS_CXX11); >>> + attrs.addNew( >>> + AttrName, >>> + SourceRange(ScopeLoc.isValid() ? ScopeLoc : AttrLoc, AttrLoc), >>> + ScopeName, ScopeLoc, nullptr, 0, >>> + getLangOpts().CPlusPlus ? AttributeList::AS_CXX11 >>> + : AttributeList::AS_C2x); >>> >>> if (TryConsumeToken(tok::ellipsis)) >>> Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis) >>> @@ -4034,13 +4039,13 @@ void Parser::ParseCXX11AttributeSpecifie >>> SkipUntil(tok::r_square); >>> } >>> >>> -/// ParseCXX11Attributes - Parse a C++11 attribute-specifier-seq. >>> +/// ParseCXX11Attributes - Parse a C++11 or C2x attribute-specifier-seq. >>> /// >>> /// attribute-specifier-seq: >>> /// attribute-specifier-seq[opt] attribute-specifier >>> void Parser::ParseCXX11Attributes(ParsedAttributesWithRange &attrs, >>> SourceLocation *endLoc) { >>> - assert(getLangOpts().CPlusPlus11); >>> + assert(standardAttributesAllowed()); >>> >>> SourceLocation StartLoc = Tok.getLocation(), Loc; >>> if (!endLoc) >>> >>> Modified: cfe/trunk/lib/Sema/AttributeList.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AttributeList.cpp?rev=315856&r1=315855&r2=315856&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/lib/Sema/AttributeList.cpp (original) >>> +++ cfe/trunk/lib/Sema/AttributeList.cpp Sun Oct 15 08:01:42 2017 >>> @@ -114,7 +114,8 @@ static StringRef normalizeAttrName(Strin >>> // Normalize the attribute name, __foo__ becomes foo. This is only >>> allowable >>> // for GNU attributes. >>> bool IsGNU = SyntaxUsed == AttributeList::AS_GNU || >>> - (SyntaxUsed == AttributeList::AS_CXX11 && ScopeName == >>> "gnu"); >>> + ((SyntaxUsed == AttributeList::AS_CXX11 || >>> + SyntaxUsed == AttributeList::AS_C2x) && ScopeName == >>> "gnu"); >>> if (IsGNU && AttrName.size() >= 4 && AttrName.startswith("__") && >>> AttrName.endswith("__")) >>> AttrName = AttrName.slice(2, AttrName.size() - 2); >>> @@ -135,7 +136,7 @@ AttributeList::Kind AttributeList::getKi >>> >>> // Ensure that in the case of C++11 attributes, we look for '::foo' if >>> it is >>> // unscoped. >>> - if (ScopeName || SyntaxUsed == AS_CXX11) >>> + if (ScopeName || SyntaxUsed == AS_CXX11 || SyntaxUsed == AS_C2x) >>> FullName += "::"; >>> FullName += AttrName; >>> >>> >>> Added: cfe/trunk/test/Misc/ast-dump-c-attr.c >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/ast-dump-c-attr.c?rev=315856&view=auto >>> >>> ============================================================================== >>> --- cfe/trunk/test/Misc/ast-dump-c-attr.c (added) >>> +++ cfe/trunk/test/Misc/ast-dump-c-attr.c Sun Oct 15 08:01:42 2017 >>> @@ -0,0 +1,46 @@ >>> +// RUN: %clang_cc1 -triple x86_64-pc-linux >>> -fdouble-square-bracket-attributes -Wno-deprecated-declarations -ast-dump >>> -ast-dump-filter Test %s | FileCheck --strict-whitespace %s >>> + >>> +int Test1 [[deprecated]]; >>> +// CHECK: VarDecl{{.*}}Test1 >>> +// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:13> "" "" >>> + >>> +enum [[deprecated("Frobble")]] Test2 { >>> + Test3 [[deprecated]] >>> +}; >>> +// CHECK: EnumDecl{{.*}}Test2 >>> +// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:8, col:28> "Frobble" "" >>> +// CHECK-NEXT: EnumConstantDecl{{.*}}Test3 >>> +// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:11> "" "" >>> + >>> +struct [[deprecated]] Test4 { >>> + [[deprecated("Frobble")]] int Test5, Test6; >>> + int Test7 [[deprecated]] : 12; >>> +}; >>> +// CHECK: RecordDecl{{.*}}Test4 >>> +// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:10> "" "" >>> +// CHECK-NEXT: FieldDecl{{.*}}Test5 >>> +// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:5, col:25> "Frobble" >>> "" >>> +// CHECK-NEXT: FieldDecl{{.*}}Test6 >>> +// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:5, col:25> "Frobble" >>> "" >>> +// CHECK-NEXT: FieldDecl{{.*}}Test7 >>> +// CHECK-NEXT: IntegerLiteral{{.*}}'int' 12 >>> +// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:15> "" "" >>> + >>> +struct [[deprecated]] Test8; >>> +// CHECK: RecordDecl{{.*}}Test8 >>> +// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:10> "" "" >>> + >>> +[[deprecated]] void Test9(int Test10 [[deprecated]]); >>> +// CHECK: FunctionDecl{{.*}}Test9 >>> +// CHECK-NEXT: ParmVarDecl{{.*}}Test10 >>> +// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:40> "" "" >>> +// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:3> "" "" >>> + >>> +void Test11 [[deprecated]](void); >>> +// CHECK: FunctionDecl{{.*}}Test11 >>> +// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:15> "" "" >>> + >>> +void Test12(void) [[deprecated]] {} >>> +// CHECK: FunctionDecl{{.*}}Test12 >>> +// CHECK-NEXT: CompoundStmt >>> +// CHECK-NEXT: DeprecatedAttr 0x{{[^ ]*}} <col:21> "" "" >>> >>> Added: cfe/trunk/test/Parser/c2x-attributes.c >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/c2x-attributes.c?rev=315856&view=auto >>> >>> ============================================================================== >>> --- cfe/trunk/test/Parser/c2x-attributes.c (added) >>> +++ cfe/trunk/test/Parser/c2x-attributes.c Sun Oct 15 08:01:42 2017 >>> @@ -0,0 +1,122 @@ >>> +// RUN: %clang_cc1 -fsyntax-only -fdouble-square-bracket-attributes >>> -verify %s >>> + >>> +enum [[]] E { >>> + One [[]], >>> + Two, >>> + Three [[]] >>> +}; >>> + >>> +enum [[]] { Four }; >>> +[[]] enum E2 { Five }; // expected-error {{an attribute list cannot >>> appear here}} >>> + >>> +// FIXME: this diagnostic can be improved. >>> +enum { [[]] Six }; // expected-error {{expected identifier}} >>> + >>> +// FIXME: this diagnostic can be improved. >>> +enum E3 [[]] { Seven }; // expected-error {{expected identifier or '('}} >>> + >>> +struct [[]] S1 { >>> + int i [[]]; >>> + int [[]] j; >>> + int k[10] [[]]; >>> + int l[[]][10]; >>> + [[]] int m, n; >>> + int o [[]] : 12; >>> +}; >>> + >>> +[[]] struct S2 { int a; }; // expected-error {{an attribute list cannot >>> appear here}} >>> +struct S3 [[]] { int a; }; // expected-error {{an attribute list cannot >>> appear here}} >>> + >>> +union [[]] U { >>> + double d [[]]; >>> + [[]] int i; >>> +}; >>> + >>> +[[]] union U2 { double d; }; // expected-error {{an attribute list cannot >>> appear here}} >>> +union U3 [[]] { double d; }; // expected-error {{an attribute list cannot >>> appear here}} >>> + >>> +struct [[]] IncompleteStruct; >>> +union [[]] IncompleteUnion; >>> +enum [[]] IncompleteEnum; >>> +enum __attribute__((deprecated)) IncompleteEnum2; >>> + >>> +[[]] void f1(void); >>> +void [[]] f2(void); >>> +void f3 [[]] (void); >>> +void f4(void) [[]]; >>> + >>> +void f5(int i [[]], [[]] int j, int [[]] k); >>> + >>> +void f6(a, b) [[]] int a; int b; { // expected-error {{an attribute list >>> cannot appear here}} >>> +} >>> + >>> +// FIXME: technically, an attribute list cannot appear here, but we >>> currently >>> +// parse it as part of the return type of the function, which is >>> reasonable >>> +// behavior given that we *don't* want to parse it as part of the K&R >>> parameter >>> +// declarations. It is disallowed to avoid a parsing ambiguity we already >>> +// handle well. >>> +int (*f7(a, b))(int, int) [[]] int a; int b; { >>> + return 0; >>> +} >>> + >>> +[[]] int a, b; >>> +int c [[]], d [[]]; >>> + >>> +void f8(void) [[]] { >>> + [[]] int i, j; >>> + int k, l [[]]; >>> +} >>> + >>> +[[]] void f9(void) { >>> + int i[10] [[]]; >>> + int (*fp1)(void)[[]]; >>> + int (*fp2 [[]])(void); >>> + >>> + int * [[]] *ipp; >>> +} >>> + >>> +void f10(int j[static 10] [[]], int k[*] [[]]); >>> + >>> +void f11(void) { >>> + [[]] {} >>> + [[]] if (1) {} >>> + >>> + [[]] switch (1) { >>> + [[]] case 1: [[]] break; >>> + [[]] default: break; >>> + } >>> + >>> + goto foo; >>> + [[]] foo: (void)1; >>> + >>> + [[]] for (;;); >>> + [[]] while (1); >>> + [[]] do [[]] { } while(1); >>> + >>> + [[]] (void)1; >>> + >>> + [[]]; >>> + >>> + (void)sizeof(int [4][[]]); >>> + (void)sizeof(struct [[]] S3 { int a [[]]; }); >>> + >>> + [[]] return; >>> +} >>> + >>> +[[attr]] void f12(void); // expected-warning {{unknown attribute 'attr' >>> ignored}} >>> +[[vendor::attr]] void f13(void); // expected-warning {{unknown attribute >>> 'attr' ignored}} >>> + >>> +// Ensure that asm statements properly handle double colons. >>> +void test_asm(void) { >>> + asm("ret" :::); >>> + asm("foo" :: "r" (xx)); // expected-error {{use of undeclared >>> identifier 'xx'}} >>> +} >>> + >>> +// Do not allow 'using' to introduce vendor attribute namespaces. >>> +[[using vendor: attr1, attr2]] void f14(void); // expected-error >>> {{expected ']'}} \ >>> + // expected-warning >>> {{unknown attribute 'vendor' ignored}} \ >>> + // expected-warning >>> {{unknown attribute 'using' ignored}} >>> + >>> +struct [[]] S4 *s; // expected-error {{an attribute list cannot appear >>> here}} >>> +struct S5 {}; >>> +int c = sizeof(struct [[]] S5); // expected-error {{an attribute list >>> cannot appear here}} >>> >>> Added: cfe/trunk/test/Parser/c2x-attributes.m >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/c2x-attributes.m?rev=315856&view=auto >>> >>> ============================================================================== >>> --- cfe/trunk/test/Parser/c2x-attributes.m (added) >>> +++ cfe/trunk/test/Parser/c2x-attributes.m Sun Oct 15 08:01:42 2017 >>> @@ -0,0 +1,21 @@ >>> +// RUN: %clang_cc1 -fsyntax-only -fdouble-square-bracket-attributes >>> -verify %s >>> +// expected-no-diagnostics >>> + >>> +enum __attribute__((deprecated)) E1 : int; // ok >>> +enum [[deprecated]] E2 : int; >>> + >>> +@interface Base >>> +@end >>> + >>> +@interface S : Base >>> +- (void) bar; >>> +@end >>> + >>> +@interface T : Base >>> +- (S *) foo; >>> +@end >>> + >>> + >>> +void f(T *t) { >>> + [[]][[t foo] bar]; >>> +} >>> >>> Added: cfe/trunk/test/Sema/attr-deprecated-c2x.c >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-deprecated-c2x.c?rev=315856&view=auto >>> >>> ============================================================================== >>> --- cfe/trunk/test/Sema/attr-deprecated-c2x.c (added) >>> +++ cfe/trunk/test/Sema/attr-deprecated-c2x.c Sun Oct 15 08:01:42 2017 >>> @@ -0,0 +1,54 @@ >>> +// RUN: %clang_cc1 %s -verify -fsyntax-only >>> -fdouble-square-bracket-attributes >>> + >>> +int f() [[deprecated]]; // expected-note 2 {{'f' has been explicitly >>> marked deprecated here}} >>> +void g() [[deprecated]];// expected-note {{'g' has been explicitly marked >>> deprecated here}} >>> +void g(); >>> + >>> +extern int var [[deprecated]]; // expected-note 2 {{'var' has been >>> explicitly marked deprecated here}} >>> + >>> +int a() { >>> + int (*ptr)() = f; // expected-warning {{'f' is deprecated}} >>> + f(); // expected-warning {{'f' is deprecated}} >>> + >>> + // test if attributes propagate to functions >>> + g(); // expected-warning {{'g' is deprecated}} >>> + >>> + return var; // expected-warning {{'var' is deprecated}} >>> +} >>> + >>> +// test if attributes propagate to variables >>> +extern int var; >>> +int w() { >>> + return var; // expected-warning {{'var' is deprecated}} >>> +} >>> + >>> +int old_fn() [[deprecated]];// expected-note {{'old_fn' has been >>> explicitly marked deprecated here}} >>> +int old_fn(); >>> +int (*fn_ptr)() = old_fn; // expected-warning {{'old_fn' is deprecated}} >>> + >>> +int old_fn() { >>> + return old_fn()+1; // no warning, deprecated functions can use >>> deprecated symbols. >>> +} >>> + >>> +struct foo { >>> + int x [[deprecated]]; // expected-note 3 {{'x' has been explicitly >>> marked deprecated here}} >>> +}; >>> + >>> +void test1(struct foo *F) { >>> + ++F->x; // expected-warning {{'x' is deprecated}} >>> + struct foo f1 = { .x = 17 }; // expected-warning {{'x' is deprecated}} >>> + struct foo f2 = { 17 }; // expected-warning {{'x' is deprecated}} >>> +} >>> + >>> +typedef struct foo foo_dep [[deprecated]]; // expected-note {{'foo_dep' >>> has been explicitly marked deprecated here}} >>> +foo_dep *test2; // expected-warning {{'foo_dep' is deprecated}} >>> + >>> +struct [[deprecated, // expected-note {{'bar_dep' has been explicitly >>> marked deprecated here}} >>> + invalid_attribute]] bar_dep ; // expected-warning {{unknown >>> attribute 'invalid_attribute' ignored}} >>> + >>> +struct bar_dep *test3; // expected-warning {{'bar_dep' is deprecated}} >>> + >>> +[[deprecated("this is the message")]] int i; // expected-note {{'i' has >>> been explicitly marked deprecated here}} >>> +void test4(void) { >>> + i = 12; // expected-warning {{'i' is deprecated: this is the message}} >>> +} >>> >>> Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=315856&r1=315855&r2=315856&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original) >>> +++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Sun Oct 15 08:01:42 2017 >>> @@ -58,7 +58,7 @@ public: >>> >>> assert(V != "GCC" && "Given a GCC spelling, which means this hasn't >>> been" >>> "flattened!"); >>> - if (V == "CXX11" || V == "Pragma") >>> + if (V == "CXX11" || V == "C2x" || V == "Pragma") >>> NS = Spelling.getValueAsString("Namespace"); >>> bool Unset; >>> K = Spelling.getValueAsBitOrUnset("KnownToGCC", Unset); >>> @@ -1326,7 +1326,7 @@ writePrettyPrintFunction(Record &R, >>> if (Variety == "GNU") { >>> Prefix = " __attribute__(("; >>> Suffix = "))"; >>> - } else if (Variety == "CXX11") { >>> + } else if (Variety == "CXX11" || Variety == "C2x") { >>> Prefix = " [["; >>> Suffix = "]]"; >>> std::string Namespace = Spellings[I].nameSpace(); >>> @@ -2716,10 +2716,14 @@ static void GenerateHasAttrSpellingStrin >>> // If this is the C++11 variety, also add in the LangOpts test. >>> if (Variety == "CXX11") >>> Test += " && LangOpts.CPlusPlus11"; >>> + else if (Variety == "C2x") >>> + Test += " && LangOpts.DoubleSquareBracketAttributes"; >>> } else if (Variety == "CXX11") >>> // C++11 mode should be checked against LangOpts, which is presumed >>> to be >>> // present in the caller. >>> Test = "LangOpts.CPlusPlus11"; >>> + else if (Variety == "C2x") >>> + Test = "LangOpts.DoubleSquareBracketAttributes"; >>> >>> std::string TestStr = >>> !Test.empty() ? Test + " ? " + llvm::itostr(Version) + " : 0" : >>> "1"; >>> @@ -2740,7 +2744,7 @@ void EmitClangAttrHasAttrImpl(RecordKeep >>> // and declspecs. Then generate a big switch statement for each of >>> them. >>> std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr"); >>> std::vector<Record *> Declspec, Microsoft, GNU, Pragma; >>> - std::map<std::string, std::vector<Record *>> CXX; >>> + std::map<std::string, std::vector<Record *>> CXX, C2x; >>> >>> // Walk over the list of all attributes, and split them out based on >>> the >>> // spelling variety. >>> @@ -2756,6 +2760,8 @@ void EmitClangAttrHasAttrImpl(RecordKeep >>> Microsoft.push_back(R); >>> else if (Variety == "CXX11") >>> CXX[SI.nameSpace()].push_back(R); >>> + else if (Variety == "C2x") >>> + C2x[SI.nameSpace()].push_back(R); >>> else if (Variety == "Pragma") >>> Pragma.push_back(R); >>> } >>> @@ -2775,20 +2781,25 @@ void EmitClangAttrHasAttrImpl(RecordKeep >>> OS << "case AttrSyntax::Pragma:\n"; >>> OS << " return llvm::StringSwitch<int>(Name)\n"; >>> GenerateHasAttrSpellingStringSwitch(Pragma, OS, "Pragma"); >>> - OS << "case AttrSyntax::CXX: {\n"; >>> - // C++11-style attributes are further split out based on the Scope. >>> - for (auto I = CXX.cbegin(), E = CXX.cend(); I != E; ++I) { >>> - if (I != CXX.begin()) >>> - 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, "CXX11", >>> I->first); >>> - OS << "}"; >>> - } >>> - OS << "\n}\n"; >>> + auto fn = [&OS](const char *Spelling, const char *Variety, >>> + const std::map<std::string, std::vector<Record *>> >>> &List) { >>> + 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 << "}"; >>> + } >>> + OS << "\n}\n"; >>> + }; >>> + fn("CXX11", "CXX", CXX); >>> + fn("C2x", "C", C2x); >>> OS << "}\n"; >>> } >>> >>> @@ -2809,10 +2820,11 @@ void EmitClangAttrSpellingListIndex(Reco >>> << StringSwitch<unsigned>(Spellings[I].variety()) >>> .Case("GNU", 0) >>> .Case("CXX11", 1) >>> - .Case("Declspec", 2) >>> - .Case("Microsoft", 3) >>> - .Case("Keyword", 4) >>> - .Case("Pragma", 5) >>> + .Case("C2x", 2) >>> + .Case("Declspec", 3) >>> + .Case("Microsoft", 4) >>> + .Case("Keyword", 5) >>> + .Case("Pragma", 6) >>> .Default(0) >>> << " && Scope == \"" << Spellings[I].nameSpace() << "\")\n" >>> << " return " << I << ";\n"; >>> @@ -3505,7 +3517,7 @@ void EmitClangAttrParsedAttrKinds(Record >>> >>> std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr"); >>> std::vector<StringMatcher::StringPair> GNU, Declspec, Microsoft, CXX11, >>> - Keywords, Pragma; >>> + Keywords, Pragma, C2x; >>> std::set<std::string> Seen; >>> for (const auto *A : Attrs) { >>> const Record &Attr = *A; >>> @@ -3543,6 +3555,10 @@ void EmitClangAttrParsedAttrKinds(Record >>> Matches = &CXX11; >>> Spelling += S.nameSpace(); >>> Spelling += "::"; >>> + } else if (Variety == "C2x") { >>> + Matches = &C2x; >>> + Spelling += S.nameSpace(); >>> + Spelling += "::"; >>> } else if (Variety == "GNU") >>> Matches = &GNU; >>> else if (Variety == "Declspec") >>> @@ -3581,6 +3597,8 @@ void EmitClangAttrParsedAttrKinds(Record >>> StringMatcher("Name", Microsoft, OS).Emit(); >>> OS << " } else if (AttributeList::AS_CXX11 == Syntax) {\n"; >>> StringMatcher("Name", CXX11, OS).Emit(); >>> + OS << " } else if (AttributeList::AS_C2x == Syntax) {\n"; >>> + StringMatcher("Name", C2x, OS).Emit(); >>> OS << " } else if (AttributeList::AS_Keyword == Syntax || "; >>> OS << "AttributeList::AS_ContextSensitiveKeyword == Syntax) {\n"; >>> StringMatcher("Name", Keywords, OS).Emit(); >>> @@ -3666,10 +3684,11 @@ static void WriteCategoryHeader(const Re >>> enum SpellingKind { >>> GNU = 1 << 0, >>> CXX11 = 1 << 1, >>> - Declspec = 1 << 2, >>> - Microsoft = 1 << 3, >>> - Keyword = 1 << 4, >>> - Pragma = 1 << 5 >>> + C2x = 1 << 2, >>> + Declspec = 1 << 3, >>> + Microsoft = 1 << 4, >>> + Keyword = 1 << 5, >>> + Pragma = 1 << 6 >>> }; >>> >>> static void WriteDocumentation(RecordKeeper &Records, >>> @@ -3716,6 +3735,7 @@ static void WriteDocumentation(RecordKee >>> SpellingKind Kind = StringSwitch<SpellingKind>(I.variety()) >>> .Case("GNU", GNU) >>> .Case("CXX11", CXX11) >>> + .Case("C2x", C2x) >>> .Case("Declspec", Declspec) >>> .Case("Microsoft", Microsoft) >>> .Case("Keyword", Keyword) >>> @@ -3725,7 +3745,7 @@ static void WriteDocumentation(RecordKee >>> SupportedSpellings |= Kind; >>> >>> std::string Name; >>> - if (Kind == CXX11 && !I.nameSpace().empty()) >>> + if ((Kind == CXX11 || Kind == C2x) && !I.nameSpace().empty()) >>> Name = I.nameSpace() + "::"; >>> Name += I.name(); >>> >>> @@ -3754,13 +3774,15 @@ static void WriteDocumentation(RecordKee >>> >>> // List what spelling syntaxes the attribute supports. >>> OS << ".. csv-table:: Supported Syntaxes\n"; >>> - OS << " :header: \"GNU\", \"C++11\", \"__declspec\", \"Keyword\","; >>> + OS << " :header: \"GNU\", \"C++11\", \"C2x\", \"__declspec\", >>> \"Keyword\","; >>> OS << " \"Pragma\", \"Pragma clang attribute\"\n\n"; >>> OS << " \""; >>> if (SupportedSpellings & GNU) OS << "X"; >>> OS << "\",\""; >>> if (SupportedSpellings & CXX11) OS << "X"; >>> OS << "\",\""; >>> + if (SupportedSpellings & C2x) OS << "X"; >>> + OS << "\",\""; >>> if (SupportedSpellings & Declspec) OS << "X"; >>> OS << "\",\""; >>> if (SupportedSpellings & Keyword) OS << "X"; >>> >>> >>> _______________________________________________ >>> cfe-commits mailing list >>> cfe-commits@lists.llvm.org >>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >> >> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits