[clang] [clang-format] Don't split "DPI"/"DPI-C" in Verilog imports (PR #66951)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 21 03:23:09 PDT 2023
================
@@ -2270,7 +2270,18 @@ ContinuationIndenter::createBreakableToken(const FormatToken &Current,
if (State.Stack.back().IsInsideObjCArrayLiteral)
return nullptr;
+ // The "DPI"/"DPI-C" in SystemVerilog direct programming interface imports
+ // cannot be split, e.g.
+ // `import "DPI" function foo();`
StringRef Text = Current.TokenText;
+ if (Style.isVerilog()) {
+ const FormatToken *Prev = Current.getPreviousNonComment();
+ if (Prev && Prev == State.Line->getFirstNonComment() &&
+ Prev->TokenText == "import") {
+ return nullptr;
+ }
+ }
+
----------------
alexfh wrote:
`isOneOf` won't work here, since the token has the type of `identifier` rather than a keyword:
```
Unwrapped lines:
Line(0, FSC=0): identifier[T=125, OC=0, "import"] string_literal[T=125, OC=7, ""DPI-C""] identifier[T=125, OC=15, "function"] identifier[T=125, OC=24, "t"] identifier[T=125, OC=26, "foo"]
Line(0, FSC=0): l_paren[T=120, OC=29, "("] r_paren[T=125, OC=30, ")"] semi[T=125, OC=31, ";"]
Line(1, FSC=0): eof[T=125, OC=32, ""]
Run 0...
AnnotatedTokens(L=0, P=0, T=5, C=0):
M=0 C=0 T=Unknown S=1 F=0 B=0 BK=0 P=0 Name=identifier L=6 PPK=2 FakeLParens= FakeRParens=0 II=0x56180dc60ce8 Text='import'
M=0 C=1 T=Unknown S=1 F=0 B=0 BK=0 P=23 Name=string_literal L=14 PPK=2 FakeLParens= FakeRParens=0 II=0x0 Text='"DPI-C"'
M=0 C=0 T=Unknown S=1 F=0 B=0 BK=1 P=23 Name=identifier L=23 PPK=2 FakeLParens= FakeRParens=0 II=0x56180dc611f8 Text='function'
M=0 C=0 T=Unknown S=1 F=0 B=0 BK=0 P=23 Name=identifier L=25 PPK=2 FakeLParens= FakeRParens=0 II=0x56180dc9b370 Text='t'
M=0 C=0 T=Unknown S=1 F=0 B=0 BK=0 P=23 Name=identifier L=29 PPK=2 FakeLParens= FakeRParens=0 II=0x56180dc9b3a0 Text='foo'
----
AnnotatedTokens(L=0, P=0, T=5, C=1):
M=0 C=0 T=VerilogMultiLineListLParen S=1 F=0 B=0 BK=0 P=0 Name=l_paren L=1 PPK=2 FakeLParens= FakeRParens=0 II=0x0 Text='('
M=0 C=0 T=Unknown S=0 F=0 B=0 BK=0 P=140 Name=r_paren L=2 PPK=2 FakeLParens= FakeRParens=0 II=0x0 Text=')'
M=0 C=0 T=Unknown S=0 F=0 B=0 BK=0 P=23 Name=semi L=3 PPK=2 FakeLParens= FakeRParens=0 II=0x0 Text=';'
----
AnnotatedTokens(L=1, P=0, T=5, C=0):
M=0 C=0 T=Unknown S=1 F=0 B=0 BK=0 P=0 Name=eof L=0 PPK=2 FakeLParens= FakeRParens=0 II=0x0 Text=''
----
```
We should leave `Current.getPreviousNonComment()` to handle comments in the middle of the statement (something like `import /*"DPI"*/ "DPI-C" ...` comes to mind).
> Shouldn't we handle export as well?
Indeed, `export "DPI-C"` is also a valid construct, and thus, string literals after `export` should be exempt from breaking too.
> I don't think this is Verilog specific.
I'd suggest to address known cases with targeted exemptions to avoid surprises in random places.
```
if (Style.isVerilog()) {
const FormatToken *Prev = Current.getPreviousNonComment();
if (Prev && Prev == State.Line->getFirstNonComment() &&
(Prev->TokenText == "import" || Prev->TokenText == "export")) {
return nullptr;
}
}
```
https://github.com/llvm/llvm-project/pull/66951
More information about the cfe-commits
mailing list