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