| 1 | //===- unittest/Format/FormatTestTableGen.cpp -----------------------------===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | #include "FormatTestUtils.h" |
| 10 | #include "clang/Format/Format.h" |
| 11 | #include "llvm/Support/Debug.h" |
| 12 | #include "gtest/gtest.h" |
| 13 | |
| 14 | #define DEBUG_TYPE "format-test" |
| 15 | |
| 16 | namespace clang { |
| 17 | namespace format { |
| 18 | |
| 19 | class FormatTestTableGen : public testing::Test { |
| 20 | protected: |
| 21 | static std::string format(StringRef Code, unsigned Offset, unsigned Length, |
| 22 | const FormatStyle &Style) { |
| 23 | LLVM_DEBUG(llvm::errs() << "---\n" ); |
| 24 | LLVM_DEBUG(llvm::errs() << Code << "\n\n" ); |
| 25 | std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length)); |
| 26 | tooling::Replacements Replaces = reformat(Style, Code, Ranges); |
| 27 | auto Result = applyAllReplacements(Code, Replaces); |
| 28 | EXPECT_TRUE(static_cast<bool>(Result)); |
| 29 | LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n" ); |
| 30 | return *Result; |
| 31 | } |
| 32 | |
| 33 | static std::string format(StringRef Code) { |
| 34 | FormatStyle Style = getGoogleStyle(Language: FormatStyle::LK_TableGen); |
| 35 | Style.ColumnLimit = 60; // To make writing tests easier. |
| 36 | return format(Code, Offset: 0, Length: Code.size(), Style); |
| 37 | } |
| 38 | |
| 39 | static void verifyFormat(StringRef Code) { |
| 40 | EXPECT_EQ(Code.str(), format(Code)) << "Expected code is not stable" ; |
| 41 | EXPECT_EQ(Code.str(), format(test::messUp(Code))); |
| 42 | } |
| 43 | |
| 44 | static void verifyFormat(StringRef Result, StringRef MessedUp) { |
| 45 | EXPECT_EQ(Result, format(MessedUp)); |
| 46 | } |
| 47 | |
| 48 | static void verifyFormat(StringRef Code, const FormatStyle &Style) { |
| 49 | EXPECT_EQ(Code.str(), format(Code, 0, Code.size(), Style)) |
| 50 | << "Expected code is not stable" ; |
| 51 | auto MessUp = test::messUp(Code); |
| 52 | EXPECT_EQ(Code.str(), format(MessUp, 0, MessUp.size(), Style)); |
| 53 | } |
| 54 | }; |
| 55 | |
| 56 | TEST_F(FormatTestTableGen, FormatStringBreak) { |
| 57 | verifyFormat(Code: "include \"OptParser.td\"\n" |
| 58 | "def flag : Flag<\"--foo\">,\n" |
| 59 | " HelpText<\n" |
| 60 | " \"This is a very, very, very, very, \"\n" |
| 61 | " \"very, very, very, very, very, very, \"\n" |
| 62 | " \"very long help string\">;" ); |
| 63 | } |
| 64 | |
| 65 | TEST_F(FormatTestTableGen, NoSpacesInSquareBracketLists) { |
| 66 | verifyFormat(Code: "def flag : Flag<[\"-\", \"--\"], \"foo\">;" ); |
| 67 | } |
| 68 | |
| 69 | TEST_F(FormatTestTableGen, LiteralsAndIdentifiers) { |
| 70 | verifyFormat(Code: "def LiteralAndIdentifiers {\n" |
| 71 | " let someInteger = -42;\n" |
| 72 | " let 0startID = $TokVarName;\n" |
| 73 | " let 0xstartInteger = 0x42;\n" |
| 74 | " let someIdentifier = $TokVarName;\n" |
| 75 | "}" ); |
| 76 | } |
| 77 | |
| 78 | TEST_F(FormatTestTableGen, BangOperators) { |
| 79 | verifyFormat(Code: "def BangOperators {\n" |
| 80 | " let IfOpe = !if(\n" |
| 81 | " !not(!and(!gt(!add(1, 2), !sub(3, 4)), !isa<Ty>($x))),\n" |
| 82 | " !foldl(0, !listconcat(!range(5, 6), !range(7, 8)),\n" |
| 83 | " total, rec, !add(total, rec.Number)),\n" |
| 84 | " !tail(!range(9, 10)));\n" |
| 85 | " let ForeachOpe = !foreach(\n" |
| 86 | " arg, arglist,\n" |
| 87 | " !if(!isa<SomeType>(arg.Type),\n" |
| 88 | " !add(!cast<SomeOtherType>(arg).Number, x), arg));\n" |
| 89 | " let CondOpe1 = !cond(!eq(size, 1): 1,\n" |
| 90 | " !eq(size, 2): 1,\n" |
| 91 | " !eq(size, 4): 1,\n" |
| 92 | " !eq(size, 8): 1,\n" |
| 93 | " !eq(size, 16): 1,\n" |
| 94 | " true: 0);\n" |
| 95 | " let CondOpe2 = !cond(!lt(x, 0): \"negativenegative\",\n" |
| 96 | " !eq(x, 0): \"zerozero\",\n" |
| 97 | " true: \"positivepositive\");\n" |
| 98 | " let CondOpe2WithComment = !cond(!lt(x, 0): // negative\n" |
| 99 | " \"negativenegative\",\n" |
| 100 | " !eq(x, 0): // zero\n" |
| 101 | " \"zerozero\",\n" |
| 102 | " true: // default\n" |
| 103 | " \"positivepositive\");\n" |
| 104 | " let CondOpe3WithCommentAfterLParen = !cond(\n" |
| 105 | " // comment\n" |
| 106 | " !eq(/* comment */ x, 0): \"zero\");\n" |
| 107 | "}" ); |
| 108 | } |
| 109 | |
| 110 | TEST_F(FormatTestTableGen, Include) { |
| 111 | verifyFormat(Code: "include \"test/IncludeFile.h\"" ); |
| 112 | } |
| 113 | |
| 114 | TEST_F(FormatTestTableGen, Types) { |
| 115 | verifyFormat(Code: "def Types : list<int>, bits<3>, list<list<string>> {}" ); |
| 116 | } |
| 117 | |
| 118 | TEST_F(FormatTestTableGen, SimpleValue1_SingleLiterals) { |
| 119 | verifyFormat(Code: "def SimpleValue {\n" |
| 120 | " let Integer = 42;\n" |
| 121 | " let String = \"some string\";\n" |
| 122 | "}" ); |
| 123 | } |
| 124 | |
| 125 | TEST_F(FormatTestTableGen, SimpleValue1_MultilineString) { |
| 126 | // test::messUp does not understand multiline TableGen code-literals. |
| 127 | // We have to give the result and the strings to format manually. |
| 128 | StringRef DefWithCode = |
| 129 | "def SimpleValueCode {\n" |
| 130 | " let Code =\n" |
| 131 | " [{ A TokCode is nothing more than a multi-line string literal " |
| 132 | "delimited by \\[{ and }\\]. It can break across lines and the line " |
| 133 | "breaks are retained in the string. \n" |
| 134 | "(https://llvm.org/docs/TableGen/ProgRef.html#grammar-token-TokCode)}];\n" |
| 135 | "}" ; |
| 136 | StringRef DefWithCodeMessedUp = |
| 137 | "def SimpleValueCode { let \n" |
| 138 | "Code= \n" |
| 139 | " [{ A TokCode is nothing more than a multi-line string " |
| 140 | "literal " |
| 141 | "delimited by \\[{ and }\\]. It can break across lines and the line " |
| 142 | "breaks are retained in the string. \n" |
| 143 | "(https://llvm.org/docs/TableGen/ProgRef.html#grammar-token-TokCode)}] \n" |
| 144 | " ; \n" |
| 145 | " } " ; |
| 146 | verifyFormat(Result: DefWithCode, MessedUp: DefWithCodeMessedUp); |
| 147 | } |
| 148 | |
| 149 | TEST_F(FormatTestTableGen, SimpleValue2) { |
| 150 | verifyFormat(Code: "def SimpleValue2 {\n" |
| 151 | " let True = true;\n" |
| 152 | " let False = false;\n" |
| 153 | "}" ); |
| 154 | } |
| 155 | |
| 156 | TEST_F(FormatTestTableGen, SimpleValue3) { |
| 157 | verifyFormat(Code: "class SimpleValue3<int x> { int Question = ?; }" ); |
| 158 | } |
| 159 | |
| 160 | TEST_F(FormatTestTableGen, SimpleValue4) { |
| 161 | verifyFormat(Code: "def SimpleValue4 { let ValueList = {1, 2, 3}; }" ); |
| 162 | } |
| 163 | |
| 164 | TEST_F(FormatTestTableGen, SimpleValue5) { |
| 165 | verifyFormat(Code: "def SimpleValue5 {\n" |
| 166 | " let SquareList = [1, 4, 9];\n" |
| 167 | " let SquareListWithType = [\"a\", \"b\", \"c\"]<string>;\n" |
| 168 | " let SquareListListWithType = [[1, 2], [3, 4, 5], [7]]<\n" |
| 169 | " list<int>>;\n" |
| 170 | " let SquareBitsListWithType = [ {1, 2},\n" |
| 171 | " {3, 4} ]<list<bits<8>>>;\n" |
| 172 | "}" ); |
| 173 | } |
| 174 | |
| 175 | TEST_F(FormatTestTableGen, SimpleValue6) { |
| 176 | verifyFormat(Code: "def SimpleValue6 {\n" |
| 177 | " let DAGArgIns = (ins i32:$src1, i32:$src2);\n" |
| 178 | " let DAGArgOuts = (outs i32:$dst1, i32:$dst2, i32:$dst3,\n" |
| 179 | " i32:$dst4, i32:$dst5, i32:$dst6, i32:$dst7);\n" |
| 180 | " let DAGArgOutsWithComment = (outs i32:$dst1, // dst1\n" |
| 181 | " i32:$dst2, // dst2\n" |
| 182 | " i32:$dst3, // dst3\n" |
| 183 | " i32:$dst4, // dst4\n" |
| 184 | " i32:$dst5, // dst5\n" |
| 185 | " i32:$dst6, // dst6\n" |
| 186 | " i32:$dst7 // dst7\n" |
| 187 | " );\n" |
| 188 | " let DAGArgBang = (!cast<SomeType>(\"Some\") i32:$src1,\n" |
| 189 | " i32:$src2);\n" |
| 190 | "}" ); |
| 191 | } |
| 192 | |
| 193 | TEST_F(FormatTestTableGen, SimpleValue7) { |
| 194 | verifyFormat(Code: "def SimpleValue7 { let Identifier = SimpleValue; }" ); |
| 195 | } |
| 196 | |
| 197 | TEST_F(FormatTestTableGen, SimpleValue8) { |
| 198 | verifyFormat(Code: "def SimpleValue8 { let Class = SimpleValue3<3>; }" ); |
| 199 | } |
| 200 | |
| 201 | TEST_F(FormatTestTableGen, ValueSuffix) { |
| 202 | verifyFormat(Code: "def SuffixedValues {\n" |
| 203 | " let Bit = value{17};\n" |
| 204 | " let Bits = value{8...15};\n" |
| 205 | " let List = value[1];\n" |
| 206 | " let Slice1 = value[1, ];\n" |
| 207 | " let Slice2 = value[4...7, 17, 2...3, 4];\n" |
| 208 | " let Field = value.field;\n" |
| 209 | "}" ); |
| 210 | } |
| 211 | |
| 212 | TEST_F(FormatTestTableGen, PasteOperator) { |
| 213 | verifyFormat(Code: "def Paste#\"Operator\" { string Paste = \"Paste\"#operator; }" ); |
| 214 | |
| 215 | verifyFormat(Code: "def [\"Traring\", \"Paste\"]# {\n" |
| 216 | " string X = Traring#;\n" |
| 217 | " string Y = List<\"Operator\">#;\n" |
| 218 | " string Z = [\"Traring\", \"Paste\", \"Traring\", \"Paste\",\n" |
| 219 | " \"Traring\", \"Paste\"]#;\n" |
| 220 | "}" ); |
| 221 | |
| 222 | verifyFormat(Result: "def x#x {}" , MessedUp: "def x\n" |
| 223 | "#x {}" ); |
| 224 | verifyFormat(Result: "def x#x {}" , MessedUp: "def x\n" |
| 225 | "#\n" |
| 226 | "x {}" ); |
| 227 | verifyFormat(Code: "def x#x" ); |
| 228 | } |
| 229 | |
| 230 | TEST_F(FormatTestTableGen, ClassDefinition) { |
| 231 | verifyFormat(Code: "class Class<int x, int y = 1, string z = \"z\", int w = -1>\n" |
| 232 | " : Parent1, Parent2<x, y> {\n" |
| 233 | " int Item1 = 1;\n" |
| 234 | " int Item2;\n" |
| 235 | " code Item3 = [{ Item3 }];\n" |
| 236 | " let Item4 = 4;\n" |
| 237 | " let Item5{1, 2} = 5;\n" |
| 238 | " defvar Item6 = 6;\n" |
| 239 | " let Item7 = ?;\n" |
| 240 | " assert !ge(x, 0), \"Assert7\";\n" |
| 241 | "}" ); |
| 242 | |
| 243 | verifyFormat(Code: "class FPFormat<bits<3> val> { bits<3> Value = val; }" ); |
| 244 | } |
| 245 | |
| 246 | TEST_F(FormatTestTableGen, Def) { |
| 247 | verifyFormat(Code: "def Def : Parent1<Def>, Parent2(defs Def) {\n" |
| 248 | " code Item1 = [{ Item1 }];\n" |
| 249 | " let Item2{1, 3...4} = {1, 2};\n" |
| 250 | " defvar Item3 = (ops nodty:$node1, nodty:$node2);\n" |
| 251 | " assert !le(Item2, 0), \"Assert4\";\n" |
| 252 | "}" ); |
| 253 | |
| 254 | verifyFormat(Code: "class FPFormat<bits<3> val> { bits<3> Value = val; }" ); |
| 255 | |
| 256 | verifyFormat(Code: "def NotFP : FPFormat<0>;" ); |
| 257 | } |
| 258 | |
| 259 | TEST_F(FormatTestTableGen, Let) { |
| 260 | verifyFormat(Code: "let x = 1, y = value<type>,\n" |
| 261 | " z = !and(!gt(!add(1, 2), !sub(3, 4)), !isa<Ty>($x)) in {\n" |
| 262 | " class Class1 : Parent<x, y> { let Item1 = z; }\n" |
| 263 | "}" ); |
| 264 | } |
| 265 | |
| 266 | TEST_F(FormatTestTableGen, MultiClass) { |
| 267 | verifyFormat(Code: "multiclass Multiclass<int x> {\n" |
| 268 | " def : Def1<(item type:$src1),\n" |
| 269 | " (!if(!ge(x, 0), !mul(!add(x, 1), !sub(x, 2)),\n" |
| 270 | " !sub(x, 2)))>;\n" |
| 271 | " def Def2 : value<type>;\n" |
| 272 | " def Def3 : type { let value = 1; }\n" |
| 273 | " defm : SomeMultiClass<Def1, Def2>;\n" |
| 274 | " defvar DefVar = 6;\n" |
| 275 | " foreach i = [1, 2, 3] in {\n" |
| 276 | " def : Foreach#i<(item type:$src1),\n" |
| 277 | " (!if(!gt(x, i),\n" |
| 278 | " !mul(!add(x, i), !sub(x, i)),\n" |
| 279 | " !sub(x, !add(i, 1))))>;\n" |
| 280 | " }\n" |
| 281 | " if !gt(x, 0) then {\n" |
| 282 | " def : IfThen<x>;\n" |
| 283 | " } else {\n" |
| 284 | " def : IfElse<x>;\n" |
| 285 | " }\n" |
| 286 | " if (dagid x, 0) then {\n" |
| 287 | " def : If2<1>;\n" |
| 288 | " }\n" |
| 289 | " let y = 1, z = 2 in {\n" |
| 290 | " multiclass Multiclass2<int x> {\n" |
| 291 | " foreach i = [1, 2, 3] in {\n" |
| 292 | " def : Foreach#i<(item type:$src1),\n" |
| 293 | " (!if(!gt(z, i),\n" |
| 294 | " !mul(!add(y, i), !sub(x, i)),\n" |
| 295 | " !sub(z, !add(i, 1))))>;\n" |
| 296 | " }\n" |
| 297 | " }\n" |
| 298 | " }\n" |
| 299 | "}" ); |
| 300 | } |
| 301 | |
| 302 | TEST_F(FormatTestTableGen, MultiClassesWithPasteOperator) { |
| 303 | // This is a sensitive example for the handling of the paste operators in |
| 304 | // brace type calculation. |
| 305 | verifyFormat(Code: "multiclass MultiClass1<int i> {\n" |
| 306 | " def : Def#x<i>;\n" |
| 307 | " def : Def#y<i>;\n" |
| 308 | "}\n" |
| 309 | "multiclass MultiClass2<int i> { def : Def#x<i>; }" ); |
| 310 | } |
| 311 | |
| 312 | TEST_F(FormatTestTableGen, Defm) { |
| 313 | verifyFormat(Code: "defm : Multiclass<0>;" ); |
| 314 | |
| 315 | verifyFormat(Code: "defm Defm1 : Multiclass<1>;" ); |
| 316 | } |
| 317 | |
| 318 | TEST_F(FormatTestTableGen, Defset) { |
| 319 | verifyFormat(Code: "defset list<Class> DefSet1 = {\n" |
| 320 | " def Def1 : Class<1>;\n" |
| 321 | " def Def2 : Class<2>;\n" |
| 322 | "}" ); |
| 323 | } |
| 324 | |
| 325 | TEST_F(FormatTestTableGen, Defvar) { |
| 326 | verifyFormat(Code: "defvar DefVar1 = !cond(!ge(!size(PaseOperator.Paste), 1): 1,\n" |
| 327 | " true: 0);" ); |
| 328 | } |
| 329 | |
| 330 | TEST_F(FormatTestTableGen, ForEach) { |
| 331 | verifyFormat( |
| 332 | Code: "foreach i = [1, 2, 3] in {\n" |
| 333 | " def : Foreach#i<(item type:$src1),\n" |
| 334 | " (!if(!lt(x, i),\n" |
| 335 | " !shl(!mul(x, i), !size(\"string\")),\n" |
| 336 | " !size(!strconcat(\"a\", \"b\", \"c\"))))>;\n" |
| 337 | "}" ); |
| 338 | } |
| 339 | |
| 340 | TEST_F(FormatTestTableGen, Dump) { verifyFormat(Code: "dump \"Dump\";" ); } |
| 341 | |
| 342 | TEST_F(FormatTestTableGen, If) { |
| 343 | verifyFormat(Code: "if !gt(x, 0) then {\n" |
| 344 | " def : IfThen<x>;\n" |
| 345 | "} else {\n" |
| 346 | " def : IfElse<x>;\n" |
| 347 | "}" ); |
| 348 | } |
| 349 | |
| 350 | TEST_F(FormatTestTableGen, Assert) { |
| 351 | verifyFormat(Code: "assert !le(DefVar1, 0), \"Assert1\";" ); |
| 352 | } |
| 353 | |
| 354 | TEST_F(FormatTestTableGen, DAGArgBreakElements) { |
| 355 | FormatStyle Style = getGoogleStyle(Language: FormatStyle::LK_TableGen); |
| 356 | Style.ColumnLimit = 60; |
| 357 | // By default, the DAGArg does not have a break inside. |
| 358 | ASSERT_EQ(Style.TableGenBreakInsideDAGArg, FormatStyle::DAS_DontBreak); |
| 359 | verifyFormat(Code: "def Def : Parent {\n" |
| 360 | " let dagarg = (ins a:$src1, aa:$src2, aaa:$src3)\n" |
| 361 | "}" , |
| 362 | Style); |
| 363 | // This option forces to break inside the DAGArg. |
| 364 | Style.TableGenBreakInsideDAGArg = FormatStyle::DAS_BreakElements; |
| 365 | verifyFormat(Code: "def Def : Parent {\n" |
| 366 | " let dagarg = (ins a:$src1,\n" |
| 367 | " aa:$src2,\n" |
| 368 | " aaa:$src3);\n" |
| 369 | "}" , |
| 370 | Style); |
| 371 | verifyFormat(Code: "def Def : Parent {\n" |
| 372 | " let dagarg = (other a:$src1,\n" |
| 373 | " aa:$src2,\n" |
| 374 | " aaa:$src3);\n" |
| 375 | "}" , |
| 376 | Style); |
| 377 | // Then, limit the DAGArg operator only to "ins". |
| 378 | Style.TableGenBreakingDAGArgOperators = {"ins" }; |
| 379 | verifyFormat(Code: "def Def : Parent {\n" |
| 380 | " let dagarg = (ins a:$src1,\n" |
| 381 | " aa:$src2,\n" |
| 382 | " aaa:$src3);\n" |
| 383 | "}" , |
| 384 | Style); |
| 385 | verifyFormat(Code: "def Def : Parent {\n" |
| 386 | " let dagarg = (other a:$src1, aa:$src2, aaa:$src3)\n" |
| 387 | "}" , |
| 388 | Style); |
| 389 | } |
| 390 | |
| 391 | TEST_F(FormatTestTableGen, DAGArgBreakAll) { |
| 392 | FormatStyle Style = getGoogleStyle(Language: FormatStyle::LK_TableGen); |
| 393 | Style.ColumnLimit = 60; |
| 394 | // By default, the DAGArg does not have a break inside. |
| 395 | verifyFormat(Code: "def Def : Parent {\n" |
| 396 | " let dagarg = (ins a:$src1, aa:$src2, aaa:$src3)\n" |
| 397 | "}" , |
| 398 | Style); |
| 399 | // This option forces to break inside the DAGArg. |
| 400 | Style.TableGenBreakInsideDAGArg = FormatStyle::DAS_BreakAll; |
| 401 | verifyFormat(Code: "def Def : Parent {\n" |
| 402 | " let dagarg = (ins\n" |
| 403 | " a:$src1,\n" |
| 404 | " aa:$src2,\n" |
| 405 | " aaa:$src3\n" |
| 406 | " );\n" |
| 407 | "}" , |
| 408 | Style); |
| 409 | verifyFormat(Code: "def Def : Parent {\n" |
| 410 | " let dagarg = (other\n" |
| 411 | " a:$src1,\n" |
| 412 | " aa:$src2,\n" |
| 413 | " aaa:$src3\n" |
| 414 | " );\n" |
| 415 | "}" , |
| 416 | Style); |
| 417 | // Then, limit the DAGArg operator only to "ins". |
| 418 | Style.TableGenBreakingDAGArgOperators = {"ins" }; |
| 419 | verifyFormat(Code: "def Def : Parent {\n" |
| 420 | " let dagarg = (ins\n" |
| 421 | " a:$src1,\n" |
| 422 | " aa:$src2,\n" |
| 423 | " aaa:$src3\n" |
| 424 | " );\n" |
| 425 | "}" , |
| 426 | Style); |
| 427 | verifyFormat(Code: "def Def : Parent {\n" |
| 428 | " let dagarg = (other a:$src1, aa:$src2, aaa:$src3);\n" |
| 429 | "}" , |
| 430 | Style); |
| 431 | } |
| 432 | |
| 433 | TEST_F(FormatTestTableGen, DAGArgAlignment) { |
| 434 | FormatStyle Style = getGoogleStyle(Language: FormatStyle::LK_TableGen); |
| 435 | Style.ColumnLimit = 60; |
| 436 | Style.TableGenBreakInsideDAGArg = FormatStyle::DAS_BreakAll; |
| 437 | Style.TableGenBreakingDAGArgOperators = {"ins" , "outs" }; |
| 438 | verifyFormat(Code: "def Def : Parent {\n" |
| 439 | " let dagarg = (ins\n" |
| 440 | " a:$src1,\n" |
| 441 | " aa:$src2,\n" |
| 442 | " aaa:$src3\n" |
| 443 | " )\n" |
| 444 | "}" , |
| 445 | Style); |
| 446 | verifyFormat(Code: "def Def : Parent {\n" |
| 447 | " let dagarg = (not a:$src1, aa:$src2, aaa:$src2)\n" |
| 448 | "}" , |
| 449 | Style); |
| 450 | Style.AlignConsecutiveTableGenBreakingDAGArgColons.Enabled = true; |
| 451 | verifyFormat(Code: "def Def : Parent {\n" |
| 452 | " let dagarg = (ins\n" |
| 453 | " a :$src1,\n" |
| 454 | " aa :$src2,\n" |
| 455 | " aaa:$src3\n" |
| 456 | " )\n" |
| 457 | "}" , |
| 458 | Style); |
| 459 | verifyFormat(Code: "def Def : Parent {\n" |
| 460 | " let dagarg = (not a:$src1, aa:$src2, aaa:$src2)\n" |
| 461 | "}" , |
| 462 | Style); |
| 463 | } |
| 464 | |
| 465 | TEST_F(FormatTestTableGen, CondOperatorAlignment) { |
| 466 | FormatStyle Style = getGoogleStyle(Language: FormatStyle::LK_TableGen); |
| 467 | Style.ColumnLimit = 60; |
| 468 | verifyFormat(Code: "let CondOpe1 = !cond(!eq(size, 1): 1,\n" |
| 469 | " !eq(size, 16): 1,\n" |
| 470 | " true: 0);" , |
| 471 | Style); |
| 472 | Style.AlignConsecutiveTableGenCondOperatorColons.Enabled = true; |
| 473 | verifyFormat(Code: "let CondOpe1 = !cond(!eq(size, 1) : 1,\n" |
| 474 | " !eq(size, 16): 1,\n" |
| 475 | " true : 0);" , |
| 476 | Style); |
| 477 | } |
| 478 | |
| 479 | TEST_F(FormatTestTableGen, DefAlignment) { |
| 480 | FormatStyle Style = getGoogleStyle(Language: FormatStyle::LK_TableGen); |
| 481 | Style.ColumnLimit = 60; |
| 482 | verifyFormat(Code: "def Def : Parent {}\n" |
| 483 | "def DefDef : Parent {}\n" |
| 484 | "def DefDefDef : Parent {}" , |
| 485 | Style); |
| 486 | Style.AlignConsecutiveTableGenDefinitionColons.Enabled = true; |
| 487 | verifyFormat(Code: "def Def : Parent {}\n" |
| 488 | "def DefDef : Parent {}\n" |
| 489 | "def DefDefDef : Parent {}" , |
| 490 | Style); |
| 491 | } |
| 492 | |
| 493 | } // namespace format |
| 494 | } // end namespace clang |
| 495 | |