[PATCH] D133647: [clang-format] Parse the else part of `#if 0`

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

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

Previously things outside of `#if` blocks were parsed as if only the
first branch of the conditional compilation branch existed.  Unless the
first condition is 0, then the outer parts would be parsed as if
everything inside the conditional parts didn't exist.  Now we use the
second conditional branch if the first condition is 0.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D133647

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
@@ -5993,6 +5993,16 @@
  ");\n"
  "#else\n"
  "#endif");
+
+  // Verify that indentation is correct when there is an `#if 0` with an
+  // `#else`.
+  verifyFormat("#if 0\n"
+   "{\n"
+   "#else\n"
+   "{\n"
+   "#endif\n"
+   "  x;\n"
+   "}");
 }
 
 TEST_F(FormatTest, GraciouslyHandleIncorrectPreprocessorConditions) {
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1124,7 +1124,9 @@
   ++PPBranchLevel;
   assert(PPBranchLevel >= 0 && PPBranchLevel <= 
(int)PPLevelBranchIndex.size());
   if (PPBranchLevel == (int)PPLevelBranchIndex.size()) {
-PPLevelBranchIndex.push_back(0);
+// If the first branch is unreachable, set the BranchIndex to 1.  This way
+// the next branch it will be parsed if there is one.
+PPLevelBranchIndex.push_back(Unreachable ? 1 : 0);
 PPLevelBranchCount.push_back(0);
   }
   PPChainBranchIndex.push(0);


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -5993,6 +5993,16 @@
  ");\n"
  "#else\n"
  "#endif");
+
+  // Verify that indentation is correct when there is an `#if 0` with an
+  // `#else`.
+  verifyFormat("#if 0\n"
+   "{\n"
+   "#else\n"
+   "{\n"
+   "#endif\n"
+   "  x;\n"
+   "}");
 }
 
 TEST_F(FormatTest, GraciouslyHandleIncorrectPreprocessorConditions) {
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1124,7 +1124,9 @@
   ++PPBranchLevel;
   assert(PPBranchLevel >= 0 && PPBranchLevel <= (int)PPLevelBranchIndex.size());
   if (PPBranchLevel == (int)PPLevelBranchIndex.size()) {
-PPLevelBranchIndex.push_back(0);
+// If the first branch is unreachable, set the BranchIndex to 1.  This way
+// the next branch it will be parsed if there is one.
+PPLevelBranchIndex.push_back(Unreachable ? 1 : 0);
 PPLevelBranchCount.push_back(0);
   }
   PPChainBranchIndex.push(0);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133635: [clang-format] Don't insert braces for loops with a null statement

2022-09-13 Thread sstwcw via Phabricator via cfe-commits
sstwcw added inline comments.



Comment at: clang/unittests/Format/FormatTest.cpp:25370
+   "#if 0\n"
+   " if (a) {\n"
+   "#else\n"

Can you confirm that there is supposed to be only one space here while there 
are two in the next test?  `messUp` turns two spaces into one space.  The 
formatter doesn't change things inside the `#if 0` block, both before and after 
D133647.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133635

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


[PATCH] D133954: [clang-format] Fix template arguments in macros

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

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

old

  #define FOO(typeName, realClass)   \
{\
  #typeName, foo < FooType>(new foo (#typeName))  \
}

new

  #define FOO(typeName, realClass)\
{ #typeName, foo(new foo(#typeName)) }

Previously, when an UnwrappedLine began with a hash in a macro
definition, the program incorrectly assumed the line was a preprocessor
directive.  It should be stringification.

The rule in spaceRequiredBefore was added in 8b5297117b.  Its purpose is
to add a space in an include directive.  It also added a space to a
template opener when the line began with a stringification hash.  So we
changed it.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D133954

Files:
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/TokenAnnotator.h
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/lib/Format/UnwrappedLineParser.h
  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
@@ -284,6 +284,17 @@
   EXPECT_TOKEN(Tokens[13], tok::ampamp, TT_BinaryOperator);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsTemplatesInMacros) {
+  auto Tokens =
+  annotate("#define FOO(typeName) \\\n"
+   "  { #typeName, foo(new foo(#typeName)) }");
+  ASSERT_EQ(Tokens.size(), 27u) << Tokens;
+  EXPECT_TOKEN(Tokens[11], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[13], tok::greater, TT_TemplateCloser);
+  EXPECT_TOKEN(Tokens[17], tok::less, TT_TemplateOpener);
+  EXPECT_TOKEN(Tokens[19], tok::greater, TT_TemplateCloser);
+}
+
 TEST_F(TokenAnnotatorTest, UnderstandsWhitespaceSensitiveMacros) {
   FormatStyle Style = getLLVMStyle();
   Style.WhitespaceSensitiveMacros.push_back("FOO");
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -9790,6 +9790,9 @@
   verifyFormat("bool x = 5 < a::x;");
   verifyFormat("bool x = a < 4 ? a > 2 : false;");
   verifyFormat("bool x = f() ? a < 2 : a > 2;");
+  verifyFormat("#define FOO(typeName, realClass)   "
+   "\\\n"
+   "  { #typeName, foo(new foo(#typeName)) }");
 
   verifyGoogleFormat("A> a;");
   verifyGoogleFormat("A>> a;");
Index: clang/lib/Format/UnwrappedLineParser.h
===
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -46,6 +46,8 @@
 
   /// Whether this \c UnwrappedLine is part of a preprocessor directive.
   bool InPPDirective;
+  /// Whether it is part of a macro body.
+  bool InMacroBody;
 
   bool MustBeDeclaration;
 
@@ -353,8 +355,8 @@
 };
 
 inline UnwrappedLine::UnwrappedLine()
-: Level(0), InPPDirective(false), MustBeDeclaration(false),
-  MatchingOpeningBlockLineIndex(kInvalidIndex) {}
+: Level(0), InPPDirective(false), InMacroBody(false),
+  MustBeDeclaration(false), MatchingOpeningBlockLineIndex(kInvalidIndex) {}
 
 } // end namespace format
 } // end namespace clang
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -116,12 +116,14 @@
 TokenSource = this;
 Line.Level = 0;
 Line.InPPDirective = true;
+// InMacroBody gets set after the `#define x` part.
   }
 
   ~ScopedMacroState() override {
 TokenSource = PreviousTokenSource;
 ResetToken = Token;
 Line.InPPDirective = false;
+Line.InMacroBody = false;
 Line.Level = PreviousLineLevel;
   }
 
@@ -196,6 +198,7 @@
 Parser.Line = std::make_unique();
 Parser.Line->Level = PreBlockLine->Level;
 Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
+Parser.Line->InMacroBody = PreBlockLine->InMacroBody;
   }
 
   ~ScopedLineState() {
@@ -1251,6 +1254,7 @@
 Line->Level += PPBranchLevel + 1;
   addUnwrappedLine();
   ++Line->Level;
+  Line->InMacroBody = true;
 
   // Errors during a preprocessor directive can only affect the layout of the
   // preprocessor directive, and thus we ignore them. An alternative approach
Index: clang/lib/Format/TokenAnnotator.h
===
--- clang/lib/Format/TokenAnnotator.h
+++ clang/lib/Format/Token

[PATCH] D128607: [clang-format] NFC Fix uninitialized memory problem

2022-06-26 Thread sstwcw via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG141ad3ba0571: [clang-format] Fix uninitialized memory 
problem (authored by sstwcw).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D128607

Files:
  clang/lib/Format/FormatTokenLexer.cpp


Index: clang/lib/Format/FormatTokenLexer.cpp
===
--- clang/lib/Format/FormatTokenLexer.cpp
+++ clang/lib/Format/FormatTokenLexer.cpp
@@ -1128,11 +1128,12 @@
 return false;
   size_t Len = Matches[0].size();
 
-  Tok.setLength(Len);
-  Tok.setLocation(Lex->getSourceLocation(Start, Len));
   // The kind has to be an identifier so we can match it against those defined
-  // in Keywords.
+  // in Keywords. The kind has to be set before the length because the 
setLength
+  // function checks that the kind is not an annotation.
   Tok.setKind(tok::raw_identifier);
+  Tok.setLength(Len);
+  Tok.setLocation(Lex->getSourceLocation(Start, Len));
   Tok.setRawIdentifierData(Start);
   Lex->seek(Lex->getCurrentBufferOffset() + Len, /*IsAtStartofline=*/false);
   return true;


Index: clang/lib/Format/FormatTokenLexer.cpp
===
--- clang/lib/Format/FormatTokenLexer.cpp
+++ clang/lib/Format/FormatTokenLexer.cpp
@@ -1128,11 +1128,12 @@
 return false;
   size_t Len = Matches[0].size();
 
-  Tok.setLength(Len);
-  Tok.setLocation(Lex->getSourceLocation(Start, Len));
   // The kind has to be an identifier so we can match it against those defined
-  // in Keywords.
+  // in Keywords. The kind has to be set before the length because the setLength
+  // function checks that the kind is not an annotation.
   Tok.setKind(tok::raw_identifier);
+  Tok.setLength(Len);
+  Tok.setLocation(Lex->getSourceLocation(Start, Len));
   Tok.setRawIdentifierData(Start);
   Lex->seek(Lex->getCurrentBufferOffset() + Len, /*IsAtStartofline=*/false);
   return true;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D128709: [clang-format] Handle Verilog attributes

2022-06-28 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
sstwcw added reviewers: HazardyKnusperkeks, MyDeveloperDay, curdeius, owenpan.
Herald added a project: All.
sstwcw requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D128709

Files:
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTestVerilog.cpp


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -71,6 +71,12 @@
 TEST_F(FormatTestVerilog, If) {
   verifyFormat("if (x)\n"
"  x = x;");
+  verifyFormat("unique if (x)\n"
+   "  x = x;");
+  verifyFormat("unique0 if (x)\n"
+   "  x = x;");
+  verifyFormat("priority if (x)\n"
+   "  x = x;");
   verifyFormat("if (x)\n"
"  x = x;\n"
"x = x;");
@@ -137,6 +143,14 @@
"  x = {x};\n"
"else\n"
"  {x} = {x};");
+
+  // With attributes.
+  verifyFormat("(* x *) if (x)\n"
+   "  x = x;");
+  verifyFormat("(* x = \"x\" *) if (x)\n"
+   "  x = x;");
+  verifyFormat("(* x, x = \"x\" *) if (x)\n"
+   "  x = x;");
 }
 
 TEST_F(FormatTestVerilog, Preprocessor) {
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1456,6 +1456,26 @@
 addUnwrappedLine();
 return;
   }
+
+  if (Style.isVerilog()) {
+// Skip things that can exist before keywords like 'if' and 'case'.
+while (true) {
+  if (FormatTok->isOneOf(Keywords.kw_priority, Keywords.kw_unique,
+ Keywords.kw_unique0)) {
+nextToken();
+  } else if (FormatTok->is(tok::l_paren)) {
+const FormatToken *Next = Tokens->peekNextToken();
+if (Next && Next->is(tok::star))
+  parseParens();
+else
+  break;
+  } else {
+break;
+  }
+}
+  }
+
+  // Tokens that only make sense at the beginning of a line.
   switch (FormatTok->Tok.getKind()) {
   case tok::kw_asm:
 nextToken();
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -3957,6 +3957,9 @@
   Left.MatchingParen->endsSequence(tok::l_paren, tok::at {
   return true;
 }
+// Add space in attribute like `(* ASYNC_REG = "TRUE" *)`.
+if (Left.endsSequence(tok::star, tok::l_paren) && 
Right.is(tok::identifier))
+  return true;
   }
   if (Left.is(TT_ImplicitStringLiteral))
 return Right.hasWhitespaceBefore();


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -71,6 +71,12 @@
 TEST_F(FormatTestVerilog, If) {
   verifyFormat("if (x)\n"
"  x = x;");
+  verifyFormat("unique if (x)\n"
+   "  x = x;");
+  verifyFormat("unique0 if (x)\n"
+   "  x = x;");
+  verifyFormat("priority if (x)\n"
+   "  x = x;");
   verifyFormat("if (x)\n"
"  x = x;\n"
"x = x;");
@@ -137,6 +143,14 @@
"  x = {x};\n"
"else\n"
"  {x} = {x};");
+
+  // With attributes.
+  verifyFormat("(* x *) if (x)\n"
+   "  x = x;");
+  verifyFormat("(* x = \"x\" *) if (x)\n"
+   "  x = x;");
+  verifyFormat("(* x, x = \"x\" *) if (x)\n"
+   "  x = x;");
 }
 
 TEST_F(FormatTestVerilog, Preprocessor) {
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1456,6 +1456,26 @@
 addUnwrappedLine();
 return;
   }
+
+  if (Style.isVerilog()) {
+// Skip things that can exist before keywords like 'if' and 'case'.
+while (true) {
+  if (FormatTok->isOneOf(Keywords.kw_priority, Keywords.kw_unique,
+ Keywords.kw_unique0)) {
+nextToken();
+  } else if (FormatTok->is(tok::l_paren)) {
+const FormatToken *Next = Tokens->peekNextToken();
+if (Next && Next->is(tok::star))
+  parseParens();
+else
+  break;
+  } else {
+break;
+  }
+}
+  }
+
+  // Tokens that only make sense at the beginning of a line.
   switch (FormatTok->Tok.getKind()) {
   case tok::kw_asm:
 nextToken();
Index: clang/lib/Format/TokenAnnotator.cpp
=

[PATCH] D128711: [clang-format] Handle Verilog blocks

2022-06-28 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
sstwcw added reviewers: HazardyKnusperkeks, MyDeveloperDay, curdeius, owenpan.
Herald added a project: All.
sstwcw requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Now stuff inside begin-end blocks get indented.

Some tests are moved into FormatTestVerilog.Block from
FormatTestVerilog.If because they have nothing to do with if statements.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D128711

Files:
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTestVerilog.cpp
  clang/unittests/Format/TokenAnnotatorTest.cpp

Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -862,6 +862,12 @@
   ASSERT_EQ(Tokens.size(), 7u) << Tokens;
   EXPECT_TOKEN(Tokens[2], tok::tilde, TT_UnaryOperator);
   EXPECT_TOKEN(Tokens[3], tok::pipe, TT_UnaryOperator);
+  // Test for block label colons.
+  Tokens = Annotate("begin : x\n"
+"end : x");
+  ASSERT_EQ(Tokens.size(), 7u);
+  EXPECT_TOKEN(Tokens[1], tok::colon, TT_VerilogBlockLabelColon);
+  EXPECT_TOKEN(Tokens[4], tok::colon, TT_VerilogBlockLabelColon);
 }
 
 } // namespace
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -66,6 +66,56 @@
   verifyFormat("x = 16'sd?;");
 }
 
+TEST_F(FormatTestVerilog, Block) {
+  verifyFormat("begin\n"
+   "  x = x;\n"
+   "end");
+  verifyFormat("begin : x\n"
+   "  x = x;\n"
+   "end : x");
+  verifyFormat("begin\n"
+   "  x = x;\n"
+   "  x = x;\n"
+   "end");
+  verifyFormat("fork\n"
+   "  x = x;\n"
+   "join");
+  verifyFormat("fork\n"
+   "  x = x;\n"
+   "join_any");
+  verifyFormat("fork\n"
+   "  x = x;\n"
+   "join_none");
+  verifyFormat("generate\n"
+   "  x = x;\n"
+   "endgenerate");
+  verifyFormat("generate : x\n"
+   "  x = x;\n"
+   "endgenerate : x");
+  // Nested blocks.
+  verifyFormat("begin\n"
+   "  begin\n"
+   "  end\n"
+   "end");
+  verifyFormat("begin : x\n"
+   "  begin\n"
+   "  end\n"
+   "end : x");
+  verifyFormat("begin : x\n"
+   "  begin : x\n"
+   "  end : x\n"
+   "end : x");
+  verifyFormat("begin\n"
+   "  begin : x\n"
+   "  end : x\n"
+   "end");
+  // Test that 'disable fork' and 'rand join' don't get mistaken as blocks.
+  verifyFormat("disable fork;\n"
+   "x = x;");
+  verifyFormat("rand join x x;\n"
+   "x = x;");
+}
+
 TEST_F(FormatTestVerilog, Delay) {
   // Delay by the default unit.
   verifyFormat("#0;");
@@ -129,10 +179,6 @@
"  x = x;\n"
"  x = x;\n"
"end");
-  verifyFormat("disable fork;\n"
-   "x = x;");
-  verifyFormat("rand join x x;\n"
-   "x = x;");
   verifyFormat("if (x) fork\n"
"  x = x;\n"
"join");
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1887,6 +1887,14 @@
 return;
   }
 
+  if (Style.isVerilog()) {
+if (Keywords.isVerilogBegin(*FormatTok)) {
+  parseBlock();
+  addUnwrappedLine();
+  return;
+}
+  }
+
   if (FormatTok->is(Keywords.kw_interface)) {
 if (parseStructLike())
   return;
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -947,6 +947,12 @@
   Tok->setType(TT_CSharpNamedArgumentColon);
   break;
 }
+  } else if (Style.isVerilog() && Tok->isNot(TT_BinaryOperator)) {
+if (Keywords.isVerilogEnd(*Tok->Previous) ||
+Keywords.isVerilogBegin(*Tok->Previous)) {
+  Tok->setType(TT_VerilogBlockLabelColon);
+}
+break;
   }
   if (Line.First->isOneOf(Keywords.kw_module, Keywords.kw_import) ||
   Line.First->startsSequence(tok::kw_export, Keywords.kw_module) ||
Index: clang/lib/Format/FormatToken.h
===
--- clang/lib/Format/FormatToken.h
+++ clang/lib/Format/FormatToken.h
@@ -135,6 +135,8 @@
   TYPE(UnaryOperator)

[PATCH] D128712: [clang-format] Handle Verilog modules

2022-06-28 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
sstwcw added reviewers: HazardyKnusperkeks, MyDeveloperDay, curdeius, owenpan.
Herald added a project: All.
sstwcw requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Now things inside hierarchies like modules and interfaces are
indented.  When the module header spans multiple lines, all except the
first line are indented as continuations.  We added the property
`IsContinuation` to mark lines that should be indented this way.

In order that the colons inside square brackets don't get labeled as
`TT_ObjCMethodExpr`, we added a check to only use this type when the
language is C#.  We used `isCpp` which returns true for C# and also when
the filename is not given and the program isn't sure what language it is
handling.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D128712

Files:
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/TokenAnnotator.h
  clang/lib/Format/UnwrappedLineFormatter.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/lib/Format/UnwrappedLineParser.h
  clang/unittests/Format/FormatTestVerilog.cpp
  clang/unittests/Format/TokenAnnotatorTest.cpp

Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -868,6 +868,13 @@
   ASSERT_EQ(Tokens.size(), 7u);
   EXPECT_TOKEN(Tokens[1], tok::colon, TT_VerilogBlockLabelColon);
   EXPECT_TOKEN(Tokens[4], tok::colon, TT_VerilogBlockLabelColon);
+  // Test that the dimension colon is annotated correctly.
+  Tokens = Annotate("var [1 : 0] x;");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::colon, TT_BitFieldColon);
+  Tokens = Annotate("extern function [1 : 0] x;");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::colon, TT_BitFieldColon);
 }
 
 } // namespace
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -139,6 +139,75 @@
 "x = x;"));
 }
 
+TEST_F(FormatTestVerilog, Hierarchy) {
+  verifyFormat("module x;\n"
+   "endmodule");
+  // Test that the end label is on the same line as the end keyword.
+  verifyFormat("module x;\n"
+   "endmodule : x");
+  // Test that things inside are indented.
+  verifyFormat("module x;\n"
+   "  generate\n"
+   "  endgenerate\n"
+   "endmodule");
+  verifyFormat("program x;\n"
+   "  generate\n"
+   "  endgenerate\n"
+   "endprogram");
+  verifyFormat("interface x;\n"
+   "  generate\n"
+   "  endgenerate\n"
+   "endinterface");
+  verifyFormat("task x;\n"
+   "  generate\n"
+   "  endgenerate\n"
+   "endtask");
+  verifyFormat("function x;\n"
+   "  generate\n"
+   "  endgenerate\n"
+   "endfunction");
+  verifyFormat("class x;\n"
+   "  generate\n"
+   "  endgenerate\n"
+   "endclass");
+  // Test that they nest.
+  verifyFormat("module x;\n"
+   "  program x;\n"
+   "program x;\n"
+   "endprogram\n"
+   "  endprogram\n"
+   "endmodule");
+  // Test that an extern declaration doesn't change the indentation.
+  verifyFormat("extern module x;\n"
+   "x = x;");
+  // Test complex headers
+  verifyFormat("extern module x\n"
+   "import x.x::x::*;\n"
+   "import x;\n"
+   "#(parameter x)\n"
+   "(output x);");
+  verifyFormat("module x\n"
+   "import x.x::x::*;\n"
+   "import x;\n"
+   "#(parameter x)\n"
+   "(output x);\n"
+   "  generate\n"
+   "  endgenerate\n"
+   "endmodule : x");
+  verifyFormat("virtual class x\n"
+   "(x)\n"
+   "extends x(x)\n"
+   "implements x, x, x;\n"
+   "  generate\n"
+   "  endgenerate\n"
+   "endclass : x\n");
+  verifyFormat("function automatic logic [1 : 0] x\n"
+   "(input x);\n"
+   "  generate\n"
+   "  endgenerate\n"
+   "endfunction : x");
+}
+
 TEST_F(FormatTestVerilog, If) {
   verifyFormat("if (x)\n"
"  x = x;");
Index: clang/lib/Format/UnwrappedLineParser.h
===
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -48,6 +48,10 @@
 
   bool MustBeDeclaration;
 
+  /// \c True if this line should b

[PATCH] D128713: [clang-format] Handle Verilog user-defined primitives

2022-06-28 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
sstwcw added reviewers: HazardyKnusperkeks, MyDeveloperDay, curdeius, owenpan.
Herald added a project: All.
sstwcw requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D128713

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

Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -441,5 +441,46 @@
   }
 }
 
+TEST_F(FormatTestVerilog, Primitive) {
+  verifyFormat("primitive multiplexer\n"
+   "(mux, control, dataA, dataB);\n"
+   "  output mux;\n"
+   "  input control, dataA, dataB;\n"
+   "  table\n"
+   "0 1 ? : 1;\n"
+   "0 0 ? : 0;\n"
+   "1 ? 1 : 1;\n"
+   "1 ? 0 : 0;\n"
+   "x 0 0 : 0;\n"
+   "x 1 1 : 1;\n"
+   "  endtable\n"
+   "endprimitive");
+  verifyFormat("primitive latch\n"
+   "(q, ena_, data);\n"
+   "  output q;\n"
+   "  reg q;\n"
+   "  input ena_, data;\n"
+   "  table\n"
+   "0 1 : ? : 1;\n"
+   "0 0 : ? : 0;\n"
+   "1 ? : ? : -;\n"
+   "? * : ? : -;\n"
+   "  endtable\n"
+   "endprimitive");
+  verifyFormat("primitive d\n"
+   "(q, clock, data);\n"
+   "  output q;\n"
+   "  reg q;\n"
+   "  input clock, data;\n"
+   "  table\n"
+   "(01) 0 : ? : 0;\n"
+   "(01) 1 : ? : 1;\n"
+   "(0?) 1 : 1 : 1;\n"
+   "(0?) 0 : 0 : 0;\n"
+   "(?0) ? : ? : -;\n"
+   "(?\?) ? : ? : -;\n"
+   "  endtable\n"
+   "endprimitive");
+}
 } // namespace format
 } // end namespace clang
Index: clang/lib/Format/UnwrappedLineParser.h
===
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -182,6 +182,7 @@
   // Returns the number of levels of indentation in addition to the normal 1
   // level for a block, used for indenting case labels.
   unsigned parseVerilogHierHeader();
+  void parseVerilogTable();
 
   // Used by addUnwrappedLine to denote whether to keep or remove a level
   // when resetting the line state.
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1912,6 +1912,10 @@
   }
 
   if (Style.isVerilog()) {
+if (FormatTok->is(Keywords.kw_table)) {
+  parseVerilogTable();
+  return;
+}
 if (Keywords.isVerilogBegin(*FormatTok) ||
 Keywords.isVerilogHier(*FormatTok)) {
   parseBlock();
@@ -4153,6 +4157,25 @@
   return AddLevels;
 }
 
+void UnwrappedLineParser::parseVerilogTable() {
+  assert(FormatTok->is(Keywords.kw_table));
+  nextToken(/*LevelDifference=*/1);
+  addUnwrappedLine();
+
+  unsigned InitialLevel = Line->Level++;
+  while (!eof() && !Keywords.isVerilogEnd(*FormatTok)) {
+FormatToken *Tok = FormatTok;
+nextToken();
+if (Tok->is(tok::semi))
+  addUnwrappedLine();
+else if (Tok->isOneOf(tok::star, tok::colon, tok::question, tok::minus))
+  Tok->setFinalizedType(TT_VerilogTableItem);
+  }
+  Line->Level = InitialLevel;
+  nextToken(/*LevelDifference=*/-1);
+  addUnwrappedLine();
+}
+
 LLVM_ATTRIBUTE_UNUSED static void printDebugInfo(const UnwrappedLine &Line,
  StringRef Prefix = "") {
   llvm::dbgs() << Prefix << "Line(" << Line.Level
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -917,6 +917,10 @@
   bool consumeToken() {
 FormatToken *Tok = CurrentToken;
 next();
+// In Verilog primitives' state tables, `:`, `?`, and `-` aren't normal
+// operators.
+if (Tok->is(TT_VerilogTableItem))
+  return true;
 switch (Tok->Tok.getKind()) {
 case tok::plus:
 case tok::minus:
@@ -3957,6 +3961,14 @@
   return true;
 }
   } else if (Style.isVerilog()) {
+// Add space between things in a primitive's state table unless in a
+// transition like `(0?)`.
+if ((Left.is(TT_VerilogTableItem) &&
+ !Right.isOneOf(tok::r_paren, tok::semi)) ||
+(

[PATCH] D128714: [clang-format] Handle Verilog case statements

2022-06-28 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
sstwcw added reviewers: HazardyKnusperkeks, MyDeveloperDay, curdeius, owenpan.
Herald added a project: All.
sstwcw requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

These statements are like switch statements in C, but without the 'case'
keyword in labels.

How labels are parsed.  In UnwrappedLineParser, the program tries to
parse a statement every time it sees a colon.  In TokenAnnotator, a
colon that isn't part of an expression is annotated as a label.

The token type `TT_GotoLabelColon` is added.  We did not include Verilog
in the name because we thought we would eventually have to fix the
problem that case labels in C can't contain ternary conditional
expressions and we would use that token type.

The style is like below.  Labels are on separate lines and indented by
default.  The linked style guide also has examples where labels and the
corresponding statements are on the same lines.  They are not supported
for now.

https://github.com/lowRISC/style-guides/blob/master/VerilogCodingStyle.md

  case (state_q)
StIdle:
  state_d = StA;
StA: begin
  state_d = StB;
end
  endcase


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D128714

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

Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -875,6 +875,21 @@
   Tokens = Annotate("extern function [1 : 0] x;");
   ASSERT_EQ(Tokens.size(), 10u) << Tokens;
   EXPECT_TOKEN(Tokens[4], tok::colon, TT_BitFieldColon);
+  // Test case labels and ternary operators.
+  Tokens = Annotate("case (x)\n"
+"  x:\n"
+"x;\n"
+"endcase\n");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::colon, TT_GotoLabelColon);
+  Tokens = Annotate("case (x)\n"
+"  x ? x : x:\n"
+"x;\n"
+"endcase\n");
+  ASSERT_EQ(Tokens.size(), 14u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::question, TT_ConditionalExpr);
+  EXPECT_TOKEN(Tokens[7], tok::colon, TT_ConditionalExpr);
+  EXPECT_TOKEN(Tokens[9], tok::colon, TT_GotoLabelColon);
 }
 
 } // namespace
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -116,6 +116,90 @@
"x = x;");
 }
 
+TEST_F(FormatTestVerilog, Case) {
+  verifyFormat("case (data)\n"
+   "endcase");
+  verifyFormat("casex (data)\n"
+   "endcase");
+  verifyFormat("casez (data)\n"
+   "endcase");
+  verifyFormat("case (data) inside\n"
+   "endcase");
+  verifyFormat("case (data)\n"
+   "  16'd0:\n"
+   "result = 10'b01;\n"
+   "endcase");
+  verifyFormat("case (data)\n"
+   "  :\n"
+   "result = 10'b01;\n"
+   "endcase");
+  // Test labels with multiple options.
+  verifyFormat("case (data)\n"
+   "  16'd0, 16'd1:\n"
+   "result = 10'b01;\n"
+   "endcase");
+  verifyFormat("case (data)\n"
+   "  16'd0, //\n"
+   "  16'd1:\n"
+   "result = 10'b01;\n"
+   "endcase");
+  // Test that blocks following labels are indented.
+  verifyFormat("case (data)\n"
+   "  16'd1: fork\n"
+   "result = 10'b10;\n"
+   "  join\n"
+   "endcase\n");
+  verifyFormat("case (data)\n"
+   "  16'd1: fork : x\n"
+   "result = 10'b10;\n"
+   "  join : x\n"
+   "endcase\n");
+  // Test default.
+  verifyFormat("case (data)\n"
+   "  default\n"
+   "result = 10'b10;\n"
+   "endcase");
+  verifyFormat("case (data)\n"
+   "  default:\n"
+   "result = 10'b10;\n"
+   "endcase");
+  // Test that question marks and colons don't get mistaken as labels.
+  verifyFormat("case (data)\n"
+   "  8'b1???:\n"
+   "instruction1(ir);\n"
+   "endcase");
+  verifyFormat("case (data)\n"
+   "  x ? 8'b1??? : 1:\n"
+   "instruction3(ir);\n"
+   "endcase");
+  // Test indention options.
+  auto Style = getLLVMStyle(FormatStyle::LK_

[PATCH] D121757: [clang-format] Take out common code for parsing blocks

2022-03-24 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 418061.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121757

Files:
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/lib/Format/UnwrappedLineParser.h


Index: clang/lib/Format/UnwrappedLineParser.h
===
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -123,6 +123,7 @@
   void parseUnbracedBody(bool CheckEOF = false);
   FormatToken *parseIfThenElse(IfStmtKind *IfKind, bool KeepBraces = false);
   void parseTryCatch();
+  void parseLoopBody(bool TryRemoveBraces, bool WrapRightBrace);
   void parseForOrWhileLoop();
   void parseDoWhile();
   void parseLabel(bool LeftAlignLabel = false);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -2699,6 +2699,29 @@
   } while (!eof());
 }
 
+void UnwrappedLineParser::parseLoopBody(bool TryRemoveBraces,
+bool WrapRightBrace) {
+  keepAncestorBraces();
+
+  if (FormatTok->is(tok::l_brace)) {
+CompoundStatementIndenter Indenter(this, Style, Line->Level);
+FormatToken *LeftBrace = FormatTok;
+parseBlock();
+if (TryRemoveBraces) {
+  assert(!NestedTooDeep.empty());
+  if (!NestedTooDeep.back())
+markOptionalBraces(LeftBrace);
+}
+if (WrapRightBrace)
+  addUnwrappedLine();
+  } else {
+parseUnbracedBody();
+  }
+
+  if (TryRemoveBraces)
+NestedTooDeep.pop_back();
+}
+
 void UnwrappedLineParser::parseForOrWhileLoop() {
   assert(FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) &&
  "'for', 'while' or foreach macro expected");
@@ -2717,43 +2740,15 @@
 parseParens();
   }
 
