[PATCH] D69577: [clang-format] [PR35518] C++17 deduction guides are wrongly formatted

2019-11-06 Thread MyDeveloperDay via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG76ec6b1ef69f: [clang-format] [PR35518] C++17 deduction 
guides are wrongly formatted (authored by MyDeveloperDay).

Changed prior to commit:
  https://reviews.llvm.org/D69577?vs=227952=228008#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69577/new/

https://reviews.llvm.org/D69577

Files:
  clang/lib/Format/TokenAnnotator.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -4977,6 +4977,29 @@
   verifyFormat("void f() { auto a = b->c(); }");
 }
 
+TEST_F(FormatTest, DeductionGuides) {
+  verifyFormat("template  A(const T &, const T &) -> A;");
+  verifyFormat("template  explicit A(T &, T &&) -> A;");
+  verifyFormat("template  S(Ts...) -> S;");
+  verifyFormat(
+  "template \n"
+  "array(T &&... t) -> array, sizeof...(T)>;");
+  verifyFormat("template  A() -> Afoo<3>())>;");
+  verifyFormat("template  A() -> A>)>;");
+  verifyFormat("template  A() -> Afoo<1>)>;");
+  verifyFormat("template  A() -> A<(3 < 2)>;");
+  verifyFormat("template  A() -> A<((3) < (2))>;");
+  verifyFormat("template  x() -> x<1>;");
+  verifyFormat("template  explicit x(T &) -> x<1>;");
+
+  // Ensure not deduction guides.
+  verifyFormat("c()->f();");
+  verifyFormat("x()->foo<1>;");
+  verifyFormat("x = p->foo<3>();");
+  verifyFormat("x()->x<1>();");
+  verifyFormat("x()->x<1>;");
+}
+
 TEST_F(FormatTest, BreaksFunctionDeclarationsWithTrailingTokens) {
   // Avoid breaking before trailing 'const' or other trailing annotations, if
   // they are not function-like.
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1350,6 +1350,70 @@
 }
   }
 
