[PATCH] D132762: [clang-format] Allow `throw` to be a keyword in front of casts

2022-08-29 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel updated this revision to Diff 456402.
rymiel added a comment.

Add a few token annotator tests


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132762

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


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -308,6 +308,34 @@
   EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_CastRParen);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsCasts) {
+  auto Tokens = annotate("(void)p;");
+  EXPECT_EQ(Tokens.size(), 6u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::r_paren, TT_CastRParen);
+
+  Tokens = annotate("auto x = (Foo)p;");
+  EXPECT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_CastRParen);
+
+  Tokens = annotate("(std::vector)p;");
+  EXPECT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_CastRParen);
+
+  Tokens = annotate("return (Foo)p;");
+  EXPECT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_CastRParen);
+
+  Tokens = annotate("throw (Foo)p;");
+  EXPECT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_CastRParen);
+}
+
+TEST_F(TokenAnnotatorTest, UnderstandsDynamicExceptionSpecifier) {
+  auto Tokens = annotate("void f() throw(int);");
+  EXPECT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::kw_throw, TT_Unknown);
+}
+
 TEST_F(TokenAnnotatorTest, UnderstandsFunctionRefQualifiers) {
   auto Tokens = annotate("void f() &;");
   EXPECT_EQ(Tokens.size(), 7u) << Tokens;
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -10958,6 +10958,7 @@
   verifyFormat("my_int a = (my_int)2.0f;");
   verifyFormat("my_int a = (my_int)sizeof(int);");
   verifyFormat("return (my_int)aaa;");
+  verifyFormat("throw (my_int)aaa;");
   verifyFormat("#define x ((int)-1)");
   verifyFormat("#define LENGTH(x, y) (x) - (y) + 1");
   verifyFormat("#define p(q) ((int *)&q)");
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2153,7 +2153,7 @@
   // before the parentheses, this is unlikely to be a cast.
   if (LeftOfParens->Tok.getIdentifierInfo() &&
   !LeftOfParens->isOneOf(Keywords.kw_in, tok::kw_return, tok::kw_case,
- tok::kw_delete)) {
+ tok::kw_delete, tok::kw_throw)) {
 return false;
   }
 
@@ -3312,6 +3312,10 @@
   !Right.isOneOf(tok::semi, tok::r_paren, tok::hashhash)) {
 return true;
   }
+  if (Left.is(tok::kw_throw) && Right.is(tok::l_paren) && Right.MatchingParen 
&&
+  Right.MatchingParen->is(TT_CastRParen)) {
+return true;
+  }
   if (Style.isJson() && Left.is(tok::string_literal) && Right.is(tok::colon))
 return false;
   if (Left.is(Keywords.kw_assert) && Style.Language == FormatStyle::LK_Java)


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -308,6 +308,34 @@
   EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_CastRParen);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsCasts) {
+  auto Tokens = annotate("(void)p;");
+  EXPECT_EQ(Tokens.size(), 6u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::r_paren, TT_CastRParen);
+
+  Tokens = annotate("auto x = (Foo)p;");
+  EXPECT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_CastRParen);
+
+  Tokens = annotate("(std::vector)p;");
+  EXPECT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_CastRParen);
+
+  Tokens = annotate("return (Foo)p;");
+  EXPECT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_CastRParen);
+
+  Tokens = annotate("throw (Foo)p;");
+  EXPECT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_CastRParen);
+}
+
+TEST_F(TokenAnnotatorTest, UnderstandsDynamicExceptionSpecifier) {
+  auto Tokens = annotate("void f() throw(int);");
+  EXPECT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::kw_throw, TT_Unknown);
+}
+
 TEST_F(TokenAnnotatorTest, UnderstandsFunctionRefQualifiers) {
   auto Tokens = annotate("void f() &;");
   EXPECT_EQ(Tokens.size(), 7u) << Tokens;
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp

[PATCH] D132762: [clang-format] Allow `throw` to be a keyword in front of casts

2022-08-29 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel updated this revision to Diff 456480.
rymiel added a comment.

Add extra tests for spacing options


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132762

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


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -308,6 +308,34 @@
   EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_CastRParen);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsCasts) {
+  auto Tokens = annotate("(void)p;");
+  EXPECT_EQ(Tokens.size(), 6u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::r_paren, TT_CastRParen);
+
+  Tokens = annotate("auto x = (Foo)p;");
+  EXPECT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::r_paren, TT_CastRParen);
+
+  Tokens = annotate("(std::vector)p;");
+  EXPECT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_CastRParen);
+
+  Tokens = annotate("return (Foo)p;");
+  EXPECT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_CastRParen);
+
+  Tokens = annotate("throw (Foo)p;");
+  EXPECT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_CastRParen);
+}
+
+TEST_F(TokenAnnotatorTest, UnderstandsDynamicExceptionSpecifier) {
+  auto Tokens = annotate("void f() throw(int);");
+  EXPECT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::kw_throw, TT_Unknown);
+}
+
 TEST_F(TokenAnnotatorTest, UnderstandsFunctionRefQualifiers) {
   auto Tokens = annotate("void f() &;");
   EXPECT_EQ(Tokens.size(), 7u) << Tokens;
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -10958,6 +10958,7 @@
   verifyFormat("my_int a = (my_int)2.0f;");
   verifyFormat("my_int a = (my_int)sizeof(int);");
   verifyFormat("return (my_int)aaa;");
+  verifyFormat("throw (my_int)aaa;");
   verifyFormat("#define x ((int)-1)");
   verifyFormat("#define LENGTH(x, y) (x) - (y) + 1");
   verifyFormat("#define p(q) ((int *)&q)");
@@ -15650,6 +15651,7 @@
   verifyFormat("Type *A = ( Type * )P;", Spaces);
   verifyFormat("Type *A = ( vector )P;", Spaces);
   verifyFormat("x = ( int32 )y;", Spaces);
+  verifyFormat("throw ( int32 )x;", Spaces);
   verifyFormat("int a = ( int )(2.0f);", Spaces);
   verifyFormat("#define AA(X) sizeof((( X * )NULL)->a)", Spaces);
   verifyFormat("my_int a = ( my_int )sizeof(int);", Spaces);
@@ -15713,6 +15715,7 @@
   verifyFormat("#define CONF_BOOL(x) ( bool ) (x)", Spaces);
   verifyFormat("bool *y = ( bool * ) ( void * ) (x);", Spaces);
   verifyFormat("bool *y = ( bool * ) (x);", Spaces);
+  verifyFormat("throw ( int32 ) x;", Spaces);
 
   // Run subset of tests again with:
   Spaces.SpacesInCStyleCastParentheses = false;
@@ -15737,6 +15740,8 @@
   verifyFormat("bool *y = (bool *) (void *) (x);", Spaces);
   verifyFormat("bool *y = (bool *) (void *) (int) (x);", Spaces);
   verifyFormat("bool *y = (bool *) (void *) (int) foo(x);", Spaces);
+  verifyFormat("throw (int32) x;", Spaces);
+
   Spaces.ColumnLimit = 80;
   Spaces.IndentWidth = 4;
   Spaces.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak;
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2153,7 +2153,7 @@
   // before the parentheses, this is unlikely to be a cast.
   if (LeftOfParens->Tok.getIdentifierInfo() &&
   !LeftOfParens->isOneOf(Keywords.kw_in, tok::kw_return, tok::kw_case,
- tok::kw_delete)) {
+ tok::kw_delete, tok::kw_throw)) {
 return false;
   }
 
@@ -3312,6 +3312,10 @@
   !Right.isOneOf(tok::semi, tok::r_paren, tok::hashhash)) {
 return true;
   }
+  if (Left.is(tok::kw_throw) && Right.is(tok::l_paren) && Right.MatchingParen 
&&
+  Right.MatchingParen->is(TT_CastRParen)) {
+return true;
+  }
   if (Style.isJson() && Left.is(tok::string_literal) && Right.is(tok::colon))
 return false;
   if (Left.is(Keywords.kw_assert) && Style.Language == FormatStyle::LK_Java)


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -308,6 +308,34 @@
   EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_CastRParen);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsCasts) {
+  auto Tokens = annotate("(void)p;");
+  EXPECT_EQ(Tokens.size(), 6u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::r_paren, TT_CastRParen);
+
+  Tokens = a

[PATCH] D132189: [clang-format] Don't put `noexcept` on empty line following constructor

2022-09-05 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added a comment.

Emilia Dreamer 

Thank you!!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132189

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


[PATCH] D132295: [clang-format] Change heuristic for locating lambda template arguments

2022-09-05 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel updated this revision to Diff 458012.
rymiel added a comment.

Rebase on main


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132295

Files:
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp
  clang/unittests/Format/TokenAnnotatorTest.cpp

Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -809,18 +809,85 @@
 
   Tokens = annotate("[]() -> auto {}");
   ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
   EXPECT_TOKEN(Tokens[4], tok::arrow, TT_LambdaArrow);
   EXPECT_TOKEN(Tokens[6], tok::l_brace, TT_LambdaLBrace);
 
   Tokens = annotate("[]() -> auto & {}");
   ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
   EXPECT_TOKEN(Tokens[4], tok::arrow, TT_LambdaArrow);
   EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
 
   Tokens = annotate("[]() -> auto * {}");
   ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
   EXPECT_TOKEN(Tokens[4], tok::arrow, TT_LambdaArrow);
   EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[] {}");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[] noexcept {}");
+  ASSERT_EQ(Tokens.size(), 6u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[3], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[] -> auto {}");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::arrow, TT_LambdaArrow);
+  EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  () {}");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  {}");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[6], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  () {}");
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  {}");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  () {}");
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  {}");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  () {}");
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  {}");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandsFunctionAnnotations) {
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -21730,6 +21730,18 @@
"g();\n"
"  }\n"
"};\n");
+  verifyFormat("auto L = [](T...) {\n"
+   "  {\n"
+   "f();\n"
+   "g();\n"
+   "  }\n"
+   "};");
+  verifyFormat("auto L = [](T...) {\n"
+   "  {\n"
+   "f();\n"
+   "g();\n"
+   "  }\n"
+   "};");
 
   // Multiple lambdas in the same parentheses change indentation rules. These
   // lambdas are forced to start on new lines.
Index: clang/lib/Format/UnwrappedLineParser.

[PATCH] D133413: [clang-tidy] Fix crashes on `if consteval` in readability checks

2022-09-07 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel created this revision.
rymiel added reviewers: njames93, LegalizeAdulthood, aaron.ballman, gribozavr2.
Herald added subscribers: carlosgalvezp, xazax.hun.
Herald added a project: All.
rymiel requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

The `readability-braces-around-statement` check tries to look at the
closing parens of the if condition to determine where to insert braces,
however, "consteval if" statements don't have a condition, and always
have braces regardless, so the skip can be checked.

The `readability-simplify-boolean-expr` check looks at the condition
of the if statement to determine what could be simplified, but as
"consteval if" statements do not have a condition that could be
simplified, they can also be skipped here.

There may still be more checks that try to look at the conditions of
`if`s that aren't included here

Fixes https://github.com/llvm/llvm-project/issues/57568


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D133413

Files:
  clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp
  clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
  
clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements-consteval-if.cpp
  
