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