+  static FormatToken *untilMatchingParen(FormatToken *Current) {
+// Used when `MatchingParen` is not yet established.
+int ParenLevel = 0;
+while (Current) {
+  if (Current->is(tok::l_paren))
+ParenLevel++;
+  if (Current->is(tok::r_paren))
+ParenLevel--;
+  if (ParenLevel < 1)
+break;
+  Current = Current->Next;
+}
+return Current;
+  }
+
+  static bool isDeductionGuide(FormatToken ) {
+// Look for a deduction guide template A(...) -> A<...>;
+if (Current.Previous && Current.Previous->is(tok::r_paren) &&
+Current.startsSequence(tok::arrow, tok::identifier, tok::less)) {
+  // Find the TemplateCloser.
+  FormatToken *TemplateCloser = Current.Next->Next;
+  int NestingLevel = 0;
+  while (TemplateCloser) {
+// Skip over an expressions in parens  A<(3 < 2)>;
+if (TemplateCloser->is(tok::l_paren)) {
+  // No Matching Paren yet so skip to matching paren
+  TemplateCloser = untilMatchingParen(TemplateCloser);
+}
+if (TemplateCloser->is(tok::less))
+  NestingLevel++;
+if (TemplateCloser->is(tok::greater))
+  NestingLevel--;
+if (NestingLevel < 1)
+  break;
+TemplateCloser = TemplateCloser->Next;
+  }
+  // Assuming we have found the end of the template ensure its followed
+  // with a semi-colon.
+  if (TemplateCloser && TemplateCloser->Next &&
+  TemplateCloser->Next->is(tok::semi) &&
+  Current.Previous->MatchingParen) {
+// Determine if the identifier `A` prior to the A<..>; is the same as
+// prior to the A(..)
+FormatToken *LeadingIdentifier =
+Current.Previous->MatchingParen->Previous;
+
+// Differentiate a deduction guide by seeing the
+// > of the template prior to the leading identifier.
+if (LeadingIdentifier) {
+  FormatToken *PriorLeadingIdentifier = LeadingIdentifier->Previous;
+  // Skip back past explicit decoration
+  if (PriorLeadingIdentifier &&
+  PriorLeadingIdentifier->is(tok::kw_explicit))
+PriorLeadingIdentifier = PriorLeadingIdentifier->Previous;
+
+  return (PriorLeadingIdentifier &&
+  PriorLeadingIdentifier->is(TT_TemplateCloser) &&
+  LeadingIdentifier->TokenText == Current.Next->TokenText);
+}
+  }
+}
+return false;
+  }
+
   void determineTokenType(FormatToken ) {
 if (!Current.is(TT_Unknown))
   // The token type is already known.
@@ -1397,6 +1461,10 @@
!Current.Previous->is(tok::kw_operator)) {
   // not auto operator->() -> xxx;
   Current.Type = TT_TrailingReturnArrow;
+
+} else if (isDeductionGuide(Current)) {
+  // Deduction guides trailing arrow " A(...) -> A;".
+  Current.Type = TT_TrailingReturnArrow;
 } else if (Current.isOneOf(tok::star, 

[PATCH] D69577: [clang-format] [PR35518] C++17 deduction guides are wrongly formatted

2019-11-05 Thread pre-merge checks [bot] via Phabricator via cfe-commits
merge_guards_bot added a comment.

Build result: pass - 59867 tests passed, 0 failed and 768 were skipped.
Log files: console-log.txt 
,
 CMakeCache.txt 



Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69577/new/

https://reviews.llvm.org/D69577



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69577: [clang-format] [PR35518] C++17 deduction guides are wrongly formatted

2019-11-05 Thread Marek Kurdej via Phabricator via cfe-commits
curdeius accepted this revision.
curdeius added a comment.
This revision is now accepted and ready to land.

LGTM. Just a small typo in comment. Otherwise, great job!




Comment at: clang/lib/Format/TokenAnnotator.cpp:1369
+  static bool isDeductionGuide(FormatToken ) {
+// Look for a deduction guide temaplte A(...) -> A<...>;
+if (Current.Previous && Current.Previous->is(tok::r_paren) &&

Typo: template.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69577/new/

https://reviews.llvm.org/D69577



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69577: [clang-format] [PR35518] C++17 deduction guides are wrongly formatted

2019-11-05 Thread MyDeveloperDay via Phabricator via cfe-commits
MyDeveloperDay updated this revision to Diff 227952.
MyDeveloperDay marked an inline comment as done.
MyDeveloperDay set the repository for this revision to rG LLVM Github Monorepo.
MyDeveloperDay added a comment.

Ensure the deduction guides follow a template
Add additional test cases raised during the reviews


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69577/new/

https://reviews.llvm.org/D69577

Files:
  clang/lib/Format/TokenAnnotator.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -4977,6 +4977,29 @@
   verifyFormat("void f() { auto a = b->c(); }");
 }
 
+TEST_F(FormatTest, DeductionGuides) {
+  verifyFormat("template  A(const T &, const T &) -> A;");
+  verifyFormat("template  explicit A(T &, T &&) -> A;");
+  verifyFormat("template  S(Ts...) -> S;");
+  verifyFormat(
+  "template \n"
+  "array(T &&... t) -> array, sizeof...(T)>;");
+  verifyFormat("template  A() -> Afoo<3>())>;");
+  verifyFormat("template  A() -> A>)>;");
+  verifyFormat("template  A() -> Afoo<1>)>;");
+  verifyFormat("template  A() -> A<(3 < 2)>;");
+  verifyFormat("template  A() -> A<((3) < (2))>;");
+  verifyFormat("template  x() -> x<1>;");
+  verifyFormat("template  explicit x(T &) -> x<1>;");
+
+  // Ensure not deduction guides.
+  verifyFormat("c()->f();");
+  verifyFormat("x()->foo<1>;");
+  verifyFormat("x = p->foo<3>();");
+  verifyFormat("x()->x<1>();");
+  verifyFormat("x()->x<1>;");
+}
+
 TEST_F(FormatTest, BreaksFunctionDeclarationsWithTrailingTokens) {
   // Avoid breaking before trailing 'const' or other trailing annotations, if
   // they are not function-like.
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1350,6 +1350,70 @@
 }
   }
 
+  static FormatToken *untilMatchingParen(FormatToken *Current) {
+// Used when `MatchingParen` is not yet established.
+int ParenLevel = 0;
+while (Current) {
+  if (Current->is(tok::l_paren))
+ParenLevel++;
+  if (Current->is(tok::r_paren))
+ParenLevel--;
+  if (ParenLevel < 1)
+break;
+  Current = Current->Next;
+}
+return Current;
+  }
+
+  static bool isDeductionGuide(FormatToken ) {
+// Look for a deduction guide temaplte A(...) -> A<...>;
+if (Current.Previous && Current.Previous->is(tok::r_paren) &&
+Current.startsSequence(tok::arrow, tok::identifier, tok::less)) {
+  // Find the TemplateCloser.
+  FormatToken *TemplateCloser = Current.Next->Next;
+  int NestingLevel = 0;
+  while (TemplateCloser) {
+// Skip over an expressions in parens  A<(3 < 2)>;
+if (TemplateCloser->is(tok::l_paren)) {
+  // No Matching Paren yet so skip to matching paren
+  TemplateCloser = untilMatchingParen(TemplateCloser);
+}
+if (TemplateCloser->is(tok::less))
+  NestingLevel++;
+if (TemplateCloser->is(tok::greater))
+  NestingLevel--;
+if (NestingLevel < 1)
+  break;
+TemplateCloser = TemplateCloser->Next;
+  }
+  // Assuming we have found the end of the template ensure its followed
+  // with a semi-colon.
+  if (TemplateCloser && TemplateCloser->Next &&
+  TemplateCloser->Next->is(tok::semi) &&
+  Current.Previous->MatchingParen) {
+// Determine if the identifier `A` prior to the A<..>; is the same as
+// prior to the A(..)
+FormatToken *LeadingIdentifier =
+Current.Previous->MatchingParen->Previous;
+
+// Differentiate a deduction guide by seeing the
+// > of the template prior to the leading identifier.
+if (LeadingIdentifier) {
+  FormatToken *PriorLeadingIdentifier = LeadingIdentifier->Previous;
+  // Skip back past explicit decoration
+  if (PriorLeadingIdentifier &&
+  PriorLeadingIdentifier->is(tok::kw_explicit))
+PriorLeadingIdentifier = PriorLeadingIdentifier->Previous;
+
+  return (PriorLeadingIdentifier &&
+  PriorLeadingIdentifier->is(TT_TemplateCloser) &&
+  LeadingIdentifier->TokenText == Current.Next->TokenText);
+}
+  }
+}
+return false;
+  }
+
   void determineTokenType(FormatToken ) {
 if (!Current.is(TT_Unknown))
   // The token type is already known.
@@ -1397,6 +1461,10 @@
!Current.Previous->is(tok::kw_operator)) {
   // not auto operator->() -> xxx;
   Current.Type = TT_TrailingReturnArrow;
+
+} else if (isDeductionGuide(Current)) {
+  // Deduction guides trailing arrow " A(...) -> A;".
+  Current.Type = TT_TrailingReturnArrow;
 } else if 

[PATCH] D69577: [clang-format] [PR35518] C++17 deduction guides are wrongly formatted

2019-11-05 Thread Marek Kurdej via Phabricator via cfe-commits
curdeius added inline comments.



Comment at: clang/unittests/Format/FormatTest.cpp:4995
+  verifyFormat("c()->f();");
+  verifyFormat("x()->foo<1>;");
+  verifyFormat("x = p->foo<3>();");

MyDeveloperDay wrote:
> curdeius wrote:
> > What about:
> > 
> > ```
> > verifyFormat("x()->x<1>;");
> > ```
> > i.e. a function `x` returning a pointer to a class having a template member 
> > `x` (for instance a template variable).
> I'm unsure if we are the limit of being able to differentiate between the two?
Well, deduction guides always have a template parameter list before class name 
(unless I'm mistaken), so we should be able to distinguish the two.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69577/new/

https://reviews.llvm.org/D69577



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69577: [clang-format] [PR35518] C++17 deduction guides are wrongly formatted

2019-11-04 Thread MyDeveloperDay via Phabricator via cfe-commits
MyDeveloperDay marked 2 inline comments as done.
MyDeveloperDay added inline comments.



Comment at: clang/unittests/Format/FormatTest.cpp:4995
+  verifyFormat("c()->f();");
+  verifyFormat("x()->foo<1>;");
+  verifyFormat("x = p->foo<3>();");

curdeius wrote:
> What about:
> 
> ```
> verifyFormat("x()->x<1>;");
> ```
> i.e. a function `x` returning a pointer to a class having a template member 
> `x` (for instance a template variable).
I'm unsure if we are the limit of being able to differentiate between the two?


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69577/new/

https://reviews.llvm.org/D69577



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69577: [clang-format] [PR35518] C++17 deduction guides are wrongly formatted

2019-11-04 Thread Marek Kurdej via Phabricator via cfe-commits
curdeius added a comment.

Minor comments.




Comment at: clang/lib/Format/TokenAnnotator.cpp:1354
+  static FormatToken *untilMatchingParen(FormatToken *Current) {
+// for when MatchingParen is not yet established
+int ParenLevel = 0;

Please write full-phrase comments.



Comment at: clang/unittests/Format/FormatTest.cpp:4995
+  verifyFormat("c()->f();");
+  verifyFormat("x()->foo<1>;");
+  verifyFormat("x = p->foo<3>();");

What about:

```
verifyFormat("x()->x<1>;");
```
i.e. a function `x` returning a pointer to a class having a template member `x` 
(for instance a template variable).


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69577/new/

https://reviews.llvm.org/D69577



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69577: [clang-format] [PR35518] C++17 deduction guides are wrongly formatted

2019-10-31 Thread MyDeveloperDay via Phabricator via cfe-commits
MyDeveloperDay updated this revision to Diff 227317.
MyDeveloperDay marked 4 inline comments as done.
MyDeveloperDay added a comment.

Add additional test case


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69577/new/

https://reviews.llvm.org/D69577

Files:
  clang/lib/Format/TokenAnnotator.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -4977,6 +4977,25 @@
   verifyFormat("void f() { auto a = b->c(); }");
 }
 
+TEST_F(FormatTest, DeductionGuides) {
+  verifyFormat("template  A(const T &, const T &) -> A;");
+  verifyFormat("template  explicit A(T &, T &&) -> A;");
+  verifyFormat("template  S(Ts...) -> S;");
+  verifyFormat(
+  "template \n"
+  "array(T &&... t) -> array, sizeof...(T)>;");
+  verifyFormat("A() -> Afoo<3>())>;");
+  verifyFormat("A() -> A>)>;");
+  verifyFormat("A() -> Afoo<1>)>;");
+  verifyFormat("A() -> A<(3 < 2)>;");
+  verifyFormat("A() -> A<((3) < (2))>;");
+
+  // Ensure not deduction guides.
+  verifyFormat("c()->f();");
+  verifyFormat("x()->foo<1>;");
+  verifyFormat("x = p->foo<3>();");
+}
+
 TEST_F(FormatTest, BreaksFunctionDeclarationsWithTrailingTokens) {
   // Avoid breaking before trailing 'const' or other trailing annotations, if
   // they are not function-like.
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1350,6 +1350,58 @@
 }
   }
 
+  static FormatToken *untilMatchingParen(FormatToken *Current) {
+// for when MatchingParen is not yet established
+int ParenLevel = 0;
+while (Current) {
+  if (Current->is(tok::l_paren))
+ParenLevel++;
+  if (Current->is(tok::r_paren))
+ParenLevel--;
+  if (ParenLevel < 1)
+break;
+  Current = Current->Next;
+}
+return Current;
+  }
+
+  static bool isDeductionGuide(FormatToken ) {
+// Look for a deduction guide A(...) -> A<...>;
+if (Current.Previous && Current.Previous->is(tok::r_paren) &&
+Current.startsSequence(tok::arrow, tok::identifier, tok::less)) {
+  // Find the TemplateCloser.
+  FormatToken *TemplateCloser = Current.Next->Next;
+  int NestingLevel = 0;
+  while (TemplateCloser) {
+// Skip over an expressions in parens  A<(3 < 2)>;
+if (TemplateCloser->is(tok::l_paren)) {
+  // No Matching Paren yet so skip to matching paren
+  TemplateCloser = untilMatchingParen(TemplateCloser);
+}
+if (TemplateCloser->is(tok::less))
+  NestingLevel++;
+if (TemplateCloser->is(tok::greater))
+  NestingLevel--;
+if (NestingLevel < 1)
+  break;
+TemplateCloser = TemplateCloser->Next;
+  }
+  // Assuming we have found the end of the template ensure its followed
+  // with a ;
+  if (TemplateCloser && TemplateCloser->Next &&
+  TemplateCloser->Next->is(tok::semi) &&
+  Current.Previous->MatchingParen) {
+// Determine if the identifier `A` prior to the A<..>; is the same as
+// prior to the A(..)
+FormatToken *LeadingIdentifier =
+Current.Previous->MatchingParen->Previous;
+return (LeadingIdentifier &&
+LeadingIdentifier->TokenText == Current.Next->TokenText);
+  }
+}
+return false;
+  }
+
   void determineTokenType(FormatToken ) {
 if (!Current.is(TT_Unknown))
   // The token type is already known.
@@ -1397,6 +1449,10 @@
!Current.Previous->is(tok::kw_operator)) {
   // not auto operator->() -> xxx;
   Current.Type = TT_TrailingReturnArrow;
+
+} else if (isDeductionGuide(Current)) {
+  // Deduction guides trailing arrow " A(...) -> A;".
+  Current.Type = TT_TrailingReturnArrow;
 } else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) {
   Current.Type = determineStarAmpUsage(Current,
Contexts.back().CanBeExpression &&
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69577: [clang-format] [PR35518] C++17 deduction guides are wrongly formatted

2019-10-31 Thread MyDeveloperDay via Phabricator via cfe-commits
MyDeveloperDay added inline comments.



Comment at: clang/lib/Format/TokenAnnotator.cpp:1371
+if (Current.Previous && Current.Previous->is(tok::r_paren) &&
+Current.startsSequence(tok::arrow, tok::identifier, tok::less)) {
+  // Find the TemplateCloser.

lichray wrote:
> Maybe make use of some `TT_TemplateOpener`?
We can't use TT_TemplateOpener  because like MatchParen it hasn't been set yet 
on the downstream tokens



Comment at: clang/unittests/Format/FormatTest.cpp:4987
+  "array(T &&... t) -> array, sizeof...(T)>;");
+  verifyFormat("A() -> Afoo<3>())>;");
+  verifyFormat("A() -> Afoo<1>)>;");

lichray wrote:
> Does `A() -> A>)>` (C++11 `>>`) work?
this should work because we are skipping everything in between the `()`


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69577/new/

https://reviews.llvm.org/D69577



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69577: [clang-format] [PR35518] C++17 deduction guides are wrongly formatted

2019-10-31 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

The functionality looks acceptable.  Trying to parse the whole thing still 
looks fragile to me.  I expect code owner to take a look at this change.




Comment at: clang/lib/Format/TokenAnnotator.cpp:1371
+if (Current.Previous && Current.Previous->is(tok::r_paren) &&
+Current.startsSequence(tok::arrow, tok::identifier, tok::less)) {
+  // Find the TemplateCloser.

Maybe make use of some `TT_TemplateOpener`?



Comment at: clang/unittests/Format/FormatTest.cpp:4987
+  "array(T &&... t) -> array, sizeof...(T)>;");
+  verifyFormat("A() -> Afoo<3>())>;");
+  verifyFormat("A() -> Afoo<1>)>;");

Does `A() -> A>)>` (C++11 `>>`) work?


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69577/new/

https://reviews.llvm.org/D69577



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69577: [clang-format] [PR35518] C++17 deduction guides are wrongly formatted

2019-10-31 Thread MyDeveloperDay via Phabricator via cfe-commits
MyDeveloperDay updated this revision to Diff 227241.
MyDeveloperDay marked an inline comment as done.
MyDeveloperDay set the repository for this revision to rC Clang.
MyDeveloperDay added a comment.

Address review comments, deduction guides with embedded parens


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69577/new/

https://reviews.llvm.org/D69577

Files:
  clang/lib/Format/TokenAnnotator.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -4977,6 +4977,24 @@
   verifyFormat("void f() { auto a = b->c(); }");
 }
 
+TEST_F(FormatTest, DeductionGuides) {
+  verifyFormat("template  A(const T &, const T &) -> A;");
+  verifyFormat("template  explicit A(T &, T &&) -> A;");
+  verifyFormat("template  S(Ts...) -> S;");
+  verifyFormat(
+  "template \n"
+  "array(T &&... t) -> array, sizeof...(T)>;");
+  verifyFormat("A() -> Afoo<3>())>;");
+  verifyFormat("A() -> Afoo<1>)>;");
+  verifyFormat("A() -> A<(3 < 2)>;");
+  verifyFormat("A() -> A<((3) < (2))>;");
+
+  // Ensure not deduction guides.
+  verifyFormat("c()->f();");
+  verifyFormat("x()->foo<1>;");
+  verifyFormat("x = p->foo<3>();");
+}
+
 TEST_F(FormatTest, BreaksFunctionDeclarationsWithTrailingTokens) {
   // Avoid breaking before trailing 'const' or other trailing annotations, if
   // they are not function-like.
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1350,6 +1350,58 @@
 }
   }
 
+  static FormatToken *untilMatchingParen(FormatToken *Current) {
+// for when MatchingParen is not yet established
+int ParenLevel = 0;
+while (Current) {
+  if (Current->is(tok::l_paren))
+ParenLevel++;
+  if (Current->is(tok::r_paren))
+ParenLevel--;
+  if (ParenLevel < 1)
+break;
+  Current = Current->Next;
+}
+return Current;
+  }
+
+  static bool isDeductionGuide(FormatToken ) {
+// Look for a deduction guide A(...) -> A<...>;
+if (Current.Previous && Current.Previous->is(tok::r_paren) &&
+Current.startsSequence(tok::arrow, tok::identifier, tok::less)) {
+  // Find the TemplateCloser.
+  FormatToken *TemplateCloser = Current.Next->Next;
+  int NestingLevel = 0;
+  while (TemplateCloser) {
+// Skip over an expressions in parens  A<(3 < 2)>;
+if (TemplateCloser->is(tok::l_paren)) {
+  // No Matching Paren yet so skip to matching paren
+  TemplateCloser = untilMatchingParen(TemplateCloser);
+}
+if (TemplateCloser->is(tok::less))
+  NestingLevel++;
+if (TemplateCloser->is(tok::greater))
+  NestingLevel--;
+if (NestingLevel < 1)
+  break;
+TemplateCloser = TemplateCloser->Next;
+  }
+  // Assuming we have found the end of the template ensure its followed
+  // with a ;
+  if (TemplateCloser && TemplateCloser->Next &&
+  TemplateCloser->Next->is(tok::semi) &&
+  Current.Previous->MatchingParen) {
+// Determine if the identifier `A` prior to the A<..>; is the same as
+// prior to the A(..)
+FormatToken *LeadingIdentifier =
+Current.Previous->MatchingParen->Previous;
+return (LeadingIdentifier &&
+LeadingIdentifier->TokenText == Current.Next->TokenText);
+  }
+}
+return false;
+  }
+
   void determineTokenType(FormatToken ) {
 if (!Current.is(TT_Unknown))
   // The token type is already known.
@@ -1397,6 +1449,10 @@
!Current.Previous->is(tok::kw_operator)) {
   // not auto operator->() -> xxx;
   Current.Type = TT_TrailingReturnArrow;
+
+} else if (isDeductionGuide(Current)) {
+  // Deduction guides trailing arrow "...) -> A;".
+  Current.Type = TT_TrailingReturnArrow;
 } else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) {
   Current.Type = determineStarAmpUsage(Current,
Contexts.back().CanBeExpression &&
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69577: [clang-format] [PR35518] C++17 deduction guides are wrongly formatted

2019-10-30 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added inline comments.



Comment at: clang/lib/Format/TokenAnnotator.cpp:1354
+  static bool isDeductionGuide(FormatToken ) {
+// Look for a deduction guide A()...) -> A<...>;
+if (Current.Previous && Current.Previous->is(tok::r_paren) &&

Parentheses not matching is comment.



Comment at: clang/lib/Format/TokenAnnotator.cpp:1365
+if (TemplateCloser->is(tok::greater))
+  NestingLevel--;
+if (TemplateCloser->is(tok::kw_decltype))

Does this work?  What about `A() -> A<(3 < 2)>;`?



Comment at: clang/lib/Format/TokenAnnotator.cpp:1366
+  NestingLevel--;
+if (TemplateCloser->is(tok::kw_decltype))
+  return false;

What's this for?  What about `A() -> Afoo<1>>);`

I guess we don't have to look for the end of template, because a class X can't 
refer to its member called X with `->` because that member is constructor.  The 
approach to match the identifiers may not work in the future but may work fine 
for now.



Comment at: clang/unittests/Format/FormatTest.cpp:4992
+  verifyFormat("x = p->foo<3>();");
+  verifyFormat("A()->Afoo<3>())>;");
+}

This looks like a deduction guide.  It should be formatted as `A() -> 
Afoo<3>())>;` I assume?  If you cannot cover this case in this 
patch, this test case needs a comment.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69577/new/

https://reviews.llvm.org/D69577



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69577: [clang-format] [PR35518] C++17 deduction guides are wrongly formatted

2019-10-30 Thread MyDeveloperDay via Phabricator via cfe-commits
MyDeveloperDay updated this revision to Diff 227166.
MyDeveloperDay added a comment.

move detection of deduction guides into a function, add additional negative 
tests


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69577/new/

https://reviews.llvm.org/D69577

Files:
  clang/lib/Format/TokenAnnotator.cpp
  clang/unittests/Format/FormatTest.cpp


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -4977,6 +4977,21 @@
   verifyFormat("void f() { auto a = b->c(); }");
 }
 
+TEST_F(FormatTest, DeductionGuides) {
+  verifyFormat("template  A(const T &, const T &) -> A;");
+  verifyFormat("template  explicit A(T &, T &&) -> A;");
+  verifyFormat("template  S(Ts...) -> S;");
+  verifyFormat(
+  "template \n"
+  "array(T &&... t) -> array, sizeof...(T)>;");
+
+  // Ensure not deduction guides.
+  verifyFormat("c()->f();");
+  verifyFormat("x()->foo<1>;");
+  verifyFormat("x = p->foo<3>();");
+  verifyFormat("A()->Afoo<3>())>;");
+}
+
 TEST_F(FormatTest, BreaksFunctionDeclarationsWithTrailingTokens) {
   // Avoid breaking before trailing 'const' or other trailing annotations, if
   // they are not function-like.
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1350,6 +1350,38 @@
 }
   }
 
+  static bool isDeductionGuide(FormatToken ) {
+// Look for a deduction guide A()...) -> A<...>;
+if (Current.Previous && Current.Previous->is(tok::r_paren) &&
+Current.startsSequence(tok::arrow, tok::identifier, tok::less)) {
+  // Find the TemplateCloser.
+  FormatToken *TemplateCloser = Current.Next->Next;
+  int NestingLevel = 1;
+  while (TemplateCloser && NestingLevel > 0) {
+TemplateCloser = TemplateCloser->Next;
+if (TemplateCloser->is(tok::less))
+  NestingLevel++;
+if (TemplateCloser->is(tok::greater))
+  NestingLevel--;
+if (TemplateCloser->is(tok::kw_decltype))
+  return false;
+  }
+  // Assuming we have found the end of the template ensure its followed
+  // with a ;
+  if (TemplateCloser && TemplateCloser->Next &&
+  TemplateCloser->Next->is(tok::semi) &&
+  Current.Previous->MatchingParen) {
+// Determine if the identifier `A` prior to the A<..>; is the same as
+// prior to the A(..)
+FormatToken *LeadingIdentifier =
+Current.Previous->MatchingParen->Previous;
+return (LeadingIdentifier &&
+LeadingIdentifier->TokenText == Current.Next->TokenText);
+  }
+}
+return false;
+  }
+
   void determineTokenType(FormatToken ) {
 if (!Current.is(TT_Unknown))
   // The token type is already known.
@@ -1397,6 +1429,10 @@
!Current.Previous->is(tok::kw_operator)) {
   // not auto operator->() -> xxx;
   Current.Type = TT_TrailingReturnArrow;
+
+} else if (isDeductionGuide(Current)) {
+  // Deduction guides trailing arrow "...) -> A;".
+  Current.Type = TT_TrailingReturnArrow;
 } else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) {
   Current.Type = determineStarAmpUsage(Current,
Contexts.back().CanBeExpression &&


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -4977,6 +4977,21 @@
   verifyFormat("void f() { auto a = b->c(); }");
 }
 
+TEST_F(FormatTest, DeductionGuides) {
+  verifyFormat("template  A(const T &, const T &) -> A;");
+  verifyFormat("template  explicit A(T &, T &&) -> A;");
+  verifyFormat("template  S(Ts...) -> S;");
+  verifyFormat(
+  "template \n"
+  "array(T &&... t) -> array, sizeof...(T)>;");
+
+  // Ensure not deduction guides.
+  verifyFormat("c()->f();");
+  verifyFormat("x()->foo<1>;");
+  verifyFormat("x = p->foo<3>();");
+  verifyFormat("A()->Afoo<3>())>;");
+}
+
 TEST_F(FormatTest, BreaksFunctionDeclarationsWithTrailingTokens) {
   // Avoid breaking before trailing 'const' or other trailing annotations, if
   // they are not function-like.
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1350,6 +1350,38 @@
 }
   }
 