clang-tools-extra/test/clang-tidy/checkers/readability/simplify-bool-expr-cxx23.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/readability/simplify-bool-expr-cxx23.cpp
===
--- /dev/null
+++ 
clang-tools-extra/test/clang-tidy/checkers/readability/simplify-bool-expr-cxx23.cpp
@@ -0,0 +1,13 @@
+// RUN: clang-tidy %s -checks='-*,readability-simplify-boolean-expr' -- 
-std=c++2b | count 0
+template 
+constexpr int foo() {
+  if consteval {
+if constexpr (Cond) {
+  return 0;
+} else {
+  return 1;
+}
+  } else {
+return 2;
+  }
+}
Index: 
clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements-consteval-if.cpp
===
--- /dev/null
+++ 
clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements-consteval-if.cpp
@@ -0,0 +1,31 @@
+// RUN: clang-tidy %s -checks='-*,readability-braces-around-statements' -- 
-std=c++2b | count 0
+
+constexpr void handle(bool) {}
+
+constexpr void shouldPass() {
+  if consteval {
+handle(true);
+  } else {
+handle(false);
+  }
+}
+
+constexpr void shouldPassNegated() {
+  if !consteval {
+handle(false);
+  } else {
+handle(true);
+  }
+}
+
+constexpr void shouldPassSimple() {
+  if consteval {
+handle(true);
+  }
+}
+
+void run() {
+shouldPass();
+shouldPassNegated();
+shouldPassSimple();
+}
Index: clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
===
--- clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
+++ clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
@@ -354,8 +354,9 @@
   }
 
   bool VisitIfStmt(IfStmt *If) {
-// Skip any if's that have a condition var or an init statement.
-if (If->hasInitStorage() || If->hasVarStorage())
+// Skip any if's that have a condition var or an init statement, or are
+// "if consteval" statements.
+if (If->hasInitStorage() || If->hasVarStorage() || If->isConsteval())
   return true;
 /*
  * if (true) ThenStmt(); -> ThenStmt();
Index: clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp
===
--- clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp
+++ clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp
@@ -131,6 +131,10 @@
   return;
 checkStmt(Result, S->getBody(), StartLoc);
   } else if (const auto *S = Result.Nodes.getNodeAs("if")) {
+// "if consteval" always has braces.
+if (S->isConsteval())
+  return;
+
 SourceLocation StartLoc = findRParenLoc(S, SM, Context);
 if (StartLoc.isInvalid())
   return;


Index: clang-tools-extra/test/clang-tidy/checkers/readability/simplify-bool-expr-cxx23.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability/simplify-bool-expr-cxx23.cpp
@@ -0,0 +1,13 @@
+// RUN: clang-tidy %s -checks='-*,readability-simplify-boolean-expr' -- -std=c++2b | count 0
+template 
+constexpr int foo() {
+  if consteval {
+if constexpr (Cond) {
+  return 0;
+} else {
+  return 1;
+}
+  } else {
+return 2;
+  }
+}
Index: clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements-consteval-if.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements-consteval-if.cpp
@@ -0,

[PATCH] D133413: [clang-tidy] Fix crashes on `if consteval` in readability checks

2022-09-07 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added a comment.

Note for reviewing:

- The C++ standard, from what I could tell, seems to imply the the else clause 
of a consteval if clause could be written without braces, however it seems that 
both GCC and Clang don't allow for this, so both clauses of constexpr if 
statements should be skipped in readability-braces-around-statement
- I was really unsure what to do with the tests. Since consteval if is a C++23 
feature, I felt like they needed to be in their own files, but these files are 
also super minimal, as they really only make sure that using them doesn't crash.
- The tests use the flag `-std=c++2b`. Seeing as that flag will probably be 
renamed once 2023 actually rolls around, is that okay?
- I cannot commit this patch myself, please commit as `Emilia Dreamer 
`


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133413

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


[PATCH] D134853: [clang-format] Correctly annotate UDLs as OverloadedOperator

2022-10-18 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel updated this revision to Diff 468473.
rymiel marked 4 inline comments as done.
rymiel added a comment.

Do not annotate the trailing identifier of an UDL


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D134853

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

Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -390,6 +390,55 @@
   EXPECT_TOKEN(Tokens[11], tok::amp, TT_PointerOrReference);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsOverloadedOperators) {
+  auto Tokens = annotate("x.operator+()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::plus, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator=()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::equal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator+=()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::plusequal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator,()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::comma, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator()()");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::r_paren, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator[]()");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  // EXPECT_TOKEN(Tokens[3], tok::l_square, TT_OverloadedOperator);
+  // EXPECT_TOKEN(Tokens[4], tok::r_square, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\"_a()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\" _a()");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\"if()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\"s()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\" s()");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
+}
+
 TEST_F(TokenAnnotatorTest, UnderstandsRequiresClausesAndConcepts) {
   auto Tokens = annotate("template \n"
  "concept C = (Foo && Bar) && (Bar && Baz);");
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -10153,6 +10153,14 @@
   // verifyFormat("void f() { operator*(a & a); }");
   // verifyFormat("void f() { operator&(a, b * b); }");
 
+  verifyFormat("void f() { return operator()(x) * b; }");
+  verifyFormat("void f() { return operator[](x) * b; }");
+  verifyFormat("void f() { return operator\"\"_a(x) * b; }");
+  verifyFormat("void f() { return operator\"\" _a(x) * b; }");
+  verifyFormat("void f() { return operator\"\"s(x) * b; }");
+  verifyFormat("void f() { return operator\"\" s(x) * b; }");
+  verifyFormat("void f() { return operator\"\"if(x) * b; }");
+
   verifyFormat("::operator delete(foo);");
   verifyFormat("::operator new(n * sizeof(foo));");
   verifyFormat("foo() { ::operator delete(foo); }");
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1176,13 +1176,17 @@
 if (CurrentToken->isOneOf(tok::star, tok::amp))
   CurrentToken->setType(TT_PointerOrReference);
 consumeToken();
-if (CurrentToken && CurrentToken->is(tok::comma) &&
+if (!CurrentToken)
+  continue;
+if (CurrentT

[PATCH] D134853: [clang-format] Correctly annotate UDLs as OverloadedOperator

2022-10-18 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel marked 2 inline comments as done.
rymiel added inline comments.



Comment at: clang/lib/Format/TokenAnnotator.cpp:2126
   return false;
 
 FormatToken *LeftOfParens = Tok.MatchingParen->getPreviousNonComment();

owenpan wrote:
> Perhaps add:
> ```
> if (Tok.MatchingParen->is(TT_OverloadedOperatorLParen))
>   return false;
> ```
Note that in testing, adding `isNot(TT_Unknown)` did not cause any issues in 
tests, but that change felt a little too drastic



Comment at: clang/unittests/Format/TokenAnnotatorTest.cpp:413
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::identifier, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);

owenpan wrote:
> rymiel wrote:
> > owenpan wrote:
> > > We need/should not annotate the suffix.
> > Unless I change the logic in `rParenEndsCast`, the suffix does need to be 
> > an OverloadedOperator, since it goes off of the token immediately before 
> > left paren (https://reviews.llvm.org/D134853#3822842)
> After we annotate `""` as `TT_OverloadedOperator`, `rParenEndsCast()` returns 
> false, at least for your test cases and the example in 
> https://github.com/llvm/llvm-project/issues/58035. If you can come up with 
> test cases that still confuses `rParenEndsCast()`, we can add a simple check 
> near the beginning of `rParenEndsCast()`. See line 2126 above.
Oh, you are right; I did not notice the extra check which disallows identifiers 
in front of casts



Comment at: clang/unittests/Format/TokenAnnotatorTest.cpp:415-423
+  Tokens = annotate("x.operator\"\"_long_literal()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\" _long_literal()");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);

owenpan wrote:
> IMO they are redundant as both `_a` and `_long_literal` are identifiers 
> starting with an underscore.
I wanted to avoid all the tests being single-character names, as 
"single-character name" was sort of an issue for one format bug; but actually 
this isn't even single character anyway so you are right


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D134853

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


[PATCH] D132131: [clang-format] Adds a formatter for aligning trailing comments over empty lines

2022-10-18 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added a comment.

Please provide a name and an email so someone could commit it on your behalf


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132131

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


[PATCH] D129443: [clang-format] Add option for aligning requires clause body

2022-10-18 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added a comment.

How should I proceed with a stale rejecting review?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129443

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


[PATCH] D129443: [clang-format] Add option for aligning requires clause body

2022-10-21 Thread Emilia Dreamer via Phabricator via cfe-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG9c422ab7ce82: [clang-format] Add option for aligning 
requires clause body (authored by eoanermine, committed by rymiel).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129443

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/Format.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -24334,6 +24334,12 @@
 TEST_F(FormatTest, Concepts) {
   EXPECT_EQ(getLLVMStyle().BreakBeforeConceptDeclarations,
 FormatStyle::BBCDS_Always);
+
+  // The default in LLVM style is REI_OuterScope, but these tests were written
+  // when the default was REI_Keyword.
+  FormatStyle Style = getLLVMStyle();
+  Style.RequiresExpressionIndentation = FormatStyle::REI_Keyword;
+
   verifyFormat("template \n"
"concept True = true;");
 
@@ -24350,13 +24356,15 @@
"concept DelayedCheck = true && requires(T t) {\n"
" t.bar();\n"
" t.baz();\n"
-   "   } && sizeof(T) <= 8;");
+   "   } && sizeof(T) <= 8;",
+   Style);
 
   verifyFormat("template \n"
"concept DelayedCheck = true && requires(T t) { // Comment\n"
" t.bar();\n"
" t.baz();\n"
-   "   } && sizeof(T) <= 8;");
+   "   } && sizeof(T) <= 8;",
+   Style);
 
   verifyFormat("template \n"
"concept DelayedCheck = false || requires(T t) { t.bar(); } && "
@@ -24458,26 +24466,30 @@
"concept Hashable = requires(T a) {\n"
" { std::hash{}(a) } -> "
"std::convertible_to;\n"
-   "   };");
+   "   };",
+   Style);
 
   verifyFormat(
   "template \n"
   "concept EqualityComparable = requires(T a, T b) {\n"
   "   { a == b } -> std::same_as;\n"
-  " };");
+  " };",
+  Style);
 
   verifyFormat(
   "template \n"
   "concept EqualityComparable = requires(T a, T b) {\n"
   "   { a == b } -> std::same_as;\n"
   "   { a != b } -> std::same_as;\n"
-  " };");
+  " };",
+  Style);
 
   verifyFormat("template \n"
"concept WeakEqualityComparable = requires(T a, T b) {\n"
"   { a == b };\n"
"   { a != b };\n"
-   " };");
+   " };",
+   Style);
 
   verifyFormat("template \n"
"concept HasSizeT = requires { typename T::size_t; };");
@@ -24493,7 +24505,8 @@
"  requires Same;\n"
"  { delete new T; };\n"
"  { delete new T[n]; };\n"
-   "};");
+   "};",
+   Style);
 
   verifyFormat("template \n"
"concept Semiregular =\n"
@@ -24506,7 +24519,8 @@
"  { delete new T[n]; };\n"
"  { new T } -> std::same_as;\n"
"} && DefaultConstructible && CopyConstructible && "
-   "CopyAssignable;");
+   "CopyAssignable;",
+   Style);
 
   verifyFormat(
   "template \n"
@@ -24520,14 +24534,16 @@
   " { delete new T; };\n"
   " { delete new T[n]; };\n"
   "   } && CopyConstructible && "
-  "CopyAssignable;");
+  "CopyAssignable;",
+  Style);
 
   verifyFormat("template \n"
"concept Two = requires(T t) {\n"
"{ t.foo() } -> std::same_as;\n"
"  } && requires(T &&t) {\n"
" { t.foo() } -> std::same_as;\n"
-   "   };");
+   "   };",
+   Style);
 
   verifyFormat(
  

[PATCH] D134853: [clang-format] Correctly annotate UDLs as OverloadedOperator

2022-10-25 Thread Emilia Dreamer via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
rymiel marked an inline comment as done.
Closed by commit rGdce5bb9a6f89: [clang-format] Correctly annotate UDLs as 
OverloadedOperator (authored by rymiel).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D134853

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

Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -390,6 +390,55 @@
   EXPECT_TOKEN(Tokens[11], tok::amp, TT_PointerOrReference);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsOverloadedOperators) {
+  auto Tokens = annotate("x.operator+()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::plus, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator=()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::equal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator+=()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::plusequal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator,()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::comma, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator()()");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::r_paren, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator[]()");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  // EXPECT_TOKEN(Tokens[3], tok::l_square, TT_OverloadedOperator);
+  // EXPECT_TOKEN(Tokens[4], tok::r_square, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\"_a()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\" _a()");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\"if()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\"s()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\" s()");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
+}
+
 TEST_F(TokenAnnotatorTest, UnderstandsRequiresClausesAndConcepts) {
   auto Tokens = annotate("template \n"
  "concept C = (Foo && Bar) && (Bar && Baz);");
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -10153,6 +10153,14 @@
   // verifyFormat("void f() { operator*(a & a); }");
   // verifyFormat("void f() { operator&(a, b * b); }");
 
+  verifyFormat("void f() { return operator()(x) * b; }");
+  verifyFormat("void f() { return operator[](x) * b; }");
+  verifyFormat("void f() { return operator\"\"_a(x) * b; }");
+  verifyFormat("void f() { return operator\"\" _a(x) * b; }");
+  verifyFormat("void f() { return operator\"\"s(x) * b; }");
+  verifyFormat("void f() { return operator\"\" s(x) * b; }");
+  verifyFormat("void f() { return operator\"\"if(x) * b; }");
+
   verifyFormat("::operator delete(foo);");
   verifyFormat("::operator new(n * sizeof(foo));");
   verifyFormat("foo() { ::operator delete(foo); }");
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1177,13 +1177,17 @@
 if (CurrentToken->isOneOf(tok::star, tok::amp))
   CurrentToken->setType(TT_PointerOrReference);
 consumeToken();
-

[PATCH] D136658: [clang-format] Move InsertBraces unit tests out of FormatTest.cpp

2022-10-25 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added a comment.

Is the intent here to somewhat reduce the 30k line behemoth of FormatTest.cpp?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D136658

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


[PATCH] D131978: [clang-format] Concepts: allow identifiers after negation

2022-08-16 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel created this revision.
rymiel added reviewers: MyDeveloperDay, curdeius, HazardyKnusperkeks, owenpan.
Herald added a project: All.
rymiel requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Previously, the formatter would refuse to treat identifiers within a
compound `concept` definition as actually part of the definition, if
they were after the negation operator `!`. It is now made consistent
with the likes of `&&` and `||`.

Fixes https://github.com/llvm/llvm-project/issues/55898


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D131978

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


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -24109,6 +24109,15 @@
"concept DelayedCheck = false || requires(T t) { t.bar(); } && "
"sizeof(T) <= 8;");
 
+  verifyFormat("template \n"
+   "concept DelayedCheck = Unit && !DerivedUnit;");
+
+  verifyFormat("template \n"
+   "concept DelayedCheck = Unit && !(DerivedUnit);");
+
+  verifyFormat("template \n"
+   "concept DelayedCheck = Unit && !!DerivedUnit;");
+
   verifyFormat("template \n"
"concept DelayedCheck = !!false || requires(T t) { t.bar(); } "
"&& sizeof(T) <= 8;");
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -3537,7 +3537,8 @@
   switch (FormatTok->Previous->Tok.getKind()) {
   case tok::coloncolon:  // Nested identifier.
   case tok::ampamp:  // Start of a function or variable for the
-  case tok::pipepipe:// constraint expression.
+  case tok::pipepipe:// constraint expression. (binary)
+  case tok::exclaim: // The same as above, but unary.
   case tok::kw_requires: // Initial identifier of a requires clause.
   case tok::equal:   // Initial identifier of a concept declaration.
 break;


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -24109,6 +24109,15 @@
"concept DelayedCheck = false || requires(T t) { t.bar(); } && "
"sizeof(T) <= 8;");
 
+  verifyFormat("template \n"
+   "concept DelayedCheck = Unit && !DerivedUnit;");
+
+  verifyFormat("template \n"
+   "concept DelayedCheck = Unit && !(DerivedUnit);");
+
+  verifyFormat("template \n"
+   "concept DelayedCheck = Unit && !!DerivedUnit;");
+
   verifyFormat("template \n"
"concept DelayedCheck = !!false || requires(T t) { t.bar(); } "
"&& sizeof(T) <= 8;");
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -3537,7 +3537,8 @@
   switch (FormatTok->Previous->Tok.getKind()) {
   case tok::coloncolon:  // Nested identifier.
   case tok::ampamp:  // Start of a function or variable for the
-  case tok::pipepipe:// constraint expression.
+  case tok::pipepipe:// constraint expression. (binary)
+  case tok::exclaim: // The same as above, but unary.
   case tok::kw_requires: // Initial identifier of a requires clause.
   case tok::equal:   // Initial identifier of a concept declaration.
 break;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D131978: [clang-format] Concepts: allow identifiers after negation

2022-08-16 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel updated this revision to Diff 453107.
rymiel added a comment.

Added negation unary operator check to TokenAnnotatorTest


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D131978

Files:
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp
  clang/unittests/Format/TokenAnnotatorTest.cpp


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -328,6 +328,13 @@
   EXPECT_TOKEN(Tokens[13], tok::ampamp, TT_BinaryOperator);
   EXPECT_TOKEN(Tokens[16], tok::ampamp, TT_BinaryOperator);
 
+  Tokens = annotate("template \n"
+"concept C = Foo && !Bar;");
+
+  ASSERT_EQ(Tokens.size(), 14u) << Tokens;
+  EXPECT_TOKEN(Tokens[9], tok::ampamp, TT_BinaryOperator);
+  EXPECT_TOKEN(Tokens[10], tok::exclaim, TT_UnaryOperator);
+
   Tokens = annotate("template \n"
 "concept C = requires(T t) {\n"
 "  { t.foo() };\n"
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -24109,6 +24109,15 @@
"concept DelayedCheck = false || requires(T t) { t.bar(); } && "
"sizeof(T) <= 8;");
 
+  verifyFormat("template \n"
+   "concept DelayedCheck = Unit && !DerivedUnit;");
+
+  verifyFormat("template \n"
+   "concept DelayedCheck = Unit && !(DerivedUnit);");
+
+  verifyFormat("template \n"
+   "concept DelayedCheck = Unit && !!DerivedUnit;");
+
   verifyFormat("template \n"
"concept DelayedCheck = !!false || requires(T t) { t.bar(); } "
"&& sizeof(T) <= 8;");
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -3537,7 +3537,8 @@
   switch (FormatTok->Previous->Tok.getKind()) {
   case tok::coloncolon:  // Nested identifier.
   case tok::ampamp:  // Start of a function or variable for the
-  case tok::pipepipe:// constraint expression.
+  case tok::pipepipe:// constraint expression. (binary)
+  case tok::exclaim: // The same as above, but unary.
   case tok::kw_requires: // Initial identifier of a requires clause.
   case tok::equal:   // Initial identifier of a concept declaration.
 break;


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -328,6 +328,13 @@
   EXPECT_TOKEN(Tokens[13], tok::ampamp, TT_BinaryOperator);
   EXPECT_TOKEN(Tokens[16], tok::ampamp, TT_BinaryOperator);
 
+  Tokens = annotate("template \n"
+"concept C = Foo && !Bar;");
+
+  ASSERT_EQ(Tokens.size(), 14u) << Tokens;
+  EXPECT_TOKEN(Tokens[9], tok::ampamp, TT_BinaryOperator);
+  EXPECT_TOKEN(Tokens[10], tok::exclaim, TT_UnaryOperator);
+
   Tokens = annotate("template \n"
 "concept C = requires(T t) {\n"
 "  { t.foo() };\n"
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -24109,6 +24109,15 @@
"concept DelayedCheck = false || requires(T t) { t.bar(); } && "
"sizeof(T) <= 8;");
 
+  verifyFormat("template \n"
+   "concept DelayedCheck = Unit && !DerivedUnit;");
+
+  verifyFormat("template \n"
+   "concept DelayedCheck = Unit && !(DerivedUnit);");
+
+  verifyFormat("template \n"
+   "concept DelayedCheck = Unit && !!DerivedUnit;");
+
   verifyFormat("template \n"
"concept DelayedCheck = !!false || requires(T t) { t.bar(); } "
"&& sizeof(T) <= 8;");
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -3537,7 +3537,8 @@
   switch (FormatTok->Previous->Tok.getKind()) {
   case tok::coloncolon:  // Nested identifier.
   case tok::ampamp:  // Start of a function or variable for the
-  case tok::pipepipe:// constraint expression.
+  case tok::pipepipe:// constraint expression. (binary)
+  case tok::exclaim: // The same as above, but unary.
   case tok::kw_requires: // Initial identifier of a requires clause.
   case tok::equal:   // Initial identifier of a concept declaration.
 break;
___

[PATCH] D131978: [clang-format] Concepts: allow identifiers after negation

2022-08-16 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added a comment.

In D131978#3727110 , 
@HazardyKnusperkeks wrote:

> It's late (where I am). I thought we had something like 
> `ClosesRequiresClause` for concepts too.
> But on the other hand, this should affect requires clauses, right? So a test 
> for that would fail before your patch.

Sorry, I'm not familiar with these tests enough to know what exactly you mean, 
but thank you for the review
Also, since this is my first change, I cannot commit this myself.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D131978

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


[PATCH] D131978: [clang-format] Concepts: allow identifiers after negation

2022-08-17 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added a comment.

It seems that even with this patch, there is seemingly weird formatting with 
the negation in requires clauses, such as:

  template 
requires !F
 int bar(T t);

This is because the "fake parens" of the unary expression opened is never 
closed by the special case clean-up made for requires clauses
However, it turns out this isn't even valid syntax, as it requires parentheses 
for disambiguation. Adding those brings back correct indentation

  template 
requires(!F)
  int bar(T t);

Is it okay to ignore this case, as it wouldn't even compile?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D131978

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


[PATCH] D132189: [clang-format] Don't put `noexcept` on empty line following constructor

2022-08-18 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel created this revision.
rymiel added reviewers: HazardyKnusperkeks, owenpan, MyDeveloperDay, curdeius.
Herald added a project: All.
rymiel requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

With the AlwaysBreakTemplateDeclarations option, having a constructor
template for a type consisting of all-uppercase letters with a
noexcept specifier would put said noexcept specifier on its own blank
line.

This is because the all-uppercase type is understood as a macro-like
attribute (such as `DEPRECATED()`), and `noexcept` is seen as the
declaration. However, `noexcept` is a keyword and cannot be an
identifier on its own.

Fixes https://github.com/llvm/llvm-project/issues/56216


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D132189

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
@@ -9525,6 +9525,12 @@
   verifyFormat("template  // T can be A, B or C.\n"
"struct C {};",
AlwaysBreak);
+  verifyFormat("template \n"
+   "C(T) noexcept;",
+   AlwaysBreak);
+  verifyFormat("template \n"
+   "ClassName(T) noexcept;",
+   AlwaysBreak);
   verifyFormat("template  class A {\n"
"public:\n"
"  E *f();\n"
@@ -9535,6 +9541,8 @@
   verifyFormat("template  class C {};", NeverBreak);
   verifyFormat("template  void f();", NeverBreak);
   verifyFormat("template  void f() {}", NeverBreak);
+  verifyFormat("template  C(T) noexcept;", NeverBreak);
+  verifyFormat("template  ClassName(T) noexcept;", NeverBreak);
   verifyFormat("template \nvoid foo(aa "
") {}",
NeverBreak);
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1922,7 +1922,7 @@
   !Current.Next->isBinaryOperator() &&
   !Current.Next->isOneOf(tok::semi, tok::colon, tok::l_brace,
  tok::comma, tok::period, tok::arrow,
- tok::coloncolon)) {
+ tok::coloncolon, tok::kw_noexcept)) {
 if (FormatToken *AfterParen = Current.MatchingParen->Next) {
   // Make sure this isn't the return type of an Obj-C block declaration
   if (AfterParen->isNot(tok::caret)) {


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -9525,6 +9525,12 @@
   verifyFormat("template  // T can be A, B or C.\n"
"struct C {};",
AlwaysBreak);
+  verifyFormat("template \n"
+   "C(T) noexcept;",
+   AlwaysBreak);
+  verifyFormat("template \n"
+   "ClassName(T) noexcept;",
+   AlwaysBreak);
   verifyFormat("template  class A {\n"
"public:\n"
"  E *f();\n"
@@ -9535,6 +9541,8 @@
   verifyFormat("template  class C {};", NeverBreak);
   verifyFormat("template  void f();", NeverBreak);
   verifyFormat("template  void f() {}", NeverBreak);
+  verifyFormat("template  C(T) noexcept;", NeverBreak);
+  verifyFormat("template  ClassName(T) noexcept;", NeverBreak);
   verifyFormat("template \nvoid foo(aa "
") {}",
NeverBreak);
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1922,7 +1922,7 @@
   !Current.Next->isBinaryOperator() &&
   !Current.Next->isOneOf(tok::semi, tok::colon, tok::l_brace,
  tok::comma, tok::period, tok::arrow,
- tok::coloncolon)) {
+ tok::coloncolon, tok::kw_noexcept)) {
 if (FormatToken *AfterParen = Current.MatchingParen->Next) {
   // Make sure this isn't the return type of an Obj-C block declaration
   if (AfterParen->isNot(tok::caret)) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D132189: [clang-format] Don't put `noexcept` on empty line following constructor

2022-08-18 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added a comment.

Note for reviewing:
The criteria for reaching this misformat are extremely specific, requiring a 
single-character type or a type of a type consisting of all-uppercase letter, 
which are poor style on their own.
I am also unsure how often this all-uppercase macro-like attribute syntax is 
relied upon

I chose to simply add the keyword `noexcept` to the negative check for symbols, 
since, as far as I am aware, `noexcept` is the only legal specifier which can 
follow a constructor
However, I am unsure what the usual course of action is for version/language 
specific things, since I only use clang-format for modern C++, but it appears 
to be capable of a whole lot more than that.
I ask this because directly after my added line, there's mention of 
Objective-C, and technically `noexcept` itself wasn't always in C++. Should 
there be extra checks for these.

There could also possibly be a TokenAnnotatorTest checking for 
`TT_FunctionAnnotationRParen`, but there wasn't an existing one similar to it, 
so I was unsure if I should add one


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132189

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


[PATCH] D132189: [clang-format] Don't put `noexcept` on empty line following constructor

2022-08-20 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel updated this revision to Diff 454191.
rymiel added a comment.

Extra tests, including token annotator tests


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132189

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


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -770,6 +770,19 @@
   EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsFunctionAnnotations) {
+  auto Tokens = annotate("template \n"
+ "DEPRECATED(\"Use NewClass::NewFunction instead.\")\n"
+ "string OldFunction(const string ¶meter) {}");
+  ASSERT_EQ(Tokens.size(), 20u) << Tokens;
+  EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_FunctionAnnotationRParen);
+
+  Tokens = annotate("template \n"
+"A(T) noexcept;");
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
+  EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_Unknown);
+}
+
 TEST_F(TokenAnnotatorTest, UnderstandsVerilogOperators) {
   auto Annotate = [this](llvm::StringRef Code) {
 return annotate(Code, getLLVMStyle(FormatStyle::LK_Verilog));
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -9525,6 +9525,15 @@
   verifyFormat("template  // T can be A, B or C.\n"
"struct C {};",
AlwaysBreak);
+  verifyFormat("template \n"
+   "C(T) noexcept;",
+   AlwaysBreak);
+  verifyFormat("template \n"
+   "ClassName(T) noexcept;",
+   AlwaysBreak);
+  verifyFormat("template \n"
+   "POOR_NAME(T) noexcept;",
+   AlwaysBreak);
   verifyFormat("template  class A {\n"
"public:\n"
"  E *f();\n"
@@ -9535,6 +9544,9 @@
   verifyFormat("template  class C {};", NeverBreak);
   verifyFormat("template  void f();", NeverBreak);
   verifyFormat("template  void f() {}", NeverBreak);
+  verifyFormat("template  C(T) noexcept;", NeverBreak);
+  verifyFormat("template  ClassName(T) noexcept;", NeverBreak);
+  verifyFormat("template  POOR_NAME(T) noexcept;", NeverBreak);
   verifyFormat("template \nvoid foo(aa "
") {}",
NeverBreak);
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1922,7 +1922,7 @@
   !Current.Next->isBinaryOperator() &&
   !Current.Next->isOneOf(tok::semi, tok::colon, tok::l_brace,
  tok::comma, tok::period, tok::arrow,
- tok::coloncolon)) {
+ tok::coloncolon, tok::kw_noexcept)) {
 if (FormatToken *AfterParen = Current.MatchingParen->Next) {
   // Make sure this isn't the return type of an Obj-C block declaration
   if (AfterParen->isNot(tok::caret)) {


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -770,6 +770,19 @@
   EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsFunctionAnnotations) {
+  auto Tokens = annotate("template \n"
+ "DEPRECATED(\"Use NewClass::NewFunction instead.\")\n"
+ "string OldFunction(const string ¶meter) {}");
+  ASSERT_EQ(Tokens.size(), 20u) << Tokens;
+  EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_FunctionAnnotationRParen);
+
+  Tokens = annotate("template \n"
+"A(T) noexcept;");
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
+  EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_Unknown);
+}
+
 TEST_F(TokenAnnotatorTest, UnderstandsVerilogOperators) {
   auto Annotate = [this](llvm::StringRef Code) {
 return annotate(Code, getLLVMStyle(FormatStyle::LK_Verilog));
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -9525,6 +9525,15 @@
   verifyFormat("template  // T can be A, B or C.\n"
"struct C {};",
AlwaysBreak);
+  verifyFormat("template \n"
+   "C(T) noexcept;",
+   AlwaysBreak);
+  verifyFormat("template \n"
+   "ClassName(T) noexcept;",
+   AlwaysBreak);
+  verifyFormat("template \n"
+  

[PATCH] D132295: [clang-format] Change heuristic for locating lambda template arguments

2022-08-20 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel created this revision.
rymiel added reviewers: HazardyKnusperkeks, owenpan, MyDeveloperDay, curdeius.
Herald added a project: All.
rymiel requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Previously, the heuristic was simply to look for template argument-
specific keywords, such as `typename`, `class`, `template` and `auto`
that are preceded by a left angle bracket `<`.

This changes the heuristic to instead look for a left angle bracket `<`
preceded by a right square bracket `]`, since according to the C++
grammar, the template arguments must *directly* follow the introducer.
(This sort of check might just end up being *too* aggressive)

This patch also adds a bunch more token annotator tests for lambdas,
specifically for some of the stranger forms of lambdas now allowed as
of C++20 or soon-to-be-allowed as part of C++23.

Fixes https://github.com/llvm/llvm-project/issues/57093

This does NOT resolve the FIXME regarding explicit template lists, but
perhaps it gets closer


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D132295

Files:
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/TokenAnnotatorTest.cpp

Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -756,18 +756,85 @@
 
   Tokens = annotate("[]() -> auto {}");
   ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
   EXPECT_TOKEN(Tokens[4], tok::arrow, TT_LambdaArrow);
   EXPECT_TOKEN(Tokens[6], tok::l_brace, TT_LambdaLBrace);
 
   Tokens = annotate("[]() -> auto & {}");
   ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
   EXPECT_TOKEN(Tokens[4], tok::arrow, TT_LambdaArrow);
   EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
 
   Tokens = annotate("[]() -> auto * {}");
   ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
   EXPECT_TOKEN(Tokens[4], tok::arrow, TT_LambdaArrow);
   EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[] {}");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[] noexcept {}");
+  ASSERT_EQ(Tokens.size(), 6u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[3], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[] -> auto {}");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::arrow, TT_LambdaArrow);
+  EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  () {}");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  {}");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[6], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  () {}");
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  {}");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  () {}");
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  {}");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  () {}");
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  {}");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
 }
 
 TEST_F(TokenA

[PATCH] D132295: [clang-format] Change heuristic for locating lambda template arguments

2022-08-21 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel updated this revision to Diff 454304.
rymiel added a comment.

Add a few format tests in addition to the annotator tests

>From some incidental testing, I am pretty sure the formatting of lambdas that 
>were mis-annotated as "array subscript" tended to end up being formatted 
>correct-ish, however, I added a test case for the bug which this patch solves, 
>which I should have done earlier.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132295

Files:
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp
  clang/unittests/Format/TokenAnnotatorTest.cpp

Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -756,18 +756,85 @@
 
   Tokens = annotate("[]() -> auto {}");
   ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
   EXPECT_TOKEN(Tokens[4], tok::arrow, TT_LambdaArrow);
   EXPECT_TOKEN(Tokens[6], tok::l_brace, TT_LambdaLBrace);
 
   Tokens = annotate("[]() -> auto & {}");
   ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
   EXPECT_TOKEN(Tokens[4], tok::arrow, TT_LambdaArrow);
   EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
 
   Tokens = annotate("[]() -> auto * {}");
   ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
   EXPECT_TOKEN(Tokens[4], tok::arrow, TT_LambdaArrow);
   EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[] {}");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[] noexcept {}");
+  ASSERT_EQ(Tokens.size(), 6u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[3], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[] -> auto {}");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::arrow, TT_LambdaArrow);
+  EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  () {}");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  {}");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[6], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  () {}");
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  {}");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  () {}");
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  {}");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  () {}");
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  {}");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandsVerilogOperators) {
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -21626,6 +21626,18 @@
"g();\n"
"  }\n"
"};\n");
+  verifyFormat("auto L = [](T...) {\n"
+   "  {\n"
+   "f();\n"
+   "g();\n"
+   "  }\n"
+   "};\n");
+  verifyFormat("auto L = []

[PATCH] D132295: [clang-format] Change heuristic for locating lambda template arguments

2022-08-22 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel updated this revision to Diff 454513.
rymiel added a comment.

Remove trailing newlines in added format tests


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132295

Files:
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp
  clang/unittests/Format/TokenAnnotatorTest.cpp

Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -756,18 +756,85 @@
 
   Tokens = annotate("[]() -> auto {}");
   ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
   EXPECT_TOKEN(Tokens[4], tok::arrow, TT_LambdaArrow);
   EXPECT_TOKEN(Tokens[6], tok::l_brace, TT_LambdaLBrace);
 
   Tokens = annotate("[]() -> auto & {}");
   ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
   EXPECT_TOKEN(Tokens[4], tok::arrow, TT_LambdaArrow);
   EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
 
   Tokens = annotate("[]() -> auto * {}");
   ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
   EXPECT_TOKEN(Tokens[4], tok::arrow, TT_LambdaArrow);
   EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[] {}");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[] noexcept {}");
+  ASSERT_EQ(Tokens.size(), 6u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[3], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[] -> auto {}");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::arrow, TT_LambdaArrow);
+  EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  () {}");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  {}");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[6], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  () {}");
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  {}");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  () {}");
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  {}");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  () {}");
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]  {}");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandsVerilogOperators) {
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -21626,6 +21626,18 @@
"g();\n"
"  }\n"
"};\n");
+  verifyFormat("auto L = [](T...) {\n"
+   "  {\n"
+   "f();\n"
+   "g();\n"
+   "  }\n"
+   "};");
+  verifyFormat("auto L = [](T...) {\n"
+   "  {\n"
+   "f();\n"
+   "g();\n"
+   "  }\n"
+   "};");
 
   // Multiple lambdas in the same parentheses change indentation rules. These
   // lambdas are forced to start on new lines.
Index: clang/li

[PATCH] D132762: [clang-format] Allow `throw` to be a keyword in front of casts

2022-08-26 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel created this revision.
rymiel added reviewers: HazardyKnusperkeks, owenpan, MyDeveloperDay, curdeius.
Herald added a project: All.
rymiel requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This makes `throw` more similar to `return`. However, unlike `return`,
it has to more strict as to not remove spaces after usages of `throw` as
a (deprecated) exception specifier.

Fixes https://github.com/llvm/llvm-project/issues/57391


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D132762

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
@@ -10958,6 +10958,7 @@
   verifyFormat("my_int a = (my_int)2.0f;");
   verifyFormat("my_int a = (my_int)sizeof(int);");
   verifyFormat("return (my_int)aaa;");
+  verifyFormat("throw (my_int)aaa;");
   verifyFormat("#define x ((int)-1)");
   verifyFormat("#define LENGTH(x, y) (x) - (y) + 1");
   verifyFormat("#define p(q) ((int *)&q)");
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2153,7 +2153,7 @@
   // before the parentheses, this is unlikely to be a cast.
   if (LeftOfParens->Tok.getIdentifierInfo() &&
   !LeftOfParens->isOneOf(Keywords.kw_in, tok::kw_return, tok::kw_case,
- tok::kw_delete)) {
+ tok::kw_delete, tok::kw_throw)) {
 return false;
   }
 
@@ -3312,6 +3312,10 @@
   !Right.isOneOf(tok::semi, tok::r_paren, tok::hashhash)) {
 return true;
   }
+  if (Left.is(tok::kw_throw) && Right.is(tok::l_paren) && Right.MatchingParen 
&&
+  Right.MatchingParen->is(TT_CastRParen)) {
+return true;
+  }
   if (Style.isJson() && Left.is(tok::string_literal) && Right.is(tok::colon))
 return false;
   if (Left.is(Keywords.kw_assert) && Style.Language == FormatStyle::LK_Java)


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -10958,6 +10958,7 @@
   verifyFormat("my_int a = (my_int)2.0f;");
   verifyFormat("my_int a = (my_int)sizeof(int);");
   verifyFormat("return (my_int)aaa;");
+  verifyFormat("throw (my_int)aaa;");
   verifyFormat("#define x ((int)-1)");
   verifyFormat("#define LENGTH(x, y) (x) - (y) + 1");
   verifyFormat("#define p(q) ((int *)&q)");
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2153,7 +2153,7 @@
   // before the parentheses, this is unlikely to be a cast.
   if (LeftOfParens->Tok.getIdentifierInfo() &&
   !LeftOfParens->isOneOf(Keywords.kw_in, tok::kw_return, tok::kw_case,
- tok::kw_delete)) {
+ tok::kw_delete, tok::kw_throw)) {
 return false;
   }
 
@@ -3312,6 +3312,10 @@
   !Right.isOneOf(tok::semi, tok::r_paren, tok::hashhash)) {
 return true;
   }
+  if (Left.is(tok::kw_throw) && Right.is(tok::l_paren) && Right.MatchingParen &&
+  Right.MatchingParen->is(TT_CastRParen)) {
+return true;
+  }
   if (Style.isJson() && Left.is(tok::string_literal) && Right.is(tok::colon))
 return false;
   if (Left.is(Keywords.kw_assert) && Style.Language == FormatStyle::LK_Java)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134049: [clang-format] Disallow trailing return arrows to be operators

2022-09-16 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel created this revision.
rymiel added reviewers: HazardyKnusperkeks, owenpan, MyDeveloperDay, curdeius.
Herald added a project: All.
rymiel requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

In the following construction:
`template  requires Foo || Bar auto func() -> int;`

The `->` of the trailing return type was actually considered as an
operator as part of the binary operation in the requires clause, with
the precedence level of `PrecedenceArrowAndPeriod`, leading to fake
parens being inserted in strange locations, that would never be closed.

Fixes one part of https://github.com/llvm/llvm-project/issues/56213
(the rest will probably be in a separate patch)


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D134049

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


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -440,6 +440,13 @@
   ASSERT_EQ(Tokens.size(), 18u) << Tokens;
   EXPECT_TOKEN(Tokens[11], tok::kw_requires, TT_RequiresClause);
 
+  Tokens = annotate("template \n"
+"requires Bar || Baz\n"
+"auto foo(T) -> int;");
+  ASSERT_EQ(Tokens.size(), 24u) << Tokens;
+  EXPECT_EQ(Tokens[11]->FakeLParens.size(), 0u);
+  EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
+
   Tokens = annotate("template \n"
 "struct S {\n"
 "  void foo() const requires Bar;\n"
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2611,8 +2611,10 @@
   }
   if (Current->is(TT_BinaryOperator) || Current->is(tok::comma))
 return Current->getPrecedence();
-  if (Current->isOneOf(tok::period, tok::arrow))
+  if (Current->isOneOf(tok::period, tok::arrow) &&
+  !Current->is(TT_TrailingReturnArrow)) {
 return PrecedenceArrowAndPeriod;
+  }
   if ((Style.Language == FormatStyle::LK_Java || Style.isJavaScript()) &&
   Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
Keywords.kw_throws)) {


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -440,6 +440,13 @@
   ASSERT_EQ(Tokens.size(), 18u) << Tokens;
   EXPECT_TOKEN(Tokens[11], tok::kw_requires, TT_RequiresClause);
 
+  Tokens = annotate("template \n"
+"requires Bar || Baz\n"
+"auto foo(T) -> int;");
+  ASSERT_EQ(Tokens.size(), 24u) << Tokens;
+  EXPECT_EQ(Tokens[11]->FakeLParens.size(), 0u);
+  EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
+
   Tokens = annotate("template \n"
 "struct S {\n"
 "  void foo() const requires Bar;\n"
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2611,8 +2611,10 @@
   }
   if (Current->is(TT_BinaryOperator) || Current->is(tok::comma))
 return Current->getPrecedence();
-  if (Current->isOneOf(tok::period, tok::arrow))
+  if (Current->isOneOf(tok::period, tok::arrow) &&
+  !Current->is(TT_TrailingReturnArrow)) {
 return PrecedenceArrowAndPeriod;
+  }
   if ((Style.Language == FormatStyle::LK_Java || Style.isJavaScript()) &&
   Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
Keywords.kw_throws)) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134052: [clang-format] Disallow requires clauses to become function declarations

2022-09-16 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel created this revision.
rymiel added reviewers: HazardyKnusperkeks, owenpan, MyDeveloperDay, curdeius.
Herald added a project: All.
rymiel requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

There already exists logic to disallow requires *expressions* to be
treated as function declarations, but this expands it to include
requires *clauses*, when they happen to also be parenthesized.

Previously, in the following case:

  template 
requires(Foo)
  T foo();

The line with the requires clause was actually being considered as the
line with the function declaration due to the parentheses, and the
*real* function declaration on the next line became a trailing
annotation

(Together with https://reviews.llvm.org/D134049) Fixes 
https://github.com/llvm/llvm-project/issues/56213


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D134052

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


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -728,6 +728,16 @@
   BaseTokenCount = 26;
   TestRequires(__LINE__);
 
+  BaseCode = "template\n"
+ "T foo();";
+  ConstrainedCode = "template\n"
+"  requires(Foo)\n"
+"T foo();";
+  BaseTokenCount = 11;
+  RequiresTokenCount = 7;
+  PrefixTokenCount = 5;
+  TestRequires(__LINE__);
+
   BaseCode = "template\n"
  "Bar(T) -> Bar;";
   ConstrainedCode = "template\n"
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1110,7 +1110,7 @@
   !Contexts.back().IsExpression && !Line.startsWith(TT_ObjCProperty) &&
   !Tok->isOneOf(TT_TypeDeclarationParen, TT_RequiresExpressionLParen) 
&&
   (!Tok->Previous ||
-   !Tok->Previous->isOneOf(tok::kw___attribute,
+   !Tok->Previous->isOneOf(tok::kw___attribute, TT_RequiresClause,
TT_LeadingJavaAnnotation))) {
 Line.MightBeFunctionDecl = true;
   }


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -728,6 +728,16 @@
   BaseTokenCount = 26;
   TestRequires(__LINE__);
 
+  BaseCode = "template\n"
+ "T foo();";
+  ConstrainedCode = "template\n"
+"  requires(Foo)\n"
+"T foo();";
+  BaseTokenCount = 11;
+  RequiresTokenCount = 7;
+  PrefixTokenCount = 5;
+  TestRequires(__LINE__);
+
   BaseCode = "template\n"
  "Bar(T) -> Bar;";
   ConstrainedCode = "template\n"
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1110,7 +1110,7 @@
   !Contexts.back().IsExpression && !Line.startsWith(TT_ObjCProperty) &&
   !Tok->isOneOf(TT_TypeDeclarationParen, TT_RequiresExpressionLParen) &&
   (!Tok->Previous ||
-   !Tok->Previous->isOneOf(tok::kw___attribute,
+   !Tok->Previous->isOneOf(tok::kw___attribute, TT_RequiresClause,
TT_LeadingJavaAnnotation))) {
 Line.MightBeFunctionDecl = true;
   }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134049: [clang-format] Disallow trailing return arrows to be operators

2022-09-16 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added inline comments.



Comment at: clang/unittests/Format/TokenAnnotatorTest.cpp:448
+  EXPECT_EQ(Tokens[11]->FakeLParens.size(), 0u);
+  EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
+

MyDeveloperDay wrote:
> should you not check that Tokens[21] is a TT_TrailingReturnArrow?
That's probably a good idea, thank you! (though the bug wasn't that `->` was 
misannotated, it was still a trailing return arrow, it just caused fake 
parentheses to be inserted earlier on)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D134049

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


[PATCH] D134049: [clang-format] Disallow trailing return arrows to be operators

2022-09-16 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel updated this revision to Diff 460810.
rymiel added a comment.

Also test the annotated value of the arrow


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D134049

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


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -440,6 +440,14 @@
   ASSERT_EQ(Tokens.size(), 18u) << Tokens;
   EXPECT_TOKEN(Tokens[11], tok::kw_requires, TT_RequiresClause);
 
+  Tokens = annotate("template \n"
+"requires Bar || Baz\n"
+"auto foo(T) -> int;");
+  ASSERT_EQ(Tokens.size(), 24u) << Tokens;
+  EXPECT_EQ(Tokens[11]->FakeLParens.size(), 0u);
+  EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
+  EXPECT_TOKEN(Tokens[20], tok::arrow, TT_TrailingReturnArrow);
+
   Tokens = annotate("template \n"
 "struct S {\n"
 "  void foo() const requires Bar;\n"
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2611,8 +2611,10 @@
   }
   if (Current->is(TT_BinaryOperator) || Current->is(tok::comma))
 return Current->getPrecedence();
-  if (Current->isOneOf(tok::period, tok::arrow))
+  if (Current->isOneOf(tok::period, tok::arrow) &&
+  !Current->is(TT_TrailingReturnArrow)) {
 return PrecedenceArrowAndPeriod;
+  }
   if ((Style.Language == FormatStyle::LK_Java || Style.isJavaScript()) &&
   Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
Keywords.kw_throws)) {


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -440,6 +440,14 @@
   ASSERT_EQ(Tokens.size(), 18u) << Tokens;
   EXPECT_TOKEN(Tokens[11], tok::kw_requires, TT_RequiresClause);
 
+  Tokens = annotate("template \n"
+"requires Bar || Baz\n"
+"auto foo(T) -> int;");
+  ASSERT_EQ(Tokens.size(), 24u) << Tokens;
+  EXPECT_EQ(Tokens[11]->FakeLParens.size(), 0u);
+  EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
+  EXPECT_TOKEN(Tokens[20], tok::arrow, TT_TrailingReturnArrow);
+
   Tokens = annotate("template \n"
 "struct S {\n"
 "  void foo() const requires Bar;\n"
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2611,8 +2611,10 @@
   }
   if (Current->is(TT_BinaryOperator) || Current->is(tok::comma))
 return Current->getPrecedence();
-  if (Current->isOneOf(tok::period, tok::arrow))
+  if (Current->isOneOf(tok::period, tok::arrow) &&
+  !Current->is(TT_TrailingReturnArrow)) {
 return PrecedenceArrowAndPeriod;
+  }
   if ((Style.Language == FormatStyle::LK_Java || Style.isJavaScript()) &&
   Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
Keywords.kw_throws)) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134049: [clang-format] Disallow trailing return arrows to be operators

2022-09-16 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel updated this revision to Diff 460947.
rymiel added a comment.

Address review comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D134049

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


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -440,6 +440,15 @@
   ASSERT_EQ(Tokens.size(), 18u) << Tokens;
   EXPECT_TOKEN(Tokens[11], tok::kw_requires, TT_RequiresClause);
 
+  Tokens = annotate("template \n"
+"requires Bar || Baz\n"
+"auto foo(T) -> int;");
+  ASSERT_EQ(Tokens.size(), 24u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
+  EXPECT_EQ(Tokens[11]->FakeLParens.size(), 0u);
+  EXPECT_TRUE(Tokens[14]->ClosesRequiresClause);
+  EXPECT_TOKEN(Tokens[20], tok::arrow, TT_TrailingReturnArrow);
+
   Tokens = annotate("template \n"
 "struct S {\n"
 "  void foo() const requires Bar;\n"
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2611,8 +2611,10 @@
   }
   if (Current->is(TT_BinaryOperator) || Current->is(tok::comma))
 return Current->getPrecedence();
-  if (Current->isOneOf(tok::period, tok::arrow))
+  if (Current->isOneOf(tok::period, tok::arrow) &&
+  Current->isNot(TT_TrailingReturnArrow)) {
 return PrecedenceArrowAndPeriod;
+  }
   if ((Style.Language == FormatStyle::LK_Java || Style.isJavaScript()) &&
   Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
Keywords.kw_throws)) {


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -440,6 +440,15 @@
   ASSERT_EQ(Tokens.size(), 18u) << Tokens;
   EXPECT_TOKEN(Tokens[11], tok::kw_requires, TT_RequiresClause);
 
+  Tokens = annotate("template \n"
+"requires Bar || Baz\n"
+"auto foo(T) -> int;");
+  ASSERT_EQ(Tokens.size(), 24u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
+  EXPECT_EQ(Tokens[11]->FakeLParens.size(), 0u);
+  EXPECT_TRUE(Tokens[14]->ClosesRequiresClause);
+  EXPECT_TOKEN(Tokens[20], tok::arrow, TT_TrailingReturnArrow);
+
   Tokens = annotate("template \n"
 "struct S {\n"
 "  void foo() const requires Bar;\n"
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2611,8 +2611,10 @@
   }
   if (Current->is(TT_BinaryOperator) || Current->is(tok::comma))
 return Current->getPrecedence();
-  if (Current->isOneOf(tok::period, tok::arrow))
+  if (Current->isOneOf(tok::period, tok::arrow) &&
+  Current->isNot(TT_TrailingReturnArrow)) {
 return PrecedenceArrowAndPeriod;
+  }
   if ((Style.Language == FormatStyle::LK_Java || Style.isJavaScript()) &&
   Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
Keywords.kw_throws)) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134049: [clang-format] Disallow trailing return arrows to be operators

2022-09-18 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added a comment.

In D134049#3798366 , @owenpan wrote:

> Would you like to get commit access? See 
> https://llvm.org/docs/DeveloperPolicy.html#obtaining-commit-access.

I must humbly say that I do not think I qualify under "a track record of 
submitting high quality patches", I've only done incidental bug fixes that are 
in easily approachable places. Do you disagree with my self-assessment? (I also 
understand that I've made lots of extremely tiny patches that are probably a 
little annoying to manage)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D134049

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


[PATCH] D134049: [clang-format] Disallow trailing return arrows to be operators

2022-09-18 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added a comment.

Thank you for the vote of confidence!! It went way more quickly than I 
expected; I now already have commit access!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D134049

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


[PATCH] D134049: [clang-format] Disallow trailing return arrows to be operators

2022-09-18 Thread Emilia Dreamer via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG0bf63f0d1b6b: [clang-format] Disallow trailing return arrows 
to be operators (authored by rymiel).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D134049

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


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -440,6 +440,15 @@
   ASSERT_EQ(Tokens.size(), 18u) << Tokens;
   EXPECT_TOKEN(Tokens[11], tok::kw_requires, TT_RequiresClause);
 
+  Tokens = annotate("template \n"
+"requires Bar || Baz\n"
+"auto foo(T) -> int;");
+  ASSERT_EQ(Tokens.size(), 24u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
+  EXPECT_EQ(Tokens[11]->FakeLParens.size(), 0u);
+  EXPECT_TRUE(Tokens[14]->ClosesRequiresClause);
+  EXPECT_TOKEN(Tokens[20], tok::arrow, TT_TrailingReturnArrow);
+
   Tokens = annotate("template \n"
 "struct S {\n"
 "  void foo() const requires Bar;\n"
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2611,8 +2611,10 @@
   }
   if (Current->is(TT_BinaryOperator) || Current->is(tok::comma))
 return Current->getPrecedence();
-  if (Current->isOneOf(tok::period, tok::arrow))
+  if (Current->isOneOf(tok::period, tok::arrow) &&
+  Current->isNot(TT_TrailingReturnArrow)) {
 return PrecedenceArrowAndPeriod;
+  }
   if ((Style.Language == FormatStyle::LK_Java || Style.isJavaScript()) &&
   Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
Keywords.kw_throws)) {


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -440,6 +440,15 @@
   ASSERT_EQ(Tokens.size(), 18u) << Tokens;
   EXPECT_TOKEN(Tokens[11], tok::kw_requires, TT_RequiresClause);
 
+  Tokens = annotate("template \n"
+"requires Bar || Baz\n"
+"auto foo(T) -> int;");
+  ASSERT_EQ(Tokens.size(), 24u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
+  EXPECT_EQ(Tokens[11]->FakeLParens.size(), 0u);
+  EXPECT_TRUE(Tokens[14]->ClosesRequiresClause);
+  EXPECT_TOKEN(Tokens[20], tok::arrow, TT_TrailingReturnArrow);
+
   Tokens = annotate("template \n"
 "struct S {\n"
 "  void foo() const requires Bar;\n"
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2611,8 +2611,10 @@
   }
   if (Current->is(TT_BinaryOperator) || Current->is(tok::comma))
 return Current->getPrecedence();
-  if (Current->isOneOf(tok::period, tok::arrow))
+  if (Current->isOneOf(tok::period, tok::arrow) &&
+  Current->isNot(TT_TrailingReturnArrow)) {
 return PrecedenceArrowAndPeriod;
+  }
   if ((Style.Language == FormatStyle::LK_Java || Style.isJavaScript()) &&
   Current->isOneOf(Keywords.kw_extends, Keywords.kw_implements,
Keywords.kw_throws)) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134052: [clang-format] Disallow requires clauses to become function declarations

2022-09-18 Thread Emilia Dreamer via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG8dab45274000: [clang-format] Disallow requires clauses to 
become function declarations (authored by rymiel).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D134052

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


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -737,6 +737,16 @@
   BaseTokenCount = 26;
   TestRequires(__LINE__);
 
+  BaseCode = "template\n"
+ "T foo();";
+  ConstrainedCode = "template\n"
+"  requires(Foo)\n"
+"T foo();";
+  BaseTokenCount = 11;
+  RequiresTokenCount = 7;
+  PrefixTokenCount = 5;
+  TestRequires(__LINE__);
+
   BaseCode = "template\n"
  "Bar(T) -> Bar;";
   ConstrainedCode = "template\n"
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1110,7 +1110,7 @@
   !Contexts.back().IsExpression && !Line.startsWith(TT_ObjCProperty) &&
   !Tok->isOneOf(TT_TypeDeclarationParen, TT_RequiresExpressionLParen) 
&&
   (!Tok->Previous ||
-   !Tok->Previous->isOneOf(tok::kw___attribute,
+   !Tok->Previous->isOneOf(tok::kw___attribute, TT_RequiresClause,
TT_LeadingJavaAnnotation))) {
 Line.MightBeFunctionDecl = true;
   }


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -737,6 +737,16 @@
   BaseTokenCount = 26;
   TestRequires(__LINE__);
 
+  BaseCode = "template\n"
+ "T foo();";
+  ConstrainedCode = "template\n"
+"  requires(Foo)\n"
+"T foo();";
+  BaseTokenCount = 11;
+  RequiresTokenCount = 7;
+  PrefixTokenCount = 5;
+  TestRequires(__LINE__);
+
   BaseCode = "template\n"
  "Bar(T) -> Bar;";
   ConstrainedCode = "template\n"
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1110,7 +1110,7 @@
   !Contexts.back().IsExpression && !Line.startsWith(TT_ObjCProperty) &&
   !Tok->isOneOf(TT_TypeDeclarationParen, TT_RequiresExpressionLParen) &&
   (!Tok->Previous ||
-   !Tok->Previous->isOneOf(tok::kw___attribute,
+   !Tok->Previous->isOneOf(tok::kw___attribute, TT_RequiresClause,
TT_LeadingJavaAnnotation))) {
 Line.MightBeFunctionDecl = true;
   }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134325: [clang-format] Look ahead before consuming `bool` in requires clause.

2022-09-20 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel created this revision.
rymiel added reviewers: HazardyKnusperkeks, owenpan, MyDeveloperDay, curdeius.
Herald added a project: All.
rymiel requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

The comment handling the bool case says:
"bool is only allowed if it is directly followed by a paren for a cast"

This change more closely follows this directive by looking ahead for
the paren before consuming the bool keyword itself. Without a following
paren, the bool would be part of something else, such as a return type
for a function declaration

Fixes https://github.com/llvm/llvm-project/issues/57538


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D134325

Files:
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/TokenAnnotatorTest.cpp


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -449,6 +449,14 @@
   EXPECT_TRUE(Tokens[14]->ClosesRequiresClause);
   EXPECT_TOKEN(Tokens[20], tok::arrow, TT_TrailingReturnArrow);
 
+  Tokens = annotate("template \n"
+"requires Bar\n"
+"bool foo(T) { return false; }");
+  ASSERT_EQ(Tokens.size(), 21u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
+  EXPECT_TRUE(Tokens[9]->ClosesRequiresClause);
+  EXPECT_TOKEN(Tokens[11], tok::identifier, TT_FunctionDeclarationName);
+
   Tokens = annotate("template \n"
 "struct S {\n"
 "  void foo() const requires Bar;\n"
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -3528,9 +3528,10 @@
   // concept C = bool(...);
   // and bool is the only type, all other types as cast must be inside a
   // cast to bool an thus are handled by the other cases.
-  nextToken();
-  if (FormatTok->isNot(tok::l_paren))
+  if (Tokens->peekNextToken()->isNot(tok::l_paren))
 return;
+  nextToken();
+  assert(FormatTok->is(tok::l_paren));
   parseParens();
   break;
 


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -449,6 +449,14 @@
   EXPECT_TRUE(Tokens[14]->ClosesRequiresClause);
   EXPECT_TOKEN(Tokens[20], tok::arrow, TT_TrailingReturnArrow);
 
+  Tokens = annotate("template \n"
+"requires Bar\n"
+"bool foo(T) { return false; }");
+  ASSERT_EQ(Tokens.size(), 21u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
+  EXPECT_TRUE(Tokens[9]->ClosesRequiresClause);
+  EXPECT_TOKEN(Tokens[11], tok::identifier, TT_FunctionDeclarationName);
+
   Tokens = annotate("template \n"
 "struct S {\n"
 "  void foo() const requires Bar;\n"
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -3528,9 +3528,10 @@
   // concept C = bool(...);
   // and bool is the only type, all other types as cast must be inside a
   // cast to bool an thus are handled by the other cases.
-  nextToken();
-  if (FormatTok->isNot(tok::l_paren))
+  if (Tokens->peekNextToken()->isNot(tok::l_paren))
 return;
+  nextToken();
+  assert(FormatTok->is(tok::l_paren));
   parseParens();
   break;
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134325: [clang-format] Look ahead before consuming `bool` in requires clause.

2022-09-24 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel updated this revision to Diff 462670.
rymiel added a comment.

Remove redundant assert

thank you for pointing that out


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D134325

Files:
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/TokenAnnotatorTest.cpp


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -449,6 +449,14 @@
   EXPECT_TRUE(Tokens[14]->ClosesRequiresClause);
   EXPECT_TOKEN(Tokens[20], tok::arrow, TT_TrailingReturnArrow);
 
+  Tokens = annotate("template \n"
+"requires Bar\n"
+"bool foo(T) { return false; }");
+  ASSERT_EQ(Tokens.size(), 21u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
+  EXPECT_TRUE(Tokens[9]->ClosesRequiresClause);
+  EXPECT_TOKEN(Tokens[11], tok::identifier, TT_FunctionDeclarationName);
+
   Tokens = annotate("template \n"
 "struct S {\n"
 "  void foo() const requires Bar;\n"
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -3528,9 +3528,9 @@
   // concept C = bool(...);
   // and bool is the only type, all other types as cast must be inside a
   // cast to bool an thus are handled by the other cases.
-  nextToken();
-  if (FormatTok->isNot(tok::l_paren))
+  if (Tokens->peekNextToken()->isNot(tok::l_paren))
 return;
+  nextToken();
   parseParens();
   break;
 


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -449,6 +449,14 @@
   EXPECT_TRUE(Tokens[14]->ClosesRequiresClause);
   EXPECT_TOKEN(Tokens[20], tok::arrow, TT_TrailingReturnArrow);
 
+  Tokens = annotate("template \n"
+"requires Bar\n"
+"bool foo(T) { return false; }");
+  ASSERT_EQ(Tokens.size(), 21u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
+  EXPECT_TRUE(Tokens[9]->ClosesRequiresClause);
+  EXPECT_TOKEN(Tokens[11], tok::identifier, TT_FunctionDeclarationName);
+
   Tokens = annotate("template \n"
 "struct S {\n"
 "  void foo() const requires Bar;\n"
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -3528,9 +3528,9 @@
   // concept C = bool(...);
   // and bool is the only type, all other types as cast must be inside a
   // cast to bool an thus are handled by the other cases.
-  nextToken();
-  if (FormatTok->isNot(tok::l_paren))
+  if (Tokens->peekNextToken()->isNot(tok::l_paren))
 return;
+  nextToken();
   parseParens();
   break;
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134587: [clang-format] Correctly annotate static and consteval lambdas

2022-09-24 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel created this revision.
rymiel added reviewers: HazardyKnusperkeks, owenpan, MyDeveloperDay, curdeius.
Herald added a project: All.
rymiel requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

P1169  "static operator()" 
(https://wg21.link/P1169) is accepted to C++23
and while clang itself doesn't exactly support it yet, clang-format
could quite easily.

This simply allows the keyword `static` to be a part of lambdas as
specified by the addition to [expr.prim.lambda.general]

While adding this, I noticed `consteval` lambdas also aren't handled,
so that keyword is now allowed to be a part of lambdas as well


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D134587

Files:
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/TokenAnnotatorTest.cpp


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -837,6 +837,21 @@
   EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
   EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_LambdaLBrace);
 
+  Tokens = annotate("[]() consteval {}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]() mutable {}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]() static {}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_LambdaLBrace);
+
   Tokens = annotate("[]() -> auto {}");
   ASSERT_EQ(Tokens.size(), 9u) << Tokens;
   EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -2230,6 +2230,7 @@
 case tok::star:
 case tok::kw_const:
 case tok::kw_constexpr:
+case tok::kw_consteval:
 case tok::comma:
 case tok::greater:
 case tok::identifier:
@@ -2237,6 +2238,7 @@
 case tok::coloncolon:
 case tok::kw_mutable:
 case tok::kw_noexcept:
+case tok::kw_static:
   nextToken();
   break;
 // Specialization of a template with an integer parameter can contain


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -837,6 +837,21 @@
   EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
   EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_LambdaLBrace);
 
+  Tokens = annotate("[]() consteval {}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]() mutable {}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]() static {}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_LambdaLBrace);
+
   Tokens = annotate("[]() -> auto {}");
   ASSERT_EQ(Tokens.size(), 9u) << Tokens;
   EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -2230,6 +2230,7 @@
 case tok::star:
 case tok::kw_const:
 case tok::kw_constexpr:
+case tok::kw_consteval:
 case tok::comma:
 case tok::greater:
 case tok::identifier:
@@ -2237,6 +2238,7 @@
 case tok::coloncolon:
 case tok::kw_mutable:
 case tok::kw_noexcept:
+case tok::kw_static:
   nextToken();
   break;
 // Specialization of a template with an integer parameter can contain
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134587: [clang-format] Correctly annotate static and consteval lambdas

2022-09-25 Thread Emilia Dreamer via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG7847225576d5: [clang-format] Correctly annotate static and 
consteval lambdas (authored by rymiel).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D134587

Files:
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/TokenAnnotatorTest.cpp


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -837,6 +837,21 @@
   EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
   EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_LambdaLBrace);
 
+  Tokens = annotate("[]() consteval {}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]() mutable {}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]() static {}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_LambdaLBrace);
+
   Tokens = annotate("[]() -> auto {}");
   ASSERT_EQ(Tokens.size(), 9u) << Tokens;
   EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -2230,6 +2230,7 @@
 case tok::star:
 case tok::kw_const:
 case tok::kw_constexpr:
+case tok::kw_consteval:
 case tok::comma:
 case tok::greater:
 case tok::identifier:
@@ -2237,6 +2238,7 @@
 case tok::coloncolon:
 case tok::kw_mutable:
 case tok::kw_noexcept:
+case tok::kw_static:
   nextToken();
   break;
 // Specialization of a template with an integer parameter can contain


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -837,6 +837,21 @@
   EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
   EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_LambdaLBrace);
 
+  Tokens = annotate("[]() consteval {}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]() mutable {}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_LambdaLBrace);
+
+  Tokens = annotate("[]() static {}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
+  EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_LambdaLBrace);
+
   Tokens = annotate("[]() -> auto {}");
   ASSERT_EQ(Tokens.size(), 9u) << Tokens;
   EXPECT_TOKEN(Tokens[0], tok::l_square, TT_LambdaLSquare);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -2230,6 +2230,7 @@
 case tok::star:
 case tok::kw_const:
 case tok::kw_constexpr:
+case tok::kw_consteval:
 case tok::comma:
 case tok::greater:
 case tok::identifier:
@@ -2237,6 +2238,7 @@
 case tok::coloncolon:
 case tok::kw_mutable:
 case tok::kw_noexcept:
+case tok::kw_static:
   nextToken();
   break;
 // Specialization of a template with an integer parameter can contain
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134325: [clang-format] Look ahead before consuming `bool` in requires clause.

2022-09-25 Thread Emilia Dreamer via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG39e6077d9723: [clang-format] Look ahead before consuming 
`bool` in requires clause. (authored by rymiel).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D134325

Files:
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/TokenAnnotatorTest.cpp


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -449,6 +449,14 @@
   EXPECT_TRUE(Tokens[14]->ClosesRequiresClause);
   EXPECT_TOKEN(Tokens[20], tok::arrow, TT_TrailingReturnArrow);
 
+  Tokens = annotate("template \n"
+"requires Bar\n"
+"bool foo(T) { return false; }");
+  ASSERT_EQ(Tokens.size(), 21u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
+  EXPECT_TRUE(Tokens[9]->ClosesRequiresClause);
+  EXPECT_TOKEN(Tokens[11], tok::identifier, TT_FunctionDeclarationName);
+
   Tokens = annotate("template \n"
 "struct S {\n"
 "  void foo() const requires Bar;\n"
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -3530,9 +3530,9 @@
   // concept C = bool(...);
   // and bool is the only type, all other types as cast must be inside a
   // cast to bool an thus are handled by the other cases.
-  nextToken();
-  if (FormatTok->isNot(tok::l_paren))
+  if (Tokens->peekNextToken()->isNot(tok::l_paren))
 return;
+  nextToken();
   parseParens();
   break;
 


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -449,6 +449,14 @@
   EXPECT_TRUE(Tokens[14]->ClosesRequiresClause);
   EXPECT_TOKEN(Tokens[20], tok::arrow, TT_TrailingReturnArrow);
 
+  Tokens = annotate("template \n"
+"requires Bar\n"
+"bool foo(T) { return false; }");
+  ASSERT_EQ(Tokens.size(), 21u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
+  EXPECT_TRUE(Tokens[9]->ClosesRequiresClause);
+  EXPECT_TOKEN(Tokens[11], tok::identifier, TT_FunctionDeclarationName);
+
   Tokens = annotate("template \n"
 "struct S {\n"
 "  void foo() const requires Bar;\n"
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -3530,9 +3530,9 @@
   // concept C = bool(...);
   // and bool is the only type, all other types as cast must be inside a
   // cast to bool an thus are handled by the other cases.
-  nextToken();
-  if (FormatTok->isNot(tok::l_paren))
+  if (Tokens->peekNextToken()->isNot(tok::l_paren))
 return;
+  nextToken();
   parseParens();
   break;
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134626: [clang-format] Correctly indent closing brace of compound requires

2022-09-25 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel created this revision.
rymiel added reviewers: HazardyKnusperkeks, owenpan, MyDeveloperDay, curdeius.
Herald added a project: All.
rymiel requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

When a compound requirement is too long to fit onto a single line, the
braces are split apart onto separate lines, and the contained expression
is indented. However, this indentation would also apply to the closing
brace and the trailing return type requirement thereof.
This was because the indentation level was being restored after all
trailing things were already read

With this change, the initial level of the opening brace is set before
attempting to read any trailing return type requirements

Fixes https://github.com/llvm/llvm-project/issues/57108


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D134626

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


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -24418,6 +24418,16 @@
   "  { x * 1 } -> std::convertible_to;\n"
   "};");
 
+  verifyFormat("template \n"
+   "concept C = requires(T x) {\n"
+   "  {\n"
+   "long_long_long_function_call(1, 2, 3, 4, 5)\n"
+   "  } -> long_long_concept_name;\n"
+   "  {\n"
+   "long_long_long_function_call(1, 2, 3, 4, 5)\n"
+   "  } noexcept -> long_long_concept_name;\n"
+   "};");
+
   verifyFormat(
   "template \n"
   "concept Swappable = requires(T &&t, U &&u) {\n"
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -964,6 +964,8 @@
   if (MacroBlock && FormatTok->is(tok::l_paren))
 parseParens();
 
+  Line->Level = InitialLevel;
+
   if (FormatTok->is(tok::kw_noexcept)) {
 // A noexcept in a requires expression.
 nextToken();
@@ -979,8 +981,6 @@
   if (MunchSemi && FormatTok->is(tok::semi))
 nextToken();
 
-  Line->Level = InitialLevel;
-
   if (PPStartHash == PPEndHash) {
 Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
 if (OpeningLineIndex != UnwrappedLine::kInvalidIndex) {


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -24418,6 +24418,16 @@
   "  { x * 1 } -> std::convertible_to;\n"
   "};");
 
+  verifyFormat("template \n"
+   "concept C = requires(T x) {\n"
+   "  {\n"
+   "long_long_long_function_call(1, 2, 3, 4, 5)\n"
+   "  } -> long_long_concept_name;\n"
+   "  {\n"
+   "long_long_long_function_call(1, 2, 3, 4, 5)\n"
+   "  } noexcept -> long_long_concept_name;\n"
+   "};");
+
   verifyFormat(
   "template \n"
   "concept Swappable = requires(T &&t, U &&u) {\n"
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -964,6 +964,8 @@
   if (MacroBlock && FormatTok->is(tok::l_paren))
 parseParens();
 
+  Line->Level = InitialLevel;
+
   if (FormatTok->is(tok::kw_noexcept)) {
 // A noexcept in a requires expression.
 nextToken();
@@ -979,8 +981,6 @@
   if (MunchSemi && FormatTok->is(tok::semi))
 nextToken();
 
-  Line->Level = InitialLevel;
-
   if (PPStartHash == PPEndHash) {
 Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
 if (OpeningLineIndex != UnwrappedLine::kInvalidIndex) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134626: [clang-format] Correctly indent closing brace of compound requires

2022-09-25 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added a comment.

Note: I don't have the historical insight to know why the code order was as it 
was. I simply tried yoinking the place where the level was being set to occur 
earlier, and it surprisingly seemed to work, and also seemed to not break any 
other tests; I hope it doesn't break something in some subtle way


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D134626

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


[PATCH] D134626: [clang-format] Correctly indent closing brace of compound requires

2022-09-27 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added a comment.

I built 2 versions of clang-format, before and after this patch, and made 2 
separate clones of all of LLVM+clang and ran them through either, removing all 
`.clang-format`s, then ran a recursive diff.

I found 1 difference, in a test case at 
`clang/test/CodeGen/constrained-math-builtins.c` and reduced it to the 
following:

clang-format before the patch produced this:

  int foo() { ; };
  
// Comment
  
  #preprocessor

clang-format after this patch produced this:

  int foo() { ; };
  
  // Comment
  
  #preprocessor

Very specific requirements here, needing a comment which follows a function 
with a non-empty body and with a (redundant) trailing semicolon, followed by 
any preprocessor directive.

Nevertheless, the output seems to make more sense *with* the patch, so I think 
this counts as a bug fix rather than a regression?

My testing surely isn't perfect but this was the only difference I found 
(besides instances of the specific bug that this patch was intended to fix)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D134626

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


[PATCH] D129443: [clang-format] Add option for aligning requires clause body

2022-09-29 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel commandeered this revision.
rymiel added a reviewer: eoanermine.
rymiel added a comment.

Commandeering to finish the final nits as per 
https://github.com/llvm/llvm-project/issues/56283#issuecomment-1261653291


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129443

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


[PATCH] D129443: [clang-format] Add option for aligning requires clause body

2022-09-29 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel updated this revision to Diff 463772.
rymiel added a comment.

Resolve nits:

- Re-sorted uses of the name RequiresExpressionIndentationKind
- Updated version to be 16
- Add test for demonstrating indentation as subexpression
- Reformatted


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129443

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/Format.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -24984,6 +24984,123 @@
"bar(requires);");
 }
 
+TEST_F(FormatTest, RequiresExpressionIndentation) {
+  auto Style = getLLVMStyle();
+  EXPECT_EQ(Style.RequiresExpressionIndentation, FormatStyle::REI_Keyword);
+
+  verifyFormat("template \n"
+   "concept C = requires(T t) {\n"
+   "  typename T::value;\n"
+   "  requires requires(typename T::value v) {\n"
+   " { t == v } -> std::same_as;\n"
+   "   };\n"
+   "};",
+   Style);
+
+  verifyFormat(
+  "template \n"
+  "void bar(T)\n"
+  "  requires Foo && requires(T t) {\n"
+  "   { t.foo() } -> std::same_as;\n"
+  " } && requires(T t) {\n"
+  "{ t.bar() } -> std::same_as;\n"
+  "--t;\n"
+  "  };",
+  Style);
+
+  verifyFormat("template \n"
+   "  requires Foo &&\n"
+   "   requires(T t) {\n"
+   " { t.foo() } -> std::same_as;\n"
+   "   } && requires(T t) {\n"
+   "  { t.bar() } -> std::same_as;\n"
+   "  --t;\n"
+   "}\n"
+   "void bar(T);",
+   Style);
+
+  verifyFormat("template  void f() {\n"
+   "  if constexpr (requires(T t) {\n"
+   "  { t.bar() } -> std::same_as;\n"
+   "}) {\n"
+   "  }\n"
+   "}",
+   Style);
+
+  verifyFormat(
+  "template  void f() {\n"
+  "  if constexpr (condition && requires(T t) {\n"
+  "   { t.bar() } -> std::same_as;\n"
+  " }) {\n"
+  "  }\n"
+  "}",
+  Style);
+
+  verifyFormat("template  struct C {\n"
+   "  void f()\n"
+   "requires requires(T t) {\n"
+   "   { t.bar() } -> std::same_as;\n"
+   " };\n"
+   "};",
+   Style);
+
+  Style.RequiresExpressionIndentation = FormatStyle::REI_OuterScope;
+
+  verifyFormat("template \n"
+   "concept C = requires(T t) {\n"
+   "  typename T::value;\n"
+   "  requires requires(typename T::value v) {\n"
+   "{ t == v } -> std::same_as;\n"
+   "  };\n"
+   "};",
+   Style);
+
+  verifyFormat("template \n"
+   "void bar(T)\n"
+   "  requires Foo && requires(T t) {\n"
+   "{ t.foo() } -> std::same_as;\n"
+   "  } && requires(T t) {\n"
+   "{ t.bar() } -> std::same_as;\n"
+   "--t;\n"
+   "  };",
+   Style);
+
+  verifyFormat("template \n"
+   "  requires Foo &&\n"
+   "   requires(T t) {\n"
+   " { t.foo() } -> std::same_as;\n"
+   "   } && requires(T t) {\n"
+   " { t.bar() } -> std::same_as;\n"
+   " --t;\n"
+   "   }\n"
+   "void bar(T);",
+   Style);
+
+  verifyFormat("template  void f() {\n"
+   "  if constexpr (requires(T t) {\n"
+   "  { t.bar() } -> std::same_as;\n"
+   "}) {\n"
+   "  }\n"
+   "}",
+   Style);
+
+  verifyFormat("template  void f() {\n"
+   "  if constexpr (condition && requires(T t) {\n"
+   "  { t.bar() } -> std::same_as;\n"
+   "}) {\n"
+   "  }\n"
+   "}",
+   Style);
+
+  verifyFormat("template  struct C {\n"
+   "  void f()\n"
+   "requires requires(T t) {\n"
+   "  { t.bar() } -> std::same_as;\n"
+   "};\n"
+   "};",
+   Style);
+}
+
 TEST_F(Form

[PATCH] D129443: [clang-format] Add option for aligning requires clause body

2022-09-29 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel updated this revision to Diff 463773.
rymiel added a comment.

Missed a spot when re-sorting


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129443

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/Format.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -24984,6 +24984,123 @@
"bar(requires);");
 }
 
+TEST_F(FormatTest, RequiresExpressionIndentation) {
+  auto Style = getLLVMStyle();
+  EXPECT_EQ(Style.RequiresExpressionIndentation, FormatStyle::REI_Keyword);
+
+  verifyFormat("template \n"
+   "concept C = requires(T t) {\n"
+   "  typename T::value;\n"
+   "  requires requires(typename T::value v) {\n"
+   " { t == v } -> std::same_as;\n"
+   "   };\n"
+   "};",
+   Style);
+
+  verifyFormat(
+  "template \n"
+  "void bar(T)\n"
+  "  requires Foo && requires(T t) {\n"
+  "   { t.foo() } -> std::same_as;\n"
+  " } && requires(T t) {\n"
+  "{ t.bar() } -> std::same_as;\n"
+  "--t;\n"
+  "  };",
+  Style);
+
+  verifyFormat("template \n"
+   "  requires Foo &&\n"
+   "   requires(T t) {\n"
+   " { t.foo() } -> std::same_as;\n"
+   "   } && requires(T t) {\n"
+   "  { t.bar() } -> std::same_as;\n"
+   "  --t;\n"
+   "}\n"
+   "void bar(T);",
+   Style);
+
+  verifyFormat("template  void f() {\n"
+   "  if constexpr (requires(T t) {\n"
+   "  { t.bar() } -> std::same_as;\n"
+   "}) {\n"
+   "  }\n"
+   "}",
+   Style);
+
+  verifyFormat(
+  "template  void f() {\n"
+  "  if constexpr (condition && requires(T t) {\n"
+  "   { t.bar() } -> std::same_as;\n"
+  " }) {\n"
+  "  }\n"
+  "}",
+  Style);
+
+  verifyFormat("template  struct C {\n"
+   "  void f()\n"
+   "requires requires(T t) {\n"
+   "   { t.bar() } -> std::same_as;\n"
+   " };\n"
+   "};",
+   Style);
+
+  Style.RequiresExpressionIndentation = FormatStyle::REI_OuterScope;
+
+  verifyFormat("template \n"
+   "concept C = requires(T t) {\n"
+   "  typename T::value;\n"
+   "  requires requires(typename T::value v) {\n"
+   "{ t == v } -> std::same_as;\n"
+   "  };\n"
+   "};",
+   Style);
+
+  verifyFormat("template \n"
+   "void bar(T)\n"
+   "  requires Foo && requires(T t) {\n"
+   "{ t.foo() } -> std::same_as;\n"
+   "  } && requires(T t) {\n"
+   "{ t.bar() } -> std::same_as;\n"
+   "--t;\n"
+   "  };",
+   Style);
+
+  verifyFormat("template \n"
+   "  requires Foo &&\n"
+   "   requires(T t) {\n"
+   " { t.foo() } -> std::same_as;\n"
+   "   } && requires(T t) {\n"
+   " { t.bar() } -> std::same_as;\n"
+   " --t;\n"
+   "   }\n"
+   "void bar(T);",
+   Style);
+
+  verifyFormat("template  void f() {\n"
+   "  if constexpr (requires(T t) {\n"
+   "  { t.bar() } -> std::same_as;\n"
+   "}) {\n"
+   "  }\n"
+   "}",
+   Style);
+
+  verifyFormat("template  void f() {\n"
+   "  if constexpr (condition && requires(T t) {\n"
+   "  { t.bar() } -> std::same_as;\n"
+   "}) {\n"
+   "  }\n"
+   "}",
+   Style);
+
+  verifyFormat("template  struct C {\n"
+   "  void f()\n"
+   "requires requires(T t) {\n"
+   "  { t.bar() } -> std::same_as;\n"
+   "};\n"
+   "};",
+   Style);
+}
+
 TEST_F(FormatTest, StatementAttributeLikeMacros) {
   FormatStyle Style = getLLVMStyle();
   StringRef Source = "void Foo::slot() {\n"
Index: clang/lib/Format

[PATCH] D133413: [clang-tidy] Fix crashes on `if consteval` in readability checks

2022-09-29 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added a comment.

Ping? This is fixing a segmentation fault. Please let me know if there are 
other people I should add as reviewers


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133413

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


[PATCH] D133413: [clang-tidy] Fix crashes on `if consteval` in readability checks

2022-09-29 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel updated this revision to Diff 464142.
rymiel edited the summary of this revision.
rymiel added a comment.

Add release note

Thank you, Aaron! Is the note I've added okay? I didn't expect to need to add a 
note to a bugfix, but I haven't written a release note before at all 
regardless. And yes, I'm able to commit it myself.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133413

Files:
  clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp
  clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements-consteval-if.cpp
  
clang-tools-extra/test/clang-tidy/checkers/readability/simplify-bool-expr-cxx23.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/readability/simplify-bool-expr-cxx23.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability/simplify-bool-expr-cxx23.cpp
@@ -0,0 +1,13 @@
+// RUN: clang-tidy %s -checks='-*,readability-simplify-boolean-expr' -- -std=c++2b | count 0
+template 
+constexpr int foo() {
+  if consteval {
+if constexpr (Cond) {
+  return 0;
+} else {
+  return 1;
+}
+  } else {
+return 2;
+  }
+}
Index: clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements-consteval-if.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements-consteval-if.cpp
@@ -0,0 +1,31 @@
+// RUN: clang-tidy %s -checks='-*,readability-braces-around-statements' -- -std=c++2b | count 0
+
+constexpr void handle(bool) {}
+
+constexpr void shouldPass() {
+  if consteval {
+handle(true);
+  } else {
+handle(false);
+  }
+}
+
+constexpr void shouldPassNegated() {
+  if !consteval {
+handle(false);
+  } else {
+handle(true);
+  }
+}
+
+constexpr void shouldPassSimple() {
+  if consteval {
+handle(true);
+  }
+}
+
+void run() {
+shouldPass();
+shouldPassNegated();
+shouldPassSimple();
+}
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -149,6 +149,11 @@
   copy assignment operators with nonstandard return types. The check is restricted to
   c++11-or-later.
 
+- Fixed crashes in :doc:`readability-braces-around-statements
+  ` and
+  :doc:`readability-simplify-boolean-expr `
+  when using a C++23 ``if consteval`` statement.
+
 Removed checks
 ^^
 
Index: clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
===
--- clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
+++ clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
@@ -354,8 +354,9 @@
   }
 
   bool VisitIfStmt(IfStmt *If) {
-// Skip any if's that have a condition var or an init statement.
-if (If->hasInitStorage() || If->hasVarStorage())
+// Skip any if's that have a condition var or an init statement, or are
+// "if consteval" statements.
+if (If->hasInitStorage() || If->hasVarStorage() || If->isConsteval())
   return true;
 /*
  * if (true) ThenStmt(); -> ThenStmt();
Index: clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp
===
--- clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp
+++ clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp
@@ -131,6 +131,10 @@
   return;
 checkStmt(Result, S->getBody(), StartLoc);
   } else if (const auto *S = Result.Nodes.getNodeAs("if")) {
+// "if consteval" always has braces.
+if (S->isConsteval())
+  return;
+
 SourceLocation StartLoc = findRParenLoc(S, SM, Context);
 if (StartLoc.isInvalid())
   return;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134853: [clang-format] Correctly annotate UDLs as OverloadedOperator

2022-09-29 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel created this revision.
rymiel added reviewers: HazardyKnusperkeks, owenpan, MyDeveloperDay, curdeius.
Herald added a project: All.
rymiel updated this revision to Diff 463768.
rymiel edited the summary of this revision.
rymiel added a comment.
rymiel updated this revision to Diff 464145.
rymiel updated this revision to Diff 464147.
rymiel published this revision for review.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Note issue being fixed


rymiel added a comment.

Notes:

As noted above, the left paren was correctly annotated, but the logic in 
`rParenEndsCast` goes based off of what is *before* the l paren. This resulted 
in a paren pair where the left one was OverloadedOperatorLParen and the right 
one was CastRParen.

This means this bug could really be fixed in two ways, I chose to annotate the 
UDL with OverloadedOperator, as I felt like that resulted in "more correct 
tokens".

Edit: While attempting to add token annotator tests for this fix, i noticed 
there aren't any at all for overloaded operators, and while writing them, I 
noticed more operators which aren't marked with OverloadedOperator, such as 
`operator[]` and UDLs which don't start with an underscore. (see below)

Unless any reviewers have any other opinions, I would leave fixing those out of 
this patch and leave the tests "incomplete" for now?

Also, UDLs that don't start with an underscore aren't considered a single 
"string_literal" token, instead becoming a string literal `""` and an 
identifier following it (where as those with an underscore become one token, 
such as `""_a`). I'm unsure if that's the expected case and if both tokens 
should just be considered part of the operator


rymiel added a comment.

Also add a few format tests


rymiel added a comment.

Reformat


rymiel added a comment.

While this patch fixes the linked bug, but I encountered more questions that I 
would like second opinions on (see notes above)


While the opening parenthesis of an user-defined literal operator was
correctly annotated as OverloadedOperatorLParen, the "" and its suffix
wasn't annotated as OverloadedOperator.

Fixes https://github.com/llvm/llvm-project/issues/58035


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D134853

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


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -376,6 +376,44 @@
   EXPECT_TOKEN(Tokens[11], tok::amp, TT_PointerOrReference);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsOverloadedOperators) {
+  auto Tokens = annotate("x.operator+()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::plus, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator=()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::equal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator+=()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::plusequal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator,()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::comma, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator()()");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::r_paren, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator[]()");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  // EXPECT_TOKEN(Tokens[3], tok::l_square, TT_OverloadedOperator);
+  // EXPECT_TOKEN(Tokens[4], tok::r_square, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\"_a()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\"a()");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  // EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  // EXPECT_TOKEN(Tokens[4], tok::identifier, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
+}
+
 TEST_F(TokenAnnotatorTest, UnderstandsRequiresClausesAndConcepts) {
   auto Tokens = annotate("template \n"
  "concept C = (Foo && Bar) && (Bar && Baz);");
Index: clang/unittests/Format/FormatTest.cpp

[PATCH] D133413: [clang-tidy] Fix crashes on `if consteval` in readability checks

2022-09-30 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel marked 2 inline comments as done.
rymiel added a comment.

Thank you for pointing those out, I was indeed able to cause crashes from those 
locations


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133413

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


[PATCH] D133413: [clang-tidy] Fix crashes on `if consteval` in readability checks

2022-09-30 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel updated this revision to Diff 464176.
rymiel added a comment.

Extra consteval checks in SimplifyBooleanExprCheck


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133413

Files:
  clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp
  clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements-consteval-if.cpp
  
clang-tools-extra/test/clang-tidy/checkers/readability/simplify-bool-expr-cxx23.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/readability/simplify-bool-expr-cxx23.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability/simplify-bool-expr-cxx23.cpp
@@ -0,0 +1,37 @@
+// RUN: clang-tidy %s -checks='-*,readability-simplify-boolean-expr' -- -std=c++2b | count 0
+template 
+constexpr int testIf() {
+  if consteval {
+if constexpr (Cond) {
+  return 0;
+} else {
+  return 1;
+}
+  } else {
+return 2;
+  }
+}
+
+constexpr bool testCompound() {
+  if consteval {
+return true;
+  }
+  return false;
+}
+
+constexpr bool testCase(int I) {
+  switch (I) {
+case 0: {
+  if consteval {
+return true;
+  }
+  return false;
+}
+default: {
+  if consteval {
+return false;
+  }
+  return true;
+}
+  }
+}
Index: clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements-consteval-if.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements-consteval-if.cpp
@@ -0,0 +1,31 @@
+// RUN: clang-tidy %s -checks='-*,readability-braces-around-statements' -- -std=c++2b | count 0
+
+constexpr void handle(bool) {}
+
+constexpr void shouldPass() {
+  if consteval {
+handle(true);
+  } else {
+handle(false);
+  }
+}
+
+constexpr void shouldPassNegated() {
+  if !consteval {
+handle(false);
+  } else {
+handle(true);
+  }
+}
+
+constexpr void shouldPassSimple() {
+  if consteval {
+handle(true);
+  }
+}
+
+void run() {
+shouldPass();
+shouldPassNegated();
+shouldPassSimple();
+}
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -149,6 +149,11 @@
   copy assignment operators with nonstandard return types. The check is restricted to
   c++11-or-later.
 
+- Fixed crashes in :doc:`readability-braces-around-statements
+  ` and
+  :doc:`readability-simplify-boolean-expr `
+  when using a C++23 ``if consteval`` statement.
+
 Removed checks
 ^^
 
Index: clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
===
--- clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
+++ clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
@@ -354,8 +354,9 @@
   }
 
   bool VisitIfStmt(IfStmt *If) {
-// Skip any if's that have a condition var or an init statement.
-if (If->hasInitStorage() || If->hasVarStorage())
+// Skip any if's that have a condition var or an init statement, or are
+// "if consteval" statements.
+if (If->hasInitStorage() || If->hasVarStorage() || If->isConsteval())
   return true;
 /*
  * if (true) ThenStmt(); -> ThenStmt();
@@ -467,7 +468,8 @@
  * if (Cond) return false; return true; -> return !Cond;
  */
 auto *If = cast(*First);
-if (!If->hasInitStorage() && !If->hasVarStorage()) {
+if (!If->hasInitStorage() && !If->hasVarStorage() &&
+!If->isConsteval()) {
   ExprAndBool ThenReturnBool =
   checkSingleStatement(If->getThen(), parseReturnLiteralBool);
   if (ThenReturnBool &&
@@ -491,7 +493,7 @@
 : cast(*First)->getSubStmt();
 auto *SubIf = dyn_cast(SubStmt);
 if (SubIf && !SubIf->getElse() && !SubIf->hasInitStorage() &&
-!SubIf->hasVarStorage()) {
+!SubIf->hasVarStorage() && !SubIf->isConsteval()) {
   ExprAndBool ThenReturnBool =
   checkSingleStatement(SubIf->getThen(), parseReturnLiteralBool);
   if (ThenReturnBool &&
Index: clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp
===
--- clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp
+++ clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp
@@ -131,6 +131,10 @@
   return;
 checkStmt(Result, S->getBody(), StartLoc);
   } else if (const auto *S = Result.Nodes.getNodeAs("if")) {
+   

[PATCH] D134626: [clang-format] Correctly indent closing brace of compound requires

2022-09-30 Thread Emilia Dreamer via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG1fa115b56979: [clang-format] Correctly indent closing brace 
of compound requires (authored by rymiel).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D134626

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


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -24510,6 +24510,16 @@
   "  { x * 1 } -> std::convertible_to;\n"
   "};");
 
+  verifyFormat("template \n"
+   "concept C = requires(T x) {\n"
+   "  {\n"
+   "long_long_long_function_call(1, 2, 3, 4, 5)\n"
+   "  } -> long_long_concept_name;\n"
+   "  {\n"
+   "long_long_long_function_call(1, 2, 3, 4, 5)\n"
+   "  } noexcept -> long_long_concept_name;\n"
+   "};");
+
   verifyFormat(
   "template \n"
   "concept Swappable = requires(T &&t, U &&u) {\n"
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -964,6 +964,8 @@
   if (MacroBlock && FormatTok->is(tok::l_paren))
 parseParens();
 
+  Line->Level = InitialLevel;
+
   if (FormatTok->is(tok::kw_noexcept)) {
 // A noexcept in a requires expression.
 nextToken();
@@ -979,8 +981,6 @@
   if (MunchSemi && FormatTok->is(tok::semi))
 nextToken();
 
-  Line->Level = InitialLevel;
-
   if (PPStartHash == PPEndHash) {
 Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
 if (OpeningLineIndex != UnwrappedLine::kInvalidIndex) {


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -24510,6 +24510,16 @@
   "  { x * 1 } -> std::convertible_to;\n"
   "};");
 
+  verifyFormat("template \n"
+   "concept C = requires(T x) {\n"
+   "  {\n"
+   "long_long_long_function_call(1, 2, 3, 4, 5)\n"
+   "  } -> long_long_concept_name;\n"
+   "  {\n"
+   "long_long_long_function_call(1, 2, 3, 4, 5)\n"
+   "  } noexcept -> long_long_concept_name;\n"
+   "};");
+
   verifyFormat(
   "template \n"
   "concept Swappable = requires(T &&t, U &&u) {\n"
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -964,6 +964,8 @@
   if (MacroBlock && FormatTok->is(tok::l_paren))
 parseParens();
 
+  Line->Level = InitialLevel;
+
   if (FormatTok->is(tok::kw_noexcept)) {
 // A noexcept in a requires expression.
 nextToken();
@@ -979,8 +981,6 @@
   if (MunchSemi && FormatTok->is(tok::semi))
 nextToken();
 
-  Line->Level = InitialLevel;
-
   if (PPStartHash == PPEndHash) {
 Line->MatchingOpeningBlockLineIndex = OpeningLineIndex;
 if (OpeningLineIndex != UnwrappedLine::kInvalidIndex) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134652: [clang-format] Add Basic Carbon Support/Infrastructure to clang-format

2022-10-02 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added a comment.

I think the above is especially relevant as Carbon may yet change everything 
about its syntax; for example, in this patch, `me` has been made a keyword, but 
that may change in the future: 
https://github.com/carbon-language/carbon-lang/pull/1382


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

https://reviews.llvm.org/D134652

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


[PATCH] D134853: [clang-format] Correctly annotate UDLs as OverloadedOperator

2022-10-02 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added a comment.

> The operator `""` and the identifier that follows should be two separate 
> tokens regardless if the identifier starts with an underscore.

So, after some investigation, it turns out the clang lexer only combines an 
underscore-less UDL to a single `string_literal` token if it's a valid standard 
library UDL (in the given standard library version)

https://github.com/llvm/llvm-project/blob/6f46ff3765dcdc178b9cf52ebd8c03437806798a/clang/lib/Lex/Lexer.cpp#L1960-L1975
https://github.com/llvm/llvm-project/blob/3f18f7c0072b642f5fe88d2fb7bb8ccf69a6c6f5/clang/lib/Lex/LiteralSupport.cpp#L1180-L1185

Which means only single-token `string_literal`s should be considered


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D134853

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


[PATCH] D133413: [clang-tidy] Fix crashes on `if consteval` in readability checks

2022-10-05 Thread Emilia Dreamer via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG2d149d17f069: [clang-tidy] Fix crashes on `if consteval` in 
readability checks (authored by rymiel).

Changed prior to commit:
  https://reviews.llvm.org/D133413?vs=464176&id=465291#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133413

Files:
  clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp
  clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements-consteval-if.cpp
  
clang-tools-extra/test/clang-tidy/checkers/readability/simplify-bool-expr-cxx23.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/readability/simplify-bool-expr-cxx23.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability/simplify-bool-expr-cxx23.cpp
@@ -0,0 +1,37 @@
+// RUN: clang-tidy %s -checks='-*,readability-simplify-boolean-expr' -- -std=c++2b | count 0
+template 
+constexpr int testIf() {
+  if consteval {
+if constexpr (Cond) {
+  return 0;
+} else {
+  return 1;
+}
+  } else {
+return 2;
+  }
+}
+
+constexpr bool testCompound() {
+  if consteval {
+return true;
+  }
+  return false;
+}
+
+constexpr bool testCase(int I) {
+  switch (I) {
+case 0: {
+  if consteval {
+return true;
+  }
+  return false;
+}
+default: {
+  if consteval {
+return false;
+  }
+  return true;
+}
+  }
+}
Index: clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements-consteval-if.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability/braces-around-statements-consteval-if.cpp
@@ -0,0 +1,31 @@
+// RUN: clang-tidy %s -checks='-*,readability-braces-around-statements' -- -std=c++2b | count 0
+
+constexpr void handle(bool) {}
+
+constexpr void shouldPass() {
+  if consteval {
+handle(true);
+  } else {
+handle(false);
+  }
+}
+
+constexpr void shouldPassNegated() {
+  if !consteval {
+handle(false);
+  } else {
+handle(true);
+  }
+}
+
+constexpr void shouldPassSimple() {
+  if consteval {
+handle(true);
+  }
+}
+
+void run() {
+shouldPass();
+shouldPassNegated();
+shouldPassSimple();
+}
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -159,6 +159,11 @@
   ` to not
   warn about `const` value parameters of declarations inside macros.
 
+- Fixed crashes in :doc:`readability-braces-around-statements
+  ` and
+  :doc:`readability-simplify-boolean-expr `
+  when using a C++23 ``if consteval`` statement.
+
 Removed checks
 ^^
 
Index: clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
===
--- clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
+++ clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp
@@ -354,8 +354,9 @@
   }
 
   bool VisitIfStmt(IfStmt *If) {
-// Skip any if's that have a condition var or an init statement.
-if (If->hasInitStorage() || If->hasVarStorage())
+// Skip any if's that have a condition var or an init statement, or are
+// "if consteval" statements.
+if (If->hasInitStorage() || If->hasVarStorage() || If->isConsteval())
   return true;
 /*
  * if (true) ThenStmt(); -> ThenStmt();
@@ -467,7 +468,8 @@
  * if (Cond) return false; return true; -> return !Cond;
  */
 auto *If = cast(*First);
-if (!If->hasInitStorage() && !If->hasVarStorage()) {
+if (!If->hasInitStorage() && !If->hasVarStorage() &&
+!If->isConsteval()) {
   ExprAndBool ThenReturnBool =
   checkSingleStatement(If->getThen(), parseReturnLiteralBool);
   if (ThenReturnBool &&
@@ -491,7 +493,7 @@
 : cast(*First)->getSubStmt();
 auto *SubIf = dyn_cast(SubStmt);
 if (SubIf && !SubIf->getElse() && !SubIf->hasInitStorage() &&
-!SubIf->hasVarStorage()) {
+!SubIf->hasVarStorage() && !SubIf->isConsteval()) {
   ExprAndBool ThenReturnBool =
   checkSingleStatement(SubIf->getThen(), parseReturnLiteralBool);
   if (ThenReturnBool &&
Index: clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp
===
--- clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp
+++ clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp
@@ -131,6 +131,1

[PATCH] D129443: [clang-format] Add option for aligning requires clause body

2022-10-07 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added a comment.

It wasn't an accidental regression, though, it was a conscious formatting 
decision (maybe ask @HazardyKnusperkeks for more). Similar to how lambdas can 
be formatted aligned to the introducer, i think this option does make sense.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129443

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


[PATCH] D129443: [clang-format] Add option for aligning requires clause body

2022-10-10 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel updated this revision to Diff 466551.
rymiel added a comment.

Flip the default and note that in the Release Notes

Sorry, I did not realize I was mentioned.
I think the default option will always be the first option? So I swapped them 
around.
Note that I didn't change the LLVM config, which right now is still set to 
`Keyword`.
I'm also not sure if the release notes should note this as "important" or 
"breaking"


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129443

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/Format.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -24995,6 +24995,123 @@
"bar(requires);");
 }
 
+TEST_F(FormatTest, RequiresExpressionIndentation) {
+  auto Style = getLLVMStyle();
+  EXPECT_EQ(Style.RequiresExpressionIndentation, FormatStyle::REI_Keyword);
+
+  verifyFormat("template \n"
+   "concept C = requires(T t) {\n"
+   "  typename T::value;\n"
+   "  requires requires(typename T::value v) {\n"
+   " { t == v } -> std::same_as;\n"
+   "   };\n"
+   "};",
+   Style);
+
+  verifyFormat(
+  "template \n"
+  "void bar(T)\n"
+  "  requires Foo && requires(T t) {\n"
+  "   { t.foo() } -> std::same_as;\n"
+  " } && requires(T t) {\n"
+  "{ t.bar() } -> std::same_as;\n"
+  "--t;\n"
+  "  };",
+  Style);
+
+  verifyFormat("template \n"
+   "  requires Foo &&\n"
+   "   requires(T t) {\n"
+   " { t.foo() } -> std::same_as;\n"
+   "   } && requires(T t) {\n"
+   "  { t.bar() } -> std::same_as;\n"
+   "  --t;\n"
+   "}\n"
+   "void bar(T);",
+   Style);
+
+  verifyFormat("template  void f() {\n"
+   "  if constexpr (requires(T t) {\n"
+   "  { t.bar() } -> std::same_as;\n"
+   "}) {\n"
+   "  }\n"
+   "}",
+   Style);
+
+  verifyFormat(
+  "template  void f() {\n"
+  "  if constexpr (condition && requires(T t) {\n"
+  "   { t.bar() } -> std::same_as;\n"
+  " }) {\n"
+  "  }\n"
+  "}",
+  Style);
+
+  verifyFormat("template  struct C {\n"
+   "  void f()\n"
+   "requires requires(T t) {\n"
+   "   { t.bar() } -> std::same_as;\n"
+   " };\n"
+   "};",
+   Style);
+
+  Style.RequiresExpressionIndentation = FormatStyle::REI_OuterScope;
+
+  verifyFormat("template \n"
+   "concept C = requires(T t) {\n"
+   "  typename T::value;\n"
+   "  requires requires(typename T::value v) {\n"
+   "{ t == v } -> std::same_as;\n"
+   "  };\n"
+   "};",
+   Style);
+
+  verifyFormat("template \n"
+   "void bar(T)\n"
+   "  requires Foo && requires(T t) {\n"
+   "{ t.foo() } -> std::same_as;\n"
+   "  } && requires(T t) {\n"
+   "{ t.bar() } -> std::same_as;\n"
+   "--t;\n"
+   "  };",
+   Style);
+
+  verifyFormat("template \n"
+   "  requires Foo &&\n"
+   "   requires(T t) {\n"
+   " { t.foo() } -> std::same_as;\n"
+   "   } && requires(T t) {\n"
+   " { t.bar() } -> std::same_as;\n"
+   " --t;\n"
+   "   }\n"
+   "void bar(T);",
+   Style);
+
+  verifyFormat("template  void f() {\n"
+   "  if constexpr (requires(T t) {\n"
+   "  { t.bar() } -> std::same_as;\n"
+   "}) {\n"
+   "  }\n"
+   "}",
+   Style);
+
+  verifyFormat("template  void f() {\n"
+   "  if constexpr (condition && requires(T t) {\n"
+   "  { t.bar() } -> std::same_as;\n"
+   "}) {\n"
+   "  }\n"
+   "}",
+   Style);
+
+  verifyFormat("template  struct C {\n"
+   "

[PATCH] D134853: [clang-format] Correctly annotate UDLs as OverloadedOperator

2022-10-11 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel updated this revision to Diff 466862.
rymiel marked an inline comment as done.
rymiel added a comment.

Handle UDLs with and without spaces

Thank you @owenpan, I was not actually aware UDLs without spaces were valid.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D134853

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

Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -376,6 +376,66 @@
   EXPECT_TOKEN(Tokens[11], tok::amp, TT_PointerOrReference);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsOverloadedOperators) {
+  auto Tokens = annotate("x.operator+()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::plus, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator=()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::equal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator+=()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::plusequal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator,()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::comma, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator()()");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::r_paren, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator[]()");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  // EXPECT_TOKEN(Tokens[3], tok::l_square, TT_OverloadedOperator);
+  // EXPECT_TOKEN(Tokens[4], tok::r_square, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\"_a()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\" _a()");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::identifier, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\"_long_literal()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\" _long_literal()");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::identifier, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\"if()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\"s()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\" s()");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::identifier, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
+}
+
 TEST_F(TokenAnnotatorTest, UnderstandsRequiresClausesAndConcepts) {
   auto Tokens = annotate("template \n"
  "concept C = (Foo && Bar) && (Bar && Baz);");
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -10153,6 +10153,14 @@
   // verifyFormat("void f() { operator*(a & a); }");
   // verifyFormat("void f() { operator&(a, b * b); }");
 
+  verifyFormat("void f() { return operator()(x) * b; }");
+  verifyFormat("void f() { return operator[](x) * b; }");
+  verifyFormat("void f() { return operator\"\"_a(x) * b; }");
+  verifyFormat("void f() { return operator\"\" _a(x) * b; }");
+  verifyFormat("void f() { return operator\"\"s(x) * b; }");
+  verifyForm

[PATCH] D129443: [clang-format] Add option for aligning requires clause body

2022-10-11 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel marked 2 inline comments as done.
rymiel added inline comments.



Comment at: clang/unittests/Format/FormatTest.cpp:20036
   Style.Language = FormatStyle::LK_Cpp;
+  CHECK_PARSE_BOOL(AlignRequiresClauseBody);
   CHECK_PARSE_BOOL(AlignTrailingComments);

owenpan wrote:
> HazardyKnusperkeks wrote:
> > Please add the parsing test for the enum.
> @rymiel Is this done?
The code this comment was added on has been completely removed; so i guess i'll 
mark it as done


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129443

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


[PATCH] D135707: [clang-format] Correctly annotate star/amp in function pointer params

2022-10-11 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel created this revision.
rymiel added reviewers: HazardyKnusperkeks, owenpan, MyDeveloperDay, curdeius.
Herald added a project: All.
rymiel requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Inside the arguments part of a function pointer declaration,
`determineStarAmpUsage` results in a binary operator rather than
pointers, because said parens are assumed to be an expression.

This patch correctly marks the argument parens of a function
pointer type as not an expression. Note that this fix already
existed for Objective-C blocks as part of 
f1f267b447f60528440d2c066b29ab014ae7f90f.
As Objective-C blocks and C/C++ function pointers share a lot
of the same logic, that fix also makes sense here.

Fixes https://github.com/llvm/llvm-project/issues/31659


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D135707

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


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -131,6 +131,20 @@
   Tokens = annotate("delete[] *(ptr);");
   EXPECT_EQ(Tokens.size(), 9u) << Tokens;
   EXPECT_TOKEN(Tokens[3], tok::star, TT_UnaryOperator);
+
+  Tokens = annotate("void f() { void (*fnptr)(char* foo); }");
+  EXPECT_EQ(Tokens.size(), 18u) << Tokens;
+  EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_FunctionTypeLParen);
+  // FIXME: The star of a function pointer probably makes more sense as
+  // TT_PointerOrReference.
+  EXPECT_TOKEN(Tokens[7], tok::star, TT_UnaryOperator);
+  EXPECT_TOKEN(Tokens[12], tok::star, TT_PointerOrReference);
+
+  Tokens = annotate("void f() { void (*fnptr)(t* foo); }");
+  EXPECT_EQ(Tokens.size(), 18u) << Tokens;
+  EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_FunctionTypeLParen);
+  EXPECT_TOKEN(Tokens[7], tok::star, TT_UnaryOperator);
+  EXPECT_TOKEN(Tokens[12], tok::star, TT_PointerOrReference);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandsUsesOfPlusAndMinus) {
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -10459,6 +10459,7 @@
   verifyFormat("#define MACRO() [](A *a) { return 1; }");
   verifyFormat("Constructor() : member([](A *a, B *b) {}) {}");
   verifyIndependentOfContext("typedef void (*f)(int *a);");
+  verifyIndependentOfContext("typedef void (*f)(Type *a);");
   verifyIndependentOfContext("int i{a * b};");
   verifyIndependentOfContext("aaa && aaa->f();");
   verifyIndependentOfContext("int x = ~*p;");
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -302,7 +302,8 @@
   Contexts.back().ContextType = Context::ForEachMacro;
   Contexts.back().IsExpression = false;
 } else if (OpeningParen.Previous && OpeningParen.Previous->MatchingParen &&
-   OpeningParen.Previous->MatchingParen->is(TT_ObjCBlockLParen)) {
+   OpeningParen.Previous->MatchingParen->isOneOf(
+   TT_ObjCBlockLParen, TT_FunctionTypeLParen)) {
   Contexts.back().IsExpression = false;
 } else if (!Line.MustBeDeclaration && !Line.InPPDirective) {
   bool IsForOrCatch =


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -131,6 +131,20 @@
   Tokens = annotate("delete[] *(ptr);");
   EXPECT_EQ(Tokens.size(), 9u) << Tokens;
   EXPECT_TOKEN(Tokens[3], tok::star, TT_UnaryOperator);
+
+  Tokens = annotate("void f() { void (*fnptr)(char* foo); }");
+  EXPECT_EQ(Tokens.size(), 18u) << Tokens;
+  EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_FunctionTypeLParen);
+  // FIXME: The star of a function pointer probably makes more sense as
+  // TT_PointerOrReference.
+  EXPECT_TOKEN(Tokens[7], tok::star, TT_UnaryOperator);
+  EXPECT_TOKEN(Tokens[12], tok::star, TT_PointerOrReference);
+
+  Tokens = annotate("void f() { void (*fnptr)(t* foo); }");
+  EXPECT_EQ(Tokens.size(), 18u) << Tokens;
+  EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_FunctionTypeLParen);
+  EXPECT_TOKEN(Tokens[7], tok::star, TT_UnaryOperator);
+  EXPECT_TOKEN(Tokens[12], tok::star, TT_PointerOrReference);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandsUsesOfPlusAndMinus) {
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -10459,6 +10459,7 @@
   verifyFormat("#define MACRO() [](A *a) { return 1; }");
   verifyFormat("Constructor() : member([](A *a, B 

[PATCH] D134853: [clang-format] Correctly annotate UDLs as OverloadedOperator

2022-10-13 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel updated this revision to Diff 467677.
rymiel added a comment.

Full stops in comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D134853

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

Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -376,6 +376,66 @@
   EXPECT_TOKEN(Tokens[11], tok::amp, TT_PointerOrReference);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsOverloadedOperators) {
+  auto Tokens = annotate("x.operator+()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::plus, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator=()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::equal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator+=()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::plusequal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator,()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::comma, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator()()");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::r_paren, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator[]()");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  // EXPECT_TOKEN(Tokens[3], tok::l_square, TT_OverloadedOperator);
+  // EXPECT_TOKEN(Tokens[4], tok::r_square, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\"_a()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\" _a()");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::identifier, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\"_long_literal()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\" _long_literal()");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::identifier, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\"if()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\"s()");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("x.operator\"\" s()");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::identifier, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
+}
+
 TEST_F(TokenAnnotatorTest, UnderstandsRequiresClausesAndConcepts) {
   auto Tokens = annotate("template \n"
  "concept C = (Foo && Bar) && (Bar && Baz);");
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -10153,6 +10153,14 @@
   // verifyFormat("void f() { operator*(a & a); }");
   // verifyFormat("void f() { operator&(a, b * b); }");
 
+  verifyFormat("void f() { return operator()(x) * b; }");
+  verifyFormat("void f() { return operator[](x) * b; }");
+  verifyFormat("void f() { return operator\"\"_a(x) * b; }");
+  verifyFormat("void f() { return operator\"\" _a(x) * b; }");
+  verifyFormat("void f() { return operator\"\"s(x) * b; }");
+  verifyFormat("void f() { return operator\"\" s(x) * b; }");
+  verifyFormat("void f() { return operator\"\"if(x) * b; }");
+
   verifyFormat("

[PATCH] D129443: [clang-format] Add option for aligning requires clause body

2022-10-13 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added a comment.

Changing the default LLVM style would change the output of all the 
requires-related test cases in `FormatTest.Concepts`. Should I change these 
test cases to use the new indentation or pass the `REI_Keyword` style to them?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129443

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


[PATCH] D135707: [clang-format] Correctly annotate star/amp in function pointer params

2022-10-14 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added a comment.

Thanks for the kind words ❤️ (I've noticed Björn already includes me in his 
reviewers list); and while I am humbled, and I do look at every patch, I don't 
*yet* trust myself to actually perform good code review, as it's not something 
I've really ever done before.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D135707

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


[PATCH] D134853: [clang-format] Correctly annotate UDLs as OverloadedOperator

2022-10-17 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added inline comments.



Comment at: clang/unittests/Format/TokenAnnotatorTest.cpp:413
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::identifier, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);

owenpan wrote:
> We need/should not annotate the suffix.
Unless I change the logic in `rParenEndsCast`, the suffix does need to be an 
OverloadedOperator, since it goes off of the token immediately before left 
paren (https://reviews.llvm.org/D134853#3822842)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D134853

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


[PATCH] D129443: [clang-format] Add option for aligning requires clause body

2022-10-17 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel updated this revision to Diff 468414.
rymiel added a comment.

Swap the default for LLVM style, and adjust tests which depended on the 
previous style to still use it.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129443

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/Format.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -24308,6 +24308,12 @@
 TEST_F(FormatTest, Concepts) {
   EXPECT_EQ(getLLVMStyle().BreakBeforeConceptDeclarations,
 FormatStyle::BBCDS_Always);
+
+  // The default in LLVM style is REI_OuterScope, but these tests were written
+  // when the default was REI_Keyword.
+  FormatStyle Style = getLLVMStyle();
+  Style.RequiresExpressionIndentation = FormatStyle::REI_Keyword;
+
   verifyFormat("template \n"
"concept True = true;");
 
@@ -24324,13 +24330,15 @@
"concept DelayedCheck = true && requires(T t) {\n"
" t.bar();\n"
" t.baz();\n"
-   "   } && sizeof(T) <= 8;");
+   "   } && sizeof(T) <= 8;",
+   Style);
 
   verifyFormat("template \n"
"concept DelayedCheck = true && requires(T t) { // Comment\n"
" t.bar();\n"
" t.baz();\n"
-   "   } && sizeof(T) <= 8;");
+   "   } && sizeof(T) <= 8;",
+   Style);
 
   verifyFormat("template \n"
"concept DelayedCheck = false || requires(T t) { t.bar(); } && "
@@ -24432,26 +24440,30 @@
"concept Hashable = requires(T a) {\n"
" { std::hash{}(a) } -> "
"std::convertible_to;\n"
-   "   };");
+   "   };",
+   Style);
 
   verifyFormat(
   "template \n"
   "concept EqualityComparable = requires(T a, T b) {\n"
   "   { a == b } -> std::same_as;\n"
-  " };");
+  " };",
+  Style);
 
   verifyFormat(
   "template \n"
   "concept EqualityComparable = requires(T a, T b) {\n"
   "   { a == b } -> std::same_as;\n"
   "   { a != b } -> std::same_as;\n"
-  " };");
+  " };",
+  Style);
 
   verifyFormat("template \n"
"concept WeakEqualityComparable = requires(T a, T b) {\n"
"   { a == b };\n"
"   { a != b };\n"
-   " };");
+   " };",
+   Style);
 
   verifyFormat("template \n"
"concept HasSizeT = requires { typename T::size_t; };");
@@ -24467,7 +24479,8 @@
"  requires Same;\n"
"  { delete new T; };\n"
"  { delete new T[n]; };\n"
-   "};");
+   "};",
+   Style);
 
   verifyFormat("template \n"
"concept Semiregular =\n"
@@ -24480,7 +24493,8 @@
"  { delete new T[n]; };\n"
"  { new T } -> std::same_as;\n"
"} && DefaultConstructible && CopyConstructible && "
-   "CopyAssignable;");
+   "CopyAssignable;",
+   Style);
 
   verifyFormat(
   "template \n"
@@ -24494,14 +24508,16 @@
   " { delete new T; };\n"
   " { delete new T[n]; };\n"
   "   } && CopyConstructible && "
-  "CopyAssignable;");
+  "CopyAssignable;",
+  Style);
 
   verifyFormat("template \n"
"concept Two = requires(T t) {\n"
"{ t.foo() } -> std::same_as;\n"
"  } && requires(T &&t) {\n"
" { t.foo() } -> std::same_as;\n"
-   "   };");
+   "   };",
+   Style);
 
   verifyFormat(
   "template \n"
@@ -24509,7 +24525,8 @@
   "  { *x } -> std::convertible_to;\n"
   "  { x + 1 } noexcept -> std::same_as;\n"
   "  

[PATCH] D135707: [clang-format] Correctly annotate star/amp in function pointer params

2022-10-17 Thread Emilia Dreamer via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG94215d2b2103: [clang-format] Correctly annotate star/amp in 
function pointer params (authored by rymiel).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D135707

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


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -131,6 +131,20 @@
   Tokens = annotate("delete[] *(ptr);");
   EXPECT_EQ(Tokens.size(), 9u) << Tokens;
   EXPECT_TOKEN(Tokens[3], tok::star, TT_UnaryOperator);
+
+  Tokens = annotate("void f() { void (*fnptr)(char* foo); }");
+  EXPECT_EQ(Tokens.size(), 18u) << Tokens;
+  EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_FunctionTypeLParen);
+  // FIXME: The star of a function pointer probably makes more sense as
+  // TT_PointerOrReference.
+  EXPECT_TOKEN(Tokens[7], tok::star, TT_UnaryOperator);
+  EXPECT_TOKEN(Tokens[12], tok::star, TT_PointerOrReference);
+
+  Tokens = annotate("void f() { void (*fnptr)(t* foo); }");
+  EXPECT_EQ(Tokens.size(), 18u) << Tokens;
+  EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_FunctionTypeLParen);
+  EXPECT_TOKEN(Tokens[7], tok::star, TT_UnaryOperator);
+  EXPECT_TOKEN(Tokens[12], tok::star, TT_PointerOrReference);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandsUsesOfPlusAndMinus) {
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -10459,6 +10459,7 @@
   verifyFormat("#define MACRO() [](A *a) { return 1; }");
   verifyFormat("Constructor() : member([](A *a, B *b) {}) {}");
   verifyIndependentOfContext("typedef void (*f)(int *a);");
+  verifyIndependentOfContext("typedef void (*f)(Type *a);");
   verifyIndependentOfContext("int i{a * b};");
   verifyIndependentOfContext("aaa && aaa->f();");
   verifyIndependentOfContext("int x = ~*p;");
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -302,7 +302,8 @@
   Contexts.back().ContextType = Context::ForEachMacro;
   Contexts.back().IsExpression = false;
 } else if (OpeningParen.Previous && OpeningParen.Previous->MatchingParen &&
-   OpeningParen.Previous->MatchingParen->is(TT_ObjCBlockLParen)) {
+   OpeningParen.Previous->MatchingParen->isOneOf(
+   TT_ObjCBlockLParen, TT_FunctionTypeLParen)) {
   Contexts.back().IsExpression = false;
 } else if (!Line.MustBeDeclaration && !Line.InPPDirective) {
   bool IsForOrCatch =


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -131,6 +131,20 @@
   Tokens = annotate("delete[] *(ptr);");
   EXPECT_EQ(Tokens.size(), 9u) << Tokens;
   EXPECT_TOKEN(Tokens[3], tok::star, TT_UnaryOperator);
+
+  Tokens = annotate("void f() { void (*fnptr)(char* foo); }");
+  EXPECT_EQ(Tokens.size(), 18u) << Tokens;
+  EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_FunctionTypeLParen);
+  // FIXME: The star of a function pointer probably makes more sense as
+  // TT_PointerOrReference.
+  EXPECT_TOKEN(Tokens[7], tok::star, TT_UnaryOperator);
+  EXPECT_TOKEN(Tokens[12], tok::star, TT_PointerOrReference);
+
+  Tokens = annotate("void f() { void (*fnptr)(t* foo); }");
+  EXPECT_EQ(Tokens.size(), 18u) << Tokens;
+  EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_FunctionTypeLParen);
+  EXPECT_TOKEN(Tokens[7], tok::star, TT_UnaryOperator);
+  EXPECT_TOKEN(Tokens[12], tok::star, TT_PointerOrReference);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandsUsesOfPlusAndMinus) {
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -10459,6 +10459,7 @@
   verifyFormat("#define MACRO() [](A *a) { return 1; }");
   verifyFormat("Constructor() : member([](A *a, B *b) {}) {}");
   verifyIndependentOfContext("typedef void (*f)(int *a);");
+  verifyIndependentOfContext("typedef void (*f)(Type *a);");
   verifyIndependentOfContext("int i{a * b};");
   verifyIndependentOfContext("aaa && aaa->f();");
   verifyIndependentOfContext("int x = ~*p;");
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -302,7 +302,8 @@

[PATCH] D140312: [clang-format] Disallow decltype in the middle of constraints

2022-12-19 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel created this revision.
rymiel added reviewers: HazardyKnusperkeks, owenpan, MyDeveloperDay.
Herald added a project: All.
rymiel requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

If a function with a `requires` clause as a constraint has a decltype
return type, such as `decltype(auto)`, the decltype was seen to be part
of the constraint clause, rather than as part of the function
declaration, causing it to be placed on the wrong line.

This patch disallows decltype to be a part of these clauses

Fixes https://github.com/llvm/llvm-project/issues/59578


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D140312

Files:
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp
  clang/unittests/Format/TokenAnnotatorTest.cpp


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -580,6 +580,14 @@
   EXPECT_TRUE(Tokens[9]->ClosesRequiresClause);
   EXPECT_TOKEN(Tokens[11], tok::identifier, TT_FunctionDeclarationName);
 
+  Tokens = annotate("template \n"
+"requires Bar\n"
+"decltype(auto) foo(T) { return false; }");
+  ASSERT_EQ(Tokens.size(), 24u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
+  EXPECT_TRUE(Tokens[9]->ClosesRequiresClause);
+  EXPECT_TOKEN(Tokens[14], tok::identifier, TT_FunctionDeclarationName);
+
   Tokens = annotate("template \n"
 "struct S {\n"
 "  void foo() const requires Bar;\n"
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -24199,6 +24199,10 @@
"  }\n"
"};");
 
+  verifyFormat("template \n"
+   "  requires(std::same_as)\n"
+   "decltype(auto) fun() {}");
+
   auto Style = getLLVMStyle();
 
   verifyFormat(
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -3560,7 +3560,6 @@
 case tok::minus:
 case tok::star:
 case tok::slash:
-case tok::kw_decltype:
   LambdaNextTimeAllowed = true;
   // Just eat them.
   nextToken();


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -580,6 +580,14 @@
   EXPECT_TRUE(Tokens[9]->ClosesRequiresClause);
   EXPECT_TOKEN(Tokens[11], tok::identifier, TT_FunctionDeclarationName);
 
+  Tokens = annotate("template \n"
+"requires Bar\n"
+"decltype(auto) foo(T) { return false; }");
+  ASSERT_EQ(Tokens.size(), 24u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
+  EXPECT_TRUE(Tokens[9]->ClosesRequiresClause);
+  EXPECT_TOKEN(Tokens[14], tok::identifier, TT_FunctionDeclarationName);
+
   Tokens = annotate("template \n"
 "struct S {\n"
 "  void foo() const requires Bar;\n"
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -24199,6 +24199,10 @@
"  }\n"
"};");
 
+  verifyFormat("template \n"
+   "  requires(std::same_as)\n"
+   "decltype(auto) fun() {}");
+
   auto Style = getLLVMStyle();
 
   verifyFormat(
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -3560,7 +3560,6 @@
 case tok::minus:
 case tok::star:
 case tok::slash:
-case tok::kw_decltype:
   LambdaNextTimeAllowed = true;
   // Just eat them.
   nextToken();
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D140330: [clang-format] Set requires expression params as not an expression

2022-12-19 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel created this revision.
rymiel added reviewers: HazardyKnusperkeks, owenpan, MyDeveloperDay.
Herald added a project: All.
rymiel requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Previously, the parens of a requires expression's "parameters" were not
explicitly set, meaning they ended up as whatever the outer scope was.
This is a problem in some cases though, since the process of determining
star/amp checks if the token is inside of an expression context

This patch always makes sure the context between those parens are always
set to not be an expression

Fixes https://github.com/llvm/llvm-project/issues/59600


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D140330

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


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -711,19 +711,50 @@
   ASSERT_EQ(Tokens.size(), 15u) << Tokens;
   EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
   EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[6], tok::star, TT_PointerOrReference);
   EXPECT_TOKEN(Tokens[10], tok::l_brace, TT_RequiresExpressionLBrace);
 
   Tokens = annotate("foo(requires(T const* volatile t) {});");
   ASSERT_EQ(Tokens.size(), 15u) << Tokens;
   EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
   EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[6], tok::star, TT_PointerOrReference);
   EXPECT_TOKEN(Tokens[10], tok::l_brace, TT_RequiresExpressionLBrace);
 
+  Tokens = annotate("foo(requires(T& t) {});");
+  ASSERT_EQ(Tokens.size(), 13u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
+  EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[5], tok::amp, TT_PointerOrReference);
+  EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_RequiresExpressionLBrace);
+
+  Tokens = annotate("foo(requires(T&& t) {});");
+  ASSERT_EQ(Tokens.size(), 13u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
+  EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[5], tok::ampamp, TT_PointerOrReference);
+  EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_RequiresExpressionLBrace);
+
+  Tokens = annotate("bool foo = requires(T& t) {};");
+  ASSERT_EQ(Tokens.size(), 13u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::kw_requires, TT_RequiresExpression);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[6], tok::amp, TT_PointerOrReference);
+  EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_RequiresExpressionLBrace);
+
+  Tokens = annotate("bool foo = requires(T&& t) {};");
+  ASSERT_EQ(Tokens.size(), 13u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::kw_requires, TT_RequiresExpression);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[6], tok::ampamp, TT_PointerOrReference);
+  EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_RequiresExpressionLBrace);
+
   Tokens =
   annotate("foo(requires(const typename Outer::Inner * const t) {});");
   ASSERT_EQ(Tokens.size(), 21u) << Tokens;
   EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
   EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[12], tok::star, TT_PointerOrReference);
   EXPECT_TOKEN(Tokens[16], tok::l_brace, TT_RequiresExpressionLBrace);
 
   Tokens = annotate("template \n"
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -321,7 +321,9 @@
 } else if (isLambdaParameterList(&OpeningParen)) {
   // This is a parameter list of a lambda expression.
   Contexts.back().IsExpression = false;
-} else if (Line.InPPDirective &&
+} else if (OpeningParen.is(TT_RequiresExpressionLParen)) {
+  Contexts.back().IsExpression = false;
+}  else if (Line.InPPDirective &&
(!OpeningParen.Previous ||
 !OpeningParen.Previous->is(tok::identifier))) {
   Contexts.back().IsExpression = true;


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -711,19 +711,50 @@
   ASSERT_EQ(Tokens.size(), 15u) << Tokens;
   EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
   EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[6], tok::star, TT_PointerOrReference);
   EXPECT_TOKEN(Tokens[10], tok::l_brace, TT_RequiresExpressionLBrac

[PATCH] D140330: [clang-format] Set requires expression params as not an expression

2022-12-19 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel updated this revision to Diff 484040.
rymiel added a comment.

Small spacing typo


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140330

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


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -711,19 +711,50 @@
   ASSERT_EQ(Tokens.size(), 15u) << Tokens;
   EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
   EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[6], tok::star, TT_PointerOrReference);
   EXPECT_TOKEN(Tokens[10], tok::l_brace, TT_RequiresExpressionLBrace);
 
   Tokens = annotate("foo(requires(T const* volatile t) {});");
   ASSERT_EQ(Tokens.size(), 15u) << Tokens;
   EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
   EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[6], tok::star, TT_PointerOrReference);
   EXPECT_TOKEN(Tokens[10], tok::l_brace, TT_RequiresExpressionLBrace);
 
+  Tokens = annotate("foo(requires(T& t) {});");
+  ASSERT_EQ(Tokens.size(), 13u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
+  EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[5], tok::amp, TT_PointerOrReference);
+  EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_RequiresExpressionLBrace);
+
+  Tokens = annotate("foo(requires(T&& t) {});");
+  ASSERT_EQ(Tokens.size(), 13u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
+  EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[5], tok::ampamp, TT_PointerOrReference);
+  EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_RequiresExpressionLBrace);
+
+  Tokens = annotate("bool foo = requires(T& t) {};");
+  ASSERT_EQ(Tokens.size(), 13u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::kw_requires, TT_RequiresExpression);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[6], tok::amp, TT_PointerOrReference);
+  EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_RequiresExpressionLBrace);
+
+  Tokens = annotate("bool foo = requires(T&& t) {};");
+  ASSERT_EQ(Tokens.size(), 13u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::kw_requires, TT_RequiresExpression);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[6], tok::ampamp, TT_PointerOrReference);
+  EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_RequiresExpressionLBrace);
+
   Tokens =
   annotate("foo(requires(const typename Outer::Inner * const t) {});");
   ASSERT_EQ(Tokens.size(), 21u) << Tokens;
   EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
   EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[12], tok::star, TT_PointerOrReference);
   EXPECT_TOKEN(Tokens[16], tok::l_brace, TT_RequiresExpressionLBrace);
 
   Tokens = annotate("template \n"
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -321,6 +321,8 @@
 } else if (isLambdaParameterList(&OpeningParen)) {
   // This is a parameter list of a lambda expression.
   Contexts.back().IsExpression = false;
+} else if (OpeningParen.is(TT_RequiresExpressionLParen)) {
+  Contexts.back().IsExpression = false;
 } else if (Line.InPPDirective &&
(!OpeningParen.Previous ||
 !OpeningParen.Previous->is(tok::identifier))) {


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -711,19 +711,50 @@
   ASSERT_EQ(Tokens.size(), 15u) << Tokens;
   EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
   EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[6], tok::star, TT_PointerOrReference);
   EXPECT_TOKEN(Tokens[10], tok::l_brace, TT_RequiresExpressionLBrace);
 
   Tokens = annotate("foo(requires(T const* volatile t) {});");
   ASSERT_EQ(Tokens.size(), 15u) << Tokens;
   EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
   EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[6], tok::star, TT_PointerOrReference);
   EXPECT_TOKEN(Tokens[10], tok::l_brace, TT_RequiresExpressionLBrace);
 
+  Tokens = annotate("foo(requires(T& t) {});");
+  ASSERT_EQ(Tokens.size(), 13u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
+  EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpr

[PATCH] D140339: [clang-format] Remove special logic for parsing concept definitions.

2022-12-19 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel created this revision.
rymiel added reviewers: HazardyKnusperkeks, owenpan, MyDeveloperDay.
Herald added a project: All.
rymiel requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Previously, clang-format relied on a special method to parse concept
definitions, `UnwrappedLineParser::parseConcept()`, which deferred to
`UnwrappedLineParser::parseConstraintExpression()`. This is problematic,
because the C++ grammar treats concepts and requires clauses
differently, causing issues such as 
https://github.com/llvm/llvm-project/issues/55898 and 
https://github.com/llvm/llvm-project/issues/58130.

This patch removes `parseConcept`, letting the formatter parse concept
definitions as more like what they actually are, fancy bool definitions.

NOTE that because of this, some long concept definitions change in their
formatting, as can be seen in the changed tests. This is because of a
change in split penalties, caused by a change in MightBeFunctionDecl on
the concept definition line, which was previously `true` but with this
patch is now `false`.

One might argue that `false` is a more "correct" value for concept
definitions, but I'd be fine with setting it to `true` again to maintain
compatibility with previous versions.

Fixes https://github.com/llvm/llvm-project/issues/58130

Depends on D140330 


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D140339

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

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -23588,10 +23588,10 @@
"concept DelayedCheck = !!false || requires(T t) { t.bar(); } "
"&& sizeof(T) <= 8;");
 
-  verifyFormat(
-  "template \n"
-  "concept DelayedCheck = static_cast(0) ||\n"
-  "   requires(T t) { t.bar(); } && sizeof(T) <= 8;");
+  verifyFormat("template \n"
+   "concept DelayedCheck =\n"
+   "static_cast(0) || requires(T t) { t.bar(); } && "
+   "sizeof(T) <= 8;");
 
   verifyFormat("template \n"
"concept DelayedCheck = bool(0) || requires(T t) { t.bar(); } "
@@ -23599,8 +23599,8 @@
 
   verifyFormat(
   "template \n"
-  "concept DelayedCheck = (bool)(0) ||\n"
-  "   requires(T t) { t.bar(); } && sizeof(T) <= 8;");
+  "concept DelayedCheck =\n"
+  "(bool)(0) || requires(T t) { t.bar(); } && sizeof(T) <= 8;");
 
   verifyFormat("template \n"
"concept DelayedCheck = (bool)0 || requires(T t) { t.bar(); } "
@@ -23636,6 +23636,9 @@
   verifyFormat("template \n"
"concept True = S::Value;");
 
+  verifyFormat("template \n"
+   "concept True = T.field;");
+
   verifyFormat(
   "template \n"
   "concept C = []() { return true; }() && requires(T t) { t.bar(); } &&\n"
@@ -23914,11 +23917,9 @@
   verifyFormat("template  concept True = true;", Style);
 
   verifyFormat(
-  "template  concept C = decltype([]() -> std::true_type {\n"
-  "return {};\n"
-  "  }())::value &&\n"
-  "  requires(T t) { t.bar(); } && "
-  "sizeof(T) <= 8;",
+  "template  concept C =\n"
+  "decltype([]() -> std::true_type { return {}; }())::value &&\n"
+  "requires(T t) { t.bar(); } && sizeof(T) <= 8;",
   Style);
 
   verifyFormat("template  concept Semiregular =\n"
@@ -23936,15 +23937,15 @@
 
   // The following tests are invalid C++, we just want to make sure we don't
   // assert.
-  verifyFormat("template \n"
-   "concept C = requires C2;");
-
-  verifyFormat("template \n"
-   "concept C = 5 + 4;");
-
   verifyFormat("template \n"
"concept C =\n"
-   "class X;");
+   "  requires C2;");
+
+  verifyFormat("template \n"
+   "concept C = 5 + 4;");
+
+  verifyFormat("template \n"
+   "concept C = class X;");
 
   verifyFormat("template \n"
"concept C = [] && true;");
Index: clang/lib/Format/UnwrappedLineParser.h
===
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -158,7 +158,6 @@
   void parseAccessSpecifier();
   bool parseEnum();
   bool parseStructLike();
-  void parseConcept();
   bool parseRequires();
   void parseRequiresClause(FormatToken *RequiresToken);
   void parseRequiresExpression(FormatToken *RequiresToken);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Form

[PATCH] D140312: [clang-format] Disallow decltype in the middle of constraints

2022-12-19 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added a comment.

What if I make this depend on D140339 ? Then 
this change would no longer impact concept definitions.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140312

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


[PATCH] D140339: [clang-format] Remove special logic for parsing concept definitions.

2022-12-19 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added inline comments.



Comment at: clang/lib/Format/TokenAnnotator.cpp:1683
 
-if (Tok->isOneOf(tok::kw_class, tok::kw_enum, tok::kw_concept,
- tok::kw_struct, tok::kw_using)) {
+if (Tok->isOneOf(tok::kw_class, tok::kw_enum, tok::kw_struct,
+ tok::kw_using)) {

HazardyKnusperkeks wrote:
> Does this change anything, besides the penalties and by that the wrapping?
> 
> While I can live with both, I think we should not format code differently, if 
> it's not by a bugfix.
The only changes I could see:
 - the change in `Context.IsExpression`, which causes the change in penalties;
 - the fact that a new `AnnotatedLine` isn't created for the body of a 
`concept` (i.e. the stuff after the equals sign), where as it previously was.
 - some invalid syntax is formatted differently

It's very likely I don't have a "sample size" large enough.

I am also okay with doing both; I made this issue to gauge what is the 
preferred direction by the reviewers.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140339

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


[PATCH] D140339: [clang-format] Remove special logic for parsing concept definitions.

2022-12-19 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel updated this revision to Diff 484066.
rymiel added a comment.

Use verifyNoCrash


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140339

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

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -23588,10 +23588,10 @@
"concept DelayedCheck = !!false || requires(T t) { t.bar(); } "
"&& sizeof(T) <= 8;");
 
-  verifyFormat(
-  "template \n"
-  "concept DelayedCheck = static_cast(0) ||\n"
-  "   requires(T t) { t.bar(); } && sizeof(T) <= 8;");
+  verifyFormat("template \n"
+   "concept DelayedCheck =\n"
+   "static_cast(0) || requires(T t) { t.bar(); } && "
+   "sizeof(T) <= 8;");
 
   verifyFormat("template \n"
"concept DelayedCheck = bool(0) || requires(T t) { t.bar(); } "
@@ -23599,8 +23599,8 @@
 
   verifyFormat(
   "template \n"
-  "concept DelayedCheck = (bool)(0) ||\n"
-  "   requires(T t) { t.bar(); } && sizeof(T) <= 8;");
+  "concept DelayedCheck =\n"
+  "(bool)(0) || requires(T t) { t.bar(); } && sizeof(T) <= 8;");
 
   verifyFormat("template \n"
"concept DelayedCheck = (bool)0 || requires(T t) { t.bar(); } "
@@ -23636,6 +23636,9 @@
   verifyFormat("template \n"
"concept True = S::Value;");
 
+  verifyFormat("template \n"
+   "concept True = T.field;");
+
   verifyFormat(
   "template \n"
   "concept C = []() { return true; }() && requires(T t) { t.bar(); } &&\n"
@@ -23914,11 +23917,9 @@
   verifyFormat("template  concept True = true;", Style);
 
   verifyFormat(
-  "template  concept C = decltype([]() -> std::true_type {\n"
-  "return {};\n"
-  "  }())::value &&\n"
-  "  requires(T t) { t.bar(); } && "
-  "sizeof(T) <= 8;",
+  "template  concept C =\n"
+  "decltype([]() -> std::true_type { return {}; }())::value &&\n"
+  "requires(T t) { t.bar(); } && sizeof(T) <= 8;",
   Style);
 
   verifyFormat("template  concept Semiregular =\n"
@@ -23936,21 +23937,20 @@
 
   // The following tests are invalid C++, we just want to make sure we don't
   // assert.
-  verifyFormat("template \n"
-   "concept C = requires C2;");
+  verifyNoCrash("template \n"
+"concept C = requires C2;");
 
-  verifyFormat("template \n"
-   "concept C = 5 + 4;");
+  verifyNoCrash("template \n"
+"concept C = 5 + 4;");
 
-  verifyFormat("template \n"
-   "concept C =\n"
-   "class X;");
+  verifyNoCrash("template \n"
+"concept C = class X;");
 
-  verifyFormat("template \n"
-   "concept C = [] && true;");
+  verifyNoCrash("template \n"
+"concept C = [] && true;");
 
-  verifyFormat("template \n"
-   "concept C = [] && requires(T t) { typename T::size_type; };");
+  verifyNoCrash("template \n"
+"concept C = [] && requires(T t) { typename T::size_type; };");
 }
 
 TEST_F(FormatTest, RequiresClausesPositions) {
Index: clang/lib/Format/UnwrappedLineParser.h
===
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -158,7 +158,6 @@
   void parseAccessSpecifier();
   bool parseEnum();
   bool parseStructLike();
-  void parseConcept();
   bool parseRequires();
   void parseRequiresClause(FormatToken *RequiresToken);
   void parseRequiresExpression(FormatToken *RequiresToken);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1813,9 +1813,6 @@
 break;
   }
   break;
-case tok::kw_concept:
-  parseConcept();
-  return;
 case tok::kw_requires: {
   if (Style.isCpp()) {
 bool ParsedClause = parseRequires();
@@ -3272,26 +3269,6 @@
   }
 }
 
-/// \brief Parses a concept definition.
-/// \pre The current token has to be the concept keyword.
-///
-/// Returns if either the concept has been completely parsed, or if it detects
-/// that the concept definition is incorrect.
-void UnwrappedLineParser::parseConcept() {
-  assert(FormatTok->is(tok::kw_concept) && "'concept' expected");
-  nextToken();
-  if (!FormatTok->is(tok::identifier))
-return;
-  nextToken();
-  if (!FormatTok->is(tok::equal))
-return;
-  nextToken();
-  parseConstraintExpressi

[PATCH] D140339: [clang-format] Remove special logic for parsing concept definitions.

2022-12-19 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel marked an inline comment as done.
rymiel added inline comments.



Comment at: clang/unittests/Format/FormatTest.cpp:23940
   // assert.
-  verifyFormat("template \n"
-   "concept C = requires C2;");
-
-  verifyFormat("template \n"
-   "concept C = 5 + 4;");
-
   verifyFormat("template \n"
"concept C =\n"

HazardyKnusperkeks wrote:
> As I have learned in other changes, we have `verifyNoCrash` (or similar), 
> this is what should be used. Didn't know about it back then.
Thank you, now I know as well


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140339

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


[PATCH] D140312: [clang-format] Disallow decltype in the middle of constraints

2022-12-22 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel marked an inline comment as done.
rymiel added inline comments.



Comment at: clang/lib/Format/UnwrappedLineParser.cpp:3494
 ///
 /// This is either the definition of a concept, or the body of a requires
 /// clause. It returns, when the parsing is complete, or the expression is

HazardyKnusperkeks wrote:
> HazardyKnusperkeks wrote:
> > The comment needs to be adapted.
> > 
> > But I think it could just be merged into the parsing of the requires 
> > clause, or not?
> Actually this needs to be done on D140339.
You are right, thank you. D140339 will make it so `parseConstraintExpression` 
will only ever be called from `parseRequiresClause`. Should I do that refactor 
in D140339 or leave it for a future patch?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140312

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


[PATCH] D140339: [clang-format] Remove special logic for parsing concept definitions.

2022-12-22 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel updated this revision to Diff 484985.
rymiel added a comment.

Adapt description of parseConstraintExpression


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140339

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

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -23588,10 +23588,10 @@
"concept DelayedCheck = !!false || requires(T t) { t.bar(); } "
"&& sizeof(T) <= 8;");
 
-  verifyFormat(
-  "template \n"
-  "concept DelayedCheck = static_cast(0) ||\n"
-  "   requires(T t) { t.bar(); } && sizeof(T) <= 8;");
+  verifyFormat("template \n"
+   "concept DelayedCheck =\n"
+   "static_cast(0) || requires(T t) { t.bar(); } && "
+   "sizeof(T) <= 8;");
 
   verifyFormat("template \n"
"concept DelayedCheck = bool(0) || requires(T t) { t.bar(); } "
@@ -23599,8 +23599,8 @@
 
   verifyFormat(
   "template \n"
-  "concept DelayedCheck = (bool)(0) ||\n"
-  "   requires(T t) { t.bar(); } && sizeof(T) <= 8;");
+  "concept DelayedCheck =\n"
+  "(bool)(0) || requires(T t) { t.bar(); } && sizeof(T) <= 8;");
 
   verifyFormat("template \n"
"concept DelayedCheck = (bool)0 || requires(T t) { t.bar(); } "
@@ -23636,6 +23636,9 @@
   verifyFormat("template \n"
"concept True = S::Value;");
 
+  verifyFormat("template \n"
+   "concept True = T.field;");
+
   verifyFormat(
   "template \n"
   "concept C = []() { return true; }() && requires(T t) { t.bar(); } &&\n"
@@ -23914,11 +23917,9 @@
   verifyFormat("template  concept True = true;", Style);
 
   verifyFormat(
-  "template  concept C = decltype([]() -> std::true_type {\n"
-  "return {};\n"
-  "  }())::value &&\n"
-  "  requires(T t) { t.bar(); } && "
-  "sizeof(T) <= 8;",
+  "template  concept C =\n"
+  "decltype([]() -> std::true_type { return {}; }())::value &&\n"
+  "requires(T t) { t.bar(); } && sizeof(T) <= 8;",
   Style);
 
   verifyFormat("template  concept Semiregular =\n"
@@ -23936,21 +23937,20 @@
 
   // The following tests are invalid C++, we just want to make sure we don't
   // assert.
-  verifyFormat("template \n"
-   "concept C = requires C2;");
+  verifyNoCrash("template \n"
+"concept C = requires C2;");
 
-  verifyFormat("template \n"
-   "concept C = 5 + 4;");
+  verifyNoCrash("template \n"
+"concept C = 5 + 4;");
 
-  verifyFormat("template \n"
-   "concept C =\n"
-   "class X;");
+  verifyNoCrash("template \n"
+"concept C = class X;");
 
-  verifyFormat("template \n"
-   "concept C = [] && true;");
+  verifyNoCrash("template \n"
+"concept C = [] && true;");
 
-  verifyFormat("template \n"
-   "concept C = [] && requires(T t) { typename T::size_type; };");
+  verifyNoCrash("template \n"
+"concept C = [] && requires(T t) { typename T::size_type; };");
 }
 
 TEST_F(FormatTest, RequiresClausesPositions) {
Index: clang/lib/Format/UnwrappedLineParser.h
===
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -158,7 +158,6 @@
   void parseAccessSpecifier();
   bool parseEnum();
   bool parseStructLike();
-  void parseConcept();
   bool parseRequires();
   void parseRequiresClause(FormatToken *RequiresToken);
   void parseRequiresExpression(FormatToken *RequiresToken);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1813,9 +1813,6 @@
 break;
   }
   break;
-case tok::kw_concept:
-  parseConcept();
-  return;
 case tok::kw_requires: {
   if (Style.isCpp()) {
 bool ParsedClause = parseRequires();
@@ -3272,26 +3269,6 @@
   }
 }
 
-/// \brief Parses a concept definition.
-/// \pre The current token has to be the concept keyword.
-///
-/// Returns if either the concept has been completely parsed, or if it detects
-/// that the concept definition is incorrect.
-void UnwrappedLineParser::parseConcept() {
-  assert(FormatTok->is(tok::kw_concept) && "'concept' expected");
-  nextToken();
-  if (!FormatTok->is(tok::identifier))
-return;
-  nextToken();
-  if (!FormatTok->is(tok::equal))
-return;
-  nextToken(

[PATCH] D138441: [clang-format][docs] Fix invalid CSS syntax in versionbadge

2022-12-22 Thread Emilia Dreamer via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGba4caec64fec: [clang-format][docs] Fix invalid CSS syntax in 
versionbadge (authored by rymiel).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D138441

Files:
  clang/docs/ClangFormatStyleOptions.rst


Index: clang/docs/ClangFormatStyleOptions.rst
===
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -1,7 +1,7 @@
 .. raw:: html
 
   
-.versionbadge { background-color: #1c913d; height: 20px; display: 
inline-block; width: 120px; text-align: center; border-radius: 5px; color: 
#FF; font-family="Verdana,Geneva,DejaVu Sans,sans-serif" }
+.versionbadge { background-color: #1c913d; height: 20px; display: 
inline-block; width: 120px; text-align: center; border-radius: 5px; color: 
#FF; font-family: "Verdana,Geneva,DejaVu Sans,sans-serif"; }
   
 
 .. role:: versionbadge


Index: clang/docs/ClangFormatStyleOptions.rst
===
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -1,7 +1,7 @@
 .. raw:: html
 
   
-.versionbadge { background-color: #1c913d; height: 20px; display: inline-block; width: 120px; text-align: center; border-radius: 5px; color: #FF; font-family="Verdana,Geneva,DejaVu Sans,sans-serif" }
+.versionbadge { background-color: #1c913d; height: 20px; display: inline-block; width: 120px; text-align: center; border-radius: 5px; color: #FF; font-family: "Verdana,Geneva,DejaVu Sans,sans-serif"; }
   
 
 .. role:: versionbadge
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D140330: [clang-format] Set requires expression params as not an expression

2022-12-22 Thread Emilia Dreamer via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG0ebed862d821: [clang-format] Set requires expression params 
as not an expression (authored by rymiel).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140330

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


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -711,19 +711,50 @@
   ASSERT_EQ(Tokens.size(), 15u) << Tokens;
   EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
   EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[6], tok::star, TT_PointerOrReference);
   EXPECT_TOKEN(Tokens[10], tok::l_brace, TT_RequiresExpressionLBrace);
 
   Tokens = annotate("foo(requires(T const* volatile t) {});");
   ASSERT_EQ(Tokens.size(), 15u) << Tokens;
   EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
   EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[6], tok::star, TT_PointerOrReference);
   EXPECT_TOKEN(Tokens[10], tok::l_brace, TT_RequiresExpressionLBrace);
 
+  Tokens = annotate("foo(requires(T& t) {});");
+  ASSERT_EQ(Tokens.size(), 13u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
+  EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[5], tok::amp, TT_PointerOrReference);
+  EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_RequiresExpressionLBrace);
+
+  Tokens = annotate("foo(requires(T&& t) {});");
+  ASSERT_EQ(Tokens.size(), 13u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
+  EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[5], tok::ampamp, TT_PointerOrReference);
+  EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_RequiresExpressionLBrace);
+
+  Tokens = annotate("bool foo = requires(T& t) {};");
+  ASSERT_EQ(Tokens.size(), 13u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::kw_requires, TT_RequiresExpression);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[6], tok::amp, TT_PointerOrReference);
+  EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_RequiresExpressionLBrace);
+
+  Tokens = annotate("bool foo = requires(T&& t) {};");
+  ASSERT_EQ(Tokens.size(), 13u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::kw_requires, TT_RequiresExpression);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[6], tok::ampamp, TT_PointerOrReference);
+  EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_RequiresExpressionLBrace);
+
   Tokens =
   annotate("foo(requires(const typename Outer::Inner * const t) {});");
   ASSERT_EQ(Tokens.size(), 21u) << Tokens;
   EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
   EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[12], tok::star, TT_PointerOrReference);
   EXPECT_TOKEN(Tokens[16], tok::l_brace, TT_RequiresExpressionLBrace);
 
   Tokens = annotate("template \n"
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -321,6 +321,8 @@
 } else if (isLambdaParameterList(&OpeningParen)) {
   // This is a parameter list of a lambda expression.
   Contexts.back().IsExpression = false;
+} else if (OpeningParen.is(TT_RequiresExpressionLParen)) {
+  Contexts.back().IsExpression = false;
 } else if (Line.InPPDirective &&
(!OpeningParen.Previous ||
 !OpeningParen.Previous->is(tok::identifier))) {


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -711,19 +711,50 @@
   ASSERT_EQ(Tokens.size(), 15u) << Tokens;
   EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
   EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[6], tok::star, TT_PointerOrReference);
   EXPECT_TOKEN(Tokens[10], tok::l_brace, TT_RequiresExpressionLBrace);
 
   Tokens = annotate("foo(requires(T const* volatile t) {});");
   ASSERT_EQ(Tokens.size(), 15u) << Tokens;
   EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression);
   EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_RequiresExpressionLParen);
+  EXPECT_TOKEN(Tokens[6], tok::star, TT_PointerOrReference);
   EXPECT_TOKEN(Tokens[10], tok::l_brace, TT_RequiresExpressionLBrace);
 
+  Tokens = annotate("foo(requires(T& t) {});");
+  ASS

[PATCH] D139211: [WIP][clang-format] Properly handle the C11 _Generic keyword.

2022-12-22 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel planned changes to this revision.
rymiel added a comment.

Going to try to make the indentation of the cases following the controlling 
expression not continuations, since that results in weird results such as:

  #define LIMIT_MAX(T) \
_Generic(  \
((T)0),\
unsigned int: UINT_MAX,\
unsigned long: ULONG_MAX,  \
unsigned long long: ULLONG_MAX)

My desired output is instead:

  #define LIMIT_MAX(T) \
_Generic(((T)0),   \
unsigned int: UINT_MAX,\
unsigned long: ULONG_MAX,  \
unsigned long long: ULLONG_MAX)

or something similar, but I'm struggling with unfamiliar parts of the codebase 
and taking my time getting familiar with them.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D139211

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


[PATCH] D139211: [clang-format] Properly handle the C11 _Generic keyword.

2022-12-23 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel updated this revision to Diff 485062.
rymiel marked an inline comment as done.
rymiel retitled this revision from "[WIP][clang-format] Properly handle the C11 
_Generic keyword." to "[clang-format] Properly handle the C11 _Generic 
keyword.".
rymiel added a comment.
This revision is now accepted and ready to land.

Change indenting behaviour

I'm still not sure what I'm doing regarding ContinuationIndenter, since I don't 
fully understand its mechanisms, so I just followed my usual method of "stick a 
very specific check in a random spot that makes the correct fields have the 
correct value", which feels like a hack here. There is probably a much better 
way to do this, perhaps something with fake parens or something, to actually 
treat the "controlling expression" and the actual selectors differently, but 
right now I've just put in a specific check to dedent the selectors to be 
relative to the _Generic keyword, and not aligned to the opening paren.

It is also no surprise that I don't know how to write tests; I included organic 
examples of cases that are semi-realistic use cases of _Generic, but there are 
definitely edge cases I don't have listed.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D139211

Files:
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/unittests/Format/FormatTest.cpp
  clang/unittests/Format/TokenAnnotatorTest.cpp

Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -1136,6 +1136,14 @@
   EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsC11GenericSelection) {
+  auto Tokens = annotate("_Generic(x, int: 1, default: 0)");
+  ASSERT_EQ(Tokens.size(), 13u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::kw__Generic, TT_Unknown);
+  EXPECT_TOKEN(Tokens[5], tok::colon, TT_GenericSelectionColon);
+  EXPECT_TOKEN(Tokens[9], tok::colon, TT_GenericSelectionColon);
+}
+
 TEST_F(TokenAnnotatorTest, UnderstandsVerilogOperators) {
   auto Annotate = [this](llvm::StringRef Code) {
 return annotate(Code, getLLVMStyle(FormatStyle::LK_Verilog));
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -22996,6 +22996,41 @@
   verifyFormat("x = (_Atomic( uint64_t ))&a;", Style);
 }
 
+TEST_F(FormatTest, C11Generic) {
+  verifyFormat("_Generic(x, int: 1, default: 0)");
+  verifyFormat("#define cbrt(X) _Generic((X), float: cbrtf, default: cbrt)(X)");
+  verifyFormat("_Generic(x, const char *: 1, char *const: 16, int: 8);");
+  verifyFormat("_Generic(x, int: f1, const int: f2)();");
+  verifyFormat("_Generic(x, struct A: 1, void (*)(void): 2);");
+
+  verifyFormat("_Generic(x,\n"
+   "float: f,\n"
+   "default: d,\n"
+   "long double: ld,\n"
+   "float _Complex: fc,\n"
+   "double _Complex: dc,\n"
+   "long double _Complex: ldc)");
+
+  FormatStyle Style = getLLVMStyle();
+  Style.ColumnLimit = 40;
+  verifyFormat("#define LIMIT_MAX(T)   \\\n"
+   "  _Generic(((T)0), \\\n"
+   "  unsigned int: UINT_MAX,  \\\n"
+   "  unsigned long: ULONG_MAX,\\\n"
+   "  unsigned long long: ULLONG_MAX)",
+   Style);
+  verifyFormat("_Generic(x,\n"
+   "struct A: 1,\n"
+   "void (*)(void): 2);",
+   Style);
+
+  Style.ContinuationIndentWidth = 2;
+  verifyFormat("_Generic(x,\n"
+   "  struct A: 1,\n"
+   "  void (*)(void): 2);",
+   Style);
+}
+
 TEST_F(FormatTest, AmbersandInLamda) {
   // Test case reported in https://bugs.llvm.org/show_bug.cgi?id=41899
   FormatStyle AlignStyle = getLLVMStyle();
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -323,6 +323,10 @@
   Contexts.back().IsExpression = false;
 } else if (OpeningParen.is(TT_RequiresExpressionLParen)) {
   Contexts.back().IsExpression = false;
+} else if (OpeningParen.Previous &&
+   OpeningParen.Previous->is(tok::kw__Generic)) {
+  Contexts.back().ContextType = Context::C11GenericSelection;
+  Contexts.back().IsExpression = true;
 } else if (Line.InPPDirective &&
(!OpeningParen.Previous ||
 !OpeningParen.Previous->is(tok::identifier))) {
@@ -1028,6 +1032,8 @@
 }
   } else if (Contexts.back().ColonIsForRa

[PATCH] D140767: [clang-format] Require space before noexcept qualifier

2022-12-29 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel created this revision.
rymiel added reviewers: HazardyKnusperkeks, owenpan, MyDeveloperDay.
Herald added a project: All.
rymiel requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This brings the noexcept qualifier more visually in line with the other
keyword qualifiers, such as "final" and "override".

Originally reported as https://github.com/llvm/llvm-project/issues/44542,
it was closed as "working by design" and reinforcing tests were added
as part of a218706cba90248be0c60bd6a8f10dbcf0270955 
. The 
exact spacing
depended on the `PointerAlignment` option, where the default value of
`Right` would leave no space.

This patch seeks to change this behaviour, regardless of the configured
`PointerAlignment` option (matching the previous behaviour of the `Left`
option).

Closes https://github.com/llvm/llvm-project/issues/59729


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D140767

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
@@ -10566,10 +10566,10 @@
 
 TEST_F(FormatTest, UnderstandsFunctionRefQualification) {
   verifyFormat("void A::b() && {}");
-  verifyFormat("void A::b() &&noexcept {}");
+  verifyFormat("void A::b() && noexcept {}");
   verifyFormat("Deleted &operator=(const Deleted &) & = default;");
   verifyFormat("Deleted &operator=(const Deleted &) && = delete;");
-  verifyFormat("Deleted &operator=(const Deleted &) &noexcept = default;");
+  verifyFormat("Deleted &operator=(const Deleted &) & noexcept = default;");
   verifyFormat("SomeType MemberFunction(const Deleted &) & = delete;");
   verifyFormat("SomeType MemberFunction(const Deleted &) && = delete;");
   verifyFormat("Deleted &operator=(const Deleted &) &;");
@@ -10579,16 +10579,16 @@
   verifyFormat("SomeType MemberFunction(const Deleted &) && {}");
   verifyFormat("SomeType MemberFunction(const Deleted &) && final {}");
   verifyFormat("SomeType MemberFunction(const Deleted &) && override {}");
-  verifyFormat("SomeType MemberFunction(const Deleted &) &&noexcept {}");
+  verifyFormat("SomeType MemberFunction(const Deleted &) && noexcept {}");
   verifyFormat("void Fn(T const &) const &;");
   verifyFormat("void Fn(T const volatile &&) const volatile &&;");
-  verifyFormat("void Fn(T const volatile &&) const volatile &&noexcept;");
+  verifyFormat("void Fn(T const volatile &&) const volatile && noexcept;");
   verifyFormat("template \n"
"void F(T) && = delete;",
getGoogleStyle());
   verifyFormat("template  void operator=(T) &;");
   verifyFormat("template  void operator=(T) const &;");
-  verifyFormat("template  void operator=(T) &noexcept;");
+  verifyFormat("template  void operator=(T) & noexcept;");
   verifyFormat("template  void operator=(T) & = default;");
   verifyFormat("template  void operator=(T) &&;");
   verifyFormat("template  void operator=(T) && = delete;");
@@ -10678,31 +10678,31 @@
 
   verifyFormat("struct f {\n"
"  template \n"
-   "  int &foo(const std::string &str) &noexcept {}\n"
+   "  int &foo(const std::string &str) & noexcept {}\n"
"};",
BreakTemplate);
 
   verifyFormat("struct f {\n"
"  template \n"
-   "  int &foo(const std::string &str) &&noexcept {}\n"
+   "  int &foo(const std::string &str) && noexcept {}\n"
"};",
BreakTemplate);
 
   verifyFormat("struct f {\n"
"  template \n"
-   "  int &foo(const std::string &str) const &noexcept {}\n"
+   "  int &foo(const std::string &str) const & noexcept {}\n"
"};",
BreakTemplate);
 
   verifyFormat("struct f {\n"
"  template \n"
-   "  int &foo(const std::string &str) const &noexcept {}\n"
+   "  int &foo(const std::string &str) const & noexcept {}\n"
"};",
BreakTemplate);
 
   verifyFormat("struct f {\n"
"  template \n"
-   "  auto foo(const std::string &str) &&noexcept -> int & {}\n"
+   "  auto foo(const std::string &str) && noexcept -> int & {}\n"
"};",
BreakTemplate);
 
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -3495,7 +3495,8 @@
 if (Right.is(TT_BlockComment))
   return true;
 // foo() -> const Bar * override/final
-if (Right.isOneOf(Keywords.kw_override, Keywords.kw_final) &&
+if (Right.isOneOf(Keywords.kw_override, Keyword

[PATCH] D140339: [clang-format] Remove special logic for parsing concept definitions.

2023-01-02 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added inline comments.



Comment at: clang/unittests/Format/FormatTest.cpp:23946-23947
-  verifyFormat("template \n"
-   "concept C =\n"
-   "class X;");
 

owenpan wrote:
> Just want to make sure that the line break didn't matter.
Sorry, that line break was removed when verifyFormat was still used


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140339

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


[PATCH] D140767: [clang-format] Require space before noexcept qualifier

2023-01-05 Thread Emilia Dreamer via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG54fab18cedac: [clang-format] Require space before noexcept 
qualifier (authored by rymiel).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140767

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
@@ -10566,10 +10566,10 @@
 
 TEST_F(FormatTest, UnderstandsFunctionRefQualification) {
   verifyFormat("void A::b() && {}");
-  verifyFormat("void A::b() &&noexcept {}");
+  verifyFormat("void A::b() && noexcept {}");
   verifyFormat("Deleted &operator=(const Deleted &) & = default;");
   verifyFormat("Deleted &operator=(const Deleted &) && = delete;");
-  verifyFormat("Deleted &operator=(const Deleted &) &noexcept = default;");
+  verifyFormat("Deleted &operator=(const Deleted &) & noexcept = default;");
   verifyFormat("SomeType MemberFunction(const Deleted &) & = delete;");
   verifyFormat("SomeType MemberFunction(const Deleted &) && = delete;");
   verifyFormat("Deleted &operator=(const Deleted &) &;");
@@ -10579,16 +10579,16 @@
   verifyFormat("SomeType MemberFunction(const Deleted &) && {}");
   verifyFormat("SomeType MemberFunction(const Deleted &) && final {}");
   verifyFormat("SomeType MemberFunction(const Deleted &) && override {}");
-  verifyFormat("SomeType MemberFunction(const Deleted &) &&noexcept {}");
+  verifyFormat("SomeType MemberFunction(const Deleted &) && noexcept {}");
   verifyFormat("void Fn(T const &) const &;");
   verifyFormat("void Fn(T const volatile &&) const volatile &&;");
-  verifyFormat("void Fn(T const volatile &&) const volatile &&noexcept;");
+  verifyFormat("void Fn(T const volatile &&) const volatile && noexcept;");
   verifyFormat("template \n"
"void F(T) && = delete;",
getGoogleStyle());
   verifyFormat("template  void operator=(T) &;");
   verifyFormat("template  void operator=(T) const &;");
-  verifyFormat("template  void operator=(T) &noexcept;");
+  verifyFormat("template  void operator=(T) & noexcept;");
   verifyFormat("template  void operator=(T) & = default;");
   verifyFormat("template  void operator=(T) &&;");
   verifyFormat("template  void operator=(T) && = delete;");
@@ -10678,31 +10678,31 @@
 
   verifyFormat("struct f {\n"
"  template \n"
-   "  int &foo(const std::string &str) &noexcept {}\n"
+   "  int &foo(const std::string &str) & noexcept {}\n"
"};",
BreakTemplate);
 
   verifyFormat("struct f {\n"
"  template \n"
-   "  int &foo(const std::string &str) &&noexcept {}\n"
+   "  int &foo(const std::string &str) && noexcept {}\n"
"};",
BreakTemplate);
 
   verifyFormat("struct f {\n"
"  template \n"
-   "  int &foo(const std::string &str) const &noexcept {}\n"
+   "  int &foo(const std::string &str) const & noexcept {}\n"
"};",
BreakTemplate);
 
   verifyFormat("struct f {\n"
"  template \n"
-   "  int &foo(const std::string &str) const &noexcept {}\n"
+   "  int &foo(const std::string &str) const & noexcept {}\n"
"};",
BreakTemplate);
 
   verifyFormat("struct f {\n"
"  template \n"
-   "  auto foo(const std::string &str) &&noexcept -> int & {}\n"
+   "  auto foo(const std::string &str) && noexcept -> int & {}\n"
"};",
BreakTemplate);
 
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -3530,7 +3530,8 @@
 if (Right.is(TT_BlockComment))
   return true;
 // foo() -> const Bar * override/final
-if (Right.isOneOf(Keywords.kw_override, Keywords.kw_final) &&
+if (Right.isOneOf(Keywords.kw_override, Keywords.kw_final,
+  tok::kw_noexcept) &&
 !Right.is(TT_StartOfName)) {
   return true;
 }


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -10566,10 +10566,10 @@
 
 TEST_F(FormatTest, UnderstandsFunctionRefQualification) {
   verifyFormat("void A::b() && {}");
-  verifyFormat("void A::b() &&noexcept {}");
+  verifyFormat("void A::b() && noexcept {}");
   verifyFormat("Deleted &operator=(const Deleted &) & = default;");
   verifyFormat("Deleted &operator=(const Deleted &) && = delete;");
-  verifyFormat("Deleted &operator=(cons

[PATCH] D140339: [clang-format] Remove special logic for parsing concept definitions.

2023-01-05 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel marked an inline comment as done.
rymiel added inline comments.



Comment at: clang/unittests/Format/FormatTest.cpp:23593-23594
-  "template \n"
-  "concept DelayedCheck = static_cast(0) ||\n"
-  "   requires(T t) { t.bar(); } && sizeof(T) <= 8;");
 

owenpan wrote:
> What would happen with parentheses added?
> ```
> concept DelayedCheck = (static_cast(0) || requires(T t) { t.bar(); }) 
> && sizeof(T) <= 8;
> concept DelayedCheck = static_cast(0) || (requires(T t) { t.bar(); } && 
> sizeof(T) <= 8);
> ```
No difference:
```
concept DelayedCheck =
(static_cast(0) || requires(T t) { t.bar(); }) && sizeof(T) <= 8;
concept DelayedCheck =
static_cast(0) || (requires(T t) { t.bar(); } && sizeof(T) <= 8);
concept DelayedCheck =
static_cast(0) || requires(T t) { t.bar(); } && sizeof(T) <= 8;
```


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140339

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


[PATCH] D140339: [clang-format] Remove special logic for parsing concept definitions.

2023-01-05 Thread Emilia Dreamer via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb1eeec6177fa: [clang-format] Remove special logic for 
parsing concept definitions. (authored by rymiel).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140339

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

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -23588,10 +23588,10 @@
"concept DelayedCheck = !!false || requires(T t) { t.bar(); } "
"&& sizeof(T) <= 8;");
 
-  verifyFormat(
-  "template \n"
-  "concept DelayedCheck = static_cast(0) ||\n"
-  "   requires(T t) { t.bar(); } && sizeof(T) <= 8;");
+  verifyFormat("template \n"
+   "concept DelayedCheck =\n"
+   "static_cast(0) || requires(T t) { t.bar(); } && "
+   "sizeof(T) <= 8;");
 
   verifyFormat("template \n"
"concept DelayedCheck = bool(0) || requires(T t) { t.bar(); } "
@@ -23599,8 +23599,8 @@
 
   verifyFormat(
   "template \n"
-  "concept DelayedCheck = (bool)(0) ||\n"
-  "   requires(T t) { t.bar(); } && sizeof(T) <= 8;");
+  "concept DelayedCheck =\n"
+  "(bool)(0) || requires(T t) { t.bar(); } && sizeof(T) <= 8;");
 
   verifyFormat("template \n"
"concept DelayedCheck = (bool)0 || requires(T t) { t.bar(); } "
@@ -23636,6 +23636,9 @@
   verifyFormat("template \n"
"concept True = S::Value;");
 
+  verifyFormat("template \n"
+   "concept True = T.field;");
+
   verifyFormat(
   "template \n"
   "concept C = []() { return true; }() && requires(T t) { t.bar(); } &&\n"
@@ -23914,11 +23917,9 @@
   verifyFormat("template  concept True = true;", Style);
 
   verifyFormat(
-  "template  concept C = decltype([]() -> std::true_type {\n"
-  "return {};\n"
-  "  }())::value &&\n"
-  "  requires(T t) { t.bar(); } && "
-  "sizeof(T) <= 8;",
+  "template  concept C =\n"
+  "decltype([]() -> std::true_type { return {}; }())::value &&\n"
+  "requires(T t) { t.bar(); } && sizeof(T) <= 8;",
   Style);
 
   verifyFormat("template  concept Semiregular =\n"
@@ -23936,21 +23937,20 @@
 
   // The following tests are invalid C++, we just want to make sure we don't
   // assert.
-  verifyFormat("template \n"
-   "concept C = requires C2;");
+  verifyNoCrash("template \n"
+"concept C = requires C2;");
 
-  verifyFormat("template \n"
-   "concept C = 5 + 4;");
+  verifyNoCrash("template \n"
+"concept C = 5 + 4;");
 
-  verifyFormat("template \n"
-   "concept C =\n"
-   "class X;");
+  verifyNoCrash("template \n"
+"concept C = class X;");
 
-  verifyFormat("template \n"
-   "concept C = [] && true;");
+  verifyNoCrash("template \n"
+"concept C = [] && true;");
 
-  verifyFormat("template \n"
-   "concept C = [] && requires(T t) { typename T::size_type; };");
+  verifyNoCrash("template \n"
+"concept C = [] && requires(T t) { typename T::size_type; };");
 }
 
 TEST_F(FormatTest, RequiresClausesPositions) {
Index: clang/lib/Format/UnwrappedLineParser.h
===
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -158,7 +158,6 @@
   void parseAccessSpecifier();
   bool parseEnum();
   bool parseStructLike();
-  void parseConcept();
   bool parseRequires();
   void parseRequiresClause(FormatToken *RequiresToken);
   void parseRequiresExpression(FormatToken *RequiresToken);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1818,9 +1818,6 @@
 break;
   }
   break;
-case tok::kw_concept:
-  parseConcept();
-  return;
 case tok::kw_requires: {
   if (Style.isCpp()) {
 bool ParsedClause = parseRequires();
@@ -3277,26 +3274,6 @@
   }
 }
 
-/// \brief Parses a concept definition.
-/// \pre The current token has to be the concept keyword.
-///
-/// Returns if either the concept has been completely parsed, or if it detects
-/// that the concept definition is incorrect.
-void UnwrappedLineParser::parseConcept() {
-  assert(FormatTok->is(tok::kw_concept) && "'concept' expected");
-  nextTo

[PATCH] D140312: [clang-format] Disallow decltype in the middle of constraints

2023-01-05 Thread Emilia Dreamer via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGd9899501576e: [clang-format] Disallow decltype in the middle 
of constraints (authored by rymiel).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140312

Files:
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTest.cpp
  clang/unittests/Format/TokenAnnotatorTest.cpp


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -580,6 +580,14 @@
   EXPECT_TRUE(Tokens[9]->ClosesRequiresClause);
   EXPECT_TOKEN(Tokens[11], tok::identifier, TT_FunctionDeclarationName);
 
+  Tokens = annotate("template \n"
+"requires Bar\n"
+"decltype(auto) foo(T) { return false; }");
+  ASSERT_EQ(Tokens.size(), 24u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
+  EXPECT_TRUE(Tokens[9]->ClosesRequiresClause);
+  EXPECT_TOKEN(Tokens[14], tok::identifier, TT_FunctionDeclarationName);
+
   Tokens = annotate("template \n"
 "struct S {\n"
 "  void foo() const requires Bar;\n"
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -24199,6 +24199,10 @@
"  }\n"
"};");
 
+  verifyFormat("template \n"
+   "  requires(std::same_as)\n"
+   "decltype(auto) fun() {}");
+
   auto Style = getLLVMStyle();
 
   verifyFormat(
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -3543,7 +3543,6 @@
 case tok::minus:
 case tok::star:
 case tok::slash:
-case tok::kw_decltype:
   LambdaNextTimeAllowed = true;
   // Just eat them.
   nextToken();


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -580,6 +580,14 @@
   EXPECT_TRUE(Tokens[9]->ClosesRequiresClause);
   EXPECT_TOKEN(Tokens[11], tok::identifier, TT_FunctionDeclarationName);
 
+  Tokens = annotate("template \n"
+"requires Bar\n"
+"decltype(auto) foo(T) { return false; }");
+  ASSERT_EQ(Tokens.size(), 24u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::kw_requires, TT_RequiresClause);
+  EXPECT_TRUE(Tokens[9]->ClosesRequiresClause);
+  EXPECT_TOKEN(Tokens[14], tok::identifier, TT_FunctionDeclarationName);
+
   Tokens = annotate("template \n"
 "struct S {\n"
 "  void foo() const requires Bar;\n"
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -24199,6 +24199,10 @@
"  }\n"
"};");
 
+  verifyFormat("template \n"
+   "  requires(std::same_as)\n"
+   "decltype(auto) fun() {}");
+
   auto Style = getLLVMStyle();
 
   verifyFormat(
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -3543,7 +3543,6 @@
 case tok::minus:
 case tok::star:
 case tok::slash:
-case tok::kw_decltype:
   LambdaNextTimeAllowed = true;
   // Just eat them.
   nextToken();
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D141098: [clang-format][NFC] Set DeriveLineEnding to false in config files

2023-01-05 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added a comment.

The LLVM Coding Standard apparently doesn't mention line endings..? A quick 
grep does show a bunch of \r\n results, primarily in tests. I'd be in favor of 
forcing \n, but I think this is a wider matter..?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141098

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


[PATCH] D141098: [clang-format][NFC] Set DeriveLineEnding to false in config files

2023-01-06 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added a comment.

> I think we should combine `DeriveLineEnding` and `UseCRLF`

Do you mean a single `LineEnding` options which is an enum with `LF`, `CRLF` 
and `Derive`, or similar?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141098

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


[PATCH] D141287: [clang-format] Inherit RightAlign option across scopes

2023-01-09 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel created this revision.
rymiel added reviewers: HazardyKnusperkeks, owenpan, MyDeveloperDay.
rymiel added a project: clang-format.
Herald added a project: All.
rymiel requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

D119599  added the ability to align compound 
assignments, right aligning
them in order to line up at the equals sign.
However, that patch didn't account for AlignTokens being called
recursively across scopes, which reset the right justification to be
false in any scope besides the top scope. This meant the compound
assignments were aligned, just not at the right place.
(No tests also ever introduced any scopes)

This patch makes sure to inherit the right justification value, just as
every other parameter is passed on.

Fixes https://github.com/llvm/llvm-project/issues/58029


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D141287

Files:
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/unittests/Format/FormatTest.cpp
  clang/unittests/Format/TokenAnnotatorTest.cpp

Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -1136,6 +1136,14 @@
   EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsC11GenericSelection) {
+  auto Tokens = annotate("_Generic(x, int: 1, default: 0)");
+  ASSERT_EQ(Tokens.size(), 13u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::kw__Generic, TT_Unknown);
+  EXPECT_TOKEN(Tokens[5], tok::colon, TT_GenericSelectionColon);
+  EXPECT_TOKEN(Tokens[9], tok::colon, TT_GenericSelectionColon);
+}
+
 TEST_F(TokenAnnotatorTest, UnderstandsVerilogOperators) {
   auto Annotate = [this](llvm::StringRef Code) {
 return annotate(Code, getLLVMStyle(FormatStyle::LK_Verilog));
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -22996,6 +22996,41 @@
   verifyFormat("x = (_Atomic( uint64_t ))&a;", Style);
 }
 
+TEST_F(FormatTest, C11Generic) {
+  verifyFormat("_Generic(x, int: 1, default: 0)");
+  verifyFormat("#define cbrt(X) _Generic((X), float: cbrtf, default: cbrt)(X)");
+  verifyFormat("_Generic(x, const char *: 1, char *const: 16, int: 8);");
+  verifyFormat("_Generic(x, int: f1, const int: f2)();");
+  verifyFormat("_Generic(x, struct A: 1, void (*)(void): 2);");
+
+  verifyFormat("_Generic(x,\n"
+   "float: f,\n"
+   "default: d,\n"
+   "long double: ld,\n"
+   "float _Complex: fc,\n"
+   "double _Complex: dc,\n"
+   "long double _Complex: ldc)");
+
+  FormatStyle Style = getLLVMStyle();
+  Style.ColumnLimit = 40;
+  verifyFormat("#define LIMIT_MAX(T)   \\\n"
+   "  _Generic(((T)0), \\\n"
+   "  unsigned int: UINT_MAX,  \\\n"
+   "  unsigned long: ULONG_MAX,\\\n"
+   "  unsigned long long: ULLONG_MAX)",
+   Style);
+  verifyFormat("_Generic(x,\n"
+   "struct A: 1,\n"
+   "void (*)(void): 2);",
+   Style);
+
+  Style.ContinuationIndentWidth = 2;
+  verifyFormat("_Generic(x,\n"
+   "  struct A: 1,\n"
+   "  void (*)(void): 2);",
+   Style);
+}
+
 TEST_F(FormatTest, AmbersandInLamda) {
   // Test case reported in https://bugs.llvm.org/show_bug.cgi?id=41899
   FormatStyle AlignStyle = getLLVMStyle();
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -323,6 +323,10 @@
   Contexts.back().IsExpression = false;
 } else if (OpeningParen.is(TT_RequiresExpressionLParen)) {
   Contexts.back().IsExpression = false;
+} else if (OpeningParen.Previous &&
+   OpeningParen.Previous->is(tok::kw__Generic)) {
+  Contexts.back().ContextType = Context::C11GenericSelection;
+  Contexts.back().IsExpression = true;
 } else if (Line.InPPDirective &&
(!OpeningParen.Previous ||
 !OpeningParen.Previous->is(tok::identifier))) {
@@ -1028,6 +1032,8 @@
 }
   } else if (Contexts.back().ColonIsForRangeExpr) {
 Tok->setType(TT_RangeBasedForLoopColon);
+  } else if (Contexts.back().ContextType == Context::C11GenericSelection) {
+Tok->setType(TT_GenericSelectionColon);
   } else if (CurrentToken && CurrentToken->is(tok::numeric_constant)) {
 Tok->setType(TT_BitFieldColon);
   } else if (Contexts.size() == 1 &

[PATCH] D141287: [clang-format] Inherit RightAlign option across scopes

2023-01-09 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel abandoned this revision.
rymiel added a comment.

I apologize, I managed to really mess up with git somehow


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141287

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


[PATCH] D141288: [clang-format] Inherit RightAlign options across scopes

2023-01-09 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel created this revision.
rymiel added reviewers: HazardyKnusperkeks, owenpan, MyDeveloperDay.
rymiel added a project: clang-format.
Herald added a project: All.
rymiel requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

D119599  added the ability to align compound 
assignments, right aligning
them in order to line up at the equals sign.
However, that patch didn't account for AlignTokens being called
recursively across scopes, which reset the right justification to be
false in any scope besides the top scope. This meant the compound
assignments were aligned, just not at the right place.
(No tests also ever introduced any scopes)

This patch makes sure to inherit the right justification value, just as
every other parameter is passed on.

Fixes https://github.com/llvm/llvm-project/issues/58029


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D141288

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


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -17693,6 +17693,20 @@
"dvsdsv<<= 5;\n"
"int dsvvdvsdvvv = 123;",
Alignment);
+  verifyFormat("int xxx = 5;\n"
+   "xxx = 5;\n"
+   "{\n"
+   "  int yyy = 6;\n"
+   "  yyy = 6;\n"
+   "}",
+   Alignment);
+  verifyFormat("int xxx = 5;\n"
+   "xxx+= 5;\n"
+   "{\n"
+   "  int yyy = 6;\n"
+   "  yyy+= 6;\n"
+   "}",
+   Alignment);
   // Test that `<=` is not treated as a compound assignment.
   verifyFormat("aa &= 5;\n"
"b <= 10;\n"
Index: clang/lib/Format/WhitespaceManager.cpp
===
--- clang/lib/Format/WhitespaceManager.cpp
+++ clang/lib/Format/WhitespaceManager.cpp
@@ -609,7 +609,8 @@
   ++CommasBeforeMatch;
 } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
   // Call AlignTokens recursively, skipping over this scope block.
-  unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i, ACS);
+  unsigned StoppedAt =
+  AlignTokens(Style, Matches, Changes, i, ACS, RightJustify);
   i = StoppedAt - 1;
   continue;
 }


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -17693,6 +17693,20 @@
"dvsdsv<<= 5;\n"
"int dsvvdvsdvvv = 123;",
Alignment);
+  verifyFormat("int xxx = 5;\n"
+   "xxx = 5;\n"
+   "{\n"
+   "  int yyy = 6;\n"
+   "  yyy = 6;\n"
+   "}",
+   Alignment);
+  verifyFormat("int xxx = 5;\n"
+   "xxx+= 5;\n"
+   "{\n"
+   "  int yyy = 6;\n"
+   "  yyy+= 6;\n"
+   "}",
+   Alignment);
   // Test that `<=` is not treated as a compound assignment.
   verifyFormat("aa &= 5;\n"
"b <= 10;\n"
Index: clang/lib/Format/WhitespaceManager.cpp
===
--- clang/lib/Format/WhitespaceManager.cpp
+++ clang/lib/Format/WhitespaceManager.cpp
@@ -609,7 +609,8 @@
   ++CommasBeforeMatch;
 } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
   // Call AlignTokens recursively, skipping over this scope block.
-  unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i, ACS);
+  unsigned StoppedAt =
+  AlignTokens(Style, Matches, Changes, i, ACS, RightJustify);
   i = StoppedAt - 1;
   continue;
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D137244: [Clang] Correctly capture bindings in dependent lambdas.

2023-01-09 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added inline comments.



Comment at: clang/test/SemaCXX/cxx20-decomposition.cpp:160
+return a;
+}() ; }(0);
+(void)[&](auto c) { return b + [&a](auto) {

aaron.ballman wrote:
> Same edit elsewhere. Did clang-format get confused?
It can't be clang-format because it would figuratively explode due to 
https://github.com/llvm/llvm-project/issues/40694! (but it did remind me to 
investigate that issue)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D137244

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


[PATCH] D139211: [clang-format] Properly handle the C11 _Generic keyword.

2023-01-10 Thread Emilia Dreamer via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG0904e0bac831: [clang-format] Properly handle the C11 
_Generic keyword. (authored by rymiel).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D139211

Files:
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/unittests/Format/FormatTest.cpp
  clang/unittests/Format/TokenAnnotatorTest.cpp

Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -1152,6 +1152,14 @@
   EXPECT_TOKEN(Tokens[1], tok::identifier, TT_FunctionDeclarationName);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsC11GenericSelection) {
+  auto Tokens = annotate("_Generic(x, int: 1, default: 0)");
+  ASSERT_EQ(Tokens.size(), 13u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::kw__Generic, TT_Unknown);
+  EXPECT_TOKEN(Tokens[5], tok::colon, TT_GenericSelectionColon);
+  EXPECT_TOKEN(Tokens[9], tok::colon, TT_GenericSelectionColon);
+}
+
 TEST_F(TokenAnnotatorTest, UnderstandsVerilogOperators) {
   auto Annotate = [this](llvm::StringRef Code) {
 return annotate(Code, getLLVMStyle(FormatStyle::LK_Verilog));
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -23012,6 +23012,41 @@
   verifyFormat("x = (_Atomic( uint64_t ))&a;", Style);
 }
 
+TEST_F(FormatTest, C11Generic) {
+  verifyFormat("_Generic(x, int: 1, default: 0)");
+  verifyFormat("#define cbrt(X) _Generic((X), float: cbrtf, default: cbrt)(X)");
+  verifyFormat("_Generic(x, const char *: 1, char *const: 16, int: 8);");
+  verifyFormat("_Generic(x, int: f1, const int: f2)();");
+  verifyFormat("_Generic(x, struct A: 1, void (*)(void): 2);");
+
+  verifyFormat("_Generic(x,\n"
+   "float: f,\n"
+   "default: d,\n"
+   "long double: ld,\n"
+   "float _Complex: fc,\n"
+   "double _Complex: dc,\n"
+   "long double _Complex: ldc)");
+
+  FormatStyle Style = getLLVMStyle();
+  Style.ColumnLimit = 40;
+  verifyFormat("#define LIMIT_MAX(T)   \\\n"
+   "  _Generic(((T)0), \\\n"
+   "  unsigned int: UINT_MAX,  \\\n"
+   "  unsigned long: ULONG_MAX,\\\n"
+   "  unsigned long long: ULLONG_MAX)",
+   Style);
+  verifyFormat("_Generic(x,\n"
+   "struct A: 1,\n"
+   "void (*)(void): 2);",
+   Style);
+
+  Style.ContinuationIndentWidth = 2;
+  verifyFormat("_Generic(x,\n"
+   "  struct A: 1,\n"
+   "  void (*)(void): 2);",
+   Style);
+}
+
 TEST_F(FormatTest, AmbersandInLamda) {
   // Test case reported in https://bugs.llvm.org/show_bug.cgi?id=41899
   FormatStyle AlignStyle = getLLVMStyle();
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -322,6 +322,10 @@
   Contexts.back().IsExpression = false;
 } else if (OpeningParen.is(TT_RequiresExpressionLParen)) {
   Contexts.back().IsExpression = false;
+} else if (OpeningParen.Previous &&
+   OpeningParen.Previous->is(tok::kw__Generic)) {
+  Contexts.back().ContextType = Context::C11GenericSelection;
+  Contexts.back().IsExpression = true;
 } else if (Line.InPPDirective &&
(!OpeningParen.Previous ||
 !OpeningParen.Previous->is(tok::identifier))) {
@@ -1027,6 +1031,8 @@
 }
   } else if (Contexts.back().ColonIsForRangeExpr) {
 Tok->setType(TT_RangeBasedForLoopColon);
+  } else if (Contexts.back().ContextType == Context::C11GenericSelection) {
+Tok->setType(TT_GenericSelectionColon);
   } else if (CurrentToken && CurrentToken->is(tok::numeric_constant)) {
 Tok->setType(TT_BitFieldColon);
   } else if (Contexts.size() == 1 &&
@@ -1626,6 +1632,8 @@
   StructArrayInitializer,
   // Like in `static_cast`.
   TemplateArgument,
+  // C11 _Generic selection.
+  C11GenericSelection,
 } ContextType = Unknown;
   };
 
@@ -3254,7 +3262,8 @@
 return 100;
   }
   if (Left.is(tok::l_paren) && Left.Previous &&
-  (Left.Previous->is(tok::kw_for) || Left.Previous->isIf())) {
+  (Left.Previous->isOneOf(tok::kw_for, tok::kw__Generic) ||
+   Left.Previous->isIf())) {
 return 1000;
   }
   if (Left.is(tok::equal) && InFunctionDecl)
@@ -4163,6 +4172,8 @@
   return false;
  

[PATCH] D141288: [clang-format] Inherit RightAlign options across scopes

2023-01-10 Thread Emilia Dreamer via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG51ba660a0700: [clang-format] Inherit RightAlign options 
across scopes (authored by rymiel).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D141288

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


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -17693,6 +17693,20 @@
"dvsdsv<<= 5;\n"
"int dsvvdvsdvvv = 123;",
Alignment);
+  verifyFormat("int xxx = 5;\n"
+   "xxx = 5;\n"
+   "{\n"
+   "  int yyy = 6;\n"
+   "  yyy = 6;\n"
+   "}",
+   Alignment);
+  verifyFormat("int xxx = 5;\n"
+   "xxx+= 5;\n"
+   "{\n"
+   "  int yyy = 6;\n"
+   "  yyy+= 6;\n"
+   "}",
+   Alignment);
   // Test that `<=` is not treated as a compound assignment.
   verifyFormat("aa &= 5;\n"
"b <= 10;\n"
Index: clang/lib/Format/WhitespaceManager.cpp
===
--- clang/lib/Format/WhitespaceManager.cpp
+++ clang/lib/Format/WhitespaceManager.cpp
@@ -609,7 +609,8 @@
   ++CommasBeforeMatch;
 } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
   // Call AlignTokens recursively, skipping over this scope block.
-  unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i, ACS);
+  unsigned StoppedAt =
+  AlignTokens(Style, Matches, Changes, i, ACS, RightJustify);
   i = StoppedAt - 1;
   continue;
 }


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -17693,6 +17693,20 @@
"dvsdsv<<= 5;\n"
"int dsvvdvsdvvv = 123;",
Alignment);
+  verifyFormat("int xxx = 5;\n"
+   "xxx = 5;\n"
+   "{\n"
+   "  int yyy = 6;\n"
+   "  yyy = 6;\n"
+   "}",
+   Alignment);
+  verifyFormat("int xxx = 5;\n"
+   "xxx+= 5;\n"
+   "{\n"
+   "  int yyy = 6;\n"
+   "  yyy+= 6;\n"
+   "}",
+   Alignment);
   // Test that `<=` is not treated as a compound assignment.
   verifyFormat("aa &= 5;\n"
"b <= 10;\n"
Index: clang/lib/Format/WhitespaceManager.cpp
===
--- clang/lib/Format/WhitespaceManager.cpp
+++ clang/lib/Format/WhitespaceManager.cpp
@@ -609,7 +609,8 @@
   ++CommasBeforeMatch;
 } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
   // Call AlignTokens recursively, skipping over this scope block.
-  unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i, ACS);
+  unsigned StoppedAt =
+  AlignTokens(Style, Matches, Changes, i, ACS, RightJustify);
   i = StoppedAt - 1;
   continue;
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D137223: [clang-format] Remove special case for kw_operator when aligning decls

2022-11-01 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel created this revision.
rymiel added reviewers: HazardyKnusperkeks, owenpan, MyDeveloperDay.
Herald added a project: All.
rymiel requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This change breaks no existing tests but does fix the linked issue.
Declarations of operator overloads are annotated with
`TT_FunctionDeclarationName` on the `operator` keyword, which is already
being checked for when aligning, so the extra `kw_operator` doesn't seem
to be necessary. (just for reference, it was added in
rG92b397fb9d55ccdf4632c2b1b15b4a0ee417cf74 
 / 
92b397fb9d55ccdf4632c2b1b15b4a0ee417cf74)

Fixes https://github.com/llvm/llvm-project/issues/55733


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D137223

Files:
  clang/lib/Format/WhitespaceManager.cpp
  clang/unittests/Format/FormatTest.cpp
  clang/unittests/Format/TokenAnnotatorTest.cpp


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -437,6 +437,23 @@
   ASSERT_EQ(Tokens.size(), 8u) << Tokens;
   EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
   EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
+
+  Tokens = annotate("int operator+(int);");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::kw_operator, TT_FunctionDeclarationName);
+  EXPECT_TOKEN(Tokens[2], tok::plus, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("auto operator=(T&) {}");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::kw_operator, TT_FunctionDeclarationName);
+  EXPECT_TOKEN(Tokens[2], tok::equal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("auto operator()() {}");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::kw_operator, TT_FunctionDeclarationName);
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandsRequiresClausesAndConcepts) {
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -17936,6 +17936,14 @@
"  doublebar();\n"
"};\n",
Alignment);
+  // Ensure operators are not aligned if they're being called, not declared
+  verifyFormat("int main() {\n"
+   "  intoperator()(int a);\n"
+   "  double operator+(double a);\n"
+   "  operator()(1);\n"
+   "  operator+(1.0);\n"
+   "};\n",
+   Alignment);
   // http://llvm.org/PR52914
   verifyFormat("char *a[] = {\"a\", // comment\n"
" \"bb\"};\n"
Index: clang/lib/Format/WhitespaceManager.cpp
===
--- clang/lib/Format/WhitespaceManager.cpp
+++ clang/lib/Format/WhitespaceManager.cpp
@@ -870,9 +870,7 @@
   AlignTokens(
   Style,
   [](Change const &C) {
-// tok::kw_operator is necessary for aligning operator overload
-// definitions.
-if (C.Tok->isOneOf(TT_FunctionDeclarationName, tok::kw_operator))
+if (C.Tok->is(TT_FunctionDeclarationName))
   return true;
 if (C.Tok->isNot(TT_StartOfName))
   return false;


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -437,6 +437,23 @@
   ASSERT_EQ(Tokens.size(), 8u) << Tokens;
   EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
   EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
+
+  Tokens = annotate("int operator+(int);");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::kw_operator, TT_FunctionDeclarationName);
+  EXPECT_TOKEN(Tokens[2], tok::plus, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("auto operator=(T&) {}");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::kw_operator, TT_FunctionDeclarationName);
+  EXPECT_TOKEN(Tokens[2], tok::equal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("auto operator()() {}");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::kw_operator, TT_Fu

[PATCH] D137223: [clang-format] Remove special case for kw_operator when aligning decls

2022-11-04 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel marked 3 inline comments as done.
rymiel added inline comments.



Comment at: clang/unittests/Format/TokenAnnotatorTest.cpp:441-456
+  Tokens = annotate("int operator+(int);");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::kw_operator, TT_FunctionDeclarationName);
+  EXPECT_TOKEN(Tokens[2], tok::plus, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("auto operator=(T&) {}");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;

owenpan wrote:
> Instead of adding new tests, you can add checks for `kw_operator` and 
> `TT_FunctionDeclarationName` to the existing ones.
I wanted to have tests that are declaring operator functions, not just calling 
them


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D137223

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


[PATCH] D137223: [clang-format] Remove special case for kw_operator when aligning decls

2022-11-04 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel updated this revision to Diff 473380.
rymiel added a comment.

Remove format test, relying only on annotator tests


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D137223

Files:
  clang/lib/Format/WhitespaceManager.cpp
  clang/unittests/Format/TokenAnnotatorTest.cpp


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -393,50 +393,80 @@
 TEST_F(TokenAnnotatorTest, UnderstandsOverloadedOperators) {
   auto Tokens = annotate("x.operator+()");
   ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::kw_operator, TT_FunctionDeclarationName);
   EXPECT_TOKEN(Tokens[3], tok::plus, TT_OverloadedOperator);
   EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
   Tokens = annotate("x.operator=()");
   ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::kw_operator, TT_FunctionDeclarationName);
   EXPECT_TOKEN(Tokens[3], tok::equal, TT_OverloadedOperator);
   EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
   Tokens = annotate("x.operator+=()");
   ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::kw_operator, TT_FunctionDeclarationName);
   EXPECT_TOKEN(Tokens[3], tok::plusequal, TT_OverloadedOperator);
   EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
   Tokens = annotate("x.operator,()");
   ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::kw_operator, TT_FunctionDeclarationName);
   EXPECT_TOKEN(Tokens[3], tok::comma, TT_OverloadedOperator);
   EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
   Tokens = annotate("x.operator()()");
   ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::kw_operator, TT_FunctionDeclarationName);
   EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_OverloadedOperator);
   EXPECT_TOKEN(Tokens[4], tok::r_paren, TT_OverloadedOperator);
   EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
   Tokens = annotate("x.operator[]()");
   ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::kw_operator, TT_FunctionDeclarationName);
   // EXPECT_TOKEN(Tokens[3], tok::l_square, TT_OverloadedOperator);
   // EXPECT_TOKEN(Tokens[4], tok::r_square, TT_OverloadedOperator);
   EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
   Tokens = annotate("x.operator\"\"_a()");
   ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::kw_operator, TT_FunctionDeclarationName);
   EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
   EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
   Tokens = annotate("x.operator\"\" _a()");
   ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  // FIXME
+  // EXPECT_TOKEN(Tokens[2], tok::kw_operator, TT_FunctionDeclarationName);
   EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
   EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
   Tokens = annotate("x.operator\"\"if()");
   ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::kw_operator, TT_FunctionDeclarationName);
   EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
   EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
   Tokens = annotate("x.operator\"\"s()");
   ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::kw_operator, TT_FunctionDeclarationName);
   EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
   EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_OverloadedOperatorLParen);
   Tokens = annotate("x.operator\"\" s()");
   ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  // FIXME
+  // EXPECT_TOKEN(Tokens[2], tok::kw_operator, TT_FunctionDeclarationName);
   EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_OverloadedOperator);
   EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_OverloadedOperatorLParen);
+
+  Tokens = annotate("int operator+(int);");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::kw_operator, TT_FunctionDeclarationName);
+  EXPECT_TOKEN(Tokens[2], tok::plus, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("auto operator=(T&) {}");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::kw_operator, TT_FunctionDeclarationName);
+  EXPECT_TOKEN(Tokens[2], tok::equal, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_OverloadedOperatorLParen);
+  Tokens = annotate("auto operator()() {}");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::kw_operator, TT_FunctionDeclarationName);
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_OverloadedOperator);
+  EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_OverloadedOperator);

[PATCH] D137474: [clang-format] Defer formatting of operator< to honor paren spacing

2022-11-04 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel created this revision.
rymiel added reviewers: HazardyKnusperkeks, owenpan, MyDeveloperDay.
Herald added a project: All.
rymiel requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

I'm not exactly sure what the intent of that section of
`spaceRequiredBetween` is doing, it seems to handle templates and <<,
but the part which adds spaces before parens is way later, as part
of `spaceRequiredBeforeParens`.

Fixes https://github.com/llvm/llvm-project/issues/58821


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D137474

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
@@ -15472,6 +15472,8 @@
   Space.SpaceBeforeParens = FormatStyle::SBPO_Always;
 
   verifyFormat("int f ();", Space);
+  verifyFormat("bool operator< ();", Space);
+  verifyFormat("bool operator> ();", Space);
   verifyFormat("void f (int a, T b) {\n"
"  while (true)\n"
"continue;\n"
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -3426,7 +3426,9 @@
 return false;
   return !Style.Cpp11BracedListStyle;
 }
-return false;
+// Don't attempt to format operator<(), as it is handled later.
+if (Right.isNot(TT_OverloadedOperatorLParen))
+  return false;
   }
   if (Right.is(tok::ellipsis)) {
 return Left.Tok.isLiteral() || (Left.is(tok::identifier) && Left.Previous 
&&


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -15472,6 +15472,8 @@
   Space.SpaceBeforeParens = FormatStyle::SBPO_Always;
 
   verifyFormat("int f ();", Space);
+  verifyFormat("bool operator< ();", Space);
+  verifyFormat("bool operator> ();", Space);
   verifyFormat("void f (int a, T b) {\n"
"  while (true)\n"
"continue;\n"
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -3426,7 +3426,9 @@
 return false;
   return !Style.Cpp11BracedListStyle;
 }
-return false;
+// Don't attempt to format operator<(), as it is handled later.
+if (Right.isNot(TT_OverloadedOperatorLParen))
+  return false;
   }
   if (Right.is(tok::ellipsis)) {
 return Left.Tok.isLiteral() || (Left.is(tok::identifier) && Left.Previous &&
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D137486: [clang-format] Correctly annotate function names before attributes

2022-11-05 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added a comment.

Are both isCpp11AttributeSpecifier and isCppAttribute required?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D137486

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


[PATCH] D137762: [clang-format] avoid breaking )( with BlockIndent

2022-11-09 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added a comment.

This patch will probably need unit tests




Comment at: clang/lib/Format/TokenAnnotator.cpp:5004-5005
 const FormatToken *Previous = Right.MatchingParen->Previous;
-return !(Previous && (Previous->is(tok::kw_for) || Previous->isIf()));
+// avoid breaking when there is an opening parens immediately following
+// a closing parens, such as in cast operators and indirect function calls
+return !((Previous && (Previous->is(tok::kw_for) || Previous->isIf())) ||

Please follow the convention on comments as seen on surrounding lines (i.e. use 
proper sentences with capitalization and a full stop at the end)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D137762

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


[PATCH] D137823: [clang-format][NFC] Moved configuration parsing tests in own file

2022-11-11 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added inline comments.



Comment at: clang/unittests/Format/ConfigParseTest.cpp:1
+//===- unittest/Format/ConfiParseTest.cpp - Config parsing unit tests 
-===//
+//

typo (Confi) :)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D137823

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


[PATCH] D137865: [clang-format][NFC] Improve documentation on ReflowComments

2022-11-15 Thread Emilia Dreamer via Phabricator via cfe-commits
rymiel added inline comments.



Comment at: clang/include/clang/Format/Format.h:3073-3076
+  /// If ``true``, clang-format will attempt to re-flow comments. That is it
+  /// will touch a comment and *reflow* long comments into new lines, trying to
+  /// obey the ``ColumnLimit``. ``/*`` comments will get a leading ``*`` on the
+  /// new lines.

HazardyKnusperkeks wrote:
> owenpan wrote:
> > Let's leave it as is because the new lines don't always get a leading `*`:
> > ```
> > $ cat foo.cpp
> > /* The LLVM Project is a collection of modular and reusable compiler and 
> > toolchain
> >technologies. */
> > $ clang-format -style='{ReflowComments: true}' foo.cpp
> > /* The LLVM Project is a collection of modular and reusable compiler and
> >toolchain technologies. */
> > ```
> That was from a short glimpse on the code.
> Adapted the text.
> Let's leave it as is because the new lines don't always get a leading `*`:

I suppose this also ties into https://github.com/llvm/llvm-project/issues/58710




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

https://reviews.llvm.org/D137865

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


  1   2   3   >