-  keepAncestorBraces();
-
-  if (FormatTok->is(tok::l_brace)) {
-FormatToken *LeftBrace = FormatTok;
-CompoundStatementIndenter Indenter(this, Style, Line->Level);
-parseBlock();
-if (Style.RemoveBracesLLVM) {
-  assert(!NestedTooDeep.empty());
-  if (!NestedTooDeep.back())
-markOptionalBraces(LeftBrace);
-}
-addUnwrappedLine();
-  } else {
-parseUnbracedBody();
-  }
-
-  if (Style.RemoveBracesLLVM)
-NestedTooDeep.pop_back();
+  parseLoopBody(/*TryRemoveBraces=*/Style.RemoveBracesLLVM,
+/*WrapRightBrace=*/true);
 }
 
 void UnwrappedLineParser::parseDoWhile() {
   assert(FormatTok->is(tok::kw_do) && "'do' expected");
   nextToken();
 
-  keepAncestorBraces();
-
-  if (FormatTok->is(tok::l_brace)) {
-CompoundStatementIndenter Indenter(this, Style, Line->Level);
-parseBlock();
-if (Style.BraceWrapping.BeforeWhile)
-  addUnwrappedLine();
-  } else {
-parseUnbracedBody();
-  }
-
-  if (Style.RemoveBracesLLVM)
-NestedTooDeep.pop_back();
+  parseLoopBody(/*BracesAreoptional=*/false, Style.BraceWrapping.BeforeWhile);
 
   // FIXME: Add error handling.
   if (!FormatTok->is(tok::kw_while)) {


Index: clang/lib/Format/UnwrappedLineParser.h
===
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -123,6 +123,7 @@
   void parseUnbracedBody(bool CheckEOF = false);
   FormatToken *parseIfThenElse(IfStmtKind *IfKind, bool KeepBraces = false);
   void parseTryCatch();
+  void parseLoopBody(bool TryRemoveBraces, bool WrapRightBrace);
   void parseForOrWhileLoop();
   void parseDoWhile();
   void parseLabel(bool LeftAlignLabel = false);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -2699,6 +2699,29 @@
   } while (!eof());
 }
 
+void UnwrappedLineParser::parseLoopBody(bool TryRemoveBraces,
+bool WrapRightBrace) {
+  keepAncestorBraces();
+
+  if (FormatTok->is(tok::l_brace)) {
+CompoundStatementIndenter Indenter(this, Style, Line->Level);
+FormatToken *LeftBrace = FormatTok;
+parseBlock();
+if (TryRemoveBraces) {
+  assert(!NestedTooDeep.empty());
+  if (!NestedTooDeep.back())
+markOptionalBraces(LeftBrace);
+}
+if (WrapRightBrace)
+  addUnwrappedLine();
+  } else {
+parseUnbracedBody();
+  }
+
+  if (TryRemoveBraces)
+NestedTooDeep.pop_back();
+}
+
 void UnwrappedLineParser::parseForOrWhileLoop() {
   assert(FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) &&
  "'for', 'while' or foreach macro expected");
@@ -2717,43 +2740,15 @@
 parseParens();
   }
 
-  keepAncestorBraces();
-
-  if (FormatTok->is(tok::l_brace)) {
-FormatToken *LeftBrace = FormatTok;
-CompoundStatementIndenter Indenter(this, Style, Line->Level);
-parseBlock();
-if (Style.RemoveBrac

[PATCH] D121756: [clang-format] Clean up code looking for if statements

2022-03-24 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 418071.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121756

Files:
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  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
@@ -660,6 +660,49 @@
   EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_ObjCBlockLBrace);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsConditionParen) {
+  auto Tokens = annotate("if (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+  Tokens = annotate("if constexpr (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_ConditionLParen);
+  Tokens = annotate("if CONSTEXPR (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_ConditionLParen);
+
+  // The parentheses following for is not TT_ConditionLParen, because inside is
+  // not just a condition.
+  Tokens = annotate("for (;;) {\n}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown);
+  Tokens = annotate("foreach (Item *item, itemlist) {\n}");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown);
+  Tokens = annotate("Q_FOREACH (Item *item, itemlist) {\n}");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown);
+  Tokens = annotate("BOOST_FOREACH (Item *item, itemlist) {\n}");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown);
+  Tokens = annotate("try {\n"
+"} catch (Exception &bar) {\n"
+"}");
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_Unknown);
+
+  Tokens = annotate("while (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+  Tokens = annotate("do {\n} while (true);");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_ConditionLParen);
+
+  Tokens = annotate("switch (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+}
+
 } // namespace
 } // namespace format
 } // namespace clang
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -3131,6 +3131,15 @@
   Style.ColumnLimit =
   20; // to concentrate at brace wrapping, not line wrap due to column limit
 
+  verifyFormat("if (xx\n"
+   ".xx)\n"
+   "  continue;",
+   Style);
+  verifyFormat("while (xx\n"
+   "   .xx)\n"
+   "  continue;",
+   Style);
+
   Style.BraceWrapping.BeforeElse = true;
   EXPECT_EQ(
   "if (foo) {\n"
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -2408,8 +2408,10 @@
   } else {
 if (FormatTok->isOneOf(tok::kw_constexpr, tok::identifier))
   nextToken();
-if (FormatTok->is(tok::l_paren))
+if (FormatTok->is(tok::l_paren)) {
+  FormatTok->setFinalizedType(TT_ConditionLParen);
   parseParens();
+}
   }
   HandleAttributes();
 
@@ -2700,14 +2702,20 @@
 void UnwrappedLineParser::parseForOrWhileLoop() {
   assert(FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) &&
  "'for', 'while' or foreach macro expected");
+  // Those that begin with a for require special treatment because inside the
+  // parentheses is not an expression.
+  bool ParensAreExpr = FormatTok->is(tok::kw_while);
   nextToken();
   // JS' for await ( ...
   if (Style.isJavaScript() && FormatTok->is(Keywords.kw_await))
 nextToken();
   if (Style.isCpp() && FormatTok->is(tok::kw_co_await))
 nextToken();
-  if (FormatTok->is(tok::l_paren))
+  if (FormatTok->is(tok::l_paren)) {
+if (ParensAreExpr)
+  FormatTok->setFinalizedType(TT_ConditionLParen);
 parseParens();
+  }
 
   keepAncestorBraces();
 
@@ -2759,6 +2767,9 @@
 ++Line->Level;
 
   nextToken();
+  // FIXME: Add error handling.
+  if (FormatTok->is(tok::l_paren))
+FormatTok->setFinalizedType(TT_ConditionLParen);
   parseStructuralElement();
 }
 
@@ -2813,8 +2824,10 @@
 void UnwrappedLineParser::parseSwitch() {
   assert(FormatT

[PATCH] D121756: [clang-format] Clean up code looking for if statements

2022-03-24 Thread sstwcw via Phabricator via cfe-commits
sstwcw marked 5 inline comments as done.
sstwcw added inline comments.



Comment at: clang/lib/Format/ContinuationIndenter.cpp:749
+  if (Current.isNot(tok::comment) &&
+  Previous.isConditionLParen(/*IncludeSpecial=*/true)) {
 // Treat the condition inside an if as if it was a second function

owenpan wrote:
> We only checked `for` and `if` before. Now you are also checking `while` and 
> `switch`?
Yes, I am.  Please see the diff and tell me whether `while` and `switch` should 
be checked here.



Comment at: clang/lib/Format/FormatToken.h:538
+ tok::kw_for, tok::kw_catch)) ||
+Prev->isOneOf(tok::kw_if, tok::kw_while, tok::kw_switch,
+  tok::kw_case, tok::kw_constexpr));

MyDeveloperDay wrote:
> What about MacroIf
What's that?



Comment at: clang/lib/Format/TokenAnnotator.cpp:2988
 return 100;
-  if (Left.is(tok::l_paren) && Left.Previous &&
-  (Left.Previous->is(tok::kw_for) || Left.Previous->isIf()))
+  if (Left.isConditionLParen(/*IncludeSpecial=*/true))
 return 1000;

MyDeveloperDay wrote:
> There has to be a missed unit test here..this condition before only handled 
> if and for
> 
> Did you run the regression suite as well as the unit tests?
I added a test.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121756

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


[PATCH] D121756: [clang-format] Clean up code looking for if statements

2022-03-24 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 418073.
sstwcw marked an inline comment as done.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121756

Files:
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  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
@@ -660,6 +660,49 @@
   EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_ObjCBlockLBrace);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsConditionParen) {
+  auto Tokens = annotate("if (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+  Tokens = annotate("if constexpr (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_ConditionLParen);
+  Tokens = annotate("if CONSTEXPR (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_ConditionLParen);
+
+  // The parentheses following for is not TT_ConditionLParen, because inside is
+  // not just a condition.
+  Tokens = annotate("for (;;) {\n}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown);
+  Tokens = annotate("foreach (Item *item, itemlist) {\n}");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown);
+  Tokens = annotate("Q_FOREACH (Item *item, itemlist) {\n}");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown);
+  Tokens = annotate("BOOST_FOREACH (Item *item, itemlist) {\n}");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown);
+  Tokens = annotate("try {\n"
+"} catch (Exception &bar) {\n"
+"}");
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_Unknown);
+
+  Tokens = annotate("while (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+  Tokens = annotate("do {\n} while (true);");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_ConditionLParen);
+
+  Tokens = annotate("switch (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+}
+
 } // namespace
 } // namespace format
 } // namespace clang
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -3131,6 +3131,15 @@
   Style.ColumnLimit =
   20; // to concentrate at brace wrapping, not line wrap due to column limit
 
+  verifyFormat("if (xx\n"
+   ".xx)\n"
+   "  continue;",
+   Style);
+  verifyFormat("while (xx\n"
+   "   .xx)\n"
+   "  continue;",
+   Style);
+
   Style.BraceWrapping.BeforeElse = true;
   EXPECT_EQ(
   "if (foo) {\n"
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -2408,8 +2408,10 @@
   } else {
 if (FormatTok->isOneOf(tok::kw_constexpr, tok::identifier))
   nextToken();
-if (FormatTok->is(tok::l_paren))
+if (FormatTok->is(tok::l_paren)) {
+  FormatTok->setFinalizedType(TT_ConditionLParen);
   parseParens();
+}
   }
   HandleAttributes();
 
@@ -2700,14 +2702,20 @@
 void UnwrappedLineParser::parseForOrWhileLoop() {
   assert(FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) &&
  "'for', 'while' or foreach macro expected");
+  const FormatToken &FirstTok = *FormatTok;
   nextToken();
   // JS' for await ( ...
   if (Style.isJavaScript() && FormatTok->is(Keywords.kw_await))
 nextToken();
   if (Style.isCpp() && FormatTok->is(tok::kw_co_await))
 nextToken();
-  if (FormatTok->is(tok::l_paren))
+  if (FormatTok->is(tok::l_paren)) {
+// Those that begin with a for require special treatment because inside the
+// parentheses is not an expression.
+if (FirstTok.is(tok::kw_while))
+  FormatTok->setFinalizedType(TT_ConditionLParen);
 parseParens();
+  }
 
   keepAncestorBraces();
 
@@ -2759,6 +2767,9 @@
 ++Line->Level;
 
   nextToken();
+  // FIXME: Add error handling.
+  if (FormatTok->is(tok::l_paren))
+FormatTok->setFinalizedType(TT_ConditionLParen);
   parseStructuralElement();
 }
 
@@ -2813,8 +2824,10 @@
 void Unwra

[PATCH] D121756: [clang-format] Clean up code looking for if statements

2022-03-24 Thread sstwcw via Phabricator via cfe-commits
sstwcw marked 2 inline comments as done.
sstwcw added a comment.

This is how checking for `while` changes behavior.

  diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp
  index 68b2a40d48c5..3f811fee9bad 100644
  --- a/flang/lib/Evaluate/tools.cpp
  +++ b/flang/lib/Evaluate/tools.cpp
  @@ -868,8 +868,8 @@ bool HasVectorSubscript(const Expr &expr) {
   parser::Message *AttachDeclaration(
   parser::Message &message, const Symbol &symbol) {
 const Symbol *unhosted{&symbol};
  -  while (
  -  const auto *assoc{unhosted->detailsIf()}) 
{
  +  while (const auto *assoc{
  + unhosted->detailsIf()}) {
   unhosted = &assoc->symbol();
 }
 if (const auto *binding{
  diff --git a/flang/lib/Semantics/data-to-inits.cpp 
b/flang/lib/Semantics/data-to-inits.cpp
  index 6bdbf5f6549f..aa8188656bcb 100644
  --- a/flang/lib/Semantics/data-to-inits.cpp
  +++ b/flang/lib/Semantics/data-to-inits.cpp
  @@ -407,8 +407,8 @@ bool DataInitializationCompiler::InitElement(
   DescribeElement(), designatorType->AsFortran());
 }
 auto folded{evaluate::Fold(context, std::move(converted->first))};
  -  switch (GetImage().Add(
  -  offsetSymbol.offset(), offsetSymbol.size(), folded, context)) {
  +  switch (GetImage().Add(offsetSymbol.offset(), offsetSymbol.size(), 
folded,
  +  context)) {
 case evaluate::InitialImage::Ok:
   return true;
 case evaluate::InitialImage::NotAConstant:
  diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp
  index 3391665786d5..f1b86a133f1c 100644
  --- a/lldb/source/API/SBDebugger.cpp
  +++ b/lldb/source/API/SBDebugger.cpp
  @@ -526,7 +526,7 @@ void SBDebugger::HandleCommand(const char *command) {
   EventSP event_sp;
   ListenerSP lldb_listener_sp = m_opaque_sp->GetListener();
   while (lldb_listener_sp->GetEventForBroadcaster(
  -process_sp.get(), event_sp, std::chrono::seconds(0))) {
  +   process_sp.get(), event_sp, std::chrono::seconds(0))) {
 SBEvent event(event_sp);
 HandleProcessEvent(process, event, GetOutputFile(), 
GetErrorFile());
   }
  diff --git a/openmp/runtime/src/kmp_alloc.cpp 
b/openmp/runtime/src/kmp_alloc.cpp
  index 0f76906714b1..319c3e779fda 100644
  --- a/openmp/runtime/src/kmp_alloc.cpp
  +++ b/openmp/runtime/src/kmp_alloc.cpp
  @@ -2051,7 +2051,8 @@ void *___kmp_fast_allocate(kmp_info_t *this_thr, size_t 
size KMP_SRC_LOC_DECL) {
   // threads only)
   // pop the head of the sync free list, push NULL instead
   while (!KMP_COMPARE_AND_STORE_PTR(
  -&this_thr->th.th_free_lists[index].th_free_list_sync, ptr, nullptr)) 
{
  +   &this_thr->th.th_free_lists[index].th_free_list_sync, ptr,
  +   nullptr)) {
 KMP_CPU_PAUSE();
 ptr = 
TCR_SYNC_PTR(this_thr->th.th_free_lists[index].th_free_list_sync);
   }
  @@ -2178,7 +2179,8 @@ void ___kmp_fast_free(kmp_info_t *this_thr, void *ptr 
KMP_SRC_LOC_DECL) {
   *((void **)tail) = old_ptr;
   
   while (!KMP_COMPARE_AND_STORE_PTR(
  -&q_th->th.th_free_lists[index].th_free_list_sync, old_ptr, 
head)) {
  +   &q_th->th.th_free_lists[index].th_free_list_sync, old_ptr,
  +   head)) {
 KMP_CPU_PAUSE();
 old_ptr = TCR_PTR(q_th->th.th_free_lists[index].th_free_list_sync);
 *((void **)tail) = old_ptr;
  diff --git a/openmp/runtime/src/kmp_atomic.cpp 
b/openmp/runtime/src/kmp_atomic.cpp
  index 21c2c60bfb60..79b8373319e4 100644
  --- a/openmp/runtime/src/kmp_atomic.cpp
  +++ b/openmp/runtime/src/kmp_atomic.cpp
  @@ -793,8 +793,9 @@ static inline kmp_cmplx128_a16_t 
operator/(kmp_cmplx128_a16_t &lhs,
   old_value = *(TYPE volatile *)lhs;   
  \
   new_value = (TYPE)(old_value OP rhs);
  \
   while (!KMP_COMPARE_AND_STORE_ACQ##BITS( 
  \
  -(kmp_int##BITS *)lhs, *VOLATILE_CAST(kmp_int##BITS *) & old_value,   
  \
  -*VOLATILE_CAST(kmp_int##BITS *) & new_value)) {  
  \
  +   (kmp_int##BITS *)lhs, 
  \
  +   *VOLATILE_CAST(kmp_int##BITS *) & old_value,  
  \
  +   *VOLATILE_CAST(kmp_int##BITS *) & new_value)) {   
  \
 KMP_DO_PAUSE;  
  \

  \
 old_value = *(TYPE volatile *)lhs; 
  \
  @@ -821,8 +822,9 @@ static inline kmp_cmplx128_a16_t 
operator/(kmp_cmplx128_a16_t &lhs,
   *old_value.vvv = *(volatile kmp_int##BITS *)lhs; 
  \
   new_value.cmp = (TYPE)(old_value.cmp OP rhs);  

[PATCH] D121757: [clang-format] Take out common code for parsing blocks

2022-03-24 Thread sstwcw via Phabricator via cfe-commits
sstwcw marked 9 inline comments as done.
sstwcw added a comment.

I tried formatting the files in `clang-formatted-files.txt`. Besides the files 
in the list that get changed when formatted with the program built from `main`, 
none gets changed when I format them with the program built from this patch, 
whether or not `parseSwitch` is modified.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121757

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


[PATCH] D121756: [clang-format] Clean up code looking for if statements NFC

2022-03-29 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 419006.
sstwcw retitled this revision from "[clang-format] Clean up code looking for if 
statements" to "[clang-format] Clean up code looking for if statements NFC".

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121756

Files:
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  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
@@ -660,6 +660,49 @@
   EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_ObjCBlockLBrace);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsConditionParen) {
+  auto Tokens = annotate("if (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+  Tokens = annotate("if constexpr (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_ConditionLParen);
+  Tokens = annotate("if CONSTEXPR (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_ConditionLParen);
+
+  // The parentheses following for is not TT_ConditionLParen, because inside is
+  // not just a condition.
+  Tokens = annotate("for (;;) {\n}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown);
+  Tokens = annotate("foreach (Item *item, itemlist) {\n}");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown);
+  Tokens = annotate("Q_FOREACH (Item *item, itemlist) {\n}");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown);
+  Tokens = annotate("BOOST_FOREACH (Item *item, itemlist) {\n}");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown);
+  Tokens = annotate("try {\n"
+"} catch (Exception &bar) {\n"
+"}");
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_Unknown);
+
+  Tokens = annotate("while (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+  Tokens = annotate("do {\n} while (true);");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_ConditionLParen);
+
+  Tokens = annotate("switch (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+}
+
 } // namespace
 } // namespace format
 } // namespace clang
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -3131,6 +3131,15 @@
   Style.ColumnLimit =
   20; // to concentrate at brace wrapping, not line wrap due to column limit
 
+  verifyFormat("if (xx\n"
+   ".xx)\n"
+   "  continue;",
+   Style);
+  verifyFormat("while (xx\n"
+   "   .xx)\n"
+   "  continue;",
+   Style);
+
   Style.BraceWrapping.BeforeElse = true;
   EXPECT_EQ(
   "if (foo) {\n"
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -2408,8 +2408,10 @@
   } else {
 if (FormatTok->isOneOf(tok::kw_constexpr, tok::identifier))
   nextToken();
-if (FormatTok->is(tok::l_paren))
+if (FormatTok->is(tok::l_paren)) {
+  FormatTok->setFinalizedType(TT_ConditionLParen);
   parseParens();
+}
   }
   HandleAttributes();
 
@@ -2700,14 +2702,20 @@
 void UnwrappedLineParser::parseForOrWhileLoop() {
   assert(FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) &&
  "'for', 'while' or foreach macro expected");
+  const FormatToken &FirstTok = *FormatTok;
   nextToken();
   // JS' for await ( ...
   if (Style.isJavaScript() && FormatTok->is(Keywords.kw_await))
 nextToken();
   if (Style.isCpp() && FormatTok->is(tok::kw_co_await))
 nextToken();
-  if (FormatTok->is(tok::l_paren))
+  if (FormatTok->is(tok::l_paren)) {
+// Those that begin with a for require special treatment because inside the
+// parentheses is not an expression.
+if (FirstTok.is(tok::kw_while))
+  FormatTok->setFinalizedType(TT_ConditionLParen);
 parseParens();
+  }
 
   keepAncestorBraces();
 
@@ -2759,6 +2767,9 @@
 ++Line->Level;
 
   nextToken();
+  // FIXME: Add error handling.
+  if (FormatTok->is(tok::l_paren))
+FormatTok->setFinalizedType(TT_ConditionLPar

[PATCH] D121754: [clang-format] Refactor determineStarAmpUsage NFC

2022-03-29 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 419007.
sstwcw retitled this revision from "[clang-format] Refactor 
determineStarAmpUsage" to "[clang-format] Refactor determineStarAmpUsage NFC".

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121754

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
@@ -78,6 +78,102 @@
   EXPECT_EQ(Tokens.size(), 21u) << Tokens;
   EXPECT_TOKEN(Tokens[10], tok::ampamp, TT_BinaryOperator);
   EXPECT_TOKEN(Tokens[11], tok::star, TT_UnaryOperator);
+
+  Tokens = annotate("case *x:");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::star, TT_UnaryOperator);
+  Tokens = annotate("case &x:");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::amp, TT_UnaryOperator);
+}
+
+TEST_F(TokenAnnotatorTest, UnderstandsUsesOfPlusAndMinus) {
+  auto Tokens = annotate("x - 0");
+  ASSERT_EQ(Tokens.size(), 4u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_BinaryOperator);
+  Tokens = annotate("0 + 0");
+  ASSERT_EQ(Tokens.size(), 4u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_BinaryOperator);
+  Tokens = annotate("x + +0");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("x ? -0 : +0");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator);
+  EXPECT_TOKEN(Tokens[5], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("(-0)");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("0, -0");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("for (; -1;) {\n}");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("x = -1;");
+  ASSERT_EQ(Tokens.size(), 6u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("x[-1]");
+  ASSERT_EQ(Tokens.size(), 6u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("x = {-1};");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("case -x:");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("co_await -x;");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("co_return -x;");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("co_yield -x;");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("delete -x;");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("return -x;");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("throw -x;");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("sizeof -x");
+  ASSERT_EQ(Tokens.size(), 4u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("co_await +x;");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("co_return +x;");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("co_yield +x;");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("delete +x;");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("return +x;");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("throw +x;");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("sizeof +x");
+  ASSERT_EQ(Tokens.size(), 4u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("(int)-x");
+  ASSERT_EQ(Tokens.size(), 6u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("(-x)");
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("!+x");
+  ASSERT_EQ(Tokens.size(), 4u) << Tokens;
+

[PATCH] D121757: [clang-format] Take out common code for parsing blocks NFC

2022-03-29 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 419009.
sstwcw retitled this revision from "[clang-format] Take out common code for 
parsing blocks" to "[clang-format] Take out common code for parsing blocks NFC".

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121757

Files:
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/lib/Format/UnwrappedLineParser.h


Index: clang/lib/Format/UnwrappedLineParser.h
===
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -123,6 +123,7 @@
   void parseUnbracedBody(bool CheckEOF = false);
   FormatToken *parseIfThenElse(IfStmtKind *IfKind, bool KeepBraces = false);
   void parseTryCatch();
+  void parseLoopBody(bool TryRemoveBraces, bool WrapRightBrace);
   void parseForOrWhileLoop();
   void parseDoWhile();
   void parseLabel(bool LeftAlignLabel = false);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -2699,6 +2699,29 @@
   } while (!eof());
 }
 
+void UnwrappedLineParser::parseLoopBody(bool TryRemoveBraces,
+bool WrapRightBrace) {
+  keepAncestorBraces();
+
+  if (FormatTok->is(tok::l_brace)) {
+CompoundStatementIndenter Indenter(this, Style, Line->Level);
+FormatToken *LeftBrace = FormatTok;
+parseBlock();
+if (TryRemoveBraces) {
+  assert(!NestedTooDeep.empty());
+  if (!NestedTooDeep.back())
+markOptionalBraces(LeftBrace);
+}
+if (WrapRightBrace)
+  addUnwrappedLine();
+  } else {
+parseUnbracedBody();
+  }
+
+  if (TryRemoveBraces)
+NestedTooDeep.pop_back();
+}
+
 void UnwrappedLineParser::parseForOrWhileLoop() {
   assert(FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) &&
  "'for', 'while' or foreach macro expected");
@@ -2717,43 +2740,15 @@
 parseParens();
   }
 
-  keepAncestorBraces();
-
-  if (FormatTok->is(tok::l_brace)) {
-FormatToken *LeftBrace = FormatTok;
-CompoundStatementIndenter Indenter(this, Style, Line->Level);
-parseBlock();
-if (Style.RemoveBracesLLVM) {
-  assert(!NestedTooDeep.empty());
-  if (!NestedTooDeep.back())
-markOptionalBraces(LeftBrace);
-}
-addUnwrappedLine();
-  } else {
-parseUnbracedBody();
-  }
-
-  if (Style.RemoveBracesLLVM)
-NestedTooDeep.pop_back();
+  parseLoopBody(/*TryRemoveBraces=*/Style.RemoveBracesLLVM,
+/*WrapRightBrace=*/true);
 }
 
 void UnwrappedLineParser::parseDoWhile() {
   assert(FormatTok->is(tok::kw_do) && "'do' expected");
   nextToken();
 
-  keepAncestorBraces();
-
-  if (FormatTok->is(tok::l_brace)) {
-CompoundStatementIndenter Indenter(this, Style, Line->Level);
-parseBlock();
-if (Style.BraceWrapping.BeforeWhile)
-  addUnwrappedLine();
-  } else {
-parseUnbracedBody();
-  }
-
-  if (Style.RemoveBracesLLVM)
-NestedTooDeep.pop_back();
+  parseLoopBody(/*BracesAreoptional=*/false, Style.BraceWrapping.BeforeWhile);
 
   // FIXME: Add error handling.
   if (!FormatTok->is(tok::kw_while)) {


Index: clang/lib/Format/UnwrappedLineParser.h
===
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -123,6 +123,7 @@
   void parseUnbracedBody(bool CheckEOF = false);
   FormatToken *parseIfThenElse(IfStmtKind *IfKind, bool KeepBraces = false);
   void parseTryCatch();
+  void parseLoopBody(bool TryRemoveBraces, bool WrapRightBrace);
   void parseForOrWhileLoop();
   void parseDoWhile();
   void parseLabel(bool LeftAlignLabel = false);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -2699,6 +2699,29 @@
   } while (!eof());
 }
 
+void UnwrappedLineParser::parseLoopBody(bool TryRemoveBraces,
+bool WrapRightBrace) {
+  keepAncestorBraces();
+
+  if (FormatTok->is(tok::l_brace)) {
+CompoundStatementIndenter Indenter(this, Style, Line->Level);
+FormatToken *LeftBrace = FormatTok;
+parseBlock();
+if (TryRemoveBraces) {
+  assert(!NestedTooDeep.empty());
+  if (!NestedTooDeep.back())
+markOptionalBraces(LeftBrace);
+}
+if (WrapRightBrace)
+  addUnwrappedLine();
+  } else {
+parseUnbracedBody();
+  }
+
+  if (TryRemoveBraces)
+NestedTooDeep.pop_back();
+}
+
 void UnwrappedLineParser::parseForOrWhileLoop() {
   assert(FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) &&
  "'for', 'while' or foreach macro expected");
@@ -2717,43 +2740,15 @@
 parseParens();
   }
 
-  keepAncestorBraces();
-
-  if (FormatTok->is(tok::l_brac

[PATCH] D121757: [clang-format] Take out common code for parsing blocks NFC

2022-03-29 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

I ran check-clang after formatting the entire code base with the new version.  
It turned out it did break some tests.  It seems to be because it messed up 
these comments.

  diff --git a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.fallthrough/p1.cpp 
b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.fallthrough/p1.cpp
  index 7a8d756b09fd..53b2ddd12885 100644
  --- a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.fallthrough/p1.cpp
  +++ b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.fallthrough/p1.cpp
  @@ -33,8 +33,8 @@ void f(int n) {
 case 6:
   do {
 [[fallthrough]];
  -} while (
  -false); // expected-error {{does not directly precede switch label}}
  +} while (false); // expected-error {{does not directly precede switch
  + // label}}
 case 7:
   switch (n) {
   case 0:

Now I have undone the parts that changed this.  Formatting with the new version 
yields the same result as formatting with the program built from the main 
branch, whether with or without the `InsertBraces` option, except for this one 
line:

  diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp 
b/clang/test/SemaCXX/constant-expression-cxx11.cpp
  index 4c6b6da9e415..4d063378f37c 100644
  --- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
  +++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
  @@ -1115,7 +1115,7 @@ static_assert(check(S(5), 11), "");
   namespace PR14171 {
   
   struct X {
  -  constexpr(operator int)() const { return 0; }
  +  constexpr (operator int)() const { return 0; }
   };
   static_assert(X() == 0, "");


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121757

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


[PATCH] D121906: [clang-format] Indent import statements in JavaScript.

2022-03-30 Thread sstwcw 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 rGf6740fe483e9: [clang-format] Indent import statements in 
JavaScript. (authored by sstwcw).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121906

Files:
  clang/lib/Format/UnwrappedLineFormatter.cpp
  clang/unittests/Format/FormatTestJS.cpp


Index: clang/unittests/Format/FormatTestJS.cpp
===
--- clang/unittests/Format/FormatTestJS.cpp
+++ clang/unittests/Format/FormatTestJS.cpp
@@ -1875,6 +1875,11 @@
   " myX} from 'm';");
   verifyFormat("import * as lib from 'some/module.js';");
   verifyFormat("var x = {import: 1};\nx.import = 2;");
+  // Ensure an import statement inside a block is at the correct level.
+  verifyFormat("function() {\n"
+   "  var x;\n"
+   "  import 'some/module.js';\n"
+   "}");
 
   verifyFormat("export function fn() {\n"
"  return 'fn';\n"
Index: clang/lib/Format/UnwrappedLineFormatter.cpp
===
--- clang/lib/Format/UnwrappedLineFormatter.cpp
+++ clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -1431,8 +1431,10 @@
   if (Newlines)
 Indent = NewlineIndent;
 
-  // Preprocessor directives get indented before the hash only if specified
-  if (Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
+  // Preprocessor directives get indented before the hash only if specified. In
+  // Javascript import statements are indented like normal statements.
+  if (!Style.isJavaScript() &&
+  Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
   (Line.Type == LT_PreprocessorDirective ||
Line.Type == LT_ImportStatement))
 Indent = 0;


Index: clang/unittests/Format/FormatTestJS.cpp
===
--- clang/unittests/Format/FormatTestJS.cpp
+++ clang/unittests/Format/FormatTestJS.cpp
@@ -1875,6 +1875,11 @@
   " myX} from 'm';");
   verifyFormat("import * as lib from 'some/module.js';");
   verifyFormat("var x = {import: 1};\nx.import = 2;");
+  // Ensure an import statement inside a block is at the correct level.
+  verifyFormat("function() {\n"
+   "  var x;\n"
+   "  import 'some/module.js';\n"
+   "}");
 
   verifyFormat("export function fn() {\n"
"  return 'fn';\n"
Index: clang/lib/Format/UnwrappedLineFormatter.cpp
===
--- clang/lib/Format/UnwrappedLineFormatter.cpp
+++ clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -1431,8 +1431,10 @@
   if (Newlines)
 Indent = NewlineIndent;
 
-  // Preprocessor directives get indented before the hash only if specified
-  if (Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
+  // Preprocessor directives get indented before the hash only if specified. In
+  // Javascript import statements are indented like normal statements.
+  if (!Style.isJavaScript() &&
+  Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
   (Line.Type == LT_PreprocessorDirective ||
Line.Type == LT_ImportStatement))
 Indent = 0;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D121754: [clang-format] Refactor determineStarAmpUsage NFC

2022-03-30 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

Maybe it's because I removed the final empty line when I pasted the diff as I 
thought that LF was a line terminator instead of a line separator.  I will try 
using arc from now on.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121754

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


[PATCH] D121756: [clang-format] Clean up code looking for if statements

2022-04-03 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 420031.
sstwcw retitled this revision from "[clang-format] Clean up code looking for if 
statements NFC" to "[clang-format] Clean up code looking for if statements".
sstwcw edited the summary of this revision.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121756

Files:
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  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
@@ -646,6 +646,55 @@
   EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_ObjCBlockLBrace);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsConditionParen) {
+  auto Tokens = annotate("if (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+  Tokens = annotate("if constexpr (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_ConditionLParen);
+  Tokens = annotate("if CONSTEXPR (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_ConditionLParen);
+
+  // The parentheses following for is not TT_ConditionLParen, because inside is
+  // not just a condition.
+  Tokens = annotate("for (;;) {\n}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown);
+  Tokens = annotate("foreach (Item *item, itemlist) {\n}");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown);
+  Tokens = annotate("Q_FOREACH (Item *item, itemlist) {\n}");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown);
+  Tokens = annotate("BOOST_FOREACH (Item *item, itemlist) {\n}");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown);
+  Tokens = annotate("try {\n"
+"} catch (Exception &bar) {\n"
+"}");
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_Unknown);
+
+  Tokens = annotate("while (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+  Tokens = annotate("do {\n} while (true);");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_ConditionLParen);
+
+  Tokens = annotate("switch (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+  Tokens = annotate("switch (x * x) {\n}");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::star, TT_BinaryOperator);
+  Tokens = annotate("switch (x & x) {\n}");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::amp, TT_BinaryOperator);
+}
+
 } // namespace
 } // namespace format
 } // namespace clang
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2628,6 +2628,10 @@
"[[likely]] case 2:\n"
"  return;\n"
"}");
+  verifyFormat("switch (x * x) { //\n"
+   "}");
+  verifyFormat("switch (x & x) { //\n"
+   "}");
   FormatStyle Attributes = getLLVMStyle();
   Attributes.AttributeMacros.push_back("LIKELY");
   Attributes.AttributeMacros.push_back("OTHER_LIKELY");
@@ -3177,6 +3181,15 @@
   Style.ColumnLimit =
   20; // to concentrate at brace wrapping, not line wrap due to column limit
 
+  verifyFormat("if (xx\n"
+   ".xx)\n"
+   "  continue;",
+   Style);
+  verifyFormat("while (xx\n"
+   "   .xx)\n"
+   "  continue;",
+   Style);
+
   Style.BraceWrapping.BeforeElse = true;
   EXPECT_EQ(
   "if (foo) {\n"
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -2422,8 +2422,10 @@
   } else {
 if (FormatTok->isOneOf(tok::kw_constexpr, tok::identifier))
   nextToken();
-if (FormatTok->is(tok::l_paren))
+if (FormatTok->is(tok::l_paren)) {
+  FormatTok->setFinalizedType(TT_ConditionLParen);
   parseParens();
+}
   }
   handleAttributes();
 
@@ -2714,14 +2716,20 @@
 void UnwrappedLineParser::parseForOrWhileLoop() {
   assert(FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) &&
  "'for', 'while' or foreach macro expected");
+  const FormatToken &FirstTok = *FormatTo

[PATCH] D121756: [clang-format] Clean up code looking for if statements

2022-04-03 Thread sstwcw via Phabricator via cfe-commits
sstwcw marked 2 inline comments as done.
sstwcw added inline comments.



Comment at: clang/lib/Format/TokenAnnotator.cpp:252-256
+} else if (OpeningParen.isConditionLParen(/*IncludeFor=*/false) ||
+   (OpeningParen.Previous &&
+OpeningParen.Previous->isOneOf(TT_BinaryOperator, tok::l_paren,
+   tok::comma,
+   tok::kw_static_assert))) {

owenpan wrote:
> owenpan wrote:
> > I don't think this is NFC.
> > Before:
> > ```
> > } else if (OpeningParen.Previous &&
> >(OpeningParen.Previous->isOneOf(tok::kw_static_assert,
> >tok::kw_while, tok::l_paren,
> >tok::comma, tok::kw_if,
> >TT_BinaryOperator) ||
> > OpeningParen.Previous->endsSequence(tok::kw_constexpr,
> > tok::kw_if) ||
> > OpeningParen.Previous->endsSequence(tok::identifier,
> > tok::kw_if))) {
> > ```
> > After:
> > ```
> > } else if ((OpeningParen.is(tok::l_paren) &&
> > OpeningParen.is(TT_ConditionLParen)) ||
> >// PreviousNonComment = OpeningParen.getPreviousNonComment()
> >(PreviousNonComment &&
> > PreviousNonComment->isOneOf(tok::kw_if, tok::kw_while,
> > tok::kw_switch, tok::kw_case,
> > tok::kw_constexpr)) ||
> >(OpeningParen.Previous &&
> > OpeningParen.Previous->isOneOf(tok::kw_static_assert,
> >tok::l_paren, tok::comma,
> >TT_BinaryOperator))) {
> > ```
> > After:
> > ```
> > } else if ((OpeningParen.is(tok::l_paren) &&
> > OpeningParen.is(TT_ConditionLParen)) ||
> > ...
> > tok::kw_constexpr)) ||
> >...
> > ```
> 
> After:
> ```
> } else if ((OpeningParen.is(tok::l_paren) &&
> (OpeningParen.is(TT_ConditionLParen) ||
> ...
>  tok::kw_constexpr ||
>...
> ```
I removed NFC from the title.  It would affect things like this:

```
new:
switch (x * x)
old:
switch (x *x)
```
However the entire llvm codebase doesn't seem to have such things.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121756

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


[PATCH] D121757: [clang-format] Take out common code for parsing blocks NFC

2022-04-05 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 420652.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121757

Files:
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/lib/Format/UnwrappedLineParser.h
  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
@@ -646,6 +646,49 @@
   EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_ObjCBlockLBrace);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsConditionParen) {
+  auto Tokens = annotate("if (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+  Tokens = annotate("if constexpr (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_ConditionLParen);
+  Tokens = annotate("if CONSTEXPR (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_ConditionLParen);
+
+  // The parentheses following for is not TT_ConditionLParen, because inside is
+  // not just a condition.
+  Tokens = annotate("for (;;) {\n}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown);
+  Tokens = annotate("foreach (Item *item, itemlist) {\n}");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown);
+  Tokens = annotate("Q_FOREACH (Item *item, itemlist) {\n}");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown);
+  Tokens = annotate("BOOST_FOREACH (Item *item, itemlist) {\n}");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown);
+  Tokens = annotate("try {\n"
+"} catch (Exception &bar) {\n"
+"}");
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_Unknown);
+
+  Tokens = annotate("while (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+  Tokens = annotate("do {\n} while (true);");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_ConditionLParen);
+
+  Tokens = annotate("switch (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+}
+
 } // namespace
 } // namespace format
 } // namespace clang
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -3177,6 +3177,15 @@
   Style.ColumnLimit =
   20; // to concentrate at brace wrapping, not line wrap due to column limit
 
+  verifyFormat("if (xx\n"
+   ".xx)\n"
+   "  continue;",
+   Style);
+  verifyFormat("while (xx\n"
+   "   .xx)\n"
+   "  continue;",
+   Style);
+
   Style.BraceWrapping.BeforeElse = true;
   EXPECT_EQ(
   "if (foo) {\n"
Index: clang/lib/Format/UnwrappedLineParser.h
===
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -125,6 +125,7 @@
   bool handleCppAttributes();
   FormatToken *parseIfThenElse(IfStmtKind *IfKind, bool KeepBraces = false);
   void parseTryCatch();
+  void parseLoopBody(bool TryRemoveBraces, bool WrapRightBrace);
   void parseForOrWhileLoop();
   void parseDoWhile();
   void parseLabel(bool LeftAlignLabel = false);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -2422,8 +2422,10 @@
   } else {
 if (FormatTok->isOneOf(tok::kw_constexpr, tok::identifier))
   nextToken();
-if (FormatTok->is(tok::l_paren))
+if (FormatTok->is(tok::l_paren)) {
+  FormatTok->setFinalizedType(TT_ConditionLParen);
   parseParens();
+}
   }
   handleAttributes();
 
@@ -2711,55 +2713,55 @@
   } while (!eof());
 }
 
+void UnwrappedLineParser::parseLoopBody(bool TryRemoveBraces,
+bool WrapRightBrace) {
+  keepAncestorBraces();
+
+  if (FormatTok->is(tok::l_brace)) {
+FormatToken *LeftBrace = FormatTok;
+CompoundStatementIndenter Indenter(this, Style, Line->Level);
+parseBlock();
+if (TryRemoveBraces) {
+  assert(!NestedTooDeep.empty());
+  if (!NestedTooDeep.back())
+markOptionalBraces(LeftBrace);
+}
+if (WrapRightBrace)
+  addUnwrappedLine()

[PATCH] D121757: [clang-format] Take out common code for parsing blocks NFC

2022-04-05 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 420653.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121757

Files:
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/lib/Format/UnwrappedLineParser.h


Index: clang/lib/Format/UnwrappedLineParser.h
===
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -125,6 +125,7 @@
   bool handleCppAttributes();
   FormatToken *parseIfThenElse(IfStmtKind *IfKind, bool KeepBraces = false);
   void parseTryCatch();
+  void parseLoopBody(bool TryRemoveBraces, bool WrapRightBrace);
   void parseForOrWhileLoop();
   void parseDoWhile();
   void parseLabel(bool LeftAlignLabel = false);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -2713,6 +2713,29 @@
   } while (!eof());
 }
 
+void UnwrappedLineParser::parseLoopBody(bool TryRemoveBraces,
+bool WrapRightBrace) {
+  keepAncestorBraces();
+
+  if (FormatTok->is(tok::l_brace)) {
+FormatToken *LeftBrace = FormatTok;
+CompoundStatementIndenter Indenter(this, Style, Line->Level);
+parseBlock();
+if (TryRemoveBraces) {
+  assert(!NestedTooDeep.empty());
+  if (!NestedTooDeep.back())
+markOptionalBraces(LeftBrace);
+}
+if (WrapRightBrace)
+  addUnwrappedLine();
+  } else {
+parseUnbracedBody();
+  }
+
+  if (TryRemoveBraces)
+NestedTooDeep.pop_back();
+}
+
 void UnwrappedLineParser::parseForOrWhileLoop() {
   assert(FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) &&
  "'for', 'while' or foreach macro expected");
@@ -2731,43 +2754,14 @@
 parseParens();
   }
 
-  keepAncestorBraces();
-
-  if (FormatTok->is(tok::l_brace)) {
-FormatToken *LeftBrace = FormatTok;
-CompoundStatementIndenter Indenter(this, Style, Line->Level);
-parseBlock();
-if (Style.RemoveBracesLLVM) {
-  assert(!NestedTooDeep.empty());
-  if (!NestedTooDeep.back())
-markOptionalBraces(LeftBrace);
-}
-addUnwrappedLine();
-  } else {
-parseUnbracedBody();
-  }
-
-  if (Style.RemoveBracesLLVM)
-NestedTooDeep.pop_back();
+  parseLoopBody(Style.RemoveBracesLLVM, true);
 }
 
 void UnwrappedLineParser::parseDoWhile() {
   assert(FormatTok->is(tok::kw_do) && "'do' expected");
   nextToken();
 
-  keepAncestorBraces();
-
-  if (FormatTok->is(tok::l_brace)) {
-CompoundStatementIndenter Indenter(this, Style, Line->Level);
-parseBlock();
-if (Style.BraceWrapping.BeforeWhile)
-  addUnwrappedLine();
-  } else {
-parseUnbracedBody();
-  }
-
-  if (Style.RemoveBracesLLVM)
-NestedTooDeep.pop_back();
+  parseLoopBody(false, Style.BraceWrapping.BeforeWhile);
 
   // FIXME: Add error handling.
   if (!FormatTok->is(tok::kw_while)) {


Index: clang/lib/Format/UnwrappedLineParser.h
===
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -125,6 +125,7 @@
   bool handleCppAttributes();
   FormatToken *parseIfThenElse(IfStmtKind *IfKind, bool KeepBraces = false);
   void parseTryCatch();
+  void parseLoopBody(bool TryRemoveBraces, bool WrapRightBrace);
   void parseForOrWhileLoop();
   void parseDoWhile();
   void parseLabel(bool LeftAlignLabel = false);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -2713,6 +2713,29 @@
   } while (!eof());
 }
 
+void UnwrappedLineParser::parseLoopBody(bool TryRemoveBraces,
+bool WrapRightBrace) {
+  keepAncestorBraces();
+
+  if (FormatTok->is(tok::l_brace)) {
+FormatToken *LeftBrace = FormatTok;
+CompoundStatementIndenter Indenter(this, Style, Line->Level);
+parseBlock();
+if (TryRemoveBraces) {
+  assert(!NestedTooDeep.empty());
+  if (!NestedTooDeep.back())
+markOptionalBraces(LeftBrace);
+}
+if (WrapRightBrace)
+  addUnwrappedLine();
+  } else {
+parseUnbracedBody();
+  }
+
+  if (TryRemoveBraces)
+NestedTooDeep.pop_back();
+}
+
 void UnwrappedLineParser::parseForOrWhileLoop() {
   assert(FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) &&
  "'for', 'while' or foreach macro expected");
@@ -2731,43 +2754,14 @@
 parseParens();
   }
 
-  keepAncestorBraces();
-
-  if (FormatTok->is(tok::l_brace)) {
-FormatToken *LeftBrace = FormatTok;
-CompoundStatementIndenter Indenter(this, Style, Line->Level);
-parseBlock();
-if (Style.RemoveBracesLLVM) {
-  assert(!NestedTooDeep.empty());
-  if (!NestedTooDeep.back())
-markOptionalBraces(LeftB

[PATCH] D126845: [clang-format] Handle Verilog numbers and operators

2022-07-28 Thread sstwcw 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 rGf93182a88788: [clang-format] Handle Verilog numbers and 
operators (authored by sstwcw).

Changed prior to commit:
  https://reviews.llvm.org/D126845?vs=439981&id=448486#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126845

Files:
  clang/lib/Format/FormatToken.h
  clang/lib/Format/FormatTokenLexer.cpp
  clang/lib/Format/FormatTokenLexer.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/unittests/Format/FormatTestVerilog.cpp
  clang/unittests/Format/TokenAnnotatorTest.cpp

Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -38,6 +38,8 @@
   EXPECT_EQ((FormatTok)->Tok.getKind(), Kind) << *(FormatTok)
 #define EXPECT_TOKEN_TYPE(FormatTok, Type) \
   EXPECT_EQ((FormatTok)->getType(), Type) << *(FormatTok)
+#define EXPECT_TOKEN_PRECEDENCE(FormatTok, Prec)   \
+  EXPECT_EQ((FormatTok)->getPrecedence(), Prec) << *(FormatTok)
 #define EXPECT_TOKEN(FormatTok, Kind, Type)\
   do { \
 EXPECT_TOKEN_KIND(FormatTok, Kind);\
@@ -764,6 +766,67 @@
   EXPECT_TOKEN(Tokens[7], tok::l_brace, TT_LambdaLBrace);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsVerilogOperators) {
+  auto Annotate = [this](llvm::StringRef Code) {
+return annotate(Code, getLLVMStyle(FormatStyle::LK_Verilog));
+  };
+  // Test that unary operators get labeled as such and that operators like '++'
+  // don't get split.
+  tok::TokenKind Unary[] = {tok::plus,  tok::minus,tok::exclaim,
+tok::tilde, tok::amp,  tok::pipe,
+tok::caret, tok::plusplus, tok::minusminus};
+  for (auto Kind : Unary) {
+auto Tokens =
+Annotate(std::string("x = ") + tok::getPunctuatorSpelling(Kind) + "x;");
+ASSERT_EQ(Tokens.size(), 6u) << Tokens;
+EXPECT_TOKEN(Tokens[2], Kind, TT_UnaryOperator);
+  }
+  // Operators formed by joining two operators like '^~'. For some of these
+  // joined operators, we don't have a separate type, so we only test for their
+  // precedence.
+  std::pair JoinedBinary[] = {
+  {prec::Comma, "<->"},   {prec::Assignment, "+="},
+  {prec::Assignment, "-="},   {prec::Assignment, "*="},
+  {prec::Assignment, "/="},   {prec::Assignment, "%="},
+  {prec::Assignment, "&="},   {prec::Assignment, "^="},
+  {prec::Assignment, "<<="},  {prec::Assignment, ">>="},
+  {prec::Assignment, "<<<="}, {prec::Assignment, ">>>="},
+  {prec::LogicalOr, "||"},{prec::LogicalAnd, "&&"},
+  {prec::Equality, "=="}, {prec::Equality, "!="},
+  {prec::Equality, "==="},{prec::Equality, "!=="},
+  {prec::Equality, "==?"},{prec::Equality, "!=?"},
+  {prec::ExclusiveOr, "~^"},  {prec::ExclusiveOr, "^~"},
+  };
+  for (auto Operator : JoinedBinary) {
+auto Tokens = Annotate(std::string("x = x ") + Operator.second + " x;");
+ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+EXPECT_TOKEN_TYPE(Tokens[3], TT_BinaryOperator);
+EXPECT_TOKEN_PRECEDENCE(Tokens[3], Operator.first);
+  }
+  // '~^' and '^~' can be unary as well as binary operators.
+  auto Tokens = Annotate("x = ~^x;");
+  ASSERT_EQ(Tokens.size(), 6u) << Tokens;
+  EXPECT_TOKEN_TYPE(Tokens[2], TT_UnaryOperator);
+  Tokens = Annotate("x = ^~x;");
+  ASSERT_EQ(Tokens.size(), 6u) << Tokens;
+  EXPECT_TOKEN_TYPE(Tokens[2], TT_UnaryOperator);
+  // The unary operators '~&' and '~|' can only be unary operators. The current
+  // implementation treats each of them as separate unary '~' and '&' or '|'
+  // operators, which is enough for formatting purposes. In FormatTestVerilog,
+  // there is a test that there is no space in between. And even if a new line
+  // is inserted between the '~' and '|', the semantic meaning is the same as
+  // the joined operator, so the CanBreakBefore property doesn't need to be
+  // false for the second operator.
+  Tokens = Annotate("x = ~&x;");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::tilde, TT_UnaryOperator);
+  EXPECT_TOKEN(Tokens[3], tok::amp, TT_UnaryOperator);
+  Tokens = Annotate("x = ~|x;");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::tilde, TT_UnaryOperator);
+  EXPECT_TOKEN(Tokens[3], tok::pipe, TT_UnaryOperator);
+}
+
 } // namespace
 } // namespace format
 } // namespace clang
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unit

[PATCH] D128711: [clang-format] Handle Verilog blocks

2022-07-28 Thread sstwcw 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 rG67480b360ca0: [clang-format] Handle Verilog blocks (authored 
by sstwcw).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D128711

Files:
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTestVerilog.cpp
  clang/unittests/Format/TokenAnnotatorTest.cpp

Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -825,6 +825,12 @@
   ASSERT_EQ(Tokens.size(), 7u) << Tokens;
   EXPECT_TOKEN(Tokens[2], tok::tilde, TT_UnaryOperator);
   EXPECT_TOKEN(Tokens[3], tok::pipe, TT_UnaryOperator);
+  // Test for block label colons.
+  Tokens = Annotate("begin : x\n"
+"end : x");
+  ASSERT_EQ(Tokens.size(), 7u);
+  EXPECT_TOKEN(Tokens[1], tok::colon, TT_VerilogBlockLabelColon);
+  EXPECT_TOKEN(Tokens[4], tok::colon, TT_VerilogBlockLabelColon);
 }
 
 } // namespace
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -66,6 +66,56 @@
   verifyFormat("x = 16'sd?;");
 }
 
+TEST_F(FormatTestVerilog, Block) {
+  verifyFormat("begin\n"
+   "  x = x;\n"
+   "end");
+  verifyFormat("begin : x\n"
+   "  x = x;\n"
+   "end : x");
+  verifyFormat("begin\n"
+   "  x = x;\n"
+   "  x = x;\n"
+   "end");
+  verifyFormat("fork\n"
+   "  x = x;\n"
+   "join");
+  verifyFormat("fork\n"
+   "  x = x;\n"
+   "join_any");
+  verifyFormat("fork\n"
+   "  x = x;\n"
+   "join_none");
+  verifyFormat("generate\n"
+   "  x = x;\n"
+   "endgenerate");
+  verifyFormat("generate : x\n"
+   "  x = x;\n"
+   "endgenerate : x");
+  // Nested blocks.
+  verifyFormat("begin\n"
+   "  begin\n"
+   "  end\n"
+   "end");
+  verifyFormat("begin : x\n"
+   "  begin\n"
+   "  end\n"
+   "end : x");
+  verifyFormat("begin : x\n"
+   "  begin : x\n"
+   "  end : x\n"
+   "end : x");
+  verifyFormat("begin\n"
+   "  begin : x\n"
+   "  end : x\n"
+   "end");
+  // Test that 'disable fork' and 'rand join' don't get mistaken as blocks.
+  verifyFormat("disable fork;\n"
+   "x = x;");
+  verifyFormat("rand join x x;\n"
+   "x = x;");
+}
+
 TEST_F(FormatTestVerilog, Delay) {
   // Delay by the default unit.
   verifyFormat("#0;");
@@ -129,10 +179,6 @@
"  x = x;\n"
"  x = x;\n"
"end");
-  verifyFormat("disable fork;\n"
-   "x = x;");
-  verifyFormat("rand join x x;\n"
-   "x = x;");
   verifyFormat("if (x) fork\n"
"  x = x;\n"
"join");
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1888,6 +1888,14 @@
 return;
   }
 
+  if (Style.isVerilog()) {
+if (Keywords.isVerilogBegin(*FormatTok)) {
+  parseBlock();
+  addUnwrappedLine();
+  return;
+}
+  }
+
   if (FormatTok->is(Keywords.kw_interface)) {
 if (parseStructLike())
   return;
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -947,6 +947,12 @@
   Tok->setType(TT_CSharpNamedArgumentColon);
   break;
 }
+  } else if (Style.isVerilog() && Tok->isNot(TT_BinaryOperator)) {
+if (Keywords.isVerilogEnd(*Tok->Previous) ||
+Keywords.isVerilogBegin(*Tok->Previous)) {
+  Tok->setType(TT_VerilogBlockLabelColon);
+}
+break;
   }
   if (Line.First->isOneOf(Keywords.kw_module, Keywords.kw_import) ||
   Line.First->startsSequence(tok::kw_export, Keywords.kw_module) ||
Index: clang/lib/Format/FormatToken.h
===
--- clang/lib/Format/FormatToken.h
+++ clang/lib/Format/FormatToken.h
@@ -135,6 +135,8 @@
   TYPE(UnaryOperator)  \
   TYPE(UnionLBrace)\
   TYPE(Untouc

[PATCH] D128712: [clang-format] Handle Verilog modules

2022-07-28 Thread sstwcw via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG6db0c18b1af6: [clang-format] Handle Verilog modules 
(authored by sstwcw).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D128712

Files:
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/TokenAnnotator.h
  clang/lib/Format/UnwrappedLineFormatter.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/lib/Format/UnwrappedLineParser.h
  clang/unittests/Format/FormatTestVerilog.cpp
  clang/unittests/Format/TokenAnnotatorTest.cpp

Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -831,6 +831,13 @@
   ASSERT_EQ(Tokens.size(), 7u);
   EXPECT_TOKEN(Tokens[1], tok::colon, TT_VerilogBlockLabelColon);
   EXPECT_TOKEN(Tokens[4], tok::colon, TT_VerilogBlockLabelColon);
+  // Test that the dimension colon is annotated correctly.
+  Tokens = Annotate("var [1 : 0] x;");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::colon, TT_BitFieldColon);
+  Tokens = Annotate("extern function [1 : 0] x;");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::colon, TT_BitFieldColon);
 }
 
 } // namespace
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -139,6 +139,75 @@
 "x = x;"));
 }
 
+TEST_F(FormatTestVerilog, Hierarchy) {
+  verifyFormat("module x;\n"
+   "endmodule");
+  // Test that the end label is on the same line as the end keyword.
+  verifyFormat("module x;\n"
+   "endmodule : x");
+  // Test that things inside are indented.
+  verifyFormat("module x;\n"
+   "  generate\n"
+   "  endgenerate\n"
+   "endmodule");
+  verifyFormat("program x;\n"
+   "  generate\n"
+   "  endgenerate\n"
+   "endprogram");
+  verifyFormat("interface x;\n"
+   "  generate\n"
+   "  endgenerate\n"
+   "endinterface");
+  verifyFormat("task x;\n"
+   "  generate\n"
+   "  endgenerate\n"
+   "endtask");
+  verifyFormat("function x;\n"
+   "  generate\n"
+   "  endgenerate\n"
+   "endfunction");
+  verifyFormat("class x;\n"
+   "  generate\n"
+   "  endgenerate\n"
+   "endclass");
+  // Test that they nest.
+  verifyFormat("module x;\n"
+   "  program x;\n"
+   "program x;\n"
+   "endprogram\n"
+   "  endprogram\n"
+   "endmodule");
+  // Test that an extern declaration doesn't change the indentation.
+  verifyFormat("extern module x;\n"
+   "x = x;");
+  // Test complex headers
+  verifyFormat("extern module x\n"
+   "import x.x::x::*;\n"
+   "import x;\n"
+   "#(parameter x)\n"
+   "(output x);");
+  verifyFormat("module x\n"
+   "import x.x::x::*;\n"
+   "import x;\n"
+   "#(parameter x)\n"
+   "(output x);\n"
+   "  generate\n"
+   "  endgenerate\n"
+   "endmodule : x");
+  verifyFormat("virtual class x\n"
+   "(x)\n"
+   "extends x(x)\n"
+   "implements x, x, x;\n"
+   "  generate\n"
+   "  endgenerate\n"
+   "endclass : x\n");
+  verifyFormat("function automatic logic [1 : 0] x\n"
+   "(input x);\n"
+   "  generate\n"
+   "  endgenerate\n"
+   "endfunction : x");
+}
+
 TEST_F(FormatTestVerilog, If) {
   verifyFormat("if (x)\n"
"  x = x;");
Index: clang/lib/Format/UnwrappedLineParser.h
===
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -49,6 +49,10 @@
 
   bool MustBeDeclaration;
 
+  /// \c True if this line should be indented by ContinuationIndent in
+  /// addition to the normal indention level.
+  bool IsContinuation = false;
+
   /// If this \c UnwrappedLine closes a block in a sequence of lines,
   /// \c MatchingOpeningBlockLineIndex stores the index of the corresponding
   /// opening line. Otherwise, \c MatchingOpeningBlockLineIndex must be
@@ -174,6 +178,11 @@
   bool tryToParsePropertyAccessor();
   void tryToParseJSFunction();
   bool tryToParseSimpleAttribute();
+  void parseVerilogHierarchyIdentifier();
+  void parseVerilogSensitivityList();
+  // Returns the number of

[PATCH] D128713: [clang-format] Handle Verilog user-defined primitives

2022-07-28 Thread sstwcw via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb67ee18e85f3: [clang-format] Handle Verilog user-defined 
primitives (authored by sstwcw).

Changed prior to commit:
  https://reviews.llvm.org/D128713?vs=443607&id=448489#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D128713

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

Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -441,5 +441,46 @@
   }
 }
 
+TEST_F(FormatTestVerilog, Primitive) {
+  verifyFormat("primitive multiplexer\n"
+   "(mux, control, dataA, dataB);\n"
+   "  output mux;\n"
+   "  input control, dataA, dataB;\n"
+   "  table\n"
+   "0 1 ? : 1;\n"
+   "0 0 ? : 0;\n"
+   "1 ? 1 : 1;\n"
+   "1 ? 0 : 0;\n"
+   "x 0 0 : 0;\n"
+   "x 1 1 : 1;\n"
+   "  endtable\n"
+   "endprimitive");
+  verifyFormat("primitive latch\n"
+   "(q, ena_, data);\n"
+   "  output q;\n"
+   "  reg q;\n"
+   "  input ena_, data;\n"
+   "  table\n"
+   "0 1 : ? : 1;\n"
+   "0 0 : ? : 0;\n"
+   "1 ? : ? : -;\n"
+   "? * : ? : -;\n"
+   "  endtable\n"
+   "endprimitive");
+  verifyFormat("primitive d\n"
+   "(q, clock, data);\n"
+   "  output q;\n"
+   "  reg q;\n"
+   "  input clock, data;\n"
+   "  table\n"
+   "(01) 0 : ? : 0;\n"
+   "(01) 1 : ? : 1;\n"
+   "(0?) 1 : 1 : 1;\n"
+   "(0?) 0 : 0 : 0;\n"
+   "(?0) ? : ? : -;\n"
+   "(?\?) ? : ? : -;\n"
+   "  endtable\n"
+   "endprimitive");
+}
 } // namespace format
 } // end namespace clang
Index: clang/lib/Format/UnwrappedLineParser.h
===
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -183,6 +183,7 @@
   // Returns the number of levels of indentation in addition to the normal 1
   // level for a block, used for indenting case labels.
   unsigned parseVerilogHierarchyHeader();
+  void parseVerilogTable();
 
   // Used by addUnwrappedLine to denote whether to keep or remove a level
   // when resetting the line state.
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1913,6 +1913,10 @@
   }
 
   if (Style.isVerilog()) {
+if (FormatTok->is(Keywords.kw_table)) {
+  parseVerilogTable();
+  return;
+}
 if (Keywords.isVerilogBegin(*FormatTok) ||
 Keywords.isVerilogHierarchy(*FormatTok)) {
   parseBlock();
@@ -4039,7 +4043,8 @@
 }
 
 void UnwrappedLineParser::parseVerilogSensitivityList() {
-  assert(FormatTok->is(tok::at));
+  if (!FormatTok->is(tok::at))
+return;
   nextToken();
   // A block event expression has 2 at signs.
   if (FormatTok->is(tok::at))
@@ -4064,15 +4069,13 @@
 nextToken();
 if (Keywords.isVerilogIdentifier(*FormatTok))
   nextToken();
-if (FormatTok->is(tok::at))
-  parseVerilogSensitivityList();
+parseVerilogSensitivityList();
 if (FormatTok->is(tok::semi))
   nextToken();
   } else if (FormatTok->isOneOf(tok::kw_case, Keywords.kw_casex,
 Keywords.kw_casez, Keywords.kw_randcase,
 Keywords.kw_randsequence)) {
-if (Style.IndentCaseLabels)
-  ++AddLevels;
+AddLevels += Style.IndentCaseLabels;
 nextToken();
 if (FormatTok->is(tok::l_paren))
   parseParens();
@@ -4154,6 +4157,25 @@
   return AddLevels;
 }
 
+void UnwrappedLineParser::parseVerilogTable() {
+  assert(FormatTok->is(Keywords.kw_table));
+  nextToken(/*LevelDifference=*/1);
+  addUnwrappedLine();
+
+  auto InitialLevel = Line->Level++;
+  while (!eof() && !Keywords.isVerilogEnd(*FormatTok)) {
+FormatToken *Tok = FormatTok;
+nextToken();
+if (Tok->is(tok::semi))
+  addUnwrappedLine();
+else if (Tok->isOneOf(tok::star, tok::colon, tok::question, tok::minus))
+  Tok->setFinalizedType(TT_VerilogTableItem);
+  }
+  Line->Level = InitialLevel;
+  nextToken(/*LevelDifference=*/-1);
+  addUnwrappedLine();
+}
+
 LLVM_ATTRIBUTE_UNUS

[PATCH] D128714: [clang-format] Handle Verilog case statements

2022-07-28 Thread sstwcw via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGc88719483c69: [clang-format] Handle Verilog case statements 
(authored by sstwcw).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D128714

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

Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -838,6 +838,21 @@
   Tokens = Annotate("extern function [1 : 0] x;");
   ASSERT_EQ(Tokens.size(), 10u) << Tokens;
   EXPECT_TOKEN(Tokens[4], tok::colon, TT_BitFieldColon);
+  // Test case labels and ternary operators.
+  Tokens = Annotate("case (x)\n"
+"  x:\n"
+"x;\n"
+"endcase\n");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::colon, TT_GotoLabelColon);
+  Tokens = Annotate("case (x)\n"
+"  x ? x : x:\n"
+"x;\n"
+"endcase\n");
+  ASSERT_EQ(Tokens.size(), 14u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::question, TT_ConditionalExpr);
+  EXPECT_TOKEN(Tokens[7], tok::colon, TT_ConditionalExpr);
+  EXPECT_TOKEN(Tokens[9], tok::colon, TT_GotoLabelColon);
 }
 
 } // namespace
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -116,6 +116,90 @@
"x = x;");
 }
 
+TEST_F(FormatTestVerilog, Case) {
+  verifyFormat("case (data)\n"
+   "endcase");
+  verifyFormat("casex (data)\n"
+   "endcase");
+  verifyFormat("casez (data)\n"
+   "endcase");
+  verifyFormat("case (data) inside\n"
+   "endcase");
+  verifyFormat("case (data)\n"
+   "  16'd0:\n"
+   "result = 10'b01;\n"
+   "endcase");
+  verifyFormat("case (data)\n"
+   "  :\n"
+   "result = 10'b01;\n"
+   "endcase");
+  // Test labels with multiple options.
+  verifyFormat("case (data)\n"
+   "  16'd0, 16'd1:\n"
+   "result = 10'b01;\n"
+   "endcase");
+  verifyFormat("case (data)\n"
+   "  16'd0, //\n"
+   "  16'd1:\n"
+   "result = 10'b01;\n"
+   "endcase");
+  // Test that blocks following labels are indented.
+  verifyFormat("case (data)\n"
+   "  16'd1: fork\n"
+   "result = 10'b10;\n"
+   "  join\n"
+   "endcase\n");
+  verifyFormat("case (data)\n"
+   "  16'd1: fork : x\n"
+   "result = 10'b10;\n"
+   "  join : x\n"
+   "endcase\n");
+  // Test default.
+  verifyFormat("case (data)\n"
+   "  default\n"
+   "result = 10'b10;\n"
+   "endcase");
+  verifyFormat("case (data)\n"
+   "  default:\n"
+   "result = 10'b10;\n"
+   "endcase");
+  // Test that question marks and colons don't get mistaken as labels.
+  verifyFormat("case (data)\n"
+   "  8'b1???:\n"
+   "instruction1(ir);\n"
+   "endcase");
+  verifyFormat("case (data)\n"
+   "  x ? 8'b1??? : 1:\n"
+   "instruction3(ir);\n"
+   "endcase");
+  // Test indention options.
+  auto Style = getLLVMStyle(FormatStyle::LK_Verilog);
+  Style.IndentCaseLabels = false;
+  verifyFormat("case (data)\n"
+   "16'd0:\n"
+   "  result = 10'b01;\n"
+   "endcase",
+   Style);
+  verifyFormat("case (data)\n"
+   "16'd0: begin\n"
+   "  result = 10'b01;\n"
+   "end\n"
+   "endcase",
+   Style);
+  Style.IndentCaseLabels = true;
+  verifyFormat("case (data)\n"
+   "  16'd0:\n"
+   "result = 10'b01;\n"
+   "endcase",
+   Style);
+  verifyFormat("case (data)\n"
+   "  16'd0: begin\n"
+   "result = 10'b01;\n"
+   "  end\n"
+   "endcase",
+   Style);
+}
+
 TEST_F(FormatTestVerilog, Delay) {
   // Delay by the default unit.
   verifyFormat("#0;");
Index: clang/lib/Format/UnwrappedLineParser.h
===

[PATCH] D128709: [clang-format] Handle Verilog attributes

2022-07-28 Thread sstwcw via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG60e12068ffeb: [clang-format] Handle Verilog attributes 
(authored by sstwcw).

Changed prior to commit:
  https://reviews.llvm.org/D128709?vs=443611&id=448491#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D128709

Files:
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/unittests/Format/FormatTestVerilog.cpp


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -295,6 +295,12 @@
 TEST_F(FormatTestVerilog, If) {
   verifyFormat("if (x)\n"
"  x = x;");
+  verifyFormat("unique if (x)\n"
+   "  x = x;");
+  verifyFormat("unique0 if (x)\n"
+   "  x = x;");
+  verifyFormat("priority if (x)\n"
+   "  x = x;");
   verifyFormat("if (x)\n"
"  x = x;\n"
"x = x;");
@@ -357,6 +363,14 @@
"  x = {x};\n"
"else\n"
"  {x} = {x};");
+
+  // With attributes.
+  verifyFormat("(* x *) if (x)\n"
+   "  x = x;");
+  verifyFormat("(* x = \"x\" *) if (x)\n"
+   "  x = x;");
+  verifyFormat("(* x, x = \"x\" *) if (x)\n"
+   "  x = x;");
 }
 
 TEST_F(FormatTestVerilog, Operators) {
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1471,6 +1471,23 @@
 addUnwrappedLine();
 return;
   }
+
+  if (Style.isVerilog()) {
+// Skip things that can exist before keywords like 'if' and 'case'.
+while (true) {
+  if (FormatTok->isOneOf(Keywords.kw_priority, Keywords.kw_unique,
+ Keywords.kw_unique0)) {
+nextToken();
+  } else if (FormatTok->is(tok::l_paren) &&
+ Tokens->peekNextToken()->is(tok::star)) {
+parseParens();
+  } else {
+break;
+  }
+}
+  }
+
+  // Tokens that only make sense at the beginning of a line.
   switch (FormatTok->Tok.getKind()) {
   case tok::kw_asm:
 nextToken();
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -4067,6 +4067,9 @@
  Keywords.isWordLike(Left))) {
   return false;
 }
+// Add space in attribute like `(* ASYNC_REG = "TRUE" *)`.
+if (Left.endsSequence(tok::star, tok::l_paren) && 
Right.is(tok::identifier))
+  return true;
   }
   if (Left.is(TT_ImplicitStringLiteral))
 return Right.hasWhitespaceBefore();


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -295,6 +295,12 @@
 TEST_F(FormatTestVerilog, If) {
   verifyFormat("if (x)\n"
"  x = x;");
+  verifyFormat("unique if (x)\n"
+   "  x = x;");
+  verifyFormat("unique0 if (x)\n"
+   "  x = x;");
+  verifyFormat("priority if (x)\n"
+   "  x = x;");
   verifyFormat("if (x)\n"
"  x = x;\n"
"x = x;");
@@ -357,6 +363,14 @@
"  x = {x};\n"
"else\n"
"  {x} = {x};");
+
+  // With attributes.
+  verifyFormat("(* x *) if (x)\n"
+   "  x = x;");
+  verifyFormat("(* x = \"x\" *) if (x)\n"
+   "  x = x;");
+  verifyFormat("(* x, x = \"x\" *) if (x)\n"
+   "  x = x;");
 }
 
 TEST_F(FormatTestVerilog, Operators) {
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1471,6 +1471,23 @@
 addUnwrappedLine();
 return;
   }
+
+  if (Style.isVerilog()) {
+// Skip things that can exist before keywords like 'if' and 'case'.
+while (true) {
+  if (FormatTok->isOneOf(Keywords.kw_priority, Keywords.kw_unique,
+ Keywords.kw_unique0)) {
+nextToken();
+  } else if (FormatTok->is(tok::l_paren) &&
+ Tokens->peekNextToken()->is(tok::star)) {
+parseParens();
+  } else {
+break;
+  }
+}
+  }
+
+  // Tokens that only make sense at the beginning of a line.
   switch (FormatTok->Tok.getKind()) {
   case tok::kw_asm:
 nextToken();
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -40

[PATCH] D88299: [clang-format] Add MacroUnexpander.

2022-07-28 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

It looks like some of the braces in the code should be removed for example 
those surrounding one-line for bodies.  Sorry if it is not my job to point this 
out, but MyDeveloperDay has not said anything.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D88299

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


[PATCH] D119599: [clang-format] Add option to align compound assignments like `+=`

2022-03-09 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

Any more problems with this revision?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D119599

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


[PATCH] D119599: [clang-format] Add option to align compound assignments like `+=`

2022-03-10 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 414347.
sstwcw added a comment.

Modify initialization.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D119599

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

Index: clang/unittests/Format/FormatTestJS.cpp
===
--- clang/unittests/Format/FormatTestJS.cpp
+++ clang/unittests/Format/FormatTestJS.cpp
@@ -2699,7 +2699,7 @@
 
 TEST_F(FormatTestJS, AlignConsecutiveDeclarations) {
   FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
-  Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+  Style.AlignConsecutiveDeclarations.Enabled = true;
   verifyFormat("letletVariable = 5;\n"
"double constVariable = 10;",
Style);
@@ -2736,7 +2736,7 @@
 TEST_F(FormatTestJS, AlignConsecutiveAssignments) {
   FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
 
-  Style.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+  Style.AlignConsecutiveAssignments.Enabled = true;
   verifyFormat("let letVariable  = 5;\n"
"double constVariable = 10;",
Style);
@@ -2772,8 +2772,8 @@
 
 TEST_F(FormatTestJS, AlignConsecutiveAssignmentsAndDeclarations) {
   FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
-  Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
-  Style.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+  Style.AlignConsecutiveDeclarations.Enabled = true;
+  Style.AlignConsecutiveAssignments.Enabled = true;
   verifyFormat("letletVariable   = 5;\n"
"double constVariable = 10;",
Style);
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2076,7 +2076,7 @@
   " res2 = [](int &a) { return 0; };",
   Style);
 
-  Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+  Style.AlignConsecutiveDeclarations.Enabled = true;
   verifyFormat("Const unsigned int *c;\n"
"const unsigned int *d;\n"
"Const unsigned int &e;\n"
@@ -2117,7 +2117,7 @@
   "res2 = [](int& a) { return 0; };",
   Style);
 
-  Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+  Style.AlignConsecutiveDeclarations.Enabled = true;
   verifyFormat("Const unsigned int* c;\n"
"const unsigned int* d;\n"
"Const unsigned int& e;\n"
@@ -2138,7 +2138,7 @@
   verifyFormat("for (int a = 0, b = 0; const Foo *c : {1, 2, 3})", Style);
   verifyFormat("for (int a = 0, b++; const Foo *c : {1, 2, 3})", Style);
 
-  Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+  Style.AlignConsecutiveDeclarations.Enabled = true;
   verifyFormat("Const unsigned int *c;\n"
"const unsigned int *d;\n"
"Const unsigned int& e;\n"
@@ -2174,7 +2174,7 @@
   " res2 = [](int & a) { return 0; };",
   Style);
 
-  Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+  Style.AlignConsecutiveDeclarations.Enabled = true;
   verifyFormat("Const unsigned int*  c;\n"
"const unsigned int*  d;\n"
"Const unsigned int & e;\n"
@@ -14462,8 +14462,8 @@
"*/\n"
"}",
Tab));
-  Tab.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
-  Tab.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+  Tab.AlignConsecutiveAssignments.Enabled = true;
+  Tab.AlignConsecutiveDeclarations.Enabled = true;
   Tab.TabWidth = 4;
   Tab.IndentWidth = 4;
   verifyFormat("class Assign {\n"
@@ -14701,8 +14701,8 @@
"*/\n"
"}",
Tab));
-  Tab.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
-  Tab.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+  Tab.AlignConsecutiveAssignments.Enabled = true;
+  Tab.AlignConsecutiveDeclarations.Enabled = true;
   Tab.TabWidth = 4;
   Tab.IndentWidth = 4;
   verifyFormat("class Assign {\n"
@@ -15872,9 +15872,8 @@
 
 TEST_F(FormatTest, AlignConsecutiveMacros) {
   FormatStyle Style = getLLVMStyle();
-  Style.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
-  Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
-  Style.AlignConsecutiveMacros = FormatStyle::ACS_None;
+  Style.AlignConsecutiveAssignments.Enabled = true;
+  Style.AlignConsecutiveDeclarations.Enabled = true;
 
   verifyFormat("#define a 3\n"
  

[PATCH] D119599: [clang-format] Add option to align compound assignments like `+=`

2022-03-12 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

@MyDeveloperDay Will you please accept this revision?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D119599

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


[PATCH] D119599: [clang-format] Add option to align compound assignments like `+=`

2022-03-12 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

How to get this revision committed?  I thought it would happen automatically 
now that it is accepted.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D119599

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


[PATCH] D120361: [clang-format] Extract doc for entire configuration structs

2022-03-13 Thread sstwcw 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 rG93b5505b456f: [clang-format] Extract doc for entire 
configuration structs (authored by sstwcw).
Herald added a project: All.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D120361

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/docs/tools/dump_format_style.py


Index: clang/docs/tools/dump_format_style.py
===
--- clang/docs/tools/dump_format_style.py
+++ clang/docs/tools/dump_format_style.py
@@ -118,7 +118,7 @@
 self.values = []
 
   def __str__(self):
-return '\n'.join(map(str, self.values))
+return self.comment + '\n' + '\n'.join(map(str, self.values))
 
 class NestedField(object):
   def __init__(self, name, comment):
Index: clang/docs/ClangFormatStyleOptions.rst
===
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -1212,6 +1212,14 @@
 
   Nested configuration flags:
 
+  Precise control over the wrapping of braces.
+
+  .. code-block:: c++
+
+# Should be declared this way:
+BreakBeforeBraces: Custom
+BraceWrapping:
+AfterClass: true
 
   * ``bool AfterCaseLabel`` Wrap case labels.
 
@@ -3992,6 +4000,15 @@
 
   Nested configuration flags:
 
+  Precise control over the spacing before parentheses.
+
+  .. code-block:: c++
+
+# Should be declared this way:
+SpaceBeforeParens: Custom
+SpaceBeforeParensOptions:
+  AfterControlStatements: true
+  AfterFunctionDefinitionName: true
 
   * ``bool AfterControlStatements`` If ``true``, put space betwee control 
statement keywords
 (for/if/while...) and opening parentheses.
@@ -4221,6 +4238,7 @@
 
   Nested configuration flags:
 
+  Control of spaces within a single line comment
 
   * ``unsigned Minimum`` The minimum number of spaces at the start of the 
comment.
 


Index: clang/docs/tools/dump_format_style.py
===
--- clang/docs/tools/dump_format_style.py
+++ clang/docs/tools/dump_format_style.py
@@ -118,7 +118,7 @@
 self.values = []
 
   def __str__(self):
-return '\n'.join(map(str, self.values))
+return self.comment + '\n' + '\n'.join(map(str, self.values))
 
 class NestedField(object):
   def __init__(self, name, comment):
Index: clang/docs/ClangFormatStyleOptions.rst
===
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -1212,6 +1212,14 @@
 
   Nested configuration flags:
 
+  Precise control over the wrapping of braces.
+
+  .. code-block:: c++
+
+# Should be declared this way:
+BreakBeforeBraces: Custom
+BraceWrapping:
+AfterClass: true
 
   * ``bool AfterCaseLabel`` Wrap case labels.
 
@@ -3992,6 +4000,15 @@
 
   Nested configuration flags:
 
+  Precise control over the spacing before parentheses.
+
+  .. code-block:: c++
+
+# Should be declared this way:
+SpaceBeforeParens: Custom
+SpaceBeforeParensOptions:
+  AfterControlStatements: true
+  AfterFunctionDefinitionName: true
 
   * ``bool AfterControlStatements`` If ``true``, put space betwee control statement keywords
 (for/if/while...) and opening parentheses.
@@ -4221,6 +4238,7 @@
 
   Nested configuration flags:
 
+  Control of spaces within a single line comment
 
   * ``unsigned Minimum`` The minimum number of spaces at the start of the comment.
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D119599: [clang-format] Add option to align compound assignments like `+=`

2022-03-13 Thread sstwcw 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 rGc24b3db45c7d: [clang-format] Add option to align compound 
assignments like `+=` (authored by sstwcw).

Changed prior to commit:
  https://reviews.llvm.org/D119599?vs=414347&id=414986#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D119599

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

Index: clang/unittests/Format/FormatTestJS.cpp
===
--- clang/unittests/Format/FormatTestJS.cpp
+++ clang/unittests/Format/FormatTestJS.cpp
@@ -2699,7 +2699,7 @@
 
 TEST_F(FormatTestJS, AlignConsecutiveDeclarations) {
   FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
-  Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+  Style.AlignConsecutiveDeclarations.Enabled = true;
   verifyFormat("letletVariable = 5;\n"
"double constVariable = 10;",
Style);
@@ -2736,7 +2736,7 @@
 TEST_F(FormatTestJS, AlignConsecutiveAssignments) {
   FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
 
-  Style.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+  Style.AlignConsecutiveAssignments.Enabled = true;
   verifyFormat("let letVariable  = 5;\n"
"double constVariable = 10;",
Style);
@@ -2772,8 +2772,8 @@
 
 TEST_F(FormatTestJS, AlignConsecutiveAssignmentsAndDeclarations) {
   FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
-  Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
-  Style.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+  Style.AlignConsecutiveDeclarations.Enabled = true;
+  Style.AlignConsecutiveAssignments.Enabled = true;
   verifyFormat("letletVariable   = 5;\n"
"double constVariable = 10;",
Style);
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2083,7 +2083,7 @@
   " res2 = [](int &a) { return 0; };",
   Style);
 
-  Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+  Style.AlignConsecutiveDeclarations.Enabled = true;
   verifyFormat("Const unsigned int *c;\n"
"const unsigned int *d;\n"
"Const unsigned int &e;\n"
@@ -2124,7 +2124,7 @@
   "res2 = [](int& a) { return 0; };",
   Style);
 
-  Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+  Style.AlignConsecutiveDeclarations.Enabled = true;
   verifyFormat("Const unsigned int* c;\n"
"const unsigned int* d;\n"
"Const unsigned int& e;\n"
@@ -2145,7 +2145,7 @@
   verifyFormat("for (int a = 0, b = 0; const Foo *c : {1, 2, 3})", Style);
   verifyFormat("for (int a = 0, b++; const Foo *c : {1, 2, 3})", Style);
 
-  Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+  Style.AlignConsecutiveDeclarations.Enabled = true;
   verifyFormat("Const unsigned int *c;\n"
"const unsigned int *d;\n"
"Const unsigned int& e;\n"
@@ -2181,7 +2181,7 @@
   " res2 = [](int & a) { return 0; };",
   Style);
 
-  Style.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+  Style.AlignConsecutiveDeclarations.Enabled = true;
   verifyFormat("Const unsigned int*  c;\n"
"const unsigned int*  d;\n"
"Const unsigned int & e;\n"
@@ -14515,8 +14515,8 @@
"*/\n"
"}",
Tab));
-  Tab.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
-  Tab.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+  Tab.AlignConsecutiveAssignments.Enabled = true;
+  Tab.AlignConsecutiveDeclarations.Enabled = true;
   Tab.TabWidth = 4;
   Tab.IndentWidth = 4;
   verifyFormat("class Assign {\n"
@@ -14754,8 +14754,8 @@
"*/\n"
"}",
Tab));
-  Tab.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
-  Tab.AlignConsecutiveDeclarations = FormatStyle::ACS_Consecutive;
+  Tab.AlignConsecutiveAssignments.Enabled = true;
+  Tab.AlignConsecutiveDeclarations.Enabled = true;
   Tab.TabWidth = 4;
   Tab.IndentWidth = 4;
   verifyFormat("class Assign {\n"
@@ -15925,9 +15925,8 @@
 
 TEST_F(FormatTest, AlignConsecutiveMacros) {
   FormatStyle Style = getLLVMStyle();
-  Style.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
-  Style.AlignConsecutiveDeclarations =

[PATCH] D121749: [clang-format][docs] Regenerate ClangFormatStyleOptions.rst

2022-03-15 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

Yes.  I probably forgot to generate the doc.  Thank you.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121749

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


[PATCH] D121753: [clang-format] Use a macro for non-C keywords

2022-03-15 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
sstwcw added a reviewer: clang-format.
sstwcw added a project: clang-format.
Herald added a project: All.
sstwcw requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

We had to add a bunch of keywords for a new language.  Using the old
method, we had to add each keyword in the declaration, initialization,
and maybe in several lists, which turned out to be tiring and
error-prone.  Also we didn't want functions like
`IsJavaScriptIdentifier` to take linear time with respect to the number
of keywords.  In the new version we use a hash table.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D121753

Files:
  clang/lib/Format/FormatToken.h
  clang/lib/Format/UnwrappedLineFormatter.cpp
  clang/lib/Format/UnwrappedLineParser.cpp

Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1481,8 +1481,8 @@
   }
 }
 if (Style.isCpp() &&
-FormatTok->isOneOf(Keywords.kw_signals, Keywords.kw_qsignals,
-   Keywords.kw_slots, Keywords.kw_qslots)) {
+FormatTok->isOneOf(Keywords.kw_signals, Keywords.kw_Q_SIGNALS,
+   Keywords.kw_slots, Keywords.kw_Q_SLOTS)) {
   nextToken();
   if (FormatTok->is(tok::colon)) {
 nextToken();
@@ -2902,7 +2902,7 @@
   FormatToken *AccessSpecifierCandidate = FormatTok;
   nextToken();
   // Understand Qt's slots.
-  if (FormatTok->isOneOf(Keywords.kw_slots, Keywords.kw_qslots))
+  if (FormatTok->isOneOf(Keywords.kw_slots, Keywords.kw_Q_SLOTS))
 nextToken();
   // Otherwise, we don't know what it is, and we'd better keep the next token.
   if (FormatTok->is(tok::colon)) {
Index: clang/lib/Format/UnwrappedLineFormatter.cpp
===
--- clang/lib/Format/UnwrappedLineFormatter.cpp
+++ clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -112,11 +112,12 @@
   else if (RootToken.isObjCAccessSpecifier())
 return true;
   // Handle Qt signals.
-  else if ((RootToken.isOneOf(Keywords.kw_signals, Keywords.kw_qsignals) &&
+  else if ((RootToken.isOneOf(Keywords.kw_signals, Keywords.kw_Q_SIGNALS) &&
 RootToken.Next && RootToken.Next->is(tok::colon)))
 return true;
   else if (RootToken.Next &&
-   RootToken.Next->isOneOf(Keywords.kw_slots, Keywords.kw_qslots) &&
+   RootToken.Next->isOneOf(Keywords.kw_slots,
+   Keywords.kw_Q_SLOTS) &&
RootToken.Next->Next && RootToken.Next->Next->is(tok::colon))
 return true;
   // Handle malformed access specifier e.g. 'private' without trailing ':'.
Index: clang/lib/Format/FormatToken.h
===
--- clang/lib/Format/FormatToken.h
+++ clang/lib/Format/FormatToken.h
@@ -20,6 +20,7 @@
 #include "clang/Format/Format.h"
 #include "clang/Lex/Lexer.h"
 #include 
+#include 
 #include 
 
 namespace clang {
@@ -880,228 +881,130 @@
 /// Encapsulates keywords that are context sensitive or for languages not
 /// properly supported by Clang's lexer.
 struct AdditionalKeywords {
+#define LIST_ADDITIONAL_KEYWORDS   \
+  /* Context-sensitive */  \
+  KEYWORD(final, 0)\
+  KEYWORD(override, ATTR_JS_KEYWORD | ATTR_CSHARP_KEYWORD) \
+  KEYWORD(in, ATTR_CSHARP_KEYWORD) \
+  KEYWORD(of, 0)   \
+  KEYWORD(CF_CLOSED_ENUM, 0)   \
+  KEYWORD(CF_ENUM, 0)  \
+  KEYWORD(CF_OPTIONS, 0)   \
+  KEYWORD(NS_CLOSED_ENUM, 0)   \
+  KEYWORD(NS_ENUM, 0)  \
+  KEYWORD(NS_OPTIONS, 0)   \
+  /* Javascript */ \
+  KEYWORD(as, ATTR_JS_KEYWORD | ATTR_CSHARP_KEYWORD)   \
+  KEYWORD(async, ATTR_JS_KEYWORD | ATTR_CSHARP_KEYWORD)\
+  KEYWORD(await, ATTR_JS_KEYWORD | ATTR_CSHARP_KEYWORD)\
+  KEYWORD(declare, ATTR_JS_KEYWORD | ATTR_CSHARP_KEYWORD)  \
+  KEYWORD(finally, ATTR_JS_KEYWORD | ATTR_CSHARP_KEYWORD)  \
+  KEYWORD(from, ATTR_JS_KEYWORD | ATTR_CSHARP_KEYWORD) \
+  KEYWORD(function, ATTR_JS_KEYWORD | ATTR_CSHARP_KEYWORD) \
+  KEYWOR

[PATCH] D121754: [clang-format] Refactor determineStarAmpUsage

2022-03-15 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
sstwcw added a reviewer: clang-format.
sstwcw added a project: clang-format.
Herald added a project: All.
sstwcw requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

There was some duplicate code in determineStarAmpUsage and
determinePlusMinusCaretUsage


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D121754

Files:
  clang/lib/Format/TokenAnnotator.cpp


Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2158,12 +2158,7 @@
 if (PrevToken->is(tok::r_paren) && PrevToken->is(TT_TypeDeclarationParen))
   return TT_PointerOrReference;
 
-if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace,
-   tok::comma, tok::semi, tok::kw_return, tok::colon,
-   tok::kw_co_return, tok::kw_co_await,
-   tok::kw_co_yield, tok::equal, tok::kw_delete,
-   tok::kw_sizeof, tok::kw_throw, TT_BinaryOperator,
-   TT_ConditionalExpr, TT_UnaryOperator, 
TT_CastRParen))
+if (determinePlusMinusCaretUsage(Tok) == TT_UnaryOperator)
   return TT_UnaryOperator;
 
 if (NextToken->is(tok::l_square) && NextToken->isNot(TT_LambdaLSquare))
@@ -2210,19 +2205,12 @@
 if (!PrevToken)
   return TT_UnaryOperator;
 
-if (PrevToken->isOneOf(TT_CastRParen, TT_UnaryOperator))
-  // This must be a sequence of leading unary operators.
-  return TT_UnaryOperator;
-
-// Use heuristics to recognize unary operators.
-if (PrevToken->isOneOf(tok::equal, tok::l_paren, tok::comma, tok::l_square,
-   tok::question, tok::colon, tok::kw_return,
-   tok::kw_case, tok::at, tok::l_brace, tok::kw_throw,
-   tok::kw_co_return, tok::kw_co_yield))
-  return TT_UnaryOperator;
-
-// There can't be two consecutive binary operators.
-if (PrevToken->is(TT_BinaryOperator))
+if (PrevToken->isOneOf(
+TT_BinaryOperator, TT_CastRParen, TT_ConditionalExpr,
+TT_UnaryOperator, tok::l_paren, tok::comma, tok::colon, tok::semi,
+tok::equal, tok::question, tok::at, tok::l_square, tok::l_brace,
+tok::kw_case, tok::kw_co_await, tok::kw_co_return, 
tok::kw_co_yield,
+tok::kw_delete, tok::kw_return, tok::kw_sizeof, tok::kw_throw))
   return TT_UnaryOperator;
 
 // Fall back to marking the token as binary operator.


Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2158,12 +2158,7 @@
 if (PrevToken->is(tok::r_paren) && PrevToken->is(TT_TypeDeclarationParen))
   return TT_PointerOrReference;
 
-if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace,
-   tok::comma, tok::semi, tok::kw_return, tok::colon,
-   tok::kw_co_return, tok::kw_co_await,
-   tok::kw_co_yield, tok::equal, tok::kw_delete,
-   tok::kw_sizeof, tok::kw_throw, TT_BinaryOperator,
-   TT_ConditionalExpr, TT_UnaryOperator, TT_CastRParen))
+if (determinePlusMinusCaretUsage(Tok) == TT_UnaryOperator)
   return TT_UnaryOperator;
 
 if (NextToken->is(tok::l_square) && NextToken->isNot(TT_LambdaLSquare))
@@ -2210,19 +2205,12 @@
 if (!PrevToken)
   return TT_UnaryOperator;
 
-if (PrevToken->isOneOf(TT_CastRParen, TT_UnaryOperator))
-  // This must be a sequence of leading unary operators.
-  return TT_UnaryOperator;
-
-// Use heuristics to recognize unary operators.
-if (PrevToken->isOneOf(tok::equal, tok::l_paren, tok::comma, tok::l_square,
-   tok::question, tok::colon, tok::kw_return,
-   tok::kw_case, tok::at, tok::l_brace, tok::kw_throw,
-   tok::kw_co_return, tok::kw_co_yield))
-  return TT_UnaryOperator;
-
-// There can't be two consecutive binary operators.
-if (PrevToken->is(TT_BinaryOperator))
+if (PrevToken->isOneOf(
+TT_BinaryOperator, TT_CastRParen, TT_ConditionalExpr,
+TT_UnaryOperator, tok::l_paren, tok::comma, tok::colon, tok::semi,
+tok::equal, tok::question, tok::at, tok::l_square, tok::l_brace,
+tok::kw_case, tok::kw_co_await, tok::kw_co_return, tok::kw_co_yield,
+tok::kw_delete, tok::kw_return, tok::kw_sizeof, tok::kw_throw))
   return TT_UnaryOperator;
 
 // Fall back to marking the token as binary operator.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D121755: [clang-format] Join spaceRequiredBefore and spaceRequiredBetween

2022-03-15 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
sstwcw added a reviewer: clang-format.
Herald added a project: All.
sstwcw requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

After all these years, having the two functions now serves to confuse
people.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D121755

Files:
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/TokenAnnotator.h

Index: clang/lib/Format/TokenAnnotator.h
===
--- clang/lib/Format/TokenAnnotator.h
+++ clang/lib/Format/TokenAnnotator.h
@@ -169,9 +169,6 @@
 
   bool spaceRequiredBeforeParens(const FormatToken &Right) const;
 
-  bool spaceRequiredBetween(const AnnotatedLine &Line, const FormatToken &Left,
-const FormatToken &Right);
-
   bool spaceRequiredBefore(const AnnotatedLine &Line, const FormatToken &Right);
 
   bool mustBreakBefore(const AnnotatedLine &Line, const FormatToken &Right);
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -3066,9 +3066,411 @@
   return false;
 }
 
-bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
-  const FormatToken &Left,
-  const FormatToken &Right) {
+bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
+ const FormatToken &Right) {
+  assert(Right.Previous);
+  const FormatToken &Left = *Right.Previous;
+
+  // If the token is finalized don't touch it (as it could be in a
+  // clang-format-off section).
+  if (Left.Finalized)
+return Right.hasWhitespaceBefore();
+
+  if (Right.Tok.getIdentifierInfo() && Left.Tok.getIdentifierInfo())
+return true; // Never ever merge two identifiers.
+
+  // Leave a space between * and /* to avoid C4138 `comment end` found outside
+  // of comment.
+  if (Left.is(tok::star) && Right.is(tok::comment))
+return true;
+
+  if (Style.isCpp()) {
+// Space between import .
+// or import .;
+if (Left.is(Keywords.kw_import) && Right.isOneOf(tok::less, tok::ellipsis))
+  return true;
+// Space between `module :` and `import :`.
+if (Left.isOneOf(Keywords.kw_module, Keywords.kw_import) &&
+Right.is(TT_ModulePartitionColon))
+  return true;
+// No space between import foo:bar but keep a space between import :bar;
+if (Left.is(tok::identifier) && Right.is(TT_ModulePartitionColon))
+  return false;
+// No space between :bar;
+if (Left.is(TT_ModulePartitionColon) &&
+Right.isOneOf(tok::identifier, tok::kw_private))
+  return false;
+if (Left.is(tok::ellipsis) && Right.is(tok::identifier) &&
+Line.First->is(Keywords.kw_import))
+  return false;
+// Space in __attribute__((attr)) ::type.
+if (Left.is(TT_AttributeParen) && Right.is(tok::coloncolon))
+  return true;
+
+if (Left.is(tok::kw_operator))
+  return Right.is(tok::coloncolon);
+if (Right.is(tok::l_brace) && Right.is(BK_BracedInit) &&
+!Left.opensScope() && Style.SpaceBeforeCpp11BracedList)
+  return true;
+if (Left.is(tok::less) && Left.is(TT_OverloadedOperator) &&
+Right.is(TT_TemplateOpener))
+  return true;
+  } else if (Style.Language == FormatStyle::LK_Proto ||
+ Style.Language == FormatStyle::LK_TextProto) {
+if (Right.is(tok::period) &&
+Left.isOneOf(Keywords.kw_optional, Keywords.kw_required,
+ Keywords.kw_repeated, Keywords.kw_extend))
+  return true;
+if (Right.is(tok::l_paren) &&
+Left.isOneOf(Keywords.kw_returns, Keywords.kw_option))
+  return true;
+if (Right.isOneOf(tok::l_brace, tok::less) && Left.is(TT_SelectorName))
+  return true;
+// Slashes occur in text protocol extension syntax: [type/type] { ... }.
+if (Left.is(tok::slash) || Right.is(tok::slash))
+  return false;
+if (Left.MatchingParen &&
+Left.MatchingParen->is(TT_ProtoExtensionLSquare) &&
+Right.isOneOf(tok::l_brace, tok::less))
+  return !Style.Cpp11BracedListStyle;
+// A percent is probably part of a formatting specification, such as %lld.
+if (Left.is(tok::percent))
+  return false;
+// Preserve the existence of a space before a percent for cases like 0x%04x
+// and "%d %d"
+if (Left.is(tok::numeric_constant) && Right.is(tok::percent))
+  return Right.hasWhitespaceBefore();
+  } else if (Style.isJson()) {
+if (Right.is(tok::colon))
+  return false;
+  } else if (Style.isCSharp()) {
+// Require spaces around '{' and  before '}' unless they appear in
+// interpolated strings. Interpolated strings are merged into a single token
+// so cannot have spaces inserted by this function.
+
+// No space betwe

[PATCH] D121756: [clang-format] Clean up code looking for if statements

2022-03-15 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
sstwcw added a reviewer: clang-format.
sstwcw added a project: clang-format.
Herald added a project: All.
sstwcw requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Previously several places had code to determine whether the line is an
if / while / for statement.  This commit replaces them with a function
call.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D121756

Files:
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/UnwrappedLineParser.cpp

Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -2422,8 +2422,10 @@
   } else {
 if (FormatTok->isOneOf(tok::kw_constexpr, tok::identifier))
   nextToken();
-if (FormatTok->is(tok::l_paren))
+if (FormatTok->Tok.is(tok::l_paren)) {
+  FormatTok->setType(TT_ConditionLParen);
   parseParens();
+}
   }
   handleAttributes();
 
@@ -2714,14 +2716,20 @@
 void UnwrappedLineParser::parseForOrWhileLoop() {
   assert(FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) &&
  "'for', 'while' or foreach macro expected");
+  // Those that begin with a for require special treatment because inside the
+  // parentheses is not an expression.
+  bool IsFor = FormatTok->is(tok::kw_for) || FormatTok->is(TT_ForEachMacro);
   nextToken();
   // JS' for await ( ...
   if (Style.isJavaScript() && FormatTok->is(Keywords.kw_await))
 nextToken();
   if (Style.isCpp() && FormatTok->is(tok::kw_co_await))
 nextToken();
-  if (FormatTok->is(tok::l_paren))
+  if (FormatTok->is(tok::l_paren)) {
+if (!IsFor)
+  FormatTok->setType(TT_ConditionLParen);
 parseParens();
+  }
 
   keepAncestorBraces();
 
@@ -2827,8 +2835,10 @@
 void UnwrappedLineParser::parseSwitch() {
   assert(FormatTok->is(tok::kw_switch) && "'switch' expected");
   nextToken();
-  if (FormatTok->is(tok::l_paren))
+  if (FormatTok->is(tok::l_paren)) {
+FormatTok->setType(TT_ConditionLParen);
 parseParens();
+  }
 
   keepAncestorBraces();
 
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -63,13 +63,6 @@
  Left->Previous->MatchingParen->is(TT_LambdaLSquare);
 }
 
-/// Returns \c true if the token is followed by a boolean condition, \c false
-/// otherwise.
-static bool isKeywordWithCondition(const FormatToken &Tok) {
-  return Tok.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch,
- tok::kw_constexpr, tok::kw_catch);
-}
-
 /// A parser that gathers additional information about tokens.
 ///
 /// The \c TokenAnnotator tries to match parenthesis and square brakets and
@@ -130,10 +123,9 @@
 // parameter cases, but should not alter program semantics.
 if (CurrentToken->Next && CurrentToken->Next->is(tok::greater) &&
 Left->ParentBracket != tok::less &&
-(isKeywordWithCondition(*Line.First) ||
- CurrentToken->getStartOfNonWhitespace() ==
- CurrentToken->Next->getStartOfNonWhitespace().getLocWithOffset(
- -1)))
+CurrentToken->getStartOfNonWhitespace() ==
+CurrentToken->Next->getStartOfNonWhitespace().getLocWithOffset(
+-1))
   return false;
 Left->MatchingParen = CurrentToken;
 CurrentToken->MatchingParen = Left;
@@ -257,12 +249,11 @@
   // type X = (...);
   // export type X = (...);
   Contexts.back().IsExpression = false;
-} else if (OpeningParen.Previous &&
-   (OpeningParen.Previous->isOneOf(tok::kw_static_assert,
-   tok::kw_while, tok::l_paren,
-   tok::comma) ||
-OpeningParen.Previous->isIf() ||
-OpeningParen.Previous->is(TT_BinaryOperator))) {
+} else if (OpeningParen.isConditionLParen(/*IncludeSpecial=*/false) ||
+   (OpeningParen.Previous &&
+OpeningParen.Previous->isOneOf(TT_BinaryOperator, tok::l_paren,
+   tok::comma,
+   tok::kw_static_assert))) {
   // static_assert, if and while usually contain expressions.
   Contexts.back().IsExpression = true;
 } else if (Style.isJavaScript() && OpeningParen.Previous &&
@@ -1437,17 +1428,18 @@
 // recovered from an error (e.g. failure to find the matching >).
 if (!CurrentToken->isTypeFinalized() &&
 !CurrentToken->isOneOf(
-TT_LambdaLSquare, TT_LambdaLBrace, TT_AttributeMacro, TT_IfMacro,
-TT_ForEachMacro, TT_Typename

[PATCH] D121757: [clang-format] Take out common code for parsing blocks

2022-03-15 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
sstwcw added a reviewer: clang-format.
sstwcw added a project: clang-format.
Herald added a project: All.
sstwcw requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D121757

Files:
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/lib/Format/UnwrappedLineParser.h

Index: clang/lib/Format/UnwrappedLineParser.h
===
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -125,6 +125,8 @@
   bool handleCppAttributes();
   FormatToken *parseIfThenElse(IfStmtKind *IfKind, bool KeepBraces = false);
   void parseTryCatch();
+  void parseIndentedBlock(bool BracesAreOptional = true,
+  bool RBraceOnSeparateLine = true);
   void parseForOrWhileLoop();
   void parseDoWhile();
   void parseLabel(bool LeftAlignLabel = false);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -2713,6 +2713,30 @@
   } while (!eof());
 }
 
+void UnwrappedLineParser::parseIndentedBlock(bool BracesAreOptional,
+ bool RBraceOnSeparateLine) {
+  CompoundStatementIndenter Indenter(this, Style, Line->Level);
+
+  keepAncestorBraces();
+
+  if (FormatTok->is(tok::l_brace)) {
+FormatToken *LeftBrace = FormatTok;
+parseBlock();
+if (BracesAreOptional && Style.RemoveBracesLLVM) {
+  assert(!NestedTooDeep.empty());
+  if (!NestedTooDeep.back())
+markOptionalBraces(LeftBrace);
+}
+if (RBraceOnSeparateLine)
+  addUnwrappedLine();
+  } else {
+parseUnbracedBody();
+  }
+
+  if (Style.RemoveBracesLLVM)
+NestedTooDeep.pop_back();
+}
+
 void UnwrappedLineParser::parseForOrWhileLoop() {
   assert(FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) &&
  "'for', 'while' or foreach macro expected");
@@ -2731,43 +2755,15 @@
 parseParens();
   }
 
-  keepAncestorBraces();
-
-  if (FormatTok->is(tok::l_brace)) {
-FormatToken *LeftBrace = FormatTok;
-CompoundStatementIndenter Indenter(this, Style, Line->Level);
-parseBlock();
-if (Style.RemoveBracesLLVM) {
-  assert(!NestedTooDeep.empty());
-  if (!NestedTooDeep.back())
-markOptionalBraces(LeftBrace);
-}
-addUnwrappedLine();
-  } else {
-parseUnbracedBody();
-  }
-
-  if (Style.RemoveBracesLLVM)
-NestedTooDeep.pop_back();
+  parseIndentedBlock(/*BracesAreOptional=*/true);
 }
 
 void UnwrappedLineParser::parseDoWhile() {
   assert(FormatTok->is(tok::kw_do) && "'do' expected");
   nextToken();
 
-  keepAncestorBraces();
-
-  if (FormatTok->is(tok::l_brace)) {
-CompoundStatementIndenter Indenter(this, Style, Line->Level);
-parseBlock();
-if (Style.BraceWrapping.BeforeWhile)
-  addUnwrappedLine();
-  } else {
-parseUnbracedBody();
-  }
-
-  if (Style.RemoveBracesLLVM)
-NestedTooDeep.pop_back();
+  parseIndentedBlock(/*BracesAreoptional=*/false,
+ /*RBraceOnSeparateLine=*/Style.BraceWrapping.BeforeWhile);
 
   // FIXME: Add error handling.
   if (!FormatTok->is(tok::kw_while)) {
@@ -2840,21 +2836,7 @@
 parseParens();
   }
 
-  keepAncestorBraces();
-
-  if (FormatTok->is(tok::l_brace)) {
-CompoundStatementIndenter Indenter(this, Style, Line->Level);
-parseBlock();
-addUnwrappedLine();
-  } else {
-addUnwrappedLine();
-++Line->Level;
-parseStructuralElement();
---Line->Level;
-  }
-
-  if (Style.RemoveBracesLLVM)
-NestedTooDeep.pop_back();
+  parseIndentedBlock();
 }
 
 // Operators that can follow a C variable.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D121758: [clang-format] Add support for formatting Verilog code

2022-03-15 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a subscriber: svenvh.
sstwcw added a comment.

Do we have people who use Verilog and knows the clang-format code base?  
@svenvh Your email address looks like you work for a hardware company.  If you 
know Verilog would you please have a look at this patch?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121758

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


[PATCH] D121758: [clang-format] Add support for formatting Verilog code

2022-03-15 Thread sstwcw via Phabricator via cfe-commits
sstwcw added inline comments.



Comment at: clang/lib/Format/UnwrappedLineParser.cpp:534
 continue;
-  parseBlock(/*MustBeDeclaration=*/false, /*AddLevels=*/1u,
- /*MunchSemi=*/true, /*UnindentWhitesmithBraces=*/false,
- CanContainBracedList,
+  parseBlock(/*Flags=*/CanContainBracedList * 
BLOCK_CAN_CONTAIN_BRACED_LIST,
+ /*AddLevels=*/1u,

One of the people in charge said multiplying with a boolean might trigger 
warnings.  Here I compiled with gcc.  This version doesn't trigger warnings.  
The other way to do it, `CanContainBracedList ? BLOCK_CAN_CONTAIN_BRACED_LIST : 
0`, triggers a warning that I shouldn't mix enum and integer.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121758

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


[PATCH] D121758: [clang-format] Add support for formatting Verilog code

2022-03-16 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

Somehow the bot can't create a branch when trying to merge this patch.  The 
error is failure to lock.  The error persists after restarting the process.  
Does anyone know why?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121758

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


[PATCH] D121754: [clang-format] Refactor determineStarAmpUsage

2022-03-16 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 416010.
sstwcw edited the summary of this revision.
sstwcw added a comment.

Add some test cases and use a separate function for the common parts.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121754

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
@@ -9754,6 +9754,9 @@
   verifyFormat("if (!(a->f())) {\n}");
   verifyFormat("if (!+i) {\n}");
   verifyFormat("~&a;");
+  verifyFormat("for (x = 0; -10 < x; --x) {\n}");
+  verifyFormat("sizeof -x");
+  verifyFormat("sizeof +x");
 
   verifyFormat("a-- > b;");
   verifyFormat("b ? -a : c;");
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2129,6 +2129,45 @@
 return true;
   }
 
+  /// Returns true if the token is used as a unary operator.
+  bool determineUnaryOperatorByUsage(const FormatToken &Tok) {
+const FormatToken *PrevToken = Tok.getPreviousNonComment();
+if (!PrevToken)
+  return true;
+
+// These keywords are deliberately not included here. They are either
+// included in determineStarAmpUsage or determinePlusMinusCaretUsage.
+// case - In a switch expression, the condition shall be of integral type,
+//   enumeration type, or class type, and the case label contains a constant
+//   expression. We were unable to come up with a case where the case
+//   keyword is followed by a star or amp.
+// @ - It may be followed by a unary `-` in Objective-C literals. We don't
+//   know how they can be followed by a star or amp.
+// co_await, delete - It doesn't make sense to have them followed by a unary
+//   `+` or `-`.
+if (PrevToken->isOneOf(TT_ConditionalExpr, tok::l_paren, tok::comma,
+   tok::colon, tok::semi, tok::equal, tok::question,
+   tok::l_square, tok::l_brace, tok::kw_co_return,
+   tok::kw_co_yield, tok::kw_return, tok::kw_throw))
+  return true;
+
+// We put sizeof here instead of only in determineStarAmpUsage. In the cases
+// where the unary `+` operator is overloaded, it is reasonable to write
+// things like `sizeof +x`. Like commit 446d6ec996c6c3.
+if (PrevToken->is(tok::kw_sizeof))
+  return true;
+
+// A sequence of leading unary operators.
+if (PrevToken->isOneOf(TT_CastRParen, TT_UnaryOperator))
+  return true;
+
+// There can't be two consecutive binary operators.
+if (PrevToken->is(TT_BinaryOperator))
+  return true;
+
+return false;
+  }
+
   /// Return the type of the given token assuming it is * or &.
   TokenType determineStarAmpUsage(const FormatToken &Tok, bool IsExpression,
   bool InTemplateArgument) {
@@ -2160,12 +2199,10 @@
 if (PrevToken->is(tok::r_paren) && PrevToken->is(TT_TypeDeclarationParen))
   return TT_PointerOrReference;
 
-if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace,
-   tok::comma, tok::semi, tok::kw_return, tok::colon,
-   tok::kw_co_return, tok::kw_co_await,
-   tok::kw_co_yield, tok::equal, tok::kw_delete,
-   tok::kw_sizeof, tok::kw_throw, TT_BinaryOperator,
-   TT_ConditionalExpr, TT_UnaryOperator, TT_CastRParen))
+if (determineUnaryOperatorByUsage(Tok))
+  return TT_UnaryOperator;
+
+if (PrevToken->isOneOf(tok::kw_co_await, tok::kw_delete))
   return TT_UnaryOperator;
 
 if (NextToken->is(tok::l_square) && NextToken->isNot(TT_LambdaLSquare))
@@ -2208,23 +2245,14 @@
   }
 
   TokenType determinePlusMinusCaretUsage(const FormatToken &Tok) {
+if (determineUnaryOperatorByUsage(Tok))
+  return TT_UnaryOperator;
+
 const FormatToken *PrevToken = Tok.getPreviousNonComment();
 if (!PrevToken)
   return TT_UnaryOperator;
 
-if (PrevToken->isOneOf(TT_CastRParen, TT_UnaryOperator))
-  // This must be a sequence of leading unary operators.
-  return TT_UnaryOperator;
-
-// Use heuristics to recognize unary operators.
-if (PrevToken->isOneOf(tok::equal, tok::l_paren, tok::comma, tok::l_square,
-   tok::question, tok::colon, tok::kw_return,
-   tok::kw_case, tok::at, tok::l_brace, tok::kw_throw,
-   tok::kw_co_return, tok::kw_co_yield))
-  return TT_UnaryOperator;
-
-// There can't be two consecutive binary operators.
-if (PrevToken->is(TT_BinaryOperator))
+if (PrevToken->isOneOf(tok::at, tok::kw_case))
   retur

[PATCH] D121754: [clang-format] Refactor determineStarAmpUsage

2022-03-16 Thread sstwcw via Phabricator via cfe-commits
sstwcw marked 3 inline comments as done.
sstwcw added a comment.

About the tokens that were only in one function.

question, colon, and TT_ConditionalExpr, are for same thing.  question was 
added before they added TT_ConditionalExpr.  It looks like now only 
TT_ConditionalExpr would be enough.

kw_return and kw_throw were in both functions.

kw_case, kw_co_await, and kw_delete are now only in one function like before 
this revisioin.

semi and kw_sizeof have test cases.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121754

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


[PATCH] D121757: [clang-format] Take out common code for parsing blocks

2022-03-16 Thread sstwcw via Phabricator via cfe-commits
sstwcw marked an inline comment as done.
sstwcw added inline comments.



Comment at: clang/lib/Format/UnwrappedLineParser.cpp:2851
-addUnwrappedLine();
-++Line->Level;
-parseStructuralElement();

HazardyKnusperkeks wrote:
> This is completely missing. Didn't it affect anything?
This chunk of code is already in `parseUnbracedBody`.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121757

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


[PATCH] D121755: [clang-format] Join spaceRequiredBefore and spaceRequiredBetween

2022-03-16 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 416025.
sstwcw added a comment.

Use the name spaceRequiredBetween.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121755

Files:
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/TokenAnnotator.h

Index: clang/lib/Format/TokenAnnotator.h
===
--- clang/lib/Format/TokenAnnotator.h
+++ clang/lib/Format/TokenAnnotator.h
@@ -172,8 +172,6 @@
   bool spaceRequiredBetween(const AnnotatedLine &Line, const FormatToken &Left,
 const FormatToken &Right);
 
-  bool spaceRequiredBefore(const AnnotatedLine &Line, const FormatToken &Right);
-
   bool mustBreakBefore(const AnnotatedLine &Line, const FormatToken &Right);
 
   bool canBreakBefore(const AnnotatedLine &Line, const FormatToken &Right);
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2733,7 +2733,7 @@
 }
   }
 } else if (Current->SpacesRequiredBefore == 0 &&
-   spaceRequiredBefore(Line, *Current)) {
+   spaceRequiredBetween(Line, *Prev, *Current)) {
   Current->SpacesRequiredBefore = 1;
 }
 
@@ -3071,6 +3071,406 @@
 bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
   const FormatToken &Left,
   const FormatToken &Right) {
+  // If the token is finalized don't touch it (as it could be in a
+  // clang-format-off section).
+  if (Left.Finalized)
+return Right.hasWhitespaceBefore();
+
+  if (Right.Tok.getIdentifierInfo() && Left.Tok.getIdentifierInfo())
+return true; // Never ever merge two identifiers.
+
+  // Leave a space between * and /* to avoid C4138 `comment end` found outside
+  // of comment.
+  if (Left.is(tok::star) && Right.is(tok::comment))
+return true;
+
+  if (Style.isCpp()) {
+// Space between import .
+// or import .;
+if (Left.is(Keywords.kw_import) && Right.isOneOf(tok::less, tok::ellipsis))
+  return true;
+// Space between `module :` and `import :`.
+if (Left.isOneOf(Keywords.kw_module, Keywords.kw_import) &&
+Right.is(TT_ModulePartitionColon))
+  return true;
+// No space between import foo:bar but keep a space between import :bar;
+if (Left.is(tok::identifier) && Right.is(TT_ModulePartitionColon))
+  return false;
+// No space between :bar;
+if (Left.is(TT_ModulePartitionColon) &&
+Right.isOneOf(tok::identifier, tok::kw_private))
+  return false;
+if (Left.is(tok::ellipsis) && Right.is(tok::identifier) &&
+Line.First->is(Keywords.kw_import))
+  return false;
+// Space in __attribute__((attr)) ::type.
+if (Left.is(TT_AttributeParen) && Right.is(tok::coloncolon))
+  return true;
+
+if (Left.is(tok::kw_operator))
+  return Right.is(tok::coloncolon);
+if (Right.is(tok::l_brace) && Right.is(BK_BracedInit) &&
+!Left.opensScope() && Style.SpaceBeforeCpp11BracedList)
+  return true;
+if (Left.is(tok::less) && Left.is(TT_OverloadedOperator) &&
+Right.is(TT_TemplateOpener))
+  return true;
+  } else if (Style.Language == FormatStyle::LK_Proto ||
+ Style.Language == FormatStyle::LK_TextProto) {
+if (Right.is(tok::period) &&
+Left.isOneOf(Keywords.kw_optional, Keywords.kw_required,
+ Keywords.kw_repeated, Keywords.kw_extend))
+  return true;
+if (Right.is(tok::l_paren) &&
+Left.isOneOf(Keywords.kw_returns, Keywords.kw_option))
+  return true;
+if (Right.isOneOf(tok::l_brace, tok::less) && Left.is(TT_SelectorName))
+  return true;
+// Slashes occur in text protocol extension syntax: [type/type] { ... }.
+if (Left.is(tok::slash) || Right.is(tok::slash))
+  return false;
+if (Left.MatchingParen &&
+Left.MatchingParen->is(TT_ProtoExtensionLSquare) &&
+Right.isOneOf(tok::l_brace, tok::less))
+  return !Style.Cpp11BracedListStyle;
+// A percent is probably part of a formatting specification, such as %lld.
+if (Left.is(tok::percent))
+  return false;
+// Preserve the existence of a space before a percent for cases like 0x%04x
+// and "%d %d"
+if (Left.is(tok::numeric_constant) && Right.is(tok::percent))
+  return Right.hasWhitespaceBefore();
+  } else if (Style.isJson()) {
+if (Right.is(tok::colon))
+  return false;
+  } else if (Style.isCSharp()) {
+// Require spaces around '{' and  before '}' unless they appear in
+// interpolated strings. Interpolated strings are merged into a single token
+// so cannot have spaces inserted by this function.
+
+// No space between 'this' and '['
+if (Left.is(tok::kw_this) && Right.is(tok::l_square))
+   

[PATCH] D121753: [clang-format] Use a macro for non-C keywords

2022-03-16 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 416051.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121753

Files:
  clang/lib/Format/FormatToken.h
  clang/lib/Format/UnwrappedLineFormatter.cpp
  clang/lib/Format/UnwrappedLineParser.cpp

Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1481,8 +1481,8 @@
   }
 }
 if (Style.isCpp() &&
-FormatTok->isOneOf(Keywords.kw_signals, Keywords.kw_qsignals,
-   Keywords.kw_slots, Keywords.kw_qslots)) {
+FormatTok->isOneOf(Keywords.kw_signals, Keywords.kw_Q_SIGNALS,
+   Keywords.kw_slots, Keywords.kw_Q_SLOTS)) {
   nextToken();
   if (FormatTok->is(tok::colon)) {
 nextToken();
@@ -2902,7 +2902,7 @@
   FormatToken *AccessSpecifierCandidate = FormatTok;
   nextToken();
   // Understand Qt's slots.
-  if (FormatTok->isOneOf(Keywords.kw_slots, Keywords.kw_qslots))
+  if (FormatTok->isOneOf(Keywords.kw_slots, Keywords.kw_Q_SLOTS))
 nextToken();
   // Otherwise, we don't know what it is, and we'd better keep the next token.
   if (FormatTok->is(tok::colon)) {
Index: clang/lib/Format/UnwrappedLineFormatter.cpp
===
--- clang/lib/Format/UnwrappedLineFormatter.cpp
+++ clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -112,11 +112,12 @@
   else if (RootToken.isObjCAccessSpecifier())
 return true;
   // Handle Qt signals.
-  else if ((RootToken.isOneOf(Keywords.kw_signals, Keywords.kw_qsignals) &&
+  else if ((RootToken.isOneOf(Keywords.kw_signals, Keywords.kw_Q_SIGNALS) &&
 RootToken.Next && RootToken.Next->is(tok::colon)))
 return true;
   else if (RootToken.Next &&
-   RootToken.Next->isOneOf(Keywords.kw_slots, Keywords.kw_qslots) &&
+   RootToken.Next->isOneOf(Keywords.kw_slots,
+   Keywords.kw_Q_SLOTS) &&
RootToken.Next->Next && RootToken.Next->Next->is(tok::colon))
 return true;
   // Handle malformed access specifier e.g. 'private' without trailing ':'.
Index: clang/lib/Format/FormatToken.h
===
--- clang/lib/Format/FormatToken.h
+++ clang/lib/Format/FormatToken.h
@@ -20,6 +20,7 @@
 #include "clang/Format/Format.h"
 #include "clang/Lex/Lexer.h"
 #include 
+#include 
 #include 
 
 namespace clang {
@@ -880,228 +881,129 @@
 /// Encapsulates keywords that are context sensitive or for languages not
 /// properly supported by Clang's lexer.
 struct AdditionalKeywords {
+#define LIST_ADDITIONAL_KEYWORDS   \
+  /* Context-sensitive ones that appear in C++ or ObjC.  The lexer lexes them  \
+   * as identifiers under our settings. */ \
+  KEYWORD(final, ATTR_CSHARP_KEYWORD)  \
+  KEYWORD(override, ATTR_JS_KEYWORD | ATTR_CSHARP_KEYWORD) \
+  KEYWORD(in, ATTR_CSHARP_KEYWORD) \
+  KEYWORD(of, 0)   \
+  KEYWORD(CF_CLOSED_ENUM, 0)   \
+  KEYWORD(CF_ENUM, 0)  \
+  KEYWORD(CF_OPTIONS, 0)   \
+  KEYWORD(NS_CLOSED_ENUM, 0)   \
+  KEYWORD(NS_ENUM, 0)  \
+  KEYWORD(NS_OPTIONS, 0)   \
+  /* Javascript */ \
+  KEYWORD(as, ATTR_JS_KEYWORD | ATTR_CSHARP_KEYWORD)   \
+  KEYWORD(async, ATTR_JS_KEYWORD | ATTR_CSHARP_KEYWORD)\
+  KEYWORD(await, ATTR_JS_KEYWORD | ATTR_CSHARP_KEYWORD)\
+  KEYWORD(declare, ATTR_JS_KEYWORD | ATTR_CSHARP_KEYWORD)  \
+  KEYWORD(finally, ATTR_JS_KEYWORD | ATTR_CSHARP_KEYWORD)  \
+  KEYWORD(from, ATTR_JS_KEYWORD | ATTR_CSHARP_KEYWORD) \
+  KEYWORD(function, ATTR_JS_KEYWORD | ATTR_CSHARP_KEYWORD) \
+  KEYWORD(get, ATTR_JS_KEYWORD | ATTR_CSHARP_KEYWORD)  \
+  KEYWORD(import, ATTR_JS_KEYWORD | ATTR_CSHARP_KEYWORD)   \
+  KEYWORD(infer, 0)\
+  KEYWORD(is, ATTR_JS_KEYWORD | ATTR_CSHARP_KEYWORD)   \
+  KEYWORD(let, ATTR_JS_KEYWORD | ATTR_CSHARP_KEYWORD)  \
+  KEYWORD(module, ATTR_JS_KEYWOR

[PATCH] D121753: [clang-format] Use a macro for non-C keywords

2022-03-16 Thread sstwcw via Phabricator via cfe-commits
sstwcw marked 5 inline comments as done.
sstwcw added inline comments.



Comment at: clang/lib/Format/FormatToken.h:947
+  /* C# */ 
\
+  KEYWORD(dollar, 0)   
\
+  KEYWORD(base, ATTR_CSHARP_KEYWORD)   
\

HazardyKnusperkeks wrote:
> Why not CSharp?
It was not in the original set for C# keywords.  But since MyDeveloperDay also 
pointed it out I guess he simply forgot.



Comment at: clang/lib/Format/FormatToken.h:992-999
+  enum {
+ATTR_JS_KEYWORD = 0x1,
+ATTR_CSHARP_KEYWORD = 0x2,
+  };
+  unsigned getAttrs(const FormatToken &Tok) const {
+auto At = KeywordAttr.find(Tok.Tok.getIdentifierInfo());
+return At == KeywordAttr.end() ? 0u : At->second;

HazardyKnusperkeks wrote:
> No fan of DEFINE_LIKE_NAMES. More a fan of scoped::enums. ;)
It looks like I would have to use the `KeywordLanguage::` prefix throughout the 
macro list and also define an operator to combine categories for keywords that 
several languages have.  Do you know of a simpler way?  With the current enum, 
the DEFINE_LIKE_NAMES can't be used directly outside `AdditionalKeywords`.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121753

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


[PATCH] D121756: [clang-format] Clean up code looking for if statements

2022-03-16 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 416052.
sstwcw edited the summary of this revision.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121756

Files:
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  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
@@ -660,6 +660,49 @@
   EXPECT_TOKEN(Tokens[9], tok::l_brace, TT_ObjCBlockLBrace);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsConditionParen) {
+  auto Tokens = annotate("if (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+  Tokens = annotate("if constexpr (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_ConditionLParen);
+  Tokens = annotate("if CONSTEXPR (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_ConditionLParen);
+
+  // The parentheses following for is not TT_ConditionLParen, because inside is
+  // not just a condition.
+  Tokens = annotate("for (;;) {\n}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown);
+  Tokens = annotate("foreach (Item *item, itemlist) {\n}");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown);
+  Tokens = annotate("Q_FOREACH (Item *item, itemlist) {\n}");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown);
+  Tokens = annotate("BOOST_FOREACH (Item *item, itemlist) {\n}");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_Unknown);
+  Tokens = annotate("try {\n"
+"} catch (Exception &bar) {\n"
+"}");
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_Unknown);
+
+  Tokens = annotate("while (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+  Tokens = annotate("do {\n} while (true);");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_ConditionLParen);
+
+  Tokens = annotate("switch (true) {\n}");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+}
+
 } // namespace
 } // namespace format
 } // namespace clang
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -2422,8 +2422,10 @@
   } else {
 if (FormatTok->isOneOf(tok::kw_constexpr, tok::identifier))
   nextToken();
-if (FormatTok->is(tok::l_paren))
+if (FormatTok->Tok.is(tok::l_paren)) {
+  FormatTok->setFinalizedType(TT_ConditionLParen);
   parseParens();
+}
   }
   handleAttributes();
 
@@ -2714,14 +2716,20 @@
 void UnwrappedLineParser::parseForOrWhileLoop() {
   assert(FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) &&
  "'for', 'while' or foreach macro expected");
+  // Those that begin with a for require special treatment because inside the
+  // parentheses is not an expression.
+  bool IsFor = FormatTok->is(tok::kw_for) || FormatTok->is(TT_ForEachMacro);
   nextToken();
   // JS' for await ( ...
   if (Style.isJavaScript() && FormatTok->is(Keywords.kw_await))
 nextToken();
   if (Style.isCpp() && FormatTok->is(tok::kw_co_await))
 nextToken();
-  if (FormatTok->is(tok::l_paren))
+  if (FormatTok->is(tok::l_paren)) {
+if (!IsFor)
+  FormatTok->setFinalizedType(TT_ConditionLParen);
 parseParens();
+  }
 
   keepAncestorBraces();
 
@@ -2773,6 +2781,9 @@
 ++Line->Level;
 
   nextToken();
+  // FIXME: Add error handling.
+  if (FormatTok->is(tok::l_paren))
+FormatTok->setFinalizedType(TT_ConditionLParen);
   parseStructuralElement();
 }
 
@@ -2827,8 +2838,10 @@
 void UnwrappedLineParser::parseSwitch() {
   assert(FormatTok->is(tok::kw_switch) && "'switch' expected");
   nextToken();
-  if (FormatTok->is(tok::l_paren))
+  if (FormatTok->is(tok::l_paren)) {
+FormatTok->setFinalizedType(TT_ConditionLParen);
 parseParens();
+  }
 
   keepAncestorBraces();
 
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -63,13 +63,6 @@
  Left->Previous->MatchingParen->is(TT_LambdaLSquare);
 }
 
-/// Returns \c true if the token is followed by a boolean condition, \c false
-/// otherwise.
-static bool isKeywordW

[PATCH] D121756: [clang-format] Clean up code looking for if statements

2022-03-16 Thread sstwcw via Phabricator via cfe-commits
sstwcw marked 4 inline comments as done.
sstwcw added inline comments.



Comment at: clang/lib/Format/TokenAnnotator.cpp:133
 Left->ParentBracket != tok::less &&
-(isKeywordWithCondition(*Line.First) ||
- CurrentToken->getStartOfNonWhitespace() ==

HazardyKnusperkeks wrote:
> Any reason why one doesn't need this check anymore?
The next check already covers what the first is supposed to cover, as explained 
in the commit message.



Comment at: clang/lib/Format/TokenAnnotator.cpp:1431-1442
+TT_AttributeMacro, TT_BracedListLBrace, TT_ClassLBrace,
+TT_CompoundRequirementLBrace, TT_ConditionLParen, TT_EnumLBrace,
+TT_FatArrow, TT_ForEachMacro, TT_FunctionLBrace,
+TT_FunctionLikeOrFreestandingMacro, TT_IfMacro,
+TT_ImplicitStringLiteral, TT_InlineASMBrace, TT_LambdaArrow,
+TT_LambdaLBrace, TT_LambdaLSquare, TT_NamespaceMacro,
+TT_ObjCStringLiteral, TT_OverloadedOperator, TT_RecordLBrace,

HazardyKnusperkeks wrote:
> Unrelated Change.
Sorry.  This part has changed several times in the main line since I started 
working on this patch.  After a few merge conflicts I got tired and started 
running sort uniq on this part.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121756

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


[PATCH] D121890: [clang-format] Copy help options to the doc directory.

2022-03-17 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
sstwcw added a reviewer: clang-format.
sstwcw added a project: clang-format.
Herald added a project: All.
sstwcw requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

The options listed in ClangFormat.rst lag behind those output by the
-help command line option.  Specifically, these are missing.

--files
--qualifier-alignment


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D121890

Files:
  clang/docs/ClangFormat.rst

Index: clang/docs/ClangFormat.rst
===
--- clang/docs/ClangFormat.rst
+++ clang/docs/ClangFormat.rst
@@ -28,74 +28,71 @@
 
   OPTIONS:
 
-  Clang-format options:
-
---Werror   - If set, changes formatting warnings to errors
---Wno-error=- If set don't error out on the specified warning type.
-  =unknown -   If set, unknown format options are only warned about.
-   This can be used to enable formatting, even if the
-   configuration contains unknown (newer) options.
-   Use with caution, as this might lead to dramatically
-   differing format depending on an option being
-   supported or not.
---assume-filename= - Override filename used to determine the language.
- When reading from stdin, clang-format assumes this
- filename to determine the language.
---cursor=- The position of the cursor when invoking
- clang-format from an editor integration
---dry-run  - If set, do not actually make the formatting changes
---dump-config  - Dump configuration options to stdout and exit.
- Can be used with -style option.
---fallback-style=  - The name of the predefined style used as a
- fallback in case clang-format is invoked with
- -style=file, but can not find the .clang-format
- file to use.
- Use -fallback-style=none to skip formatting.
---ferror-limit=  - Set the maximum number of clang-format errors to
- emit before stopping (0 = no limit). Used only
- with --dry-run or -n
--i - Inplace edit s, if specified.
---length=- Format a range of this length (in bytes).
- Multiple ranges can be formatted by specifying
- several -offset and -length pairs.
- When only a single -offset is specified without
- -length, clang-format will format up to the end
- of the file.
- Can only be used with one input file.
---lines=   - : - format a range of
- lines (both 1-based).
- Multiple ranges can be formatted by specifying
- several -lines arguments.
- Can't be used with -offset and -length.
- Can only be used with one input file.
--n - Alias for --dry-run
---offset=- Format a range starting at this byte offset.
- Multiple ranges can be formatted by specifying
- several -offset and -length pairs.
- Can only be used with one input file.
---output-replacements-xml  - Output replacements as XML.
---sort-includes- If set, overrides the include sorting behavior
- determined by the SortIncludes style flag
---style=   - Coding style, currently supports:
-   LLVM, Google, Chromium, Mozilla, WebKit.
- Use -style=file to load style configuration from
- .clang-format file located in one of the parent
- directories of the source file (or current
- directory for stdin).
- Use -style=file: to load style
- configuration from a format file located at
- . This path can be absolute or
- relative to the working directory.
- Use -style="{key: value, ...}" to set specific
- parameters, e.g.:
-   -style="{BasedOnSt

[PATCH] D121890: [clang-format] Copy help options to the doc directory.

2022-03-17 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 416097.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121890

Files:
  clang/docs/ClangFormat.rst

Index: clang/docs/ClangFormat.rst
===
--- clang/docs/ClangFormat.rst
+++ clang/docs/ClangFormat.rst
@@ -30,72 +30,69 @@
 
   Clang-format options:
 
---Werror   - If set, changes formatting warnings to errors
---Wno-error=- If set don't error out on the specified warning type.
-  =unknown -   If set, unknown format options are only warned about.
-   This can be used to enable formatting, even if the
-   configuration contains unknown (newer) options.
-   Use with caution, as this might lead to dramatically
-   differing format depending on an option being
-   supported or not.
---assume-filename= - Override filename used to determine the language.
- When reading from stdin, clang-format assumes this
- filename to determine the language.
---cursor=- The position of the cursor when invoking
- clang-format from an editor integration
---dry-run  - If set, do not actually make the formatting changes
---dump-config  - Dump configuration options to stdout and exit.
- Can be used with -style option.
---fallback-style=  - The name of the predefined style used as a
- fallback in case clang-format is invoked with
- -style=file, but can not find the .clang-format
- file to use.
- Use -fallback-style=none to skip formatting.
---ferror-limit=  - Set the maximum number of clang-format errors to
- emit before stopping (0 = no limit). Used only
- with --dry-run or -n
--i - Inplace edit s, if specified.
---length=- Format a range of this length (in bytes).
- Multiple ranges can be formatted by specifying
- several -offset and -length pairs.
- When only a single -offset is specified without
- -length, clang-format will format up to the end
- of the file.
- Can only be used with one input file.
---lines=   - : - format a range of
- lines (both 1-based).
- Multiple ranges can be formatted by specifying
- several -lines arguments.
- Can't be used with -offset and -length.
- Can only be used with one input file.
--n - Alias for --dry-run
---offset=- Format a range starting at this byte offset.
- Multiple ranges can be formatted by specifying
- several -offset and -length pairs.
- Can only be used with one input file.
---output-replacements-xml  - Output replacements as XML.
---sort-includes- If set, overrides the include sorting behavior
- determined by the SortIncludes style flag
---style=   - Coding style, currently supports:
-   LLVM, Google, Chromium, Mozilla, WebKit.
- Use -style=file to load style configuration from
- .clang-format file located in one of the parent
- directories of the source file (or current
- directory for stdin).
- Use -style=file: to load style
- configuration from a format file located at
- . This path can be absolute or
- relative to the working directory.
- Use -style="{key: value, ...}" to set specific
- parameters, e.g.:
-   -style="{BasedOnStyle: llvm, IndentWidth: 8}"
---verbose  - If set, shows the list of processed files
+--Werror   - If set, changes formatting warnings to errors
+--Wno-error=- If set don't error out on the specified warning type.
+  =unknown -   I

[PATCH] D121890: [clang-format] Copy help options to the doc directory.

2022-03-17 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

If anyone's wondering why all the lines changed.  The `--qualifier-alignment` 
is too long so all the descriptions are moved to the right.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121890

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


[PATCH] D121890: [clang-format] Copy help options to the doc directory.

2022-03-17 Thread sstwcw via Phabricator via cfe-commits
sstwcw added inline comments.



Comment at: clang/docs/ClangFormat.rst:76
+--output-replacements-xml  - Output replacements as XML.
+--qualifier-alignment= - If set, overrides the qualifier alignment 
style determined by the QualifierAlignment style flag
+--sort-includes- If set, overrides the include sorting 
behavior determined by the SortIncludes style flag

curdeius wrote:
> Shouldn't long descriptions like this one be split into multiple lines and 
> aligned with `-`?
> Did you do it by hand or with some script?
It was not split in the `-help` output.  I copied the output from a terminal by 
hand.  If you run `clang-format -help` from the latest git build in an 
80-column terminal you will see that output is all over the place.  The options 
that were broken into lines have hard line breaks lin 
`clang/tools/clang-format/ClangFormat.cpp`.  But now with the 
`--qualifier-alignment` option being too wide even those got pushed over 80 
columns.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121890

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


[PATCH] D121906: [clang-format] Indent import statements in JavaScript.

2022-03-17 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
sstwcw added a reviewer: clang-format.
sstwcw added a project: clang-format.
Herald added a project: All.
sstwcw requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

[clang-format] Indent import statements in JavaScript.

Take for example this piece of code found at
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import.

for (const link of document.querySelectorAll("nav > a")) {

  link.addEventListener("click", e => {
e.preventDefault();
  
import('/modules/my-module.js')
.then(module => {
  module.loadPageInto(main);
})
.catch(err => {
  main.textContent = err.message;
});
  });

}

Previously the import line would be unindented, looking like this.

for (const link of document.querySelectorAll("nav > a")) {

  link.addEventListener("click", e => {
e.preventDefault();

import('/modules/my-module.js')

.then(module => {
  module.loadPageInto(main);
})
.catch(err => {
  main.textContent = err.message;
});
  });

}

Actually we were going to fix this along with fixing Verilog import
statements.  But the patch got too big.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D121906

Files:
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/UnwrappedLineFormatter.cpp
  clang/unittests/Format/FormatTestJS.cpp


Index: clang/unittests/Format/FormatTestJS.cpp
===
--- clang/unittests/Format/FormatTestJS.cpp
+++ clang/unittests/Format/FormatTestJS.cpp
@@ -1868,6 +1868,11 @@
   " myX} from 'm';");
   verifyFormat("import * as lib from 'some/module.js';");
   verifyFormat("var x = {import: 1};\nx.import = 2;");
+  // Ensure an import statement inside a block is at the correct level.
+  verifyFormat("function() {\n"
+   "  var x;\n"
+   "  import 'some/module.js';\n"
+   "}");
 
   verifyFormat("export function fn() {\n"
"  return 'fn';\n"
Index: clang/lib/Format/UnwrappedLineFormatter.cpp
===
--- clang/lib/Format/UnwrappedLineFormatter.cpp
+++ clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -1431,8 +1431,10 @@
   if (Newlines)
 Indent = NewlineIndent;
 
-  // Preprocessor directives get indented before the hash only if specified
-  if (Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
+  // Preprocessor directives get indented before the hash only if specified. In
+  // Javascript import statements are indented like normal statements.
+  if (Style.Language != FormatStyle::LK_JavaScript &&
+  Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
   (Line.Type == LT_PreprocessorDirective ||
Line.Type == LT_ImportStatement))
 Indent = 0;
Index: clang/lib/Format/ContinuationIndenter.cpp
===
--- clang/lib/Format/ContinuationIndenter.cpp
+++ clang/lib/Format/ContinuationIndenter.cpp
@@ -623,9 +623,11 @@
 
   unsigned Spaces = Current.SpacesRequiredBefore + ExtraSpaces;
 
-  // Indent preprocessor directives after the hash if required.
+  // Indent preprocessor directives after the hash if required. In Javascript
+  // import statements are indented like normal statements.
   int PPColumnCorrection = 0;
-  if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash &&
+  if (Style.Language != FormatStyle::LK_JavaScript &&
+  Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash &&
   Previous.is(tok::hash) && State.FirstIndent > 0 &&
   (State.Line->Type == LT_PreprocessorDirective ||
State.Line->Type == LT_ImportStatement)) {


Index: clang/unittests/Format/FormatTestJS.cpp
===
--- clang/unittests/Format/FormatTestJS.cpp
+++ clang/unittests/Format/FormatTestJS.cpp
@@ -1868,6 +1868,11 @@
   " myX} from 'm';");
   verifyFormat("import * as lib from 'some/module.js';");
   verifyFormat("var x = {import: 1};\nx.import = 2;");
+  // Ensure an import statement inside a block is at the correct level.
+  verifyFormat("function() {\n"
+   "  var x;\n"
+   "  import 'some/module.js';\n"
+   "}");
 
   verifyFormat("export function fn() {\n"
"  return 'fn';\n"
Index: clang/lib/Format/UnwrappedLineFormatter.cpp
===
--- clang/lib/Format/UnwrappedLineFormatter.cpp
+++ clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -1431,8 +1431,10 @@
   if (Newlines)
 Indent = NewlineIndent;
 
-  // Preprocessor directives get indented before the hash only if specified
-  if (Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
+  /

[PATCH] D121907: [clang-format] Use an enum for context types.

2022-03-17 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
sstwcw added a reviewer: clang-format.
sstwcw added a project: clang-format.
Herald added a project: All.
sstwcw requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

We currently have all those fields in AnnotatingParser::Context.  They
are not inherited from the Context object for the parent scope.  They
are exclusive.  Now they are replaced with an enum.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D121907

Files:
  clang/lib/Format/TokenAnnotator.cpp

Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -113,8 +113,8 @@
 Contexts.back().IsExpression = false;
 // If there's a template keyword before the opening angle bracket, this is a
 // template parameter, not an argument.
-Contexts.back().InTemplateArgument =
-Left->Previous && Left->Previous->isNot(tok::kw_template);
+if (Left->Previous && Left->Previous->isNot(tok::kw_template))
+  Contexts.back().ContextType = Context::TemplateArgument;
 
 if (Style.Language == FormatStyle::LK_Java &&
 CurrentToken->is(tok::question))
@@ -288,7 +288,7 @@
 } else if (OpeningParen.Previous &&
OpeningParen.Previous->is(TT_ForEachMacro)) {
   // The first argument to a foreach macro is a declaration.
-  Contexts.back().IsForEachMacro = true;
+  Contexts.back().ContextType = Context::ForEachMacro;
   Contexts.back().IsExpression = false;
 } else if (OpeningParen.Previous && OpeningParen.Previous->MatchingParen &&
OpeningParen.Previous->MatchingParen->is(TT_ObjCBlockLParen)) {
@@ -558,7 +558,7 @@
 bool CppArrayTemplates =
 Style.isCpp() && Parent && Parent->is(TT_TemplateCloser) &&
 (Contexts.back().CanBeExpression || Contexts.back().IsExpression ||
- Contexts.back().InTemplateArgument);
+ Contexts.back().ContextType == Context::TemplateArgument);
 
 bool IsCpp11AttributeSpecifier = isCpp11AttributeSpecifier(*Left) ||
  Contexts.back().InCpp11AttributeSpecifier;
@@ -803,7 +803,7 @@
 if (Style.AlignArrayOfStructures != FormatStyle::AIAS_None) {
   if (OpeningBrace.ParentBracket == tok::l_brace &&
   couldBeInStructArrayInitializer() && CommaCount > 0)
-Contexts.back().InStructArrayInitializer = true;
+Contexts.back().ContextType = Context::StructArrayInitializer;
 }
 next();
 return true;
@@ -1157,16 +1157,22 @@
   parseTemplateDeclaration();
   break;
 case tok::comma:
-  if (Contexts.back().InCtorInitializer)
+  switch (Contexts.back().ContextType) {
+  case Context::CtorInitializer:
 Tok->setType(TT_CtorInitializerComma);
-  else if (Contexts.back().InInheritanceList)
+break;
+  case Context::InheritanceList:
 Tok->setType(TT_InheritanceComma);
-  else if (Contexts.back().FirstStartOfName &&
-   (Contexts.size() == 1 || startsWithInitStatement(Line))) {
-Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt = true;
-Line.IsMultiVariableDeclStmt = true;
+break;
+  default:
+if (Contexts.back().FirstStartOfName &&
+(Contexts.size() == 1 || startsWithInitStatement(Line))) {
+  Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt = true;
+  Line.IsMultiVariableDeclStmt = true;
+}
+break;
   }
-  if (Contexts.back().IsForEachMacro)
+  if (Contexts.back().ContextType == Context::ForEachMacro)
 Contexts.back().IsExpression = true;
   break;
 case tok::identifier:
@@ -1411,7 +1417,7 @@
 }
 
 for (const auto &ctx : Contexts)
-  if (ctx.InStructArrayInitializer)
+  if (ctx.ContextType == Context::StructArrayInitializer)
 return LT_ArrayOfStructInitializer;
 
 return LT_Other;
@@ -1488,14 +1494,27 @@
 FormatToken *FirstObjCSelectorName = nullptr;
 FormatToken *FirstStartOfName = nullptr;
 bool CanBeExpression = true;
-bool InTemplateArgument = false;
-bool InCtorInitializer = false;
-bool InInheritanceList = false;
 bool CaretFound = false;
-bool IsForEachMacro = false;
+// These two are not handled like the rest in ContextType because they are
+// not exclusive.
 bool InCpp11AttributeSpecifier = false;
 bool InCSharpAttributeSpecifier = false;
-bool InStructArrayInitializer = false;
+enum {
+  Unknown,
+  // Like the part after `:` in a constructor.
+  //   Context(...) : IsExpression(IsExpression)
+  CtorInitializer,
+  // Like in the parentheses in a foreach.
+  ForEachMacro,
+  // Like the inheritance list in a class declaration.
+  //   class Input : public IO
+  Inheritance

[PATCH] D121757: [clang-format] Take out common code for parsing blocks

2022-03-17 Thread sstwcw via Phabricator via cfe-commits
sstwcw marked an inline comment as done.
sstwcw added a comment.

This patch is only intended to reduce the number of times the functionality 
gets implemented separately.  Any change in behavior would be unintended.  And 
we also use the `parseIndentedBlock` in Verilog stuff, so it's not just two 
places.  I will wait for the check-clang result to see what to do.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121757

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


[PATCH] D121890: [clang-format] Copy help options to the doc directory.

2022-03-17 Thread sstwcw via Phabricator via cfe-commits
sstwcw marked an inline comment as done.
sstwcw added a comment.

The issue is #54418.

Actually I don't know who I should add as reviewers.  The patches for
clang-format don't always seem to have the same reviewers.  Who are the
main developers and how do you decide who you add each time?

I give up making the doc generated.  It would require either integrating
into the build process or writing a parser script like for the style
options.  Besides, that file is not entirely generated.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121890

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


[PATCH] D121758: [clang-format] Add support for formatting Verilog code

2022-03-17 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

Yes.  I am surprised that you asked since everyone asked me to break it apart.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121758

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


[PATCH] D121749: [clang-format][docs] Regenerate ClangFormatStyleOptions.rst

2022-03-17 Thread sstwcw via Phabricator via cfe-commits
sstwcw added inline comments.



Comment at: clang/docs/ClangFormatStyleOptions.rst:361
 
-  * ``bool AlignCompound`` Only for ``AlignConsecutiveAssignments``.  Whether 
compound
-assignments like ``+=`` are aligned along with ``=``.
+  * ``bool AlignCompound`` Only for ``AlignConsecutiveAssignments``.  Whether 
compound assignments
+like ``+=`` are aligned along with ``=``.

MyDeveloperDay wrote:
> Is this wider than 80 chars?
The comment in the source code is within 80 columns.  The python script 
prepended the option name.  It's the same case as line 1541.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121749

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


[PATCH] D121757: [clang-format] Take out common code for parsing blocks

2022-03-17 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

For the new stuff I have the option of still adding the function 
`parseIndentedBlock` but only using it in new code.  Please be more blunt about 
whether I should close this revision and do it that way.  I guess I might have 
misunderstood you before from how you reacted when I closed the large patch.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121757

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


[PATCH] D121754: [clang-format] Refactor determineStarAmpUsage

2022-03-18 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 416450.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121754

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
@@ -80,6 +80,88 @@
   EXPECT_TOKEN(Tokens[11], tok::star, TT_UnaryOperator);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsUsesOfPlusAndMinus) {
+  auto Tokens = annotate("x - 0");
+  EXPECT_EQ(Tokens.size(), 4u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_BinaryOperator);
+  Tokens = annotate("0 + 0");
+  EXPECT_EQ(Tokens.size(), 4u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_BinaryOperator);
+  Tokens = annotate("x + +0");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("x ? -0 : +0");
+  EXPECT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator);
+  EXPECT_TOKEN(Tokens[5], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("(-0)");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("0, -0");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("for (; -1;) {\n}");
+  EXPECT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("x = -1;");
+  EXPECT_EQ(Tokens.size(), 6u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("x[-1]");
+  EXPECT_EQ(Tokens.size(), 6u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("x = {-1};");
+  EXPECT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("co_await -x;");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("co_return -x;");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("co_yield -x;");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("delete -x;");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("return -x;");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("throw -x;");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("sizeof -x");
+  EXPECT_EQ(Tokens.size(), 4u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("co_await +x;");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("co_return +x;");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("co_yield +x;");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("delete +x;");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("return +x;");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("throw +x;");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("sizeof +x");
+  EXPECT_EQ(Tokens.size(), 4u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("(int)-x");
+  EXPECT_EQ(Tokens.size(), 6u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("!+x");
+  EXPECT_EQ(Tokens.size(), 4u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+}
+
 TEST_F(TokenAnnotatorTest, UnderstandsClasses) {
   auto Tokens = annotate("class C {};");
   EXPECT_EQ(Tokens.size(), 6u) << Tokens;
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -9753,6 +9753,11 @@
   verifyFormat("if (!(a->f())) {\n}");
   verifyFormat("if (!+i) {\n}");
   verifyFormat("~&a;");
+  verifyFormat("for (x = 0; -10 < x; --x) {\n}");
+  verifyFormat("sizeof -x");
+  verifyFormat("sizeof +x");
+  verifyFormat("delete +x;");
+  verifyFormat("co_await +x;");
 
   verifyFormat("a-- > b;");
   verifyFormat("b ? -a : c;");
Index: clang/lib/Format/Toke

[PATCH] D121890: [clang-format] Copy help options to the doc directory.

2022-03-18 Thread sstwcw via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGfee94803f59d: [clang-format] Copy help options to the doc 
directory. (authored by sstwcw).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121890

Files:
  clang/docs/ClangFormat.rst

Index: clang/docs/ClangFormat.rst
===
--- clang/docs/ClangFormat.rst
+++ clang/docs/ClangFormat.rst
@@ -30,72 +30,69 @@
 
   Clang-format options:
 
---Werror   - If set, changes formatting warnings to errors
---Wno-error=- If set don't error out on the specified warning type.
-  =unknown -   If set, unknown format options are only warned about.
-   This can be used to enable formatting, even if the
-   configuration contains unknown (newer) options.
-   Use with caution, as this might lead to dramatically
-   differing format depending on an option being
-   supported or not.
---assume-filename= - Override filename used to determine the language.
- When reading from stdin, clang-format assumes this
- filename to determine the language.
---cursor=- The position of the cursor when invoking
- clang-format from an editor integration
---dry-run  - If set, do not actually make the formatting changes
---dump-config  - Dump configuration options to stdout and exit.
- Can be used with -style option.
---fallback-style=  - The name of the predefined style used as a
- fallback in case clang-format is invoked with
- -style=file, but can not find the .clang-format
- file to use.
- Use -fallback-style=none to skip formatting.
---ferror-limit=  - Set the maximum number of clang-format errors to
- emit before stopping (0 = no limit). Used only
- with --dry-run or -n
--i - Inplace edit s, if specified.
---length=- Format a range of this length (in bytes).
- Multiple ranges can be formatted by specifying
- several -offset and -length pairs.
- When only a single -offset is specified without
- -length, clang-format will format up to the end
- of the file.
- Can only be used with one input file.
---lines=   - : - format a range of
- lines (both 1-based).
- Multiple ranges can be formatted by specifying
- several -lines arguments.
- Can't be used with -offset and -length.
- Can only be used with one input file.
--n - Alias for --dry-run
---offset=- Format a range starting at this byte offset.
- Multiple ranges can be formatted by specifying
- several -offset and -length pairs.
- Can only be used with one input file.
---output-replacements-xml  - Output replacements as XML.
---sort-includes- If set, overrides the include sorting behavior
- determined by the SortIncludes style flag
---style=   - Coding style, currently supports:
-   LLVM, Google, Chromium, Mozilla, WebKit.
- Use -style=file to load style configuration from
- .clang-format file located in one of the parent
- directories of the source file (or current
- directory for stdin).
- Use -style=file: to load style
- configuration from a format file located at
- . This path can be absolute or
- relative to the working directory.
- Use -style="{key: value, ...}" to set specific
- parameters, e.g.:
-   -style="{BasedOnStyle: llvm, IndentWidth: 8}"
---verbose  - If set, shows the list of processed files
+--Werror   - If set, changes formatting warni

[PATCH] D121754: [clang-format] Refactor determineStarAmpUsage

2022-03-18 Thread sstwcw via Phabricator via cfe-commits
sstwcw marked 5 inline comments as done.
sstwcw added inline comments.



Comment at: clang/lib/Format/TokenAnnotator.cpp:2146-2147
+//   know how they can be followed by a star or amp.
+// co_await, delete - It doesn't make sense to have them followed by a 
unary
+//   `+` or `-`.
+if (PrevToken->isOneOf(TT_ConditionalExpr, tok::l_paren, tok::comma,

MyDeveloperDay wrote:
> HazardyKnusperkeks wrote:
> > Especially here, why should a `+` after `delete` be a binary operator?
> > How much sense it makes doesn't matter, it is valid c++: 
> > https://gcc.godbolt.org/z/c1x1nn3Ej
> I'm also trying to understand did you mean you couldn't have
> 
> case -1:
> case +1:
> case +0:
> case  -0:
> 
> https://gcc.godbolt.org/z/qvE44d5xz
In the new version `+` following `delete` is a unary operator.  Previously I 
was under the impression that we only formatted code that is sensible.



Comment at: clang/lib/Format/TokenAnnotator.cpp:2146-2147
+//   know how they can be followed by a star or amp.
+// co_await, delete - It doesn't make sense to have them followed by a 
unary
+//   `+` or `-`.
+if (PrevToken->isOneOf(TT_ConditionalExpr, tok::l_paren, tok::comma,

sstwcw wrote:
> MyDeveloperDay wrote:
> > HazardyKnusperkeks wrote:
> > > Especially here, why should a `+` after `delete` be a binary operator?
> > > How much sense it makes doesn't matter, it is valid c++: 
> > > https://gcc.godbolt.org/z/c1x1nn3Ej
> > I'm also trying to understand did you mean you couldn't have
> > 
> > case -1:
> > case +1:
> > case +0:
> > case  -0:
> > 
> > https://gcc.godbolt.org/z/qvE44d5xz
> In the new version `+` following `delete` is a unary operator.  Previously I 
> was under the impression that we only formatted code that is sensible.
> case -1:
> case +1:

I meant we couldn't have things like `case *x` or `case &x`.  Is the comment 
not clear enough?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121754

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


[PATCH] D121906: [clang-format] Indent import statements in JavaScript.

2022-03-18 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 416456.
sstwcw added a comment.

use `isJavascript`


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121906

Files:
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/UnwrappedLineFormatter.cpp
  clang/unittests/Format/FormatTestJS.cpp


Index: clang/unittests/Format/FormatTestJS.cpp
===
--- clang/unittests/Format/FormatTestJS.cpp
+++ clang/unittests/Format/FormatTestJS.cpp
@@ -1868,6 +1868,11 @@
   " myX} from 'm';");
   verifyFormat("import * as lib from 'some/module.js';");
   verifyFormat("var x = {import: 1};\nx.import = 2;");
+  // Ensure an import statement inside a block is at the correct level.
+  verifyFormat("function() {\n"
+   "  var x;\n"
+   "  import 'some/module.js';\n"
+   "}");
 
   verifyFormat("export function fn() {\n"
"  return 'fn';\n"
Index: clang/lib/Format/UnwrappedLineFormatter.cpp
===
--- clang/lib/Format/UnwrappedLineFormatter.cpp
+++ clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -1431,8 +1431,10 @@
   if (Newlines)
 Indent = NewlineIndent;
 
-  // Preprocessor directives get indented before the hash only if specified
-  if (Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
+  // Preprocessor directives get indented before the hash only if specified. In
+  // Javascript import statements are indented like normal statements.
+  if (!Style.isJavaScript() &&
+  Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
   (Line.Type == LT_PreprocessorDirective ||
Line.Type == LT_ImportStatement))
 Indent = 0;
Index: clang/lib/Format/ContinuationIndenter.cpp
===
--- clang/lib/Format/ContinuationIndenter.cpp
+++ clang/lib/Format/ContinuationIndenter.cpp
@@ -623,9 +623,11 @@
 
   unsigned Spaces = Current.SpacesRequiredBefore + ExtraSpaces;
 
-  // Indent preprocessor directives after the hash if required.
+  // Indent preprocessor directives after the hash if required. In Javascript
+  // import statements are indented like normal statements.
   int PPColumnCorrection = 0;
-  if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash &&
+  if (!Style.isJavaScript() &&
+  Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash &&
   Previous.is(tok::hash) && State.FirstIndent > 0 &&
   (State.Line->Type == LT_PreprocessorDirective ||
State.Line->Type == LT_ImportStatement)) {


Index: clang/unittests/Format/FormatTestJS.cpp
===
--- clang/unittests/Format/FormatTestJS.cpp
+++ clang/unittests/Format/FormatTestJS.cpp
@@ -1868,6 +1868,11 @@
   " myX} from 'm';");
   verifyFormat("import * as lib from 'some/module.js';");
   verifyFormat("var x = {import: 1};\nx.import = 2;");
+  // Ensure an import statement inside a block is at the correct level.
+  verifyFormat("function() {\n"
+   "  var x;\n"
+   "  import 'some/module.js';\n"
+   "}");
 
   verifyFormat("export function fn() {\n"
"  return 'fn';\n"
Index: clang/lib/Format/UnwrappedLineFormatter.cpp
===
--- clang/lib/Format/UnwrappedLineFormatter.cpp
+++ clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -1431,8 +1431,10 @@
   if (Newlines)
 Indent = NewlineIndent;
 
-  // Preprocessor directives get indented before the hash only if specified
-  if (Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
+  // Preprocessor directives get indented before the hash only if specified. In
+  // Javascript import statements are indented like normal statements.
+  if (!Style.isJavaScript() &&
+  Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
   (Line.Type == LT_PreprocessorDirective ||
Line.Type == LT_ImportStatement))
 Indent = 0;
Index: clang/lib/Format/ContinuationIndenter.cpp
===
--- clang/lib/Format/ContinuationIndenter.cpp
+++ clang/lib/Format/ContinuationIndenter.cpp
@@ -623,9 +623,11 @@
 
   unsigned Spaces = Current.SpacesRequiredBefore + ExtraSpaces;
 
-  // Indent preprocessor directives after the hash if required.
+  // Indent preprocessor directives after the hash if required. In Javascript
+  // import statements are indented like normal statements.
   int PPColumnCorrection = 0;
-  if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash &&
+  if (!Style.isJavaScript() &&
+  Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash &&
   Previous.is(tok::hash) && State.FirstIndent > 0 &&
   (State.Line->Type == LT_P

[PATCH] D121907: [clang-format] Use an enum for context types.

2022-03-18 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 416458.
sstwcw added a comment.

Remove comment.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121907

Files:
  clang/lib/Format/TokenAnnotator.cpp

Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -113,8 +113,8 @@
 Contexts.back().IsExpression = false;
 // If there's a template keyword before the opening angle bracket, this is a
 // template parameter, not an argument.
-Contexts.back().InTemplateArgument =
-Left->Previous && Left->Previous->isNot(tok::kw_template);
+if (Left->Previous && Left->Previous->isNot(tok::kw_template))
+  Contexts.back().ContextType = Context::TemplateArgument;
 
 if (Style.Language == FormatStyle::LK_Java &&
 CurrentToken->is(tok::question))
@@ -288,7 +288,7 @@
 } else if (OpeningParen.Previous &&
OpeningParen.Previous->is(TT_ForEachMacro)) {
   // The first argument to a foreach macro is a declaration.
-  Contexts.back().IsForEachMacro = true;
+  Contexts.back().ContextType = Context::ForEachMacro;
   Contexts.back().IsExpression = false;
 } else if (OpeningParen.Previous && OpeningParen.Previous->MatchingParen &&
OpeningParen.Previous->MatchingParen->is(TT_ObjCBlockLParen)) {
@@ -558,7 +558,7 @@
 bool CppArrayTemplates =
 Style.isCpp() && Parent && Parent->is(TT_TemplateCloser) &&
 (Contexts.back().CanBeExpression || Contexts.back().IsExpression ||
- Contexts.back().InTemplateArgument);
+ Contexts.back().ContextType == Context::TemplateArgument);
 
 bool IsCpp11AttributeSpecifier = isCpp11AttributeSpecifier(*Left) ||
  Contexts.back().InCpp11AttributeSpecifier;
@@ -803,7 +803,7 @@
 if (Style.AlignArrayOfStructures != FormatStyle::AIAS_None) {
   if (OpeningBrace.ParentBracket == tok::l_brace &&
   couldBeInStructArrayInitializer() && CommaCount > 0)
-Contexts.back().InStructArrayInitializer = true;
+Contexts.back().ContextType = Context::StructArrayInitializer;
 }
 next();
 return true;
@@ -1157,16 +1157,22 @@
   parseTemplateDeclaration();
   break;
 case tok::comma:
-  if (Contexts.back().InCtorInitializer)
+  switch (Contexts.back().ContextType) {
+  case Context::CtorInitializer:
 Tok->setType(TT_CtorInitializerComma);
-  else if (Contexts.back().InInheritanceList)
+break;
+  case Context::InheritanceList:
 Tok->setType(TT_InheritanceComma);
-  else if (Contexts.back().FirstStartOfName &&
-   (Contexts.size() == 1 || startsWithInitStatement(Line))) {
-Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt = true;
-Line.IsMultiVariableDeclStmt = true;
+break;
+  default:
+if (Contexts.back().FirstStartOfName &&
+(Contexts.size() == 1 || startsWithInitStatement(Line))) {
+  Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt = true;
+  Line.IsMultiVariableDeclStmt = true;
+}
+break;
   }
-  if (Contexts.back().IsForEachMacro)
+  if (Contexts.back().ContextType == Context::ForEachMacro)
 Contexts.back().IsExpression = true;
   break;
 case tok::identifier:
@@ -1411,7 +1417,7 @@
 }
 
 for (const auto &ctx : Contexts)
-  if (ctx.InStructArrayInitializer)
+  if (ctx.ContextType == Context::StructArrayInitializer)
 return LT_ArrayOfStructInitializer;
 
 return LT_Other;
@@ -1488,14 +1494,25 @@
 FormatToken *FirstObjCSelectorName = nullptr;
 FormatToken *FirstStartOfName = nullptr;
 bool CanBeExpression = true;
-bool InTemplateArgument = false;
-bool InCtorInitializer = false;
-bool InInheritanceList = false;
 bool CaretFound = false;
-bool IsForEachMacro = false;
 bool InCpp11AttributeSpecifier = false;
 bool InCSharpAttributeSpecifier = false;
-bool InStructArrayInitializer = false;
+enum {
+  Unknown,
+  // Like the part after `:` in a constructor.
+  //   Context(...) : IsExpression(IsExpression)
+  CtorInitializer,
+  // Like in the parentheses in a foreach.
+  ForEachMacro,
+  // Like the inheritance list in a class declaration.
+  //   class Input : public IO
+  InheritanceList,
+  // Like in the braced list.
+  //   int x[] = {};
+  StructArrayInitializer,
+  // Like in `static_cast`.
+  TemplateArgument,
+} ContextType = Unknown;
   };
 
   /// Puts a new \c Context onto the stack \c Contexts for the lifetime
@@ -1513,9 +1530,9 @@
 
 ~ScopedContextCreator() {
   if (P.Style.AlignArrayOfStructures != FormatStyle::AIAS_None) {

[PATCH] D121907: [clang-format] Use an enum for context types. NFC

2022-03-18 Thread sstwcw via Phabricator via cfe-commits
sstwcw marked 2 inline comments as done.
sstwcw added a comment.

In D121907#3390226 , @MyDeveloperDay 
wrote:

> So out of interest, what is the reason? my assumption is that you wanted to 
> add more for Verilog and you felt adding the extra bools was the wrong design 
> and its better an an enum

You are right.

>   bool InCpp11AttributeSpecifier = false;
>   bool InCSharpAttributeSpecifier = false;
>
> Does the fact that some aren't exclusive make you think its ok to split it 
> into enums and bools is ok?  (no real opinion just wondered what you and 
> others think?)

Does it make me think it's ok? Yes. Good? No. I am lazy and I chose this way 
which doesn't require examining those two options.




Comment at: clang/lib/Format/TokenAnnotator.cpp:116
 // template parameter, not an argument.
-Contexts.back().InTemplateArgument =
-Left->Previous && Left->Previous->isNot(tok::kw_template);
+if (Left->Previous && Left->Previous->isNot(tok::kw_template))
+  Contexts.back().ContextType = Context::TemplateArgument;

owenpan wrote:
> If this was bug, it should be in a separate patch with test cases added.
Sorry that the previous patch did not include more context.  Pun intended.  Now 
you can scroll up and see that the context was just initialized, so 
`InTemplateArgument` starts being false, so it didn't matter whether the 
original code was `InTemplateArgument = ...;` or `if (...) InTemplateArgument = 
true;`.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121907

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


[PATCH] D121755: [clang-format] Join spaceRequiredBefore and spaceRequiredBetween

2022-03-18 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

By the way, last time I used a breakpoint on `spaceRequiredBefore` and stepped 
until return.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121755

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


[PATCH] D121906: [clang-format] Indent import statements in JavaScript.

2022-03-18 Thread sstwcw via Phabricator via cfe-commits
sstwcw marked an inline comment as done.
sstwcw added inline comments.



Comment at: clang/lib/Format/ContinuationIndenter.cpp:631
+  Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash &&
   Previous.is(tok::hash) && State.FirstIndent > 0 &&
   (State.Line->Type == LT_PreprocessorDirective ||

MyDeveloperDay wrote:
> can I check? is this case really firing? i mean isn't it
> 
> `# import`
> 
> why would javascript be seeing that?
In Javascript import statements also need some special handling. So the line is 
intentionally labeled as LT_ImportStatement. In `AnnotatingParser::parseLine` 
there is this.
```
if (Style.isJavaScript() && CurrentToken->is(Keywords.kw_import))
  ImportStatement = true;
```
I don't know why the line type isn't printed in 
`TokenAnnotator::printDebugInfo`.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121906

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


[PATCH] D121907: [clang-format] Use an enum for context types. NFC

2022-03-21 Thread sstwcw via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
sstwcw marked an inline comment as done.
Closed by commit rG8c31b68f4876: [clang-format] Use an enum for context types. 
NFC (authored by sstwcw).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121907

Files:
  clang/lib/Format/TokenAnnotator.cpp

Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -113,8 +113,8 @@
 Contexts.back().IsExpression = false;
 // If there's a template keyword before the opening angle bracket, this is a
 // template parameter, not an argument.
-Contexts.back().InTemplateArgument =
-Left->Previous && Left->Previous->isNot(tok::kw_template);
+if (Left->Previous && Left->Previous->isNot(tok::kw_template))
+  Contexts.back().ContextType = Context::TemplateArgument;
 
 if (Style.Language == FormatStyle::LK_Java &&
 CurrentToken->is(tok::question))
@@ -288,7 +288,7 @@
 } else if (OpeningParen.Previous &&
OpeningParen.Previous->is(TT_ForEachMacro)) {
   // The first argument to a foreach macro is a declaration.
-  Contexts.back().IsForEachMacro = true;
+  Contexts.back().ContextType = Context::ForEachMacro;
   Contexts.back().IsExpression = false;
 } else if (OpeningParen.Previous && OpeningParen.Previous->MatchingParen &&
OpeningParen.Previous->MatchingParen->is(TT_ObjCBlockLParen)) {
@@ -558,7 +558,7 @@
 bool CppArrayTemplates =
 Style.isCpp() && Parent && Parent->is(TT_TemplateCloser) &&
 (Contexts.back().CanBeExpression || Contexts.back().IsExpression ||
- Contexts.back().InTemplateArgument);
+ Contexts.back().ContextType == Context::TemplateArgument);
 
 bool IsCpp11AttributeSpecifier = isCpp11AttributeSpecifier(*Left) ||
  Contexts.back().InCpp11AttributeSpecifier;
@@ -803,7 +803,7 @@
 if (Style.AlignArrayOfStructures != FormatStyle::AIAS_None) {
   if (OpeningBrace.ParentBracket == tok::l_brace &&
   couldBeInStructArrayInitializer() && CommaCount > 0)
-Contexts.back().InStructArrayInitializer = true;
+Contexts.back().ContextType = Context::StructArrayInitializer;
 }
 next();
 return true;
@@ -1157,16 +1157,22 @@
   parseTemplateDeclaration();
   break;
 case tok::comma:
-  if (Contexts.back().InCtorInitializer)
+  switch (Contexts.back().ContextType) {
+  case Context::CtorInitializer:
 Tok->setType(TT_CtorInitializerComma);
-  else if (Contexts.back().InInheritanceList)
+break;
+  case Context::InheritanceList:
 Tok->setType(TT_InheritanceComma);
-  else if (Contexts.back().FirstStartOfName &&
-   (Contexts.size() == 1 || startsWithInitStatement(Line))) {
-Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt = true;
-Line.IsMultiVariableDeclStmt = true;
+break;
+  default:
+if (Contexts.back().FirstStartOfName &&
+(Contexts.size() == 1 || startsWithInitStatement(Line))) {
+  Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt = true;
+  Line.IsMultiVariableDeclStmt = true;
+}
+break;
   }
-  if (Contexts.back().IsForEachMacro)
+  if (Contexts.back().ContextType == Context::ForEachMacro)
 Contexts.back().IsExpression = true;
   break;
 case tok::identifier:
@@ -1411,7 +1417,7 @@
 }
 
 for (const auto &ctx : Contexts)
-  if (ctx.InStructArrayInitializer)
+  if (ctx.ContextType == Context::StructArrayInitializer)
 return LT_ArrayOfStructInitializer;
 
 return LT_Other;
@@ -1488,14 +1494,25 @@
 FormatToken *FirstObjCSelectorName = nullptr;
 FormatToken *FirstStartOfName = nullptr;
 bool CanBeExpression = true;
-bool InTemplateArgument = false;
-bool InCtorInitializer = false;
-bool InInheritanceList = false;
 bool CaretFound = false;
-bool IsForEachMacro = false;
 bool InCpp11AttributeSpecifier = false;
 bool InCSharpAttributeSpecifier = false;
-bool InStructArrayInitializer = false;
+enum {
+  Unknown,
+  // Like the part after `:` in a constructor.
+  //   Context(...) : IsExpression(IsExpression)
+  CtorInitializer,
+  // Like in the parentheses in a foreach.
+  ForEachMacro,
+  // Like the inheritance list in a class declaration.
+  //   class Input : public IO
+  InheritanceList,
+  // Like in the braced list.
+  //   int x[] = {};
+  StructArrayInitializer,
+  // Like in `static_cast`.
+  TemplateArgument,
+} ContextType = Unknown;
   };
 
   /// Pu

[PATCH] D121754: [clang-format] Refactor determineStarAmpUsage

2022-03-21 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 417115.
sstwcw marked an inline comment as done.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121754

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
@@ -78,6 +78,102 @@
   EXPECT_EQ(Tokens.size(), 21u) << Tokens;
   EXPECT_TOKEN(Tokens[10], tok::ampamp, TT_BinaryOperator);
   EXPECT_TOKEN(Tokens[11], tok::star, TT_UnaryOperator);
+
+  Tokens = annotate("case *x:");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::star, TT_UnaryOperator);
+  Tokens = annotate("case &x:");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::amp, TT_UnaryOperator);
+}
+
+TEST_F(TokenAnnotatorTest, UnderstandsUsesOfPlusAndMinus) {
+  auto Tokens = annotate("x - 0");
+  EXPECT_EQ(Tokens.size(), 4u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_BinaryOperator);
+  Tokens = annotate("0 + 0");
+  EXPECT_EQ(Tokens.size(), 4u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_BinaryOperator);
+  Tokens = annotate("x + +0");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("x ? -0 : +0");
+  EXPECT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator);
+  EXPECT_TOKEN(Tokens[5], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("(-0)");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("0, -0");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("for (; -1;) {\n}");
+  EXPECT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("x = -1;");
+  EXPECT_EQ(Tokens.size(), 6u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("x[-1]");
+  EXPECT_EQ(Tokens.size(), 6u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("x = {-1};");
+  EXPECT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("case -x:");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("co_await -x;");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("co_return -x;");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("co_yield -x;");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("delete -x;");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("return -x;");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("throw -x;");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("sizeof -x");
+  EXPECT_EQ(Tokens.size(), 4u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("co_await +x;");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("co_return +x;");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("co_yield +x;");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("delete +x;");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("return +x;");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("throw +x;");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("sizeof +x");
+  EXPECT_EQ(Tokens.size(), 4u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT_UnaryOperator);
+  Tokens = annotate("(int)-x");
+  EXPECT_EQ(Tokens.size(), 6u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("(-x)");
+  EXPECT_EQ(Tokens.size(), 5u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_UnaryOperator);
+  Tokens = annotate("!+x");
+  EXPECT_EQ(Tokens.size(), 4u) << Tokens;
+  EXPECT_TOKEN(Tokens[0], tok::exclaim, TT_UnaryOperator);
+  EXPECT_TOKEN(Tokens[1], tok::plus, TT

[PATCH] D121754: [clang-format] Refactor determineStarAmpUsage

2022-03-21 Thread sstwcw via Phabricator via cfe-commits
sstwcw marked 5 inline comments as done.
sstwcw added inline comments.



Comment at: clang/unittests/Format/TokenAnnotatorTest.cpp:85
+  auto Tokens = annotate("x - 0");
+  EXPECT_EQ(Tokens.size(), 4u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::minus, TT_BinaryOperator);

HazardyKnusperkeks wrote:
> I know the other cases also use EXPECT, but the size should be an ASSERT, so 
> there would be no seg fault if the number would change (it shouldn't).
I tried a wrong number and `EXPECT_EQ` didn't give a segfault.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121754

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


[PATCH] D121916: [clang-format] [doc] Add script to automatically update help output in ClangFormat.rst.

2022-03-21 Thread sstwcw via Phabricator via cfe-commits
sstwcw added inline comments.



Comment at: clang/docs/tools/dump_format_help.py:29
+def get_help_output():
+args = ["clang-format", "--help"]
+cmd = subprocess.Popen(args, stdout=subprocess.PIPE,

You intentionally did not write `build/bin/clang-format` to accommodate people 
who build in other directories, right? Sorry this comment is late.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121916

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


[PATCH] D121906: [clang-format] Indent import statements in JavaScript.

2022-03-21 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 417125.
sstwcw marked an inline comment as done.
sstwcw added a comment.

remove unnecessary check


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121906

Files:
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/UnwrappedLineFormatter.cpp
  clang/unittests/Format/FormatTestJS.cpp


Index: clang/unittests/Format/FormatTestJS.cpp
===
--- clang/unittests/Format/FormatTestJS.cpp
+++ clang/unittests/Format/FormatTestJS.cpp
@@ -1868,6 +1868,11 @@
   " myX} from 'm';");
   verifyFormat("import * as lib from 'some/module.js';");
   verifyFormat("var x = {import: 1};\nx.import = 2;");
+  // Ensure an import statement inside a block is at the correct level.
+  verifyFormat("function() {\n"
+   "  var x;\n"
+   "  import 'some/module.js';\n"
+   "}");
 
   verifyFormat("export function fn() {\n"
"  return 'fn';\n"
Index: clang/lib/Format/UnwrappedLineFormatter.cpp
===
--- clang/lib/Format/UnwrappedLineFormatter.cpp
+++ clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -1431,8 +1431,10 @@
   if (Newlines)
 Indent = NewlineIndent;
 
-  // Preprocessor directives get indented before the hash only if specified
-  if (Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
+  // Preprocessor directives get indented before the hash only if specified. In
+  // Javascript import statements are indented like normal statements.
+  if (!Style.isJavaScript() &&
+  Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
   (Line.Type == LT_PreprocessorDirective ||
Line.Type == LT_ImportStatement))
 Indent = 0;
Index: clang/lib/Format/ContinuationIndenter.cpp
===
--- clang/lib/Format/ContinuationIndenter.cpp
+++ clang/lib/Format/ContinuationIndenter.cpp
@@ -623,7 +623,8 @@
 
   unsigned Spaces = Current.SpacesRequiredBefore + ExtraSpaces;
 
-  // Indent preprocessor directives after the hash if required.
+  // Indent preprocessor directives after the hash if required. In Javascript
+  // import statements are indented like normal statements.
   int PPColumnCorrection = 0;
   if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash &&
   Previous.is(tok::hash) && State.FirstIndent > 0 &&


Index: clang/unittests/Format/FormatTestJS.cpp
===
--- clang/unittests/Format/FormatTestJS.cpp
+++ clang/unittests/Format/FormatTestJS.cpp
@@ -1868,6 +1868,11 @@
   " myX} from 'm';");
   verifyFormat("import * as lib from 'some/module.js';");
   verifyFormat("var x = {import: 1};\nx.import = 2;");
+  // Ensure an import statement inside a block is at the correct level.
+  verifyFormat("function() {\n"
+   "  var x;\n"
+   "  import 'some/module.js';\n"
+   "}");
 
   verifyFormat("export function fn() {\n"
"  return 'fn';\n"
Index: clang/lib/Format/UnwrappedLineFormatter.cpp
===
--- clang/lib/Format/UnwrappedLineFormatter.cpp
+++ clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -1431,8 +1431,10 @@
   if (Newlines)
 Indent = NewlineIndent;
 
-  // Preprocessor directives get indented before the hash only if specified
-  if (Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
+  // Preprocessor directives get indented before the hash only if specified. In
+  // Javascript import statements are indented like normal statements.
+  if (!Style.isJavaScript() &&
+  Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
   (Line.Type == LT_PreprocessorDirective ||
Line.Type == LT_ImportStatement))
 Indent = 0;
Index: clang/lib/Format/ContinuationIndenter.cpp
===
--- clang/lib/Format/ContinuationIndenter.cpp
+++ clang/lib/Format/ContinuationIndenter.cpp
@@ -623,7 +623,8 @@
 
   unsigned Spaces = Current.SpacesRequiredBefore + ExtraSpaces;
 
-  // Indent preprocessor directives after the hash if required.
+  // Indent preprocessor directives after the hash if required. In Javascript
+  // import statements are indented like normal statements.
   int PPColumnCorrection = 0;
   if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash &&
   Previous.is(tok::hash) && State.FirstIndent > 0 &&
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D121906: [clang-format] Indent import statements in JavaScript.

2022-03-21 Thread sstwcw via Phabricator via cfe-commits
sstwcw marked an inline comment as done.
sstwcw added inline comments.



Comment at: clang/lib/Format/ContinuationIndenter.cpp:633
   (State.Line->Type == LT_PreprocessorDirective ||
State.Line->Type == LT_ImportStatement)) {
 Spaces += State.FirstIndent;

MyDeveloperDay wrote:
> AfterHash  - Could be true
> Previous is hash - Can't be true can it?
> FirstIndent > 0 - I guess could be true
> State.Line->Type being LT_ImportStatement could be true..
> 
> true && false && true && true == false right?
> 
> Remove `!Style.isJavaScript()` from this, does your test still pass?
> 
> Either add the second test to cover this case or remove the condition, I 
> don't mind either way.
I undid the change here.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121906

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


[PATCH] D121906: [clang-format] Indent import statements in JavaScript.

2022-03-21 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 417128.
sstwcw marked an inline comment as done.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121906

Files:
  clang/lib/Format/UnwrappedLineFormatter.cpp
  clang/unittests/Format/FormatTestJS.cpp


Index: clang/unittests/Format/FormatTestJS.cpp
===
--- clang/unittests/Format/FormatTestJS.cpp
+++ clang/unittests/Format/FormatTestJS.cpp
@@ -1868,6 +1868,11 @@
   " myX} from 'm';");
   verifyFormat("import * as lib from 'some/module.js';");
   verifyFormat("var x = {import: 1};\nx.import = 2;");
+  // Ensure an import statement inside a block is at the correct level.
+  verifyFormat("function() {\n"
+   "  var x;\n"
+   "  import 'some/module.js';\n"
+   "}");
 
   verifyFormat("export function fn() {\n"
"  return 'fn';\n"
Index: clang/lib/Format/UnwrappedLineFormatter.cpp
===
--- clang/lib/Format/UnwrappedLineFormatter.cpp
+++ clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -1431,8 +1431,10 @@
   if (Newlines)
 Indent = NewlineIndent;
 
-  // Preprocessor directives get indented before the hash only if specified
-  if (Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
+  // Preprocessor directives get indented before the hash only if specified. In
+  // Javascript import statements are indented like normal statements.
+  if (!Style.isJavaScript() &&
+  Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
   (Line.Type == LT_PreprocessorDirective ||
Line.Type == LT_ImportStatement))
 Indent = 0;


Index: clang/unittests/Format/FormatTestJS.cpp
===
--- clang/unittests/Format/FormatTestJS.cpp
+++ clang/unittests/Format/FormatTestJS.cpp
@@ -1868,6 +1868,11 @@
   " myX} from 'm';");
   verifyFormat("import * as lib from 'some/module.js';");
   verifyFormat("var x = {import: 1};\nx.import = 2;");
+  // Ensure an import statement inside a block is at the correct level.
+  verifyFormat("function() {\n"
+   "  var x;\n"
+   "  import 'some/module.js';\n"
+   "}");
 
   verifyFormat("export function fn() {\n"
"  return 'fn';\n"
Index: clang/lib/Format/UnwrappedLineFormatter.cpp
===
--- clang/lib/Format/UnwrappedLineFormatter.cpp
+++ clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -1431,8 +1431,10 @@
   if (Newlines)
 Indent = NewlineIndent;
 
-  // Preprocessor directives get indented before the hash only if specified
-  if (Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
+  // Preprocessor directives get indented before the hash only if specified. In
+  // Javascript import statements are indented like normal statements.
+  if (!Style.isJavaScript() &&
+  Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
   (Line.Type == LT_PreprocessorDirective ||
Line.Type == LT_ImportStatement))
 Indent = 0;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D121753: [clang-format] Use a macro for non-C keywords

2022-03-21 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

Allow me another attempt in justifying this patch.

Using the macros, it is easier to see when a keyword is not classified as some 
language's keyword.  The author and reviewers didn't notice `final` and 
`dollar` being in only one place previously.  With the old way, when someone 
adds a new keyword he is also more likely to forget to include it in the sets.

In the commit message when I said the old way turned out to be error-prone, I 
did debug why some code doesn't get formatted right only to find I forgot to 
add a keyword in one of the places.

With the `isIdentifier` and `isKeyword` functions matching the sets separately, 
it is more likely one of them will get it wrong.  In the original 
`isCSharpKeyword` function, the check is wrong, it should be `!=`.

  CSharpExtraKeywords.find(Tok.Tok.getIdentifierInfo()) == 
CSharpExtraKeywords.end()


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121753

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


[PATCH] D121756: [clang-format] Clean up code looking for if statements

2022-03-21 Thread sstwcw via Phabricator via cfe-commits
sstwcw marked 2 inline comments as done.
sstwcw added a comment.

It turned out this patch does change behavior.

  -  while (
  -  FormatTok->isOneOf(tok::identifier, tok::kw_requires, 
tok::coloncolon)) {
  +  while (FormatTok->isOneOf(tok::identifier, tok::kw_requires,
  +tok::coloncolon)) {

So what do I do?

And what's the regression suite?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121756

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


[PATCH] D123450: [clang-format] Parse Verilog if statements

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

This patch mainly handles treating `begin` as block openers.

While and for statements will be handled in another patch.

We added an alias option in FormatToken to treat a token as another
token.  This way when some language uses an alternative symbol like
backtick for hash we can continue using tok::hash in the code.  For
keywords like `begin`, left braces aren't block openers in if
expressions while they are in structs and enums.  That means we can't
simply treat `begin` and the left brace the same way.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D123450

Files:
  clang/docs/ClangFormat.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/FormatToken.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/QualifierAlignmentFixer.cpp
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/UnwrappedLineFormatter.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/tools/clang-format/ClangFormat.cpp
  clang/unittests/Format/CMakeLists.txt
  clang/unittests/Format/FormatTestUtils.h
  clang/unittests/Format/FormatTestVerilog.cpp

Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- /dev/null
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -0,0 +1,118 @@
+//===- unittest/Format/FormatTestVerilog.cpp --===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "FormatTestUtils.h"
+#include "clang/Format/Format.h"
+#include "llvm/Support/Debug.h"
+#include "gtest/gtest.h"
+
+#define DEBUG_TYPE "format-test"
+
+namespace clang {
+namespace format {
+
+class FormatTestVerilog : public ::testing::Test {
+protected:
+  static std::string format(llvm::StringRef Code, unsigned Offset,
+unsigned Length, const FormatStyle &Style) {
+LLVM_DEBUG(llvm::errs() << "---\n");
+LLVM_DEBUG(llvm::errs() << Code << "\n\n");
+std::vector Ranges(1, tooling::Range(Offset, Length));
+tooling::Replacements Replaces = reformat(Style, Code, Ranges);
+auto Result = applyAllReplacements(Code, Replaces);
+EXPECT_TRUE(static_cast(Result));
+LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
+return *Result;
+  }
+
+  static std::string format(llvm::StringRef Code, const FormatStyle &Style) {
+return format(Code, 0, Code.size(), Style);
+  }
+
+  static void verifyFormat(
+  llvm::StringRef Code,
+  const FormatStyle &Style = getLLVMStyle(FormatStyle::LK_Verilog)) {
+EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable";
+EXPECT_EQ(Code.str(),
+  format(test::messUp(Code, /*HandleHash=*/false), Style));
+  }
+};
+
+TEST_F(FormatTestVerilog, If) {
+  verifyFormat("if (x)\n"
+   "  x = x;");
+  verifyFormat("if (x)\n"
+   "  x = x;\n"
+   "x = x;");
+
+  // Test else
+  verifyFormat("if (x)\n"
+   "  x = x;\n"
+   "else if (x)\n"
+   "  x = x;\n"
+   "else\n"
+   "  x = x;");
+  verifyFormat("if (x) begin\n"
+   "  x = x;\n"
+   "end else if (x) begin\n"
+   "  x = x;\n"
+   "end else begin\n"
+   "  x = x;\n"
+   "end");
+  verifyFormat("if (x) begin : x\n"
+   "  x = x;\n"
+   "end : x else if (x) begin : x\n"
+   "  x = x;\n"
+   "end : x else begin : x\n"
+   "  x = x;\n"
+   "end : x");
+
+  // Test block keywords.
+  verifyFormat("if (x) begin\n"
+   "  x = x;\n"
+   "end");
+  verifyFormat("if (x) begin : x\n"
+   "  x = x;\n"
+   "end : x");
+  verifyFormat("if (x) begin\n"
+   "  x = x;\n"
+   "  x = x;\n"
+   "end");
+  verifyFormat("disable fork;\n"
+   "x = x;");
+  verifyFormat("rand join x x;\n"
+   "x = x;");
+  verifyFormat("if (x) fork\n"
+   "  x = x;\n"
+   "join");
+  verifyFormat("if (x) fork\n"
+   "  x = x;\n"
+   "join_any");
+  verifyFormat("if (x) fork\n"
+   "  x = x;\n"
+   "join_none");
+  verifyFormat("if (x) generate\n"
+   "  x = x;\n"
+   "endgenerate");
+  verifyFormat("if (x) generate : x\n"
+   "  x = x;\n"
+   "endgenerate : x");
+
+  // Te

[PATCH] D121916: [clang-format] [doc] Add script to automatically update help output in ClangFormat.rst.

2022-04-09 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

It looks like you forgot to chmod +x.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121916

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


[PATCH] D123450: [clang-format] Parse Verilog if statements

2022-04-09 Thread sstwcw via Phabricator via cfe-commits
sstwcw added inline comments.



Comment at: clang/lib/Format/FormatToken.h:1157
+VerilogExtraKeywords = std::unordered_set(
+{kw_always,   kw_always_comb,  kw_always_ff,kw_always_latch,
+ kw_assert,   kw_assign,   kw_assume,   kw_automatic,

Does anyone know why this part gets aligned unlike the two lists above?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D123450

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


[PATCH] D123450: [clang-format] Parse Verilog if statements

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



Comment at: clang/lib/Format/FormatToken.h:374
+  /// Verilog we want to treat the backtick like a hash.
+  tok::TokenKind AliasToken = tok::unknown;
+

HazardyKnusperkeks wrote:
> Can't we do that with a type?
> 
> I'm not very happy about the alias, because you can still call 
> `Tok.getKind()`.
The main problem I seek to solve with the alias thing is with `tok::hash`.  In 
Verilog they use a backtick instead of a hash.  At first I modified all places 
in the code to recognize the backtick.  MyDeveloperDay said "year really not 
nice.. its like we can never use tok::hash again!"  Using a type also requires 
modifying all instances of tok::hash if I get you right.  How do I please 
everyone?



Comment at: clang/lib/Format/FormatToken.h:1157
+VerilogExtraKeywords = std::unordered_set(
+{kw_always,   kw_always_comb,  kw_always_ff,kw_always_latch,
+ kw_assert,   kw_assign,   kw_assume,   kw_automatic,

HazardyKnusperkeks wrote:
> sstwcw wrote:
> > Does anyone know why this part gets aligned unlike the two lists above?
> Have you reformatted the other lines with the same config and revision?
> If yes, my guess would be the missing comment.
It was the missing comment.



Comment at: clang/lib/Format/FormatToken.h:1533
+switch (Tok.Tok.getKind()) {
+case tok::kw_case:
+case tok::kw_class:

HazardyKnusperkeks wrote:
> So you have a blacklist what is not a keyword? Seems a bit non future proof, 
> new C++ keywords would have to be added here.
This is a whitelist of what is a keyword.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D123450

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


[PATCH] D123450: [clang-format] Parse Verilog if statements

2022-04-11 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 422049.
sstwcw marked 2 inline comments as done.
sstwcw added a comment.

add comment


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D123450

Files:
  clang/docs/ClangFormat.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/FormatToken.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/QualifierAlignmentFixer.cpp
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/UnwrappedLineFormatter.cpp
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/tools/clang-format/ClangFormat.cpp
  clang/unittests/Format/CMakeLists.txt
  clang/unittests/Format/FormatTestUtils.h
  clang/unittests/Format/FormatTestVerilog.cpp

Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- /dev/null
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -0,0 +1,118 @@
+//===- unittest/Format/FormatTestVerilog.cpp --===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "FormatTestUtils.h"
+#include "clang/Format/Format.h"
+#include "llvm/Support/Debug.h"
+#include "gtest/gtest.h"
+
+#define DEBUG_TYPE "format-test"
+
+namespace clang {
+namespace format {
+
+class FormatTestVerilog : public ::testing::Test {
+protected:
+  static std::string format(llvm::StringRef Code, unsigned Offset,
+unsigned Length, const FormatStyle &Style) {
+LLVM_DEBUG(llvm::errs() << "---\n");
+LLVM_DEBUG(llvm::errs() << Code << "\n\n");
+std::vector Ranges(1, tooling::Range(Offset, Length));
+tooling::Replacements Replaces = reformat(Style, Code, Ranges);
+auto Result = applyAllReplacements(Code, Replaces);
+EXPECT_TRUE(static_cast(Result));
+LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
+return *Result;
+  }
+
+  static std::string format(llvm::StringRef Code, const FormatStyle &Style) {
+return format(Code, 0, Code.size(), Style);
+  }
+
+  static void verifyFormat(
+  llvm::StringRef Code,
+  const FormatStyle &Style = getLLVMStyle(FormatStyle::LK_Verilog)) {
+EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable";
+EXPECT_EQ(Code.str(),
+  format(test::messUp(Code, /*HandleHash=*/false), Style));
+  }
+};
+
+TEST_F(FormatTestVerilog, If) {
+  verifyFormat("if (x)\n"
+   "  x = x;");
+  verifyFormat("if (x)\n"
+   "  x = x;\n"
+   "x = x;");
+
+  // Test else
+  verifyFormat("if (x)\n"
+   "  x = x;\n"
+   "else if (x)\n"
+   "  x = x;\n"
+   "else\n"
+   "  x = x;");
+  verifyFormat("if (x) begin\n"
+   "  x = x;\n"
+   "end else if (x) begin\n"
+   "  x = x;\n"
+   "end else begin\n"
+   "  x = x;\n"
+   "end");
+  verifyFormat("if (x) begin : x\n"
+   "  x = x;\n"
+   "end : x else if (x) begin : x\n"
+   "  x = x;\n"
+   "end : x else begin : x\n"
+   "  x = x;\n"
+   "end : x");
+
+  // Test block keywords.
+  verifyFormat("if (x) begin\n"
+   "  x = x;\n"
+   "end");
+  verifyFormat("if (x) begin : x\n"
+   "  x = x;\n"
+   "end : x");
+  verifyFormat("if (x) begin\n"
+   "  x = x;\n"
+   "  x = x;\n"
+   "end");
+  verifyFormat("disable fork;\n"
+   "x = x;");
+  verifyFormat("rand join x x;\n"
+   "x = x;");
+  verifyFormat("if (x) fork\n"
+   "  x = x;\n"
+   "join");
+  verifyFormat("if (x) fork\n"
+   "  x = x;\n"
+   "join_any");
+  verifyFormat("if (x) fork\n"
+   "  x = x;\n"
+   "join_none");
+  verifyFormat("if (x) generate\n"
+   "  x = x;\n"
+   "endgenerate");
+  verifyFormat("if (x) generate : x\n"
+   "  x = x;\n"
+   "endgenerate : x");
+
+  // Test that concatenation braces don't get regarded as blocks.
+  verifyFormat("if (x)\n"
+   "  {x} = x;");
+  verifyFormat("if (x)\n"
+   "  x = {x};");
+  verifyFormat("if (x)\n"
+   "  x = {x};\n"
+   "else\n"
+   "  {x} = {x};");
+}
+
+} // namespace format
+} // end namespace clang
Index: clang/unittests/Format/FormatTestUtils.h
===
--- clang/unittests/Format/FormatTestUtils.h
+++ clang/unittests/Format/FormatTestUtils.h
@@ -19,7 +19,10 @@
 namespace format {
 namespace test {
 

[PATCH] D121757: [clang-format] Take out common code for parsing blocks NFC

2022-04-11 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

Would you have a look at the parent revision namely D121756 
?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121757

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


[PATCH] D123450: [clang-format] Parse Verilog if statements

2022-04-13 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 422496.
sstwcw edited the summary of this revision.
sstwcw added a comment.

abandon alias


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D123450

Files:
  clang/docs/ClangFormat.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/UnwrappedLineParser.cpp
  clang/tools/clang-format/ClangFormat.cpp
  clang/unittests/Format/CMakeLists.txt
  clang/unittests/Format/FormatTestUtils.h
  clang/unittests/Format/FormatTestVerilog.cpp

Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- /dev/null
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -0,0 +1,118 @@
+//===- unittest/Format/FormatTestVerilog.cpp --===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "FormatTestUtils.h"
+#include "clang/Format/Format.h"
+#include "llvm/Support/Debug.h"
+#include "gtest/gtest.h"
+
+#define DEBUG_TYPE "format-test"
+
+namespace clang {
+namespace format {
+
+class FormatTestVerilog : public ::testing::Test {
+protected:
+  static std::string format(llvm::StringRef Code, unsigned Offset,
+unsigned Length, const FormatStyle &Style) {
+LLVM_DEBUG(llvm::errs() << "---\n");
+LLVM_DEBUG(llvm::errs() << Code << "\n\n");
+std::vector Ranges(1, tooling::Range(Offset, Length));
+tooling::Replacements Replaces = reformat(Style, Code, Ranges);
+auto Result = applyAllReplacements(Code, Replaces);
+EXPECT_TRUE(static_cast(Result));
+LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
+return *Result;
+  }
+
+  static std::string format(llvm::StringRef Code, const FormatStyle &Style) {
+return format(Code, 0, Code.size(), Style);
+  }
+
+  static void verifyFormat(
+  llvm::StringRef Code,
+  const FormatStyle &Style = getLLVMStyle(FormatStyle::LK_Verilog)) {
+EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable";
+EXPECT_EQ(Code.str(),
+  format(test::messUp(Code, /*HandleHash=*/false), Style));
+  }
+};
+
+TEST_F(FormatTestVerilog, If) {
+  verifyFormat("if (x)\n"
+   "  x = x;");
+  verifyFormat("if (x)\n"
+   "  x = x;\n"
+   "x = x;");
+
+  // Test else
+  verifyFormat("if (x)\n"
+   "  x = x;\n"
+   "else if (x)\n"
+   "  x = x;\n"
+   "else\n"
+   "  x = x;");
+  verifyFormat("if (x) begin\n"
+   "  x = x;\n"
+   "end else if (x) begin\n"
+   "  x = x;\n"
+   "end else begin\n"
+   "  x = x;\n"
+   "end");
+  verifyFormat("if (x) begin : x\n"
+   "  x = x;\n"
+   "end : x else if (x) begin : x\n"
+   "  x = x;\n"
+   "end : x else begin : x\n"
+   "  x = x;\n"
+   "end : x");
+
+  // Test block keywords.
+  verifyFormat("if (x) begin\n"
+   "  x = x;\n"
+   "end");
+  verifyFormat("if (x) begin : x\n"
+   "  x = x;\n"
+   "end : x");
+  verifyFormat("if (x) begin\n"
+   "  x = x;\n"
+   "  x = x;\n"
+   "end");
+  verifyFormat("disable fork;\n"
+   "x = x;");
+  verifyFormat("rand join x x;\n"
+   "x = x;");
+  verifyFormat("if (x) fork\n"
+   "  x = x;\n"
+   "join");
+  verifyFormat("if (x) fork\n"
+   "  x = x;\n"
+   "join_any");
+  verifyFormat("if (x) fork\n"
+   "  x = x;\n"
+   "join_none");
+  verifyFormat("if (x) generate\n"
+   "  x = x;\n"
+   "endgenerate");
+  verifyFormat("if (x) generate : x\n"
+   "  x = x;\n"
+   "endgenerate : x");
+
+  // Test that concatenation braces don't get regarded as blocks.
+  verifyFormat("if (x)\n"
+   "  {x} = x;");
+  verifyFormat("if (x)\n"
+   "  x = {x};");
+  verifyFormat("if (x)\n"
+   "  x = {x};\n"
+   "else\n"
+   "  {x} = {x};");
+}
+
+} // namespace format
+} // end namespace clang
Index: clang/unittests/Format/FormatTestUtils.h
===
--- clang/unittests/Format/FormatTestUtils.h
+++ clang/unittests/Format/FormatTestUtils.h
@@ -19,7 +19,10 @@
 namespace format {
 namespace test {
 
-inline std::string messUp(llvm::StringRef Code) {
+// When HandleHash is false, preprocessor directives starting with hash will not
+// be on separate lines.  

[PATCH] D123450: [clang-format] Parse Verilog if statements

2022-04-13 Thread sstwcw via Phabricator via cfe-commits
sstwcw marked an inline comment as done.
sstwcw added inline comments.



Comment at: clang/lib/Format/FormatToken.h:374
+  /// Verilog we want to treat the backtick like a hash.
+  tok::TokenKind AliasToken = tok::unknown;
+

HazardyKnusperkeks wrote:
> sstwcw wrote:
> > HazardyKnusperkeks wrote:
> > > Can't we do that with a type?
> > > 
> > > I'm not very happy about the alias, because you can still call 
> > > `Tok.getKind()`.
> > The main problem I seek to solve with the alias thing is with `tok::hash`.  
> > In Verilog they use a backtick instead of a hash.  At first I modified all 
> > places in the code to recognize the backtick.  MyDeveloperDay said "year 
> > really not nice.. its like we can never use tok::hash again!"  Using a type 
> > also requires modifying all instances of tok::hash if I get you right.  How 
> > do I please everyone?
> Then you must hide Tok in the private part, so that no one can ever access 
> `Tok.getKind()` accidentally.
In the new version the type of `Tok` itself gets changed instead.  So an alias 
is not needed.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D123450

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


[PATCH] D119599: Add option to align compound assignments like `+=`

2022-02-11 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
sstwcw added reviewers: curdeius, HazardyKnusperkeks.
sstwcw added projects: clang-format, clang-tools-extra.
sstwcw requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

About the column limit option in the test AlignConsecutiveDeclarations.
Previously, the test worked when the column limit was set to 0.
However, when the column limit is less than the length of a single line,
the formatter is supposed to give up aligning stuff.  Previously it
aligned things due to a bug.  In the function AlignTokens:

  unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
  
  // If we are restricted by the maximum column width, end the sequence.
  if (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn ||
  CommasBeforeLastMatch != CommasBeforeMatch) {
AlignCurrentSequence();
StartOfSequence = i;
  }

`ChangeMaxColumn` would wrap around 0.  `ChangeMaxColumn < MinColumn`
would fail.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D119599

Files:
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  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
@@ -16392,6 +16392,23 @@
Alignment));
 }
 
+TEST_F(FormatTest, AlignCompoundAssignments) {
+  FormatStyle Alignment = getLLVMStyle();
+  Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+  Alignment.AlignCompoundAssignments = true;
+  verifyFormat("aa <= 5;\n"
+   "a   &= 5;\n"
+   "bcd *= 5;\n"
+   "ghtyf   += 5;\n"
+   "dvfvdb  -= 5;\n"
+   "a   /= 5;\n"
+   "vdsvsv  %= 5;\n"
+   "sfdbddfbdfbb^= 5;\n"
+   "dvsdsv  |= 5;\n"
+   "int dsvvdvsdvvv  = 123;",
+   Alignment);
+}
+
 TEST_F(FormatTest, AlignConsecutiveAssignments) {
   FormatStyle Alignment = getLLVMStyle();
   Alignment.AlignConsecutiveMacros = FormatStyle::ACS_Consecutive;
@@ -16410,7 +16427,8 @@
   verifyFormat("int a   = method();\n"
"int oneTwoThree = 133;",
Alignment);
-  verifyFormat("a &= 5;\n"
+  verifyFormat("aa <= 5;\n"
+   "a &= 5;\n"
"bcd *= 5;\n"
"ghtyf += 5;\n"
"dvfvdb -= 5;\n"
@@ -16847,9 +16865,11 @@
"double b();",
Alignment);
   unsigned OldColumnLimit = Alignment.ColumnLimit;
-  // We need to set ColumnLimit to zero, in order to stress nested alignments,
-  // otherwise the function parameters will be re-flowed onto a single line.
-  Alignment.ColumnLimit = 0;
+  // We need to set ColumnLimit to a small number, in order to stress
+  // nested alignments, otherwise the function parameters will be
+  // re-flowed onto a single line. It also needs to be wide enough so
+  // that things still get aligned.
+  Alignment.ColumnLimit = 20;
   EXPECT_EQ("inta(int   x,\n"
 " float y);\n"
 "double b(intx,\n"
@@ -19248,12 +19268,13 @@
 TEST_F(FormatTest, ParsesConfigurationBools) {
   FormatStyle Style = {};
   Style.Language = FormatStyle::LK_Cpp;
-  CHECK_PARSE_BOOL(AlignTrailingComments);
   CHECK_PARSE_BOOL(AllowAllArgumentsOnNextLine);
   CHECK_PARSE_BOOL(AllowAllParametersOfDeclarationOnNextLine);
+  CHECK_PARSE_BOOL(AlignCompoundAssignments);
   CHECK_PARSE_BOOL(AllowShortCaseLabelsOnASingleLine);
   CHECK_PARSE_BOOL(AllowShortEnumsOnASingleLine);
   CHECK_PARSE_BOOL(AllowShortLoopsOnASingleLine);
+  CHECK_PARSE_BOOL(AlignTrailingComments);
   CHECK_PARSE_BOOL(BinPackArguments);
   CHECK_PARSE_BOOL(BinPackParameters);
   CHECK_PARSE_BOOL(BreakAfterJavaFieldAnnotations);
Index: clang/lib/Format/WhitespaceManager.cpp
===
--- clang/lib/Format/WhitespaceManager.cpp
+++ clang/lib/Format/WhitespaceManager.cpp
@@ -270,7 +270,7 @@
 template 
 static void
 AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
-   unsigned Column, F &&Matches,
+   unsigned Column, unsigned AnchorWidth, F &&Matches,
SmallVector &Changes) {
   bool FoundMatchOnLine = false;
   int Shift = 0;
@@ -329,7 +329,9 @@
 // shifted by the same amount
 if (!FoundMatchOnLine && !SkipMatchCheck && Matches(Changes[i])) {
   FoundMatchOnLine = true;
-  Shift = Column - Changes[i].StartOfTokenColumn;
+  Shift = Column +
+  (AnchorWidth ? AnchorWidth - Changes[i].TokenLength : 0) -
+  Changes[i].StartOfTokenColumn;
   Changes[i].Spaces += Shift;
   // FIXME: This is a workaround that should be remove

[PATCH] D119625: Fix integer underflow bug when aligning code in clang-format

2022-02-12 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
sstwcw added a reviewer: clang-format.
sstwcw added a project: clang-format.
sstwcw requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D119625

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
@@ -16847,9 +16847,11 @@
"double b();",
Alignment);
   unsigned OldColumnLimit = Alignment.ColumnLimit;
-  // We need to set ColumnLimit to zero, in order to stress nested alignments,
-  // otherwise the function parameters will be re-flowed onto a single line.
-  Alignment.ColumnLimit = 0;
+  // We need to set ColumnLimit to a small number, in order to stress
+  // nested alignments, otherwise the function parameters will be
+  // re-flowed onto a single line. It also needs to be wide enough so
+  // that things still get aligned.
+  Alignment.ColumnLimit = 20;
   EXPECT_EQ("inta(int   x,\n"
 " float y);\n"
 "double b(intx,\n"
Index: clang/lib/Format/WhitespaceManager.cpp
===
--- clang/lib/Format/WhitespaceManager.cpp
+++ clang/lib/Format/WhitespaceManager.cpp
@@ -575,7 +575,7 @@
   if (!Changes[j].IsInsideToken)
 LineLengthAfter += Changes[j].TokenLength;
 }
-unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
+int ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
 
 // If we are restricted by the maximum column width, end the sequence.
 if (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn ||


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -16847,9 +16847,11 @@
"double b();",
Alignment);
   unsigned OldColumnLimit = Alignment.ColumnLimit;
-  // We need to set ColumnLimit to zero, in order to stress nested alignments,
-  // otherwise the function parameters will be re-flowed onto a single line.
-  Alignment.ColumnLimit = 0;
+  // We need to set ColumnLimit to a small number, in order to stress
+  // nested alignments, otherwise the function parameters will be
+  // re-flowed onto a single line. It also needs to be wide enough so
+  // that things still get aligned.
+  Alignment.ColumnLimit = 20;
   EXPECT_EQ("inta(int   x,\n"
 " float y);\n"
 "double b(intx,\n"
Index: clang/lib/Format/WhitespaceManager.cpp
===
--- clang/lib/Format/WhitespaceManager.cpp
+++ clang/lib/Format/WhitespaceManager.cpp
@@ -575,7 +575,7 @@
   if (!Changes[j].IsInsideToken)
 LineLengthAfter += Changes[j].TokenLength;
 }
-unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
+int ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
 
 // If we are restricted by the maximum column width, end the sequence.
 if (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn ||
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D119625: Fix integer underflow bug when aligning code in clang-format

2022-02-12 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

This isolates the problem that changes the unit test mentioned in 
https://reviews.llvm.org/D119599.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D119625

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


[PATCH] D119599: Add option to align compound assignments like `+=`

2022-02-12 Thread sstwcw via Phabricator via cfe-commits
sstwcw marked 6 inline comments as done.
sstwcw added inline comments.



Comment at: clang/include/clang/Format/Format.h:151
 
+  /// When aligning assignments, whether compound assignments like
+  /// ``+=``'s are aligned along with ``=``'s.

curdeius wrote:
> You need to update the RST files when updating the doc comments here. Please 
> use 
> https://github.com/llvm/llvm-project/blob/main/clang/docs/tools/dump_format_style.py
>  for that.
I guess it is saying I need to say what version the option first appeared in.  
How do I know what version it will be?



Comment at: clang/include/clang/Format/Format.h:157
+  ///   a   &= 2;
+  ///   bbb  = 2;
+  ///

HazardyKnusperkeks wrote:
> curdeius wrote:
> > I guess it would be complicated to avoid adding an additional space here. I 
> > mean, it could be:
> > ```
> > a  &= 2;
> > bbb = 2;
> > ```
> > And with 3-char operators, there's one more space.
> That would be awesome, but it should be an option to turn off or on.
> But I think this would really be complicated.
I can do it either way. But I thought without the extra space the formatted 
code looked ugly, especially when mixing `>>=` and `=`.  Which way do you 
prefer?


```
a >>= 2;
bbb = 2;
```



Comment at: clang/lib/Format/WhitespaceManager.cpp:580
 
-unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
-int LineLengthAfter = Changes[i].TokenLength;
+unsigned ChangeWidthLeft = Changes[i].StartOfTokenColumn;
+unsigned ChangeWidthAnchor = 0;

MyDeveloperDay wrote:
> I like the final outcome, I'm uneasy about renaming all the variables, just 
> because you now understand them. I'm struggling to read the algorithm in the 
> same context as the prior version
> 
> 
Originally we tracked the column to put the operators to, so `ChangeMinColumn` 
and `ChangeMaxColumn` made sense.  Now the column we are tracking is no longer 
the column to which we change the start of the operators to, the original names 
don't make sense any more.



Comment at: clang/unittests/Format/FormatTest.cpp:16852
-  // otherwise the function parameters will be re-flowed onto a single line.
-  Alignment.ColumnLimit = 0;
   EXPECT_EQ("inta(int   x,\n"

MyDeveloperDay wrote:
> Huge `no` from me, don't change the tests because they break based on your 
> change.
Here is the problem in isolation: https://reviews.llvm.org/D119625.  What do 
you suggest about this test?



Comment at: clang/unittests/Format/FormatTest.cpp:16872
+  // that things still get aligned.
+  Alignment.ColumnLimit = 20;
   EXPECT_EQ("inta(int   x,\n"

curdeius wrote:
> Is it something that can be done/fixed separately?
I added a revision here https://reviews.llvm.org/D119625.  If you commit it 
separately there will be a merge conflict though.



Comment at: clang/unittests/Format/FormatTest.cpp:19277
   CHECK_PARSE_BOOL(AllowShortLoopsOnASingleLine);
+  CHECK_PARSE_BOOL(AlignTrailingComments);
   CHECK_PARSE_BOOL(BinPackArguments);

MyDeveloperDay wrote:
> `IJKL` last L looked i came before l right? so why did you move this down
Sorry.  I forgot my ABC's.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D119599

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


[PATCH] D119599: Add option to align compound assignments like `+=`

2022-02-12 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 408172.
sstwcw marked an inline comment as done.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D119599

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  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
@@ -16392,6 +16392,122 @@
Alignment));
 }
 
+TEST_F(FormatTest, AlignCompoundAssignments) {
+  FormatStyle Alignment = getLLVMStyle();
+  Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+  Alignment.AlignCompoundAssignments = true;
+  verifyFormat("aa <= 5;\n"
+   "a   = 5;\n"
+   "bcd = 5;\n"
+   "ghtyf   = 5;\n"
+   "dvfvdb  = 5;\n"
+   "a   = 5;\n"
+   "vdsvsv  = 5;\n"
+   "sfdbddfbdfbb= 5;\n"
+   "dvsdsv  = 5;\n"
+   "int dsvvdvsdvvv = 123;",
+   Alignment);
+  verifyFormat("aa <= 5;\n"
+   "a   &= 5;\n"
+   "bcd *= 5;\n"
+   "ghtyf   += 5;\n"
+   "dvfvdb  -= 5;\n"
+   "a   /= 5;\n"
+   "vdsvsv  %= 5;\n"
+   "sfdbddfbdfbb^= 5;\n"
+   "dvsdsv  |= 5;\n"
+   "int dsvvdvsdvvv  = 123;",
+   Alignment);
+  verifyFormat("a   &= 5;\n"
+   "bcd *= 5;\n"
+   "ghtyf  >>= 5;\n"
+   "dvfvdb  -= 5;\n"
+   "a   /= 5;\n"
+   "aa <= 5;\n"
+   "vdsvsv   %= 5;\n"
+   "sfdbddfbdfbb ^= 5;\n"
+   "dvsdsv  <<= 5;\n"
+   "int dsvvdvsdvvv   = 123;",
+   Alignment);
+  Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+  EXPECT_EQ("int a   += 5;\n"
+"int one  = 1;\n"
+"\n"
+"int oneTwoThree = 123;\n",
+format("int a += 5;\n"
+   "int one = 1;\n"
+   "\n"
+   "int oneTwoThree = 123;\n",
+   Alignment));
+  EXPECT_EQ("int a   += 5;\n"
+"int one  = 1;\n"
+"//\n"
+"int oneTwoThree = 123;\n",
+format("int a += 5;\n"
+   "int one = 1;\n"
+   "//\n"
+   "int oneTwoThree = 123;\n",
+   Alignment));
+  Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_AcrossEmptyLines;
+  EXPECT_EQ("int a   += 5;\n"
+"int one  = 1;\n"
+"\n"
+"int oneTwoThree  = 123;\n",
+format("int a += 5;\n"
+   "int one = 1;\n"
+   "\n"
+   "int oneTwoThree = 123;\n",
+   Alignment));
+  EXPECT_EQ("int a   += 5;\n"
+"int one  = 1;\n"
+"//\n"
+"int oneTwoThree = 123;\n",
+format("int a += 5;\n"
+   "int one = 1;\n"
+   "//\n"
+   "int oneTwoThree = 123;\n",
+   Alignment));
+  Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_AcrossComments;
+  EXPECT_EQ("int a   += 5;\n"
+"int one  = 1;\n"
+"\n"
+"int oneTwoThree = 123;\n",
+format("int a += 5;\n"
+   "int one = 1;\n"
+   "\n"
+   "int oneTwoThree = 123;\n",
+   Alignment));
+  EXPECT_EQ("int a   += 5;\n"
+"int one  = 1;\n"
+"//\n"
+"int oneTwoThree  = 123;\n",
+format("int a += 5;\n"
+   "int one = 1;\n"
+   "//\n"
+   "int oneTwoThree = 123;\n",
+   Alignment));
+  Alignment.AlignConsecutiveAssignments =
+  FormatStyle::ACS_AcrossEmptyLinesAndComments;
+  EXPECT_EQ("int a+= 5;\n"
+"int one >>= 1;\n"
+"\n"
+"int oneTwoThree   = 123;\n",
+format("int a += 5;\n"
+   "int one >>= 1;\n"
+   "\n"
+   "int oneTwoThree = 123;\n",
+   Alignment));
+  EXPECT_EQ("int a+= 5;\n"
+"int one   = 1;\n"
+"//\n"
+"int oneTwoThree <<= 123;\n",
+format("int a += 5;\n"
+   "int one = 1;\n"
+   "//\n"
+   "int oneTwoThree <<= 123;\n",
+   Alignment));
+}
+
 TEST_F(FormatTest

[PATCH] D119599: Add option to align compound assignments like `+=`

2022-02-12 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 408177.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D119599

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  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
@@ -16392,6 +16392,122 @@
Alignment));
 }
 
+TEST_F(FormatTest, AlignCompoundAssignments) {
+  FormatStyle Alignment = getLLVMStyle();
+  Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+  Alignment.AlignCompoundAssignments = true;
+  verifyFormat("aa <= 5;\n"
+   "a   = 5;\n"
+   "bcd = 5;\n"
+   "ghtyf   = 5;\n"
+   "dvfvdb  = 5;\n"
+   "a   = 5;\n"
+   "vdsvsv  = 5;\n"
+   "sfdbddfbdfbb= 5;\n"
+   "dvsdsv  = 5;\n"
+   "int dsvvdvsdvvv = 123;",
+   Alignment);
+  verifyFormat("aa <= 5;\n"
+   "a   &= 5;\n"
+   "bcd *= 5;\n"
+   "ghtyf   += 5;\n"
+   "dvfvdb  -= 5;\n"
+   "a   /= 5;\n"
+   "vdsvsv  %= 5;\n"
+   "sfdbddfbdfbb^= 5;\n"
+   "dvsdsv  |= 5;\n"
+   "int dsvvdvsdvvv  = 123;",
+   Alignment);
+  verifyFormat("a   &= 5;\n"
+   "bcd *= 5;\n"
+   "ghtyf  >>= 5;\n"
+   "dvfvdb  -= 5;\n"
+   "a   /= 5;\n"
+   "aa <= 5;\n"
+   "vdsvsv   %= 5;\n"
+   "sfdbddfbdfbb ^= 5;\n"
+   "dvsdsv  <<= 5;\n"
+   "int dsvvdvsdvvv   = 123;",
+   Alignment);
+  Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_Consecutive;
+  EXPECT_EQ("int a   += 5;\n"
+"int one  = 1;\n"
+"\n"
+"int oneTwoThree = 123;\n",
+format("int a += 5;\n"
+   "int one = 1;\n"
+   "\n"
+   "int oneTwoThree = 123;\n",
+   Alignment));
+  EXPECT_EQ("int a   += 5;\n"
+"int one  = 1;\n"
+"//\n"
+"int oneTwoThree = 123;\n",
+format("int a += 5;\n"
+   "int one = 1;\n"
+   "//\n"
+   "int oneTwoThree = 123;\n",
+   Alignment));
+  Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_AcrossEmptyLines;
+  EXPECT_EQ("int a   += 5;\n"
+"int one  = 1;\n"
+"\n"
+"int oneTwoThree  = 123;\n",
+format("int a += 5;\n"
+   "int one = 1;\n"
+   "\n"
+   "int oneTwoThree = 123;\n",
+   Alignment));
+  EXPECT_EQ("int a   += 5;\n"
+"int one  = 1;\n"
+"//\n"
+"int oneTwoThree = 123;\n",
+format("int a += 5;\n"
+   "int one = 1;\n"
+   "//\n"
+   "int oneTwoThree = 123;\n",
+   Alignment));
+  Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_AcrossComments;
+  EXPECT_EQ("int a   += 5;\n"
+"int one  = 1;\n"
+"\n"
+"int oneTwoThree = 123;\n",
+format("int a += 5;\n"
+   "int one = 1;\n"
+   "\n"
+   "int oneTwoThree = 123;\n",
+   Alignment));
+  EXPECT_EQ("int a   += 5;\n"
+"int one  = 1;\n"
+"//\n"
+"int oneTwoThree  = 123;\n",
+format("int a += 5;\n"
+   "int one = 1;\n"
+   "//\n"
+   "int oneTwoThree = 123;\n",
+   Alignment));
+  Alignment.AlignConsecutiveAssignments =
+  FormatStyle::ACS_AcrossEmptyLinesAndComments;
+  EXPECT_EQ("int a+= 5;\n"
+"int one >>= 1;\n"
+"\n"
+"int oneTwoThree   = 123;\n",
+format("int a += 5;\n"
+   "int one >>= 1;\n"
+   "\n"
+   "int oneTwoThree = 123;\n",
+   Alignment));
+  EXPECT_EQ("int a+= 5;\n"
+"int one   = 1;\n"
+"//\n"
+"int oneTwoThree <<= 123;\n",
+format("int a += 5;\n"
+   "int one = 1;\n"
+   "//\n"
+   "int oneTwoThree <<= 123;\n",
+   Alignment));
+}
+
 TEST_F(FormatTest, AlignConsecutiveAssignments) {
   Forma

[PATCH] D119599: Add option to align compound assignments like `+=`

2022-02-12 Thread sstwcw via Phabricator via cfe-commits
sstwcw added inline comments.



Comment at: clang/lib/Format/WhitespaceManager.cpp:273
 AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
-   unsigned Column, F &&Matches,
+   unsigned Column, unsigned AnchorWidth, F &&Matches,
SmallVector &Changes) {

MyDeveloperDay wrote:
> I guess I just don't understand what we mean by AnchorWidth
Now that I look at it again it seems like only one column parameter is needed.



Comment at: clang/unittests/Format/FormatTest.cpp:16452
+  Alignment.AlignConsecutiveAssignments = FormatStyle::ACS_AcrossEmptyLines;
+  EXPECT_EQ("int a   += 5;\n"
+"int one  = 1;\n"

MyDeveloperDay wrote:
> Is there a reason you couldn't use verifyFormat here? I would expect it to 
> `messUp` the formatting and put it back correctly no?
`messUp` turns every newline into a space.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D119599

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


[PATCH] D119649: [clang-format] Correctly format loops and `if` statements even if preceded with comments.

2022-02-12 Thread sstwcw via Phabricator via cfe-commits
sstwcw added inline comments.



Comment at: clang/lib/Format/UnwrappedLineFormatter.cpp:379
 if (NextLine.First->is(tok::l_brace)) {
   if ((TheLine->First->isOneOf(tok::kw_if, tok::kw_else, tok::kw_while,
tok::kw_for, tok::kw_switch, tok::kw_try,

Why not use `FirstNonComment` instead of `TheLine->First` down here?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D119649

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


[PATCH] D119599: Add option to align compound assignments like `+=`

2022-02-12 Thread sstwcw via Phabricator via cfe-commits
sstwcw added inline comments.



Comment at: clang/include/clang/Format/Format.h:157
+  ///   a   &= 2;
+  ///   bbb  = 2;
+  ///

HazardyKnusperkeks wrote:
> sstwcw wrote:
> > HazardyKnusperkeks wrote:
> > > curdeius wrote:
> > > > I guess it would be complicated to avoid adding an additional space 
> > > > here. I mean, it could be:
> > > > ```
> > > > a  &= 2;
> > > > bbb = 2;
> > > > ```
> > > > And with 3-char operators, there's one more space.
> > > That would be awesome, but it should be an option to turn off or on.
> > > But I think this would really be complicated.
> > I can do it either way. But I thought without the extra space the formatted 
> > code looked ugly, especially when mixing `>>=` and `=`.  Which way do you 
> > prefer?
> > 
> > 
> > ```
> > a >>= 2;
> > bbb = 2;
> > ```
> I would prefer an option, to be able to do both.
> I think I would use the variant which is more compact, but can't say for sure 
> until I really have the option and tried it.
You mean like a new entry under `AlignConsecutiveStyle` with the options to 
align the left ends of the operators and to align the equal sign with and 
without padding them to the same length? I don't want the new option to be 
merged with `AlignCompound`, because we are working on adding support for a 
language that uses both `=` and `<=` for regular assignments, and maybe someone 
will want to support a language that has both `=` and `:=` in the future.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D119599

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


  1   2   3   >