[PATCH] D154093: [clang-format] Break long string literals in C#, etc.

2023-09-12 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

In D154093#4644727 , @alexfh wrote:

> This patch makes clang-format produce invalid JS/TS code
>
> In D154093#4644512 , @eaeltsin 
> wrote:
>
>> This introduces an invalid TS transformation, from
>>
>>   type x = 'ab';
>>
>> to
>>
>>   type x = ('a'+'b');
>>
>> Which doesn't compile - 
>> https://www.typescriptlang.org/play?#code/C4TwDgpgBAHlC8UDkBDARkg3AKG6SUICUAFKklANTIYCUOQA
>>
>> Should we revert?
>
> Similarly, strings in dictionary literals can't be broken: `var w = {'a' + 
> 'b': 0};` (https://gcc.godbolt.org/z/6renEv5sa). Please fix or revert.

Here is the fix. https://github.com/llvm/llvm-project/pull/66168


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154093

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


[PATCH] D154093: [clang-format] Break long string literals in C#, etc.

2023-09-04 Thread sstwcw via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGddc80637ccbc: [clang-format] Break long string literals in 
C#, etc. (authored by sstwcw).

Changed prior to commit:
  https://reviews.llvm.org/D154093?vs=553729=555795#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154093

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/BreakableToken.cpp
  clang/lib/Format/BreakableToken.h
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/WhitespaceManager.cpp
  clang/unittests/Format/FormatTestCSharp.cpp
  clang/unittests/Format/FormatTestJS.cpp
  clang/unittests/Format/FormatTestJava.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
@@ -1868,6 +1868,30 @@
   EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_Unknown);
   EXPECT_TOKEN(Tokens[5], tok::comma, TT_Unknown);
   EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_Unknown);
+
+  // String literals in concatenation.
+  Tokens = Annotate("x = {\"\"};");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_StringInConcatenation);
+  Tokens = Annotate("x = {\"\", \"\"};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_StringInConcatenation);
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_StringInConcatenation);
+  Tokens = Annotate("x = '{{\"\"}};");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_StringInConcatenation);
+  // Cases where the string should not be annotated that type.  Fix the
+  // `TT_Unknown` if needed in the future.
+  Tokens = Annotate("x = {\"\" == \"\"};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_Unknown);
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_Unknown);
+  Tokens = Annotate("x = {(\"\")};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_Unknown);
+  Tokens = Annotate("x = '{\"\"};");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_Unknown);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandConstructors) {
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -1157,6 +1157,66 @@
   verifyFormat("{< 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  = getGoogleStyle(FormatStyle::LK_Java)) {
-return format(Code, 0, Code.size(), Style);
+  FormatStyle getDefaultStyle() const override {
+return getGoogleStyle(FormatStyle::LK_Java);
   }
 
   static FormatStyle getStyleWithColumns(unsigned ColumnLimit) {
@@ -41,13 +26,6 @@
 Style.ColumnLimit = ColumnLimit;
 return Style;
   }
-
-  static void verifyFormat(
-  llvm::StringRef Code,
-  const FormatStyle  = getGoogleStyle(FormatStyle::LK_Java)) {
-EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable";
-EXPECT_EQ(Code.str(), format(test::messUp(Code), Style));
-  }
 };
 
 TEST_F(FormatTestJava, NoAlternativeOperatorNames) {
@@ -565,9 +543,9 @@
 }
 
 TEST_F(FormatTestJava, BreaksStringLiterals) {
-  // FIXME: String literal breaking is currently disabled for Java and JS, as it
-  // requires strings to be merged using "+" which we don't support.
-  verifyFormat("\"some text other\";", getStyleWithColumns(14));
+  verifyFormat("x = \"some text \"\n"
+   "+ \"other\";",
+   "x = \"some text other\";", getStyleWithColumns(18));
 }
 
 TEST_F(FormatTestJava, AlignsBlockComments) {
@@ -625,5 +603,7 @@
Style);
 }
 
+} // namespace
+} // namespace test
 } // namespace format
-} // end namespace clang
+} // namespace clang
Index: clang/unittests/Format/FormatTestJS.cpp
===
--- clang/unittests/Format/FormatTestJS.cpp
+++ clang/unittests/Format/FormatTestJS.cpp
@@ -1505,6 +1505,97 @@
 TEST_F(FormatTestJS, StringLiteralConcatenation) {
   verifyFormat("var literal = 'hello ' +\n"
"'world';");
+
+  // Long strings should be broken.
+  

[PATCH] D154093: [clang-format] Break long string literals in C#, etc.

2023-08-26 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 553729.
sstwcw added a comment.

Stop using `SmallString` in the tests.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154093

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/BreakableToken.cpp
  clang/lib/Format/BreakableToken.h
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/WhitespaceManager.cpp
  clang/unittests/Format/FormatTestCSharp.cpp
  clang/unittests/Format/FormatTestJS.cpp
  clang/unittests/Format/FormatTestJava.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
@@ -1863,6 +1863,30 @@
   EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_Unknown);
   EXPECT_TOKEN(Tokens[5], tok::comma, TT_Unknown);
   EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_Unknown);
+
+  // String literals in concatenation.
+  Tokens = Annotate("x = {\"\"};");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_StringInConcatenation);
+  Tokens = Annotate("x = {\"\", \"\"};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_StringInConcatenation);
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_StringInConcatenation);
+  Tokens = Annotate("x = '{{\"\"}};");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_StringInConcatenation);
+  // Cases where the string should not be annotated that type.  Fix the
+  // `TT_Unknown` if needed in the future.
+  Tokens = Annotate("x = {\"\" == \"\"};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_Unknown);
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_Unknown);
+  Tokens = Annotate("x = {(\"\")};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_Unknown);
+  Tokens = Annotate("x = '{\"\"};");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_Unknown);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandConstructors) {
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -1157,6 +1157,66 @@
   verifyFormat("{< 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  = getGoogleStyle(FormatStyle::LK_Java)) {
-return format(Code, 0, Code.size(), Style);
+  FormatStyle getDefaultStyle() const override {
+return getGoogleStyle(FormatStyle::LK_Java);
   }
 
   static FormatStyle getStyleWithColumns(unsigned ColumnLimit) {
@@ -41,13 +26,6 @@
 Style.ColumnLimit = ColumnLimit;
 return Style;
   }
-
-  static void verifyFormat(
-  llvm::StringRef Code,
-  const FormatStyle  = getGoogleStyle(FormatStyle::LK_Java)) {
-EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable";
-EXPECT_EQ(Code.str(), format(test::messUp(Code), Style));
-  }
 };
 
 TEST_F(FormatTestJava, NoAlternativeOperatorNames) {
@@ -565,9 +543,9 @@
 }
 
 TEST_F(FormatTestJava, BreaksStringLiterals) {
-  // FIXME: String literal breaking is currently disabled for Java and JS, as it
-  // requires strings to be merged using "+" which we don't support.
-  verifyFormat("\"some text other\";", getStyleWithColumns(14));
+  verifyFormat("x = \"some text \"\n"
+   "+ \"other\";",
+   "x = \"some text other\";", getStyleWithColumns(18));
 }
 
 TEST_F(FormatTestJava, AlignsBlockComments) {
@@ -625,5 +603,7 @@
Style);
 }
 
+} // namespace
+} // namespace test
 } // namespace format
-} // end namespace clang
+} // namespace clang
Index: clang/unittests/Format/FormatTestJS.cpp
===
--- clang/unittests/Format/FormatTestJS.cpp
+++ clang/unittests/Format/FormatTestJS.cpp
@@ -1505,6 +1505,97 @@
 TEST_F(FormatTestJS, StringLiteralConcatenation) {
   verifyFormat("var literal = 'hello ' +\n"
"'world';");
+
+  // Long strings should be broken.
+  verifyFormat("var literal =\n"
+   "' ' +\n"
+   "'';",
+   "var literal = ' ';",
+

[PATCH] D158697: [clang-format][doc] Correct typos

2023-08-26 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 rG1d0061fc5e1f: [clang-format][doc] Correct typos (authored by 
sstwcw).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D158697

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h


Index: clang/include/clang/Format/Format.h
===
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -971,13 +971,13 @@
   /// For example:
   /// \code
   ///   x = (char *__capability)
-  ///   int function(void) __ununsed;
+  ///   int function(void) __unused;
   ///   void only_writes_to_buffer(char *__output buffer);
   /// \endcode
   ///
   /// In the .clang-format configuration file, this can be configured like:
   /// \code{.yaml}
-  ///   AttributeMacros: ['__capability', '__output', '__ununsed']
+  ///   AttributeMacros: ['__capability', '__output', '__unused']
   /// \endcode
   ///
   /// \version 12
@@ -4015,7 +4015,7 @@
   /// AfterFunctionDefinitionName: true
   /// \endcode
   struct SpaceBeforeParensCustom {
-/// If ``true``, put space betwee control statement keywords
+/// If ``true``, put space between control statement keywords
 /// (for/if/while...) and opening parentheses.
 /// \code
 ///true:  false:
Index: clang/docs/ClangFormatStyleOptions.rst
===
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -1549,14 +1549,14 @@
   .. code-block:: c++
 
 x = (char *__capability)
-int function(void) __ununsed;
+int function(void) __unused;
 void only_writes_to_buffer(char *__output buffer);
 
   In the .clang-format configuration file, this can be configured like:
 
   .. code-block:: yaml
 
-AttributeMacros: ['__capability', '__output', '__ununsed']
+AttributeMacros: ['__capability', '__output', '__unused']
 
 .. _BinPackArguments:
 


Index: clang/include/clang/Format/Format.h
===
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -971,13 +971,13 @@
   /// For example:
   /// \code
   ///   x = (char *__capability)
-  ///   int function(void) __ununsed;
+  ///   int function(void) __unused;
   ///   void only_writes_to_buffer(char *__output buffer);
   /// \endcode
   ///
   /// In the .clang-format configuration file, this can be configured like:
   /// \code{.yaml}
-  ///   AttributeMacros: ['__capability', '__output', '__ununsed']
+  ///   AttributeMacros: ['__capability', '__output', '__unused']
   /// \endcode
   ///
   /// \version 12
@@ -4015,7 +4015,7 @@
   /// AfterFunctionDefinitionName: true
   /// \endcode
   struct SpaceBeforeParensCustom {
-/// If ``true``, put space betwee control statement keywords
+/// If ``true``, put space between control statement keywords
 /// (for/if/while...) and opening parentheses.
 /// \code
 ///true:  false:
Index: clang/docs/ClangFormatStyleOptions.rst
===
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -1549,14 +1549,14 @@
   .. code-block:: c++
 
 x = (char *__capability)
-int function(void) __ununsed;
+int function(void) __unused;
 void only_writes_to_buffer(char *__output buffer);
 
   In the .clang-format configuration file, this can be configured like:
 
   .. code-block:: yaml
 
-AttributeMacros: ['__capability', '__output', '__ununsed']
+AttributeMacros: ['__capability', '__output', '__unused']
 
 .. _BinPackArguments:
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D154093: [clang-format] Break long string literals in C#, etc.

2023-08-24 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

In the JavaScript tests that I added, it was wrong to use `SmallString`.  Would 
you prefer me changing it to `string` or expanding the 6 test cases so we don't 
need a variable for the string?

Shortly after I committed this patch, the server builds caught the problem in 
the JavaScript tests.  When the program reads a file, a null byte is added at 
the end.  The program relies on this property because it means it doesn't have 
to do a bound check on the source string, including in some of the code I wrote 
though this time it was another piece of code that caught the problem.  Also 
the null byte is not copied when a SmallString is initialized from a `const 
char*`.  A null byte will be added if the `c_str` method is used at least once. 
 But it was not the case here.  So my test ended up passing a string which does 
not have a null byte at the end.  I didn't catch the problem when I ran the 
tests myself because ironically I had the address sanitizer enabled.  The 
address sanitizer didn't catch the problem because the byte past the end of the 
string in the `SmallString` is the struct padding which is still inside the 
object as far as the address sanitizer is concerned.  However the address 
sanitizer likes to add padding between variables.  So now the uninitialized 
part of the struct padding is the padding null bytes added by the address 
sanitizer instead of the variable that used to be there.  So the assertion that 
the byte is null now holds.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154093

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


[PATCH] D158697: [clang-format][doc] Correct typos

2023-08-23 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
Herald added projects: All, clang, clang-format.
Herald added a subscriber: cfe-commits.
Herald added reviewers: rymiel, HazardyKnusperkeks, owenpan, MyDeveloperDay.
sstwcw requested review of this revision.
Herald added a comment.

NOTE: Clang-Format Team Automated Review Comment

It looks like your clang-format review does not contain any unit tests, please 
try to ensure all code changes have a unit test (unless this is an `NFC` or 
refactoring, adding documentation etc..)

Add your unit tests in `clang/unittests/Format` and you can build with `ninja 
FormatTests`.  We recommend using the `verifyFormat(xxx)` format of unit tests 
rather than `EXPECT_EQ` as this will ensure you change is tolerant to random 
whitespace changes (see FormatTest.cpp as an example)

For situations where your change is altering the TokenAnnotator.cpp which can 
happen if you are trying to improve the annotation phase to ensure we are 
correctly identifying the type of a token, please add a token annotator test in 
`TokenAnnotatorTest.cpp`


I ran the script for dumping the format style options before committing
16ccba51072b 
 just in 
case.  It turned out that the 2 files didn't matchc
any more due to an attempt at fixing typos.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D158697

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h


Index: clang/include/clang/Format/Format.h
===
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -971,13 +971,13 @@
   /// For example:
   /// \code
   ///   x = (char *__capability)
-  ///   int function(void) __ununsed;
+  ///   int function(void) __unused;
   ///   void only_writes_to_buffer(char *__output buffer);
   /// \endcode
   ///
   /// In the .clang-format configuration file, this can be configured like:
   /// \code{.yaml}
-  ///   AttributeMacros: ['__capability', '__output', '__ununsed']
+  ///   AttributeMacros: ['__capability', '__output', '__unused']
   /// \endcode
   ///
   /// \version 12
@@ -4043,7 +4043,7 @@
   /// AfterFunctionDefinitionName: true
   /// \endcode
   struct SpaceBeforeParensCustom {
-/// If ``true``, put space betwee control statement keywords
+/// If ``true``, put space between control statement keywords
 /// (for/if/while...) and opening parentheses.
 /// \code
 ///true:  false:
Index: clang/docs/ClangFormatStyleOptions.rst
===
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -1549,14 +1549,14 @@
   .. code-block:: c++
 
 x = (char *__capability)
-int function(void) __ununsed;
+int function(void) __unused;
 void only_writes_to_buffer(char *__output buffer);
 
   In the .clang-format configuration file, this can be configured like:
 
   .. code-block:: yaml
 
-AttributeMacros: ['__capability', '__output', '__ununsed']
+AttributeMacros: ['__capability', '__output', '__unused']
 
 .. _BinPackArguments:
 


Index: clang/include/clang/Format/Format.h
===
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -971,13 +971,13 @@
   /// For example:
   /// \code
   ///   x = (char *__capability)
-  ///   int function(void) __ununsed;
+  ///   int function(void) __unused;
   ///   void only_writes_to_buffer(char *__output buffer);
   /// \endcode
   ///
   /// In the .clang-format configuration file, this can be configured like:
   /// \code{.yaml}
-  ///   AttributeMacros: ['__capability', '__output', '__ununsed']
+  ///   AttributeMacros: ['__capability', '__output', '__unused']
   /// \endcode
   ///
   /// \version 12
@@ -4043,7 +4043,7 @@
   /// AfterFunctionDefinitionName: true
   /// \endcode
   struct SpaceBeforeParensCustom {
-/// If ``true``, put space betwee control statement keywords
+/// If ``true``, put space between control statement keywords
 /// (for/if/while...) and opening parentheses.
 /// \code
 ///true:  false:
Index: clang/docs/ClangFormatStyleOptions.rst
===
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -1549,14 +1549,14 @@
   .. code-block:: c++
 
 x = (char *__capability)
-int function(void) __ununsed;
+int function(void) __unused;
 void only_writes_to_buffer(char *__output buffer);
 
   In the .clang-format configuration file, this can be configured like:
 
   .. code-block:: yaml
 
-AttributeMacros: ['__capability', '__output', '__ununsed']
+AttributeMacros: ['__capability', '__output', '__unused']
 
 .. _BinPackArguments:
 

[PATCH] D154093: [clang-format] Break long string literals in C#, etc.

2023-08-23 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 rG16ccba51072b: [clang-format] Break long string literals in 
C#, etc. (authored by sstwcw).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154093

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/BreakableToken.cpp
  clang/lib/Format/BreakableToken.h
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/WhitespaceManager.cpp
  clang/unittests/Format/FormatTestCSharp.cpp
  clang/unittests/Format/FormatTestJS.cpp
  clang/unittests/Format/FormatTestJava.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
@@ -1815,6 +1815,30 @@
   EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_Unknown);
   EXPECT_TOKEN(Tokens[5], tok::comma, TT_Unknown);
   EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_Unknown);
+
+  // String literals in concatenation.
+  Tokens = Annotate("x = {\"\"};");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_StringInConcatenation);
+  Tokens = Annotate("x = {\"\", \"\"};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_StringInConcatenation);
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_StringInConcatenation);
+  Tokens = Annotate("x = '{{\"\"}};");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_StringInConcatenation);
+  // Cases where the string should not be annotated that type.  Fix the
+  // `TT_Unknown` if needed in the future.
+  Tokens = Annotate("x = {\"\" == \"\"};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_Unknown);
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_Unknown);
+  Tokens = Annotate("x = {(\"\")};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_Unknown);
+  Tokens = Annotate("x = '{\"\"};");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_Unknown);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandConstructors) {
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -1157,6 +1157,66 @@
   verifyFormat("{< 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  = getGoogleStyle(FormatStyle::LK_Java)) {
-return format(Code, 0, Code.size(), Style);
+  FormatStyle getDefaultStyle() const override {
+return getGoogleStyle(FormatStyle::LK_Java);
   }
 
   static FormatStyle getStyleWithColumns(unsigned ColumnLimit) {
@@ -41,13 +26,6 @@
 Style.ColumnLimit = ColumnLimit;
 return Style;
   }
-
-  static void verifyFormat(
-  llvm::StringRef Code,
-  const FormatStyle  = getGoogleStyle(FormatStyle::LK_Java)) {
-EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable";
-EXPECT_EQ(Code.str(), format(test::messUp(Code), Style));
-  }
 };
 
 TEST_F(FormatTestJava, NoAlternativeOperatorNames) {
@@ -565,9 +543,9 @@
 }
 
 TEST_F(FormatTestJava, BreaksStringLiterals) {
-  // FIXME: String literal breaking is currently disabled for Java and JS, as it
-  // requires strings to be merged using "+" which we don't support.
-  verifyFormat("\"some text other\";", getStyleWithColumns(14));
+  verifyFormat("x = \"some text \"\n"
+   "+ \"other\";",
+   "x = \"some text other\";", getStyleWithColumns(18));
 }
 
 TEST_F(FormatTestJava, AlignsBlockComments) {
@@ -625,5 +603,7 @@
Style);
 }
 
+} // namespace
+} // namespace test
 } // namespace format
-} // end namespace clang
+} // namespace clang
Index: clang/unittests/Format/FormatTestJS.cpp
===
--- clang/unittests/Format/FormatTestJS.cpp
+++ clang/unittests/Format/FormatTestJS.cpp
@@ -1505,6 +1505,97 @@
 TEST_F(FormatTestJS, StringLiteralConcatenation) {
   verifyFormat("var literal = 'hello ' +\n"
"'world';");
+
+  // Long strings should be broken.
+  verifyFormat("var literal =\n"
+ 

[PATCH] D154467: [clang-format] Add Verilog suffixes to the scripts

2023-08-23 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 rG825cec2c0b1e: [clang-format] Add Verilog suffixes to the 
scripts (authored by sstwcw).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154467

Files:
  clang/tools/clang-format/clang-format-diff.py
  clang/tools/clang-format/git-clang-format


Index: clang/tools/clang-format/git-clang-format
===
--- clang/tools/clang-format/git-clang-format
+++ clang/tools/clang-format/git-clang-format
@@ -98,6 +98,7 @@
   'ts',  # TypeScript
   'cs',  # C Sharp
   'json',  # Json
+  'sv', 'svh', 'v', 'vh', # Verilog
   ])
 
   p = argparse.ArgumentParser(
Index: clang/tools/clang-format/clang-format-diff.py
===
--- clang/tools/clang-format/clang-format-diff.py
+++ clang/tools/clang-format/clang-format-diff.py
@@ -61,8 +61,8 @@
 parser.add_argument(
 "-iregex",
 metavar="PATTERN",
-default=r".*\.(cpp|cc|c\+\+|cxx|cppm|ccm|cxxm|c\+\+m|c|cl|h|hh|hpp|hxx"
-r"|m|mm|inc|js|ts|proto|protodevel|java|cs|json)",
+default=r".*\.(?:cpp|cc|c\+\+|cxx|cppm|ccm|cxxm|c\+\+m|c|cl|h|hh|hpp"
+r"|hxx|m|mm|inc|js|ts|proto|protodevel|java|cs|json|s?vh?)",
 help="custom pattern selecting file paths to reformat "
 "(case insensitive, overridden by -regex)",
 )


Index: clang/tools/clang-format/git-clang-format
===
--- clang/tools/clang-format/git-clang-format
+++ clang/tools/clang-format/git-clang-format
@@ -98,6 +98,7 @@
   'ts',  # TypeScript
   'cs',  # C Sharp
   'json',  # Json
+  'sv', 'svh', 'v', 'vh', # Verilog
   ])
 
   p = argparse.ArgumentParser(
Index: clang/tools/clang-format/clang-format-diff.py
===
--- clang/tools/clang-format/clang-format-diff.py
+++ clang/tools/clang-format/clang-format-diff.py
@@ -61,8 +61,8 @@
 parser.add_argument(
 "-iregex",
 metavar="PATTERN",
-default=r".*\.(cpp|cc|c\+\+|cxx|cppm|ccm|cxxm|c\+\+m|c|cl|h|hh|hpp|hxx"
-r"|m|mm|inc|js|ts|proto|protodevel|java|cs|json)",
+default=r".*\.(?:cpp|cc|c\+\+|cxx|cppm|ccm|cxxm|c\+\+m|c|cl|h|hh|hpp"
+r"|hxx|m|mm|inc|js|ts|proto|protodevel|java|cs|json|s?vh?)",
 help="custom pattern selecting file paths to reformat "
 "(case insensitive, overridden by -regex)",
 )
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D154091: [clang-format] Recognize escape sequences when breaking strings

2023-08-23 Thread sstwcw via Phabricator via cfe-commits
sstwcw abandoned this revision.
sstwcw added a comment.

I am closing it since no one seems to like it.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154091

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


[PATCH] D154093: [clang-format] Break long string literals in C#, etc.

2023-08-07 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 547770.
sstwcw added a comment.

- Add tests for code in JavaScript template strings


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154093

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/BreakableToken.cpp
  clang/lib/Format/BreakableToken.h
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/WhitespaceManager.cpp
  clang/unittests/Format/FormatTestCSharp.cpp
  clang/unittests/Format/FormatTestJS.cpp
  clang/unittests/Format/FormatTestJava.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
@@ -1815,6 +1815,30 @@
   EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_Unknown);
   EXPECT_TOKEN(Tokens[5], tok::comma, TT_Unknown);
   EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_Unknown);
+
+  // String literals in concatenation.
+  Tokens = Annotate("x = {\"\"};");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_StringInConcatenation);
+  Tokens = Annotate("x = {\"\", \"\"};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_StringInConcatenation);
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_StringInConcatenation);
+  Tokens = Annotate("x = '{{\"\"}};");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_StringInConcatenation);
+  // Cases where the string should not be annotated that type.  Fix the
+  // `TT_Unknown` if needed in the future.
+  Tokens = Annotate("x = {\"\" == \"\"};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_Unknown);
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_Unknown);
+  Tokens = Annotate("x = {(\"\")};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_Unknown);
+  Tokens = Annotate("x = '{\"\"};");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_Unknown);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandConstructors) {
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -1157,6 +1157,66 @@
   verifyFormat("{< 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  = getGoogleStyle(FormatStyle::LK_Java)) {
-return format(Code, 0, Code.size(), Style);
+  FormatStyle getDefaultStyle() const override {
+return getGoogleStyle(FormatStyle::LK_Java);
   }
 
   static FormatStyle getStyleWithColumns(unsigned ColumnLimit) {
@@ -41,13 +26,6 @@
 Style.ColumnLimit = ColumnLimit;
 return Style;
   }
-
-  static void verifyFormat(
-  llvm::StringRef Code,
-  const FormatStyle  = getGoogleStyle(FormatStyle::LK_Java)) {
-EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable";
-EXPECT_EQ(Code.str(), format(test::messUp(Code), Style));
-  }
 };
 
 TEST_F(FormatTestJava, NoAlternativeOperatorNames) {
@@ -565,9 +543,9 @@
 }
 
 TEST_F(FormatTestJava, BreaksStringLiterals) {
-  // FIXME: String literal breaking is currently disabled for Java and JS, as it
-  // requires strings to be merged using "+" which we don't support.
-  verifyFormat("\"some text other\";", getStyleWithColumns(14));
+  verifyFormat("x = \"some text \"\n"
+   "+ \"other\";",
+   "x = \"some text other\";", getStyleWithColumns(18));
 }
 
 TEST_F(FormatTestJava, AlignsBlockComments) {
@@ -625,5 +603,7 @@
Style);
 }
 
+} // namespace
+} // namespace test
 } // namespace format
-} // end namespace clang
+} // namespace clang
Index: clang/unittests/Format/FormatTestJS.cpp
===
--- clang/unittests/Format/FormatTestJS.cpp
+++ clang/unittests/Format/FormatTestJS.cpp
@@ -1505,6 +1505,97 @@
 TEST_F(FormatTestJS, StringLiteralConcatenation) {
   verifyFormat("var literal = 'hello ' +\n"
"'world';");
+
+  // Long strings should be broken.
+  verifyFormat("var literal =\n"
+   "' ' +\n"
+   "'';",
+   "var literal = ' ';",

[PATCH] D154093: [clang-format] Break long string literals in C#, etc.

2023-08-07 Thread sstwcw via Phabricator via cfe-commits
sstwcw added inline comments.



Comment at: clang/unittests/Format/FormatTestCSharp.cpp:221
 TEST_F(FormatTestCSharp, CSharpFatArrows) {
-  verifyFormat("Task serverTask = Task.Run(async() => {");
+  verifyIncompleteFormat("Task serverTask = Task.Run(async() => {");
   verifyFormat("public override string ToString() => \"{Name}\\{Age}\";");

MyDeveloperDay wrote:
> not sure what changing here and why?
The brace is not paired.  The old `verifyFormat` function didn't care about it. 
 In `FormatTestBase.h` there is the function `verifyFormat` which requires the 
code to be complete and `verifyIncompleteFormat` which doesn't.



Comment at: clang/unittests/Format/FormatTestJS.cpp:1575
+   "/ /;",
+   getGoogleJSStyleWithColumns(18));
 }

MyDeveloperDay wrote:
> out of interest what happens with  `xx ${variable} 
> xx` type strings? can we add a test to show we won't break in 
> the middle of a ${vas} even though the column limit might be reached?
There can be a break inside the braces.  I added a test.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154093

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


[PATCH] D154093: [clang-format] Break long string literals in C#, etc.

2023-08-07 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 547767.
sstwcw marked 2 inline comments as done.
sstwcw added a comment.

- Add tests for code in JavaScript template strings


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154093

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/BreakableToken.cpp
  clang/lib/Format/BreakableToken.h
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/WhitespaceManager.cpp
  clang/unittests/Format/FormatTestCSharp.cpp
  clang/unittests/Format/FormatTestJS.cpp
  clang/unittests/Format/FormatTestJava.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
@@ -1815,6 +1815,30 @@
   EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_Unknown);
   EXPECT_TOKEN(Tokens[5], tok::comma, TT_Unknown);
   EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_Unknown);
+
+  // String literals in concatenation.
+  Tokens = Annotate("x = {\"\"};");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_StringInConcatenation);
+  Tokens = Annotate("x = {\"\", \"\"};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_StringInConcatenation);
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_StringInConcatenation);
+  Tokens = Annotate("x = '{{\"\"}};");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_StringInConcatenation);
+  // Cases where the string should not be annotated that type.  Fix the
+  // `TT_Unknown` if needed in the future.
+  Tokens = Annotate("x = {\"\" == \"\"};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_Unknown);
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_Unknown);
+  Tokens = Annotate("x = {(\"\")};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_Unknown);
+  Tokens = Annotate("x = '{\"\"};");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_Unknown);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandConstructors) {
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -1157,6 +1157,66 @@
   verifyFormat("{< 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  = getGoogleStyle(FormatStyle::LK_Java)) {
-return format(Code, 0, Code.size(), Style);
+  FormatStyle getDefaultStyle() const override {
+return getGoogleStyle(FormatStyle::LK_Java);
   }
 
   static FormatStyle getStyleWithColumns(unsigned ColumnLimit) {
@@ -41,13 +26,6 @@
 Style.ColumnLimit = ColumnLimit;
 return Style;
   }
-
-  static void verifyFormat(
-  llvm::StringRef Code,
-  const FormatStyle  = getGoogleStyle(FormatStyle::LK_Java)) {
-EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable";
-EXPECT_EQ(Code.str(), format(test::messUp(Code), Style));
-  }
 };
 
 TEST_F(FormatTestJava, NoAlternativeOperatorNames) {
@@ -565,9 +543,9 @@
 }
 
 TEST_F(FormatTestJava, BreaksStringLiterals) {
-  // FIXME: String literal breaking is currently disabled for Java and JS, as it
-  // requires strings to be merged using "+" which we don't support.
-  verifyFormat("\"some text other\";", getStyleWithColumns(14));
+  verifyFormat("x = \"some text \"\n"
+   "+ \"other\";",
+   "x = \"some text other\";", getStyleWithColumns(18));
 }
 
 TEST_F(FormatTestJava, AlignsBlockComments) {
@@ -625,5 +603,7 @@
Style);
 }
 
+} // namespace
+} // namespace test
 } // namespace format
-} // end namespace clang
+} // namespace clang
Index: clang/unittests/Format/FormatTestJS.cpp
===
--- clang/unittests/Format/FormatTestJS.cpp
+++ clang/unittests/Format/FormatTestJS.cpp
@@ -1505,6 +1505,97 @@
 TEST_F(FormatTestJS, StringLiteralConcatenation) {
   verifyFormat("var literal = 'hello ' +\n"
"'world';");
+
+  // Long strings should be broken.
+  verifyFormat("var literal =\n"
+   "' ' +\n"
+   "'';",
+

[PATCH] D154093: [clang-format] Break long string literals in C#, etc.

2023-08-06 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

@MyDeveloperDay Can you take a look at the last test in 
FormatTestCSharp.Attributes?  I tried to enable breaking string literals by 
default.  The long string got broken.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154093

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


[PATCH] D154093: [clang-format] Break long string literals in C#, etc.

2023-08-06 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

In D154093#4544496 , @owenpan wrote:

> In D154093#4542339 , @sstwcw wrote:
>
>> @owenpan What do you think about this revision especially the replacement 
>> part?
>
> See D154093#4544495 . Then we can 
> extend it by using `,` instead of `+` for Verilog (plus inserting a pair of 
> braces).

I added support for that.  See the updated description.  It turned out
that because inserting plus signs may involve inserting parentheses, all
the replacement stuff are still needed.  So I didn't split the Verilog
stuff into a separate patch.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154093

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


[PATCH] D154093: [clang-format] Break long strings in Verilog

2023-08-06 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 547619.
sstwcw added a comment.

Add support for breaking strings with + in C# and others


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154093

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/BreakableToken.cpp
  clang/lib/Format/BreakableToken.h
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/WhitespaceManager.cpp
  clang/unittests/Format/FormatTestCSharp.cpp
  clang/unittests/Format/FormatTestJS.cpp
  clang/unittests/Format/FormatTestJava.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
@@ -1815,6 +1815,30 @@
   EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_Unknown);
   EXPECT_TOKEN(Tokens[5], tok::comma, TT_Unknown);
   EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_Unknown);
+
+  // String literals in concatenation.
+  Tokens = Annotate("x = {\"\"};");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_StringInConcatenation);
+  Tokens = Annotate("x = {\"\", \"\"};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_StringInConcatenation);
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_StringInConcatenation);
+  Tokens = Annotate("x = '{{\"\"}};");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_StringInConcatenation);
+  // Cases where the string should not be annotated that type.  Fix the
+  // `TT_Unknown` if needed in the future.
+  Tokens = Annotate("x = {\"\" == \"\"};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_Unknown);
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_Unknown);
+  Tokens = Annotate("x = {(\"\")};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_Unknown);
+  Tokens = Annotate("x = '{\"\"};");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_Unknown);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandConstructors) {
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -1157,6 +1157,66 @@
   verifyFormat("{< 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  = getGoogleStyle(FormatStyle::LK_Java)) {
-return format(Code, 0, Code.size(), Style);
+  FormatStyle getDefaultStyle() const override {
+return getGoogleStyle(FormatStyle::LK_Java);
   }
 
   static FormatStyle getStyleWithColumns(unsigned ColumnLimit) {
@@ -41,13 +26,6 @@
 Style.ColumnLimit = ColumnLimit;
 return Style;
   }
-
-  static void verifyFormat(
-  llvm::StringRef Code,
-  const FormatStyle  = getGoogleStyle(FormatStyle::LK_Java)) {
-EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable";
-EXPECT_EQ(Code.str(), format(test::messUp(Code), Style));
-  }
 };
 
 TEST_F(FormatTestJava, NoAlternativeOperatorNames) {
@@ -565,9 +543,9 @@
 }
 
 TEST_F(FormatTestJava, BreaksStringLiterals) {
-  // FIXME: String literal breaking is currently disabled for Java and JS, as it
-  // requires strings to be merged using "+" which we don't support.
-  verifyFormat("\"some text other\";", getStyleWithColumns(14));
+  verifyFormat("x = \"some text \"\n"
+   "+ \"other\";",
+   "x = \"some text other\";", getStyleWithColumns(18));
 }
 
 TEST_F(FormatTestJava, AlignsBlockComments) {
@@ -625,5 +603,7 @@
Style);
 }
 
+} // namespace
+} // namespace test
 } // namespace format
-} // end namespace clang
+} // namespace clang
Index: clang/unittests/Format/FormatTestJS.cpp
===
--- clang/unittests/Format/FormatTestJS.cpp
+++ clang/unittests/Format/FormatTestJS.cpp
@@ -1505,6 +1505,74 @@
 TEST_F(FormatTestJS, StringLiteralConcatenation) {
   verifyFormat("var literal = 'hello ' +\n"
"'world';");
+
+  // Long strings should be broken.
+  verifyFormat("var literal =\n"
+   "' ' +\n"
+   "'';",
+   "var literal = ' 

[PATCH] D154093: [clang-format] Break long strings in Verilog

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

@owenpan What do you think about this revision especially the replacement part?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154093

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


[PATCH] D154093: [clang-format] Break long strings in Verilog

2023-07-21 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 542916.
sstwcw added a comment.

- Add comment explaining the replacements


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154093

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/BreakableToken.cpp
  clang/lib/Format/BreakableToken.h
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/WhitespaceManager.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
@@ -1802,6 +1802,30 @@
   EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_Unknown);
   EXPECT_TOKEN(Tokens[5], tok::comma, TT_Unknown);
   EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_Unknown);
+
+  // String literals in concatenation.
+  Tokens = Annotate("x = {\"\"};");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_VerilogStringInConcatenation);
+  Tokens = Annotate("x = {\"\", \"\"};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_VerilogStringInConcatenation);
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_VerilogStringInConcatenation);
+  Tokens = Annotate("x = '{{\"\"}};");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_VerilogStringInConcatenation);
+  // Cases where the string should not be annotated that type.  Fix the
+  // `TT_Unknown` if needed in the future.
+  Tokens = Annotate("x = {\"\" == \"\"};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_Unknown);
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_Unknown);
+  Tokens = Annotate("x = {(\"\")};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_Unknown);
+  Tokens = Annotate("x = '{\"\"};");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_Unknown);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandConstructors) {
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -1155,6 +1155,66 @@
   verifyFormat("{< 0 && Changes[i - 1].OriginalWhitespaceRange.getBegin() ==
- C.OriginalWhitespaceRange.getBegin()) {
-  // Do not generate two replacements for the same location.
-  continue;
+if (i > 0) {
+  auto Last = Changes[i - 1].OriginalWhitespaceRange;
+  auto New = Changes[i].OriginalWhitespaceRange;
+  // Do not generate two replacements for the same location.  As a special
+  // case, it is allowed if there is a replacement for the empty range
+  // between 2 tokens and another non-empty range at the start of the second
+  // token.  We didn't implement logic to combine replacements for 2
+  // consecutive source ranges into a single replacement, because the
+  // program works fine without it.
+  //
+  // We can't eliminate empty original whitespace ranges.  They appear when
+  // 2 tokens have no whitespace in between in the input.  It does not
+  // matter whether whitespace is to be added.  If no whitespace is to be
+  // added, the replacement will be empty, and it gets eliminated after this
+  // step in storeReplacement.  For example, if the input is `foo();`,
+  // there will be a replacement for the range between every consecutive
+  // pair of tokens.
+  //
+  // A replacement at the start of a token can be added by
+  // BreakableVerilogStringLiteral::insertBreak when it adds braces around
+  // the string literal.  Say Verilog code is being formatted and the first
+  // line is to become the next 2 lines.
+  // x("long string");
+  // x({"long ",
+  //"string"});
+  // There will be a replacement for the empty range between the parenthesis
+  // and the string and another replacement for the quote character.  The
+  // replacement for the empty range between the parenthesis and the quote
+  // comes from ContinuationIndenter::addTokenOnCurrentLine when it changes
+  // the original empty range between the parenthesis and the string to
+  // another empty one.  The replacement for the quote character comes from
+  // BreakableVerilogStringLiteral::insertBreak when it adds the brace.  In
+  // the example, the replacement for the empty range is the same as the
+  // original text.  However, eliminating replacements that are same as the
+  // original 

[PATCH] D154093: [clang-format] Break long strings in Verilog

2023-07-20 Thread sstwcw via Phabricator via cfe-commits
sstwcw marked an inline comment as done.
sstwcw added a comment.

Are there any more problems?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154093

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


[PATCH] D154093: [clang-format] Break long strings in Verilog

2023-07-15 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:2247
bool DryRun, bool Strict) {
-  std::unique_ptr Token =
+  std::unique_ptr Token =
   createBreakableToken(Current, State, AllowBreak);

HazardyKnusperkeks wrote:
> This const can be readded, or not?
I forgot to add it.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154093

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


[PATCH] D154093: [clang-format] Break long strings in Verilog

2023-07-15 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 540752.
sstwcw added a comment.

- Add back the const qualifier


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154093

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/BreakableToken.cpp
  clang/lib/Format/BreakableToken.h
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/WhitespaceManager.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
@@ -1802,6 +1802,30 @@
   EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_Unknown);
   EXPECT_TOKEN(Tokens[5], tok::comma, TT_Unknown);
   EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_Unknown);
+
+  // String literals in concatenation.
+  Tokens = Annotate("x = {\"\"};");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_VerilogStringInConcatenation);
+  Tokens = Annotate("x = {\"\", \"\"};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_VerilogStringInConcatenation);
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_VerilogStringInConcatenation);
+  Tokens = Annotate("x = '{{\"\"}};");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_VerilogStringInConcatenation);
+  // Cases where the string should not be annotated that type.  Fix the
+  // `TT_Unknown` if needed in the future.
+  Tokens = Annotate("x = {\"\" == \"\"};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_Unknown);
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_Unknown);
+  Tokens = Annotate("x = {(\"\")};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_Unknown);
+  Tokens = Annotate("x = '{\"\"};");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_Unknown);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandConstructors) {
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -1155,6 +1155,66 @@
   verifyFormat("{< 0 && Changes[i - 1].OriginalWhitespaceRange.getBegin() ==
- C.OriginalWhitespaceRange.getBegin()) {
-  // Do not generate two replacements for the same location.
-  continue;
+if (i > 0) {
+  auto Last = Changes[i - 1].OriginalWhitespaceRange;
+  auto New = Changes[i].OriginalWhitespaceRange;
+  // Do not generate two replacements for the same location.  As a special
+  // case, it is allowed if there is a replacement for the empty range
+  // between 2 tokens and another non-empty range at the start of the second
+  // token.
+  //
+  // An original whitespace range that is empty is encountered when 2 tokens
+  // have no whitespace in between in the input.  It does not matter whether
+  // whitespace is to be added.  For example, if the input is `foo();`,
+  // there will be a replacement for the range between every consecutive
+  // pair of tokens.
+  //
+  //  A replacement at the start of a token can be added by
+  // `BreakableVerilogStringLiteral::insertBreak` when it adds braces around
+  // the string literal.  Say the line `x("long string");` is to become the
+  // 2 lines `x({"long ",` and `   "string"});`.  There will be a
+  // replacement for the empty range between the parenthesis and the string
+  // and another replacement for the quote character.
+  if (Last.getBegin() == New.getBegin() &&
+  (Last.getEnd() != Last.getBegin() ||
+   New.getEnd() == New.getBegin())) {
+continue;
+  }
 }
 if (C.CreateReplacement) {
   std::string ReplacementText = C.PreviousLinePostfix;
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -862,6 +862,11 @@
 OpeningBrace.Previous->is(TT_JsTypeColon)) {
   Contexts.back().IsExpression = false;
 }
+if (Style.isVerilog() &&
+(!OpeningBrace.getPreviousNonComment() ||
+ OpeningBrace.getPreviousNonComment()->isNot(Keywords.kw_apostrophe))) {
+  Contexts.back().VerilogMayBeConcatenation = true;
+}
 
 unsigned CommaCount = 0;
 while (CurrentToken) {
@@ -1736,6 +1741,9 @@
 bool InCpp11AttributeSpecifier = false;
 bool InCSharpAttributeSpecifier = false;
 

[PATCH] D154093: [clang-format] Break long strings in Verilog

2023-07-14 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 540611.
sstwcw edited the summary of this revision.
sstwcw added a comment.

- Add back the const qualifiers for methods


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154093

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/BreakableToken.cpp
  clang/lib/Format/BreakableToken.h
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/WhitespaceManager.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
@@ -1792,6 +1792,30 @@
   EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_Unknown);
   EXPECT_TOKEN(Tokens[5], tok::comma, TT_Unknown);
   EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_Unknown);
+
+  // String literals in concatenation.
+  Tokens = Annotate("x = {\"\"};");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_VerilogStringInConcatenation);
+  Tokens = Annotate("x = {\"\", \"\"};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_VerilogStringInConcatenation);
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_VerilogStringInConcatenation);
+  Tokens = Annotate("x = '{{\"\"}};");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_VerilogStringInConcatenation);
+  // Cases where the string should not be annotated that type.  Fix the
+  // `TT_Unknown` if needed in the future.
+  Tokens = Annotate("x = {\"\" == \"\"};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_Unknown);
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_Unknown);
+  Tokens = Annotate("x = {(\"\")};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_Unknown);
+  Tokens = Annotate("x = '{\"\"};");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_Unknown);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandConstructors) {
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -1155,6 +1155,66 @@
   verifyFormat("{< 0 && Changes[i - 1].OriginalWhitespaceRange.getBegin() ==
- C.OriginalWhitespaceRange.getBegin()) {
-  // Do not generate two replacements for the same location.
-  continue;
+if (i > 0) {
+  auto Last = Changes[i - 1].OriginalWhitespaceRange;
+  auto New = Changes[i].OriginalWhitespaceRange;
+  // Do not generate two replacements for the same location.  As a special
+  // case, it is allowed if there is a replacement for the empty range
+  // between 2 tokens and another non-empty range at the start of the second
+  // token.
+  if (Last.getBegin() == New.getBegin() &&
+  (Last.getEnd() != Last.getBegin() ||
+   New.getEnd() == New.getBegin())) {
+continue;
+  }
 }
 if (C.CreateReplacement) {
   std::string ReplacementText = C.PreviousLinePostfix;
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -862,6 +862,11 @@
 OpeningBrace.Previous->is(TT_JsTypeColon)) {
   Contexts.back().IsExpression = false;
 }
+if (Style.isVerilog() &&
+(!OpeningBrace.getPreviousNonComment() ||
+ OpeningBrace.getPreviousNonComment()->isNot(Keywords.kw_apostrophe))) {
+  Contexts.back().VerilogMayBeConcatenation = true;
+}
 
 unsigned CommaCount = 0;
 while (CurrentToken) {
@@ -1736,6 +1741,9 @@
 bool InCpp11AttributeSpecifier = false;
 bool InCSharpAttributeSpecifier = false;
 bool VerilogAssignmentFound = false;
+// Whether the braces may mean concatenation instead of structure or array
+// literal.
+bool VerilogMayBeConcatenation = false;
 enum {
   Unknown,
   // Like the part after `:` in a constructor.
@@ -2068,6 +2076,14 @@
   } else {
 Current.setType(TT_LineComment);
   }
+} else if (Current.is(tok::string_literal)) {
+  if (Style.isVerilog() && Contexts.back().VerilogMayBeConcatenation &&
+  Current.getPreviousNonComment() &&
+  Current.getPreviousNonComment()->isOneOf(tok::comma, tok::l_brace) &&
+  Current.getNextNonComment() &&
+  Current.getNextNonComment()->isOneOf(tok::comma, tok::r_brace)) {
+

[PATCH] D154484: [clang-format] Add an option to remove redundant parentheses

2023-07-09 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

Did you forget about GNU statement expressions?

  if (({
foo();
bar();
  })) {
  }




Comment at: clang/docs/ReleaseNotes.rst:804
 - Add ``KeepEmptyLinesAtEOF`` to keep empty lines at end of file.
+- Add ``RemoveParenthese`` to remove redundant parentheses.
 

The option is misspelled.


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

https://reviews.llvm.org/D154484

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


[PATCH] D154093: [clang-format] Break long strings in Verilog

2023-07-06 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 537975.
sstwcw marked an inline comment as done.
sstwcw added a comment.

- Drop the line in the doc


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154093

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/BreakableToken.cpp
  clang/lib/Format/BreakableToken.h
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/WhitespaceManager.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
@@ -1792,6 +1792,30 @@
   EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_Unknown);
   EXPECT_TOKEN(Tokens[5], tok::comma, TT_Unknown);
   EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_Unknown);
+
+  // String literals in concatenation.
+  Tokens = Annotate("x = {\"\"};");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_VerilogStringInConcatenation);
+  Tokens = Annotate("x = {\"\", \"\"};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_VerilogStringInConcatenation);
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_VerilogStringInConcatenation);
+  Tokens = Annotate("x = '{{\"\"}};");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_VerilogStringInConcatenation);
+  // Cases where the string should not be annotated that type.  Fix the
+  // `TT_Unknown` if needed in the future.
+  Tokens = Annotate("x = {\"\" == \"\"};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_Unknown);
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_Unknown);
+  Tokens = Annotate("x = {(\"\")};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_Unknown);
+  Tokens = Annotate("x = '{\"\"};");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_Unknown);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandConstructors) {
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -1155,6 +1155,66 @@
   verifyFormat("{< 0 && Changes[i - 1].OriginalWhitespaceRange.getBegin() ==
- C.OriginalWhitespaceRange.getBegin()) {
-  // Do not generate two replacements for the same location.
-  continue;
+if (i > 0) {
+  auto Last = Changes[i - 1].OriginalWhitespaceRange;
+  auto New = Changes[i].OriginalWhitespaceRange;
+  // Do not generate two replacements for the same location.  As a special
+  // case, it is allowed if there is a replacement for the empty range
+  // between 2 tokens and another non-empty range at the start of the second
+  // token.
+  if (Last.getBegin() == New.getBegin() &&
+  (Last.getEnd() != Last.getBegin() ||
+   New.getEnd() == New.getBegin())) {
+continue;
+  }
 }
 if (C.CreateReplacement) {
   std::string ReplacementText = C.PreviousLinePostfix;
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -862,6 +862,11 @@
 OpeningBrace.Previous->is(TT_JsTypeColon)) {
   Contexts.back().IsExpression = false;
 }
+if (Style.isVerilog() &&
+(!OpeningBrace.getPreviousNonComment() ||
+ OpeningBrace.getPreviousNonComment()->isNot(Keywords.kw_apostrophe))) {
+  Contexts.back().VerilogMayBeConcatenation = true;
+}
 
 unsigned CommaCount = 0;
 while (CurrentToken) {
@@ -1736,6 +1741,9 @@
 bool InCpp11AttributeSpecifier = false;
 bool InCSharpAttributeSpecifier = false;
 bool VerilogAssignmentFound = false;
+// Whether the braces may mean concatenation instead of structure or array
+// literal.
+bool VerilogMayBeConcatenation = false;
 enum {
   Unknown,
   // Like the part after `:` in a constructor.
@@ -2068,6 +2076,14 @@
   } else {
 Current.setType(TT_LineComment);
   }
+} else if (Current.is(tok::string_literal)) {
+  if (Style.isVerilog() && Contexts.back().VerilogMayBeConcatenation &&
+  Current.getPreviousNonComment() &&
+  Current.getPreviousNonComment()->isOneOf(tok::comma, tok::l_brace) &&
+  Current.getNextNonComment() &&
+  Current.getNextNonComment()->isOneOf(tok::comma, tok::r_brace)) {
+

[PATCH] D154093: [clang-format] Break long strings in Verilog

2023-07-06 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

If it is expected that the method does not modify the field, and the 
expectation is not fulfilled, I prefer to make it clear rather than to pretend 
that the method works as expected.  Can you help me come up with an 
alternative?  Braces need to be added around the string literal when it gets 
broken into parts.  Only one pair of braces need to be added no matter how many 
times the string gets broken.  My solution was to use a mutable field to mark 
whether braces have already been added.  Do you have another way?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154093

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


[PATCH] D154091: [clang-format] Recognize escape sequences when breaking strings

2023-07-06 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 537701.
sstwcw added a comment.

- Add tests for non-whitespace sequences


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154091

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

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -14832,6 +14832,69 @@
 "\"/and\"",
 format("\"some/tex/and\"", getLLVMStyleWithColumns(6)));
 
+  // Escape sequences should be recognized.  When the limit is 13 columns,
+  // another character can fit on the first line between the escape sequence and
+  // the closing quote.  We know the escape sequence is recognized when the
+  // program doesn't put the character following the escape sequence on the
+  // first line.
+  verifyFormat(R"(x = "some\n"
+"text";)",
+   R"(x = "some\ntext";)", getLLVMStyleWithColumns(12));
+  verifyFormat(R"(x = "some\n"
+"text";)",
+   R"(x = "some\ntext";)", getLLVMStyleWithColumns(13));
+  verifyFormat(R"(x = "some\n"
+" text";)",
+   R"(x = "some\n text";)", getLLVMStyleWithColumns(13));
+  verifyFormat(R"(x = "some\t"
+"text";)",
+   R"(x = "some\ttext";)", getLLVMStyleWithColumns(12));
+  verifyFormat(R"(x = "some\t"
+"text";)",
+   R"(x = "some\ttext";)", getLLVMStyleWithColumns(13));
+  verifyFormat(R"(x = "some\f"
+"text";)",
+   R"(x = "some\ftext";)", getLLVMStyleWithColumns(13));
+  verifyFormat(R"(x = "some\r"
+"text";)",
+   R"(x = "some\rtext";)", getLLVMStyleWithColumns(13));
+  verifyFormat(R"(x = "some\v"
+"text";)",
+   R"(x = "some\vtext";)", getLLVMStyleWithColumns(13));
+  // A newline outside of the column limit should not cause a break.
+  verifyFormat(R"(x = "something "
+"so\nshort";)",
+   R"(x = "something so\nshort";)", getLLVMStyleWithColumns(16));
+  verifyFormat(R"(x = "something "
+"so\nshort";)",
+   R"(x = "something so\nshort";)", getLLVMStyleWithColumns(19));
+  verifyFormat(R"(x = "something so\n"
+"short";)",
+   R"(x = "something so\nshort";)", getLLVMStyleWithColumns(20));
+  // Escape sequences for characters that are not whitespace should not be
+  // treated as whitespace.
+  verifyFormat(R"(x = "some\at"
+"ext";)",
+   R"(x = "some\atext";)", getLLVMStyleWithColumns(13));
+  verifyFormat(R"(x = "some\bt"
+"ext";)",
+   R"(x = "some\btext";)", getLLVMStyleWithColumns(13));
+  verifyFormat(R"(x = "some\et"
+"ext";)",
+   R"(x = "some\etext";)", getLLVMStyleWithColumns(13));
+  verifyFormat(R"(x = "s\157me"
+"text";)",
+   R"(x = "s\157metext";)", getLLVMStyleWithColumns(13));
+  verifyFormat(R"(x = "s\x6fme"
+"text";)",
+   R"(x = "s\x6fmetext";)", getLLVMStyleWithColumns(13));
+  verifyFormat(R"(x = "s\u006fm"
+"etext";)",
+   R"(x = "s\u006fmetext";)", getLLVMStyleWithColumns(14));
+  verifyFormat(R"(x = "s\U006fm"
+"etext";)",
+   R"(x = "s\U006fmetext";)", getLLVMStyleWithColumns(18));
+
   EXPECT_EQ("variable =\n"
 "\"long string \"\n"
 "\"literal\";",
Index: clang/lib/Format/BreakableToken.cpp
===
--- clang/lib/Format/BreakableToken.cpp
+++ clang/lib/Format/BreakableToken.cpp
@@ -176,13 +176,15 @@
   if (ColumnLimit <= UsedColumns)
 return BreakableToken::Split(StringRef::npos, 0);
   unsigned MaxSplit = ColumnLimit - UsedColumns;
-  StringRef::size_type SpaceOffset = 0;
+  StringRef::size_type NewLine = 0;
+  StringRef::size_type AfterSpace = 0;
   StringRef::size_type SlashOffset = 0;
   StringRef::size_type WordStartOffset = 0;
   StringRef::size_type SplitPoint = 0;
   for (unsigned Chars = 0;;) {
 unsigned Advance;
-if (Text[0] == '\\') {
+bool EscapeSequence = Text[0] == '\\';
+if (EscapeSequence) {
   Advance = encoding::getEscapeSequenceLength(Text);
   Chars += Advance;
 } else {
@@ -194,8 +196,21 @@
 if (Chars > MaxSplit || Text.size() <= Advance)
   break;
 
+if (EscapeSequence && Advance == 2) {
+  switch (Text[1]) {
+  case 'n':
+NewLine = SplitPoint + 2;
+break;
+  case 'f':
+  case 'r':
+  case 't':
+  case 'v':
+AfterSpace = SplitPoint + 2;
+break;
+  }
+}
 if (IsBlank(Text[0]))
-  SpaceOffset = SplitPoint;
+  AfterSpace = SplitPoint + 1;
 if (Text[0] == '/')
   SlashOffset = SplitPoint;
 if (Advance == 1 && !isAlphanumeric(Text[0]))
@@ -205,8 +220,10 @@
 Text = Text.substr(Advance);
   }
 
-  if (SpaceOffset != 0)
-return 

[PATCH] D154091: [clang-format] Recognize escape sequences when breaking strings

2023-07-05 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

It won't break the string inside an escape sequence.  But escape sequences like 
`\040`, `\x20`, and `\u0020` don't get recognized as whitespace.




Comment at: clang/lib/Format/BreakableToken.cpp:199
 
+if (EscapeSequence && Advance == 2) {
+  switch (Text[1]) {

MyDeveloperDay wrote:
> Can we add a unit test for escape sequences > \X which I assume this handles
There are already tests that verify that the string does not get broken inside 
an escape sequence in `BreaksWideAndNSStringLiterals` and 
`DoNotBreakStringLiteralsInEscapeSequence`.  And escape sequences longer than 1 
character following the backslash should not begin with one of these letters.  
So I don't see what tests I should add.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154091

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


[PATCH] D154467: [clang-format] Add Verilog suffixes to the scripts

2023-07-04 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
Herald added projects: All, clang, clang-format.
Herald added a subscriber: cfe-commits.
Herald added reviewers: rymiel, HazardyKnusperkeks, owenpan, MyDeveloperDay.
sstwcw requested review of this revision.
Herald added a comment.

NOTE: Clang-Format Team Automated Review Comment

It looks like your clang-format review does not contain any unit tests, please 
try to ensure all code changes have a unit test (unless this is an `NFC` or 
refactoring, adding documentation etc..)

Add your unit tests in `clang/unittests/Format` and you can build with `ninja 
FormatTests`.  We recommend using the `verifyFormat(xxx)` format of unit tests 
rather than `EXPECT_EQ` as this will ensure you change is tolerant to random 
whitespace changes (see FormatTest.cpp as an example)

For situations where your change is altering the TokenAnnotator.cpp which can 
happen if you are trying to improve the annotation phase to ensure we are 
correctly identifying the type of a token, please add a token annotator test in 
`TokenAnnotatorTest.cpp`


I decided not to wait for D149088  because it 
was taking a long time.

The capture group in the regexp was changed to non-capturing.  It
doesn't need to be captured.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D154467

Files:
  clang/tools/clang-format/clang-format-diff.py
  clang/tools/clang-format/git-clang-format


Index: clang/tools/clang-format/git-clang-format
===
--- clang/tools/clang-format/git-clang-format
+++ clang/tools/clang-format/git-clang-format
@@ -98,6 +98,7 @@
   'ts',  # TypeScript
   'cs',  # C Sharp
   'json',  # Json
+  'sv', 'svh', 'v', 'vh', # Verilog
   ])
 
   p = argparse.ArgumentParser(
Index: clang/tools/clang-format/clang-format-diff.py
===
--- clang/tools/clang-format/clang-format-diff.py
+++ clang/tools/clang-format/clang-format-diff.py
@@ -61,8 +61,8 @@
 parser.add_argument(
 "-iregex",
 metavar="PATTERN",
-default=r".*\.(cpp|cc|c\+\+|cxx|cppm|ccm|cxxm|c\+\+m|c|cl|h|hh|hpp|hxx"
-r"|m|mm|inc|js|ts|proto|protodevel|java|cs|json)",
+default=r".*\.(?:cpp|cc|c\+\+|cxx|cppm|ccm|cxxm|c\+\+m|c|cl|h|hh|hpp"
+r"|hxx|m|mm|inc|js|ts|proto|protodevel|java|cs|json|s?vh?)",
 help="custom pattern selecting file paths to reformat "
 "(case insensitive, overridden by -regex)",
 )


Index: clang/tools/clang-format/git-clang-format
===
--- clang/tools/clang-format/git-clang-format
+++ clang/tools/clang-format/git-clang-format
@@ -98,6 +98,7 @@
   'ts',  # TypeScript
   'cs',  # C Sharp
   'json',  # Json
+  'sv', 'svh', 'v', 'vh', # Verilog
   ])
 
   p = argparse.ArgumentParser(
Index: clang/tools/clang-format/clang-format-diff.py
===
--- clang/tools/clang-format/clang-format-diff.py
+++ clang/tools/clang-format/clang-format-diff.py
@@ -61,8 +61,8 @@
 parser.add_argument(
 "-iregex",
 metavar="PATTERN",
-default=r".*\.(cpp|cc|c\+\+|cxx|cppm|ccm|cxxm|c\+\+m|c|cl|h|hh|hpp|hxx"
-r"|m|mm|inc|js|ts|proto|protodevel|java|cs|json)",
+default=r".*\.(?:cpp|cc|c\+\+|cxx|cppm|ccm|cxxm|c\+\+m|c|cl|h|hh|hpp"
+r"|hxx|m|mm|inc|js|ts|proto|protodevel|java|cs|json|s?vh?)",
 help="custom pattern selecting file paths to reformat "
 "(case insensitive, overridden by -regex)",
 )
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D154091: [clang-format] Recognize escape sequences when breaking strings

2023-07-04 Thread sstwcw via Phabricator via cfe-commits
sstwcw marked an inline comment as done.
sstwcw added a comment.

In D154091#4470158 , @MyDeveloperDay 
wrote:

> What would happen in a \r\n example

If the entire `\r\n` part fits on the first line, the break is after `\r\n`.  
If only the part up to `\r` fits on the first line, the break is between `\r` 
and `\n`.




Comment at: clang/lib/Format/BreakableToken.cpp:207
+  case 't':
+  case 'v':
+AfterSpace = SplitPoint + 2;

MyDeveloperDay wrote:
> Are you testing \r \v \f
I am now.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154091

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


[PATCH] D154091: [clang-format] Recognize escape sequences when breaking strings

2023-07-04 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 537190.
sstwcw added a comment.

- Add tests for other escape sequences


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154091

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

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -14813,6 +14813,46 @@
 "\"/and\"",
 format("\"some/tex/and\"", getLLVMStyleWithColumns(6)));
 
+  // Escape sequences should be recognized.  When the limit is 13 columns,
+  // another character can fit on the first line between the escape sequence and
+  // the closing quote.  We know the escape sequence is recognized when the
+  // program doesn't put the character following the escape sequence on the
+  // first line.
+  verifyFormat(R"(x = "some\n"
+"text";)",
+   R"(x = "some\ntext";)", getLLVMStyleWithColumns(12));
+  verifyFormat(R"(x = "some\n"
+"text";)",
+   R"(x = "some\ntext";)", getLLVMStyleWithColumns(13));
+  verifyFormat(R"(x = "some\n"
+" text";)",
+   R"(x = "some\n text";)", getLLVMStyleWithColumns(13));
+  verifyFormat(R"(x = "some\t"
+"text";)",
+   R"(x = "some\ttext";)", getLLVMStyleWithColumns(12));
+  verifyFormat(R"(x = "some\t"
+"text";)",
+   R"(x = "some\ttext";)", getLLVMStyleWithColumns(13));
+  verifyFormat(R"(x = "some\f"
+"text";)",
+   R"(x = "some\ftext";)", getLLVMStyleWithColumns(13));
+  verifyFormat(R"(x = "some\r"
+"text";)",
+   R"(x = "some\rtext";)", getLLVMStyleWithColumns(13));
+  verifyFormat(R"(x = "some\v"
+"text";)",
+   R"(x = "some\vtext";)", getLLVMStyleWithColumns(13));
+  // A newline outside of the column limit should not cause a break.
+  verifyFormat(R"(x = "something "
+"so\nshort";)",
+   R"(x = "something so\nshort";)", getLLVMStyleWithColumns(16));
+  verifyFormat(R"(x = "something "
+"so\nshort";)",
+   R"(x = "something so\nshort";)", getLLVMStyleWithColumns(19));
+  verifyFormat(R"(x = "something so\n"
+"short";)",
+   R"(x = "something so\nshort";)", getLLVMStyleWithColumns(20));
+
   EXPECT_EQ("variable =\n"
 "\"long string \"\n"
 "\"literal\";",
Index: clang/lib/Format/BreakableToken.cpp
===
--- clang/lib/Format/BreakableToken.cpp
+++ clang/lib/Format/BreakableToken.cpp
@@ -176,13 +176,15 @@
   if (ColumnLimit <= UsedColumns)
 return BreakableToken::Split(StringRef::npos, 0);
   unsigned MaxSplit = ColumnLimit - UsedColumns;
-  StringRef::size_type SpaceOffset = 0;
+  StringRef::size_type NewLine = 0;
+  StringRef::size_type AfterSpace = 0;
   StringRef::size_type SlashOffset = 0;
   StringRef::size_type WordStartOffset = 0;
   StringRef::size_type SplitPoint = 0;
   for (unsigned Chars = 0;;) {
 unsigned Advance;
-if (Text[0] == '\\') {
+bool EscapeSequence = Text[0] == '\\';
+if (EscapeSequence) {
   Advance = encoding::getEscapeSequenceLength(Text);
   Chars += Advance;
 } else {
@@ -194,8 +196,21 @@
 if (Chars > MaxSplit || Text.size() <= Advance)
   break;
 
+if (EscapeSequence && Advance == 2) {
+  switch (Text[1]) {
+  case 'n':
+NewLine = SplitPoint + 2;
+break;
+  case 'f':
+  case 'r':
+  case 't':
+  case 'v':
+AfterSpace = SplitPoint + 2;
+break;
+  }
+}
 if (IsBlank(Text[0]))
-  SpaceOffset = SplitPoint;
+  AfterSpace = SplitPoint + 1;
 if (Text[0] == '/')
   SlashOffset = SplitPoint;
 if (Advance == 1 && !isAlphanumeric(Text[0]))
@@ -205,8 +220,10 @@
 Text = Text.substr(Advance);
   }
 
-  if (SpaceOffset != 0)
-return BreakableToken::Split(SpaceOffset + 1, 0);
+  if (NewLine != 0)
+return BreakableToken::Split(NewLine, 0);
+  if (AfterSpace >= 2)
+return BreakableToken::Split(AfterSpace, 0);
   if (SlashOffset != 0)
 return BreakableToken::Split(SlashOffset + 1, 0);
   if (WordStartOffset != 0)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D154093: [clang-format] Break long strings in Verilog

2023-07-01 Thread sstwcw via Phabricator via cfe-commits
sstwcw added inline comments.



Comment at: clang/include/clang/Format/Format.h:1914
   ///const char* x =
-  ///  "veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongString";
+  ///"veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongString";
   /// \endcode

It looks like they made a mistake in this example.  The second line gets 
indented by a continuation indentation both before and after this patch.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154093

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


[PATCH] D154093: [clang-format] Break long strings in Verilog

2023-07-01 Thread sstwcw via Phabricator via cfe-commits
sstwcw marked 2 inline comments as done.
sstwcw added a comment.

In D154093#4466246 , 
@HazardyKnusperkeks wrote:

> I'd really prefer you put what you need to modify `mutable` instead of 
> removing the `const` from everything else. But that's just my opinion.

Why should the `insertBreak` method be const?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154093

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


[PATCH] D154093: [clang-format] Break long strings in Verilog

2023-07-01 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 536555.
sstwcw added a comment.

- Address comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154093

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/BreakableToken.cpp
  clang/lib/Format/BreakableToken.h
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/WhitespaceManager.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
@@ -1770,6 +1770,24 @@
   EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_Unknown);
   EXPECT_TOKEN(Tokens[5], tok::comma, TT_Unknown);
   EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_Unknown);
+
+  // String literals in concatenation.
+  Tokens = Annotate("x = {\"\"};");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_VerilogStringInConcatenation);
+  Tokens = Annotate("x = {\"\", \"\"};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_VerilogStringInConcatenation);
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_VerilogStringInConcatenation);
+  // Cases where the string should not be annotated that type.  Fix the
+  // `TT_Unknown` if needed in the future.
+  Tokens = Annotate("x = {\"\" == \"\"};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_Unknown);
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_Unknown);
+  Tokens = Annotate("x = '{\"\"};");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_Unknown);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandConstructors) {
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -1155,6 +1155,66 @@
   verifyFormat("{< 0 && Changes[i - 1].OriginalWhitespaceRange.getBegin() ==
- C.OriginalWhitespaceRange.getBegin()) {
-  // Do not generate two replacements for the same location.
-  continue;
+if (i > 0) {
+  auto Last = Changes[i - 1].OriginalWhitespaceRange;
+  auto New = Changes[i].OriginalWhitespaceRange;
+  // Do not generate two replacements for the same location.  As a special
+  // case, it is allowed if there is a replacement for the empty range
+  // between 2 tokens and another non-empty range at the start of the second
+  // token.
+  if (Last.getBegin() == New.getBegin() &&
+  (Last.getEnd() != Last.getBegin() ||
+   New.getEnd() == New.getBegin())) {
+continue;
+  }
 }
 if (C.CreateReplacement) {
   std::string ReplacementText = C.PreviousLinePostfix;
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -867,6 +867,11 @@
 OpeningBrace.Previous->is(TT_JsTypeColon)) {
   Contexts.back().IsExpression = false;
 }
+if (Style.isVerilog() &&
+(!OpeningBrace.getPreviousNonComment() ||
+ OpeningBrace.getPreviousNonComment()->isNot(Keywords.kw_apostrophe))) {
+  Contexts.back().VerilogMayBeConcatenation = true;
+}
 
 unsigned CommaCount = 0;
 while (CurrentToken) {
@@ -1741,6 +1746,9 @@
 bool InCpp11AttributeSpecifier = false;
 bool InCSharpAttributeSpecifier = false;
 bool VerilogAssignmentFound = false;
+// Whether the braces may mean concatenation instead of structure or array
+// literal.
+bool VerilogMayBeConcatenation = false;
 enum {
   Unknown,
   // Like the part after `:` in a constructor.
@@ -2073,6 +2081,14 @@
   } else {
 Current.setType(TT_LineComment);
   }
+} else if (Current.is(tok::string_literal)) {
+  if (Style.isVerilog() && Contexts.back().VerilogMayBeConcatenation &&
+  Current.getPreviousNonComment() &&
+  Current.getPreviousNonComment()->isOneOf(tok::comma, tok::l_brace) &&
+  Current.getNextNonComment() &&
+  Current.getNextNonComment()->isOneOf(tok::comma, tok::r_brace)) {
+Current.setType(TT_VerilogStringInConcatenation);
+  }
 } else if (Current.is(tok::l_paren)) {
   if (lParenStartsCppCast(Current))
 Current.setType(TT_CppCastLParen);
Index: clang/lib/Format/FormatToken.h
===
--- clang/lib/Format/FormatToken.h
+++ clang/lib/Format/FormatToken.h
@@ -163,6 +163,8 @@
   

[PATCH] D154091: [clang-format] Recognize escape sequences when breaking strings

2023-07-01 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 536531.
sstwcw added a comment.

- Add tests for newline outside of column limit


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154091

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


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -14815,6 +14815,33 @@
 "\"/and\"",
 format("\"some/tex/and\"", getLLVMStyleWithColumns(6)));
 
+  // Escape sequences should be recognized.
+  verifyFormat(R"(x = "some\n"
+"text";)",
+   R"(x = "some\ntext";)", getLLVMStyleWithColumns(12));
+  verifyFormat(R"(x = "some\n"
+"text";)",
+   R"(x = "some\ntext";)", getLLVMStyleWithColumns(13));
+  verifyFormat(R"(x = "some\n"
+" text";)",
+   R"(x = "some\n text";)", getLLVMStyleWithColumns(13));
+  verifyFormat(R"(x = "some\t"
+"text";)",
+   R"(x = "some\ttext";)", getLLVMStyleWithColumns(12));
+  verifyFormat(R"(x = "some\t"
+"text";)",
+   R"(x = "some\ttext";)", getLLVMStyleWithColumns(13));
+  // A newline outside of the column limit should not cause a break.
+  verifyFormat(R"(x = "something "
+"so\nshort";)",
+   R"(x = "something so\nshort";)", getLLVMStyleWithColumns(16));
+  verifyFormat(R"(x = "something "
+"so\nshort";)",
+   R"(x = "something so\nshort";)", getLLVMStyleWithColumns(19));
+  verifyFormat(R"(x = "something so\n"
+"short";)",
+   R"(x = "something so\nshort";)", getLLVMStyleWithColumns(20));
+
   EXPECT_EQ("variable =\n"
 "\"long string \"\n"
 "\"literal\";",
Index: clang/lib/Format/BreakableToken.cpp
===
--- clang/lib/Format/BreakableToken.cpp
+++ clang/lib/Format/BreakableToken.cpp
@@ -176,13 +176,15 @@
   if (ColumnLimit <= UsedColumns)
 return BreakableToken::Split(StringRef::npos, 0);
   unsigned MaxSplit = ColumnLimit - UsedColumns;
-  StringRef::size_type SpaceOffset = 0;
+  StringRef::size_type NewLine = 0;
+  StringRef::size_type AfterSpace = 0;
   StringRef::size_type SlashOffset = 0;
   StringRef::size_type WordStartOffset = 0;
   StringRef::size_type SplitPoint = 0;
   for (unsigned Chars = 0;;) {
 unsigned Advance;
-if (Text[0] == '\\') {
+bool EscapeSequence = Text[0] == '\\';
+if (EscapeSequence) {
   Advance = encoding::getEscapeSequenceLength(Text);
   Chars += Advance;
 } else {
@@ -194,8 +196,21 @@
 if (Chars > MaxSplit || Text.size() <= Advance)
   break;
 
+if (EscapeSequence && Advance == 2) {
+  switch (Text[1]) {
+  case 'n':
+NewLine = SplitPoint + 2;
+break;
+  case 'f':
+  case 'r':
+  case 't':
+  case 'v':
+AfterSpace = SplitPoint + 2;
+break;
+  }
+}
 if (IsBlank(Text[0]))
-  SpaceOffset = SplitPoint;
+  AfterSpace = SplitPoint + 1;
 if (Text[0] == '/')
   SlashOffset = SplitPoint;
 if (Advance == 1 && !isAlphanumeric(Text[0]))
@@ -205,8 +220,10 @@
 Text = Text.substr(Advance);
   }
 
-  if (SpaceOffset != 0)
-return BreakableToken::Split(SpaceOffset + 1, 0);
+  if (NewLine != 0)
+return BreakableToken::Split(NewLine, 0);
+  if (AfterSpace >= 2)
+return BreakableToken::Split(AfterSpace, 0);
   if (SlashOffset != 0)
 return BreakableToken::Split(SlashOffset + 1, 0);
   if (WordStartOffset != 0)


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -14815,6 +14815,33 @@
 "\"/and\"",
 format("\"some/tex/and\"", getLLVMStyleWithColumns(6)));
 
+  // Escape sequences should be recognized.
+  verifyFormat(R"(x = "some\n"
+"text";)",
+   R"(x = "some\ntext";)", getLLVMStyleWithColumns(12));
+  verifyFormat(R"(x = "some\n"
+"text";)",
+   R"(x = "some\ntext";)", getLLVMStyleWithColumns(13));
+  verifyFormat(R"(x = "some\n"
+" text";)",
+   R"(x = "some\n text";)", getLLVMStyleWithColumns(13));
+  verifyFormat(R"(x = "some\t"
+"text";)",
+   R"(x = "some\ttext";)", getLLVMStyleWithColumns(12));
+  verifyFormat(R"(x = "some\t"
+"text";)",
+   R"(x = "some\ttext";)", getLLVMStyleWithColumns(13));
+  // A newline outside of the column limit should not cause a break.
+  verifyFormat(R"(x = "something "
+"so\nshort";)",
+   R"(x = "something so\nshort";)", getLLVMStyleWithColumns(16));
+  verifyFormat(R"(x = "something "
+"so\nshort";)",
+   R"(x = "something so\nshort";)", getLLVMStyleWithColumns(19));
+  

[PATCH] D154091: [clang-format] Recognize escape sequences when breaking strings

2023-07-01 Thread sstwcw via Phabricator via cfe-commits
sstwcw marked 2 inline comments as done.
sstwcw added inline comments.



Comment at: clang/lib/Format/BreakableToken.cpp:223
 
-  if (SpaceOffset != 0)
-return BreakableToken::Split(SpaceOffset + 1, 0);
+  if (NewLine != 0)
+return BreakableToken::Split(NewLine, 0);

HazardyKnusperkeks wrote:
> What if the new line is after the limit?
Then the loop will exit on line 197.  I added a test for it.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154091

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


[PATCH] D154091: [clang-format] Recognize escape sequences when breaking strings

2023-06-30 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

See the updated summary.  There does not seem to be an issue on GitHub when I 
searched.  I simply noticed it when reading the code in order to understand how 
strings got broken.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154091

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


[PATCH] D152623: [clang-format] Indent Verilog struct literal on new line

2023-06-29 Thread sstwcw via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG6bf66d839f13: [clang-format] Indent Verilog struct literal 
on new line (authored by sstwcw).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D152623

Files:
  clang/lib/Format/ContinuationIndenter.cpp
  clang/unittests/Format/FormatTestVerilog.cpp


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -1172,6 +1172,15 @@
   verifyFormat("c = '{a : 0, b : 0.0, default : 0};", Style);
   verifyFormat("c = ab'{a : 0, b : 0.0};", Style);
   verifyFormat("c = ab'{cd : cd'{1, 1.0}, ef : ef'{2, 2.0}};", Style);
+
+  // It should be indented correctly when the line has to break.
+  verifyFormat("c = //\n"
+   "'{default: 0};");
+  Style = getDefaultStyle();
+  Style.ContinuationIndentWidth = 2;
+  verifyFormat("c = //\n"
+   "  '{default: 0};",
+   Style);
 }
 
 TEST_F(FormatTestVerilog, StructuredProcedure) {
Index: clang/lib/Format/ContinuationIndenter.cpp
===
--- clang/lib/Format/ContinuationIndenter.cpp
+++ clang/lib/Format/ContinuationIndenter.cpp
@@ -1173,7 +1173,15 @@
   }
   if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
 return State.Stack[State.Stack.size() - 2].LastSpace;
+  // Field labels in a nested type should be aligned to the brace. For example
+  // in ProtoBuf:
+  //   optional int32 b = 2 [(foo_options) = {aaa: 123,
+  //  :"baz"}];
+  // For Verilog, a quote following a brace is treated as an identifier.  And
+  // Both braces and colons get annotated as TT_DictLiteral.  So we have to
+  // check.
   if (Current.is(tok::identifier) && Current.Next &&
+  (!Style.isVerilog() || Current.Next->is(tok::colon)) &&
   (Current.Next->is(TT_DictLiteral) ||
((Style.Language == FormatStyle::LK_Proto ||
  Style.Language == FormatStyle::LK_TextProto) &&


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -1172,6 +1172,15 @@
   verifyFormat("c = '{a : 0, b : 0.0, default : 0};", Style);
   verifyFormat("c = ab'{a : 0, b : 0.0};", Style);
   verifyFormat("c = ab'{cd : cd'{1, 1.0}, ef : ef'{2, 2.0}};", Style);
+
+  // It should be indented correctly when the line has to break.
+  verifyFormat("c = //\n"
+   "'{default: 0};");
+  Style = getDefaultStyle();
+  Style.ContinuationIndentWidth = 2;
+  verifyFormat("c = //\n"
+   "  '{default: 0};",
+   Style);
 }
 
 TEST_F(FormatTestVerilog, StructuredProcedure) {
Index: clang/lib/Format/ContinuationIndenter.cpp
===
--- clang/lib/Format/ContinuationIndenter.cpp
+++ clang/lib/Format/ContinuationIndenter.cpp
@@ -1173,7 +1173,15 @@
   }
   if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
 return State.Stack[State.Stack.size() - 2].LastSpace;
+  // Field labels in a nested type should be aligned to the brace. For example
+  // in ProtoBuf:
+  //   optional int32 b = 2 [(foo_options) = {aaa: 123,
+  //  :"baz"}];
+  // For Verilog, a quote following a brace is treated as an identifier.  And
+  // Both braces and colons get annotated as TT_DictLiteral.  So we have to
+  // check.
   if (Current.is(tok::identifier) && Current.Next &&
+  (!Style.isVerilog() || Current.Next->is(tok::colon)) &&
   (Current.Next->is(TT_DictLiteral) ||
((Style.Language == FormatStyle::LK_Proto ||
  Style.Language == FormatStyle::LK_TextProto) &&
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D154091: [clang-format] Prefer breaking long strings at new lines

2023-06-29 Thread sstwcw via Phabricator via cfe-commits
sstwcw added inline comments.



Comment at: clang/lib/Format/BreakableToken.cpp:225
+return BreakableToken::Split(NewLine, 0);
+  if (AfterSpace >= 2)
+return BreakableToken::Split(AfterSpace, 0);

Should I change the threshold from 2 to 1?

It is set to 2 because it is the old behavior.  There is already a test.

```
already in the test:
"some"
" tex"
"t"

