1 //==- SemanticHighlightingTests.cpp - SemanticHighlighting tests-*- C++ -* -==// 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 "Annotations.h" 10 #include "Config.h" 11 #include "Protocol.h" 12 #include "SemanticHighlighting.h" 13 #include "SourceCode.h" 14 #include "TestTU.h" 15 #include "llvm/ADT/ArrayRef.h" 16 #include "llvm/ADT/STLExtras.h" 17 #include "llvm/ADT/StringRef.h" 18 #include "llvm/Support/Error.h" 19 #include "llvm/Support/ScopedPrinter.h" 20 #include "llvm/Support/raw_ostream.h" 21 #include "gmock/gmock.h" 22 #include <algorithm> 23 24 namespace clang { 25 namespace clangd { 26 namespace { 27 28 using testing::IsEmpty; 29 using testing::SizeIs; 30 31 /// Annotates the input code with provided semantic highlightings. Results look 32 /// something like: 33 /// class $Class[[X]] { 34 /// $Primitive[[int]] $Field[[a]] = 0; 35 /// }; 36 std::string annotate(llvm::StringRef Input, 37 llvm::ArrayRef<HighlightingToken> Tokens) { 38 assert(llvm::is_sorted( 39 Tokens, [](const HighlightingToken &L, const HighlightingToken &R) { 40 return L.R.start < R.R.start; 41 })); 42 43 std::string Buf; 44 llvm::raw_string_ostream OS(Buf); 45 unsigned NextChar = 0; 46 for (auto &T : Tokens) { 47 unsigned StartOffset = llvm::cantFail(positionToOffset(Input, T.R.start)); 48 unsigned EndOffset = llvm::cantFail(positionToOffset(Input, T.R.end)); 49 assert(StartOffset <= EndOffset); 50 assert(NextChar <= StartOffset); 51 52 bool hasDef = 53 T.Modifiers & (1 << uint32_t(HighlightingModifier::Definition)); 54 bool hasDecl = 55 T.Modifiers & (1 << uint32_t(HighlightingModifier::Declaration)); 56 EXPECT_TRUE(!hasDef || hasDecl); 57 58 OS << Input.substr(NextChar, StartOffset - NextChar); 59 OS << '$' << T.Kind; 60 for (unsigned I = 0; 61 I <= static_cast<uint32_t>(HighlightingModifier::LastModifier); ++I) { 62 if (T.Modifiers & (1 << I)) { 63 // _decl_def is common and redundant, just print _def instead. 64 if (I != uint32_t(HighlightingModifier::Declaration) || !hasDef) 65 OS << '_' << static_cast<HighlightingModifier>(I); 66 } 67 } 68 OS << "[[" << Input.substr(StartOffset, EndOffset - StartOffset) << "]]"; 69 NextChar = EndOffset; 70 } 71 OS << Input.substr(NextChar); 72 return std::move(OS.str()); 73 } 74 75 void checkHighlightings(llvm::StringRef Code, 76 std::vector<std::pair</*FileName*/ llvm::StringRef, 77 /*FileContent*/ llvm::StringRef>> 78 AdditionalFiles = {}, 79 uint32_t ModifierMask = -1, 80 std::vector<std::string> AdditionalArgs = {}) { 81 Annotations Test(Code); 82 TestTU TU; 83 TU.Code = std::string(Test.code()); 84 85 TU.ExtraArgs.push_back("-std=c++20"); 86 TU.ExtraArgs.push_back("-xobjective-c++"); 87 TU.ExtraArgs.insert(std::end(TU.ExtraArgs), std::begin(AdditionalArgs), 88 std::end(AdditionalArgs)); 89 90 for (auto File : AdditionalFiles) 91 TU.AdditionalFiles.insert({File.first, std::string(File.second)}); 92 auto AST = TU.build(); 93 auto Actual = 94 getSemanticHighlightings(AST, /*IncludeInactiveRegionTokens=*/true); 95 for (auto &Token : Actual) 96 Token.Modifiers &= ModifierMask; 97 98 EXPECT_EQ(Code, annotate(Test.code(), Actual)); 99 } 100 101 constexpr static uint32_t ScopeModifierMask = 102 1 << unsigned(HighlightingModifier::FunctionScope) | 103 1 << unsigned(HighlightingModifier::ClassScope) | 104 1 << unsigned(HighlightingModifier::FileScope) | 105 1 << unsigned(HighlightingModifier::GlobalScope); 106 107 TEST(SemanticHighlighting, GetsCorrectTokens) { 108 const char *TestCases[] = { 109 R"cpp( 110 struct $Class_def[[AS]] { 111 double $Field_decl[[SomeMember]]; 112 }; 113 struct { 114 } $Variable_def[[S]]; 115 void $Function_def[[foo]](int $Parameter_def[[A]], $Class[[AS]] $Parameter_def[[As]]) { 116 $Primitive_deduced_defaultLibrary[[auto]] $LocalVariable_def[[VeryLongVariableName]] = 12312; 117 $Class[[AS]] $LocalVariable_def[[AA]]; 118 $Primitive_deduced_defaultLibrary[[auto]] $LocalVariable_def[[L]] = $LocalVariable[[AA]].$Field[[SomeMember]] $Operator[[+]] $Parameter[[A]]; 119 auto $LocalVariable_def[[FN]] = [ $LocalVariable[[AA]]](int $Parameter_def[[A]]) -> void {}; 120 $LocalVariable[[FN]]$Operator_userDefined[[(]]12312$Operator_userDefined[[)]]; 121 } 122 )cpp", 123 R"cpp( 124 void $Function_decl[[foo]](int); 125 void $Function_decl[[Gah]](); 126 void $Function_def[[foo]]() { 127 auto $LocalVariable_def[[Bou]] = $Function[[Gah]]; 128 } 129 struct $Class_def[[A]] { 130 void $Method_decl[[abc]](); 131 }; 132 )cpp", 133 R"cpp( 134 namespace $Namespace_decl[[abc]] { 135 template$Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] 136 struct $Class_def[[A]] { 137 $TemplateParameter[[T]] $Field_decl[[t]]; 138 }; 139 } 140 template$Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] 141 struct $Class_def[[C]] : $Namespace[[abc]]::$Class[[A]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]] { 142 typename $TemplateParameter[[T]]::$Type_dependentName[[A]]* $Field_decl[[D]]; 143 }; 144 $Namespace[[abc]]::$Class[[A]]$Bracket[[<]]int$Bracket[[>]] $Variable_def[[AA]]; 145 typedef $Namespace[[abc]]::$Class[[A]]$Bracket[[<]]int$Bracket[[>]] $Class_decl[[AAA]]; 146 struct $Class_def[[B]] { 147 $Class_decl_constrDestr[[B]](); 148 ~$Class_decl_constrDestr[[B]](); 149 void operator$Operator_decl[[<<]]($Class[[B]]); 150 $Class[[AAA]] $Field_decl[[AA]]; 151 }; 152 $Class[[B]]::$Class_def_constrDestr[[B]]() {} 153 $Class[[B]]::~$Class_def_constrDestr[[B]]() {} 154 void $Function_def[[f]] () { 155 $Class[[B]] $LocalVariable_def[[BB]] = $Class[[B]](); 156 $LocalVariable[[BB]].~$Class_constrDestr[[B]](); 157 $Class[[B]](); 158 } 159 )cpp", 160 R"cpp( 161 enum class $Enum_decl[[E]] { 162 $EnumConstant_decl_readonly[[A]], 163 $EnumConstant_decl_readonly[[B]], 164 }; 165 enum $Enum_decl[[EE]] { 166 $EnumConstant_decl_readonly[[Hi]], 167 }; 168 struct $Class_def[[A]] { 169 $Enum[[E]] $Field_decl[[EEE]]; 170 $Enum[[EE]] $Field_decl[[EEEE]]; 171 }; 172 int $Variable_def[[I]] = $EnumConstant_readonly[[Hi]]; 173 $Enum[[E]] $Variable_def[[L]] = $Enum[[E]]::$EnumConstant_readonly[[B]]; 174 )cpp", 175 R"cpp( 176 namespace $Namespace_decl[[abc]] { 177 namespace {} 178 namespace $Namespace_decl[[bcd]] { 179 struct $Class_def[[A]] {}; 180 namespace $Namespace_decl[[cde]] { 181 struct $Class_def[[A]] { 182 enum class $Enum_decl[[B]] { 183 $EnumConstant_decl_readonly[[Hi]], 184 }; 185 }; 186 } 187 } 188 } 189 using namespace $Namespace[[abc]]::$Namespace[[bcd]]; 190 namespace $Namespace_decl[[vwz]] = 191 $Namespace[[abc]]::$Namespace[[bcd]]::$Namespace[[cde]]; 192 $Namespace[[abc]]::$Namespace[[bcd]]::$Class[[A]] $Variable_def[[AA]]; 193 $Namespace[[vwz]]::$Class[[A]]::$Enum[[B]] $Variable_def[[AAA]] = 194 $Namespace[[vwz]]::$Class[[A]]::$Enum[[B]]::$EnumConstant_readonly[[Hi]]; 195 ::$Namespace[[vwz]]::$Class[[A]] $Variable_def[[B]]; 196 ::$Namespace[[abc]]::$Namespace[[bcd]]::$Class[[A]] $Variable_def[[BB]]; 197 )cpp", 198 R"cpp( 199 struct $Class_def[[D]] { 200 double $Field_decl[[C]]; 201 }; 202 struct $Class_def[[A]] { 203 double $Field_decl[[B]]; 204 $Class[[D]] $Field_decl[[E]]; 205 static double $StaticField_decl_static[[S]]; 206 static void $StaticMethod_def_static[[bar]]() {} 207 void $Method_def[[foo]]() { 208 $Field[[B]] $Operator[[=]] 123; 209 this->$Field[[B]] $Operator[[=]] 156; 210 this->$Method[[foo]](); 211 $Method[[foo]](); 212 $StaticMethod_static[[bar]](); 213 $StaticField_static[[S]] $Operator[[=]] 90.1; 214 } 215 }; 216 void $Function_def[[foo]]() { 217 $Class[[A]] $LocalVariable_def[[AA]]; 218 $LocalVariable[[AA]].$Field[[B]] $Operator[[+=]] 2; 219 $LocalVariable[[AA]].$Method[[foo]](); 220 $LocalVariable[[AA]].$Field[[E]].$Field[[C]]; 221 $Class[[A]]::$StaticField_static[[S]] $Operator[[=]] 90; 222 } 223 )cpp", 224 R"cpp( 225 struct $Class_def[[AA]] { 226 int $Field_decl[[A]]; 227 }; 228 int $Variable_def[[B]]; 229 $Class[[AA]] $Variable_def[[A]]{$Variable[[B]]}; 230 )cpp", 231 R"cpp( 232 namespace $Namespace_decl[[a]] { 233 struct $Class_def[[A]] {}; 234 typedef char $Primitive_decl[[C]]; 235 } 236 typedef $Namespace[[a]]::$Class[[A]] $Class_decl[[B]]; 237 using $Class_decl[[BB]] = $Namespace[[a]]::$Class[[A]]; 238 enum class $Enum_decl[[E]] {}; 239 typedef $Enum[[E]] $Enum_decl[[C]]; 240 typedef $Enum[[C]] $Enum_decl[[CC]]; 241 using $Enum_decl[[CD]] = $Enum[[CC]]; 242 $Enum[[CC]] $Function_decl[[f]]($Class[[B]]); 243 $Enum[[CD]] $Function_decl[[f]]($Class[[BB]]); 244 typedef $Namespace[[a]]::$Primitive[[C]] $Primitive_decl[[PC]]; 245 typedef float $Primitive_decl[[F]]; 246 )cpp", 247 R"cpp( 248 template$Bracket[[<]]typename $TemplateParameter_def[[T]], typename = void$Bracket[[>]] 249 class $Class_def[[A]] { 250 $TemplateParameter[[T]] $Field_decl[[AA]]; 251 $TemplateParameter[[T]] $Method_decl[[foo]](); 252 }; 253 template$Bracket[[<]]class $TemplateParameter_def[[TT]]$Bracket[[>]] 254 class $Class_def[[B]] { 255 $Class[[A]]$Bracket[[<]]$TemplateParameter[[TT]]$Bracket[[>]] $Field_decl[[AA]]; 256 }; 257 template$Bracket[[<]]class $TemplateParameter_def[[TT]], class $TemplateParameter_def[[GG]]$Bracket[[>]] 258 class $Class_def[[BB]] {}; 259 template$Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]] 260 class $Class_def[[BB]]$Bracket[[<]]$TemplateParameter[[T]], int$Bracket[[>]] {}; 261 template$Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]] 262 class $Class_def[[BB]]$Bracket[[<]]$TemplateParameter[[T]], $TemplateParameter[[T]]*$Bracket[[>]] {}; 263 264 template$Bracket[[<]]template$Bracket[[<]]class$Bracket[[>]] class $TemplateParameter_def[[T]], class $TemplateParameter_def[[C]]$Bracket[[>]] 265 $TemplateParameter[[T]]$Bracket[[<]]$TemplateParameter[[C]]$Bracket[[>]] $Function_decl[[f]](); 266 267 template$Bracket[[<]]typename$Bracket[[>]] 268 class $Class_def[[Foo]] {}; 269 270 template$Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] 271 void $Function_decl[[foo]]($TemplateParameter[[T]] ...); 272 )cpp", 273 R"cpp( 274 template $Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]] 275 struct $Class_def[[Tmpl]] {$TemplateParameter[[T]] $Field_decl[[x]] = 0;}; 276 extern template struct $Class_def[[Tmpl]]$Bracket[[<]]float$Bracket[[>]]; 277 template struct $Class_def[[Tmpl]]$Bracket[[<]]double$Bracket[[>]]; 278 )cpp", 279 // This test is to guard against highlightings disappearing when using 280 // conversion operators as their behaviour in the clang AST differ from 281 // other CXXMethodDecls. 282 R"cpp( 283 class $Class_def[[Foo]] {}; 284 struct $Class_def[[Bar]] { 285 explicit operator $Class[[Foo]]*() const; 286 explicit operator int() const; 287 operator $Class[[Foo]](); 288 }; 289 void $Function_def[[f]]() { 290 $Class[[Bar]] $LocalVariable_def[[B]]; 291 $Class[[Foo]] $LocalVariable_def[[F]] = $LocalVariable[[B]]; 292 $Class[[Foo]] *$LocalVariable_def[[FP]] = ($Class[[Foo]]*)$LocalVariable[[B]]; 293 int $LocalVariable_def[[I]] = (int)$LocalVariable[[B]]; 294 } 295 )cpp", 296 R"cpp( 297 struct $Class_def[[B]] {}; 298 struct $Class_def[[A]] { 299 $Class[[B]] $Field_decl[[BB]]; 300 $Class[[A]] &operator$Operator_decl[[=]]($Class[[A]] &&$Parameter_def[[O]]); 301 }; 302 303 $Class[[A]] &$Class[[A]]::operator$Operator_def[[=]]($Class[[A]] &&$Parameter_def[[O]]) = default; 304 )cpp", 305 R"cpp( 306 enum $Enum_decl[[En]] { 307 $EnumConstant_decl_readonly[[EC]], 308 }; 309 class $Class_def[[Foo]] {}; 310 class $Class_def[[Bar]] { 311 public: 312 $Class[[Foo]] $Field_decl[[Fo]]; 313 $Enum[[En]] $Field_decl[[E]]; 314 int $Field_decl[[I]]; 315 $Class_def_constrDestr[[Bar]] ($Class[[Foo]] $Parameter_def[[F]], 316 $Enum[[En]] $Parameter_def[[E]]) 317 : $Field[[Fo]] ($Parameter[[F]]), $Field[[E]] ($Parameter[[E]]), 318 $Field[[I]] (123) {} 319 }; 320 class $Class_def[[Bar2]] : public $Class[[Bar]] { 321 $Class_def_constrDestr[[Bar2]]() : $Class[[Bar]]($Class[[Foo]](), $EnumConstant_readonly[[EC]]) {} 322 }; 323 )cpp", 324 R"cpp( 325 enum $Enum_decl[[E]] { 326 $EnumConstant_decl_readonly[[E]], 327 }; 328 class $Class_def[[Foo]] {}; 329 $Enum_deduced[[auto]] $Variable_def[[AE]] = $Enum[[E]]::$EnumConstant_readonly[[E]]; 330 $Class_deduced[[auto]] $Variable_def[[AF]] = $Class[[Foo]](); 331 $Class_deduced[[decltype]](auto) $Variable_def[[AF2]] = $Class[[Foo]](); 332 $Class_deduced[[auto]] *$Variable_def[[AFP]] = $Operator[[&]]$Variable[[AF]]; 333 $Enum_deduced[[auto]] &$Variable_def[[AER]] = $Variable[[AE]]; 334 $Primitive_deduced_defaultLibrary[[auto]] $Variable_def[[Form]] = 10.2 $Operator[[+]] 2 $Operator[[*]] 4; 335 $Primitive_deduced_defaultLibrary[[decltype]]($Variable[[Form]]) $Variable_def[[F]] = 10; 336 auto $Variable_def[[Fun]] = []()->void{}; 337 )cpp", 338 R"cpp( 339 class $Class_def[[G]] {}; 340 template$Bracket[[<]]$Class[[G]] *$TemplateParameter_def_readonly[[U]]$Bracket[[>]] 341 class $Class_def[[GP]] {}; 342 template$Bracket[[<]]$Class[[G]] &$TemplateParameter_def_readonly[[U]]$Bracket[[>]] 343 class $Class_def[[GR]] {}; 344 template$Bracket[[<]]int *$TemplateParameter_def_readonly[[U]]$Bracket[[>]] 345 class $Class_def[[IP]] { 346 void $Method_def[[f]]() { 347 $Operator[[*]]$TemplateParameter_readonly[[U]] $Operator[[+=]] 5; 348 } 349 }; 350 template$Bracket[[<]]unsigned $TemplateParameter_def_readonly[[U]] = 2$Bracket[[>]] 351 class $Class_def[[Foo]] { 352 void $Method_def[[f]]() { 353 for(int $LocalVariable_def[[I]] = 0; 354 $LocalVariable[[I]] $Operator[[<]] $TemplateParameter_readonly[[U]];) {} 355 } 356 }; 357 358 $Class[[G]] $Variable_def[[L]]; 359 void $Function_def[[f]]() { 360 $Class[[Foo]]$Bracket[[<]]123$Bracket[[>]] $LocalVariable_def[[F]]; 361 $Class[[GP]]$Bracket[[<]]$Operator[[&]]$Variable[[L]]$Bracket[[>]] $LocalVariable_def[[LL]]; 362 $Class[[GR]]$Bracket[[<]]$Variable[[L]]$Bracket[[>]] $LocalVariable_def[[LLL]]; 363 } 364 )cpp", 365 R"cpp( 366 template$Bracket[[<]]typename $TemplateParameter_def[[T]], 367 void ($TemplateParameter[[T]]::*$TemplateParameter_def_readonly[[method]])(int)$Bracket[[>]] 368 struct $Class_def[[G]] { 369 void $Method_def[[foo]]( 370 $TemplateParameter[[T]] *$Parameter_def[[O]]) { 371 ($Parameter[[O]]$Operator_userDefined[[->*]]$TemplateParameter_readonly[[method]])(10); 372 373 } 374 }; 375 struct $Class_def[[F]] { 376 void $Method_decl[[f]](int); 377 }; 378 template$Bracket[[<]]void (*$TemplateParameter_def_readonly[[Func]])()$Bracket[[>]] 379 struct $Class_def[[A]] { 380 void $Method_def[[f]]() { 381 ($Operator[[*]]$TemplateParameter_readonly[[Func]])(); 382 } 383 }; 384 385 void $Function_def[[foo]]() { 386 $Class[[F]] $LocalVariable_def[[FF]]; 387 $Class[[G]]$Bracket[[<]]$Class[[F]], $Operator[[&]]$Class[[F]]::$Method[[f]]$Bracket[[>]] $LocalVariable_def[[GG]]; 388 $LocalVariable[[GG]].$Method[[foo]]($Operator[[&]]$LocalVariable_usedAsMutablePointer[[FF]]); 389 $Class[[A]]$Bracket[[<]]$Function[[foo]]$Bracket[[>]] $LocalVariable_def[[AA]]; 390 } 391 )cpp", 392 // Tokens that share a source range but have conflicting Kinds are not 393 // highlighted. 394 R"cpp( 395 #define $Macro_decl[[DEF_MULTIPLE]](X) namespace X { class X { int X; }; } 396 #define $Macro_decl[[DEF_CLASS]](T) class T {}; 397 // Preamble ends. 398 $Macro[[DEF_MULTIPLE]](XYZ); 399 $Macro[[DEF_MULTIPLE]](XYZW); 400 $Macro[[DEF_CLASS]]($Class_def[[A]]) 401 #define $Macro_decl[[MACRO_CONCAT]](X, V, T) T foo##X = V 402 #define $Macro_decl[[DEF_VAR]](X, V) int X = V 403 #define $Macro_decl[[DEF_VAR_T]](T, X, V) T X = V 404 #define $Macro_decl[[DEF_VAR_REV]](V, X) $Macro[[DEF_VAR]](X, V) 405 #define $Macro_decl[[CPY]](X) X 406 #define $Macro_decl[[DEF_VAR_TYPE]](X, Y) X Y 407 #define $Macro_decl[[SOME_NAME]] variable 408 #define $Macro_decl[[SOME_NAME_SET]] variable2 = 123 409 #define $Macro_decl[[INC_VAR]](X) X += 2 410 void $Function_def[[foo]]() { 411 $Macro[[DEF_VAR]]($LocalVariable_def[[X]], 123); 412 $Macro[[DEF_VAR_REV]](908, $LocalVariable_def[[XY]]); 413 int $Macro[[CPY]]( $LocalVariable_def[[XX]] ); 414 $Macro[[DEF_VAR_TYPE]]($Class[[A]], $LocalVariable_def[[AA]]); 415 double $Macro[[SOME_NAME]]; 416 int $Macro[[SOME_NAME_SET]]; 417 $LocalVariable[[variable]] $Operator[[=]] 20.1; 418 $Macro[[MACRO_CONCAT]](var, 2, float); 419 $Macro[[DEF_VAR_T]]($Class[[A]], $Macro[[CPY]]( 420 $Macro[[CPY]]($LocalVariable_def[[Nested]])), 421 $Macro[[CPY]]($Class[[A]]())); 422 $Macro[[INC_VAR]]($LocalVariable[[variable]]); 423 } 424 void $Macro[[SOME_NAME]](); 425 $Macro[[DEF_VAR]]($Variable_def[[MMMMM]], 567); 426 $Macro[[DEF_VAR_REV]](756, $Variable_def[[AB]]); 427 428 #define $Macro_decl[[CALL_FN]](F) F(); 429 #define $Macro_decl[[DEF_FN]](F) void F () 430 $Macro[[DEF_FN]]($Function_def[[g]]) { 431 $Macro[[CALL_FN]]($Function[[foo]]); 432 } 433 )cpp", 434 R"cpp( 435 #define $Macro_decl[[fail]](expr) expr 436 #define $Macro_decl[[assert]](COND) if (!(COND)) { $Macro[[fail]]("assertion failed" #COND); } 437 // Preamble ends. 438 int $Variable_def[[x]]; 439 int $Variable_def[[y]]; 440 int $Function_decl[[f]](); 441 void $Function_def[[foo]]() { 442 $Macro[[assert]]($Variable[[x]] $Operator[[!=]] $Variable[[y]]); 443 $Macro[[assert]]($Variable[[x]] $Operator[[!=]] $Function[[f]]()); 444 } 445 )cpp", 446 // highlighting all macro references 447 R"cpp( 448 #ifndef $Macro[[name]] 449 #define $Macro_decl[[name]] 450 #endif 451 452 #define $Macro_decl[[test]] 453 #undef $Macro[[test]] 454 #ifdef $Macro[[test]] 455 #endif 456 457 #if defined($Macro[[test]]) 458 #endif 459 )cpp", 460 R"cpp( 461 struct $Class_def[[S]] { 462 float $Field_decl[[Value]]; 463 $Class[[S]] *$Field_decl[[Next]]; 464 }; 465 $Class[[S]] $Variable_def[[Global]][2] = {$Class[[S]](), $Class[[S]]()}; 466 auto [$Variable_decl[[G1]], $Variable_decl[[G2]]] = $Variable[[Global]]; 467 void $Function_def[[f]]($Class[[S]] $Parameter_def[[P]]) { 468 int $LocalVariable_def[[A]][2] = {1,2}; 469 auto [$LocalVariable_decl[[B1]], $LocalVariable_decl[[B2]]] = $LocalVariable[[A]]; 470 auto [$LocalVariable_decl[[G1]], $LocalVariable_decl[[G2]]] = $Variable[[Global]]; 471 $Class_deduced[[auto]] [$LocalVariable_decl[[P1]], $LocalVariable_decl[[P2]]] = $Parameter[[P]]; 472 // Highlights references to BindingDecls. 473 $LocalVariable[[B1]]$Operator[[++]]; 474 } 475 )cpp", 476 R"cpp( 477 template$Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]] 478 class $Class_def[[A]] { 479 using $TemplateParameter_decl[[TemplateParam1]] = $TemplateParameter[[T]]; 480 typedef $TemplateParameter[[T]] $TemplateParameter_decl[[TemplateParam2]]; 481 using $Primitive_decl[[IntType]] = int; 482 483 using $Typedef_decl[[Pointer]] = $TemplateParameter[[T]] *; 484 using $Typedef_decl[[LVReference]] = $TemplateParameter[[T]] &; 485 using $Typedef_decl[[RVReference]] = $TemplateParameter[[T]]&&; 486 using $Typedef_decl[[Array]] = $TemplateParameter[[T]]*[3]; 487 using $Typedef_decl[[MemberPointer]] = int ($Class[[A]]::*)(int); 488 489 // Use various previously defined typedefs in a function type. 490 void $Method_decl[[func]]( 491 $Typedef[[Pointer]], $Typedef[[LVReference]], $Typedef[[RVReference]], 492 $Typedef[[Array]], $Typedef[[MemberPointer]]); 493 }; 494 )cpp", 495 R"cpp( 496 template $Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]] 497 void $Function_decl[[phase1]]($TemplateParameter[[T]]); 498 template $Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]] 499 void $Function_def[[foo]]($TemplateParameter[[T]] $Parameter_def[[P]]) { 500 $Function[[phase1]]($Parameter[[P]]); 501 $Unknown_dependentName[[phase2]]($Parameter[[P]]); 502 } 503 )cpp", 504 R"cpp( 505 class $Class_def[[A]] { 506 template $Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]] 507 void $Method_decl[[bar]]($TemplateParameter[[T]]); 508 }; 509 510 template $Bracket[[<]]class $TemplateParameter_def[[U]]$Bracket[[>]] 511 void $Function_def[[foo]]($TemplateParameter[[U]] $Parameter_def[[P]]) { 512 $Class[[A]]().$Method[[bar]]($Parameter[[P]]); 513 } 514 )cpp", 515 R"cpp( 516 struct $Class_def[[A]] { 517 template $Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]] 518 static void $StaticMethod_decl_static[[foo]]($TemplateParameter[[T]]); 519 }; 520 521 template $Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]] 522 struct $Class_def[[B]] { 523 void $Method_def[[bar]]() { 524 $Class[[A]]::$StaticMethod_static[[foo]]($TemplateParameter[[T]]()); 525 } 526 }; 527 )cpp", 528 R"cpp( 529 template $Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]] 530 void $Function_decl[[foo]](typename $TemplateParameter[[T]]::$Type_dependentName[[Type]] 531 = $TemplateParameter[[T]]::$Unknown_dependentName[[val]]); 532 )cpp", 533 R"cpp( 534 template $Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]] 535 void $Function_def[[foo]]($TemplateParameter[[T]] $Parameter_def[[P]]) { 536 $Parameter[[P]].$Unknown_dependentName[[Field]]; 537 } 538 )cpp", 539 R"cpp( 540 template $Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]] 541 class $Class_def[[A]] { 542 int $Method_def[[foo]]() { 543 return $TemplateParameter[[T]]::$Unknown_dependentName[[Field]]; 544 } 545 }; 546 )cpp", 547 // Highlighting the using decl as the underlying using shadow decl. 548 R"cpp( 549 void $Function_decl[[foo]](); 550 using ::$Function[[foo]]; 551 )cpp", 552 // Highlighting of template template arguments. 553 R"cpp( 554 template $Bracket[[<]]template $Bracket[[<]]class$Bracket[[>]] class $TemplateParameter_def[[TT]], 555 template $Bracket[[<]]class$Bracket[[>]] class ...$TemplateParameter_def[[TTs]]$Bracket[[>]] 556 struct $Class_def[[Foo]] { 557 $Class[[Foo]]$Bracket[[<]]$TemplateParameter[[TT]], $TemplateParameter[[TTs]]...$Bracket[[>]] 558 *$Field_decl[[t]]; 559 }; 560 )cpp", 561 // Inactive code highlighting 562 R"cpp( 563 // Code in the preamble. 564 // Inactive lines get an empty InactiveCode token at the beginning. 565 #ifdef $Macro[[test]] 566 $InactiveCode[[int Inactive1;]] 567 #endif 568 569 // A declaration to cause the preamble to end. 570 int $Variable_def[[EndPreamble]]; 571 572 // Code after the preamble. 573 // Code inside inactive blocks does not get regular highlightings 574 // because it's not part of the AST. 575 #define $Macro_decl[[test2]] 576 #if defined($Macro[[test]]) 577 $InactiveCode[[int Inactive2;]] 578 #elif defined($Macro[[test2]]) 579 int $Variable_def[[Active1]]; 580 #else 581 $InactiveCode[[int Inactive3;]] 582 #endif 583 584 #ifndef $Macro[[test]] 585 int $Variable_def[[Active2]]; 586 #endif 587 588 #ifdef $Macro[[test]] 589 $InactiveCode[[int Inactive4;]] 590 #else 591 int $Variable_def[[Active3]]; 592 #endif 593 )cpp", 594 // Argument to 'sizeof...' 595 R"cpp( 596 template $Bracket[[<]]typename... $TemplateParameter_def[[Elements]]$Bracket[[>]] 597 struct $Class_def[[TupleSize]] { 598 static const int $StaticField_decl_readonly_static[[size]] = 599 sizeof...($TemplateParameter[[Elements]]); 600 }; 601 )cpp", 602 // More dependent types 603 R"cpp( 604 template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] 605 struct $Class_def[[Waldo]] { 606 using $Typedef_decl[[Location1]] = typename $TemplateParameter[[T]] 607 ::$Type_dependentName[[Resolver]]::$Type_dependentName[[Location]]; 608 using $Typedef_decl[[Location2]] = typename $TemplateParameter[[T]] 609 ::template $Type_dependentName[[Resolver]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]] 610 ::$Type_dependentName[[Location]]; 611 using $Typedef_decl[[Location3]] = typename $TemplateParameter[[T]] 612 ::$Type_dependentName[[Resolver]] 613 ::template $Type_dependentName[[Location]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]]; 614 static const int $StaticField_decl_readonly_static[[Value]] = $TemplateParameter[[T]] 615 ::$Type_dependentName[[Resolver]]::$Unknown_dependentName[[Value]]; 616 }; 617 )cpp", 618 // Dependent name with heuristic target 619 R"cpp( 620 template $Bracket[[<]]typename$Bracket[[>]] 621 struct $Class_def[[Foo]] { 622 int $Field_decl[[Waldo]]; 623 void $Method_def[[bar]]() { 624 $Class[[Foo]]().$Field[[Waldo]]; 625 } 626 template $Bracket[[<]]typename $TemplateParameter_def[[U]]$Bracket[[>]] 627 void $Method_def[[bar1]]() { 628 $Class[[Foo]]$Bracket[[<]]$TemplateParameter[[U]]$Bracket[[>]]().$Field_dependentName[[Waldo]]; 629 } 630 631 void $Method_decl[[Overload]](); 632 void $Method_decl_readonly[[Overload]]() const; 633 }; 634 template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] 635 void $Function_def[[baz]]($Class[[Foo]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]] $Parameter_def[[o]]) { 636 $Parameter[[o]].$Method_readonly_dependentName[[Overload]](); 637 } 638 )cpp", 639 // Concepts 640 R"cpp( 641 template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] 642 concept $Concept_decl[[Fooable]] = 643 requires($TemplateParameter[[T]] $Parameter_def[[F]]) { 644 $Parameter[[F]].$Unknown_dependentName[[foo]](); 645 }; 646 template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] 647 requires $Concept[[Fooable]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]] 648 void $Function_def[[bar]]($TemplateParameter[[T]] $Parameter_def[[F]]) { 649 $Parameter[[F]].$Unknown_dependentName[[foo]](); 650 } 651 652 struct $Class_def[[F]] { 653 void $Method_def[[foo]]() {}; 654 }; 655 $Concept[[Fooable]] $Class_deduced[[auto]] $Variable_def[[f]] = $Class[[F]](); 656 657 void $Function_def[[Bar]]($Concept[[Fooable]] $TemplateParameter[[auto]] $Parameter_def[[x]]) {} 658 659 template$Bracket[[<]]$Concept[[Fooable]] auto $TemplateParameter_def_readonly[[x]]$Bracket[[>]] void $Function_def[[Boo]]() {} 660 bool $Variable_def[[b]] = $Concept[[Fooable]]$Bracket[[<]]int$Bracket[[>]]; 661 )cpp", 662 // Dependent template name 663 R"cpp( 664 template $Bracket[[<]]template $Bracket[[<]]typename$Bracket[[>]] class$Bracket[[>]] struct $Class_def[[A]] {}; 665 template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] 666 using $Typedef_decl[[W]] = $Class[[A]]$Bracket[[<]] 667 $TemplateParameter[[T]]::template $Class_dependentName[[Waldo]] 668 $Bracket[[>]]; 669 )cpp", 670 R"cpp( 671 class $Class_def_abstract[[Abstract]] { 672 public: 673 virtual void $Method_decl_abstract_virtual[[pure]]() = 0; 674 virtual void $Method_decl_virtual[[impl]](); 675 }; 676 void $Function_def[[foo]]($Class_abstract[[Abstract]]* $Parameter_def[[A]]) { 677 $Parameter[[A]]->$Method_abstract_virtual[[pure]](); 678 $Parameter[[A]]->$Method_virtual[[impl]](); 679 } 680 )cpp", 681 R"cpp( 682 <:[deprecated]:> int $Variable_def_deprecated[[x]]; 683 )cpp", 684 R"cpp( 685 // ObjC: Classes and methods 686 @class $Class_decl[[Forward]]; 687 688 @interface $Class_def[[Foo]] 689 @end 690 @interface $Class_def[[Bar]] : $Class[[Foo]] 691 -(id) $Method_decl[[x]]:(int)$Parameter_def[[a]] $Method_decl[[y]]:(int)$Parameter_def[[b]]; 692 +(instancetype)$StaticMethod_decl_static[[sharedInstance]]; 693 +(void) $StaticMethod_decl_static[[explode]]; 694 @end 695 @implementation $Class_def[[Bar]] 696 -(id) $Method_def[[x]]:(int)$Parameter_def[[a]] $Method_def[[y]]:(int)$Parameter_def[[b]] { 697 return self; 698 } 699 +(instancetype)$StaticMethod_def_static[[sharedInstance]] { return 0; } 700 +(void) $StaticMethod_def_static[[explode]] {} 701 @end 702 703 void $Function_def[[m]]($Class[[Bar]] *$Parameter_def[[b]]) { 704 [$Parameter[[b]] $Method[[x]]:1 $Method[[y]]:2]; 705 [$Class[[Bar]] $StaticMethod_static[[explode]]]; 706 } 707 )cpp", 708 R"cpp( 709 // ObjC: Protocols 710 @protocol $Interface_def[[Protocol]] 711 @end 712 @protocol $Interface_def[[Protocol2]] <$Interface[[Protocol]]> 713 @end 714 @interface $Class_def[[Klass]] <$Interface[[Protocol]]> 715 @end 716 id<$Interface[[Protocol]]> $Variable_def[[x]]; 717 )cpp", 718 R"cpp( 719 // ObjC: Categories 720 @interface $Class_def[[Foo]] 721 @end 722 @interface $Class[[Foo]]($Namespace_def[[Bar]]) 723 @end 724 @implementation $Class[[Foo]]($Namespace_def[[Bar]]) 725 @end 726 )cpp", 727 R"cpp( 728 // ObjC: Properties and Ivars. 729 @interface $Class_def[[Foo]] { 730 int $Field_decl[[_someProperty]]; 731 } 732 @property(nonatomic, assign) int $Field_decl[[someProperty]]; 733 @property(readonly, class) $Class[[Foo]] *$Field_decl_readonly_static[[sharedInstance]]; 734 @end 735 @implementation $Class_def[[Foo]] 736 @synthesize someProperty = _someProperty; 737 - (int)$Method_def[[otherMethod]] { 738 return 0; 739 } 740 - (int)$Method_def[[doSomething]] { 741 $Class[[Foo]].$Field_static[[sharedInstance]].$Field[[someProperty]] $Operator[[=]] 1; 742 self.$Field[[someProperty]] $Operator[[=]] self.$Field[[someProperty]] $Operator[[+]] self.$Field[[otherMethod]] $Operator[[+]] 1; 743 self->$Field[[_someProperty]] $Operator[[=]] $Field[[_someProperty]] $Operator[[+]] 1; 744 } 745 @end 746 )cpp", 747 // Member imported from dependent base 748 R"cpp( 749 template $Bracket[[<]]typename$Bracket[[>]] struct $Class_def[[Base]] { 750 int $Field_decl[[member]]; 751 }; 752 template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] 753 struct $Class_def[[Derived]] : $Class[[Base]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]] { 754 using $Class[[Base]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]]::$Field_dependentName[[member]]; 755 756 void $Method_def[[method]]() { 757 (void)$Field_dependentName[[member]]; 758 } 759 }; 760 )cpp", 761 // Modifier for variables passed as non-const references 762 R"cpp( 763 struct $Class_def[[ClassWithOp]] { 764 void operator$Operator_decl[[(]]$Operator_decl[[)]](int); 765 void operator$Operator_decl[[(]]$Operator_decl[[)]](int, int &); 766 void operator$Operator_decl[[(]]$Operator_decl[[)]](int, int, const int &); 767 int &operator$Operator_decl[[[]]$Operator_decl[[]]](int &); 768 int operator$Operator_decl[[[]]$Operator_decl[[]]](int) const; 769 }; 770 struct $Class_def[[ClassWithStaticMember]] { 771 static inline int $StaticField_def_static[[j]] = 0; 772 }; 773 struct $Class_def[[ClassWithRefMembers]] { 774 $Class_def_constrDestr[[ClassWithRefMembers]](int $Parameter_def[[i]]) 775 : $Field[[i1]]($Parameter[[i]]), 776 $Field_readonly[[i2]]($Parameter[[i]]), 777 $Field[[i3]]($Parameter_usedAsMutableReference[[i]]), 778 $Field_readonly[[i4]]($Class[[ClassWithStaticMember]]::$StaticField_static[[j]]), 779 $Field[[i5]]($Class[[ClassWithStaticMember]]::$StaticField_static_usedAsMutableReference[[j]]) 780 {} 781 int $Field_decl[[i1]]; 782 const int &$Field_decl_readonly[[i2]]; 783 int &$Field_decl[[i3]]; 784 const int &$Field_decl_readonly[[i4]]; 785 int &$Field_decl[[i5]]; 786 }; 787 void $Function_def[[fun]](int, const int, 788 int*, const int*, 789 int&, const int&, 790 int*&, const int*&, const int* const &, 791 int**, int**&, int** const &, 792 int = 123) { 793 int $LocalVariable_def[[val]]; 794 int* $LocalVariable_def[[ptr]]; 795 const int* $LocalVariable_def_readonly[[constPtr]]; 796 int** $LocalVariable_def[[array]]; 797 $Function[[fun]]($LocalVariable[[val]], $LocalVariable[[val]], 798 $LocalVariable_usedAsMutablePointer[[ptr]], $LocalVariable_readonly[[constPtr]], 799 $LocalVariable_usedAsMutableReference[[val]], $LocalVariable[[val]], 800 801 $LocalVariable_usedAsMutableReference[[ptr]], 802 $LocalVariable_readonly_usedAsMutableReference[[constPtr]], 803 $LocalVariable_readonly[[constPtr]], 804 805 $LocalVariable_usedAsMutablePointer[[array]], $LocalVariable_usedAsMutableReference[[array]], 806 $LocalVariable[[array]] 807 ); 808 [](int){}$Operator_userDefined[[(]]$LocalVariable[[val]]$Operator_userDefined[[)]]; 809 [](int&){}$Operator_userDefined[[(]]$LocalVariable_usedAsMutableReference[[val]]$Operator_userDefined[[)]]; 810 [](const int&){}$Operator_userDefined[[(]]$LocalVariable[[val]]$Operator_userDefined[[)]]; 811 $Class[[ClassWithOp]] $LocalVariable_def[[c]]; 812 const $Class[[ClassWithOp]] $LocalVariable_def_readonly[[c2]]; 813 $LocalVariable[[c]]$Operator_userDefined[[(]]$LocalVariable[[val]]$Operator_userDefined[[)]]; 814 $LocalVariable[[c]]$Operator_userDefined[[(]]0, $LocalVariable_usedAsMutableReference[[val]]$Operator_userDefined[[)]]; 815 $LocalVariable[[c]]$Operator_userDefined[[(]]0, 0, $LocalVariable[[val]]$Operator_userDefined[[)]]; 816 $LocalVariable[[c]]$Operator_userDefined[[[]]$LocalVariable_usedAsMutableReference[[val]]$Operator_userDefined[[]]]; 817 $LocalVariable_readonly[[c2]]$Operator_userDefined[[[]]$LocalVariable[[val]]$Operator_userDefined[[]]]; 818 } 819 struct $Class_def[[S]] { 820 $Class_def_constrDestr[[S]](int&) { 821 $Class[[S]] $LocalVariable_def[[s1]]($Field_usedAsMutableReference[[field]]); 822 $Class[[S]] $LocalVariable_def[[s2]]($LocalVariable[[s1]].$Field_usedAsMutableReference[[field]]); 823 824 $Class[[S]] $LocalVariable_def[[s3]]($StaticField_static_usedAsMutableReference[[staticField]]); 825 $Class[[S]] $LocalVariable_def[[s4]]($Class[[S]]::$StaticField_static_usedAsMutableReference[[staticField]]); 826 } 827 int $Field_decl[[field]]; 828 static int $StaticField_decl_static[[staticField]]; 829 }; 830 template $Bracket[[<]]typename $TemplateParameter_def[[X]]$Bracket[[>]] 831 void $Function_def[[foo]]($TemplateParameter[[X]]& $Parameter_def[[x]]) { 832 // We do not support dependent types, so this one should *not* get the modifier. 833 $Function[[foo]]($Parameter[[x]]); 834 } 835 )cpp", 836 // init-captures 837 R"cpp( 838 void $Function_def[[foo]]() { 839 int $LocalVariable_def[[a]], $LocalVariable_def[[b]]; 840 [ $LocalVariable_def[[c]] = $LocalVariable[[a]], 841 $LocalVariable_def[[d]]($LocalVariable[[b]]) ]() {}$Operator_userDefined[[(]]$Operator_userDefined[[)]]; 842 } 843 )cpp", 844 // Enum base specifier 845 R"cpp( 846 using $Primitive_decl[[MyTypedef]] = int; 847 enum $Enum_decl[[MyEnum]] : $Primitive[[MyTypedef]] {}; 848 )cpp", 849 // Enum base specifier 850 R"cpp( 851 typedef int $Primitive_decl[[MyTypedef]]; 852 enum $Enum_decl[[MyEnum]] : $Primitive[[MyTypedef]] {}; 853 )cpp", 854 // Using enum 855 R"cpp( 856 enum class $Enum_decl[[Color]] { $EnumConstant_decl_readonly[[Black]] }; 857 namespace $Namespace_decl[[ns]] { 858 using enum $Enum[[Color]]; 859 $Enum[[Color]] $Variable_def[[ModelT]] = $EnumConstant[[Black]]; 860 } 861 )cpp", 862 // Issue 1096 863 R"cpp( 864 void $Function_decl[[Foo]](); 865 // Use <: :> digraphs for deprecated attribute to avoid conflict with annotation syntax 866 <:<:deprecated:>:> void $Function_decl_deprecated[[Foo]](int* $Parameter_def[[x]]); 867 void $Function_decl[[Foo]](int $Parameter_def[[x]]); 868 template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] 869 void $Function_def[[Bar]]($TemplateParameter[[T]] $Parameter_def[[x]]) { 870 $Function_deprecated[[Foo]]($Parameter[[x]]); 871 $Function_deprecated[[Foo]]($Parameter[[x]]); 872 $Function_deprecated[[Foo]]($Parameter[[x]]); 873 } 874 )cpp", 875 // Predefined identifiers 876 R"cpp( 877 void $Function_def[[Foo]]() { 878 const char *$LocalVariable_def_readonly[[s]] = $LocalVariable_readonly_static[[__func__]]; 879 } 880 )cpp", 881 // override and final 882 R"cpp( 883 class $Class_def_abstract[[Base]] { virtual void $Method_decl_abstract_virtual[[m]]() = 0; }; 884 class $Class_def[[override]] : public $Class_abstract[[Base]] { void $Method_decl_virtual[[m]]() $Modifier[[override]]; }; 885 class $Class_def[[final]] : public $Class[[override]] { void $Method_decl_virtual[[m]]() $Modifier[[override]] $Modifier[[final]]; }; 886 )cpp", 887 // Issue 1222: readonly modifier for generic parameter 888 R"cpp( 889 template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] 890 auto $Function_def[[foo]](const $TemplateParameter[[T]] $Parameter_def_readonly[[template_type]], 891 const $TemplateParameter[[auto]] $Parameter_def_readonly[[auto_type]], 892 const int $Parameter_def_readonly[[explicit_type]]) { 893 return $Parameter_readonly[[template_type]] 894 $Operator_userDefined[[+]] $Parameter_readonly[[auto_type]] 895 $Operator_userDefined[[+]] $Parameter_readonly[[explicit_type]]; 896 } 897 )cpp", 898 // Explicit template specialization 899 R"cpp( 900 struct $Class_def[[Base]]{}; 901 template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] 902 struct $Class_def[[S]] : public $Class[[Base]] {}; 903 template $Bracket[[<]]$Bracket[[>]] 904 struct $Class_def[[S]]$Bracket[[<]]void$Bracket[[>]] : public $Class[[Base]] {}; 905 906 template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] 907 $TemplateParameter[[T]] $Variable_def[[x]] = {}; 908 template $Bracket[[<]]$Bracket[[>]] 909 int $Variable_def[[x]]$Bracket[[<]]int$Bracket[[>]] = (int)sizeof($Class[[Base]]); 910 )cpp", 911 // operator calls in template 912 R"cpp( 913 template$Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] class $Class_def[[C]] { 914 bool $Method_def[[compare]]($TemplateParameter[[T]] $Parameter_def[[t1]], $TemplateParameter[[T]] $Parameter_def[[t2]]) { return $Parameter[[t1]] $Operator_userDefined[[==]] $Parameter[[t2]]; } 915 $TemplateParameter[[T]] $Method_def[[deref]]($TemplateParameter[[T]] *$Parameter_def[[t]]) { return $Operator_userDefined[[*]]$Parameter[[t]]; } 916 }; 917 )cpp", 918 // new and delete 919 R"cpp( 920 struct $Class_def[[S]] { int *$Field_decl[[a]]; }; 921 void $Function_def[[f]]() { 922 $Class[[S]] *$LocalVariable_def[[s]] = $Operator[[new]] $Class[[S]]; 923 $LocalVariable[[s]]->$Field[[a]] $Operator[[=]] $Operator[[new]] int[10]; 924 $Operator[[delete]][] $LocalVariable[[s]]->$Field[[a]]; 925 $Operator[[delete]] $LocalVariable[[s]]; 926 } 927 )cpp", 928 // explicit operator invocation 929 R"cpp( 930 struct $Class_def[[S]] { 931 $Class[[S]] operator$Operator_decl[[+]](const $Class[[S]] &$Parameter_def_readonly[[other]]); 932 }; 933 void $Function_def[[f]]() { 934 $Class[[S]] $LocalVariable_def[[s]]; 935 $Class[[S]] $LocalVariable_def[[s2]] = $LocalVariable[[s]].operator$Operator_userDefined[[+]]($LocalVariable[[s]]); 936 } 937 )cpp", 938 R"cpp( 939 // Brackets support: C++ casts 940 void $Function_def[[f]]() { 941 struct $Class_def[[B]] { virtual ~$Class_decl_constrDestr[[B]](); }; 942 struct $Class_def[[D]] : public $Class[[B]] {}; 943 $Class[[B]] $LocalVariable_def[[b]]; 944 int $LocalVariable_def[[i]] = static_cast$Bracket[[<]]int$Bracket[[>]](3.5); 945 void *$LocalVariable_def[[p]] = reinterpret_cast$Bracket[[<]]void *$Bracket[[>]](0); 946 $Class[[D]] &$LocalVariable_def[[d]] = dynamic_cast$Bracket[[<]]$Class[[D]] &$Bracket[[>]]($LocalVariable[[b]]); 947 } 948 )cpp", 949 // Brackets support: Nested template instantiations. 950 R"cpp( 951 template$Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] struct $Class_def[[S]] {}; 952 void $Function_def[[f]]() { 953 $Class[[S]]$Bracket[[<]]$Class[[S]]$Bracket[[<]]int$Bracket[[>]]$Bracket[[>]] $LocalVariable_def[[s1]]; 954 $Class[[S]]$Bracket[[<]]$Class[[S]]$Bracket[[<]]int$Bracket[[>]]\ 955 $Bracket[[>]] $LocalVariable_def[[s2]]; 956 $Class[[S]]$Bracket[[<]]$Class[[S]]$Bracket[[<]]$Class[[S]]$Bracket[[<]]int$Bracket[[>]]$Bracket[[>]]$Bracket[[>]] $LocalVariable_def[[s3]]; 957 $Class[[S]]$Bracket[[<]]$Class[[S]]$Bracket[[<]]$Class[[S]]$Bracket[[<]]int$Bracket[[>]]\ 958 $Bracket[[>]]$Bracket[[>]] $LocalVariable_def[[s4]]; 959 $Class[[S]]$Bracket[[<]]$Class[[S]]$Bracket[[<]]$Class[[S]]$Bracket[[<]]int$Bracket[[>]]\ 960 $Bracket[[>]]$Bracket[[>]] $LocalVariable_def[[s5]]; 961 $Class[[S]]$Bracket[[<]]$Class[[S]]$Bracket[[<]]$Class[[S]]$Bracket[[<]]int$Bracket[[>]]\ 962 $Bracket[[>]]$Bracket[[>]] $LocalVariable_def[[s6]]; 963 $Class[[S]]$Bracket[[<]]$Class[[S]]$Bracket[[<]]$Class[[S]]$Bracket[[<]]int$Bracket[[>]]$Bracket[[>]]\ 964 $Bracket[[>]] $LocalVariable_def[[s7]]; 965 } 966 )cpp", 967 // Brackets support: One of the brackets is a macro. 968 R"cpp( 969 #define $Macro_decl[[LESS]] < 970 template $Macro[[LESS]] typename $TemplateParameter_def[[T]] > class $Class_def[[A]] {}; 971 )cpp", 972 // Brackets support: Specializations 973 R"cpp( 974 template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] class $Class_def[[S]] { 975 public: 976 template $Bracket[[<]]typename $TemplateParameter_def[[U]]$Bracket[[>]] class $Class_decl[[Nested]]; 977 }; 978 template $Bracket[[<]]$Bracket[[>]] class $Class_def[[S]]$Bracket[[<]]int$Bracket[[>]] {}; 979 template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] 980 class $Class_def[[S]]$Bracket[[<]]$TemplateParameter[[T]]*$Bracket[[>]] {}; 981 template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] 982 template $Bracket[[<]]typename $TemplateParameter_def[[U]]$Bracket[[>]] 983 class $Class[[S]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]]::$Class_def[[Nested]] {}; 984 template $Bracket[[<]]$Bracket[[>]] 985 template $Bracket[[<]]$Bracket[[>]] 986 class $Class[[S]]$Bracket[[<]]float$Bracket[[>]]::$Class_def[[Nested]]$Bracket[[<]]float$Bracket[[>]] {}; 987 template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] void $Function_decl[[foo]](); 988 void $Function_def[[bar]]() { 989 $Function[[foo]]$Bracket[[<]]int$Bracket[[>]](); 990 } 991 template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] constexpr int $Variable_def_readonly[[V]] = 42; 992 constexpr int $Variable_def_readonly[[Y]] = $Variable_readonly[[V]]$Bracket[[<]]char$Bracket[[>]]; 993 template $Bracket[[<]]$Bracket[[>]] 994 constexpr int $Variable_def_readonly[[V]]$Bracket[[<]]int$Bracket[[>]] = 5; 995 template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] 996 constexpr int $Variable_def_readonly[[V]]$Bracket[[<]]$TemplateParameter[[T]]*$Bracket[[>]] = 6; 997 template $Bracket[[<]]typename$Bracket[[>]] 998 class $Class_def[[A]] { 999 enum class $Enum_decl[[E]]; 1000 }; 1001 template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] 1002 enum class $Class[[A]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]]::$Enum_decl[[E]] {$EnumConstant_decl_readonly[[X]], $EnumConstant_decl_readonly[[Y]], $EnumConstant_decl_readonly[[Z]]}; 1003 template $Bracket[[<]]class $TemplateParameter_def[[T]]$Bracket[[>]] 1004 class $Class_def[[B]] { 1005 template $Bracket[[<]]class $TemplateParameter_def[[U]]$Bracket[[>]] void $Method_def[[foo]]($TemplateParameter[[U]]) { } 1006 template$Bracket[[<]]$Bracket[[>]] void $Method_def[[foo]]$Bracket[[<]]int$Bracket[[>]](int) { } 1007 friend void $Function_decl[[foo]]$Bracket[[<]]$Bracket[[>]]($TemplateParameter[[T]]); 1008 }; 1009 )cpp", 1010 // Brackets support: Function calls 1011 R"cpp( 1012 template $Bracket[[<]]typename$Bracket[[>]] void $Function_decl[[free]](); 1013 template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] 1014 struct $Class_def[[A]] { 1015 template $Bracket[[<]]typename$Bracket[[>]] void $Method_decl[[mem]](); 1016 }; 1017 void $Function_def[[foo]]() { 1018 $Class[[A]]$Bracket[[<]]int$Bracket[[>]] $LocalVariable_def[[a]]; 1019 $LocalVariable[[a]].$Method[[mem]]$Bracket[[<]]int$Bracket[[>]](); 1020 } 1021 template$Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] 1022 void $Function_def[[bar]]() { 1023 $Function[[free]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]](); 1024 $Class[[A]]$Bracket[[<]]int$Bracket[[>]] $LocalVariable_def[[a]]; 1025 $LocalVariable[[a]].$Method[[mem]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]](); 1026 $Class[[A]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]] $LocalVariable_def[[b]]; 1027 $LocalVariable[[b]].template $Method_dependentName[[mem]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]](); 1028 } 1029 )cpp", 1030 // Brackets support: Concepts 1031 R"cpp( 1032 template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] 1033 concept $Concept_decl[[C]] = true; 1034 template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] requires $Concept[[C]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]] 1035 class $Class_def[[Z]] {}; 1036 template $Bracket[[<]]typename, typename$Bracket[[>]] 1037 concept $Concept_decl[[C2]] = true; 1038 template $Bracket[[<]]$Concept[[C2]]$Bracket[[<]]int$Bracket[[>]] $TemplateParameter_def[[A]]$Bracket[[>]] 1039 class $Class_def[[B]] {}; 1040 )cpp", 1041 // Labels 1042 R"cpp( 1043 bool $Function_def[[funcWithGoto]](bool $Parameter_def[[b]]) { 1044 if ($Parameter[[b]]) 1045 goto $Label[[return_true]]; 1046 return false; 1047 $Label_decl[[return_true]]: 1048 return true; 1049 } 1050 )cpp", 1051 // no crash 1052 R"cpp( 1053 struct $Class_def[[Foo]] { 1054 void $Method_decl[[foo]](); 1055 }; 1056 1057 void $Function_def[[s]]($Class[[Foo]] $Parameter_def[[f]]) { 1058 auto $LocalVariable_def[[k]] = $Operator[[&]]$Class[[Foo]]::$Method[[foo]]; 1059 ($Parameter[[f]]$Operator[[.*]]$LocalVariable[[k]])(); // no crash on VisitCXXMemberCallExpr 1060 } 1061 )cpp", 1062 R"cpp( 1063 template$Bracket[[<]]typename$Bracket[[>]] 1064 class $Class_def[[Foo]] {}; 1065 1066 template$Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] 1067 void $Function_def[[k]]() { 1068 auto $LocalVariable_def[[s]] = $Operator[[new]] $Class[[Foo]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]](); 1069 $Operator[[delete]] $LocalVariable[[s]]; 1070 } 1071 )cpp", 1072 // Recursive UsingValueDecl 1073 R"cpp( 1074 template $Bracket[[<]]int$Bracket[[>]] class $Class_def[[X]] { 1075 template $Bracket[[<]]int$Bracket[[>]] class $Class_def[[Y]] { 1076 using $Class[[Y]]$Bracket[[<]]0$Bracket[[>]]::$Unknown_dependentName[[xxx]]; 1077 }; 1078 }; 1079 )cpp", 1080 // Heuristically resolved IndirectFieldDecl 1081 R"cpp( 1082 template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] 1083 struct $Class_def[[Base]] { 1084 struct { 1085 int $Field_decl[[waldo]]; 1086 }; 1087 }; 1088 template $Bracket[[<]]typename $TemplateParameter_def[[T]]$Bracket[[>]] 1089 struct $Class_def[[Derived]] : $Class[[Base]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]] { 1090 using $Class[[Base]]$Bracket[[<]]$TemplateParameter[[T]]$Bracket[[>]]::$Field_dependentName[[waldo]]; 1091 void $Method_def[[foo]]() { 1092 $Field_dependentName[[waldo]]; 1093 } 1094 }; 1095 )cpp", 1096 // Pointer-to-member with nested-name-specifiers 1097 R"cpp( 1098 struct $Class_def[[Outer]] { 1099 struct $Class_def[[Inner]] {}; 1100 }; 1101 using $Typedef_decl[[Alias]] = void ($Class[[Outer]]::$Class[[Inner]]:: *)(); 1102 )cpp"}; 1103 for (const auto &TestCase : TestCases) 1104 // Mask off scope modifiers to keep the tests manageable. 1105 // They're tested separately. 1106 checkHighlightings(TestCase, {}, ~ScopeModifierMask); 1107 1108 checkHighlightings(R"cpp( 1109 class $Class_def[[A]] { 1110 #include "imp.h" 1111 }; 1112 )cpp", 1113 {{"imp.h", R"cpp( 1114 int someMethod(); 1115 void otherMethod(); 1116 )cpp"}}, 1117 ~ScopeModifierMask); 1118 1119 // A separate test for macros in headers. 1120 checkHighlightings(R"cpp( 1121 #include "imp.h" 1122 $Macro[[DEFINE_Y]] 1123 $Macro[[DXYZ_Y]](A); 1124 )cpp", 1125 {{"imp.h", R"cpp( 1126 #define DXYZ(X) class X {}; 1127 #define DXYZ_Y(Y) DXYZ(x##Y) 1128 #define DEFINE(X) int X; 1129 #define DEFINE_Y DEFINE(Y) 1130 )cpp"}}, 1131 ~ScopeModifierMask); 1132 1133 checkHighlightings(R"cpp( 1134 #include "SYSObject.h" 1135 @interface $Class_defaultLibrary[[SYSObject]] ($Namespace_def[[UserCategory]]) 1136 @property(nonatomic, readonly) int $Field_decl_readonly[[user_property]]; 1137 @end 1138 int $Function_def[[somethingUsingSystemSymbols]]() { 1139 $Class_defaultLibrary[[SYSObject]] *$LocalVariable_def[[obj]] = [$Class_defaultLibrary[[SYSObject]] $StaticMethod_static_defaultLibrary[[new]]]; 1140 return $LocalVariable[[obj]].$Field_defaultLibrary[[value]] $Operator[[+]] $LocalVariable[[obj]].$Field_readonly[[user_property]]; 1141 } 1142 )cpp", 1143 {{"SystemSDK/SYSObject.h", R"cpp( 1144 @interface SYSObject 1145 @property(nonatomic, assign) int value; 1146 + (instancetype)new; 1147 @end 1148 )cpp"}}, 1149 ~ScopeModifierMask, {"-isystemSystemSDK/"}); 1150 } 1151 1152 TEST(SemanticHighlighting, ScopeModifiers) { 1153 const char *TestCases[] = { 1154 R"cpp( 1155 static int $Variable_fileScope[[x]]; 1156 namespace $Namespace_globalScope[[ns]] { 1157 class $Class_globalScope[[x]]; 1158 } 1159 namespace { 1160 void $Function_fileScope[[foo]](); 1161 } 1162 )cpp", 1163 R"cpp( 1164 void $Function_globalScope[[foo]](int $Parameter_functionScope[[y]]) { 1165 int $LocalVariable_functionScope[[z]]; 1166 } 1167 )cpp", 1168 R"cpp( 1169 // Lambdas are considered functions, not classes. 1170 auto $Variable_fileScope[[x]] = [$LocalVariable_functionScope[[m]](42)] { 1171 return $LocalVariable_functionScope[[m]]; 1172 }; 1173 )cpp", 1174 R"cpp( 1175 // Classes in functions are classes. 1176 void $Function_globalScope[[foo]]() { 1177 class $Class_functionScope[[X]] { 1178 int $Field_classScope[[x]]; 1179 }; 1180 }; 1181 )cpp", 1182 R"cpp( 1183 template $Bracket[[<]]int $TemplateParameter_classScope[[T]]$Bracket[[>]] 1184 class $Class_globalScope[[X]] { 1185 }; 1186 )cpp", 1187 R"cpp( 1188 // No useful scope for template parameters of variable templates. 1189 template $Bracket[[<]]typename $TemplateParameter[[A]]$Bracket[[>]] 1190 unsigned $Variable_globalScope[[X]] = 1191 $TemplateParameter[[A]]::$Unknown_classScope[[x]]; 1192 )cpp", 1193 R"cpp( 1194 #define $Macro_globalScope[[X]] 1 1195 int $Variable_globalScope[[Y]] = $Macro_globalScope[[X]]; 1196 )cpp", 1197 }; 1198 1199 for (const char *Test : TestCases) 1200 checkHighlightings(Test, {}, ScopeModifierMask); 1201 } 1202 1203 // Ranges are highlighted as variables, unless highlighted as $Function etc. 1204 std::vector<HighlightingToken> tokens(llvm::StringRef MarkedText) { 1205 Annotations A(MarkedText); 1206 std::vector<HighlightingToken> Results; 1207 for (const Range& R : A.ranges()) 1208 Results.push_back({HighlightingKind::Variable, 0, R}); 1209 for (unsigned I = 0; I < static_cast<unsigned>(HighlightingKind::LastKind); ++I) { 1210 HighlightingKind Kind = static_cast<HighlightingKind>(I); 1211 for (const Range& R : A.ranges(llvm::to_string(Kind))) 1212 Results.push_back({Kind, 0, R}); 1213 } 1214 llvm::sort(Results); 1215 return Results; 1216 } 1217 1218 TEST(SemanticHighlighting, toSemanticTokens) { 1219 auto Tokens = tokens(R"( 1220 [[blah]] 1221 1222 $Function[[big]] [[bang]] 1223 )"); 1224 Tokens.front().Modifiers |= unsigned(HighlightingModifier::Declaration); 1225 Tokens.front().Modifiers |= unsigned(HighlightingModifier::Readonly); 1226 auto Results = toSemanticTokens(Tokens, /*Code=*/""); 1227 1228 ASSERT_THAT(Results, SizeIs(3)); 1229 EXPECT_EQ(Results[0].tokenType, unsigned(HighlightingKind::Variable)); 1230 EXPECT_EQ(Results[0].tokenModifiers, 1231 unsigned(HighlightingModifier::Declaration) | 1232 unsigned(HighlightingModifier::Readonly)); 1233 EXPECT_EQ(Results[0].deltaLine, 1u); 1234 EXPECT_EQ(Results[0].deltaStart, 1u); 1235 EXPECT_EQ(Results[0].length, 4u); 1236 1237 EXPECT_EQ(Results[1].tokenType, unsigned(HighlightingKind::Function)); 1238 EXPECT_EQ(Results[1].tokenModifiers, 0u); 1239 EXPECT_EQ(Results[1].deltaLine, 2u); 1240 EXPECT_EQ(Results[1].deltaStart, 4u); 1241 EXPECT_EQ(Results[1].length, 3u); 1242 1243 EXPECT_EQ(Results[2].tokenType, unsigned(HighlightingKind::Variable)); 1244 EXPECT_EQ(Results[1].tokenModifiers, 0u); 1245 EXPECT_EQ(Results[2].deltaLine, 0u); 1246 EXPECT_EQ(Results[2].deltaStart, 4u); 1247 EXPECT_EQ(Results[2].length, 4u); 1248 } 1249 1250 TEST(SemanticHighlighting, diffSemanticTokens) { 1251 auto Before = toSemanticTokens(tokens(R"( 1252 [[foo]] [[bar]] [[baz]] 1253 [[one]] [[two]] [[three]] 1254 )"), 1255 /*Code=*/""); 1256 EXPECT_THAT(diffTokens(Before, Before), IsEmpty()); 1257 1258 auto After = toSemanticTokens(tokens(R"( 1259 [[foo]] [[hello]] [[world]] [[baz]] 1260 [[one]] [[two]] [[three]] 1261 )"), 1262 /*Code=*/""); 1263 1264 // Replace [bar, baz] with [hello, world, baz] 1265 auto Diff = diffTokens(Before, After); 1266 ASSERT_THAT(Diff, SizeIs(1)); 1267 EXPECT_EQ(1u, Diff.front().startToken); 1268 EXPECT_EQ(2u, Diff.front().deleteTokens); 1269 ASSERT_THAT(Diff.front().tokens, SizeIs(3)); 1270 // hello 1271 EXPECT_EQ(0u, Diff.front().tokens[0].deltaLine); 1272 EXPECT_EQ(4u, Diff.front().tokens[0].deltaStart); 1273 EXPECT_EQ(5u, Diff.front().tokens[0].length); 1274 // world 1275 EXPECT_EQ(0u, Diff.front().tokens[1].deltaLine); 1276 EXPECT_EQ(6u, Diff.front().tokens[1].deltaStart); 1277 EXPECT_EQ(5u, Diff.front().tokens[1].length); 1278 // baz 1279 EXPECT_EQ(0u, Diff.front().tokens[2].deltaLine); 1280 EXPECT_EQ(6u, Diff.front().tokens[2].deltaStart); 1281 EXPECT_EQ(3u, Diff.front().tokens[2].length); 1282 } 1283 1284 TEST(SemanticHighlighting, MultilineTokens) { 1285 llvm::StringRef AnnotatedCode = R"cpp( 1286 [[fo 1287 o 1288 o]] [[bar]])cpp"; 1289 auto Toks = toSemanticTokens(tokens(AnnotatedCode), 1290 Annotations(AnnotatedCode).code()); 1291 ASSERT_THAT(Toks, SizeIs(4)); 1292 // foo 1293 EXPECT_EQ(Toks[0].deltaLine, 1u); 1294 EXPECT_EQ(Toks[0].deltaStart, 2u); 1295 EXPECT_EQ(Toks[0].length, 2u); 1296 EXPECT_EQ(Toks[1].deltaLine, 1u); 1297 EXPECT_EQ(Toks[1].deltaStart, 0u); 1298 EXPECT_EQ(Toks[1].length, 1u); 1299 EXPECT_EQ(Toks[2].deltaLine, 1u); 1300 EXPECT_EQ(Toks[2].deltaStart, 0u); 1301 EXPECT_EQ(Toks[2].length, 1u); 1302 1303 // bar 1304 EXPECT_EQ(Toks[3].deltaLine, 0u); 1305 EXPECT_EQ(Toks[3].deltaStart, 2u); 1306 EXPECT_EQ(Toks[3].length, 3u); 1307 } 1308 1309 TEST(SemanticHighlighting, WithHighlightingFilter) { 1310 llvm::StringRef AnnotatedCode = R"cpp( 1311 int *$Variable[[x]] = new int; 1312 )cpp"; 1313 Config Cfg; 1314 Cfg.SemanticTokens.DisabledKinds = {"Operator"}; 1315 Cfg.SemanticTokens.DisabledModifiers = {"Declaration", "Definition"}; 1316 WithContextValue WithCfg(Config::Key, std::move(Cfg)); 1317 checkHighlightings(AnnotatedCode, {}, ~ScopeModifierMask); 1318 } 1319 } // namespace 1320 } // namespace clangd 1321 } // namespace clang 1322