+  static bool isDeductionGuide(FormatToken ) {
+// Look for a deduction guide A()...) -> A<...>;
+if (Current.Previous && Current.Previous->is(tok::r_paren) &&
+Current.startsSequence(tok::arrow, tok::identifier, tok::less)) {
+  // Find the TemplateCloser.
+  FormatToken *TemplateCloser = Current.Next->Next;
+  int NestingLevel = 1;
+  while 

[PATCH] D69577: [clang-format] [PR35518] C++17 deduction guides are wrongly formatted

2019-10-30 Thread MyDeveloperDay via Phabricator via cfe-commits
MyDeveloperDay marked 4 inline comments as done.
MyDeveloperDay added inline comments.



Comment at: clang/lib/Format/TokenAnnotator.cpp:1400-1403
+} else if (Current.Previous && Current.Previous->is(tok::r_paren) &&
+   Current.startsSequence(tok::arrow, tok::identifier, tok::less)) 
{
+  // Deduction guides trailing arrow "...) -> A".
+  Current.Type = TT_TrailingReturnArrow;

lichray wrote:
> MyDeveloperDay wrote:
> > lichray wrote:
> > > klimek wrote:
> > > > Why doesn't this trigger on function templates:
> > > >   c()->f();
> > > > 
> > > Comparing to the `else if` branch above, several questions can arise:
> > > 
> > > 1. Has deduction-guide be considered a declaration (it is, of course, in 
> > > standard)?  If yes, without `MustBeDeclaration`, how `x = p->foo<3>();` 
> > > being formatted?
> > > 2. Without restrictions on `NestingLevel`, how `A() -> 
> > > Afoo<3>())>;` being formatted?
> > > 3. How `x()->foo<1>;` being formatted?  What's the difference between 
> > > this and a deduction-guide?  A deduction-guide has to follow 
> > > `TheSameType(...) -> TheSameType<>;` and appears only at namespace 
> > > level, do these help?
> > > 
> > > Oh no, `auto x = p -> foo<1>();` this is a bug (I will look for bug 
> > > reports, don't mind).
> > This case I agree is wrong  (but that comes from the existing rule no?)
> > ```
> > auto x = p -> foo<1>();
> > ```
> > 
> > The other examples are currently as follows
> > ```
> > c()->f();
> > x()->foo<1>;
> > x = p->foo<3>();
> > A()->Afoo<3>())>;
> > ```
> > 
> > This is how they look from the last build @hans  made on the 17th October
> > 
> > ```
> > auto x = p -> foo<1>();
> > c()->f();
> > x()->foo<1>;
> > x = p->foo<3>();
> > A()->Afoo<3>())>;
> > ```
> > 
> > Debug info
> > 
> > ```
> > 
> > AnnotatedTokens(L=0):
> >  M=0 C=0 T=Unknown S=1 B=0 BK=0 P=0 Name=auto L=4 PPK=2 FakeLParens=2/ 
> > FakeRParens=0 II=0x2c52129f718 Text='auto'
> >  M=0 C=1 T=StartOfName S=1 B=0 BK=0 P=220 Name=identifier L=6 PPK=2 
> > FakeLParens= FakeRParens=0 II=0x2c5212a2da8 Text='x'
> >  M=0 C=0 T=BinaryOperator S=1 B=0 BK=0 P=22 Name=equal L=8 PPK=2 
> > FakeLParens= FakeRParens=0 II=0x0 Text='='
> >  M=0 C=1 T=Unknown S=1 B=0 BK=0 P=22 Name=identifier L=10 PPK=2 
> > FakeLParens=0/ FakeRParens=0 II=0x2c5212a2dd8 Text='p'
> >  M=0 C=1 T=TrailingReturnArrow S=1 B=0 BK=0 P=23 Name=arrow L=13 PPK=2 
> > FakeLParens= FakeRParens=0 II=0x0 Text='->'
> >  M=0 C=0 T=Unknown S=1 B=0 BK=0 P=23 Name=identifier L=17 PPK=2 
> > FakeLParens= FakeRParens=0 II=0x2c5212a2d78 Text='foo'
> >  M=0 C=0 T=TemplateOpener S=0 B=0 BK=0 P=30 Name=less L=18 PPK=2 
> > FakeLParens= FakeRParens=0 II=0x0 Text='<'
> >  M=0 C=1 T=Unknown S=0 B=0 BK=0 P=360 Name=numeric_constant L=19 PPK=2 
> > FakeLParens= FakeRParens=0 II=0x0 Text='1'
> >  M=0 C=0 T=TemplateCloser S=0 B=0 BK=0 P=270 Name=greater L=20 PPK=2 
> > FakeLParens= FakeRParens=0 II=0x0 Text='>'
> >  M=0 C=0 T=Unknown S=0 B=0 BK=0 P=30 Name=l_paren L=21 PPK=2 FakeLParens= 
> > FakeRParens=0 II=0x0 Text='('
> >  M=0 C=0 T=Unknown S=0 B=0 BK=0 P=59 Name=r_paren L=22 PPK=2 FakeLParens= 
> > FakeRParens=2 II=0x0 Text=')'
> >  M=0 C=0 T=Unknown S=0 B=0 BK=0 P=23 Name=semi L=23 PPK=2 FakeLParens= 
> > FakeRParens=0 II=0x0 Text=';'
> > 
> > AnnotatedTokens(L=0):
> >  M=0 C=0 T=Unknown S=1 B=0 BK=0 P=0 Name=identifier L=1 PPK=2 
> > FakeLParens=0/ FakeRParens=0 II=0x2c5212a2e08 Text='c'
> >  M=0 C=0 T=Unknown S=0 B=0 BK=0 P=23 Name=l_paren L=2 PPK=2 FakeLParens= 
> > FakeRParens=0 II=0x0 Text='('
> >  M=0 C=0 T=Unknown S=0 B=0 BK=0 P=140 Name=r_paren L=3 PPK=2 FakeLParens= 
> > FakeRParens=0 II=0x0 Text=')'
> >  M=0 C=1 T=Unknown S=0 B=0 BK=0 P=170 Name=arrow L=5 PPK=2 FakeLParens= 
> > FakeRParens=0 II=0x0 Text='->'
> >  M=0 C=0 T=TrailingAnnotation S=0 B=0 BK=0 P=190 Name=identifier L=6 PPK=2 
> > FakeLParens= FakeRParens=0 II=0x2c5212a2d48 Text='f'
> >  M=0 C=0 T=TemplateOpener S=0 B=0 BK=0 P=30 Name=less L=7 PPK=2 
> > FakeLParens= FakeRParens=0 II=0x0 Text='<'
> >  M=0 C=1 T=Unknown S=0 B=0 BK=0 P=360 Name=int L=10 PPK=2 FakeLParens= 
> > FakeRParens=0 II=0x2c52129fa50 Text='int'
> >  M=0 C=0 T=TemplateCloser S=0 B=0 BK=0 P=270 Name=greater L=11 PPK=2 
> > FakeLParens= FakeRParens=0 II=0x0 Text='>'
> >  M=0 C=0 T=Unknown S=0 B=0 BK=0 P=30 Name=l_paren L=12 PPK=2 FakeLParens= 
> > FakeRParens=0 II=0x0 Text='('
> >  M=0 C=0 T=Unknown S=0 B=0 BK=0 P=140 Name=r_paren L=13 PPK=2 FakeLParens= 
> > FakeRParens=1 II=0x0 Text=')'
> >  M=0 C=0 T=Unknown S=0 B=0 BK=0 P=23 Name=semi L=14 PPK=2 FakeLParens= 
> > FakeRParens=0 II=0x0 Text=';'
> > 
> > AnnotatedTokens(L=0):
> >  M=0 C=0 T=Unknown S=1 B=0 BK=0 P=0 Name=identifier L=1 PPK=2 
> > FakeLParens=0/ FakeRParens=0 II=0x2c5212a2da8 Text='x'
> >  M=0 C=0 T=Unknown S=0 B=0 BK=0 P=23 Name=l_paren L=2 PPK=2 FakeLParens= 
> > FakeRParens=0 II=0x0 Text='('
> >  M=0 C=0 T=Unknown S=0 B=0 BK=0 P=140 Name=r_paren L=3 PPK=2 FakeLParens= 
> > 

[PATCH] D69577: [clang-format] [PR35518] C++17 deduction guides are wrongly formatted

2019-10-30 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added inline comments.



Comment at: clang/lib/Format/TokenAnnotator.cpp:1400-1403
+} else if (Current.Previous && Current.Previous->is(tok::r_paren) &&
+   Current.startsSequence(tok::arrow, tok::identifier, tok::less)) 
{
+  // Deduction guides trailing arrow "...) -> A".
+  Current.Type = TT_TrailingReturnArrow;

MyDeveloperDay wrote:
> lichray wrote:
> > klimek wrote:
> > > Why doesn't this trigger on function templates:
> > >   c()->f();
> > > 
> > Comparing to the `else if` branch above, several questions can arise:
> > 
> > 1. Has deduction-guide be considered a declaration (it is, of course, in 
> > standard)?  If yes, without `MustBeDeclaration`, how `x = p->foo<3>();` 
> > being formatted?
> > 2. Without restrictions on `NestingLevel`, how `A() -> 
> > Afoo<3>())>;` being formatted?
> > 3. How `x()->foo<1>;` being formatted?  What's the difference between this 
> > and a deduction-guide?  A deduction-guide has to follow `TheSameType(...) 
> > -> TheSameType<>;` and appears only at namespace level, do these help?
> > 
> > Oh no, `auto x = p -> foo<1>();` this is a bug (I will look for bug 
> > reports, don't mind).
> This case I agree is wrong  (but that comes from the existing rule no?)
> ```
> auto x = p -> foo<1>();
> ```
> 
> The other examples are currently as follows
> ```
> c()->f();
> x()->foo<1>;
> x = p->foo<3>();
> A()->Afoo<3>())>;
> ```
> 
> This is how they look from the last build @hans  made on the 17th October
> 
> ```
> auto x = p -> foo<1>();
> c()->f();
> x()->foo<1>;
> x = p->foo<3>();
> A()->Afoo<3>())>;
> ```
> 
> Debug info
> 
> ```
> 
> AnnotatedTokens(L=0):
>  M=0 C=0 T=Unknown S=1 B=0 BK=0 P=0 Name=auto L=4 PPK=2 FakeLParens=2/ 
> FakeRParens=0 II=0x2c52129f718 Text='auto'
>  M=0 C=1 T=StartOfName S=1 B=0 BK=0 P=220 Name=identifier L=6 PPK=2 
> FakeLParens= FakeRParens=0 II=0x2c5212a2da8 Text='x'
>  M=0 C=0 T=BinaryOperator S=1 B=0 BK=0 P=22 Name=equal L=8 PPK=2 FakeLParens= 
> FakeRParens=0 II=0x0 Text='='
>  M=0 C=1 T=Unknown S=1 B=0 BK=0 P=22 Name=identifier L=10 PPK=2 
> FakeLParens=0/ FakeRParens=0 II=0x2c5212a2dd8 Text='p'
>  M=0 C=1 T=TrailingReturnArrow S=1 B=0 BK=0 P=23 Name=arrow L=13 PPK=2 
> FakeLParens= FakeRParens=0 II=0x0 Text='->'
>  M=0 C=0 T=Unknown S=1 B=0 BK=0 P=23 Name=identifier L=17 PPK=2 FakeLParens= 
> FakeRParens=0 II=0x2c5212a2d78 Text='foo'
>  M=0 C=0 T=TemplateOpener S=0 B=0 BK=0 P=30 Name=less L=18 PPK=2 FakeLParens= 
> FakeRParens=0 II=0x0 Text='<'
>  M=0 C=1 T=Unknown S=0 B=0 BK=0 P=360 Name=numeric_constant L=19 PPK=2 
> FakeLParens= FakeRParens=0 II=0x0 Text='1'
>  M=0 C=0 T=TemplateCloser S=0 B=0 BK=0 P=270 Name=greater L=20 PPK=2 
> FakeLParens= FakeRParens=0 II=0x0 Text='>'
>  M=0 C=0 T=Unknown S=0 B=0 BK=0 P=30 Name=l_paren L=21 PPK=2 FakeLParens= 
> FakeRParens=0 II=0x0 Text='('
>  M=0 C=0 T=Unknown S=0 B=0 BK=0 P=59 Name=r_paren L=22 PPK=2 FakeLParens= 
> FakeRParens=2 II=0x0 Text=')'
>  M=0 C=0 T=Unknown S=0 B=0 BK=0 P=23 Name=semi L=23 PPK=2 FakeLParens= 
> FakeRParens=0 II=0x0 Text=';'
> 
> AnnotatedTokens(L=0):
>  M=0 C=0 T=Unknown S=1 B=0 BK=0 P=0 Name=identifier L=1 PPK=2 FakeLParens=0/ 
> FakeRParens=0 II=0x2c5212a2e08 Text='c'
>  M=0 C=0 T=Unknown S=0 B=0 BK=0 P=23 Name=l_paren L=2 PPK=2 FakeLParens= 
> FakeRParens=0 II=0x0 Text='('
>  M=0 C=0 T=Unknown S=0 B=0 BK=0 P=140 Name=r_paren L=3 PPK=2 FakeLParens= 
> FakeRParens=0 II=0x0 Text=')'
>  M=0 C=1 T=Unknown S=0 B=0 BK=0 P=170 Name=arrow L=5 PPK=2 FakeLParens= 
> FakeRParens=0 II=0x0 Text='->'
>  M=0 C=0 T=TrailingAnnotation S=0 B=0 BK=0 P=190 Name=identifier L=6 PPK=2 
> FakeLParens= FakeRParens=0 II=0x2c5212a2d48 Text='f'
>  M=0 C=0 T=TemplateOpener S=0 B=0 BK=0 P=30 Name=less L=7 PPK=2 FakeLParens= 
> FakeRParens=0 II=0x0 Text='<'
>  M=0 C=1 T=Unknown S=0 B=0 BK=0 P=360 Name=int L=10 PPK=2 FakeLParens= 
> FakeRParens=0 II=0x2c52129fa50 Text='int'
>  M=0 C=0 T=TemplateCloser S=0 B=0 BK=0 P=270 Name=greater L=11 PPK=2 
> FakeLParens= FakeRParens=0 II=0x0 Text='>'
>  M=0 C=0 T=Unknown S=0 B=0 BK=0 P=30 Name=l_paren L=12 PPK=2 FakeLParens= 
> FakeRParens=0 II=0x0 Text='('
>  M=0 C=0 T=Unknown S=0 B=0 BK=0 P=140 Name=r_paren L=13 PPK=2 FakeLParens= 
> FakeRParens=1 II=0x0 Text=')'
>  M=0 C=0 T=Unknown S=0 B=0 BK=0 P=23 Name=semi L=14 PPK=2 FakeLParens= 
> FakeRParens=0 II=0x0 Text=';'
> 
> AnnotatedTokens(L=0):
>  M=0 C=0 T=Unknown S=1 B=0 BK=0 P=0 Name=identifier L=1 PPK=2 FakeLParens=0/ 
> FakeRParens=0 II=0x2c5212a2da8 Text='x'
>  M=0 C=0 T=Unknown S=0 B=0 BK=0 P=23 Name=l_paren L=2 PPK=2 FakeLParens= 
> FakeRParens=0 II=0x0 Text='('
>  M=0 C=0 T=Unknown S=0 B=0 BK=0 P=140 Name=r_paren L=3 PPK=2 FakeLParens= 
> FakeRParens=0 II=0x0 Text=')'
>  M=0 C=1 T=Unknown S=0 B=0 BK=0 P=170 Name=arrow L=5 PPK=2 FakeLParens= 
> FakeRParens=0 II=0x0 Text='->'
>  M=0 C=0 T=TrailingAnnotation S=0 B=0 BK=0 P=190 Name=identifier L=8 PPK=2 
> FakeLParens= FakeRParens=0 II=0x2c5212a2d78 Text='foo'
>  M=0 C=0 

