<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Jan 16, 2014 at 1:11 AM, Daniel Jasper <span dir="ltr"><<a href="mailto:djasper@google.com" target="_blank">djasper@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: djasper<br>
Date: Thu Jan 16 03:11:55 2014<br>
New Revision: 199368<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=199368&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=199368&view=rev</a><br>
Log:<br>
clang-format: Enable formatting of lambdas with explicit return type.<br>
<br>
So clang-format can now format:<br>
<br>
  int c = []()->int { return 2; }();<br>
  int c = []()->vector<int> { return { 2 }; }();<br>
<br>
Modified:<br>
    cfe/trunk/lib/Format/FormatToken.cpp<br>
    cfe/trunk/lib/Format/FormatToken.h<br>
    cfe/trunk/lib/Format/TokenAnnotator.cpp<br>
    cfe/trunk/lib/Format/UnwrappedLineParser.cpp<br>
    cfe/trunk/unittests/Format/FormatTest.cpp<br>
<br>
Modified: cfe/trunk/lib/Format/FormatToken.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatToken.cpp?rev=199368&r1=199367&r2=199368&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatToken.cpp?rev=199368&r1=199367&r2=199368&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Format/FormatToken.cpp (original)<br>
+++ cfe/trunk/lib/Format/FormatToken.cpp Thu Jan 16 03:11:55 2014<br>
@@ -22,6 +22,36 @@<br>
 namespace clang {<br>
 namespace format {<br>
<br>
+// FIXME: This is copy&pasted from Sema. Put it in a common place and remove<br>
+// duplication.<br>
+bool FormatToken::isSimpleTypeSpecifier() const {<br>
+  switch (Tok.getKind()) {<br>
+  case tok::kw_short:<br>
+  case tok::kw_long:<br>
+  case tok::kw___int64:<br>
+  case tok::kw___int128:<br>
+  case tok::kw_signed:<br>
+  case tok::kw_unsigned:<br>
+  case tok::kw_void:<br>
+  case tok::kw_char:<br>
+  case tok::kw_int:<br>
+  case tok::kw_half:<br>
+  case tok::kw_float:<br>
+  case tok::kw_double:<br>
+  case tok::kw_wchar_t:<br>
+  case tok::kw_bool:<br>
+  case tok::kw___underlying_type:<br>
+  case tok::annot_typename:<br>
+  case tok::kw_char16_t:<br>
+  case tok::kw_char32_t:<br>
+  case tok::kw_typeof:<br>
+  case tok::kw_decltype:<br>
+    return true;<br>
+  default:<br>
+    return false;<br>
+  }<br>
+}<br>
+<br>
 TokenRole::~TokenRole() {}<br>
<br>
 void TokenRole::precomputeFormattingInfos(const FormatToken *Token) {}<br>
<br>
Modified: cfe/trunk/lib/Format/FormatToken.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatToken.h?rev=199368&r1=199367&r2=199368&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatToken.h?rev=199368&r1=199367&r2=199368&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Format/FormatToken.h (original)<br>
+++ cfe/trunk/lib/Format/FormatToken.h Thu Jan 16 03:11:55 2014<br>
@@ -280,6 +280,9 @@ struct FormatToken {<br>
            (!ColonRequired || (Next && Next->is(tok::colon)));<br>
   }<br>
<br>
+  /// \brief Determine whether the token is a simple-type-specifier.<br>
+  bool isSimpleTypeSpecifier() const;<br>
+<br>
   bool isObjCAccessSpecifier() const {<br>
     return is(tok::at) && Next && (Next->isObjCAtKeyword(tok::objc_public) ||<br>
                                    Next->isObjCAtKeyword(tok::objc_protected) ||<br>
<br>
Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=199368&r1=199367&r2=199368&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=199368&r1=199367&r2=199368&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Format/TokenAnnotator.cpp (original)<br>
+++ cfe/trunk/lib/Format/TokenAnnotator.cpp Thu Jan 16 03:11:55 2014<br>
@@ -697,7 +697,7 @@ private:<br>
         bool ParensAreType = !Current.Previous ||<br>
                              Current.Previous->Type == TT_PointerOrReference ||<br>
                              Current.Previous->Type == TT_TemplateCloser ||<br>
-                             isSimpleTypeSpecifier(*Current.Previous);<br>
+                             Current.Previous->isSimpleTypeSpecifier();<br>
         bool ParensCouldEndDecl =<br>
             Current.Next &&<br>
             Current.Next->isOneOf(tok::equal, tok::semi, tok::l_brace);<br>
@@ -778,7 +778,7 @@ private:<br>
<br>
     return (!IsPPKeyword && PreviousNotConst->is(tok::identifier)) ||<br>
            PreviousNotConst->Type == TT_PointerOrReference ||<br>
-           isSimpleTypeSpecifier(*PreviousNotConst);<br>
+           PreviousNotConst->isSimpleTypeSpecifier();<br>
   }<br>
<br>
   /// \brief Return the type of the given token assuming it is * or &.<br>
@@ -853,36 +853,6 @@ private:<br>
     return TT_UnaryOperator;<br>
   }<br>
<br>
-  // FIXME: This is copy&pasted from Sema. Put it in a common place and remove<br>
-  // duplication.<br>
-  /// \brief Determine whether the token kind starts a simple-type-specifier.<br>
-  bool isSimpleTypeSpecifier(const FormatToken &Tok) const {<br>
-    switch (Tok.Tok.getKind()) {<br>
-    case tok::kw_short:<br>
-    case tok::kw_long:<br>
-    case tok::kw___int64:<br>
-    case tok::kw___int128:<br>
-    case tok::kw_signed:<br>
-    case tok::kw_unsigned:<br>
-    case tok::kw_void:<br>
-    case tok::kw_char:<br>
-    case tok::kw_int:<br>
-    case tok::kw_half:<br>
-    case tok::kw_float:<br>
-    case tok::kw_double:<br>
-    case tok::kw_wchar_t:<br>
-    case tok::kw_bool:<br>
-    case tok::kw___underlying_type:<br>
-    case tok::annot_typename:<br>
-    case tok::kw_char16_t:<br>
-    case tok::kw_char32_t:<br>
-    case tok::kw_typeof:<br>
-    case tok::kw_decltype:<br>
-      return true;<br>
-    default:<br>
-      return false;<br>
-    }<br>
-  }<br>
<br>
   SmallVector<Context, 8> Contexts;<br>
<br>
<br>
Modified: cfe/trunk/lib/Format/UnwrappedLineParser.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.cpp?rev=199368&r1=199367&r2=199368&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.cpp?rev=199368&r1=199367&r2=199368&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Format/UnwrappedLineParser.cpp (original)<br>
+++ cfe/trunk/lib/Format/UnwrappedLineParser.cpp Thu Jan 16 03:11:55 2014<br>
@@ -762,15 +762,22 @@ bool UnwrappedLineParser::tryToParseLamb<br>
   if (!tryToParseLambdaIntroducer())<br>
     return false;<br>
<br>
-  while (FormatTok->isNot(tok::l_brace)) {<br>
+  while (FormatTok && FormatTok->isNot(tok::l_brace)) {<br>
+    if (FormatTok->isSimpleTypeSpecifier()) {<br>
+      nextToken();<br>
+      continue;<br>
+    }<br>
     switch (FormatTok->Tok.getKind()) {<br>
     case tok::l_brace:<br>
       break;<br>
     case tok::l_paren:<br>
       parseParens();<br>
       break;<br>
+    case tok::less:<br>
+    case tok::greater:<br>
     case tok::identifier:<br>
     case tok::kw_mutable:<br>
+    case tok::arrow:<br>
       nextToken();<br>
       break;<br>
     default:<br>
@@ -956,7 +963,6 @@ void UnwrappedLineParser::parseSquare()<br>
   if (tryToParseLambda())<br>
     return;<br>
   do {<br>
-    // llvm::errs() << FormatTok->Tok.getName() << "\n";<br>
     switch (FormatTok->Tok.getKind()) {<br>
     case tok::l_paren:<br>
       parseParens();<br>
<br>
Modified: cfe/trunk/unittests/Format/FormatTest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=199368&r1=199367&r2=199368&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=199368&r1=199367&r2=199368&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)<br>
+++ cfe/trunk/unittests/Format/FormatTest.cpp Thu Jan 16 03:11:55 2014<br>
@@ -7890,6 +7890,10 @@ TEST_F(FormatTest, FormatsLambdas) {<br>
                "        [&](int, int) { return 1; });\n"<br>
                "}\n");<br>
<br>
+  // Lambdas with return types.<br>
+  verifyFormat("int c = []()->int { return 2; }();\n");<br></blockquote><div><br></div><div>Is this the right formatting here? I would've expected spaces around the "->" as I would for a trailing return type on a non-lambda:<br>
<br>auto func(T x, T y) -> decltype(x + y);<br><br>but I realize lambdas are intended to be fairly compact so the extra whitespace may be undesirable. </div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+  verifyFormat("int c = []()->vector<int> { return { 2 }; }();\n");<br></blockquote><div><br>Do we put spaces around {} init generally? That seems uncommon.<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+<br>
   // Not lambdas.<br>
   verifyFormat("constexpr char hello[]{ \"hello\" };");<br>
   verifyFormat("double &operator[](int i) { return 0; }\n"<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>