I expect:
"some"
" "
"text"
```


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154091

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


[PATCH] D154093: [clang-format] Break strings in Verilog

2023-06-29 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
Herald added projects: All, clang, clang-format.
Herald added a subscriber: cfe-commits.
Herald added reviewers: rymiel, HazardyKnusperkeks, owenpan, MyDeveloperDay.
sstwcw requested review of this revision.

In Verilog, concatenations need to have braces around them and commas
between the parts.

Some const qualifiers were removed.  It is because the new insertBreak
method modifies a field.  And adaptStartOfLine calls that method in
another class.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D154093

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/BreakableToken.cpp
  clang/lib/Format/BreakableToken.h
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/WhitespaceManager.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
@@ -1743,6 +1743,24 @@
   EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_Unknown);
   EXPECT_TOKEN(Tokens[5], tok::comma, TT_Unknown);
   EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_Unknown);
+
+  // String literals in concatenation.
+  Tokens = Annotate("x = {\"\"};");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_VerilogStringInConcatenation);
+  Tokens = Annotate("x = {\"\", \"\"};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_VerilogStringInConcatenation);
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_VerilogStringInConcatenation);
+  // Cases where the string should not be annotated that type.  Fix the
+  // `TT_Unknown` if needed in the future.
+  Tokens = Annotate("x = {\"\" == \"\"};");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::string_literal, TT_Unknown);
+  EXPECT_TOKEN(Tokens[5], tok::string_literal, TT_Unknown);
+  Tokens = Annotate("x = '{\"\"};");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_Unknown);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandConstructors) {
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -1155,6 +1155,66 @@
   verifyFormat("{< 0 && Changes[i - 1].OriginalWhitespaceRange.getBegin() ==
- C.OriginalWhitespaceRange.getBegin()) {
-  // Do not generate two replacements for the same location.
-  continue;
+if (i > 0) {
+  auto Last = Changes[i - 1].OriginalWhitespaceRange;
+  auto New = Changes[i].OriginalWhitespaceRange;
+  // Do not generate two replacements for the same location.  As a special
+  // case, it is allowed if there is a replacement for the empty range
+  // between 2 tokens and another non-empty range at the start of the second
+  // token.
+  if (Last.getBegin() == New.getBegin() &&
+  (Last.getEnd() != Last.getBegin() ||
+   New.getEnd() == New.getBegin())) {
+continue;
+  }
 }
 if (C.CreateReplacement) {
   std::string ReplacementText = C.PreviousLinePostfix;
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -862,6 +862,11 @@
 OpeningBrace.Previous->is(TT_JsTypeColon)) {
   Contexts.back().IsExpression = false;
 }
+if (Style.isVerilog() &&
+(!OpeningBrace.getPreviousNonComment() ||
+ OpeningBrace.getPreviousNonComment()->isNot(Keywords.kw_apostrophe))) {
+  Contexts.back().VerilogMayBeConcatenation = true;
+}
 
 unsigned CommaCount = 0;
 while (CurrentToken) {
@@ -1736,6 +1741,9 @@
 bool InCpp11AttributeSpecifier = false;
 bool InCSharpAttributeSpecifier = false;
 bool VerilogAssignmentFound = false;
+// Whether the braces may mean concatenation instead of structure or array
+// literal.
+bool VerilogMayBeConcatenation = false;
 enum {
   Unknown,
   // Like the part after `:` in a constructor.
@@ -2068,6 +2076,14 @@
   } else {
 Current.setType(TT_LineComment);
   }
+} else if (Current.is(tok::string_literal)) {
+  if (Style.isVerilog() && Contexts.back().VerilogMayBeConcatenation &&
+  Current.getPreviousNonComment() &&
+  Current.getPreviousNonComment()->isOneOf(tok::comma, tok::l_brace) &&
+  Current.getNextNonComment() &&
+  Current.getNextNonComment()->isOneOf(tok::comma, tok::r_brace)) {
+Current.setType(TT_VerilogStringInConcatenation);
+  }
 } 

[PATCH] D154091: [clang-format] Prefer breaking long strings at new lines

2023-06-29 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
Herald added projects: All, clang, clang-format.
Herald added a subscriber: cfe-commits.
Herald added reviewers: rymiel, HazardyKnusperkeks, owenpan, MyDeveloperDay.
sstwcw requested review of this revision.

Previously, escape sequences in string literals were not recognized
when the program considered where to break string literals.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D154091

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


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -14807,6 +14807,23 @@
 "\"/and\"",
 format("\"some/tex/and\"", getLLVMStyleWithColumns(6)));
 
+  // Escape sequences should be recognized.
+  verifyFormat(R"(x = "some\n"
+"text";)",
+   R"(x = "some\ntext";)", getLLVMStyleWithColumns(12));
+  verifyFormat(R"(x = "some\n"
+"text";)",
+   R"(x = "some\ntext";)", getLLVMStyleWithColumns(13));
+  verifyFormat(R"(x = "some\n"
+" text";)",
+   R"(x = "some\n text";)", getLLVMStyleWithColumns(13));
+  verifyFormat(R"(x = "some\t"
+"text";)",
+   R"(x = "some\ttext";)", getLLVMStyleWithColumns(12));
+  verifyFormat(R"(x = "some\t"
+"text";)",
+   R"(x = "some\ttext";)", getLLVMStyleWithColumns(13));
+
   EXPECT_EQ("variable =\n"
 "\"long string \"\n"
 "\"literal\";",
Index: clang/lib/Format/BreakableToken.cpp
===
--- clang/lib/Format/BreakableToken.cpp
+++ clang/lib/Format/BreakableToken.cpp
@@ -176,13 +176,15 @@
   if (ColumnLimit <= UsedColumns)
 return BreakableToken::Split(StringRef::npos, 0);
   unsigned MaxSplit = ColumnLimit - UsedColumns;
-  StringRef::size_type SpaceOffset = 0;
+  StringRef::size_type NewLine = 0;
+  StringRef::size_type AfterSpace = 0;
   StringRef::size_type SlashOffset = 0;
   StringRef::size_type WordStartOffset = 0;
   StringRef::size_type SplitPoint = 0;
   for (unsigned Chars = 0;;) {
 unsigned Advance;
-if (Text[0] == '\\') {
+bool EscapeSequence = Text[0] == '\\';
+if (EscapeSequence) {
   Advance = encoding::getEscapeSequenceLength(Text);
   Chars += Advance;
 } else {
@@ -194,8 +196,21 @@
 if (Chars > MaxSplit || Text.size() <= Advance)
   break;
 
+if (EscapeSequence && Advance == 2) {
+  switch (Text[1]) {
+  case 'n':
+NewLine = SplitPoint + 2;
+break;
+  case 'f':
+  case 'r':
+  case 't':
+  case 'v':
+AfterSpace = SplitPoint + 2;
+break;
+  }
+}
 if (IsBlank(Text[0]))
-  SpaceOffset = SplitPoint;
+  AfterSpace = SplitPoint + 1;
 if (Text[0] == '/')
   SlashOffset = SplitPoint;
 if (Advance == 1 && !isAlphanumeric(Text[0]))
@@ -205,8 +220,10 @@
 Text = Text.substr(Advance);
   }
 
-  if (SpaceOffset != 0)
-return BreakableToken::Split(SpaceOffset + 1, 0);
+  if (NewLine != 0)
+return BreakableToken::Split(NewLine, 0);
+  if (AfterSpace >= 2)
+return BreakableToken::Split(AfterSpace, 0);
   if (SlashOffset != 0)
 return BreakableToken::Split(SlashOffset + 1, 0);
   if (WordStartOffset != 0)


Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -14807,6 +14807,23 @@
 "\"/and\"",
 format("\"some/tex/and\"", getLLVMStyleWithColumns(6)));
 
+  // Escape sequences should be recognized.
+  verifyFormat(R"(x = "some\n"
+"text";)",
+   R"(x = "some\ntext";)", getLLVMStyleWithColumns(12));
+  verifyFormat(R"(x = "some\n"
+"text";)",
+   R"(x = "some\ntext";)", getLLVMStyleWithColumns(13));
+  verifyFormat(R"(x = "some\n"
+" text";)",
+   R"(x = "some\n text";)", getLLVMStyleWithColumns(13));
+  verifyFormat(R"(x = "some\t"
+"text";)",
+   R"(x = "some\ttext";)", getLLVMStyleWithColumns(12));
+  verifyFormat(R"(x = "some\t"
+"text";)",
+   R"(x = "some\ttext";)", getLLVMStyleWithColumns(13));
+
   EXPECT_EQ("variable =\n"
 "\"long string \"\n"
 "\"literal\";",
Index: clang/lib/Format/BreakableToken.cpp
===
--- clang/lib/Format/BreakableToken.cpp
+++ clang/lib/Format/BreakableToken.cpp
@@ -176,13 +176,15 @@
   if (ColumnLimit <= UsedColumns)
 return BreakableToken::Split(StringRef::npos, 0);
   unsigned MaxSplit = ColumnLimit - UsedColumns;
-  StringRef::size_type SpaceOffset = 0;
+  StringRef::size_type NewLine = 0;
+  StringRef::size_type AfterSpace = 0;
   StringRef::size_type SlashOffset = 0;
   StringRef::size_type 

[PATCH] D152623: [clang-format] Indent Verilog struct literal on new line

2023-06-22 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 533617.
sstwcw added a comment.

- limit change to Verilog


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D152623

Files:
  clang/lib/Format/ContinuationIndenter.cpp
  clang/unittests/Format/FormatTestVerilog.cpp


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -1172,6 +1172,15 @@
   verifyFormat("c = '{a : 0, b : 0.0, default : 0};", Style);
   verifyFormat("c = ab'{a : 0, b : 0.0};", Style);
   verifyFormat("c = ab'{cd : cd'{1, 1.0}, ef : ef'{2, 2.0}};", Style);
+
+  // It should be indented correctly when the line has to break.
+  verifyFormat("c = //\n"
+   "'{default: 0};");
+  Style = getDefaultStyle();
+  Style.ContinuationIndentWidth = 2;
+  verifyFormat("c = //\n"
+   "  '{default: 0};",
+   Style);
 }
 
 TEST_F(FormatTestVerilog, StructuredProcedure) {
Index: clang/lib/Format/ContinuationIndenter.cpp
===
--- clang/lib/Format/ContinuationIndenter.cpp
+++ clang/lib/Format/ContinuationIndenter.cpp
@@ -1172,7 +1172,15 @@
   }
   if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
 return State.Stack[State.Stack.size() - 2].LastSpace;
+  // Field labels in a nested type should be aligned to the brace. For example
+  // in ProtoBuf:
+  //   optional int32 b = 2 [(foo_options) = {aaa: 123,
+  //  :"baz"}];
+  // For Verilog, a quote following a brace is treated as an identifier.  And
+  // Both braces and colons get annotated as TT_DictLiteral.  So we have to
+  // check.
   if (Current.is(tok::identifier) && Current.Next &&
+  (!Style.isVerilog() || Current.Next->is(tok::colon)) &&
   (Current.Next->is(TT_DictLiteral) ||
((Style.Language == FormatStyle::LK_Proto ||
  Style.Language == FormatStyle::LK_TextProto) &&


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -1172,6 +1172,15 @@
   verifyFormat("c = '{a : 0, b : 0.0, default : 0};", Style);
   verifyFormat("c = ab'{a : 0, b : 0.0};", Style);
   verifyFormat("c = ab'{cd : cd'{1, 1.0}, ef : ef'{2, 2.0}};", Style);
+
+  // It should be indented correctly when the line has to break.
+  verifyFormat("c = //\n"
+   "'{default: 0};");
+  Style = getDefaultStyle();
+  Style.ContinuationIndentWidth = 2;
+  verifyFormat("c = //\n"
+   "  '{default: 0};",
+   Style);
 }
 
 TEST_F(FormatTestVerilog, StructuredProcedure) {
Index: clang/lib/Format/ContinuationIndenter.cpp
===
--- clang/lib/Format/ContinuationIndenter.cpp
+++ clang/lib/Format/ContinuationIndenter.cpp
@@ -1172,7 +1172,15 @@
   }
   if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
 return State.Stack[State.Stack.size() - 2].LastSpace;
+  // Field labels in a nested type should be aligned to the brace. For example
+  // in ProtoBuf:
+  //   optional int32 b = 2 [(foo_options) = {aaa: 123,
+  //  :"baz"}];
+  // For Verilog, a quote following a brace is treated as an identifier.  And
+  // Both braces and colons get annotated as TT_DictLiteral.  So we have to
+  // check.
   if (Current.is(tok::identifier) && Current.Next &&
+  (!Style.isVerilog() || Current.Next->is(tok::colon)) &&
   (Current.Next->is(TT_DictLiteral) ||
((Style.Language == FormatStyle::LK_Proto ||
  Style.Language == FormatStyle::LK_TextProto) &&
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D152623: [clang-format] Indent Verilog struct literal on new line

2023-06-22 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

> So I assume your `'` is a 'DictLiteral`?

The brace following the quote is a `DictLiteral`.  The quote is a 
`tok::identifier` and `TT_Unknown`.

> Does it have to be one?

The brace is set to this type when used this way in all other languages.  I 
don't want to make an exception.

> I don't know what else maybe a `DictLiteral` in what language and am not so 
> comfortable with this change.

I changed the patch to use the new behavior only for Verilog.

The `DictLiteral` type gets set on the braces and colons in literals where the 
field names and values are separated by colons in all languages that have them. 
 In addition, because the protocol buffer text format allows angular brackets 
as braces, the type is also set on those angular brackets for that language.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D152623

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


[PATCH] D152623: [clang-format] Indent Verilog struct literal on new line

2023-06-10 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
Herald added projects: All, clang, clang-format.
Herald added a subscriber: cfe-commits.
Herald added reviewers: rymiel, HazardyKnusperkeks, owenpan, MyDeveloperDay.
sstwcw requested review of this revision.

Before:

  c = //
  '{default: 0};

After:

  c = //
  '{default: 0};

If the line has to be broken, the continuation part should be
indented.  Before this fix, it was not the case if the continuation
part was a struct literal.  The rule that caused the problem was added
in 783bac6b.  It was intended for aligning the field labels in
ProtoBuf.  The type `TT_DictLiteral` was only for colons back then, so
the program didn't have to check whether the token was a colon when it
was already type `TT_DictLiteral`.  Now the type applies to more
things including the braces enclosing a dictionary literal.  In
Verilog, struct literals start with a quote.  The quote is regarded as
an identifier by the program.  So the rule for aligning the fields in
ProtoBuf applied to this situation by mistake.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D152623

Files:
  clang/lib/Format/ContinuationIndenter.cpp
  clang/unittests/Format/FormatTestVerilog.cpp


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -1172,6 +1172,15 @@
   verifyFormat("c = '{a : 0, b : 0.0, default : 0};", Style);
   verifyFormat("c = ab'{a : 0, b : 0.0};", Style);
   verifyFormat("c = ab'{cd : cd'{1, 1.0}, ef : ef'{2, 2.0}};", Style);
+
+  // It should be indented correctly when the line has to break.
+  verifyFormat("c = //\n"
+   "'{default: 0};");
+  Style = getDefaultStyle();
+  Style.ContinuationIndentWidth = 2;
+  verifyFormat("c = //\n"
+   "  '{default: 0};",
+   Style);
 }
 
 TEST_F(FormatTestVerilog, StructuredProcedure) {
Index: clang/lib/Format/ContinuationIndenter.cpp
===
--- clang/lib/Format/ContinuationIndenter.cpp
+++ clang/lib/Format/ContinuationIndenter.cpp
@@ -1172,8 +1172,12 @@
   }
   if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
 return State.Stack[State.Stack.size() - 2].LastSpace;
+  // Field labels in a nested type should be aligned to the brace. For example
+  // in ProtoBuf:
+  //   optional int32 b = 2 [(foo_options) = {aaa: 123,
+  //  :"baz"}];
   if (Current.is(tok::identifier) && Current.Next &&
-  (Current.Next->is(TT_DictLiteral) ||
+  ((Current.Next->is(tok::colon) && Current.Next->is(TT_DictLiteral)) ||
((Style.Language == FormatStyle::LK_Proto ||
  Style.Language == FormatStyle::LK_TextProto) &&
 Current.Next->isOneOf(tok::less, tok::l_brace {


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -1172,6 +1172,15 @@
   verifyFormat("c = '{a : 0, b : 0.0, default : 0};", Style);
   verifyFormat("c = ab'{a : 0, b : 0.0};", Style);
   verifyFormat("c = ab'{cd : cd'{1, 1.0}, ef : ef'{2, 2.0}};", Style);
+
+  // It should be indented correctly when the line has to break.
+  verifyFormat("c = //\n"
+   "'{default: 0};");
+  Style = getDefaultStyle();
+  Style.ContinuationIndentWidth = 2;
+  verifyFormat("c = //\n"
+   "  '{default: 0};",
+   Style);
 }
 
 TEST_F(FormatTestVerilog, StructuredProcedure) {
Index: clang/lib/Format/ContinuationIndenter.cpp
===
--- clang/lib/Format/ContinuationIndenter.cpp
+++ clang/lib/Format/ContinuationIndenter.cpp
@@ -1172,8 +1172,12 @@
   }
   if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
 return State.Stack[State.Stack.size() - 2].LastSpace;
+  // Field labels in a nested type should be aligned to the brace. For example
+  // in ProtoBuf:
+  //   optional int32 b = 2 [(foo_options) = {aaa: 123,
+  //  :"baz"}];
   if (Current.is(tok::identifier) && Current.Next &&
-  (Current.Next->is(TT_DictLiteral) ||
+  ((Current.Next->is(tok::colon) && Current.Next->is(TT_DictLiteral)) ||
((Style.Language == FormatStyle::LK_Proto ||
  Style.Language == FormatStyle::LK_TextProto) &&
 Current.Next->isOneOf(tok::less, tok::l_brace {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D151632: [clang-format] Parse the Verilog language option in configuration

2023-06-02 Thread sstwcw via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG24231df9b8ef: [clang-format] Parse the Verilog language 
option in configuration (authored by sstwcw).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D151632

Files:
  clang/lib/Format/Format.cpp
  clang/unittests/Format/ConfigParseTest.cpp


Index: clang/unittests/Format/ConfigParseTest.cpp
===
--- clang/unittests/Format/ConfigParseTest.cpp
+++ clang/unittests/Format/ConfigParseTest.cpp
@@ -1022,6 +1022,23 @@
 ParseError::Error);
 
   EXPECT_EQ(FormatStyle::LK_Cpp, Style.Language);
+
+  Style.Language = FormatStyle::LK_Verilog;
+  CHECK_PARSE("---\n"
+  "Language: Verilog\n"
+  "IndentWidth: 12\n"
+  "---\n"
+  "Language: Cpp\n"
+  "IndentWidth: 34\n"
+  "...\n",
+  IndentWidth, 12u);
+  CHECK_PARSE("---\n"
+  "IndentWidth: 78\n"
+  "---\n"
+  "Language: Verilog\n"
+  "IndentWidth: 56\n"
+  "...\n",
+  IndentWidth, 56u);
 }
 
 TEST(ConfigParseTest, UsesLanguageForBasedOnStyle) {
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -375,6 +375,7 @@
 IO.enumCase(Value, "TextProto", FormatStyle::LK_TextProto);
 IO.enumCase(Value, "CSharp", FormatStyle::LK_CSharp);
 IO.enumCase(Value, "Json", FormatStyle::LK_Json);
+IO.enumCase(Value, "Verilog", FormatStyle::LK_Verilog);
   }
 };
 


Index: clang/unittests/Format/ConfigParseTest.cpp
===
--- clang/unittests/Format/ConfigParseTest.cpp
+++ clang/unittests/Format/ConfigParseTest.cpp
@@ -1022,6 +1022,23 @@
 ParseError::Error);
 
   EXPECT_EQ(FormatStyle::LK_Cpp, Style.Language);
+
+  Style.Language = FormatStyle::LK_Verilog;
+  CHECK_PARSE("---\n"
+  "Language: Verilog\n"
+  "IndentWidth: 12\n"
+  "---\n"
+  "Language: Cpp\n"
+  "IndentWidth: 34\n"
+  "...\n",
+  IndentWidth, 12u);
+  CHECK_PARSE("---\n"
+  "IndentWidth: 78\n"
+  "---\n"
+  "Language: Verilog\n"
+  "IndentWidth: 56\n"
+  "...\n",
+  IndentWidth, 56u);
 }
 
 TEST(ConfigParseTest, UsesLanguageForBasedOnStyle) {
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -375,6 +375,7 @@
 IO.enumCase(Value, "TextProto", FormatStyle::LK_TextProto);
 IO.enumCase(Value, "CSharp", FormatStyle::LK_CSharp);
 IO.enumCase(Value, "Json", FormatStyle::LK_Json);
+IO.enumCase(Value, "Verilog", FormatStyle::LK_Verilog);
   }
 };
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D151632: [clang-format] Parse the Verilog language option in configuration

2023-05-28 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
Herald added projects: All, clang, clang-format.
Herald added a subscriber: cfe-commits.
Herald added reviewers: rymiel, HazardyKnusperkeks, owenpan, MyDeveloperDay.
sstwcw requested review of this revision.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D151632

Files:
  clang/lib/Format/Format.cpp
  clang/unittests/Format/ConfigParseTest.cpp


Index: clang/unittests/Format/ConfigParseTest.cpp
===
--- clang/unittests/Format/ConfigParseTest.cpp
+++ clang/unittests/Format/ConfigParseTest.cpp
@@ -1022,6 +1022,23 @@
 ParseError::Error);
 
   EXPECT_EQ(FormatStyle::LK_Cpp, Style.Language);
+
+  Style.Language = FormatStyle::LK_Verilog;
+  CHECK_PARSE("---\n"
+  "Language: Verilog\n"
+  "IndentWidth: 12\n"
+  "---\n"
+  "Language: Cpp\n"
+  "IndentWidth: 34\n"
+  "...\n",
+  IndentWidth, 12u);
+  CHECK_PARSE("---\n"
+  "IndentWidth: 78\n"
+  "---\n"
+  "Language: Verilog\n"
+  "IndentWidth: 56\n"
+  "...\n",
+  IndentWidth, 56u);
 }
 
 TEST(ConfigParseTest, UsesLanguageForBasedOnStyle) {
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -375,6 +375,7 @@
 IO.enumCase(Value, "TextProto", FormatStyle::LK_TextProto);
 IO.enumCase(Value, "CSharp", FormatStyle::LK_CSharp);
 IO.enumCase(Value, "Json", FormatStyle::LK_Json);
+IO.enumCase(Value, "Verilog", FormatStyle::LK_Verilog);
   }
 };
 


Index: clang/unittests/Format/ConfigParseTest.cpp
===
--- clang/unittests/Format/ConfigParseTest.cpp
+++ clang/unittests/Format/ConfigParseTest.cpp
@@ -1022,6 +1022,23 @@
 ParseError::Error);
 
   EXPECT_EQ(FormatStyle::LK_Cpp, Style.Language);
+
+  Style.Language = FormatStyle::LK_Verilog;
+  CHECK_PARSE("---\n"
+  "Language: Verilog\n"
+  "IndentWidth: 12\n"
+  "---\n"
+  "Language: Cpp\n"
+  "IndentWidth: 34\n"
+  "...\n",
+  IndentWidth, 12u);
+  CHECK_PARSE("---\n"
+  "IndentWidth: 78\n"
+  "---\n"
+  "Language: Verilog\n"
+  "IndentWidth: 56\n"
+  "...\n",
+  IndentWidth, 56u);
 }
 
 TEST(ConfigParseTest, UsesLanguageForBasedOnStyle) {
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -375,6 +375,7 @@
 IO.enumCase(Value, "TextProto", FormatStyle::LK_TextProto);
 IO.enumCase(Value, "CSharp", FormatStyle::LK_CSharp);
 IO.enumCase(Value, "Json", FormatStyle::LK_Json);
+IO.enumCase(Value, "Verilog", FormatStyle::LK_Verilog);
   }
 };
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D149562: [clang-format] Stop comment disrupting indentation of Verilog ports

2023-05-15 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 rG369e8762b4d6: [clang-format] Stop comment disrupting 
indentation of Verilog ports (authored by sstwcw).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D149562

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/FormatToken.h
  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
@@ -517,6 +517,15 @@
"(input var x `a, //\n"
" b);\n"
"endmodule");
+  // A line comment shouldn't disrupt the indentation of the port list.
+  verifyFormat("extern module x\n"
+   "(//\n"
+   " output y);");
+  verifyFormat("extern module x\n"
+   "#(//\n"
+   "  parameter x)\n"
+   "(//\n"
+   " output y);");
   // With a concatenation in the names.
   auto Style = getDefaultStyle();
   Style.ColumnLimit = 40;
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -4196,11 +4196,14 @@
 if (FormatTok->is(Keywords.kw_verilogHash)) {
   NewLine();
   nextToken();
-  if (FormatTok->is(tok::l_paren))
+  if (FormatTok->is(tok::l_paren)) {
+FormatTok->setFinalizedType(TT_VerilogMultiLineListLParen);
 parseParens();
+  }
 }
 if (FormatTok->is(tok::l_paren)) {
   NewLine();
+  FormatTok->setFinalizedType(TT_VerilogMultiLineListLParen);
   parseParens();
 }
 
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -3312,6 +3312,8 @@
   if (Prev->is(BK_BracedInit) && Prev->opensScope()) {
 Current->SpacesRequiredBefore =
 (Style.Cpp11BracedListStyle && !Style.SpacesInParentheses) ? 0 : 1;
+  } else if (Prev->is(TT_VerilogMultiLineListLParen)) {
+Current->SpacesRequiredBefore = 0;
   } else {
 Current->SpacesRequiredBefore = Style.SpacesBeforeTrailingComments;
   }