[PATCH] D69577: [clang-format] [PR35518] C++17 deduction guides are wrongly formatted

2019-10-30 Thread MyDeveloperDay via Phabricator via cfe-commits
MyDeveloperDay added a comment.

Sorry ignore my last results, let me rerun, I was using the revision without 
the change.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69577/new/

https://reviews.llvm.org/D69577



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69577: [clang-format] [PR35518] C++17 deduction guides are wrongly formatted

2019-10-30 Thread MyDeveloperDay via Phabricator via cfe-commits
MyDeveloperDay marked an inline comment as done.
MyDeveloperDay added a subscriber: hans.
MyDeveloperDay added inline comments.



Comment at: clang/lib/Format/TokenAnnotator.cpp:1400-1403
+} else if (Current.Previous && Current.Previous->is(tok::r_paren) &&
+   Current.startsSequence(tok::arrow, tok::identifier, tok::less)) 
{
+  // Deduction guides trailing arrow "...) -> A".
+  Current.Type = TT_TrailingReturnArrow;

lichray wrote:
> klimek wrote:
> > Why doesn't this trigger on function templates:
> >   c()->f();
> > 
> Comparing to the `else if` branch above, several questions can arise:
> 
> 1. Has deduction-guide be considered a declaration (it is, of course, in 
> standard)?  If yes, without `MustBeDeclaration`, how `x = p->foo<3>();` being 
> formatted?
> 2. Without restrictions on `NestingLevel`, how `A() -> 
> Afoo<3>())>;` being formatted?
> 3. How `x()->foo<1>;` being formatted?  What's the difference between this 
> and a deduction-guide?  A deduction-guide has to follow `TheSameType(...) -> 
> TheSameType<>;` and appears only at namespace level, do these help?
> 
> Oh no, `auto x = p -> foo<1>();` this is a bug (I will look for bug reports, 
> don't mind).
This case I agree is wrong  (but that comes from the existing rule no?)
```
auto x = p -> foo<1>();
```

The other examples are currently as follows
```
c()->f();
x()->foo<1>;
x = p->foo<3>();
A()->Afoo<3>())>;
```

This is how they look from the last build @hans  made on the 17th October

```
auto x = p -> foo<1>();
c()->f();
x()->foo<1>;
x = p->foo<3>();
A()->Afoo<3>())>;
```

Debug info

```

AnnotatedTokens(L=0):
 M=0 C=0 T=Unknown S=1 B=0 BK=0 P=0 Name=auto L=4 PPK=2 FakeLParens=2/ 
FakeRParens=0 II=0x2c52129f718 Text='auto'
 M=0 C=1 T=StartOfName S=1 B=0 BK=0 P=220 Name=identifier L=6 PPK=2 
FakeLParens= FakeRParens=0 II=0x2c5212a2da8 Text='x'
 M=0 C=0 T=BinaryOperator S=1 B=0 BK=0 P=22 Name=equal L=8 PPK=2 FakeLParens= 
FakeRParens=0 II=0x0 Text='='
 M=0 C=1 T=Unknown S=1 B=0 BK=0 P=22 Name=identifier L=10 PPK=2 FakeLParens=0/ 
FakeRParens=0 II=0x2c5212a2dd8 Text='p'
 M=0 C=1 T=TrailingReturnArrow S=1 B=0 BK=0 P=23 Name=arrow L=13 PPK=2 
FakeLParens= FakeRParens=0 II=0x0 Text='->'
 M=0 C=0 T=Unknown S=1 B=0 BK=0 P=23 Name=identifier L=17 PPK=2 FakeLParens= 
FakeRParens=0 II=0x2c5212a2d78 Text='foo'
 M=0 C=0 T=TemplateOpener S=0 B=0 BK=0 P=30 Name=less L=18 PPK=2 FakeLParens= 
FakeRParens=0 II=0x0 Text='<'
 M=0 C=1 T=Unknown S=0 B=0 BK=0 P=360 Name=numeric_constant L=19 PPK=2 
FakeLParens= FakeRParens=0 II=0x0 Text='1'
 M=0 C=0 T=TemplateCloser S=0 B=0 BK=0 P=270 Name=greater L=20 PPK=2 
FakeLParens= FakeRParens=0 II=0x0 Text='>'
 M=0 C=0 T=Unknown S=0 B=0 BK=0 P=30 Name=l_paren L=21 PPK=2 FakeLParens= 
FakeRParens=0 II=0x0 Text='('
 M=0 C=0 T=Unknown S=0 B=0 BK=0 P=59 Name=r_paren L=22 PPK=2 FakeLParens= 
FakeRParens=2 II=0x0 Text=')'
 M=0 C=0 T=Unknown S=0 B=0 BK=0 P=23 Name=semi L=23 PPK=2 FakeLParens= 
FakeRParens=0 II=0x0 Text=';'

AnnotatedTokens(L=0):
 M=0 C=0 T=Unknown S=1 B=0 BK=0 P=0 Name=identifier L=1 PPK=2 FakeLParens=0/ 
FakeRParens=0 II=0x2c5212a2e08 Text='c'
 M=0 C=0 T=Unknown S=0 B=0 BK=0 P=23 Name=l_paren L=2 PPK=2 FakeLParens= 
FakeRParens=0 II=0x0 Text='('
 M=0 C=0 T=Unknown S=0 B=0 BK=0 P=140 Name=r_paren L=3 PPK=2 FakeLParens= 
FakeRParens=0 II=0x0 Text=')'
 M=0 C=1 T=Unknown S=0 B=0 BK=0 P=170 Name=arrow L=5 PPK=2 FakeLParens= 
FakeRParens=0 II=0x0 Text='->'
 M=0 C=0 T=TrailingAnnotation S=0 B=0 BK=0 P=190 Name=identifier L=6 PPK=2 
FakeLParens= FakeRParens=0 II=0x2c5212a2d48 Text='f'
 M=0 C=0 T=TemplateOpener S=0 B=0 BK=0 P=30 Name=less L=7 PPK=2 FakeLParens= 
FakeRParens=0 II=0x0 Text='<'
 M=0 C=1 T=Unknown S=0 B=0 BK=0 P=360 Name=int L=10 PPK=2 FakeLParens= 
FakeRParens=0 II=0x2c52129fa50 Text='int'
 M=0 C=0 T=TemplateCloser S=0 B=0 BK=0 P=270 Name=greater L=11 PPK=2 
FakeLParens= FakeRParens=0 II=0x0 Text='>'
 M=0 C=0 T=Unknown S=0 B=0 BK=0 P=30 Name=l_paren L=12 PPK=2 FakeLParens= 
FakeRParens=0 II=0x0 Text='('
 M=0 C=0 T=Unknown S=0 B=0 BK=0 P=140 Name=r_paren L=13 PPK=2 FakeLParens= 
FakeRParens=1 II=0x0 Text=')'
 M=0 C=0 T=Unknown S=0 B=0 BK=0 P=23 Name=semi L=14 PPK=2 FakeLParens= 
FakeRParens=0 II=0x0 Text=';'

AnnotatedTokens(L=0):
 M=0 C=0 T=Unknown S=1 B=0 BK=0 P=0 Name=identifier L=1 PPK=2 FakeLParens=0/ 
FakeRParens=0 II=0x2c5212a2da8 Text='x'
 M=0 C=0 T=Unknown S=0 B=0 BK=0 P=23 Name=l_paren L=2 PPK=2 FakeLParens= 
FakeRParens=0 II=0x0 Text='('
 M=0 C=0 T=Unknown S=0 B=0 BK=0 P=140 Name=r_paren L=3 PPK=2 FakeLParens= 
FakeRParens=0 II=0x0 Text=')'
 M=0 C=1 T=Unknown S=0 B=0 BK=0 P=170 Name=arrow L=5 PPK=2 FakeLParens= 
FakeRParens=0 II=0x0 Text='->'
 M=0 C=0 T=TrailingAnnotation S=0 B=0 BK=0 P=190 Name=identifier L=8 PPK=2 
FakeLParens= FakeRParens=0 II=0x2c5212a2d78 Text='foo'
 M=0 C=0 T=TemplateOpener S=0 B=0 BK=0 P=30 Name=less L=9 PPK=2 FakeLParens= 
FakeRParens=0 II=0x0 Text='<'
 M=0 C=1 T=Unknown S=0 B=0 BK=0 P=360 

[PATCH] D69577: [clang-format] [PR35518] C++17 deduction guides are wrongly formatted

2019-10-30 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added inline comments.



Comment at: clang/lib/Format/TokenAnnotator.cpp:1400
   Current.Type = TT_TrailingReturnArrow;
+} else if (Current.Previous && Current.Previous->is(tok::r_paren) &&
+   Current.startsSequence(tok::arrow, tok::identifier, tok::less)) 
{

klimek wrote:
> Why doesn't this trigger on function templates:
>   c()->f();
> 
Comparing to the `else if` branch above, several questions can arise:

1. Has deduction-guide be considered a declaration (it is, of course, in 
standard)?  If yes, without `MustBeDeclaration`, how `x = p->foo<3>();` being 
formatted?
2. Without restrictions on `NestingLevel`, how `A() -> 
Afoo<3>())>;` being formatted?
3. How `x()->foo<1>;` being formatted?  What's the difference between this and 
a deduction-guide?  A deduction-guide has to follow `TheSameType(...) -> 
TheSameType<>;` and appears only at namespace level, do these help?

Oh no, `auto x = p -> foo<1>();` this is a bug (I will look for bug reports, 
don't mind).


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69577/new/

https://reviews.llvm.org/D69577



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69577: [clang-format] [PR35518] C++17 deduction guides are wrongly formatted

2019-10-30 Thread Manuel Klimek via Phabricator via cfe-commits
klimek added inline comments.



Comment at: clang/lib/Format/TokenAnnotator.cpp:1400-1403
+} else if (Current.Previous && Current.Previous->is(tok::r_paren) &&
+   Current.startsSequence(tok::arrow, tok::identifier, tok::less)) 
{
+  // Deduction guides trailing arrow "...) -> A".
+  Current.Type = TT_TrailingReturnArrow;

Why doesn't this trigger on function templates:
  c()->f();



CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69577/new/

https://reviews.llvm.org/D69577



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69577: [clang-format] [PR35518] C++17 deduction guides are wrongly formatted

2019-10-30 Thread MyDeveloperDay via Phabricator via cfe-commits
MyDeveloperDay updated this revision to Diff 227062.
MyDeveloperDay added a reviewer: lichray.
MyDeveloperDay added a comment.

Detect deduction guides arrow as a TrailingReturn arrow, allowing use of 
existing space before/after rules


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69577/new/

https://reviews.llvm.org/D69577

Files:
  clang/lib/Format/TokenAnnotator.cpp
  clang/unittests/Format/FormatTest.cpp


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -4977,6 +4977,15 @@
   verifyFormat("void f() { auto a = b->c(); }");
 }
 
+TEST_F(FormatTest, DeductionGuides) {
+  verifyFormat("template  A(const T &, const T &) -> A;");
+  verifyFormat("template  explicit A(T &, T &&) -> A;");
+  verifyFormat("template  S(Ts...) -> S;");
+  verifyFormat(
+  "template \n"
+  "array(T &&... t) -> array, sizeof...(T)>;");
+}
+
 TEST_F(FormatTest, BreaksFunctionDeclarationsWithTrailingTokens) {
   // Avoid breaking before trailing 'const' or other trailing annotations, if
   // they are not function-like.
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1397,6 +1397,10 @@
!Current.Previous->is(tok::kw_operator)) {
   // not auto operator->() -> xxx;
   Current.Type = TT_TrailingReturnArrow;
+} else if (Current.Previous && Current.Previous->is(tok::r_paren) &&
+   Current.startsSequence(tok::arrow, tok::identifier, tok::less)) 
{
+  // Deduction guides trailing arrow "...) -> A".
+  Current.Type = TT_TrailingReturnArrow;
 } else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) {
   Current.Type = determineStarAmpUsage(Current,
Contexts.back().CanBeExpression &&


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -4977,6 +4977,15 @@
   verifyFormat("void f() { auto a = b->c(); }");
 }
 
+TEST_F(FormatTest, DeductionGuides) {
+  verifyFormat("template  A(const T &, const T &) -> A;");
+  verifyFormat("template  explicit A(T &, T &&) -> A;");
+  verifyFormat("template  S(Ts...) -> S;");
+  verifyFormat(
+  "template \n"
+  "array(T &&... t) -> array, sizeof...(T)>;");
+}
+
 TEST_F(FormatTest, BreaksFunctionDeclarationsWithTrailingTokens) {
   // Avoid breaking before trailing 'const' or other trailing annotations, if
   // they are not function-like.
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1397,6 +1397,10 @@
!Current.Previous->is(tok::kw_operator)) {
   // not auto operator->() -> xxx;
   Current.Type = TT_TrailingReturnArrow;
+} else if (Current.Previous && Current.Previous->is(tok::r_paren) &&
+   Current.startsSequence(tok::arrow, tok::identifier, tok::less)) {
+  // Deduction guides trailing arrow "...) -> A".
+  Current.Type = TT_TrailingReturnArrow;
 } else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) {
   Current.Type = determineStarAmpUsage(Current,
Contexts.back().CanBeExpression &&
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69577: [clang-format] [PR35518] C++17 deduction guides are wrongly formatted

2019-10-30 Thread MyDeveloperDay via Phabricator via cfe-commits
MyDeveloperDay added a comment.

In D69577#1726587 , @lichray wrote:

> Should we find a way to set `->`'s type to `TT_TrailingReturnArrow`?


that's possible then we might be able to use the existing spaces before rule

  if (Right.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow) ||
  Left.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow))
return true;


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69577/new/

https://reviews.llvm.org/D69577



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69577: [clang-format] [PR35518] C++17 deduction guides are wrongly formatted

2019-10-30 Thread Zhihao Yuan via Phabricator via cfe-commits
lichray added a comment.

Should we find a way to set `->`'s type to `TT_TrailingReturnArrow`?


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69577/new/

https://reviews.llvm.org/D69577



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D69577: [clang-format] [PR35518] C++17 deduction guides are wrongly formatted

2019-10-29 Thread MyDeveloperDay via Phabricator via cfe-commits
MyDeveloperDay created this revision.
MyDeveloperDay added reviewers: klimek, mitchell-stellar, owenpan, sammccall.
MyDeveloperDay added projects: clang-format, clang-tools-extra.
Herald added a project: clang.

see https://bugs.llvm.org/show_bug.cgi?id=35518

clang-format removes spaces around deduction guides but not trailing return 
types, make the consistent

  template  S(T)->S;
  auto f(int, int) -> double;

becomes

  template  S(T) -> S;
  auto f(int, int) -> double;




Repository:
  rC Clang

https://reviews.llvm.org/D69577

Files:
  clang/lib/Format/TokenAnnotator.cpp
  clang/unittests/Format/FormatTest.cpp


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -4977,6 +4977,15 @@
   verifyFormat("void f() { auto a = b->c(); }");
 }
 
+TEST_F(FormatTest, DeductionGuides) {
+  verifyFormat("template  A(const T &, const T &) -> A;");
+  verifyFormat("template  explicit A(T &, T &&) -> A;");
+  verifyFormat("template  S(Ts...) -> S;");
+  verifyFormat(
+  "template \n"
+  "array(T &&... t) -> array, sizeof...(T)>;");
+}
+
 TEST_F(FormatTest, BreaksFunctionDeclarationsWithTrailingTokens) {
   // Avoid breaking before trailing 'const' or other trailing annotations, if
   // they are not function-like.
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2932,6 +2932,16 @@
 return Right.is(TT_TemplateCloser) && Left.is(TT_TemplateCloser) &&
(Style.Standard < FormatStyle::LS_Cpp11 || Style.SpacesInAngles);
   }
+
+  // Deduction guides add a space around the arrow  "...) -> A".
+  if (Left.is(tok::r_paren) &&
+  Right.startsSequence(tok::arrow, TT_TrailingAnnotation,
+   TT_TemplateOpener))
+return true;
+  if (Left.is(tok::arrow) &&
+  Right.startsSequence(TT_TrailingAnnotation, TT_TemplateOpener))
+return true;
+
   if (Right.isOneOf(tok::arrow, tok::arrowstar, tok::periodstar) ||
   Left.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) ||
   (Right.is(tok::period) && Right.isNot(TT_DesignatedInitializerPeriod)))


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -4977,6 +4977,15 @@
   verifyFormat("void f() { auto a = b->c(); }");
 }
 
+TEST_F(FormatTest, DeductionGuides) {
+  verifyFormat("template  A(const T &, const T &) -> A;");
+  verifyFormat("template  explicit A(T &, T &&) -> A;");
+  verifyFormat("template  S(Ts...) -> S;");
+  verifyFormat(
+  "template \n"
+  "array(T &&... t) -> array, sizeof...(T)>;");
+}
+
 TEST_F(FormatTest, BreaksFunctionDeclarationsWithTrailingTokens) {
   // Avoid breaking before trailing 'const' or other trailing annotations, if
   // they are not function-like.
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2932,6 +2932,16 @@
 return Right.is(TT_TemplateCloser) && Left.is(TT_TemplateCloser) &&
(Style.Standard < FormatStyle::LS_Cpp11 || Style.SpacesInAngles);
   }
+
+  // Deduction guides add a space around the arrow  "...) -> A".
+  if (Left.is(tok::r_paren) &&
+  Right.startsSequence(tok::arrow, TT_TrailingAnnotation,
+   TT_TemplateOpener))
+return true;
+  if (Left.is(tok::arrow) &&
+  Right.startsSequence(TT_TrailingAnnotation, TT_TemplateOpener))
+return true;
+
   if (Right.isOneOf(tok::arrow, tok::arrowstar, tok::periodstar) ||
   Left.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) ||
   (Right.is(tok::period) && Right.isNot(TT_DesignatedInitializerPeriod)))
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits