Thank you! On Wed, Oct 18, 2017 at 7:38 AM, Aaron Ballman <aa...@aaronballman.com> wrote:
> 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