Index: clang/lib/Format/FormatToken.h
===
--- clang/lib/Format/FormatToken.h
+++ clang/lib/Format/FormatToken.h
@@ -156,6 +156,9 @@
   /* list of port connections or parameters in a module instantiation */   \
   TYPE(VerilogInstancePortComma)   \
   TYPE(VerilogInstancePortLParen)  \
+  /* A parenthesized list within which line breaks are inserted by the \
+   * formatter, for example the list of ports in a module header. */   \
+  TYPE(VerilogMultiLineListLParen) \
   /* for the base in a number literal, not including the quote */  \
   TYPE(VerilogNumberBase)  \
   /* like `(strong1, pull0)` */\
Index: clang/lib/Format/ContinuationIndenter.cpp
===
--- clang/lib/Format/ContinuationIndenter.cpp
+++ clang/lib/Format/ContinuationIndenter.cpp
@@ -748,7 +748,8 @@
   !CurrentState.IsCSharpGenericTypeConstraint && Previous.opensScope() &&
   Previous.isNot(TT_ObjCMethodExpr) && Previous.isNot(TT_RequiresClause) &&
   !(Current.MacroParent && Previous.MacroParent) &&
-  (Current.isNot(TT_LineComment) || Previous.is(BK_BracedInit))) {
+  (Current.isNot(TT_LineComment) ||
+   Previous.isOneOf(BK_BracedInit, TT_VerilogMultiLineListLParen))) {
 CurrentState.Indent = State.Column + Spaces;
 CurrentState.IsAligned = true;
   }
