Author: sstwcw
Date: 2026-05-31T20:56:39Z
New Revision: fae9a1c3e887d58f03994d078f117e1f29b1810c

URL: 
https://github.com/llvm/llvm-project/commit/fae9a1c3e887d58f03994d078f117e1f29b1810c
DIFF: 
https://github.com/llvm/llvm-project/commit/fae9a1c3e887d58f03994d078f117e1f29b1810c.diff

LOG: [clang-format] Recognize Verilog class item qualifiers (#199085)

old

```SystemVerilog
class Packet
  extern protected virtual function int send
      (int value);
  endclass : Packet
```

new

```SystemVerilog
class Packet
  extern protected virtual function int send
      (int value);
endclass : Packet
```

Previously the `extern` line failed to parse completely because the
`protected virtual` part was not recognized. It made the following lines
get indented wrong.

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h
index 7f6721a87877a..556bb0f3dd0af 100644
--- a/clang/lib/Format/FormatToken.h
+++ b/clang/lib/Format/FormatToken.h
@@ -1950,6 +1950,7 @@ struct AdditionalKeywords {
     case tok::kw_for:
     case tok::kw_if:
     case tok::kw_import:
+    case tok::kw_protected:
     case tok::kw_restrict:
     case tok::kw_signed:
     case tok::kw_static:

diff  --git a/clang/lib/Format/UnwrappedLineParser.cpp 
b/clang/lib/Format/UnwrappedLineParser.cpp
index 9536a233def58..39b7f566e2e6b 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -1456,6 +1456,7 @@ void UnwrappedLineParser::parseStructuralElement(
            Tokens->peekNextToken()->is(tok::star)) {
       parseParens();
     }
+    skipVerilogQualifiers();
     // Skip things that can exist before keywords like 'if' and 'case'.
     if (FormatTok->isOneOf(Keywords.kw_priority, Keywords.kw_unique,
                            Keywords.kw_unique0)) {
@@ -4603,8 +4604,7 @@ void UnwrappedLineParser::parseVerilogExtern() {
   // "DPI-C"
   if (FormatTok->is(tok::string_literal))
     nextToken();
-  if (FormatTok->isOneOf(Keywords.kw_context, Keywords.kw_pure))
-    nextToken();
+  skipVerilogQualifiers();
   if (Keywords.isVerilogIdentifier(*FormatTok))
     nextToken();
   if (FormatTok->is(tok::equal))
@@ -4613,6 +4613,15 @@ void UnwrappedLineParser::parseVerilogExtern() {
     parseVerilogHierarchyHeader();
 }
 
+void UnwrappedLineParser::skipVerilogQualifiers() {
+  while (FormatTok->isOneOf(tok::kw_protected, tok::kw_virtual, tok::kw_static,
+                            Keywords.kw_rand, Keywords.kw_context,
+                            Keywords.kw_pure, Keywords.kw_randc,
+                            Keywords.kw_local)) {
+    nextToken();
+  }
+}
+
 bool UnwrappedLineParser::containsExpansion(const UnwrappedLine &Line) const {
   for (const auto &N : Line.Tokens) {
     if (N.Tok->MacroCtx)

diff  --git a/clang/lib/Format/UnwrappedLineParser.h 
b/clang/lib/Format/UnwrappedLineParser.h
index 8181eec1495f7..cd92866756c5a 100644
--- a/clang/lib/Format/UnwrappedLineParser.h
+++ b/clang/lib/Format/UnwrappedLineParser.h
@@ -208,6 +208,8 @@ class UnwrappedLineParser {
   void parseVerilogCaseLabel();
   // For import, export, and extern.
   void parseVerilogExtern();
+  // Skip things that can precede the keywords like module.
+  void skipVerilogQualifiers();
   std::optional<llvm::SmallVector<llvm::SmallVector<FormatToken *, 8>, 1>>
   parseMacroCall();
 

diff  --git a/clang/unittests/Format/FormatTestVerilog.cpp 
b/clang/unittests/Format/FormatTestVerilog.cpp
index 66295b441d3ce..9b92d3e19204d 100644
--- a/clang/unittests/Format/FormatTestVerilog.cpp
+++ b/clang/unittests/Format/FormatTestVerilog.cpp
@@ -686,6 +686,9 @@ TEST_F(FormatTestVerilog, Hierarchy) {
                "x = x;");
   verifyFormat("export \"DPI-C\" function exported_sv_func;\n"
                "x = x;");
+  verifyFormat("extern protected virtual function int send\n"
+               "    (int value);\n"
+               "x = x;");
   verifyFormat("import \"DPI-C\" function void f1\n"
                "    (input int i1,\n"
                "     pair i2,\n"
@@ -719,6 +722,9 @@ TEST_F(FormatTestVerilog, Hierarchy) {
                "  generate\n"
                "  endgenerate\n"
                "endfunction : x");
+  verifyFormat("protected virtual function int x\n"
+               "    (int value);\n"
+               "endfunction");
   // Type names with '::' should be recognized.
   verifyFormat("function automatic x::x x\n"
                "    (input x);\n"


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to