r203628 - Allow GNU-style attributes on lambda expressions.

Aaron Ballman aaron at aaronballman.com
Tue Mar 11 17:01:07 PDT 2014


Author: aaronballman
Date: Tue Mar 11 19:01:07 2014
New Revision: 203628

URL: http://llvm.org/viewvc/llvm-project?rev=203628&view=rev
Log:
Allow GNU-style attributes on lambda expressions.

Modified:
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/test/Misc/ast-dump-attr.cpp
    cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=203628&r1=203627&r2=203628&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Tue Mar 11 19:01:07 2014
@@ -995,7 +995,6 @@ ExprResult Parser::ParseLambdaExpression
     ParsedAttributes Attr(AttrFactory);
     SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
     SourceLocation EllipsisLoc;
-
     
     if (Tok.isNot(tok::r_paren)) {
       Actions.RecordParsingTemplateParameterDepth(TemplateParameterDepth);
@@ -1009,6 +1008,10 @@ ExprResult Parser::ParseLambdaExpression
     SourceLocation RParenLoc = T.getCloseLocation();
     DeclEndLoc = RParenLoc;
 
+    // GNU-style attributes must be parsed before the mutable specifier to be
+    // compatible with GCC.
+    MaybeParseGNUAttributes(Attr, &DeclEndLoc);
+
     // Parse 'mutable'[opt].
     SourceLocation MutableLoc;
     if (TryConsumeToken(tok::kw_mutable, MutableLoc))
@@ -1067,6 +1070,7 @@ ExprResult Parser::ParseLambdaExpression
                                            TrailingReturnType),
                   Attr, DeclEndLoc);
   } else if (Tok.is(tok::kw_mutable) || Tok.is(tok::arrow) ||
+             Tok.is(tok::kw___attribute) ||
              (Tok.is(tok::l_square) && NextToken().is(tok::l_square))) {
     // It's common to forget that one needs '()' before 'mutable', an attribute
     // specifier, or the result type. Deal with this.
@@ -1074,6 +1078,7 @@ ExprResult Parser::ParseLambdaExpression
     switch (Tok.getKind()) {
     case tok::kw_mutable: TokKind = 0; break;
     case tok::arrow: TokKind = 1; break;
+    case tok::kw___attribute:
     case tok::l_square: TokKind = 2; break;
     default: llvm_unreachable("Unknown token kind");
     }
@@ -1083,7 +1088,12 @@ ExprResult Parser::ParseLambdaExpression
       << FixItHint::CreateInsertion(Tok.getLocation(), "() ");
     SourceLocation DeclLoc = Tok.getLocation();
     SourceLocation DeclEndLoc = DeclLoc;
-    
+
+    // GNU-style attributes must be parsed before the mutable specifier to be
+    // compatible with GCC.
+    ParsedAttributes Attr(AttrFactory);
+    MaybeParseGNUAttributes(Attr, &DeclEndLoc);
+
     // Parse 'mutable', if it's there.
     SourceLocation MutableLoc;
     if (Tok.is(tok::kw_mutable)) {
@@ -1092,7 +1102,6 @@ ExprResult Parser::ParseLambdaExpression
     }
 
     // Parse attribute-specifier[opt].
-    ParsedAttributes Attr(AttrFactory);
     MaybeParseCXX11Attributes(Attr, &DeclEndLoc);
 
     // Parse the return type, if there is one.

Modified: cfe/trunk/test/Misc/ast-dump-attr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/ast-dump-attr.cpp?rev=203628&r1=203627&r2=203628&view=diff
==============================================================================
--- cfe/trunk/test/Misc/ast-dump-attr.cpp (original)
+++ cfe/trunk/test/Misc/ast-dump-attr.cpp Tue Mar 11 19:01:07 2014
@@ -114,3 +114,18 @@ extern "C" int printf(const char *format
 int __attribute__((cdecl)) TestOne(void), TestTwo(void);
 // CHECK: FunctionDecl{{.*}}TestOne{{.*}}__attribute__((cdecl))
 // CHECK: FunctionDecl{{.*}}TestTwo{{.*}}__attribute__((cdecl))
+
+void func() {
+  auto Test = []() __attribute__((no_thread_safety_analysis)) {};
+  // CHECK: CXXMethodDecl{{.*}}operator() 'void (void) const'
+  // CHECK: NoThreadSafetyAnalysisAttr
+
+  // Because GNU's noreturn applies to the function type, and this lambda does
+  // not have a capture list, the call operator and the function pointer
+  // conversion should both be noreturn, but the method should not contain a
+  // NoReturnAttr because the attribute applied to the type.
+  auto Test2 = []() __attribute__((noreturn)) { while(1); };
+  // CHECK: CXXMethodDecl{{.*}}operator() 'void (void) __attribute__((noreturn)) const'
+  // CHECK-NOT: NoReturnAttr
+  // CHECK: CXXConversionDecl{{.*}}operator void (*)() __attribute__((noreturn))
+}

Modified: cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp?rev=203628&r1=203627&r2=203628&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp (original)
+++ cfe/trunk/test/Parser/cxx0x-lambda-expressions.cpp Tue Mar 11 19:01:07 2014
@@ -67,6 +67,7 @@ class C {
 
   void attributes() {
     [] [[]] {}; // expected-error {{lambda requires '()' before attribute specifier}}
+    [] __attribute__((noreturn)) {}; // expected-error {{lambda requires '()' before attribute specifier}}
     []() [[]]
       mutable {}; // expected-error {{expected body of lambda expression}}
 
@@ -75,5 +76,10 @@ class C {
     []() mutable [[]] -> void {};
     []() mutable noexcept [[]] -> void {};
 
-}
+    // Testing GNU-style attributes on lambdas -- the attribute is specified
+    // before the mutable specifier instead of after (unlike C++11).
+    []() __attribute__((noreturn)) mutable { while(1); };
+    []() mutable
+      __attribute__((noreturn)) { while(1); }; // expected-error {{expected body of lambda expression}}
+  }
 };





More information about the cfe-commits mailing list