Index: clang/include/clang/Format/Format.h
===
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -4019,9 +4019,12 @@
   /// The number of spaces before trailing line comments
   /// (``//`` - comments).
   ///
-  /// This does not affect trailing block comments (``/*`` - comments) as
-  /// those commonly have different usage patterns and a number of special
-  /// cases.
+  /// This does not affect trailing block comments (``/*`` - comments) as those
+  /// commonly have different 

[PATCH] D150403: [clang-format] Adjust braced list detection (try 2)

2023-05-12 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

> To this end, I am tracking the previous token type in a stack parallel
> to LBraceStack to help scope this particular case.

Maybe keep the description up to date with the code.


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

https://reviews.llvm.org/D150403

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


[PATCH] D150403: [clang-format] Adjust braced list detection (try 2)

2023-05-12 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

I would suggest adding a link to the revision on the issue thread for your 
future bug fixes.  This people like me don't try to fix what others have fixed.


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

https://reviews.llvm.org/D150403

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


[PATCH] D150452: [clang-format] Recognize nested blocks

2023-05-12 Thread sstwcw via Phabricator via cfe-commits
sstwcw abandoned this revision.
sstwcw added a comment.

I like D150403  better.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D150452

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


[PATCH] D150452: [clang-format] Recognize nested blocks

2023-05-12 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 521667.
sstwcw added a comment.

- Remove the special case for operator[], it isn't necessary.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D150452

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

Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -40,6 +40,8 @@
   EXPECT_EQ((FormatTok)->getType(), Type) << *(FormatTok)
 #define EXPECT_TOKEN_PRECEDENCE(FormatTok, Prec)   \
   EXPECT_EQ((FormatTok)->getPrecedence(), Prec) << *(FormatTok)
+#define EXPECT_BRACE_KIND(FormatTok, Kind) \
+  EXPECT_EQ(FormatTok->getBlockKind(), Kind)
 #define EXPECT_TOKEN(FormatTok, Kind, Type)\
   do { \
 EXPECT_TOKEN_KIND(FormatTok, Kind);\
@@ -1783,6 +1785,22 @@
   EXPECT_TOKEN(Tokens[3], tok::colon, TT_CaseLabelColon);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsNestedBlocks) {
+  // The closing braces are not annotated.  It doesn't seem to cause a
+  // problem.  So we only test for the opening braces.
+  auto Tokens = annotate("{\n"
+ "  {\n"
+ "{ int a = 0; }\n"
+ "  }\n"
+ "  {}\n"
+ "}");
+  ASSERT_EQ(Tokens.size(), 14u) << Tokens;
+  EXPECT_BRACE_KIND(Tokens[0], BK_Block);
+  EXPECT_BRACE_KIND(Tokens[1], BK_Block);
+  EXPECT_BRACE_KIND(Tokens[2], BK_Block);
+  EXPECT_BRACE_KIND(Tokens[10], BK_Block);
+}
+
 } // namespace
 } // namespace format
 } // namespace clang
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -55,6 +55,15 @@
 
 TEST_F(FormatTest, FormatsNestedBlockStatements) {
   EXPECT_EQ("{\n  {\n{}\n  }\n}", format("{{{}}}"));
+  // The innermost block is on a single line because a block with only 1
+  // statement is hard-coded to be squeezed into one line in
+  // ContinuationIndenter, not because it is recognized as an initializer list.
+  verifyFormat("int main() {\n"
+   "  {\n"
+   "{ int a = 0; }\n"
+   "  }\n"
+   "  {}\n"
+   "}");
 }
 
 TEST_F(FormatTest, FormatsNestedCall) {
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -488,10 +488,17 @@
   unsigned StoredPosition = Tokens->getPosition();
   FormatToken *Tok = FormatTok;
   const FormatToken *PrevTok = Tok->Previous;
+  // A rough guess at whether a block is a lambda expression.
+  bool ProbablyLambda = false;
   // Keep a stack of positions of lbrace tokens. We will
   // update information about whether an lbrace starts a
   // braced init list or a different block during the loop.
-  SmallVector LBraceStack;
+  struct StackEntry {
+FormatToken *Tok;
+const FormatToken *PrevTok, *NextTok;
+bool ProbablyLambda;
+  };
+  SmallVector LBraceStack;
   assert(Tok->is(tok::l_brace));
   do {
 // Get next non-comment token.
@@ -521,12 +528,13 @@
   } else {
 Tok->setBlockKind(BK_Unknown);
   }
-  LBraceStack.push_back(Tok);
+  LBraceStack.push_back({Tok, PrevTok, NextTok, ProbablyLambda});
   break;
 case tok::r_brace:
   if (LBraceStack.empty())
 break;
-  if (LBraceStack.back()->is(BK_Unknown)) {
+  switch (LBraceStack.back().Tok->getBlockKind()) {
+  case BK_Unknown: {
 bool ProbablyBracedList = false;
 if (Style.Language == FormatStyle::LK_Proto) {
   ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
@@ -554,7 +562,7 @@
 
   // If we already marked the opening brace as braced list, the closing
   // must also be part of it.
-  ProbablyBracedList = LBraceStack.back()->is(TT_BracedListLBrace);
+  ProbablyBracedList = LBraceStack.back().Tok->is(TT_BracedListLBrace);
 
   ProbablyBracedList = ProbablyBracedList ||
(Style.isJavaScript() &&
@@ -595,15 +603,43 @@
 }
 if (ProbablyBracedList) {
   Tok->setBlockKind(BK_BracedInit);
-  LBraceStack.back()->setBlockKind(BK_BracedInit);
+  LBraceStack.back().Tok->setBlockKind(BK_BracedInit);
 } else {
   Tok->setBlockKind(BK_Block);
-  LBraceStack.back()->setBlockKind(BK_Block);
+   

[PATCH] D149562: [clang-format] Stop comment disrupting indentation of Verilog ports

2023-05-12 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

> I agree if the brace doesn't start a block, but clang-format sometimes got it 
> wrong and misannotates a block as a braced list. (See 
> https://github.com/llvm/llvm-project/issues/33891 for an example.)

This patch isn't affected by the problem.  The Verilog port list is not as 
ambiguous as braced blocks.

> I'll go along with other reviewers on this one.

So what do the other reviewers think about this patch?  The braced 
initialization list thing was added a long time ago by DJasper, so that 
behavior probably has to stay.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D149562

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


[PATCH] D150452: [clang-format] Recognize nested blocks

2023-05-12 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
Herald added projects: All, clang, clang-format.
Herald added a subscriber: cfe-commits.
Herald added reviewers: rymiel, HazardyKnusperkeks, owenpan, MyDeveloperDay.
sstwcw requested review of this revision.

Now a block gets recognized as a block if it contains a block.

The special cases we added don't have additional tests because they
are already tested for example in FormatTest.FormatsLambdas and
FormatTestJS.ContainerLiterals.

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


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D150452

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

Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -40,6 +40,8 @@
   EXPECT_EQ((FormatTok)->getType(), Type) << *(FormatTok)
 #define EXPECT_TOKEN_PRECEDENCE(FormatTok, Prec)   \
   EXPECT_EQ((FormatTok)->getPrecedence(), Prec) << *(FormatTok)
+#define EXPECT_BRACE_KIND(FormatTok, Kind) \
+  EXPECT_EQ(FormatTok->getBlockKind(), Kind)
 #define EXPECT_TOKEN(FormatTok, Kind, Type)\
   do { \
 EXPECT_TOKEN_KIND(FormatTok, Kind);\
@@ -1783,6 +1785,22 @@
   EXPECT_TOKEN(Tokens[3], tok::colon, TT_CaseLabelColon);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsNestedBlocks) {
+  // The closing braces are not annotated.  It doesn't seem to cause a
+  // problem.  So we only test for the opening braces.
+  auto Tokens = annotate("{\n"
+ "  {\n"
+ "{ int a = 0; }\n"
+ "  }\n"
+ "  {}\n"
+ "}");
+  ASSERT_EQ(Tokens.size(), 14u) << Tokens;
+  EXPECT_BRACE_KIND(Tokens[0], BK_Block);
+  EXPECT_BRACE_KIND(Tokens[1], BK_Block);
+  EXPECT_BRACE_KIND(Tokens[2], BK_Block);
+  EXPECT_BRACE_KIND(Tokens[10], BK_Block);
+}
+
 } // namespace
 } // namespace format
 } // namespace clang
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -55,6 +55,15 @@
 
 TEST_F(FormatTest, FormatsNestedBlockStatements) {
   EXPECT_EQ("{\n  {\n{}\n  }\n}", format("{{{}}}"));
+  // The innermost block is on a single line because a block with only 1
+  // statement is hard-coded to be squeezed into one line in
+  // ContinuationIndenter, not because it is recognized as an initializer list.
+  verifyFormat("int main() {\n"
+   "  {\n"
+   "{ int a = 0; }\n"
+   "  }\n"
+   "  {}\n"
+   "}");
 }
 
 TEST_F(FormatTest, FormatsNestedCall) {
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -488,10 +488,17 @@
   unsigned StoredPosition = Tokens->getPosition();
   FormatToken *Tok = FormatTok;
   const FormatToken *PrevTok = Tok->Previous;
+  // A rough guess at whether a block is a lambda expression.
+  bool ProbablyLambda = false;
   // Keep a stack of positions of lbrace tokens. We will
   // update information about whether an lbrace starts a
   // braced init list or a different block during the loop.
-  SmallVector LBraceStack;
+  struct StackEntry {
+FormatToken *Tok;
+const FormatToken *PrevTok, *NextTok;
+bool ProbablyLambda;
+  };
+  SmallVector LBraceStack;
   assert(Tok->is(tok::l_brace));
   do {
 // Get next non-comment token.
@@ -521,12 +528,13 @@
   } else {
 Tok->setBlockKind(BK_Unknown);
   }
-  LBraceStack.push_back(Tok);
+  LBraceStack.push_back({Tok, PrevTok, NextTok, ProbablyLambda});
   break;
 case tok::r_brace:
   if (LBraceStack.empty())
 break;
-  if (LBraceStack.back()->is(BK_Unknown)) {
+  switch (LBraceStack.back().Tok->getBlockKind()) {
+  case BK_Unknown: {
 bool ProbablyBracedList = false;
 if (Style.Language == FormatStyle::LK_Proto) {
   ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
@@ -554,7 +562,7 @@
 
   // If we already marked the opening brace as braced list, the closing
   // must also be part of it.
-  ProbablyBracedList = LBraceStack.back()->is(TT_BracedListLBrace);
+  ProbablyBracedList = LBraceStack.back().Tok->is(TT_BracedListLBrace);
 
   ProbablyBracedList = ProbablyBracedList ||
(Style.isJavaScript() &&
@@ -595,15 +603,43 @@
   

[PATCH] D149562: [clang-format] Stop comment disrupting indentation of Verilog ports

2023-05-10 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

> IMO a trailing comment (empty or not) belongs to the code before it.

There is only a parenthesis before it.  It doesn't usually need a comment.  It 
is like in 5a61139.  One doesn't tend to comment a single brace.

> A comment about the code below it should start on a new line.

In this special case, the comment would be indented to the same column as the 
next line, so it should be clear it is for the next line.  Like the case 
forbraced initializer lists, the first field will be on the same line as the 
brace if there isn't a comment, so the first comment is also on the same line 
as the brace when there is one.

  foo foo{// first field
  a,
  // second field
  b};


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D149562

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


[PATCH] D149657: [clang-format] Don't indent Verilog `begin` keyword on its own line

2023-05-06 Thread sstwcw via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGdf722b01246d: [clang-format] Dont indent Verilog 
`begin` keyword on its own line (authored by sstwcw).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D149657

Files:
  clang/lib/Format/ContinuationIndenter.cpp
  clang/unittests/Format/FormatTestVerilog.cpp


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -162,6 +162,39 @@
"x = x;");
   verifyFormat("rand join x x;\n"
"x = x;");
+  // The begin keyword should not be indented if it is too long to fit on the
+  // same line.
+  verifyFormat("while (true) //\n"
+   "begin\n"
+   "  while (true) //\n"
+   "  begin\n"
+   "  end\n"
+   "end");
+  verifyFormat("while (true) //\n"
+   "begin : x\n"
+   "  while (true) //\n"
+   "  begin : x\n"
+   "  end : x\n"
+   "end : x");
+  verifyFormat("while (true) //\n"
+   "fork\n"
+   "  while (true) //\n"
+   "  fork\n"
+   "  join\n"
+   "join");
+  auto Style = getDefaultStyle();
+  Style.ColumnLimit = 17;
+  verifyFormat("while (true)\n"
+   "begin\n"
+   "  while (true)\n"
+   "  begin\n"
+   "  end\n"
+   "end",
+   "while (true) begin\n"
+   "  while (true) begin"
+   "  end\n"
+   "end",
+   Style);
 }
 
 TEST_F(FormatTestVerilog, Case) {
Index: clang/lib/Format/ContinuationIndenter.cpp
===
--- clang/lib/Format/ContinuationIndenter.cpp
+++ clang/lib/Format/ContinuationIndenter.cpp
@@ -1125,7 +1125,8 @@
Style.IndentWidth;
   }
 
-  if (NextNonComment->is(tok::l_brace) && NextNonComment->is(BK_Block)) {
+  if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(BK_Block)) ||
+  (Style.isVerilog() && Keywords.isVerilogBegin(*NextNonComment))) {
 if (Current.NestingLevel == 0 ||
 (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
  State.NextToken->is(TT_LambdaLBrace))) {


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -162,6 +162,39 @@
"x = x;");
   verifyFormat("rand join x x;\n"
"x = x;");
+  // The begin keyword should not be indented if it is too long to fit on the
+  // same line.
+  verifyFormat("while (true) //\n"
+   "begin\n"
+   "  while (true) //\n"
+   "  begin\n"
+   "  end\n"
+   "end");
+  verifyFormat("while (true) //\n"
+   "begin : x\n"
+   "  while (true) //\n"
+   "  begin : x\n"
+   "  end : x\n"
+   "end : x");
+  verifyFormat("while (true) //\n"
+   "fork\n"
+   "  while (true) //\n"
+   "  fork\n"
+   "  join\n"
+   "join");
+  auto Style = getDefaultStyle();
+  Style.ColumnLimit = 17;
+  verifyFormat("while (true)\n"
+   "begin\n"
+   "  while (true)\n"
+   "  begin\n"
+   "  end\n"
+   "end",
+   "while (true) begin\n"
+   "  while (true) begin"
+   "  end\n"
+   "end",
+   Style);
 }
 
 TEST_F(FormatTestVerilog, Case) {
Index: clang/lib/Format/ContinuationIndenter.cpp
===
--- clang/lib/Format/ContinuationIndenter.cpp
+++ clang/lib/Format/ContinuationIndenter.cpp
@@ -1125,7 +1125,8 @@
Style.IndentWidth;
   }
 
-  if (NextNonComment->is(tok::l_brace) && NextNonComment->is(BK_Block)) {
+  if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(BK_Block)) ||
+  (Style.isVerilog() && Keywords.isVerilogBegin(*NextNonComment))) {
 if (Current.NestingLevel == 0 ||
 (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
  State.NextToken->is(TT_LambdaLBrace))) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D149561: [clang-format] Recognize Verilog edge identifiers

2023-05-06 Thread sstwcw via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGe12428557a45: [clang-format] Recognize Verilog edge 
identifiers (authored by sstwcw).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D149561

Files:
  clang/lib/Format/FormatToken.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
@@ -1684,6 +1684,15 @@
   Tokens = Annotate("case (x) endcase;");
   ASSERT_EQ(Tokens.size(), 7u) << Tokens;
   EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+
+  // Sensitivity list. The TT_Unknown type is clearly not binding for the
+  // future, please adapt if those tokens get annotated.  This test is only here
+  // to prevent the comma from being annotated as TT_VerilogInstancePortComma.
+  Tokens = Annotate("always @(posedge x, posedge y);");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_Unknown);
+  EXPECT_TOKEN(Tokens[5], tok::comma, TT_Unknown);
+  EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_Unknown);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandConstructors) {
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -1157,6 +1157,14 @@
"  x <= x;");
   verifyFormat("always @(posedge x)\n"
"  x <= x;");
+  verifyFormat("always @(posedge x or posedge y)\n"
+   "  x <= x;");
+  verifyFormat("always @(posedge x, posedge y)\n"
+   "  x <= x;");
+  verifyFormat("always @(negedge x, negedge y)\n"
+   "  x <= x;");
+  verifyFormat("always @(edge x, edge y)\n"
+   "  x <= x;");
   verifyFormat("always\n"
"  x <= x;");
   verifyFormat("always @*\n"
Index: clang/lib/Format/FormatToken.h
===
--- clang/lib/Format/FormatToken.h
+++ clang/lib/Format/FormatToken.h
@@ -1068,6 +1068,7 @@
 kw_delay_mode_zero = ("delay_mode_zero");
 kw_disable = ("disable");
 kw_dist = ("dist");
+kw_edge = ("edge");
 kw_elsif = ("elsif");
 kw_end = ("end");
 kw_end_keywords = ("end_keywords");
@@ -1113,10 +1114,12 @@
 kw_macromodule = ("macromodule");
 kw_matches = ("matches");
 kw_medium = ("medium");
+kw_negedge = ("negedge");
 kw_nounconnected_drive = ("nounconnected_drive");
 kw_output = ("output");
 kw_packed = ("packed");
 kw_parameter = ("parameter");
+kw_posedge = ("posedge");
 kw_primitive = ("primitive");
 kw_priority = ("priority");
 kw_program = ("program");
@@ -1198,132 +1201,71 @@
 // Some keywords are not included here because they don't need special
 // treatment like `showcancelled` or they should be treated as identifiers
 // like `int` and `logic`.
-VerilogExtraKeywords =
-std::unordered_set({kw_always,
-  kw_always_comb,
-  kw_always_ff,
-  kw_always_latch,
-  kw_assert,
-  kw_assign,
-  kw_assume,
-  kw_automatic,
-  kw_before,
-  kw_begin,
-  kw_bins,
-  kw_binsof,
-  kw_casex,
-  kw_casez,
-  kw_celldefine,
-  kw_checker,
-  kw_clocking,
-  kw_constraint,
-  kw_cover,
-  kw_covergroup,
-  kw_coverpoint,
-  kw_disable,
-  kw_dist,
-  kw_end,
-  kw_endcase,
-  kw_endchecker,
-  kw_endclass,
-  kw_endclocking,
-  kw_endfunction,
- 

[PATCH] D149657: [clang-format] Stop indent Verilog `begin` keyword on single line

2023-05-02 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
Herald added projects: All, clang, clang-format.
Herald added a subscriber: cfe-commits.
Herald added reviewers: rymiel, HazardyKnusperkeks, owenpan, MyDeveloperDay.
sstwcw requested review of this revision.

When the line is too long and the `begin` keyword wraps to the next
line, it shouldn't be indented.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D149657

Files:
  clang/lib/Format/ContinuationIndenter.cpp
  clang/unittests/Format/FormatTestVerilog.cpp


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -162,6 +162,39 @@
"x = x;");
   verifyFormat("rand join x x;\n"
"x = x;");
+  // The begin keyword should not be indented if it is too long to fit on the
+  // same line.
+  verifyFormat("while (true) //\n"
+   "begin\n"
+   "  while (true) //\n"
+   "  begin\n"
+   "  end\n"
+   "end");
+  verifyFormat("while (true) //\n"
+   "begin : x\n"
+   "  while (true) //\n"
+   "  begin : x\n"
+   "  end : x\n"
+   "end : x");
+  verifyFormat("while (true) //\n"
+   "fork\n"
+   "  while (true) //\n"
+   "  fork\n"
+   "  join\n"
+   "join");
+  auto Style = getDefaultStyle();
+  Style.ColumnLimit = 17;
+  verifyFormat("while (true)\n"
+   "begin\n"
+   "  while (true)\n"
+   "  begin\n"
+   "  end\n"
+   "end",
+   "while (true) begin\n"
+   "  while (true) begin"
+   "  end\n"
+   "end",
+   Style);
 }
 
 TEST_F(FormatTestVerilog, Case) {
Index: clang/lib/Format/ContinuationIndenter.cpp
===
--- clang/lib/Format/ContinuationIndenter.cpp
+++ clang/lib/Format/ContinuationIndenter.cpp
@@ -1125,7 +1125,8 @@
Style.IndentWidth;
   }
 
-  if (NextNonComment->is(tok::l_brace) && NextNonComment->is(BK_Block)) {
+  if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(BK_Block)) ||
+  (Style.isVerilog() && Keywords.isVerilogBegin(*NextNonComment))) {
 if (Current.NestingLevel == 0 ||
 (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
  State.NextToken->is(TT_LambdaLBrace))) {


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -162,6 +162,39 @@
"x = x;");
   verifyFormat("rand join x x;\n"
"x = x;");
+  // The begin keyword should not be indented if it is too long to fit on the
+  // same line.
+  verifyFormat("while (true) //\n"
+   "begin\n"
+   "  while (true) //\n"
+   "  begin\n"
+   "  end\n"
+   "end");
+  verifyFormat("while (true) //\n"
+   "begin : x\n"
+   "  while (true) //\n"
+   "  begin : x\n"
+   "  end : x\n"
+   "end : x");
+  verifyFormat("while (true) //\n"
+   "fork\n"
+   "  while (true) //\n"
+   "  fork\n"
+   "  join\n"
+   "join");
+  auto Style = getDefaultStyle();
+  Style.ColumnLimit = 17;
+  verifyFormat("while (true)\n"
+   "begin\n"
+   "  while (true)\n"
+   "  begin\n"
+   "  end\n"
+   "end",
+   "while (true) begin\n"
+   "  while (true) begin"
+   "  end\n"
+   "end",
+   Style);
 }
 
 TEST_F(FormatTestVerilog, Case) {
Index: clang/lib/Format/ContinuationIndenter.cpp
===
--- clang/lib/Format/ContinuationIndenter.cpp
+++ clang/lib/Format/ContinuationIndenter.cpp
@@ -1125,7 +1125,8 @@
Style.IndentWidth;
   }
 
-  if (NextNonComment->is(tok::l_brace) && NextNonComment->is(BK_Block)) {
+  if ((NextNonComment->is(tok::l_brace) && NextNonComment->is(BK_Block)) ||
+  (Style.isVerilog() && Keywords.isVerilogBegin(*NextNonComment))) {
 if (Current.NestingLevel == 0 ||
 (Style.LambdaBodyIndentation == FormatStyle::LBI_OuterScope &&
  State.NextToken->is(TT_LambdaLBrace))) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D149561: [clang-format] Recognize Verilog edge identifiers

2023-05-02 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 518752.
sstwcw added a comment.

- add annotator test


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D149561

Files:
  clang/lib/Format/FormatToken.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
@@ -1684,6 +1684,15 @@
   Tokens = Annotate("case (x) endcase;");
   ASSERT_EQ(Tokens.size(), 7u) << Tokens;
   EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+
+  // Sensitivity list. The TT_Unknown type is clearly not binding for the
+  // future, please adapt if those tokens get annotated.  This test is only here
+  // to prevent the comma from being annotated as TT_VerilogInstancePortComma.
+  Tokens = Annotate("always @(posedge x, posedge y);");
+  ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_Unknown);
+  EXPECT_TOKEN(Tokens[5], tok::comma, TT_Unknown);
+  EXPECT_TOKEN(Tokens[8], tok::r_paren, TT_Unknown);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandConstructors) {
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -1157,6 +1157,14 @@
"  x <= x;");
   verifyFormat("always @(posedge x)\n"
"  x <= x;");
+  verifyFormat("always @(posedge x or posedge y)\n"
+   "  x <= x;");
+  verifyFormat("always @(posedge x, posedge y)\n"
+   "  x <= x;");
+  verifyFormat("always @(negedge x, negedge y)\n"
+   "  x <= x;");
+  verifyFormat("always @(edge x, edge y)\n"
+   "  x <= x;");
   verifyFormat("always\n"
"  x <= x;");
   verifyFormat("always @*\n"
Index: clang/lib/Format/FormatToken.h
===
--- clang/lib/Format/FormatToken.h
+++ clang/lib/Format/FormatToken.h
@@ -1068,6 +1068,7 @@
 kw_delay_mode_zero = ("delay_mode_zero");
 kw_disable = ("disable");
 kw_dist = ("dist");
+kw_edge = ("edge");
 kw_elsif = ("elsif");
 kw_end = ("end");
 kw_end_keywords = ("end_keywords");
@@ -1113,10 +1114,12 @@
 kw_macromodule = ("macromodule");
 kw_matches = ("matches");
 kw_medium = ("medium");
+kw_negedge = ("negedge");
 kw_nounconnected_drive = ("nounconnected_drive");
 kw_output = ("output");
 kw_packed = ("packed");
 kw_parameter = ("parameter");
+kw_posedge = ("posedge");
 kw_primitive = ("primitive");
 kw_priority = ("priority");
 kw_program = ("program");
@@ -1198,132 +1201,71 @@
 // Some keywords are not included here because they don't need special
 // treatment like `showcancelled` or they should be treated as identifiers
 // like `int` and `logic`.
-VerilogExtraKeywords =
-std::unordered_set({kw_always,
-  kw_always_comb,
-  kw_always_ff,
-  kw_always_latch,
-  kw_assert,
-  kw_assign,
-  kw_assume,
-  kw_automatic,
-  kw_before,
-  kw_begin,
-  kw_bins,
-  kw_binsof,
-  kw_casex,
-  kw_casez,
-  kw_celldefine,
-  kw_checker,
-  kw_clocking,
-  kw_constraint,
-  kw_cover,
-  kw_covergroup,
-  kw_coverpoint,
-  kw_disable,
-  kw_dist,
-  kw_end,
-  kw_endcase,
-  kw_endchecker,
-  kw_endclass,
-  kw_endclocking,
-  kw_endfunction,
-  kw_endgenerate,
-  kw_endgroup,
-  

[PATCH] D149562: [clang-format] Stop comment disrupting indentation of Verilog ports

2023-05-02 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

In D149562#4310396 , 
@HazardyKnusperkeks wrote:

> I don't see the problem, could you elaborate a bit more? (Keep in mind, I 
> have no idea about Verilog.)

The current way the port list gets formatted is like this:

  module x
  (input x1,
   input x2,
   input x3,
   input x4);
  endmodule

One may want to add a comment for one of the ports like this:

  module x
  (input x1,
   // second port
   input x2,
   // third port
   input x3,
   // forth port
   input x4);
  endmodule

The port list thing and the comment thing work fine for now, except
when there is a comment for the first port.  The comment on the first
line would cause the port list to be indented, like this:

  module x
  ( // first port
  input x1,
  // second port
  input x2,
  // third port
  input x3,
  // forth port
  input x4);
  endmodule

After this patch, a comment on the first line would not cause the
problem.  Now the code gets formatted like this.  The ports are
indented the same whether or not there is a comment on the first line.

  module x
  (// first port
   input x1,
   // second port
   input x2,
   // third port
   input x3,
   // forth port
   input x4);
  endmodule




Comment at: clang/include/clang/Format/Format.h:4027
+  /// is probably for the port on the following line instead of the parenthesis
+  /// it follows.
   /// \code

MyDeveloperDay wrote:
> This seems an odd corner case
See the last block of code in the example I added.  This is the only way I came 
up with to ensure that the comment for the first port is aligned with the 
comments for the rest of the ports and that whether the first comment exists 
does not affect how other lines are indented.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D149562

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


[PATCH] D149562: [clang-format] Stop comment disrupting indentation of Verilog ports

2023-04-30 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
Herald added projects: All, clang, clang-format.
Herald added a subscriber: cfe-commits.
Herald added reviewers: rymiel, HazardyKnusperkeks, owenpan, MyDeveloperDay.
sstwcw requested review of this revision.

Before:

  module x
  #( //
  parameter x)
  ( //
  input y);
  endmodule

After:

  module x
  #(//
parameter x)
  (//
   input y);
  endmodule

If the first line in a port or parameter list is not a comment, the
following lines would be aligned to the first line as intended:

  module x
  #(parameter x1,
parameter x2)
  (input y,
   input y2);
  endmodule

Previously, the indentation would be changed to an extra continuation
indentation relative to the start of the parenthesis or the hash if
the first token inside the parentheses is a comment.  It is a feature
introduced in ddaa9be97839.  The feature enabled one to insert a `//`
comment right after an opening parentheses to put the function
arguments on a new line with a small indentation regardless of how
long the function name is, like this:

  someFunction(anotherFunction( // Force break.
  parameter));
  `

People are unlikely to use this feature in a Verilog port list because
the formatter already puts the port list on its own lines.  A comment
at the start of a port list is probably a comment for the port on the
next line.

We also removed the space before the comment so that its indentation
would be same as that for a line comment anywhere else in the port
list.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D149562

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/FormatToken.h
  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
@@ -484,6 +484,15 @@
"(input var x `a, //\n"
" b);\n"
"endmodule");
+  // A line comment shouldn't disrupt the indentation of the port list.
+  verifyFormat("extern module x\n"
+   "(//\n"
+   " output y);");
+  verifyFormat("extern module x\n"
+   "#(//\n"
+   "  parameter x)\n"
+   "(//\n"
+   " output y);");
   // With a concatenation in the names.
   auto Style = getDefaultStyle();
   Style.ColumnLimit = 40;
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -4194,11 +4194,14 @@
 if (FormatTok->is(Keywords.kw_verilogHash)) {
   NewLine();
   nextToken();
-  if (FormatTok->is(tok::l_paren))
+  if (FormatTok->is(tok::l_paren)) {
+FormatTok->setFinalizedType(TT_VerilogMultiLineListLParen);
 parseParens();
+  }
 }
 if (FormatTok->is(tok::l_paren)) {
   NewLine();
+  FormatTok->setFinalizedType(TT_VerilogMultiLineListLParen);
   parseParens();
 }
 
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -3312,6 +3312,8 @@
   if (Prev->is(BK_BracedInit) && Prev->opensScope()) {
 Current->SpacesRequiredBefore =
 (Style.Cpp11BracedListStyle && !Style.SpacesInParentheses) ? 0 : 1;
+  } else if (Prev->is(TT_VerilogMultiLineListLParen)) {
+Current->SpacesRequiredBefore = 0;
   } else {
 Current->SpacesRequiredBefore = Style.SpacesBeforeTrailingComments;
   }
Index: clang/lib/Format/FormatToken.h
===
--- clang/lib/Format/FormatToken.h
+++ clang/lib/Format/FormatToken.h
@@ -156,6 +156,9 @@
   /* list of port connections or parameters in a module instantiation */   \
   TYPE(VerilogInstancePortComma)   \
   TYPE(VerilogInstancePortLParen)  \
+  /* A parenthesized list within which line breaks are inserted by the \
+   * formatter, for example the list of ports in a module header. */   \
+  TYPE(VerilogMultiLineListLParen) \
   /* for the base in a number literal, not including the quote */  \
   TYPE(VerilogNumberBase)  \
   /* like `(strong1, pull0)` */\
Index: clang/lib/Format/ContinuationIndenter.cpp

[PATCH] D149561: [clang-format] Recognize Verilog edge identifiers

2023-04-30 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
Herald added projects: All, clang, clang-format.
Herald added a subscriber: cfe-commits.
Herald added reviewers: rymiel, HazardyKnusperkeks, owenpan, MyDeveloperDay.
sstwcw requested review of this revision.

Previously the event expression would be misidentified as a port list.
A line break would be added after the comma.  The events can be
separated with either a comma or the `or` keyword, and a line break
would not be inserted if the `or` keyword was used.  We changed the
behavior of the comma to match the `or` keyword.

Before:

  always @(posedge x,
   posedge y)
x <= x;
  always @(posedge x or posedge y)
x <= x;

After:

  always @(posedge x, posedge y)
x <= x;
  always @(posedge x or posedge y)
x <= x;


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D149561

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

Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -1157,6 +1157,14 @@
"  x <= x;");
   verifyFormat("always @(posedge x)\n"
"  x <= x;");
+  verifyFormat("always @(posedge x or posedge y)\n"
+   "  x <= x;");
+  verifyFormat("always @(posedge x, posedge y)\n"
+   "  x <= x;");
+  verifyFormat("always @(negedge x, negedge y)\n"
+   "  x <= x;");
+  verifyFormat("always @(edge x, edge y)\n"
+   "  x <= x;");
   verifyFormat("always\n"
"  x <= x;");
   verifyFormat("always @*\n"
Index: clang/lib/Format/FormatToken.h
===
--- clang/lib/Format/FormatToken.h
+++ clang/lib/Format/FormatToken.h
@@ -1068,6 +1068,7 @@
 kw_delay_mode_zero = ("delay_mode_zero");
 kw_disable = ("disable");
 kw_dist = ("dist");
+kw_edge = ("edge");
 kw_elsif = ("elsif");
 kw_end = ("end");
 kw_end_keywords = ("end_keywords");
@@ -1113,10 +1114,12 @@
 kw_macromodule = ("macromodule");
 kw_matches = ("matches");
 kw_medium = ("medium");
+kw_negedge = ("negedge");
 kw_nounconnected_drive = ("nounconnected_drive");
 kw_output = ("output");
 kw_packed = ("packed");
 kw_parameter = ("parameter");
+kw_posedge = ("posedge");
 kw_primitive = ("primitive");
 kw_priority = ("priority");
 kw_program = ("program");
@@ -1198,132 +1201,71 @@
 // Some keywords are not included here because they don't need special
 // treatment like `showcancelled` or they should be treated as identifiers
 // like `int` and `logic`.
-VerilogExtraKeywords =
-std::unordered_set({kw_always,
-  kw_always_comb,
-  kw_always_ff,
-  kw_always_latch,
-  kw_assert,
-  kw_assign,
-  kw_assume,
-  kw_automatic,
-  kw_before,
-  kw_begin,
-  kw_bins,
-  kw_binsof,
-  kw_casex,
-  kw_casez,
-  kw_celldefine,
-  kw_checker,
-  kw_clocking,
-  kw_constraint,
-  kw_cover,
-  kw_covergroup,
-  kw_coverpoint,
-  kw_disable,
-  kw_dist,
-  kw_end,
-  kw_endcase,
-  kw_endchecker,
-  kw_endclass,
-  kw_endclocking,
-  kw_endfunction,
-  kw_endgenerate,
-  kw_endgroup,
-  kw_endinterface,
-  kw_endmodule,
-  kw_endpackage,
-  kw_endprimitive,
-  kw_endprogram,
-  kw_endproperty,
-  

[PATCH] D148484: [clang-format] Correctly format goto labels followed by blocks

2023-04-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 rG82a90caa88fd: [clang-format] Correctly format goto labels 
followed by blocks (authored by sstwcw).

Changed prior to commit:
  https://reviews.llvm.org/D148484?vs=514249=518363#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D148484

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
@@ -1621,7 +1621,7 @@
 "x;\n"
 "endcase\n");
   ASSERT_EQ(Tokens.size(), 10u) << Tokens;
-  EXPECT_TOKEN(Tokens[5], tok::colon, TT_GotoLabelColon);
+  EXPECT_TOKEN(Tokens[5], tok::colon, TT_CaseLabelColon);
   Tokens = Annotate("case (x)\n"
 "  x ? x : x:\n"
 "x;\n"
@@ -1629,7 +1629,7 @@
   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);
+  EXPECT_TOKEN(Tokens[9], tok::colon, TT_CaseLabelColon);
   // Non-blocking assignments.
   Tokens = Annotate("a <= b;");
   ASSERT_EQ(Tokens.size(), 5u) << Tokens;
@@ -1752,6 +1752,21 @@
   EXPECT_TOKEN(Tokens[1], tok::question, TT_ConditionalExpr);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsLabels) {
+  auto Tokens = annotate("{ x: break; }");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::colon, TT_GotoLabelColon);
+  Tokens = annotate("{ case x: break; }");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::colon, TT_CaseLabelColon);
+  Tokens = annotate("{ x: { break; } }");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::colon, TT_GotoLabelColon);
+  Tokens = annotate("{ case x: { break; } }");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::colon, TT_CaseLabelColon);
+}
+
 } // namespace
 } // namespace format
 } // namespace clang
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2998,6 +2998,17 @@
"test_label:;\n"
"  int i = 0;\n"
"}");
+  verifyFormat("{\n"
+   "  some_code();\n"
+   "test_label: { some_other_code(); }\n"
+   "}");
+  verifyFormat("{\n"
+   "  some_code();\n"
+   "test_label: {\n"
+   "  some_other_code();\n"
+   "  some_other_code();\n"
+   "}\n"
+   "}");
   FormatStyle Style = getLLVMStyle();
   Style.IndentGotoLabels = false;
   verifyFormat("void f() {\n"
@@ -3022,6 +3033,23 @@
"test_label:;\n"
"  int i = 0;\n"
"}");
+  verifyFormat("{\n"
+   "  some_code();\n"
+   "test_label: { some_other_code(); }\n"
+   "}",
+   Style);
+  // The opening brace may either be on the same unwrapped line as the colon or
+  // on a separate one. The formatter should recognize both.
+  Style = getLLVMStyle();
+  Style.BreakBeforeBraces = FormatStyle::BraceBreakingStyle::BS_Allman;
+  verifyFormat("{\n"
+   "  some_code();\n"
+   "test_label:\n"
+   "{\n"
+   "  some_other_code();\n"
+   "}\n"
+   "}",
+   Style);
 }
 
 TEST_F(FormatTest, MultiLineControlStatements) {
@@ -16962,6 +16990,19 @@
"}\n"
"}",
CaseStyle);
+  // Goto labels should not be affected.
+  verifyFormat("switch (x) {\n"
+   "goto_label:\n"
+   "default :\n"
+   "}",
+   CaseStyle);
+  verifyFormat("switch (x) {\n"
+   "goto_label: { break; }\n"
+   "default : {\n"
+   "  break;\n"
+   "}\n"
+   "}",
+   CaseStyle);
 
   FormatStyle NoSpaceStyle = getLLVMStyle();
   EXPECT_EQ(NoSpaceStyle.SpaceBeforeCaseColon, false);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1493,6 +1493,7 @@
 }
 nextToken();
 if (FormatTok->is(tok::colon)) {
+  FormatTok->setFinalizedType(TT_CaseLabelColon);
   parseLabel();
   return;
 }

[PATCH] D149352: [clang-format] Recognize Verilog type dimension in module header

2023-04-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 rG4134f836103e: [clang-format] Recognize Verilog type 
dimension in module header (authored by sstwcw).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D149352

Files:
  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
@@ -1615,6 +1615,13 @@
   Tokens = Annotate("extern function [1 : 0] x;");
   ASSERT_EQ(Tokens.size(), 10u) << Tokens;
   EXPECT_TOKEN(Tokens[4], tok::colon, TT_BitFieldColon);
+  Tokens = Annotate("module test\n"
+"(input wire [7 : 0] a[7 : 0]);\n"
+"endmodule");
+  ASSERT_EQ(Tokens.size(), 20u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::identifier, TT_VerilogDimensionedTypeName);
+  EXPECT_TOKEN(Tokens[7], tok::colon, TT_BitFieldColon);
+  EXPECT_TOKEN(Tokens[13], tok::colon, TT_BitFieldColon);
   // Test case labels and ternary operators.
   Tokens = Annotate("case (x)\n"
 "  x:\n"
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -359,6 +359,12 @@
" input var shortreal in2,\n"
" output tagged_st out);\n"
"endmodule");
+  // There should be a space following the type but not the variable name.
+  verifyFormat("module test\n"
+   "(input wire [7 : 0] a,\n"
+   " input wire b[7 : 0],\n"
+   " input wire [7 : 0] c[7 : 0]);\n"
+   "endmodule");
   // Ports should be grouped by types.
   verifyFormat("module test\n"
"(input [7 : 0] a,\n"
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2165,6 +2165,10 @@
   /// This is a heuristic based on whether \p Tok is an identifier following
   /// something that is likely a type.
   bool isStartOfName(const FormatToken ) {
+// Handled in ExpressionParser for Verilog.
+if (Style.isVerilog())
+  return false;
+
 if (Tok.isNot(tok::identifier) || !Tok.Previous)
   return false;
 


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -1615,6 +1615,13 @@
   Tokens = Annotate("extern function [1 : 0] x;");
   ASSERT_EQ(Tokens.size(), 10u) << Tokens;
   EXPECT_TOKEN(Tokens[4], tok::colon, TT_BitFieldColon);
+  Tokens = Annotate("module test\n"
+"(input wire [7 : 0] a[7 : 0]);\n"
+"endmodule");
+  ASSERT_EQ(Tokens.size(), 20u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::identifier, TT_VerilogDimensionedTypeName);
+  EXPECT_TOKEN(Tokens[7], tok::colon, TT_BitFieldColon);
+  EXPECT_TOKEN(Tokens[13], tok::colon, TT_BitFieldColon);
   // Test case labels and ternary operators.
   Tokens = Annotate("case (x)\n"
 "  x:\n"
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -359,6 +359,12 @@
" input var shortreal in2,\n"
" output tagged_st out);\n"
"endmodule");
+  // There should be a space following the type but not the variable name.
+  verifyFormat("module test\n"
+   "(input wire [7 : 0] a,\n"
+   " input wire b[7 : 0],\n"
+   " input wire [7 : 0] c[7 : 0]);\n"
+   "endmodule");
   // Ports should be grouped by types.
   verifyFormat("module test\n"
"(input [7 : 0] a,\n"
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2165,6 +2165,10 @@
   /// This is a heuristic based on whether \p Tok is an identifier following
   /// something that is likely a type.
   bool isStartOfName(const FormatToken ) {
+// Handled in ExpressionParser for Verilog.
+if (Style.isVerilog())
+  return false;
+
 if (Tok.isNot(tok::identifier) || !Tok.Previous)
   return false;
 
___
cfe-commits mailing 

[PATCH] D149352: [clang-format] Recognize Verilog type dimension in module header

2023-04-27 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
sstwcw added a reviewer: curdeius.
Herald added projects: All, clang, clang-format.
Herald added a subscriber: cfe-commits.
Herald added reviewers: rymiel, HazardyKnusperkeks, owenpan, MyDeveloperDay.
sstwcw requested review of this revision.

We had the function `verilogGroupDecl` for that.  However, the type
name would be incorrectly annotated in `isStartOfName` when it was not
a C++ keyword and followed another identifier.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D149352

Files:
  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
@@ -1615,6 +1615,13 @@
   Tokens = Annotate("extern function [1 : 0] x;");
   ASSERT_EQ(Tokens.size(), 10u) << Tokens;
   EXPECT_TOKEN(Tokens[4], tok::colon, TT_BitFieldColon);
+  Tokens = Annotate("module test\n"
+"(input wire [7 : 0] a[7 : 0]);\n"
+"endmodule");
+  ASSERT_EQ(Tokens.size(), 20u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::identifier, TT_VerilogDimensionedTypeName);
+  EXPECT_TOKEN(Tokens[7], tok::colon, TT_BitFieldColon);
+  EXPECT_TOKEN(Tokens[13], tok::colon, TT_BitFieldColon);
   // Test case labels and ternary operators.
   Tokens = Annotate("case (x)\n"
 "  x:\n"
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -359,6 +359,12 @@
" input var shortreal in2,\n"
" output tagged_st out);\n"
"endmodule");
+  // There should be a space following the type but not the variable name.
+  verifyFormat("module test\n"
+   "(input wire [7 : 0] a,\n"
+   " input wire b[7 : 0],\n"
+   " input wire [7 : 0] c[7 : 0]);\n"
+   "endmodule");
   // Ports should be grouped by types.
   verifyFormat("module test\n"
"(input [7 : 0] a,\n"
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2161,6 +2161,10 @@
   /// This is a heuristic based on whether \p Tok is an identifier following
   /// something that is likely a type.
   bool isStartOfName(const FormatToken ) {
+// Handled in ExpressionParser for Verilog.
+if (Style.isVerilog())
+  return false;
+
 if (Tok.isNot(tok::identifier) || !Tok.Previous)
   return false;
 


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -1615,6 +1615,13 @@
   Tokens = Annotate("extern function [1 : 0] x;");
   ASSERT_EQ(Tokens.size(), 10u) << Tokens;
   EXPECT_TOKEN(Tokens[4], tok::colon, TT_BitFieldColon);
+  Tokens = Annotate("module test\n"
+"(input wire [7 : 0] a[7 : 0]);\n"
+"endmodule");
+  ASSERT_EQ(Tokens.size(), 20u) << Tokens;
+  EXPECT_TOKEN(Tokens[4], tok::identifier, TT_VerilogDimensionedTypeName);
+  EXPECT_TOKEN(Tokens[7], tok::colon, TT_BitFieldColon);
+  EXPECT_TOKEN(Tokens[13], tok::colon, TT_BitFieldColon);
   // Test case labels and ternary operators.
   Tokens = Annotate("case (x)\n"
 "  x:\n"
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -359,6 +359,12 @@
" input var shortreal in2,\n"
" output tagged_st out);\n"
"endmodule");
+  // There should be a space following the type but not the variable name.
+  verifyFormat("module test\n"
+   "(input wire [7 : 0] a,\n"
+   " input wire b[7 : 0],\n"
+   " input wire [7 : 0] c[7 : 0]);\n"
+   "endmodule");
   // Ports should be grouped by types.
   verifyFormat("module test\n"
"(input [7 : 0] a,\n"
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2161,6 +2161,10 @@
   /// This is a heuristic based on whether \p Tok is an identifier following
   /// something that is likely a type.
   bool isStartOfName(const FormatToken ) {
+// Handled in ExpressionParser for Verilog.
+if (Style.isVerilog())
+  return false;
+
   

[PATCH] D148484: [clang-format] Correctly format goto labels followed by blocks

2023-04-24 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

Is this patch accepted or rejected?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D148484

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


[PATCH] D148484: [clang-format] Correctly format goto labels followed by blocks

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



Comment at: clang/lib/Format/TokenAnnotator.cpp:4525
-const FormatToken *Next = Right.getNextNonComment();
-if (!Next || Next->is(tok::semi))
   return false;

MyDeveloperDay wrote:
> how is the semi case handled or is it not needed
It is not needed anymore.  It was added to handle a semicolon following a goto 
label. Now the type `TT_GotoLabelColon` includes the case.



Comment at: clang/unittests/Format/FormatTest.cpp:3020-3024
   verifyFormat("{\n"
"  some_code();\n"
-   "test_label:;\n"
-   "  int i = 0;\n"
-   "}");

HazardyKnusperkeks wrote:
> Why did you remove that?
It was an accident.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D148484

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


[PATCH] D148484: [clang-format] Correctly format goto labels followed by blocks

2023-04-17 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 514249.
sstwcw added a comment.

- Remove change in line wrapping


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D148484

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
@@ -1621,7 +1621,7 @@
 "x;\n"
 "endcase\n");
   ASSERT_EQ(Tokens.size(), 10u) << Tokens;
-  EXPECT_TOKEN(Tokens[5], tok::colon, TT_GotoLabelColon);
+  EXPECT_TOKEN(Tokens[5], tok::colon, TT_CaseLabelColon);
   Tokens = Annotate("case (x)\n"
 "  x ? x : x:\n"
 "x;\n"
@@ -1629,7 +1629,7 @@
   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);
+  EXPECT_TOKEN(Tokens[9], tok::colon, TT_CaseLabelColon);
   // Non-blocking assignments.
   Tokens = Annotate("a <= b;");
   ASSERT_EQ(Tokens.size(), 5u) << Tokens;
@@ -1724,6 +1724,21 @@
   EXPECT_TOKEN(Tokens[8], tok::l_paren, TT_ConditionLParen);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsLabels) {
+  auto Tokens = annotate("{ x: break; }");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::colon, TT_GotoLabelColon);
+  Tokens = annotate("{ case x: break; }");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::colon, TT_CaseLabelColon);
+  Tokens = annotate("{ x: { break; } }");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::colon, TT_GotoLabelColon);
+  Tokens = annotate("{ case x: { break; } }");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::colon, TT_CaseLabelColon);
+}
+
 } // namespace
 } // namespace format
 } // namespace clang
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2998,6 +2998,17 @@
"test_label:;\n"
"  int i = 0;\n"
"}");
+  verifyFormat("{\n"
+   "  some_code();\n"
+   "test_label: { some_other_code(); }\n"
+   "}");
+  verifyFormat("{\n"
+   "  some_code();\n"
+   "test_label: {\n"
+   "  some_other_code();\n"
+   "  some_other_code();\n"
+   "}\n"
+   "}");
   FormatStyle Style = getLLVMStyle();
   Style.IndentGotoLabels = false;
   verifyFormat("void f() {\n"
@@ -3022,6 +3033,23 @@
"test_label:;\n"
"  int i = 0;\n"
"}");
+  verifyFormat("{\n"
+   "  some_code();\n"
+   "test_label: { some_other_code(); }\n"
+   "}",
+   Style);
+  // The opening brace may either be on the same unwrapped line as the colon or
+  // on a separate one. The formatter should recognize both.
+  Style = getLLVMStyle();
+  Style.BreakBeforeBraces = FormatStyle::BraceBreakingStyle::BS_Allman;
+  verifyFormat("{\n"
+   "  some_code();\n"
+   "test_label:\n"
+   "{\n"
+   "  some_other_code();\n"
+   "}\n"
+   "}",
+   Style);
 }
 
 TEST_F(FormatTest, MultiLineControlStatements) {
@@ -16777,6 +16805,19 @@
"}\n"
"}",
CaseStyle);
+  // Goto labels should not be affected.
+  verifyFormat("switch (x) {\n"
+   "goto_label:\n"
+   "default :\n"
+   "}",
+   CaseStyle);
+  verifyFormat("switch (x) {\n"
+   "goto_label: { break; }\n"
+   "default : {\n"
+   "  break;\n"
+   "}\n"
+   "}",
+   CaseStyle);
 
   FormatStyle NoSpaceStyle = getLLVMStyle();
   EXPECT_EQ(NoSpaceStyle.SpaceBeforeCaseColon, false);
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1493,6 +1493,7 @@
 }
 nextToken();
 if (FormatTok->is(tok::colon)) {
+  FormatTok->setFinalizedType(TT_CaseLabelColon);
   parseLabel();
   return;
 }
@@ -1925,6 +1926,7 @@
 if (!Style.isVerilog() && FormatTok->is(tok::colon) &&
 !Line->MustBeDeclaration) {
   Line->Tokens.begin()->Tok->MustBreakBefore = true;
+  

[PATCH] D148482: [clang-format][NFC] Output tokens on test assert

2023-04-16 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 rGb6301a018d58: [clang-format][NFC] Output tokens on test 
assert (authored by sstwcw).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D148482

Files:
  clang/unittests/Format/TokenAnnotatorTest.cpp


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -841,7 +841,7 @@
 "  [[nodiscard]] constexpr operator T() const { "
 "return number_zero_v; }\n"
 "};");
-  ASSERT_EQ(Tokens.size(), 44u);
+  ASSERT_EQ(Tokens.size(), 44u) << Tokens;
   EXPECT_TOKEN(Tokens[13], tok::kw_requires, TT_RequiresClause);
   EXPECT_TOKEN(Tokens[14], tok::kw_requires, TT_RequiresExpression);
   EXPECT_TOKEN(Tokens[15], tok::l_brace, TT_RequiresExpressionLBrace);
@@ -1605,7 +1605,7 @@
   // Test for block label colons.
   Tokens = Annotate("begin : x\n"
 "end : x");
-  ASSERT_EQ(Tokens.size(), 7u);
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
   EXPECT_TOKEN(Tokens[1], tok::colon, TT_VerilogBlockLabelColon);
   EXPECT_TOKEN(Tokens[4], tok::colon, TT_VerilogBlockLabelColon);
   // Test that the dimension colon is annotated correctly.
@@ -1632,15 +1632,15 @@
   EXPECT_TOKEN(Tokens[9], tok::colon, TT_GotoLabelColon);
   // Non-blocking assignments.
   Tokens = Annotate("a <= b;");
-  ASSERT_EQ(Tokens.size(), 5u);
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
   EXPECT_TOKEN(Tokens[1], tok::lessequal, TT_BinaryOperator);
   EXPECT_TOKEN_PRECEDENCE(Tokens[1], prec::Assignment);
   Tokens = Annotate("if (a <= b) break;");
-  ASSERT_EQ(Tokens.size(), 9u);
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
   EXPECT_TOKEN(Tokens[3], tok::lessequal, TT_BinaryOperator);
   EXPECT_TOKEN_PRECEDENCE(Tokens[3], prec::Relational);
   Tokens = Annotate("a <= b <= a;");
-  ASSERT_EQ(Tokens.size(), 7u);
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
   EXPECT_TOKEN(Tokens[1], tok::lessequal, TT_BinaryOperator);
   EXPECT_TOKEN_PRECEDENCE(Tokens[1], prec::Assignment);
   EXPECT_TOKEN(Tokens[3], tok::lessequal, TT_BinaryOperator);
@@ -1648,12 +1648,12 @@
 
   // Port lists in module instantiation.
   Tokens = Annotate("module_x instance_1(port_1), instance_2(port_2);");
-  ASSERT_EQ(Tokens.size(), 12u);
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
   EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_VerilogInstancePortLParen);
   EXPECT_TOKEN(Tokens[7], tok::l_paren, TT_VerilogInstancePortLParen);
   Tokens = Annotate("module_x #(parameter) instance_1(port_1), "
 "instance_2(port_2);");
-  ASSERT_EQ(Tokens.size(), 16u);
+  ASSERT_EQ(Tokens.size(), 16u) << Tokens;
   EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_VerilogInstancePortLParen);
   EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_VerilogInstancePortLParen);
   EXPECT_TOKEN(Tokens[11], tok::l_paren, TT_VerilogInstancePortLParen);


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -841,7 +841,7 @@
 "  [[nodiscard]] constexpr operator T() const { "
 "return number_zero_v; }\n"
 "};");
-  ASSERT_EQ(Tokens.size(), 44u);
+  ASSERT_EQ(Tokens.size(), 44u) << Tokens;
   EXPECT_TOKEN(Tokens[13], tok::kw_requires, TT_RequiresClause);
   EXPECT_TOKEN(Tokens[14], tok::kw_requires, TT_RequiresExpression);
   EXPECT_TOKEN(Tokens[15], tok::l_brace, TT_RequiresExpressionLBrace);
@@ -1605,7 +1605,7 @@
   // Test for block label colons.
   Tokens = Annotate("begin : x\n"
 "end : x");
-  ASSERT_EQ(Tokens.size(), 7u);
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
   EXPECT_TOKEN(Tokens[1], tok::colon, TT_VerilogBlockLabelColon);
   EXPECT_TOKEN(Tokens[4], tok::colon, TT_VerilogBlockLabelColon);
   // Test that the dimension colon is annotated correctly.
@@ -1632,15 +1632,15 @@
   EXPECT_TOKEN(Tokens[9], tok::colon, TT_GotoLabelColon);
   // Non-blocking assignments.
   Tokens = Annotate("a <= b;");
-  ASSERT_EQ(Tokens.size(), 5u);
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
   EXPECT_TOKEN(Tokens[1], tok::lessequal, TT_BinaryOperator);
   EXPECT_TOKEN_PRECEDENCE(Tokens[1], prec::Assignment);
   Tokens = Annotate("if (a <= b) break;");
-  ASSERT_EQ(Tokens.size(), 9u);
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
   EXPECT_TOKEN(Tokens[3], tok::lessequal, TT_BinaryOperator);
   EXPECT_TOKEN_PRECEDENCE(Tokens[3], prec::Relational);
   Tokens = Annotate("a <= b <= a;");
-  ASSERT_EQ(Tokens.size(), 7u);
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
   EXPECT_TOKEN(Tokens[1], tok::lessequal, TT_BinaryOperator);
   

[PATCH] D148484: [clang-format] Correctly format goto labels followed by blocks

2023-04-16 Thread sstwcw via Phabricator via cfe-commits
sstwcw added inline comments.



Comment at: clang/lib/Format/UnwrappedLineFormatter.cpp:714
 // are in a control flow statements as well as several style flags.
-if (Line.First->is(tok::kw_case) ||
+if (Line.First->is(tok::kw_case) || Line.Last->is(TT_GotoLabelColon) ||
+Line.Last->endsSequence(tok::l_brace, TT_GotoLabelColon) ||

Should I make this change?

Without it:

```
label: { break; }
```

With it:

```
label: {
  break;
}
```

Without the entire patch:

```
label : { break; }
```


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D148484

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


[PATCH] D148484: [clang-format] Correctly format goto labels followed by blocks

2023-04-16 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
sstwcw added reviewers: HazardyKnusperkeks, MyDeveloperDay, owenpan, rymiel.
Herald added projects: All, clang, clang-format.
Herald added a subscriber: cfe-commits.
sstwcw requested review of this revision.

There doesn't seem to be an issue on GitHub.  But previously, a space
would be inserted before the goto colon in the code below.

  switch (x) {
  case 0:
  goto_0: {
action();
break;
  }
  }

Previously, the colon following a goto label would be annotated as
`TT_InheritanceColon`.  A goto label followed by an opening brace
wasn't recognized.  It is easy to add another line to have
`spaceRequiredBefore` function recognize the case, but I believed it
is more proper to avoid doing the same thing in `UnwrappedLineParser`
and `TokenAnnotator`.  So now the label colons would be labeled in
`UnwrappedLineParser`, and `spaceRequiredBefore` would rely on that.

Previously we had the type `TT_GotoLabelColon` intended for both goto
labels and case labels.  But since handling of goto labels and case
labels differ somewhat, I split it into separate types for goto and
case labels.

This patch doesn't change the behavior for case labels.  I added the
lines annotating case labels because they would previously be
mistakenly annotated as `TT_InheritanceColon` just like goto labels.
And since I added the annotations, the checks for the `case` and
`default` keywords in `spaceRequiredBefore` are not necessary anymore.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D148484

Files:
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/lib/Format/UnwrappedLineFormatter.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
@@ -1621,7 +1621,7 @@
 "x;\n"
 "endcase\n");
   ASSERT_EQ(Tokens.size(), 10u) << Tokens;
-  EXPECT_TOKEN(Tokens[5], tok::colon, TT_GotoLabelColon);
+  EXPECT_TOKEN(Tokens[5], tok::colon, TT_CaseLabelColon);
   Tokens = Annotate("case (x)\n"
 "  x ? x : x:\n"
 "x;\n"
@@ -1629,7 +1629,7 @@
   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);
+  EXPECT_TOKEN(Tokens[9], tok::colon, TT_CaseLabelColon);
   // Non-blocking assignments.
   Tokens = Annotate("a <= b;");
   ASSERT_EQ(Tokens.size(), 5u);
@@ -1708,6 +1708,7 @@
   EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_FunctionLBrace);
 }
 
+
 TEST_F(TokenAnnotatorTest, UnderstandsConditionParens) {
   auto Tokens = annotate("if (x) {}");
   ASSERT_EQ(Tokens.size(), 7u) << Tokens;
@@ -1724,6 +1725,21 @@
   EXPECT_TOKEN(Tokens[8], tok::l_paren, TT_ConditionLParen);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsLabels) {
+  auto Tokens = annotate("{ x: break; }");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::colon, TT_GotoLabelColon);
+  Tokens = annotate("{ case x: break; }");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::colon, TT_CaseLabelColon);
+  Tokens = annotate("{ x: { break; } }");
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::colon, TT_GotoLabelColon);
+  Tokens = annotate("{ case x: { break; } }");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::colon, TT_CaseLabelColon);
+}
+
 } // namespace
 } // namespace format
 } // namespace clang
Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2998,6 +2998,12 @@
"test_label:;\n"
"  int i = 0;\n"
"}");
+  verifyFormat("{\n"
+   "  some_code();\n"
+   "test_label: {\n"
+   "  some_other_code();\n"
+   "}\n"
+   "}");
   FormatStyle Style = getLLVMStyle();
   Style.IndentGotoLabels = false;
   verifyFormat("void f() {\n"
@@ -3019,9 +3025,23 @@
Style);
   verifyFormat("{\n"
"  some_code();\n"
-   "test_label:;\n"
-   "  int i = 0;\n"
-   "}");
+   "test_label: {\n"
+   "  some_other_code();\n"
+   "}\n"
+   "}",
+   Style);
+  // The opening brace may either be on the same unwrapped line as the colon or
+  // on a separate one. The formatter should recognize both.
+  Style = getLLVMStyle();
+  Style.BreakBeforeBraces = FormatStyle::BraceBreakingStyle::BS_Allman;
+  verifyFormat("{\n"
+ 

[PATCH] D148482: [clang-format][NFC] Output tokens on test assert

2023-04-16 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
sstwcw added reviewers: HazardyKnusperkeks, MyDeveloperDay, owenpan, rymiel.
Herald added projects: All, clang, clang-format.
Herald added a subscriber: cfe-commits.
sstwcw requested review of this revision.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D148482

Files:
  clang/unittests/Format/TokenAnnotatorTest.cpp


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -841,7 +841,7 @@
 "  [[nodiscard]] constexpr operator T() const { "
 "return number_zero_v; }\n"
 "};");
-  ASSERT_EQ(Tokens.size(), 44u);
+  ASSERT_EQ(Tokens.size(), 44u) << Tokens;
   EXPECT_TOKEN(Tokens[13], tok::kw_requires, TT_RequiresClause);
   EXPECT_TOKEN(Tokens[14], tok::kw_requires, TT_RequiresExpression);
   EXPECT_TOKEN(Tokens[15], tok::l_brace, TT_RequiresExpressionLBrace);
@@ -1605,7 +1605,7 @@
   // Test for block label colons.
   Tokens = Annotate("begin : x\n"
 "end : x");
-  ASSERT_EQ(Tokens.size(), 7u);
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
   EXPECT_TOKEN(Tokens[1], tok::colon, TT_VerilogBlockLabelColon);
   EXPECT_TOKEN(Tokens[4], tok::colon, TT_VerilogBlockLabelColon);
   // Test that the dimension colon is annotated correctly.
@@ -1632,15 +1632,15 @@
   EXPECT_TOKEN(Tokens[9], tok::colon, TT_GotoLabelColon);
   // Non-blocking assignments.
   Tokens = Annotate("a <= b;");
-  ASSERT_EQ(Tokens.size(), 5u);
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
   EXPECT_TOKEN(Tokens[1], tok::lessequal, TT_BinaryOperator);
   EXPECT_TOKEN_PRECEDENCE(Tokens[1], prec::Assignment);
   Tokens = Annotate("if (a <= b) break;");
-  ASSERT_EQ(Tokens.size(), 9u);
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
   EXPECT_TOKEN(Tokens[3], tok::lessequal, TT_BinaryOperator);
   EXPECT_TOKEN_PRECEDENCE(Tokens[3], prec::Relational);
   Tokens = Annotate("a <= b <= a;");
-  ASSERT_EQ(Tokens.size(), 7u);
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
   EXPECT_TOKEN(Tokens[1], tok::lessequal, TT_BinaryOperator);
   EXPECT_TOKEN_PRECEDENCE(Tokens[1], prec::Assignment);
   EXPECT_TOKEN(Tokens[3], tok::lessequal, TT_BinaryOperator);
@@ -1648,12 +1648,12 @@
 
   // Port lists in module instantiation.
   Tokens = Annotate("module_x instance_1(port_1), instance_2(port_2);");
-  ASSERT_EQ(Tokens.size(), 12u);
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
   EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_VerilogInstancePortLParen);
   EXPECT_TOKEN(Tokens[7], tok::l_paren, TT_VerilogInstancePortLParen);
   Tokens = Annotate("module_x #(parameter) instance_1(port_1), "
 "instance_2(port_2);");
-  ASSERT_EQ(Tokens.size(), 16u);
+  ASSERT_EQ(Tokens.size(), 16u) << Tokens;
   EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_VerilogInstancePortLParen);
   EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_VerilogInstancePortLParen);
   EXPECT_TOKEN(Tokens[11], tok::l_paren, TT_VerilogInstancePortLParen);


Index: clang/unittests/Format/TokenAnnotatorTest.cpp
===
--- clang/unittests/Format/TokenAnnotatorTest.cpp
+++ clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -841,7 +841,7 @@
 "  [[nodiscard]] constexpr operator T() const { "
 "return number_zero_v; }\n"
 "};");
-  ASSERT_EQ(Tokens.size(), 44u);
+  ASSERT_EQ(Tokens.size(), 44u) << Tokens;
   EXPECT_TOKEN(Tokens[13], tok::kw_requires, TT_RequiresClause);
   EXPECT_TOKEN(Tokens[14], tok::kw_requires, TT_RequiresExpression);
   EXPECT_TOKEN(Tokens[15], tok::l_brace, TT_RequiresExpressionLBrace);
@@ -1605,7 +1605,7 @@
   // Test for block label colons.
   Tokens = Annotate("begin : x\n"
 "end : x");
-  ASSERT_EQ(Tokens.size(), 7u);
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
   EXPECT_TOKEN(Tokens[1], tok::colon, TT_VerilogBlockLabelColon);
   EXPECT_TOKEN(Tokens[4], tok::colon, TT_VerilogBlockLabelColon);
   // Test that the dimension colon is annotated correctly.
@@ -1632,15 +1632,15 @@
   EXPECT_TOKEN(Tokens[9], tok::colon, TT_GotoLabelColon);
   // Non-blocking assignments.
   Tokens = Annotate("a <= b;");
-  ASSERT_EQ(Tokens.size(), 5u);
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
   EXPECT_TOKEN(Tokens[1], tok::lessequal, TT_BinaryOperator);
   EXPECT_TOKEN_PRECEDENCE(Tokens[1], prec::Assignment);
   Tokens = Annotate("if (a <= b) break;");
-  ASSERT_EQ(Tokens.size(), 9u);
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
   EXPECT_TOKEN(Tokens[3], tok::lessequal, TT_BinaryOperator);
   EXPECT_TOKEN_PRECEDENCE(Tokens[3], prec::Relational);
   Tokens = Annotate("a <= b <= a;");
-  ASSERT_EQ(Tokens.size(), 7u);
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
   EXPECT_TOKEN(Tokens[1], tok::lessequal, TT_BinaryOperator);
   EXPECT_TOKEN_PRECEDENCE(Tokens[1], prec::Assignment);
   

[PATCH] D147895: [clang-format] Handle Verilog assertions and loops

2023-04-16 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 rG0571ba8d1b4d: [clang-format] Handle Verilog assertions and 
loops (authored by sstwcw).

Changed prior to commit:
  https://reviews.llvm.org/D147895?vs=512044=514053#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D147895

Files:
  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
@@ -1657,6 +1657,26 @@
   EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_VerilogInstancePortLParen);
   EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_VerilogInstancePortLParen);
   EXPECT_TOKEN(Tokens[11], tok::l_paren, TT_VerilogInstancePortLParen);
+
+  // Condition parentheses.
+  Tokens = Annotate("assert (x);");
+  ASSERT_EQ(Tokens.size(), 6u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+  Tokens = Annotate("assert #0 (x);");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_ConditionLParen);
+  Tokens = Annotate("assert final (x);");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_ConditionLParen);
+  Tokens = Annotate("foreach (x[x]) continue;");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+  Tokens = Annotate("repeat (x[x]) continue;");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+  Tokens = Annotate("case (x) endcase;");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandConstructors) {
@@ -1688,6 +1708,22 @@
   EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_FunctionLBrace);
 }
 
+TEST_F(TokenAnnotatorTest, UnderstandsConditionParens) {
+  auto Tokens = annotate("if (x) {}");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+  Tokens = annotate("if constexpr (x) {}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_ConditionLParen);
+  Tokens = annotate("if CONSTEXPR (x) {}");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_ConditionLParen);
+  Tokens = annotate("if (x) {} else if (x) {}");
+  ASSERT_EQ(Tokens.size(), 14u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+  EXPECT_TOKEN(Tokens[8], tok::l_paren, TT_ConditionLParen);
+}
+
 } // namespace
 } // namespace format
 } // namespace clang
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -671,6 +671,107 @@
"  x = x;");
   verifyFormat("(* x, x = \"x\" *) if (x)\n"
"  x = x;");
+
+  // Assert are treated similar to if.  But the else parts should not be
+  // chained.
+  verifyFormat("assert (x);");
+  verifyFormat("assert (x)\n"
+   "  $info();");
+  verifyFormat("assert (x)\n"
+   "  $info();\n"
+   "else\n"
+   "  $error();");
+  verifyFormat("assert (x)\n"
+   "else\n"
+   "  $error();");
+  verifyFormat("assert (x)\n"
+   "else begin\n"
+   "end");
+  verifyFormat("assert (x)\n"
+   "else\n"
+   "  if (x)\n"
+   "$error();");
+  verifyFormat("assert (x)\n"
+   "  $info();\n"
+   "else\n"
+   "  if (x)\n"
+   "$error();");
+  verifyFormat("assert (x)\n"
+   "  $info();\n"
+   "else\n"
+   "  if (x)\n"
+   "$error();\n"
+   "  else\n"
+   "$error();");
+  verifyFormat("assert (x)\n"
+   "  $info();\n"
+   "else\n"
+   "  if (x)\n"
+   "$error();\n"
+   "  else if (x)\n"
+   "$error();\n"
+   "  else\n"
+   "$error();");
+  // The body is optional for asserts.  The next line should not be indented if
+  // the statement already ended with a semicolon.
+  verifyFormat("assert (x);\n"
+   "x = x;");
+  verifyFormat("if (x)\n"
+   "  assert (x);\n"
+   "else if (x) begin\n"
+   "end else begin\n"
+   "end");
+  verifyFormat("if (x)\n"
+   "  assert (x);\n"

[PATCH] D147895: [clang-format] Handle Verilog assertions and loops

2023-04-11 Thread sstwcw via Phabricator via cfe-commits
sstwcw added inline comments.



Comment at: clang/unittests/Format/TokenAnnotatorTest.cpp:844
 "};");
-  ASSERT_EQ(Tokens.size(), 44u);
+  ASSERT_EQ(Tokens.size(), 44u) << Tokens;
   EXPECT_TOKEN(Tokens[13], tok::kw_requires, TT_RequiresClause);

HazardyKnusperkeks wrote:
> Unrelated, I'd prefer it as a single commit.
How should I name the separate commit?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D147895

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


[PATCH] D93240: [clang-format] Add SpaceBeforeCaseColon option

2023-04-09 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.
Herald added a project: All.
Herald added reviewers: rymiel, owenpan.

A goto label isn't affected by this option.  Is it intentional?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D93240

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


[PATCH] D147895: [clang-format] Handle Verilog assertions and loops

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

Assert statements in Verilog can optionally have an else part.  We
handle them like for `if` statements, except that an `if` statement in
the else part of an `assert` statement doesn't get merged with the
`else` keyword.  Like this:

  assert (x)
$info();
  else
if (y)
  $info();
else if (z)
  $info();
else
  $info();

`foreach` and `repeat` are now handled like for or while loops.

We used the type `TT_ConditionLParen` to mark the condition part so
they are handled in the same way as the condition part of an `if`
statement.  When the code being formatted is not in Verilog, it is
only set for `if` statements, not loops.  It's because loop conditions
are currently handled slightly differently, and existing behavior is
not supposed to change.  We formatted all files ending in `.cpp` and
`.h` in the repository with and without this change.  It showed that
setting the type for `if` statements doesn't change existing behavior.

And we noticed that we forgot to make the program print the list of
tokens when the number is not correct in `TokenAnnotatorTest`.  It's
fixed now.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D147895

Files:
  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
@@ -841,7 +841,7 @@
 "  [[nodiscard]] constexpr operator T() const { "
 "return number_zero_v; }\n"
 "};");
-  ASSERT_EQ(Tokens.size(), 44u);
+  ASSERT_EQ(Tokens.size(), 44u) << Tokens;
   EXPECT_TOKEN(Tokens[13], tok::kw_requires, TT_RequiresClause);
   EXPECT_TOKEN(Tokens[14], tok::kw_requires, TT_RequiresExpression);
   EXPECT_TOKEN(Tokens[15], tok::l_brace, TT_RequiresExpressionLBrace);
@@ -1605,7 +1605,7 @@
   // Test for block label colons.
   Tokens = Annotate("begin : x\n"
 "end : x");
-  ASSERT_EQ(Tokens.size(), 7u);
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
   EXPECT_TOKEN(Tokens[1], tok::colon, TT_VerilogBlockLabelColon);
   EXPECT_TOKEN(Tokens[4], tok::colon, TT_VerilogBlockLabelColon);
   // Test that the dimension colon is annotated correctly.
@@ -1632,15 +1632,15 @@
   EXPECT_TOKEN(Tokens[9], tok::colon, TT_GotoLabelColon);
   // Non-blocking assignments.
   Tokens = Annotate("a <= b;");
-  ASSERT_EQ(Tokens.size(), 5u);
+  ASSERT_EQ(Tokens.size(), 5u) << Tokens;
   EXPECT_TOKEN(Tokens[1], tok::lessequal, TT_BinaryOperator);
   EXPECT_TOKEN_PRECEDENCE(Tokens[1], prec::Assignment);
   Tokens = Annotate("if (a <= b) break;");
-  ASSERT_EQ(Tokens.size(), 9u);
+  ASSERT_EQ(Tokens.size(), 9u) << Tokens;
   EXPECT_TOKEN(Tokens[3], tok::lessequal, TT_BinaryOperator);
   EXPECT_TOKEN_PRECEDENCE(Tokens[3], prec::Relational);
   Tokens = Annotate("a <= b <= a;");
-  ASSERT_EQ(Tokens.size(), 7u);
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
   EXPECT_TOKEN(Tokens[1], tok::lessequal, TT_BinaryOperator);
   EXPECT_TOKEN_PRECEDENCE(Tokens[1], prec::Assignment);
   EXPECT_TOKEN(Tokens[3], tok::lessequal, TT_BinaryOperator);
@@ -1648,15 +1648,35 @@
 
   // Port lists in module instantiation.
   Tokens = Annotate("module_x instance_1(port_1), instance_2(port_2);");
-  ASSERT_EQ(Tokens.size(), 12u);
+  ASSERT_EQ(Tokens.size(), 12u) << Tokens;
   EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_VerilogInstancePortLParen);
   EXPECT_TOKEN(Tokens[7], tok::l_paren, TT_VerilogInstancePortLParen);
   Tokens = Annotate("module_x #(parameter) instance_1(port_1), "
 "instance_2(port_2);");
-  ASSERT_EQ(Tokens.size(), 16u);
+  ASSERT_EQ(Tokens.size(), 16u) << Tokens;
   EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_VerilogInstancePortLParen);
   EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_VerilogInstancePortLParen);
   EXPECT_TOKEN(Tokens[11], tok::l_paren, TT_VerilogInstancePortLParen);
+
+  // Condition parentheses.
+  Tokens = Annotate("assert (x);");
+  ASSERT_EQ(Tokens.size(), 6u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+  Tokens = Annotate("assert #0 (x);");
+  ASSERT_EQ(Tokens.size(), 8u) << Tokens;
+  EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_ConditionLParen);
+  Tokens = Annotate("assert final (x);");
+  ASSERT_EQ(Tokens.size(), 7u) << Tokens;
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_ConditionLParen);
+  Tokens = Annotate("foreach (x[x]) continue;");
+  ASSERT_EQ(Tokens.size(), 10u) << Tokens;
+  EXPECT_TOKEN(Tokens[1], tok::l_paren, TT_ConditionLParen);
+  

[PATCH] D146101: [clang-format] Add BracedInitializerIndentWidth option.

2023-04-07 Thread sstwcw via Phabricator via cfe-commits
sstwcw added inline comments.



Comment at: clang/docs/tools/dump_format_style.py:72
 
-  subtype, napplied = re.subn(r'^std::vector<(.*)>$', r'\1', typestr)
-  if napplied == 1:
-return 'List of ' + pluralize(to_yaml_type(subtype))
+  match = re.match(r'std::vector<(.*)>$', typestr)
+  if match:

rymiel wrote:
> jp4a50 wrote:
> > I changed this from `subn` to `match` here since it's just a simpler way of 
> > expressing the same thing.
> (Just FYI, those pythons sources are pretty ancient and untouched, I planned 
> on refactoring the whole thing using more modern, idiomatic Python but then 
> concluded that it's not really necessary)
Is curdeius the one who knows about the Python scripts and the YAML parser?  
Did he move on to meaningful things?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146101

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


[PATCH] D147422: [clang-format] NFC Document the other space before colon option

2023-04-07 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 rG8385ee05e59d: [clang-format] NFC Document the other space 
before colon option (authored by sstwcw).

Changed prior to commit:
  https://reviews.llvm.org/D147422?vs=510391=511681#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D147422

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h


Index: clang/include/clang/Format/Format.h
===
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -3749,7 +3749,8 @@
   /// \version 7
   bool SpaceBeforeInheritanceColon;
 
-  /// If ``true``, a space will be add before a JSON colon.
+  /// If ``true``, a space will be added before a JSON colon. For other
+  /// languages, e.g. JavaScript, use ``SpacesInContainerLiterals`` instead.
   /// \code
   ///true:  false:
   ///{  {
@@ -4032,8 +4033,9 @@
   /// \version 10
   bool SpacesInConditionalStatement;
 
-  /// If ``true``, spaces are inserted inside container literals (e.g.
-  /// ObjC and Javascript array and dict literals).
+  /// If ``true``, spaces are inserted inside container literals (e.g.  ObjC 
and
+  /// Javascript array and dict literals). For JSON, use
+  /// ``SpaceBeforeJsonColon`` instead.
   /// \code{.js}
   ///true:  false:
   ///var arr = [ 1, 2, 3 ]; vs. var arr = [1, 2, 3];
Index: clang/docs/ClangFormatStyleOptions.rst
===
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -4782,7 +4782,8 @@
 .. _SpaceBeforeJsonColon:
 
 **SpaceBeforeJsonColon** (``Boolean``) :versionbadge:`clang-format 17` :ref:`¶ 
`
-  If ``true``, a space will be add before a JSON colon.
+  If ``true``, a space will be added before a JSON colon. For other
+  languages, e.g. JavaScript, use ``SpacesInContainerLiterals`` instead.
 
   .. code-block:: c++
 
@@ -5100,8 +5101,9 @@
 .. _SpacesInContainerLiterals:
 
 **SpacesInContainerLiterals** (``Boolean``) :versionbadge:`clang-format 3.7` 
:ref:`¶ `
-  If ``true``, spaces are inserted inside container literals (e.g.
-  ObjC and Javascript array and dict literals).
+  If ``true``, spaces are inserted inside container literals (e.g.  ObjC and
+  Javascript array and dict literals). For JSON, use
+  ``SpaceBeforeJsonColon`` instead.
 
   .. code-block:: js
 


Index: clang/include/clang/Format/Format.h
===
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -3749,7 +3749,8 @@
   /// \version 7
   bool SpaceBeforeInheritanceColon;
 
-  /// If ``true``, a space will be add before a JSON colon.
+  /// If ``true``, a space will be added before a JSON colon. For other
+  /// languages, e.g. JavaScript, use ``SpacesInContainerLiterals`` instead.
   /// \code
   ///true:  false:
   ///{  {
@@ -4032,8 +4033,9 @@
   /// \version 10
   bool SpacesInConditionalStatement;
 
-  /// If ``true``, spaces are inserted inside container literals (e.g.
-  /// ObjC and Javascript array and dict literals).
+  /// If ``true``, spaces are inserted inside container literals (e.g.  ObjC and
+  /// Javascript array and dict literals). For JSON, use
+  /// ``SpaceBeforeJsonColon`` instead.
   /// \code{.js}
   ///true:  false:
   ///var arr = [ 1, 2, 3 ]; vs. var arr = [1, 2, 3];
Index: clang/docs/ClangFormatStyleOptions.rst
===
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -4782,7 +4782,8 @@
 .. _SpaceBeforeJsonColon:
 
 **SpaceBeforeJsonColon** (``Boolean``) :versionbadge:`clang-format 17` :ref:`¶ `
-  If ``true``, a space will be add before a JSON colon.
+  If ``true``, a space will be added before a JSON colon. For other
+  languages, e.g. JavaScript, use ``SpacesInContainerLiterals`` instead.
 
   .. code-block:: c++
 
@@ -5100,8 +5101,9 @@
 .. _SpacesInContainerLiterals:
 
 **SpacesInContainerLiterals** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ `
-  If ``true``, spaces are inserted inside container literals (e.g.
-  ObjC and Javascript array and dict literals).
+  If ``true``, spaces are inserted inside container literals (e.g.  ObjC and
+  Javascript array and dict literals). For JSON, use
+  ``SpaceBeforeJsonColon`` instead.
 
   .. code-block:: js
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org

[PATCH] D147327: [clang-format] Add option for having one port per line in Verilog

2023-04-04 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 rG74cc4389f37d: [clang-format] Add option for having one port 
per line in Verilog (authored by sstwcw).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D147327

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/unittests/Format/ConfigParseTest.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
@@ -1645,6 +1645,18 @@
   EXPECT_TOKEN_PRECEDENCE(Tokens[1], prec::Assignment);
   EXPECT_TOKEN(Tokens[3], tok::lessequal, TT_BinaryOperator);
   EXPECT_TOKEN_PRECEDENCE(Tokens[3], prec::Relational);
+
+  // Port lists in module instantiation.
+  Tokens = Annotate("module_x instance_1(port_1), instance_2(port_2);");
+  ASSERT_EQ(Tokens.size(), 12u);
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_VerilogInstancePortLParen);
+  EXPECT_TOKEN(Tokens[7], tok::l_paren, TT_VerilogInstancePortLParen);
+  Tokens = Annotate("module_x #(parameter) instance_1(port_1), "
+"instance_2(port_2);");
+  ASSERT_EQ(Tokens.size(), 16u);
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_VerilogInstancePortLParen);
+  EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_VerilogInstancePortLParen);
+  EXPECT_TOKEN(Tokens[11], tok::l_paren, TT_VerilogInstancePortLParen);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandConstructors) {
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -673,6 +673,77 @@
"  x = x;");
 }
 
+TEST_F(FormatTestVerilog, Instantiation) {
+  // Without ports.
+  verifyFormat("ffnand ff1;");
+  // With named ports.
+  verifyFormat("ffnand ff1(.qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2));");
+  // With wildcard.
+  verifyFormat("ffnand ff1(.qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2),\n"
+   "   .*);");
+  verifyFormat("ffnand ff1(.*,\n"
+   "   .qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2));");
+  // With unconnected ports.
+  verifyFormat("ffnand ff1(.q(),\n"
+   "   .qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2));");
+  verifyFormat("ffnand ff1(.q(),\n"
+   "   .qbar(),\n"
+   "   .clear(),\n"
+   "   .preset());");
+  verifyFormat("ffnand ff1(,\n"
+   "   .qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2));");
+  // With positional ports.
+  verifyFormat("ffnand ff1(out1,\n"
+   "   in1,\n"
+   "   in2);");
+  verifyFormat("ffnand ff1(,\n"
+   "   out1,\n"
+   "   in1,\n"
+   "   in2);");
+  // Multiple instantiations.
+  verifyFormat("ffnand ff1(.q(),\n"
+   "   .qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2)),\n"
+   "   ff1(.q(),\n"
+   "   .qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2));");
+  verifyFormat("ffnand //\n"
+   "ff1(.q(),\n"
+   ".qbar(out1),\n"
+   ".clear(in1),\n"
+   ".preset(in2)),\n"
+   "ff1(.q(),\n"
+   ".qbar(out1),\n"
+   ".clear(in1),\n"
+   ".preset(in2));");
+  // With breaking between instance ports disabled.
+  auto Style = getDefaultStyle();
+  Style.VerilogBreakBetweenInstancePorts = false;
+  verifyFormat("ffnand ff1;", Style);
+  verifyFormat("ffnand ff1(.qbar(out1), .clear(in1), .preset(in2), .*);",
+   Style);
+  verifyFormat("ffnand ff1(out1, in1, in2);", Style);
+  verifyFormat("ffnand ff1(.q(), .qbar(out1), .clear(in1), .preset(in2)),\n"
+   "   ff1(.q(), .qbar(out1), .clear(in1), .preset(in2));",
+   Style);
+  verifyFormat("ffnand //\n"
+   "ff1(.q(), .qbar(out1), .clear(in1), .preset(in2)),\n"
+   "ff1(.q(), .qbar(out1), .clear(in1), .preset(in2));",
+   Style);
+}
+
 

[PATCH] D147422: [clang-format] NFC Document the other space before colon option

2023-04-03 Thread sstwcw via Phabricator via cfe-commits
sstwcw added a comment.

In D147422#4240024 , @MyDeveloperDay 
wrote:

> In D147422#4240021 , @owenpan wrote:
>
>> Should we extend `SpacesInContainerLiterals` so that it controls JSON colons 
>> too? If yes, then we don't need `SpaceBeforeJsonColon`. Otherwise, IMO we 
>> should leave the doc alone.
>
> My concern for `SpacesInContainerLiterals` is that it impacts arrays contents 
> too '[ 1, 2, 3 ]'.

It looks like a line break gets inserted in arrays.  Does that mean the option 
doesn't affect arrays?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D147422

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


[PATCH] D147422: [clang-format] NFC Document the other space before colon option

2023-04-02 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
sstwcw added reviewers: HazardyKnusperkeks, MyDeveloperDay, owenpan, rymiel.
Herald added subscribers: cfe-commits, JDevlieghere.
Herald added projects: All, clang, clang-format.
sstwcw requested review of this revision.
Herald added a comment.

NOTE: Clang-Format Team Automated Review Comment

It looks like your clang-format review does not contain any unit tests, please 
try to ensure all code changes have a unit test (unless this is an `NFC` or 
refactoring, adding documentation etc..)

Add you unit tests in `clang/unittests/Format` and build `ninja FormatTests` we 
recommend using the `verifyFormat(xxx)` format of unit tests rather than 
`EXPECT_EQ` as this will ensure you change is tolerant to random whitespace 
changes (see FormatTest.cpp as an example)

For situations where your change is altering the TokenAnnotator.cpp which can 
happen if you are trying to improve the annotation phase to ensure we are 
correctly identifying the type of a token, please add a token annotator test in 
`TokenAnnotatorTest.cpp`


There are two options that do much the same thing, but for different
languages.  With the addition to the doc, the user is less likely to
configure the wrong option and get frustrated that it doesn't work.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D147422

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h


Index: clang/include/clang/Format/Format.h
===
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -3748,7 +3748,8 @@
   /// \version 7
   bool SpaceBeforeInheritanceColon;
 
-  /// If ``true``, a space will be add before a JSON colon.
+  /// If ``true``, a space will be add before a JSON colon. For other 
languages,
+  /// use ``SpacesInContainerLiterals`` instead.
   /// \code
   ///true:  false:
   ///{  {
@@ -4031,8 +4032,9 @@
   /// \version 10
   bool SpacesInConditionalStatement;
 
-  /// If ``true``, spaces are inserted inside container literals (e.g.
-  /// ObjC and Javascript array and dict literals).
+  /// If ``true``, spaces are inserted inside container literals (e.g.  ObjC 
and
+  /// Javascript array and dict literals). For JSON, use
+  /// ``SpaceBeforeJsonColon`` instead.
   /// \code{.js}
   ///true:  false:
   ///var arr = [ 1, 2, 3 ]; vs. var arr = [1, 2, 3];
Index: clang/docs/ClangFormatStyleOptions.rst
===
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -4781,7 +4781,8 @@
 .. _SpaceBeforeJsonColon:
 
 **SpaceBeforeJsonColon** (``Boolean``) :versionbadge:`clang-format 17` :ref:`¶ 
`
-  If ``true``, a space will be add before a JSON colon.
+  If ``true``, a space will be add before a JSON colon. For other languages,
+  use ``SpacesInContainerLiterals`` instead.
 
   .. code-block:: c++
 
@@ -5099,8 +5100,9 @@
 .. _SpacesInContainerLiterals:
 
 **SpacesInContainerLiterals** (``Boolean``) :versionbadge:`clang-format 3.7` 
:ref:`¶ `
-  If ``true``, spaces are inserted inside container literals (e.g.
-  ObjC and Javascript array and dict literals).
+  If ``true``, spaces are inserted inside container literals (e.g.  ObjC and
+  Javascript array and dict literals). For JSON, use
+  ``SpaceBeforeJsonColon`` instead.
 
   .. code-block:: js
 


Index: clang/include/clang/Format/Format.h
===
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -3748,7 +3748,8 @@
   /// \version 7
   bool SpaceBeforeInheritanceColon;
 
-  /// If ``true``, a space will be add before a JSON colon.
+  /// If ``true``, a space will be add before a JSON colon. For other languages,
+  /// use ``SpacesInContainerLiterals`` instead.
   /// \code
   ///true:  false:
   ///{  {
@@ -4031,8 +4032,9 @@
   /// \version 10
   bool SpacesInConditionalStatement;
 
-  /// If ``true``, spaces are inserted inside container literals (e.g.
-  /// ObjC and Javascript array and dict literals).
+  /// If ``true``, spaces are inserted inside container literals (e.g.  ObjC and
+  /// Javascript array and dict literals). For JSON, use
+  /// ``SpaceBeforeJsonColon`` instead.
   /// \code{.js}
   ///true:  false:
   ///var arr = [ 1, 2, 3 ]; vs. var arr = [1, 2, 3];
Index: clang/docs/ClangFormatStyleOptions.rst
===
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -4781,7 +4781,8 @@
 .. _SpaceBeforeJsonColon:
 
 **SpaceBeforeJsonColon** (``Boolean``) :versionbadge:`clang-format 17` :ref:`¶ `
- 

[PATCH] D147327: [clang-format] Add option for having one port per line in Verilog

2023-04-02 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 510385.
sstwcw added a comment.

- Use lambda


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D147327

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/unittests/Format/ConfigParseTest.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
@@ -1579,6 +1579,18 @@
   EXPECT_TOKEN_PRECEDENCE(Tokens[1], prec::Assignment);
   EXPECT_TOKEN(Tokens[3], tok::lessequal, TT_BinaryOperator);
   EXPECT_TOKEN_PRECEDENCE(Tokens[3], prec::Relational);
+
+  // Port lists in module instantiation.
+  Tokens = Annotate("module_x instance_1(port_1), instance_2(port_2);");
+  ASSERT_EQ(Tokens.size(), 12u);
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_VerilogInstancePortLParen);
+  EXPECT_TOKEN(Tokens[7], tok::l_paren, TT_VerilogInstancePortLParen);
+  Tokens = Annotate("module_x #(parameter) instance_1(port_1), "
+"instance_2(port_2);");
+  ASSERT_EQ(Tokens.size(), 16u);
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_VerilogInstancePortLParen);
+  EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_VerilogInstancePortLParen);
+  EXPECT_TOKEN(Tokens[11], tok::l_paren, TT_VerilogInstancePortLParen);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandConstructors) {
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -673,6 +673,77 @@
"  x = x;");
 }
 
+TEST_F(FormatTestVerilog, Instantiation) {
+  // Without ports.
+  verifyFormat("ffnand ff1;");
+  // With named ports.
+  verifyFormat("ffnand ff1(.qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2));");
+  // With wildcard.
+  verifyFormat("ffnand ff1(.qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2),\n"
+   "   .*);");
+  verifyFormat("ffnand ff1(.*,\n"
+   "   .qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2));");
+  // With unconnected ports.
+  verifyFormat("ffnand ff1(.q(),\n"
+   "   .qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2));");
+  verifyFormat("ffnand ff1(.q(),\n"
+   "   .qbar(),\n"
+   "   .clear(),\n"
+   "   .preset());");
+  verifyFormat("ffnand ff1(,\n"
+   "   .qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2));");
+  // With positional ports.
+  verifyFormat("ffnand ff1(out1,\n"
+   "   in1,\n"
+   "   in2);");
+  verifyFormat("ffnand ff1(,\n"
+   "   out1,\n"
+   "   in1,\n"
+   "   in2);");
+  // Multiple instantiations.
+  verifyFormat("ffnand ff1(.q(),\n"
+   "   .qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2)),\n"
+   "   ff1(.q(),\n"
+   "   .qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2));");
+  verifyFormat("ffnand //\n"
+   "ff1(.q(),\n"
+   ".qbar(out1),\n"
+   ".clear(in1),\n"
+   ".preset(in2)),\n"
+   "ff1(.q(),\n"
+   ".qbar(out1),\n"
+   ".clear(in1),\n"
+   ".preset(in2));");
+  // With breaking between instance ports disabled.
+  auto Style = getDefaultStyle();
+  Style.VerilogBreakBetweenInstancePorts = false;
+  verifyFormat("ffnand ff1;", Style);
+  verifyFormat("ffnand ff1(.qbar(out1), .clear(in1), .preset(in2), .*);",
+   Style);
+  verifyFormat("ffnand ff1(out1, in1, in2);", Style);
+  verifyFormat("ffnand ff1(.q(), .qbar(out1), .clear(in1), .preset(in2)),\n"
+   "   ff1(.q(), .qbar(out1), .clear(in1), .preset(in2));",
+   Style);
+  verifyFormat("ffnand //\n"
+   "ff1(.q(), .qbar(out1), .clear(in1), .preset(in2)),\n"
+   "ff1(.q(), .qbar(out1), .clear(in1), .preset(in2));",
+   Style);
+}
+
 TEST_F(FormatTestVerilog, Operators) {
   // Test that unary operators are not followed by space.
   verifyFormat("x = +x;");
Index: 

[PATCH] D147329: [clang-format] Handle Verilog struct literals

2023-04-01 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 rGfeb585e7d62c: [clang-format] Handle Verilog struct literals 
(authored by sstwcw).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D147329

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


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -916,6 +916,25 @@
   verifyFormat("{

[PATCH] D147328: [clang-format] Handle enum in Verilog

2023-04-01 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 rG92b2be39656b: [clang-format] Handle enum in Verilog 
(authored by sstwcw).

Changed prior to commit:
  https://reviews.llvm.org/D147328?vs=510031=510248#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D147328

Files:
  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
@@ -338,6 +338,20 @@
 "x = x;");
 }
 
+TEST_F(FormatTestVerilog, Enum) {
+  verifyFormat("enum { x } x;");
+  verifyFormat("typedef enum { x } x;");
+  verifyFormat("enum { red, yellow, green } x;");
+  verifyFormat("typedef enum { red, yellow, green } x;");
+  verifyFormat("enum integer { x } x;");
+  verifyFormat("typedef enum { x = 0 } x;");
+  verifyFormat("typedef enum { red = 0, yellow = 1, green = 2 } x;");
+  verifyFormat("typedef enum integer { x } x;");
+  verifyFormat("typedef enum bit [0 : 1] { x } x;");
+  verifyFormat("typedef enum { add = 10, sub[5], jmp[6 : 8] } E1;");
+  verifyFormat("typedef enum { add = 10, sub[5] = 0, jmp[6 : 8] = 1 } E1;");
+}
+
 TEST_F(FormatTestVerilog, Headers) {
   // Test headers with multiple ports.
   verifyFormat("module mh1\n"
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1709,8 +1709,8 @@
   // enum definition can start a structural element.
   if (!parseEnum())
 break;
-  // This only applies for C++.
-  if (!Style.isCpp()) {
+  // This only applies to C++ and Verilog.
+  if (!Style.isCpp() && !Style.isVerilog()) {
 addUnwrappedLine();
 return;
   }
@@ -3541,7 +3541,15 @@
  FormatTok->isOneOf(tok::colon, tok::coloncolon, tok::less,
 tok::greater, tok::comma, tok::question,
 tok::l_square, tok::r_square)) {
-nextToken();
+if (Style.isVerilog()) {
+  FormatTok->setFinalizedType(TT_VerilogDimensionedTypeName);
+  nextToken();
+  // In Verilog the base type can have dimensions.
+  while (FormatTok->is(tok::l_square))
+parseSquare();
+} else {
+  nextToken();
+}
 // We can have macros or attributes in between 'enum' and the enum name.
 if (FormatTok->is(tok::l_paren))
   parseParens();


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -338,6 +338,20 @@
 "x = x;");
 }
 
+TEST_F(FormatTestVerilog, Enum) {
+  verifyFormat("enum { x } x;");
+  verifyFormat("typedef enum { x } x;");
+  verifyFormat("enum { red, yellow, green } x;");
+  verifyFormat("typedef enum { red, yellow, green } x;");
+  verifyFormat("enum integer { x } x;");
+  verifyFormat("typedef enum { x = 0 } x;");
+  verifyFormat("typedef enum { red = 0, yellow = 1, green = 2 } x;");
+  verifyFormat("typedef enum integer { x } x;");
+  verifyFormat("typedef enum bit [0 : 1] { x } x;");
+  verifyFormat("typedef enum { add = 10, sub[5], jmp[6 : 8] } E1;");
+  verifyFormat("typedef enum { add = 10, sub[5] = 0, jmp[6 : 8] = 1 } E1;");
+}
+
 TEST_F(FormatTestVerilog, Headers) {
   // Test headers with multiple ports.
   verifyFormat("module mh1\n"
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1709,8 +1709,8 @@
   // enum definition can start a structural element.
   if (!parseEnum())
 break;
-  // This only applies for C++.
-  if (!Style.isCpp()) {
+  // This only applies to C++ and Verilog.
+  if (!Style.isCpp() && !Style.isVerilog()) {
 addUnwrappedLine();
 return;
   }
@@ -3541,7 +3541,15 @@
  FormatTok->isOneOf(tok::colon, tok::coloncolon, tok::less,
 tok::greater, tok::comma, tok::question,
 tok::l_square, tok::r_square)) {
-nextToken();
+if (Style.isVerilog()) {
+  FormatTok->setFinalizedType(TT_VerilogDimensionedTypeName);
+  nextToken();
+  // In Verilog the base type can have dimensions.
+  while (FormatTok->is(tok::l_square))
+parseSquare();
+} else {
+  nextToken();
+}
 // We can have macros or attributes in between 'enum' and the enum name.
 if 

[PATCH] D147327: [clang-format] Add option for having one port per line in Verilog

2023-04-01 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 510244.
sstwcw marked 2 inline comments as done.
sstwcw added a comment.

- Use shorter conditions


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D147327

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/unittests/Format/ConfigParseTest.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
@@ -1579,6 +1579,18 @@
   EXPECT_TOKEN_PRECEDENCE(Tokens[1], prec::Assignment);
   EXPECT_TOKEN(Tokens[3], tok::lessequal, TT_BinaryOperator);
   EXPECT_TOKEN_PRECEDENCE(Tokens[3], prec::Relational);
+
+  // Port lists in module instantiation.
+  Tokens = Annotate("module_x instance_1(port_1), instance_2(port_2);");
+  ASSERT_EQ(Tokens.size(), 12u);
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_VerilogInstancePortLParen);
+  EXPECT_TOKEN(Tokens[7], tok::l_paren, TT_VerilogInstancePortLParen);
+  Tokens = Annotate("module_x #(parameter) instance_1(port_1), "
+"instance_2(port_2);");
+  ASSERT_EQ(Tokens.size(), 16u);
+  EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_VerilogInstancePortLParen);
+  EXPECT_TOKEN(Tokens[6], tok::l_paren, TT_VerilogInstancePortLParen);
+  EXPECT_TOKEN(Tokens[11], tok::l_paren, TT_VerilogInstancePortLParen);
 }
 
 TEST_F(TokenAnnotatorTest, UnderstandConstructors) {
Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -659,6 +659,77 @@
"  x = x;");
 }
 
+TEST_F(FormatTestVerilog, Instantiation) {
+  // Without ports.
+  verifyFormat("ffnand ff1;");
+  // With named ports.
+  verifyFormat("ffnand ff1(.qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2));");
+  // With wildcard.
+  verifyFormat("ffnand ff1(.qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2),\n"
+   "   .*);");
+  verifyFormat("ffnand ff1(.*,\n"
+   "   .qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2));");
+  // With unconnected ports.
+  verifyFormat("ffnand ff1(.q(),\n"
+   "   .qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2));");
+  verifyFormat("ffnand ff1(.q(),\n"
+   "   .qbar(),\n"
+   "   .clear(),\n"
+   "   .preset());");
+  verifyFormat("ffnand ff1(,\n"
+   "   .qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2));");
+  // With positional ports.
+  verifyFormat("ffnand ff1(out1,\n"
+   "   in1,\n"
+   "   in2);");
+  verifyFormat("ffnand ff1(,\n"
+   "   out1,\n"
+   "   in1,\n"
+   "   in2);");
+  // Multiple instantiations.
+  verifyFormat("ffnand ff1(.q(),\n"
+   "   .qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2)),\n"
+   "   ff1(.q(),\n"
+   "   .qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2));");
+  verifyFormat("ffnand //\n"
+   "ff1(.q(),\n"
+   ".qbar(out1),\n"
+   ".clear(in1),\n"
+   ".preset(in2)),\n"
+   "ff1(.q(),\n"
+   ".qbar(out1),\n"
+   ".clear(in1),\n"
+   ".preset(in2));");
+  // With breaking between instance ports disabled.
+  auto Style = getDefaultStyle();
+  Style.VerilogBreakBetweenInstancePorts = false;
+  verifyFormat("ffnand ff1;", Style);
+  verifyFormat("ffnand ff1(.qbar(out1), .clear(in1), .preset(in2), .*);",
+   Style);
+  verifyFormat("ffnand ff1(out1, in1, in2);", Style);
+  verifyFormat("ffnand ff1(.q(), .qbar(out1), .clear(in1), .preset(in2)),\n"
+   "   ff1(.q(), .qbar(out1), .clear(in1), .preset(in2));",
+   Style);
+  verifyFormat("ffnand //\n"
+   "ff1(.q(), .qbar(out1), .clear(in1), .preset(in2)),\n"
+   "ff1(.q(), .qbar(out1), .clear(in1), .preset(in2));",
+   Style);
+}
+
 TEST_F(FormatTestVerilog, Operators) {
   // Test that unary operators are not followed by space.
   

[PATCH] D147327: [clang-format] Add option for having one port per line in Verilog

2023-03-31 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 510038.
sstwcw added a comment.

Generate doc


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D147327

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/FormatToken.h
  clang/lib/Format/TokenAnnotator.cpp
  clang/unittests/Format/ConfigParseTest.cpp
  clang/unittests/Format/FormatTestVerilog.cpp

Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -659,6 +659,77 @@
"  x = x;");
 }
 
+TEST_F(FormatTestVerilog, Instantiation) {
+  // Without ports.
+  verifyFormat("ffnand ff1;");
+  // With named ports.
+  verifyFormat("ffnand ff1(.qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2));");
+  // With wildcard.
+  verifyFormat("ffnand ff1(.qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2),\n"
+   "   .*);");
+  verifyFormat("ffnand ff1(.*,\n"
+   "   .qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2));");
+  // With unconnected ports.
+  verifyFormat("ffnand ff1(.q(),\n"
+   "   .qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2));");
+  verifyFormat("ffnand ff1(.q(),\n"
+   "   .qbar(),\n"
+   "   .clear(),\n"
+   "   .preset());");
+  verifyFormat("ffnand ff1(,\n"
+   "   .qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2));");
+  // With positional ports.
+  verifyFormat("ffnand ff1(out1,\n"
+   "   in1,\n"
+   "   in2);");
+  verifyFormat("ffnand ff1(,\n"
+   "   out1,\n"
+   "   in1,\n"
+   "   in2);");
+  // Multiple instantiations.
+  verifyFormat("ffnand ff1(.q(),\n"
+   "   .qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2)),\n"
+   "   ff1(.q(),\n"
+   "   .qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2));");
+  verifyFormat("ffnand //\n"
+   "ff1(.q(),\n"
+   ".qbar(out1),\n"
+   ".clear(in1),\n"
+   ".preset(in2)),\n"
+   "ff1(.q(),\n"
+   ".qbar(out1),\n"
+   ".clear(in1),\n"
+   ".preset(in2));");
+  // With breaking between instance ports disabled.
+  auto Style = getDefaultStyle();
+  Style.VerilogBreakBetweenInstancePorts = false;
+  verifyFormat("ffnand ff1;", Style);
+  verifyFormat("ffnand ff1(.qbar(out1), .clear(in1), .preset(in2), .*);",
+   Style);
+  verifyFormat("ffnand ff1(out1, in1, in2);", Style);
+  verifyFormat("ffnand ff1(.q(), .qbar(out1), .clear(in1), .preset(in2)),\n"
+   "   ff1(.q(), .qbar(out1), .clear(in1), .preset(in2));",
+   Style);
+  verifyFormat("ffnand //\n"
+   "ff1(.q(), .qbar(out1), .clear(in1), .preset(in2)),\n"
+   "ff1(.q(), .qbar(out1), .clear(in1), .preset(in2));",
+   Style);
+}
+
 TEST_F(FormatTestVerilog, Operators) {
   // Test that unary operators are not followed by space.
   verifyFormat("x = +x;");
Index: clang/unittests/Format/ConfigParseTest.cpp
===
--- clang/unittests/Format/ConfigParseTest.cpp
+++ clang/unittests/Format/ConfigParseTest.cpp
@@ -192,6 +192,7 @@
   CHECK_PARSE_BOOL(SpaceBeforeJsonColon);
   CHECK_PARSE_BOOL(SpaceBeforeRangeBasedForLoopColon);
   CHECK_PARSE_BOOL(SpaceBeforeSquareBrackets);
+  CHECK_PARSE_BOOL(VerilogBreakBetweenInstancePorts);
 
   CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterCaseLabel);
   CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterClass);
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -311,6 +311,9 @@
   bool OperatorCalledAsMemberFunction =
   Prev->Previous && Prev->Previous->isOneOf(tok::period, tok::arrow);
   Contexts.back().IsExpression = OperatorCalledAsMemberFunction;
+} else if (OpeningParen.is(TT_VerilogInstancePortLParen)) {
+  Contexts.back().IsExpression = true;
+  Contexts.back().ContextType = Context::VerilogInstancePortList;
 } else if (Style.isJavaScript() &&
(Line.startsWith(Keywords.kw_type, 

[PATCH] D147329: [clang-format] Handle Verilog struct literals

2023-03-31 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
Herald added subscribers: cfe-commits, ctetreau.
Herald added projects: All, clang, clang-format.
Herald added reviewers: rymiel, HazardyKnusperkeks, owenpan, MyDeveloperDay.
sstwcw requested review of this revision.

Previously `isVerilogIdentifier` was mistaking the apostrophe used in
struct literals as an identifier.  It is fixed.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D147329

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


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -902,6 +902,25 @@
   verifyFormat("{

[PATCH] D147328: [clang-format] Handle enum in Verilog

2023-03-31 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
Herald added projects: All, clang, clang-format.
Herald added a subscriber: cfe-commits.
Herald added reviewers: rymiel, HazardyKnusperkeks, owenpan, MyDeveloperDay.
sstwcw requested review of this revision.

Verilog has enum just like C.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D147328

Files:
  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
@@ -338,6 +338,20 @@
 "x = x;");
 }
 
+TEST_F(FormatTestVerilog, Enum) {
+  verifyFormat("enum { x } x;");
+  verifyFormat("typedef enum { x } x;");
+  verifyFormat("enum { red, yellow, green } x;");
+  verifyFormat("typedef enum { red, yellow, green } x;");
+  verifyFormat("enum integer { x } x;");
+  verifyFormat("typedef enum { x = 0 } x;");
+  verifyFormat("typedef enum { red = 0, yellow = 1, green = 2 } x;");
+  verifyFormat("typedef enum integer { x } x;");
+  verifyFormat("typedef enum bit [0 : 1] { x } x;");
+  verifyFormat("typedef enum { add = 10, sub[5], jmp[6 : 8] } E1;");
+  verifyFormat("typedef enum { add = 10, sub[5] = 0, jmp[6 : 8] = 1 } E1;");
+}
+
 TEST_F(FormatTestVerilog, Headers) {
   // Test headers with multiple ports.
   verifyFormat("module mh1\n"
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1709,8 +1709,8 @@
   // enum definition can start a structural element.
   if (!parseEnum())
 break;
-  // This only applies for C++.
-  if (!Style.isCpp()) {
+  // This only applies for C++ and Verilog.
+  if (!Style.isCpp() && !Style.isVerilog()) {
 addUnwrappedLine();
 return;
   }
@@ -3541,7 +3541,15 @@
  FormatTok->isOneOf(tok::colon, tok::coloncolon, tok::less,
 tok::greater, tok::comma, tok::question,
 tok::l_square, tok::r_square)) {
-nextToken();
+if (Style.isVerilog()) {
+  FormatTok->setFinalizedType(TT_VerilogDimensionedTypeName);
+  nextToken();
+  // In Verilog the base type can have dimensions.
+  while (FormatTok->is(tok::l_square))
+parseSquare();
+} else {
+  nextToken();
+}
 // We can have macros or attributes in between 'enum' and the enum name.
 if (FormatTok->is(tok::l_paren))
   parseParens();


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -338,6 +338,20 @@
 "x = x;");
 }
 
+TEST_F(FormatTestVerilog, Enum) {
+  verifyFormat("enum { x } x;");
+  verifyFormat("typedef enum { x } x;");
+  verifyFormat("enum { red, yellow, green } x;");
+  verifyFormat("typedef enum { red, yellow, green } x;");
+  verifyFormat("enum integer { x } x;");
+  verifyFormat("typedef enum { x = 0 } x;");
+  verifyFormat("typedef enum { red = 0, yellow = 1, green = 2 } x;");
+  verifyFormat("typedef enum integer { x } x;");
+  verifyFormat("typedef enum bit [0 : 1] { x } x;");
+  verifyFormat("typedef enum { add = 10, sub[5], jmp[6 : 8] } E1;");
+  verifyFormat("typedef enum { add = 10, sub[5] = 0, jmp[6 : 8] = 1 } E1;");
+}
+
 TEST_F(FormatTestVerilog, Headers) {
   // Test headers with multiple ports.
   verifyFormat("module mh1\n"
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1709,8 +1709,8 @@
   // enum definition can start a structural element.
   if (!parseEnum())
 break;
-  // This only applies for C++.
-  if (!Style.isCpp()) {
+  // This only applies for C++ and Verilog.
+  if (!Style.isCpp() && !Style.isVerilog()) {
 addUnwrappedLine();
 return;
   }
@@ -3541,7 +3541,15 @@
  FormatTok->isOneOf(tok::colon, tok::coloncolon, tok::less,
 tok::greater, tok::comma, tok::question,
 tok::l_square, tok::r_square)) {
-nextToken();
+if (Style.isVerilog()) {
+  FormatTok->setFinalizedType(TT_VerilogDimensionedTypeName);
+  nextToken();
+  // In Verilog the base type can have dimensions.
+  while (FormatTok->is(tok::l_square))
+parseSquare();
+} else {
+  nextToken();
+}
 // We can have macros or attributes in between 'enum' and the enum name.
 if (FormatTok->is(tok::l_paren))
   parseParens();
___
cfe-commits mailing list

[PATCH] D147327: [clang-format] Add option for having one port on a line in Verilog

2023-03-31 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
Herald added projects: All, clang, clang-format.
Herald added a subscriber: cfe-commits.
Herald added reviewers: rymiel, HazardyKnusperkeks, owenpan, MyDeveloperDay.
sstwcw requested review of this revision.
Herald added a comment.

NOTE: Clang-Format Team Automated Review Comment

Your review contains a change to clang/include/clang/Format/Format.h but does 
not contain an update to ClangFormatStyleOptions.rst

ClangFormatStyleOptions.rst is generated via 
clang/docs/tools/dump_format_style.py,  please run this to regenerate the .rst

You can validate that the rst is valid by running.

  ./docs/tools/dump_format_style.py
  mkdir -p html
  /usr/bin/sphinx-build -n ./docs ./html


We added the option `VerilogBreakBetweenInstancePorts` to put ports on
separate lines in module instantiations.  We made it default to true
because style guides mostly recommend it that way for example:

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


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D147327

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

Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -659,6 +659,77 @@
"  x = x;");
 }
 
+TEST_F(FormatTestVerilog, Instantiation) {
+  // Without ports.
+  verifyFormat("ffnand ff1;");
+  // With named ports.
+  verifyFormat("ffnand ff1(.qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2));");
+  // With wildcard.
+  verifyFormat("ffnand ff1(.qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2),\n"
+   "   .*);");
+  verifyFormat("ffnand ff1(.*,\n"
+   "   .qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2));");
+  // With unconnected ports.
+  verifyFormat("ffnand ff1(.q(),\n"
+   "   .qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2));");
+  verifyFormat("ffnand ff1(.q(),\n"
+   "   .qbar(),\n"
+   "   .clear(),\n"
+   "   .preset());");
+  verifyFormat("ffnand ff1(,\n"
+   "   .qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2));");
+  // With positional ports.
+  verifyFormat("ffnand ff1(out1,\n"
+   "   in1,\n"
+   "   in2);");
+  verifyFormat("ffnand ff1(,\n"
+   "   out1,\n"
+   "   in1,\n"
+   "   in2);");
+  // Multiple instantiations.
+  verifyFormat("ffnand ff1(.q(),\n"
+   "   .qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2)),\n"
+   "   ff1(.q(),\n"
+   "   .qbar(out1),\n"
+   "   .clear(in1),\n"
+   "   .preset(in2));");
+  verifyFormat("ffnand //\n"
+   "ff1(.q(),\n"
+   ".qbar(out1),\n"
+   ".clear(in1),\n"
+   ".preset(in2)),\n"
+   "ff1(.q(),\n"
+   ".qbar(out1),\n"
+   ".clear(in1),\n"
+   ".preset(in2));");
+  // With breaking between instance ports disabled.
+  auto Style = getDefaultStyle();
+  Style.VerilogBreakBetweenInstancePorts = false;
+  verifyFormat("ffnand ff1;", Style);
+  verifyFormat("ffnand ff1(.qbar(out1), .clear(in1), .preset(in2), .*);",
+   Style);
+  verifyFormat("ffnand ff1(out1, in1, in2);", Style);
+  verifyFormat("ffnand ff1(.q(), .qbar(out1), .clear(in1), .preset(in2)),\n"
+   "   ff1(.q(), .qbar(out1), .clear(in1), .preset(in2));",
+   Style);
+  verifyFormat("ffnand //\n"
+   "ff1(.q(), .qbar(out1), .clear(in1), .preset(in2)),\n"
+   "ff1(.q(), .qbar(out1), .clear(in1), .preset(in2));",
+   Style);
+}
+
 TEST_F(FormatTestVerilog, Operators) {
   // Test that unary operators are not followed by space.
   verifyFormat("x = +x;");
Index: clang/unittests/Format/ConfigParseTest.cpp
===
--- clang/unittests/Format/ConfigParseTest.cpp
+++ clang/unittests/Format/ConfigParseTest.cpp
@@ -192,6 +192,7 @@
   CHECK_PARSE_BOOL(SpaceBeforeJsonColon);
   CHECK_PARSE_BOOL(SpaceBeforeRangeBasedForLoopColon);
   CHECK_PARSE_BOOL(SpaceBeforeSquareBrackets);
+  

[PATCH] D146401: [clang-format] Don't squash Verilog escaped identifiers

2023-03-26 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 rG6cef325481a8: [clang-format] Dont squash Verilog 
escaped identifiers (authored by sstwcw).

Changed prior to commit:
  https://reviews.llvm.org/D146401?vs=506454=508444#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146401

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

Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -6,47 +6,26 @@
 //
 //===--===//
 
-#include "FormatTestUtils.h"
-#include "clang/Format/Format.h"
-#include "llvm/Support/Debug.h"
-#include "gtest/gtest.h"
+#include "FormatTestBase.h"
 
 #define DEBUG_TYPE "format-test"
 
 namespace clang {
 namespace format {
-
-class FormatTestVerilog : public ::testing::Test {
+namespace test {
+namespace {
+class FormatTestVerilog : public test::FormatTestBase {
 protected:
-  static std::string format(llvm::StringRef Code, unsigned Offset,
-unsigned Length, const FormatStyle ) {
-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  = getLLVMStyle(FormatStyle::LK_Verilog)) {
-return format(Code, 0, Code.size(), Style);
+  FormatStyle getDefaultStyle() const override {
+return getLLVMStyle(FormatStyle::LK_Verilog);
   }
-
-  static void verifyFormat(
-  llvm::StringRef Code,
-  const FormatStyle  = 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));
+  std::string messUp(llvm::StringRef Code) const override {
+return test::messUp(Code, /*HandleHash=*/false);
   }
 };
 
 TEST_F(FormatTestVerilog, Align) {
-  FormatStyle Style = getLLVMStyle(FormatStyle::LK_Verilog);
+  FormatStyle Style = getDefaultStyle();
   Style.AlignConsecutiveAssignments.Enabled = true;
   verifyFormat("x<= x;\n"
"sfdbddfbdfbb <= x;\n"
@@ -242,7 +221,7 @@
"instruction3(ir);\n"
"endcase");
   // Test indention options.
-  auto Style = getLLVMStyle(FormatStyle::LK_Verilog);
+  auto Style = getDefaultStyle();
   Style.IndentCaseLabels = false;
   verifyFormat("case (data)\n"
"16'd0:\n"
@@ -268,7 +247,7 @@
"endcase",
Style);
   // Other colons should not be mistaken as case colons.
-  Style = getLLVMStyle(FormatStyle::LK_Verilog);
+  Style = getDefaultStyle();
   Style.BitFieldColonSpacing = FormatStyle::BFCS_None;
   verifyFormat("case (x[1:0])\n"
"endcase",
@@ -283,7 +262,7 @@
   verifyFormat("default:\n"
"  x[1 : 0] = x[1 : 0];",
Style);
-  Style = getLLVMStyle(FormatStyle::LK_Verilog);
+  Style = getDefaultStyle();
   Style.SpacesInContainerLiterals = true;
   verifyFormat("case ('{x : x, default : 9})\n"
"endcase",
@@ -355,8 +334,8 @@
   verifyFormat("#1.5s;");
   // The following expression should be on the same line.
   verifyFormat("#1 x = x;");
-  EXPECT_EQ("#1 x = x;", format("#1\n"
-"x = x;"));
+  verifyFormat("#1 x = x;", "#1\n"
+"x = x;");
 }
 
 TEST_F(FormatTestVerilog, Headers) {
@@ -486,7 +465,7 @@
" b);\n"
"endmodule");
   // With a concatenation in the names.
-  auto Style = getLLVMStyle(FormatStyle::LK_Verilog);
+  auto Style = getDefaultStyle();
   Style.ColumnLimit = 40;
   verifyFormat("`define X(x)   \\\n"
"  module test  \\\n"
@@ -577,6 +556,28 @@
"endfunction : x");
 }
 
+TEST_F(FormatTestVerilog, Identifiers) {
+  // Escaped identifiers should not be split.
+  verifyFormat("\\busa+index");
+  verifyFormat("\\-clock");
+  verifyFormat("\\***error-condition***");
+  verifyFormat("\\net1\\/net2");
+  verifyFormat("\\{a,b}");
+  verifyFormat("\\a*(b+c)");
+  // Escaped identifiers can't be joined with the next token.  Extra space
+  // should be removed.
+  verifyFormat("\\busa+index ;", "\\busa+index\n"
+ 

[PATCH] D146403: [clang-format] More work on space around operators in Verilog

2023-03-25 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 rG0e01c3d28217: [clang-format] More work on space around 
operators in Verilog (authored by sstwcw).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146403

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

Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -657,6 +657,14 @@
   verifyFormat("x = ++x;");
   verifyFormat("x = --x;");
 
+  // Test that `*` and `*>` are binary.
+  verifyFormat("x = x * x;");
+  verifyFormat("x = (x * x);");
+  verifyFormat("(opcode *> o1) = 6.1;");
+  verifyFormat("(C, D *> Q) = 18;");
+  // The wildcard import is not a binary operator.
+  verifyFormat("import p::*;");
+
   // Test that operators don't get split.
   verifyFormat("x = x++;");
   verifyFormat("x = x--;");
@@ -697,6 +705,13 @@
   EXPECT_EQ("x = x < -x;", format("x=x<-x;"));
   EXPECT_EQ("x = x << -x;", format("x=x<<-x;"));
   EXPECT_EQ("x = x <<< -x;", format("x=x<<<-x;"));
+
+  // Test that operators that are C++ identifiers get treated as operators.
+  verifyFormat("solve s before d;");   // before
+  verifyFormat("binsof(i) intersect {0};");// intersect
+  verifyFormat("req dist {1};");   // dist
+  verifyFormat("a inside {b, c};");// inside
+  verifyFormat("bus.randomize() with { atype == low; };"); // with
 }
 
 TEST_F(FormatTestVerilog, Preprocessor) {
@@ -849,6 +864,26 @@
"endprimitive");
 }
 
+TEST_F(FormatTestVerilog, Streaming) {
+  verifyFormat("x = {>>{j}};");
+  verifyFormat("x = {>>byte{j}};");
+  verifyFormat("x = {<<{j}};");
+  verifyFormat("x = {<>4{6'b11_0101}};");
+  verifyFormat("x = {<<2{{<<{4'b1101;");
+  verifyFormat("bit [96 : 1] y = {>>{a, b, c}};");
+  verifyFormat("int j = {>>{a, b, c}};");
+  verifyFormat("{>>{a, b, c}} = 23'b1;");
+  verifyFormat("{>>{a, b, c}} = x;");
+  verifyFormat("{>>{j}} = x;");
+  verifyFormat("{>>byte{j}} = x;");
+  verifyFormat("{<<{j}} = x;");
+  verifyFormat("{<` in module path declarations in
+  // specify blocks because merged tokens take the type of the first one by
+  // default.
+  if (Tok.is(tok::star))
+return TT_BinaryOperator;
+  return determineUnaryOperatorByUsage(Tok) ? TT_UnaryOperator
+: TT_BinaryOperator;
+}
+
 const FormatToken *PrevToken = Tok.getPreviousNonComment();
 if (!PrevToken)
   return TT_UnaryOperator;
@@ -3987,7 +3998,12 @@
 return !Left.isOneOf(tok::l_paren, tok::l_square, tok::at) &&
(Left.isNot(tok::colon) || Left.isNot(TT_ObjCMethodExpr));
   }
-  if ((Left.isOneOf(tok::identifier, tok::greater, tok::r_square,
+  // No space between the variable name and the initializer list.
+  // A a1{1};
+  // Verilog doesn't have such syntax, but it has word operators that are C++
+  // identifiers like `a inside {b, c}`. So the rule is not applicable.
+  if (!Style.isVerilog() &&
+  (Left.isOneOf(tok::identifier, tok::greater, tok::r_square,
 tok::r_paren) ||
Left.isSimpleTypeSpecifier()) &&
   Right.is(tok::l_brace) && Right.getNextNonComment() &&
@@ -4373,12 +4389,24 @@
  Keywords.isWordLike(Left))) {
   return false;
 }
+// Don't add spaces in imports like `import foo::*;`.
+if ((Right.is(tok::star) && Left.is(tok::coloncolon)) ||
+(Left.is(tok::star) && Right.is(tok::semi))) {
+  return false;
+}
 // Add space in attribute like `(* ASYNC_REG = "TRUE" *)`.
 if (Left.endsSequence(tok::star, tok::l_paren) && Right.is(tok::identifier))
   return true;
 // Add space before drive strength like in `wire (strong1, pull0)`.
 if (Right.is(tok::l_paren) && Right.is(TT_VerilogStrength))
   return true;
+// Don't add space in a streaming concatenation like `{>>{j}}`.
+if ((Left.is(tok::l_brace) &&
+ Right.isOneOf(tok::lessless, tok::greatergreater)) ||
+(Left.endsSequence(tok::lessless, tok::l_brace) ||
+ Left.endsSequence(tok::greatergreater, tok::l_brace))) {
+  return false;
+}
   }
   if (Left.is(TT_ImplicitStringLiteral))
 return Right.hasWhitespaceBefore();
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D146402: [clang-format] Handle Verilog assign statements

2023-03-25 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 rGf90668c8ccc5: [clang-format] Handle Verilog assign 
statements (authored by sstwcw).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146402

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


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -97,6 +97,23 @@
Style);
 }
 
+TEST_F(FormatTestVerilog, Assign) {
+  verifyFormat("assign mynet = enable;");
+  verifyFormat("assign (strong1, pull0) #1 mynet = enable;");
+  verifyFormat("assign #1 mynet = enable;");
+  verifyFormat("assign mynet = enable;");
+  // Test that assignments are on separate lines.
+  verifyFormat("assign mynet = enable,\n"
+   "   mynet1 = enable1;");
+  // Test that `<=` and `,` don't confuse it.
+  verifyFormat("assign mynet = enable1 <= enable2;");
+  verifyFormat("assign mynet = enable1 <= enable2,\n"
+   "   mynet1 = enable3;");
+  verifyFormat("assign mynet = enable,\n"
+   "   mynet1 = enable2 <= enable3;");
+  verifyFormat("assign mynet = enable(enable1, enable2);");
+}
+
 TEST_F(FormatTestVerilog, BasedLiteral) {
   verifyFormat("x = '0;");
   verifyFormat("x = '1;");
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1286,8 +1286,11 @@
 Tok->setType(TT_InheritanceComma);
 break;
   default:
-if (Contexts.back().FirstStartOfName &&
-(Contexts.size() == 1 || startsWithInitStatement(Line))) {
+if (Style.isVerilog() && Contexts.size() == 1 &&
+Line.startsWith(Keywords.kw_assign)) {
+  Tok->setFinalizedType(TT_VerilogAssignComma);
+} else if (Contexts.back().FirstStartOfName &&
+   (Contexts.size() == 1 || startsWithInitStatement(Line))) {
   Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt = true;
   Line.IsMultiVariableDeclStmt = true;
 }
@@ -4720,6 +4723,9 @@
   return true;
 }
   } else if (Style.isVerilog()) {
+// Break between assignments.
+if (Left.is(TT_VerilogAssignComma))
+  return true;
 // Break between ports of different types.
 if (Left.is(TT_VerilogTypeComma))
   return true;
Index: clang/lib/Format/FormatToken.h
===
--- clang/lib/Format/FormatToken.h
+++ clang/lib/Format/FormatToken.h
@@ -144,6 +144,8 @@
   TYPE(UnaryOperator)  
\
   TYPE(UnionLBrace)
\
   TYPE(UntouchableMacroFunc)   
\
+  /* Like in 'assign x = 0, y = 1;' . */   
\
+  TYPE(VerilogAssignComma) 
\
   /* like in begin : block */  
\
   TYPE(VerilogBlockLabelColon) 
\
   /* The square bracket for the dimension part of the type name.   
\


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -97,6 +97,23 @@
Style);
 }
 
+TEST_F(FormatTestVerilog, Assign) {
+  verifyFormat("assign mynet = enable;");
+  verifyFormat("assign (strong1, pull0) #1 mynet = enable;");
+  verifyFormat("assign #1 mynet = enable;");
+  verifyFormat("assign mynet = enable;");
+  // Test that assignments are on separate lines.
+  verifyFormat("assign mynet = enable,\n"
+   "   mynet1 = enable1;");
+  // Test that `<=` and `,` don't confuse it.
+  verifyFormat("assign mynet = enable1 <= enable2;");
+  verifyFormat("assign mynet = enable1 <= enable2,\n"
+   "   mynet1 = enable3;");
+  verifyFormat("assign mynet = enable,\n"
+   "   mynet1 = enable2 <= enable3;");
+  verifyFormat("assign mynet = enable(enable1, enable2);");
+}
+
 TEST_F(FormatTestVerilog, BasedLiteral) {
   verifyFormat("x = '0;");
   verifyFormat("x = '1;");
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1286,8 +1286,11 @@
 Tok->setType(TT_InheritanceComma);
 break;
   

[PATCH] D146401: [clang-format] Don't squash Verilog escaped identifiers

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



Comment at: clang/unittests/Format/FormatTestVerilog.cpp:897
 }
+} // namespace
+} // namespace test

MyDeveloperDay wrote:
> is this correct? do you have an anonymous namespace?
It is correct.  The class `FormatTestVerilog` is only used in this file.  Other 
files have it too.  I didn't notice it when I copied the first few lines from 
`FormatTest.cpp` this time, but I probably forgot to add it when creating the 
file.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146401

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


[PATCH] D146403: [clang-format] More work on space around operators in Verilog

2023-03-19 Thread sstwcw via Phabricator via cfe-commits
sstwcw updated this revision to Diff 506457.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146403

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

Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -657,6 +657,14 @@
   verifyFormat("x = ++x;");
   verifyFormat("x = --x;");
 
+  // Test that `*` and `*>` are binary.
+  verifyFormat("x = x * x;");
+  verifyFormat("x = (x * x);");
+  verifyFormat("(opcode *> o1) = 6.1;");
+  verifyFormat("(C, D *> Q) = 18;");
+  // The wildcard import is not a binary operator.
+  verifyFormat("import p::*;");
+
   // Test that operators don't get split.
   verifyFormat("x = x++;");
   verifyFormat("x = x--;");
@@ -697,6 +705,13 @@
   EXPECT_EQ("x = x < -x;", format("x=x<-x;"));
   EXPECT_EQ("x = x << -x;", format("x=x<<-x;"));
   EXPECT_EQ("x = x <<< -x;", format("x=x<<<-x;"));
+
+  // Test that operators that are C++ identifiers get treated as operators.
+  verifyFormat("solve s before d;");   // before
+  verifyFormat("binsof(i) intersect {0};");// intersect
+  verifyFormat("req dist {1};");   // dist
+  verifyFormat("a inside {b, c};");// inside
+  verifyFormat("bus.randomize() with { atype == low; };"); // with
 }
 
 TEST_F(FormatTestVerilog, Preprocessor) {
@@ -849,6 +864,26 @@
"endprimitive");
 }
 
+TEST_F(FormatTestVerilog, Streaming) {
+  verifyFormat("x = {>>{j}};");
+  verifyFormat("x = {>>byte{j}};");
+  verifyFormat("x = {<<{j}};");
+  verifyFormat("x = {<>4{6'b11_0101}};");
+  verifyFormat("x = {<<2{{<<{4'b1101;");
+  verifyFormat("bit [96 : 1] y = {>>{a, b, c}};");
+  verifyFormat("int j = {>>{a, b, c}};");
+  verifyFormat("{>>{a, b, c}} = 23'b1;");
+  verifyFormat("{>>{a, b, c}} = x;");
+  verifyFormat("{>>{j}} = x;");
+  verifyFormat("{>>byte{j}} = x;");
+  verifyFormat("{<<{j}} = x;");
+  verifyFormat("{<` in module path declarations in
+  // specify blocks because merged tokens take the type of the first one by
+  // default.
+  if (Tok.is(tok::star))
+return TT_BinaryOperator;
+  return determineUnaryOperatorByUsage(Tok) ? TT_UnaryOperator
+: TT_BinaryOperator;
+}
+
 const FormatToken *PrevToken = Tok.getPreviousNonComment();
 if (!PrevToken)
   return TT_UnaryOperator;
@@ -3984,7 +3995,12 @@
 return !Left.isOneOf(tok::l_paren, tok::l_square, tok::at) &&
(Left.isNot(tok::colon) || Left.isNot(TT_ObjCMethodExpr));
   }
-  if ((Left.isOneOf(tok::identifier, tok::greater, tok::r_square,
+  // No space between the variable name and the initializer list.
+  // A a1{1};
+  // Verilog doesn't have such syntax, but it has word operators that are C++
+  // identifiers like `a inside {b, c}`. So the rule is not applicable.
+  if (!Style.isVerilog() &&
+  (Left.isOneOf(tok::identifier, tok::greater, tok::r_square,
 tok::r_paren) ||
Left.isSimpleTypeSpecifier()) &&
   Right.is(tok::l_brace) && Right.getNextNonComment() &&
@@ -4370,12 +4386,24 @@
  Keywords.isWordLike(Left))) {
   return false;
 }
+// Don't add spaces in imports like `import foo::*;`.
+if ((Right.is(tok::star) && Left.is(tok::coloncolon)) ||
+(Left.is(tok::star) && Right.is(tok::semi))) {
+  return false;
+}
 // Add space in attribute like `(* ASYNC_REG = "TRUE" *)`.
 if (Left.endsSequence(tok::star, tok::l_paren) && Right.is(tok::identifier))
   return true;
 // Add space before drive strength like in `wire (strong1, pull0)`.
 if (Right.is(tok::l_paren) && Right.is(TT_VerilogStrength))
   return true;
+// Don't add space in a streaming concatenation like `{>>{j}}`.
+if ((Left.is(tok::l_brace) &&
+ Right.isOneOf(tok::lessless, tok::greatergreater)) ||
+(Left.endsSequence(tok::lessless, tok::l_brace) ||
+ Left.endsSequence(tok::greatergreater, tok::l_brace))) {
+  return false;
+}
   }
   if (Left.is(TT_ImplicitStringLiteral))
 return Right.hasWhitespaceBefore();
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D146403: [clang-format] More work on space around operators in Verilog

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

before:

  (opcode *>o1) = 6.1;
  a inside{b, c};
  x = { >> {j}};

after:

  (opcode *> o1) = 6.1;
  a inside {b, c};
  x = {>>{j}};


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D146403

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

Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -657,6 +657,14 @@
   verifyFormat("x = ++x;");
   verifyFormat("x = --x;");
 
+  // Test that `*` and `*>` are binary.
+  verifyFormat("x = x * x;");
+  verifyFormat("x = (x * x);");
+  verifyFormat("(opcode *> o1) = 6.1;");
+  verifyFormat("(C, D *> Q) = 18;");
+  // The wildcard import is not a binary operator.
+  verifyFormat("import p::*;");
+
   // Test that operators don't get split.
   verifyFormat("x = x++;");
   verifyFormat("x = x--;");
@@ -697,6 +705,13 @@
   EXPECT_EQ("x = x < -x;", format("x=x<-x;"));
   EXPECT_EQ("x = x << -x;", format("x=x<<-x;"));
   EXPECT_EQ("x = x <<< -x;", format("x=x<<<-x;"));
+
+  // Test that operators that are C++ identifiers get treated as operators.
+  verifyFormat("solve s before d;");   // before
+  verifyFormat("binsof(i) intersect {0};");// intersect
+  verifyFormat("req dist {1};");   // dist
+  verifyFormat("a inside {b, c};");// inside
+  verifyFormat("bus.randomize() with { atype == low; };"); // with
 }
 
 TEST_F(FormatTestVerilog, Preprocessor) {
@@ -849,6 +864,26 @@
"endprimitive");
 }
 
+TEST_F(FormatTestVerilog, Streaming) {
+  verifyFormat("x = {>>{j}};");
+  verifyFormat("x = {>>byte{j}};");
+  verifyFormat("x = {<<{j}};");
+  verifyFormat("x = {<>4{6'b11_0101}};");
+  verifyFormat("x = {<<2{{<<{4'b1101;");
+  verifyFormat("bit [96 : 1] y = {>>{a, b, c}};");
+  verifyFormat("int j = {>>{a, b, c}};");
+  verifyFormat("{>>{a, b, c}} = 23'b1;");
+  verifyFormat("{>>{a, b, c}} = x;");
+  verifyFormat("{>>{j}} = x;");
+  verifyFormat("{>>byte{j}} = x;");
+  verifyFormat("{<<{j}} = x;");
+  verifyFormat("{<` in module path declarations in
+  // specify blocks because merged tokens take the type of the first one by
+  // default.
+  if (Tok.is(tok::star))
+return TT_BinaryOperator;
+  if (determineUnaryOperatorByUsage(Tok))
+return TT_UnaryOperator;
+  return TT_BinaryOperator;
+}
+
 const FormatToken *PrevToken = Tok.getPreviousNonComment();
 if (!PrevToken)
   return TT_UnaryOperator;
@@ -3984,7 +3996,12 @@
 return !Left.isOneOf(tok::l_paren, tok::l_square, tok::at) &&
(Left.isNot(tok::colon) || Left.isNot(TT_ObjCMethodExpr));
   }
-  if ((Left.isOneOf(tok::identifier, tok::greater, tok::r_square,
+  // No space between the variable name and the initializer list.
+  // A a1{1};
+  // Verilog doesn't have such syntax, but it has word operators that are C++
+  // identifiers like `a inside {b, c}`. So the rule is not applicable.
+  if (!Style.isVerilog() &&
+  (Left.isOneOf(tok::identifier, tok::greater, tok::r_square,
 tok::r_paren) ||
Left.isSimpleTypeSpecifier()) &&
   Right.is(tok::l_brace) && Right.getNextNonComment() &&
@@ -4370,12 +4387,24 @@
  Keywords.isWordLike(Left))) {
   return false;
 }
+// Don't add spaces in imports like `import foo::*;`.
+if ((Right.is(tok::star) && Left.is(tok::coloncolon)) ||
+(Left.is(tok::star) && Right.is(tok::semi))) {
+  return false;
+}
 // Add space in attribute like `(* ASYNC_REG = "TRUE" *)`.
 if (Left.endsSequence(tok::star, tok::l_paren) && Right.is(tok::identifier))
   return true;
 // Add space before drive strength like in `wire (strong1, pull0)`.
 if (Right.is(tok::l_paren) && Right.is(TT_VerilogStrength))
   return true;
+// Don't add space in a streaming concatenation like `{>>{j}}`.
+if ((Left.is(tok::l_brace) &&
+ Right.isOneOf(tok::lessless, tok::greatergreater)) ||
+(Left.endsSequence(tok::lessless, tok::l_brace) ||
+ Left.endsSequence(tok::greatergreater, tok::l_brace))) {
+  return false;
+}
   }
   if (Left.is(TT_ImplicitStringLiteral))
 return Right.hasWhitespaceBefore();
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D146402: [clang-format] Handle Verilog assign statements

2023-03-19 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
sstwcw added reviewers: HazardyKnusperkeks, MyDeveloperDay, owenpan, rymiel.
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/D146402

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


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -97,6 +97,23 @@
Style);
 }
 
+TEST_F(FormatTestVerilog, Assign) {
+  verifyFormat("assign mynet = enable;");
+  verifyFormat("assign (strong1, pull0) #1 mynet = enable;");
+  verifyFormat("assign #1 mynet = enable;");
+  verifyFormat("assign mynet = enable;");
+  // Test that assignments are on separate lines.
+  verifyFormat("assign mynet = enable,\n"
+   "   mynet1 = enable1;");
+  // Test that `<=` and `,` don't confuse it.
+  verifyFormat("assign mynet = enable1 <= enable2;");
+  verifyFormat("assign mynet = enable1 <= enable2,\n"
+   "   mynet1 = enable3;");
+  verifyFormat("assign mynet = enable,\n"
+   "   mynet1 = enable2 <= enable3;");
+  verifyFormat("assign mynet = enable(enable1, enable2);");
+}
+
 TEST_F(FormatTestVerilog, BasedLiteral) {
   verifyFormat("x = '0;");
   verifyFormat("x = '1;");
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1284,8 +1284,11 @@
 Tok->setType(TT_InheritanceComma);
 break;
   default:
-if (Contexts.back().FirstStartOfName &&
-(Contexts.size() == 1 || startsWithInitStatement(Line))) {
+if (Style.isVerilog() && Contexts.size() == 1 &&
+Line.startsWith(Keywords.kw_assign)) {
+  Tok->setFinalizedType(TT_VerilogAssignComma);
+} else if (Contexts.back().FirstStartOfName &&
+   (Contexts.size() == 1 || startsWithInitStatement(Line))) {
   Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt = true;
   Line.IsMultiVariableDeclStmt = true;
 }
@@ -4689,6 +4692,9 @@
   return true;
 }
   } else if (Style.isVerilog()) {
+// Break between assignments.
+if (Left.is(TT_VerilogAssignComma))
+  return true;
 // Break between ports of different types.
 if (Left.is(TT_VerilogTypeComma))
   return true;
Index: clang/lib/Format/FormatToken.h
===
--- clang/lib/Format/FormatToken.h
+++ clang/lib/Format/FormatToken.h
@@ -144,6 +144,8 @@
   TYPE(UnaryOperator)  
\
   TYPE(UnionLBrace)
\
   TYPE(UntouchableMacroFunc)   
\
+  /* Like in 'assign x = 0, y = 1;' . */   
\
+  TYPE(VerilogAssignComma) 
\
   /* like in begin : block */  
\
   TYPE(VerilogBlockLabelColon) 
\
   /* The square bracket for the dimension part of the type name.   
\


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -97,6 +97,23 @@
Style);
 }
 
+TEST_F(FormatTestVerilog, Assign) {
+  verifyFormat("assign mynet = enable;");
+  verifyFormat("assign (strong1, pull0) #1 mynet = enable;");
+  verifyFormat("assign #1 mynet = enable;");
+  verifyFormat("assign mynet = enable;");
+  // Test that assignments are on separate lines.
+  verifyFormat("assign mynet = enable,\n"
+   "   mynet1 = enable1;");
+  // Test that `<=` and `,` don't confuse it.
+  verifyFormat("assign mynet = enable1 <= enable2;");
+  verifyFormat("assign mynet = enable1 <= enable2,\n"
+   "   mynet1 = enable3;");
+  verifyFormat("assign mynet = enable,\n"
+   "   mynet1 = enable2 <= enable3;");
+  verifyFormat("assign mynet = enable(enable1, enable2);");
+}
+
 TEST_F(FormatTestVerilog, BasedLiteral) {
   verifyFormat("x = '0;");
   verifyFormat("x = '1;");
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -1284,8 +1284,11 @@
 Tok->setType(TT_InheritanceComma);
 break;
   default:
-if (Contexts.back().FirstStartOfName &&
- 

[PATCH] D146401: [clang-format] Don't squash Verilog escaped identifiers

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

An escaped identifier always needs a space following it so the parser
can tell it apart from the next token.

The unit tests are changed to use `FormatTestBase.h` because we need the
2-argument version of `verifyFormat`.  We also added the `messUp`
virtual function because Verilog needs a different version of it.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D146401

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

Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -6,47 +6,26 @@
 //
 //===--===//
 
-#include "FormatTestUtils.h"
-#include "clang/Format/Format.h"
-#include "llvm/Support/Debug.h"
-#include "gtest/gtest.h"
+#include "FormatTestBase.h"
 
 #define DEBUG_TYPE "format-test"
 
 namespace clang {
 namespace format {
-
-class FormatTestVerilog : public ::testing::Test {
+namespace test {
+namespace {
+class FormatTestVerilog : public test::FormatTestBase {
 protected:
-  static std::string format(llvm::StringRef Code, unsigned Offset,
-unsigned Length, const FormatStyle ) {
-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  = getLLVMStyle(FormatStyle::LK_Verilog)) {
-return format(Code, 0, Code.size(), Style);
+  virtual FormatStyle getDefaultStyle() const override {
+return getLLVMStyle(FormatStyle::LK_Verilog);
   }
-
-  static void verifyFormat(
-  llvm::StringRef Code,
-  const FormatStyle  = 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));
+  virtual std::string messUp(llvm::StringRef Code) const override {
+return test::messUp(Code, /*HandleHash=*/false);
   }
 };
 
 TEST_F(FormatTestVerilog, Align) {
-  FormatStyle Style = getLLVMStyle(FormatStyle::LK_Verilog);
+  FormatStyle Style = getDefaultStyle();
   Style.AlignConsecutiveAssignments.Enabled = true;
   verifyFormat("x<= x;\n"
"sfdbddfbdfbb <= x;\n"
@@ -225,7 +204,7 @@
"instruction3(ir);\n"
"endcase");
   // Test indention options.
-  auto Style = getLLVMStyle(FormatStyle::LK_Verilog);
+  auto Style = getDefaultStyle();
   Style.IndentCaseLabels = false;
   verifyFormat("case (data)\n"
"16'd0:\n"
@@ -251,7 +230,7 @@
"endcase",
Style);
   // Other colons should not be mistaken as case colons.
-  Style = getLLVMStyle(FormatStyle::LK_Verilog);
+  Style = getDefaultStyle();
   Style.BitFieldColonSpacing = FormatStyle::BFCS_None;
   verifyFormat("case (x[1:0])\n"
"endcase",
@@ -266,7 +245,7 @@
   verifyFormat("default:\n"
"  x[1 : 0] = x[1 : 0];",
Style);
-  Style = getLLVMStyle(FormatStyle::LK_Verilog);
+  Style = getDefaultStyle();
   Style.SpacesInContainerLiterals = true;
   verifyFormat("case ('{x : x, default : 9})\n"
"endcase",
@@ -338,8 +317,8 @@
   verifyFormat("#1.5s;");
   // The following expression should be on the same line.
   verifyFormat("#1 x = x;");
-  EXPECT_EQ("#1 x = x;", format("#1\n"
-"x = x;"));
+  verifyFormat("#1 x = x;", "#1\n"
+"x = x;");
 }
 
 TEST_F(FormatTestVerilog, Headers) {
@@ -469,7 +448,7 @@
" b);\n"
"endmodule");
   // With a concatenation in the names.
-  auto Style = getLLVMStyle(FormatStyle::LK_Verilog);
+  auto Style = getDefaultStyle();
   Style.ColumnLimit = 40;
   verifyFormat("`define X(x)   \\\n"
"  module test  \\\n"
@@ -560,6 +539,28 @@
"endfunction : x");
 }
 
+TEST_F(FormatTestVerilog, Identifiers) {
+  // Escaped identifiers should not be split.
+  verifyFormat("\\busa+index");
+  verifyFormat("\\-clock");
+  verifyFormat("\\***error-condition***");
+  verifyFormat("\\net1\\/net2");
+  

[PATCH] D145888: [clang-format] Fix non-case colons in Verilog case lines

2023-03-19 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 rGb688b58f83ce: [clang-format] Fix non-case colons in Verilog 
case lines (authored by sstwcw).

Changed prior to commit:
  https://reviews.llvm.org/D145888?vs=504481=506431#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145888

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


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -250,6 +250,39 @@
"  end\n"
"endcase",
Style);
+  // Other colons should not be mistaken as case colons.
+  Style = getLLVMStyle(FormatStyle::LK_Verilog);
+  Style.BitFieldColonSpacing = FormatStyle::BFCS_None;
+  verifyFormat("case (x[1:0])\n"
+   "endcase",
+   Style);
+  verifyFormat("default:\n"
+   "  x[1:0] = x[1:0];",
+   Style);
+  Style.BitFieldColonSpacing = FormatStyle::BFCS_Both;
+  verifyFormat("case (x[1 : 0])\n"
+   "endcase",
+   Style);
+  verifyFormat("default:\n"
+   "  x[1 : 0] = x[1 : 0];",
+   Style);
+  Style = getLLVMStyle(FormatStyle::LK_Verilog);
+  Style.SpacesInContainerLiterals = true;
+  verifyFormat("case ('{x : x, default : 9})\n"
+   "endcase",
+   Style);
+  verifyFormat("x = '{x : x, default : 9};\n", Style);
+  verifyFormat("default:\n"
+   "  x = '{x : x, default : 9};\n",
+   Style);
+  Style.SpacesInContainerLiterals = false;
+  verifyFormat("case ('{x: x, default: 9})\n"
+   "endcase",
+   Style);
+  verifyFormat("x = '{x: x, default: 9};\n", Style);
+  verifyFormat("default:\n"
+   "  x = '{x: x, default: 9};\n",
+   Style);
 }
 
 TEST_F(FormatTestVerilog, Coverage) {
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -4426,8 +4426,6 @@
  Line.First->isOneOf(tok::kw_default, tok::kw_case))) {
   return Style.SpaceBeforeCaseColon;
 }
-if (Line.First->isOneOf(tok::kw_default, tok::kw_case))
-  return Style.SpaceBeforeCaseColon;
 const FormatToken *Next = Right.getNextNonComment();
 if (!Next || Next->is(tok::semi))
   return false;


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -250,6 +250,39 @@
"  end\n"
"endcase",
Style);
+  // Other colons should not be mistaken as case colons.
+  Style = getLLVMStyle(FormatStyle::LK_Verilog);
+  Style.BitFieldColonSpacing = FormatStyle::BFCS_None;
+  verifyFormat("case (x[1:0])\n"
+   "endcase",
+   Style);
+  verifyFormat("default:\n"
+   "  x[1:0] = x[1:0];",
+   Style);
+  Style.BitFieldColonSpacing = FormatStyle::BFCS_Both;
+  verifyFormat("case (x[1 : 0])\n"
+   "endcase",
+   Style);
+  verifyFormat("default:\n"
+   "  x[1 : 0] = x[1 : 0];",
+   Style);
+  Style = getLLVMStyle(FormatStyle::LK_Verilog);
+  Style.SpacesInContainerLiterals = true;
+  verifyFormat("case ('{x : x, default : 9})\n"
+   "endcase",
+   Style);
+  verifyFormat("x = '{x : x, default : 9};\n", Style);
+  verifyFormat("default:\n"
+   "  x = '{x : x, default : 9};\n",
+   Style);
+  Style.SpacesInContainerLiterals = false;
+  verifyFormat("case ('{x: x, default: 9})\n"
+   "endcase",
+   Style);
+  verifyFormat("x = '{x: x, default: 9};\n", Style);
+  verifyFormat("default:\n"
+   "  x = '{x: x, default: 9};\n",
+   Style);
 }
 
 TEST_F(FormatTestVerilog, Coverage) {
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -4426,8 +4426,6 @@
  Line.First->isOneOf(tok::kw_default, tok::kw_case))) {
   return Style.SpaceBeforeCaseColon;
 }
-if (Line.First->isOneOf(tok::kw_default, tok::kw_case))
-  return Style.SpaceBeforeCaseColon;
 const FormatToken *Next = Right.getNextNonComment();
 if (!Next || Next->is(tok::semi))
   return false;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D145888: [clang-format] Fix non-case colons in Verilog case lines

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



Comment at: clang/lib/Format/TokenAnnotator.cpp:4424
-if (Line.First->isOneOf(tok::kw_default, tok::kw_case))
-  return Style.SpaceBeforeCaseColon;
 const FormatToken *Next = Right.getNextNonComment();

MyDeveloperDay wrote:
> Hmm.. this is going to impact others, did you make a change here before and 
> break something for c++? or was this a bug in the C++ code, is there not a 
> unit test for setting SpaceBeforeCaseColon? 
You can see that the previous rule already covers what this one covers.  This 
rule doesn't change the behavior for C++.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145888

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


[PATCH] D145794: [clang-format] Recognize Verilog always blocks

2023-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 rGa1f8bab9bad7: [clang-format] Recognize Verilog always blocks 
(authored by sstwcw).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145794

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
@@ -252,6 +252,12 @@
Style);
 }
 
+TEST_F(FormatTestVerilog, Coverage) {
+  verifyFormat("covergroup x\n"
+   "@@(begin x);\n"
+   "endgroup");
+}
+
 TEST_F(FormatTestVerilog, Declaration) {
   verifyFormat("wire mynet;");
   verifyFormat("wire mynet, mynet1;");
@@ -809,5 +815,50 @@
"  endtable\n"
"endprimitive");
 }
+
+TEST_F(FormatTestVerilog, StructuredProcedure) {
+  // Blocks should be indented correctly.
+  verifyFormat("initial begin\n"
+   "end");
+  verifyFormat("initial begin\n"
+   "  x <= x;\n"
+   "  x <= x;\n"
+   "end");
+  verifyFormat("initial\n"
+   "  x <= x;\n"
+   "x <= x;");
+  verifyFormat("always @(x) begin\n"
+   "end");
+  verifyFormat("always @(x) begin\n"
+   "  x <= x;\n"
+   "  x <= x;\n"
+   "end");
+  verifyFormat("always @(x)\n"
+   "  x <= x;\n"
+   "x <= x;");
+  // Various keywords.
+  verifyFormat("always @(x)\n"
+   "  x <= x;");
+  verifyFormat("always @(posedge x)\n"
+   "  x <= x;");
+  verifyFormat("always\n"
+   "  x <= x;");
+  verifyFormat("always @*\n"
+   "  x <= x;");
+  verifyFormat("always @(*)\n"
+   "  x <= x;");
+  verifyFormat("always_comb\n"
+   "  x <= x;");
+  verifyFormat("always_latch @(x)\n"
+   "  x <= x;");
+  verifyFormat("always_ff @(posedge x)\n"
+   "  x <= x;");
+  verifyFormat("initial\n"
+   "  x <= x;");
+  verifyFormat("final\n"
+   "  x <= x;");
+  verifyFormat("forever\n"
+   "  x <= x;");
+}
 } // namespace format
 } // end namespace clang
Index: clang/lib/Format/UnwrappedLineParser.h
===
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -166,7 +166,7 @@
   FormatToken *parseIfThenElse(IfStmtKind *IfKind, bool KeepBraces = false);
   void parseTryCatch();
   void parseLoopBody(bool KeepBraces, bool WrapRightBrace);
-  void parseForOrWhileLoop();
+  void parseForOrWhileLoop(bool HasParens = true);
   void parseDoWhile();
   void parseLabel(bool LeftAlignLabel = false);
   void parseCaseLabel();
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1389,6 +1389,11 @@
   }
 
   if (Style.isVerilog()) {
+if (Keywords.isVerilogStructuredProcedure(*FormatTok)) {
+  parseForOrWhileLoop(/*HasParens=*/false);
+  return;
+}
+
 // Skip things that can exist before keywords like 'if' and 'case'.
 while (true) {
   if (FormatTok->isOneOf(Keywords.kw_priority, Keywords.kw_unique,
@@ -2963,8 +2968,14 @@
 NestedTooDeep.pop_back();
 }
 
-void UnwrappedLineParser::parseForOrWhileLoop() {
-  assert(FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) &&
+void UnwrappedLineParser::parseForOrWhileLoop(bool HasParens) {
+  assert((FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) ||
+  (Style.isVerilog() &&
+   FormatTok->isOneOf(Keywords.kw_always, Keywords.kw_always_comb,
+  Keywords.kw_always_ff, Keywords.kw_always_latch,
+  Keywords.kw_final, Keywords.kw_initial,
+  Keywords.kw_foreach, Keywords.kw_forever,
+  Keywords.kw_repeat))) &&
  "'for', 'while' or foreach macro expected");
   const bool KeepBraces = !Style.RemoveBracesLLVM ||
   !FormatTok->isOneOf(tok::kw_for, tok::kw_while);
@@ -2975,8 +2986,11 @@
 nextToken();
   if (Style.isCpp() && FormatTok->is(tok::kw_co_await))
 nextToken();
-  if (FormatTok->is(tok::l_paren))
+  if (HasParens && FormatTok->is(tok::l_paren))
 parseParens();
+  // Event control.
+  if (Style.isVerilog())
+parseVerilogSensitivityList();
 
   handleAttributes();
   parseLoopBody(KeepBraces, 

[PATCH] D145888: [clang-format] Fix non-case colons in Verilog case lines

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

Back in D128714 , we should have replaced the 
old rule about colons when
we added the new one.  Because we didn't, all colons got mistaken as
case colons as long as the line began with `case` or `default`.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D145888

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


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -250,6 +250,33 @@
"  end\n"
"endcase",
Style);
+  // Other colons should not be mistaken as case colons.
+  Style = getLLVMStyle(FormatStyle::LK_Verilog);
+  Style.BitFieldColonSpacing = FormatStyle::BFCS_None;
+  verifyFormat("case (x[1:0])\n"
+   "endcase", Style);
+  verifyFormat("default:\n"
+   "  x[1:0] = x[1:0];", Style);
+  Style.BitFieldColonSpacing = FormatStyle::BFCS_Both;
+  verifyFormat("case (x[1 : 0])\n"
+   "endcase", Style);
+  verifyFormat("default:\n"
+   "  x[1 : 0] = x[1 : 0];", Style);
+  Style = getLLVMStyle(FormatStyle::LK_Verilog);
+  Style.SpacesInContainerLiterals = true;
+  verifyFormat("case ('{x : x, default : 9})\n"
+   "endcase", Style);
+  verifyFormat("x = '{x : x, default : 9};\n", Style);
+  verifyFormat("default:\n"
+   "  x = '{x : x, default : 9};\n",
+   Style);
+  Style.SpacesInContainerLiterals = false;
+  verifyFormat("case ('{x: x, default: 9})\n"
+   "endcase", Style);
+  verifyFormat("x = '{x: x, default: 9};\n", Style);
+  verifyFormat("default:\n"
+   "  x = '{x: x, default: 9};\n",
+   Style);
 }
 
 TEST_F(FormatTestVerilog, Declaration) {
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -4420,8 +4420,6 @@
  Line.First->isOneOf(tok::kw_default, tok::kw_case))) {
   return Style.SpaceBeforeCaseColon;
 }
-if (Line.First->isOneOf(tok::kw_default, tok::kw_case))
-  return Style.SpaceBeforeCaseColon;
 const FormatToken *Next = Right.getNextNonComment();
 if (!Next || Next->is(tok::semi))
   return false;


Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -250,6 +250,33 @@
"  end\n"
"endcase",
Style);
+  // Other colons should not be mistaken as case colons.
+  Style = getLLVMStyle(FormatStyle::LK_Verilog);
+  Style.BitFieldColonSpacing = FormatStyle::BFCS_None;
+  verifyFormat("case (x[1:0])\n"
+   "endcase", Style);
+  verifyFormat("default:\n"
+   "  x[1:0] = x[1:0];", Style);
+  Style.BitFieldColonSpacing = FormatStyle::BFCS_Both;
+  verifyFormat("case (x[1 : 0])\n"
+   "endcase", Style);
+  verifyFormat("default:\n"
+   "  x[1 : 0] = x[1 : 0];", Style);
+  Style = getLLVMStyle(FormatStyle::LK_Verilog);
+  Style.SpacesInContainerLiterals = true;
+  verifyFormat("case ('{x : x, default : 9})\n"
+   "endcase", Style);
+  verifyFormat("x = '{x : x, default : 9};\n", Style);
+  verifyFormat("default:\n"
+   "  x = '{x : x, default : 9};\n",
+   Style);
+  Style.SpacesInContainerLiterals = false;
+  verifyFormat("case ('{x: x, default: 9})\n"
+   "endcase", Style);
+  verifyFormat("x = '{x: x, default: 9};\n", Style);
+  verifyFormat("default:\n"
+   "  x = '{x: x, default: 9};\n",
+   Style);
 }
 
 TEST_F(FormatTestVerilog, Declaration) {
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -4420,8 +4420,6 @@
  Line.First->isOneOf(tok::kw_default, tok::kw_case))) {
   return Style.SpaceBeforeCaseColon;
 }
-if (Line.First->isOneOf(tok::kw_default, tok::kw_case))
-  return Style.SpaceBeforeCaseColon;
 const FormatToken *Next = Right.getNextNonComment();
 if (!Next || Next->is(tok::semi))
   return false;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D145794: [clang-format] Recognize Verilog always blocks

2023-03-10 Thread sstwcw via Phabricator via cfe-commits
sstwcw created this revision.
sstwcw added reviewers: HazardyKnusperkeks, MyDeveloperDay, owenpan, rymiel.
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 small `Coverage` test was added because we added the space rule
about 2 at signs along with the rule about onely 1 of it.  We have not
fully covered covergroup yet.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D145794

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
@@ -252,6 +252,12 @@
Style);
 }
 
+TEST_F(FormatTestVerilog, Coverage) {
+  verifyFormat("covergroup x\n"
+   "@@(begin x);\n"
+   "endgroup");
+}
+
 TEST_F(FormatTestVerilog, Declaration) {
   verifyFormat("wire mynet;");
   verifyFormat("wire mynet, mynet1;");
@@ -809,5 +815,50 @@
"  endtable\n"
"endprimitive");
 }
+
+TEST_F(FormatTestVerilog, StructuredProcedure) {
+  // Blocks should be indented correctly.
+  verifyFormat("initial begin\n"
+   "end");
+  verifyFormat("initial begin\n"
+   "  x <= x;\n"
+   "  x <= x;\n"
+   "end");
+  verifyFormat("initial\n"
+   "  x <= x;\n"
+   "x <= x;");
+  verifyFormat("always @(x) begin\n"
+   "end");
+  verifyFormat("always @(x) begin\n"
+   "  x <= x;\n"
+   "  x <= x;\n"
+   "end");
+  verifyFormat("always @(x)\n"
+   "  x <= x;\n"
+   "x <= x;");
+  // Various keywords.
+  verifyFormat("always @(x)\n"
+   "  x <= x;");
+  verifyFormat("always @(posedge x)\n"
+   "  x <= x;");
+  verifyFormat("always\n"
+   "  x <= x;");
+  verifyFormat("always @*\n"
+   "  x <= x;");
+  verifyFormat("always @(*)\n"
+   "  x <= x;");
+  verifyFormat("always_comb\n"
+   "  x <= x;");
+  verifyFormat("always_latch @(x)\n"
+   "  x <= x;");
+  verifyFormat("always_ff @(posedge x)\n"
+   "  x <= x;");
+  verifyFormat("initial\n"
+   "  x <= x;");
+  verifyFormat("final\n"
+   "  x <= x;");
+  verifyFormat("forever\n"
+   "  x <= x;");
+}
 } // namespace format
 } // end namespace clang
Index: clang/lib/Format/UnwrappedLineParser.h
===
--- clang/lib/Format/UnwrappedLineParser.h
+++ clang/lib/Format/UnwrappedLineParser.h
@@ -166,7 +166,7 @@
   FormatToken *parseIfThenElse(IfStmtKind *IfKind, bool KeepBraces = false);
   void parseTryCatch();
   void parseLoopBody(bool KeepBraces, bool WrapRightBrace);
-  void parseForOrWhileLoop();
+  void parseForOrWhileLoop(bool HasParens = true);
   void parseDoWhile();
   void parseLabel(bool LeftAlignLabel = false);
   void parseCaseLabel();
Index: clang/lib/Format/UnwrappedLineParser.cpp
===
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1389,6 +1389,11 @@
   }
 
   if (Style.isVerilog()) {
+if (Keywords.isVerilogStructuredProcedure(*FormatTok)) {
+  parseForOrWhileLoop(/*HasParens=*/false);
+  return;
+}
+
 // Skip things that can exist before keywords like 'if' and 'case'.
 while (true) {
   if (FormatTok->isOneOf(Keywords.kw_priority, Keywords.kw_unique,
@@ -2963,8 +2968,14 @@
 NestedTooDeep.pop_back();
 }
 
-void UnwrappedLineParser::parseForOrWhileLoop() {
-  assert(FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) &&
+void UnwrappedLineParser::parseForOrWhileLoop(bool HasParens) {
+  assert((FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) ||
+  (Style.isVerilog() &&
+   FormatTok->isOneOf(Keywords.kw_always, Keywords.kw_always_comb,
+  Keywords.kw_always_ff, Keywords.kw_always_latch,
+  Keywords.kw_final, Keywords.kw_initial,
+  Keywords.kw_foreach, Keywords.kw_forever,
+  Keywords.kw_repeat))) &&
  "'for', 'while' or foreach macro expected");
   const bool KeepBraces = !Style.RemoveBracesLLVM ||
   !FormatTok->isOneOf(tok::kw_for, tok::kw_while);
@@ -2975,8 +2986,11 @@
 nextToken();
   if (Style.isCpp() && FormatTok->is(tok::kw_co_await))
 nextToken();
-  if (FormatTok->is(tok::l_paren))
+  if (HasParens && FormatTok->is(tok::l_paren))
 

[PATCH] D143825: [clang-format] Put ports on separate lines in Verilog module headers

2023-02-19 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 rG6e473aeffdc1: [clang-format] Put ports on separate lines in 
Verilog module headers (authored by sstwcw).

Changed prior to commit:
  https://reviews.llvm.org/D143825?vs=498376=498711#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D143825

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

Index: clang/unittests/Format/FormatTestVerilog.cpp
===
--- clang/unittests/Format/FormatTestVerilog.cpp
+++ clang/unittests/Format/FormatTestVerilog.cpp
@@ -252,6 +252,34 @@
Style);
 }
 
+TEST_F(FormatTestVerilog, Declaration) {
+  verifyFormat("wire mynet;");
+  verifyFormat("wire mynet, mynet1;");
+  verifyFormat("wire mynet, //\n"
+   " mynet1;");
+  verifyFormat("wire mynet = enable;");
+  verifyFormat("wire mynet = enable, mynet1;");
+  verifyFormat("wire mynet = enable, //\n"
+   " mynet1;");
+  verifyFormat("wire mynet, mynet1 = enable;");
+  verifyFormat("wire mynet, //\n"
+   " mynet1 = enable;");
+  verifyFormat("wire mynet = enable, mynet1 = enable;");
+  verifyFormat("wire mynet = enable, //\n"
+   " mynet1 = enable;");
+  verifyFormat("wire (strong1, pull0) mynet;");
+  verifyFormat("wire (strong1, pull0) mynet, mynet1;");
+  verifyFormat("wire (strong1, pull0) mynet, //\n"
+   "  mynet1;");
+  verifyFormat("wire (strong1, pull0) mynet = enable;");
+  verifyFormat("wire (strong1, pull0) mynet = enable, mynet1;");
+  verifyFormat("wire (strong1, pull0) mynet = enable, //\n"
+   "  mynet1;");
+  verifyFormat("wire (strong1, pull0) mynet, mynet1 = enable;");
+  verifyFormat("wire (strong1, pull0) mynet, //\n"
+   "  mynet1 = enable;");
+}
+
 TEST_F(FormatTestVerilog, Delay) {
   // Delay by the default unit.
   verifyFormat("#0;");
@@ -275,6 +303,155 @@
 "x = x;"));
 }
 
+TEST_F(FormatTestVerilog, Headers) {
+  // Test headers with multiple ports.
+  verifyFormat("module mh1\n"
+   "(input var int in1,\n"
+   " input var shortreal in2,\n"
+   " output tagged_st out);\n"
+   "endmodule");
+  // Ports should be grouped by types.
+  verifyFormat("module test\n"
+   "(input [7 : 0] a,\n"
+   " input signed [7 : 0] b, c, d);\n"
+   "endmodule");
+  verifyFormat("module test\n"
+   "(input [7 : 0] a,\n"
+   " (* x = x *) input signed [7 : 0] b, c, d);\n"
+   "endmodule");
+  verifyFormat("module test\n"
+   "(input [7 : 0] a = 0,\n"
+   " input signed [7 : 0] b = 0, c = 0, d = 0);\n"
+   "endmodule");
+  verifyFormat("module test\n"
+   "#(parameter x)\n"
+   "(input [7 : 0] a,\n"
+   " input signed [7 : 0] b, c, d);\n"
+   "endmodule");
+  // When a line needs to be broken, ports of the same type should be aligned to
+  // the same column.
+  verifyFormat("module test\n"
+   "(input signed [7 : 0] b, c, //\n"
+   "  d);\n"
+   "endmodule");
+  verifyFormat("module test\n"
+   "((* x = x *) input signed [7 : 0] b, c, //\n"
+   "  d);\n"
+   "endmodule");
+  verifyFormat("module test\n"
+   "(input signed [7 : 0] b = 0, c, //\n"
+   "  d);\n"
+   "endmodule");
+  verifyFormat("module test\n"
+   "(input signed [7 : 0] b, c = 0, //\n"
+   "  d);\n"
+   "endmodule");
+  verifyFormat("module test\n"
+   "(input signed [7 : 0] b, c, //\n"
+   "  d = 0);\n"
+   "endmodule");
+  verifyFormat("module test\n"
+   "(input wire logic signed [7 : 0][0 : 1] b, c, //\n"
+   "d);\n"
+   "endmodule");
+  verifyFormat("module test\n"
+   "(input signed [7 : 0] b, //\n"
+   "  c, //\n"
+   "  d);\n"
+   "endmodule");
+  verifyFormat("module test\n"
+   "(input [7 : 0] a,\n"
+   " input signed [7 : 0] b, //\n"
+   "  c, //\n"
+   "  d);\n"
+   "endmodule");
+  verifyFormat("module test\n"
+

  1   2   3   >