clang-tools  15.0.0git
SemanticHighlightingTests.cpp
Go to the documentation of this file.
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 "Protocol.h"
11 #include "SemanticHighlighting.h"
12 #include "SourceCode.h"
13 #include "TestTU.h"
14 #include "llvm/ADT/ArrayRef.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/Support/Error.h"
18 #include "llvm/Support/ScopedPrinter.h"
19 #include "llvm/Support/raw_ostream.h"
20 #include "gmock/gmock.h"
21 #include <algorithm>
22 
23 namespace clang {
24 namespace clangd {
25 namespace {
26 
27 using testing::IsEmpty;
28 using testing::SizeIs;
29 
30 /// Annotates the input code with provided semantic highlightings. Results look
31 /// something like:
32 /// class $Class[[X]] {
33 /// $Primitive[[int]] $Field[[a]] = 0;
34 /// };
35 std::string annotate(llvm::StringRef Input,
36  llvm::ArrayRef<HighlightingToken> Tokens) {
37  assert(std::is_sorted(
38  Tokens.begin(), Tokens.end(),
39  [](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  OS << Input.substr(NextChar, StartOffset - NextChar);
53  OS << '$' << T.Kind;
54  for (unsigned I = 0;
55  I <= static_cast<uint32_t>(HighlightingModifier::LastModifier); ++I) {
56  if (T.Modifiers & (1 << I))
57  OS << '_' << static_cast<HighlightingModifier>(I);
58  }
59  OS << "[[" << Input.substr(StartOffset, EndOffset - StartOffset) << "]]";
60  NextChar = EndOffset;
61  }
62  OS << Input.substr(NextChar);
63  return std::move(OS.str());
64 }
65 
66 void checkHighlightings(llvm::StringRef Code,
67  std::vector<std::pair</*FileName*/ llvm::StringRef,
68  /*FileContent*/ llvm::StringRef>>
69  AdditionalFiles = {},
70  uint32_t ModifierMask = -1,
71  std::vector<std::string> AdditionalArgs = {}) {
72  Annotations Test(Code);
73  TestTU TU;
74  TU.Code = std::string(Test.code());
75 
76  TU.ExtraArgs.push_back("-std=c++20");
77  TU.ExtraArgs.push_back("-xobjective-c++");
78  TU.ExtraArgs.insert(std::end(TU.ExtraArgs), std::begin(AdditionalArgs),
79  std::end(AdditionalArgs));
80 
81  for (auto File : AdditionalFiles)
82  TU.AdditionalFiles.insert({File.first, std::string(File.second)});
83  auto AST = TU.build();
84  auto Actual = getSemanticHighlightings(AST);
85  for (auto &Token : Actual)
86  Token.Modifiers &= ModifierMask;
87 
88  EXPECT_EQ(Code, annotate(Test.code(), Actual));
89 }
90 
91 constexpr static uint32_t ScopeModifierMask =
93  1 << unsigned(HighlightingModifier::ClassScope) |
94  1 << unsigned(HighlightingModifier::FileScope) |
95  1 << unsigned(HighlightingModifier::GlobalScope);
96 
97 TEST(SemanticHighlighting, GetsCorrectTokens) {
98  const char *TestCases[] = {
99  R"cpp(
100  struct $Class_decl[[AS]] {
101  double $Field_decl[[SomeMember]];
102  };
103  struct {
104  } $Variable_decl[[S]];
105  void $Function_decl[[foo]](int $Parameter_decl[[A]], $Class[[AS]] $Parameter_decl[[As]]) {
106  $Primitive_deduced_defaultLibrary[[auto]] $LocalVariable_decl[[VeryLongVariableName]] = 12312;
107  $Class[[AS]] $LocalVariable_decl[[AA]];
108  $Primitive_deduced_defaultLibrary[[auto]] $LocalVariable_decl[[L]] = $LocalVariable[[AA]].$Field[[SomeMember]] + $Parameter[[A]];
109  auto $LocalVariable_decl[[FN]] = [ $LocalVariable[[AA]]](int $Parameter_decl[[A]]) -> void {};
110  $LocalVariable[[FN]](12312);
111  }
112  )cpp",
113  R"cpp(
114  void $Function_decl[[foo]](int);
115  void $Function_decl[[Gah]]();
116  void $Function_decl[[foo]]() {
117  auto $LocalVariable_decl[[Bou]] = $Function[[Gah]];
118  }
119  struct $Class_decl[[A]] {
120  void $Method_decl[[abc]]();
121  };
122  )cpp",
123  R"cpp(
124  namespace $Namespace_decl[[abc]] {
125  template<typename $TemplateParameter_decl[[T]]>
126  struct $Class_decl[[A]] {
127  $TemplateParameter[[T]] $Field_decl[[t]];
128  };
129  }
130  template<typename $TemplateParameter_decl[[T]]>
131  struct $Class_decl[[C]] : $Namespace[[abc]]::$Class[[A]]<$TemplateParameter[[T]]> {
132  typename $TemplateParameter[[T]]::$Type_dependentName[[A]]* $Field_decl[[D]];
133  };
134  $Namespace[[abc]]::$Class[[A]]<int> $Variable_decl[[AA]];
135  typedef $Namespace[[abc]]::$Class[[A]]<int> $Class_decl[[AAA]];
136  struct $Class_decl[[B]] {
137  $Class_decl[[B]]();
138  ~$Class[[B]](); // FIXME: inconsistent with constructor
139  void operator<<($Class[[B]]);
140  $Class[[AAA]] $Field_decl[[AA]];
141  };
142  $Class[[B]]::$Class_decl[[B]]() {}
143  $Class[[B]]::~$Class[[B]]() {} // FIXME: inconsistent with constructor
144  void $Function_decl[[f]] () {
145  $Class[[B]] $LocalVariable_decl[[BB]] = $Class[[B]]();
146  $LocalVariable[[BB]].~$Class[[B]]();
147  $Class[[B]]();
148  }
149  )cpp",
150  R"cpp(
151  enum class $Enum_decl[[E]] {
152  $EnumConstant_decl_readonly[[A]],
153  $EnumConstant_decl_readonly[[B]],
154  };
155  enum $Enum_decl[[EE]] {
156  $EnumConstant_decl_readonly[[Hi]],
157  };
158  struct $Class_decl[[A]] {
159  $Enum[[E]] $Field_decl[[EEE]];
160  $Enum[[EE]] $Field_decl[[EEEE]];
161  };
162  int $Variable_decl[[I]] = $EnumConstant_readonly[[Hi]];
163  $Enum[[E]] $Variable_decl[[L]] = $Enum[[E]]::$EnumConstant_readonly[[B]];
164  )cpp",
165  R"cpp(
166  namespace $Namespace_decl[[abc]] {
167  namespace {}
168  namespace $Namespace_decl[[bcd]] {
169  struct $Class_decl[[A]] {};
170  namespace $Namespace_decl[[cde]] {
171  struct $Class_decl[[A]] {
172  enum class $Enum_decl[[B]] {
173  $EnumConstant_decl_readonly[[Hi]],
174  };
175  };
176  }
177  }
178  }
179  using namespace $Namespace[[abc]]::$Namespace[[bcd]];
180  namespace $Namespace_decl[[vwz]] =
181  $Namespace[[abc]]::$Namespace[[bcd]]::$Namespace[[cde]];
182  $Namespace[[abc]]::$Namespace[[bcd]]::$Class[[A]] $Variable_decl[[AA]];
183  $Namespace[[vwz]]::$Class[[A]]::$Enum[[B]] $Variable_decl[[AAA]] =
184  $Namespace[[vwz]]::$Class[[A]]::$Enum[[B]]::$EnumConstant_readonly[[Hi]];
185  ::$Namespace[[vwz]]::$Class[[A]] $Variable_decl[[B]];
186  ::$Namespace[[abc]]::$Namespace[[bcd]]::$Class[[A]] $Variable_decl[[BB]];
187  )cpp",
188  R"cpp(
189  struct $Class_decl[[D]] {
190  double $Field_decl[[C]];
191  };
192  struct $Class_decl[[A]] {
193  double $Field_decl[[B]];
194  $Class[[D]] $Field_decl[[E]];
195  static double $StaticField_decl_static[[S]];
196  static void $StaticMethod_decl_static[[bar]]() {}
197  void $Method_decl[[foo]]() {
198  $Field[[B]] = 123;
199  this->$Field[[B]] = 156;
200  this->$Method[[foo]]();
201  $Method[[foo]]();
202  $StaticMethod_static[[bar]]();
203  $StaticField_static[[S]] = 90.1;
204  }
205  };
206  void $Function_decl[[foo]]() {
207  $Class[[A]] $LocalVariable_decl[[AA]];
208  $LocalVariable[[AA]].$Field[[B]] += 2;
209  $LocalVariable[[AA]].$Method[[foo]]();
210  $LocalVariable[[AA]].$Field[[E]].$Field[[C]];
211  $Class[[A]]::$StaticField_static[[S]] = 90;
212  }
213  )cpp",
214  R"cpp(
215  struct $Class_decl[[AA]] {
216  int $Field_decl[[A]];
217  };
218  int $Variable_decl[[B]];
219  $Class[[AA]] $Variable_decl[[A]]{$Variable[[B]]};
220  )cpp",
221  R"cpp(
222  namespace $Namespace_decl[[a]] {
223  struct $Class_decl[[A]] {};
224  typedef char $Primitive_decl[[C]];
225  }
226  typedef $Namespace[[a]]::$Class[[A]] $Class_decl[[B]];
227  using $Class_decl[[BB]] = $Namespace[[a]]::$Class[[A]];
228  enum class $Enum_decl[[E]] {};
229  typedef $Enum[[E]] $Enum_decl[[C]];
230  typedef $Enum[[C]] $Enum_decl[[CC]];
231  using $Enum_decl[[CD]] = $Enum[[CC]];
232  $Enum[[CC]] $Function_decl[[f]]($Class[[B]]);
233  $Enum[[CD]] $Function_decl[[f]]($Class[[BB]]);
234  typedef $Namespace[[a]]::$Primitive[[C]] $Primitive_decl[[PC]];
235  typedef float $Primitive_decl[[F]];
236  )cpp",
237  R"cpp(
238  template<typename $TemplateParameter_decl[[T]], typename = void>
239  class $Class_decl[[A]] {
240  $TemplateParameter[[T]] $Field_decl[[AA]];
241  $TemplateParameter[[T]] $Method_decl[[foo]]();
242  };
243  template<class $TemplateParameter_decl[[TT]]>
244  class $Class_decl[[B]] {
245  $Class[[A]]<$TemplateParameter[[TT]]> $Field_decl[[AA]];
246  };
247  template<class $TemplateParameter_decl[[TT]], class $TemplateParameter_decl[[GG]]>
248  class $Class_decl[[BB]] {};
249  template<class $TemplateParameter_decl[[T]]>
250  class $Class_decl[[BB]]<$TemplateParameter[[T]], int> {};
251  template<class $TemplateParameter_decl[[T]]>
252  class $Class_decl[[BB]]<$TemplateParameter[[T]], $TemplateParameter[[T]]*> {};
253 
254  template<template<class> class $TemplateParameter_decl[[T]], class $TemplateParameter_decl[[C]]>
255  $TemplateParameter[[T]]<$TemplateParameter[[C]]> $Function_decl[[f]]();
256 
257  template<typename>
258  class $Class_decl[[Foo]] {};
259 
260  template<typename $TemplateParameter_decl[[T]]>
261  void $Function_decl[[foo]]($TemplateParameter[[T]] ...);
262  )cpp",
263  R"cpp(
264  template <class $TemplateParameter_decl[[T]]>
265  struct $Class_decl[[Tmpl]] {$TemplateParameter[[T]] $Field_decl[[x]] = 0;};
266  extern template struct $Class_decl[[Tmpl]]<float>;
267  template struct $Class_decl[[Tmpl]]<double>;
268  )cpp",
269  // This test is to guard against highlightings disappearing when using
270  // conversion operators as their behaviour in the clang AST differ from
271  // other CXXMethodDecls.
272  R"cpp(
273  class $Class_decl[[Foo]] {};
274  struct $Class_decl[[Bar]] {
275  explicit operator $Class[[Foo]]*() const;
276  explicit operator int() const;
277  operator $Class[[Foo]]();
278  };
279  void $Function_decl[[f]]() {
280  $Class[[Bar]] $LocalVariable_decl[[B]];
281  $Class[[Foo]] $LocalVariable_decl[[F]] = $LocalVariable[[B]];
282  $Class[[Foo]] *$LocalVariable_decl[[FP]] = ($Class[[Foo]]*)$LocalVariable[[B]];
283  int $LocalVariable_decl[[I]] = (int)$LocalVariable[[B]];
284  }
285  )cpp",
286  R"cpp(
287  struct $Class_decl[[B]] {};
288  struct $Class_decl[[A]] {
289  $Class[[B]] $Field_decl[[BB]];
290  $Class[[A]] &operator=($Class[[A]] &&$Parameter_decl[[O]]);
291  };
292 
293  $Class[[A]] &$Class[[A]]::operator=($Class[[A]] &&$Parameter_decl[[O]]) = default;
294  )cpp",
295  R"cpp(
296  enum $Enum_decl[[En]] {
297  $EnumConstant_decl_readonly[[EC]],
298  };
299  class $Class_decl[[Foo]] {};
300  class $Class_decl[[Bar]] {
301  public:
302  $Class[[Foo]] $Field_decl[[Fo]];
303  $Enum[[En]] $Field_decl[[E]];
304  int $Field_decl[[I]];
305  $Class_decl[[Bar]] ($Class[[Foo]] $Parameter_decl[[F]],
306  $Enum[[En]] $Parameter_decl[[E]])
307  : $Field[[Fo]] ($Parameter[[F]]), $Field[[E]] ($Parameter[[E]]),
308  $Field[[I]] (123) {}
309  };
310  class $Class_decl[[Bar2]] : public $Class[[Bar]] {
311  $Class_decl[[Bar2]]() : $Class[[Bar]]($Class[[Foo]](), $EnumConstant_readonly[[EC]]) {}
312  };
313  )cpp",
314  R"cpp(
315  enum $Enum_decl[[E]] {
316  $EnumConstant_decl_readonly[[E]],
317  };
318  class $Class_decl[[Foo]] {};
319  $Enum_deduced[[auto]] $Variable_decl[[AE]] = $Enum[[E]]::$EnumConstant_readonly[[E]];
320  $Class_deduced[[auto]] $Variable_decl[[AF]] = $Class[[Foo]]();
321  $Class_deduced[[decltype]](auto) $Variable_decl[[AF2]] = $Class[[Foo]]();
322  $Class_deduced[[auto]] *$Variable_decl[[AFP]] = &$Variable[[AF]];
323  $Enum_deduced[[auto]] &$Variable_decl[[AER]] = $Variable[[AE]];
324  $Primitive_deduced_defaultLibrary[[auto]] $Variable_decl[[Form]] = 10.2 + 2 * 4;
325  $Primitive_deduced_defaultLibrary[[decltype]]($Variable[[Form]]) $Variable_decl[[F]] = 10;
326  auto $Variable_decl[[Fun]] = []()->void{};
327  )cpp",
328  R"cpp(
329  class $Class_decl[[G]] {};
330  template<$Class[[G]] *$TemplateParameter_decl_readonly[[U]]>
331  class $Class_decl[[GP]] {};
332  template<$Class[[G]] &$TemplateParameter_decl_readonly[[U]]>
333  class $Class_decl[[GR]] {};
334  template<int *$TemplateParameter_decl_readonly[[U]]>
335  class $Class_decl[[IP]] {
336  void $Method_decl[[f]]() {
337  *$TemplateParameter_readonly[[U]] += 5;
338  }
339  };
340  template<unsigned $TemplateParameter_decl_readonly[[U]] = 2>
341  class $Class_decl[[Foo]] {
342  void $Method_decl[[f]]() {
343  for(int $LocalVariable_decl[[I]] = 0;
344  $LocalVariable[[I]] < $TemplateParameter_readonly[[U]];) {}
345  }
346  };
347 
348  $Class[[G]] $Variable_decl[[L]];
349  void $Function_decl[[f]]() {
350  $Class[[Foo]]<123> $LocalVariable_decl[[F]];
351  $Class[[GP]]<&$Variable[[L]]> $LocalVariable_decl[[LL]];
352  $Class[[GR]]<$Variable[[L]]> $LocalVariable_decl[[LLL]];
353  }
354  )cpp",
355  R"cpp(
356  template<typename $TemplateParameter_decl[[T]],
357  void ($TemplateParameter[[T]]::*$TemplateParameter_decl_readonly[[method]])(int)>
358  struct $Class_decl[[G]] {
359  void $Method_decl[[foo]](
360  $TemplateParameter[[T]] *$Parameter_decl[[O]]) {
361  ($Parameter[[O]]->*$TemplateParameter_readonly[[method]])(10);
362  }
363  };
364  struct $Class_decl[[F]] {
365  void $Method_decl[[f]](int);
366  };
367  template<void (*$TemplateParameter_decl_readonly[[Func]])()>
368  struct $Class_decl[[A]] {
369  void $Method_decl[[f]]() {
370  (*$TemplateParameter_readonly[[Func]])();
371  }
372  };
373 
374  void $Function_decl[[foo]]() {
375  $Class[[F]] $LocalVariable_decl[[FF]];
376  $Class[[G]]<$Class[[F]], &$Class[[F]]::$Method[[f]]> $LocalVariable_decl[[GG]];
377  $LocalVariable[[GG]].$Method[[foo]](&$LocalVariable[[FF]]);
378  $Class[[A]]<$Function[[foo]]> $LocalVariable_decl[[AA]];
379  }
380  )cpp",
381  // Tokens that share a source range but have conflicting Kinds are not
382  // highlighted.
383  R"cpp(
384  #define $Macro_decl[[DEF_MULTIPLE]](X) namespace X { class X { int X; }; }
385  #define $Macro_decl[[DEF_CLASS]](T) class T {};
386  // Preamble ends.
387  $Macro[[DEF_MULTIPLE]](XYZ);
388  $Macro[[DEF_MULTIPLE]](XYZW);
389  $Macro[[DEF_CLASS]]($Class_decl[[A]])
390  #define $Macro_decl[[MACRO_CONCAT]](X, V, T) T foo##X = V
391  #define $Macro_decl[[DEF_VAR]](X, V) int X = V
392  #define $Macro_decl[[DEF_VAR_T]](T, X, V) T X = V
393  #define $Macro_decl[[DEF_VAR_REV]](V, X) DEF_VAR(X, V)
394  #define $Macro_decl[[CPY]](X) X
395  #define $Macro_decl[[DEF_VAR_TYPE]](X, Y) X Y
396  #define $Macro_decl[[SOME_NAME]] variable
397  #define $Macro_decl[[SOME_NAME_SET]] variable2 = 123
398  #define $Macro_decl[[INC_VAR]](X) X += 2
399  void $Function_decl[[foo]]() {
400  $Macro[[DEF_VAR]]($LocalVariable_decl[[X]], 123);
401  $Macro[[DEF_VAR_REV]](908, $LocalVariable_decl[[XY]]);
402  int $Macro[[CPY]]( $LocalVariable_decl[[XX]] );
403  $Macro[[DEF_VAR_TYPE]]($Class[[A]], $LocalVariable_decl[[AA]]);
404  double $Macro[[SOME_NAME]];
405  int $Macro[[SOME_NAME_SET]];
406  $LocalVariable[[variable]] = 20.1;
407  $Macro[[MACRO_CONCAT]](var, 2, float);
408  $Macro[[DEF_VAR_T]]($Class[[A]], $Macro[[CPY]](
409  $Macro[[CPY]]($LocalVariable_decl[[Nested]])),
410  $Macro[[CPY]]($Class[[A]]()));
411  $Macro[[INC_VAR]]($LocalVariable[[variable]]);
412  }
413  void $Macro[[SOME_NAME]]();
414  $Macro[[DEF_VAR]]($Variable_decl[[MMMMM]], 567);
415  $Macro[[DEF_VAR_REV]](756, $Variable_decl[[AB]]);
416 
417  #define $Macro_decl[[CALL_FN]](F) F();
418  #define $Macro_decl[[DEF_FN]](F) void F ()
419  $Macro[[DEF_FN]]($Function_decl[[g]]) {
420  $Macro[[CALL_FN]]($Function[[foo]]);
421  }
422  )cpp",
423  R"cpp(
424  #define $Macro_decl[[fail]](expr) expr
425  #define $Macro_decl[[assert]](COND) if (!(COND)) { fail("assertion failed" #COND); }
426  // Preamble ends.
427  int $Variable_decl[[x]];
428  int $Variable_decl[[y]];
429  int $Function_decl[[f]]();
430  void $Function_decl[[foo]]() {
431  $Macro[[assert]]($Variable[[x]] != $Variable[[y]]);
432  $Macro[[assert]]($Variable[[x]] != $Function[[f]]());
433  }
434  )cpp",
435  // highlighting all macro references
436  R"cpp(
437  #ifndef $Macro[[name]]
438  #define $Macro_decl[[name]]
439  #endif
440 
441  #define $Macro_decl[[test]]
442  #undef $Macro[[test]]
443 $InactiveCode[[#ifdef test]]
444 $InactiveCode[[#endif]]
445 
446 $InactiveCode[[#if defined(test)]]
447 $InactiveCode[[#endif]]
448  )cpp",
449  R"cpp(
450  struct $Class_decl[[S]] {
451  float $Field_decl[[Value]];
452  $Class[[S]] *$Field_decl[[Next]];
453  };
454  $Class[[S]] $Variable_decl[[Global]][2] = {$Class[[S]](), $Class[[S]]()};
455  auto [$Variable_decl[[G1]], $Variable_decl[[G2]]] = $Variable[[Global]];
456  void $Function_decl[[f]]($Class[[S]] $Parameter_decl[[P]]) {
457  int $LocalVariable_decl[[A]][2] = {1,2};
458  auto [$LocalVariable_decl[[B1]], $LocalVariable_decl[[B2]]] = $LocalVariable[[A]];
459  auto [$LocalVariable_decl[[G1]], $LocalVariable_decl[[G2]]] = $Variable[[Global]];
460  $Class_deduced[[auto]] [$LocalVariable_decl[[P1]], $LocalVariable_decl[[P2]]] = $Parameter[[P]];
461  // Highlights references to BindingDecls.
462  $LocalVariable[[B1]]++;
463  }
464  )cpp",
465  R"cpp(
466  template<class $TemplateParameter_decl[[T]]>
467  class $Class_decl[[A]] {
468  using $TemplateParameter_decl[[TemplateParam1]] = $TemplateParameter[[T]];
469  typedef $TemplateParameter[[T]] $TemplateParameter_decl[[TemplateParam2]];
470  using $Primitive_decl[[IntType]] = int;
471 
472  using $Typedef_decl[[Pointer]] = $TemplateParameter[[T]] *;
473  using $Typedef_decl[[LVReference]] = $TemplateParameter[[T]] &;
474  using $Typedef_decl[[RVReference]] = $TemplateParameter[[T]]&&;
475  using $Typedef_decl[[Array]] = $TemplateParameter[[T]]*[3];
476  using $Typedef_decl[[MemberPointer]] = int ($Class[[A]]::*)(int);
477 
478  // Use various previously defined typedefs in a function type.
479  void $Method_decl[[func]](
480  $Typedef[[Pointer]], $Typedef[[LVReference]], $Typedef[[RVReference]],
481  $Typedef[[Array]], $Typedef[[MemberPointer]]);
482  };
483  )cpp",
484  R"cpp(
485  template <class $TemplateParameter_decl[[T]]>
486  void $Function_decl[[phase1]]($TemplateParameter[[T]]);
487  template <class $TemplateParameter_decl[[T]]>
488  void $Function_decl[[foo]]($TemplateParameter[[T]] $Parameter_decl[[P]]) {
489  $Function[[phase1]]($Parameter[[P]]);
490  $Unknown_dependentName[[phase2]]($Parameter[[P]]);
491  }
492  )cpp",
493  R"cpp(
494  class $Class_decl[[A]] {
495  template <class $TemplateParameter_decl[[T]]>
496  void $Method_decl[[bar]]($TemplateParameter[[T]]);
497  };
498 
499  template <class $TemplateParameter_decl[[U]]>
500  void $Function_decl[[foo]]($TemplateParameter[[U]] $Parameter_decl[[P]]) {
501  $Class[[A]]().$Method[[bar]]($Parameter[[P]]);
502  }
503  )cpp",
504  R"cpp(
505  struct $Class_decl[[A]] {
506  template <class $TemplateParameter_decl[[T]]>
507  static void $StaticMethod_decl_static[[foo]]($TemplateParameter[[T]]);
508  };
509 
510  template <class $TemplateParameter_decl[[T]]>
511  struct $Class_decl[[B]] {
512  void $Method_decl[[bar]]() {
513  $Class[[A]]::$StaticMethod_static[[foo]]($TemplateParameter[[T]]());
514  }
515  };
516  )cpp",
517  R"cpp(
518  template <class $TemplateParameter_decl[[T]]>
519  void $Function_decl[[foo]](typename $TemplateParameter[[T]]::$Type_dependentName[[Type]]
520  = $TemplateParameter[[T]]::$Unknown_dependentName[[val]]);
521  )cpp",
522  R"cpp(
523  template <class $TemplateParameter_decl[[T]]>
524  void $Function_decl[[foo]]($TemplateParameter[[T]] $Parameter_decl[[P]]) {
525  $Parameter[[P]].$Unknown_dependentName[[Field]];
526  }
527  )cpp",
528  R"cpp(
529  template <class $TemplateParameter_decl[[T]]>
530  class $Class_decl[[A]] {
531  int $Method_decl[[foo]]() {
532  return $TemplateParameter[[T]]::$Unknown_dependentName[[Field]];
533  }
534  };
535  )cpp",
536  // Highlighting the using decl as the underlying using shadow decl.
537  R"cpp(
538  void $Function_decl[[foo]]();
539  using ::$Function[[foo]];
540  )cpp",
541  // Highlighting of template template arguments.
542  R"cpp(
543  template <template <class> class $TemplateParameter_decl[[TT]],
544  template <class> class ...$TemplateParameter_decl[[TTs]]>
545  struct $Class_decl[[Foo]] {
546  $Class[[Foo]]<$TemplateParameter[[TT]], $TemplateParameter[[TTs]]...>
547  *$Field_decl[[t]];
548  };
549  )cpp",
550  // Inactive code highlighting
551  R"cpp(
552  // Code in the preamble.
553  // Inactive lines get an empty InactiveCode token at the beginning.
554 $InactiveCode[[#ifdef test]]
555 $InactiveCode[[#endif]]
556 
557  // A declaration to cause the preamble to end.
558  int $Variable_decl[[EndPreamble]];
559 
560  // Code after the preamble.
561  // Code inside inactive blocks does not get regular highlightings
562  // because it's not part of the AST.
563  #define $Macro_decl[[test2]]
564 $InactiveCode[[#if defined(test)]]
565 $InactiveCode[[int Inactive2;]]
566 $InactiveCode[[#elif defined(test2)]]
567  int $Variable_decl[[Active1]];
568 $InactiveCode[[#else]]
569 $InactiveCode[[int Inactive3;]]
570 $InactiveCode[[#endif]]
571 
572  #ifndef $Macro[[test]]
573  int $Variable_decl[[Active2]];
574  #endif
575 
576 $InactiveCode[[#ifdef test]]
577 $InactiveCode[[int Inactive4;]]
578 $InactiveCode[[#else]]
579  int $Variable_decl[[Active3]];
580  #endif
581  )cpp",
582  // Argument to 'sizeof...'
583  R"cpp(
584  template <typename... $TemplateParameter_decl[[Elements]]>
585  struct $Class_decl[[TupleSize]] {
586  static const int $StaticField_decl_readonly_static[[size]] =
587 sizeof...($TemplateParameter[[Elements]]);
588  };
589  )cpp",
590  // More dependent types
591  R"cpp(
592  template <typename $TemplateParameter_decl[[T]]>
593  struct $Class_decl[[Waldo]] {
594  using $Typedef_decl[[Location1]] = typename $TemplateParameter[[T]]
595  ::$Type_dependentName[[Resolver]]::$Type_dependentName[[Location]];
596  using $Typedef_decl[[Location2]] = typename $TemplateParameter[[T]]
597  ::template $Type_dependentName[[Resolver]]<$TemplateParameter[[T]]>
598  ::$Type_dependentName[[Location]];
599  using $Typedef_decl[[Location3]] = typename $TemplateParameter[[T]]
600  ::$Type_dependentName[[Resolver]]
601  ::template $Type_dependentName[[Location]]<$TemplateParameter[[T]]>;
602  static const int $StaticField_decl_readonly_static[[Value]] = $TemplateParameter[[T]]
603  ::$Type_dependentName[[Resolver]]::$Unknown_dependentName[[Value]];
604  };
605  )cpp",
606  // Dependent name with heuristic target
607  R"cpp(
608  template <typename>
609  struct $Class_decl[[Foo]] {
610  int $Field_decl[[Waldo]];
611  void $Method_decl[[bar]]() {
612  $Class[[Foo]]().$Field_dependentName[[Waldo]];
613  }
614  template <typename $TemplateParameter_decl[[U]]>
615  void $Method_decl[[bar1]]() {
616  $Class[[Foo]]<$TemplateParameter[[U]]>().$Field_dependentName[[Waldo]];
617  }
618 
619  void $Method_decl[[Overload]]();
620  void $Method_decl_readonly[[Overload]]() const;
621  };
622  template <typename $TemplateParameter_decl[[T]]>
623  void $Function_decl[[baz]]($Class[[Foo]]<$TemplateParameter[[T]]> $Parameter_decl[[o]]) {
624  $Parameter[[o]].$Method_readonly_dependentName[[Overload]]();
625  }
626  )cpp",
627  // Concepts
628  R"cpp(
629  template <typename $TemplateParameter_decl[[T]]>
630  concept $Concept_decl[[Fooable]] =
631  requires($TemplateParameter[[T]] $Parameter_decl[[F]]) {
632  $Parameter[[F]].$Unknown_dependentName[[foo]]();
633  };
634  template <typename $TemplateParameter_decl[[T]]>
635  requires $Concept[[Fooable]]<$TemplateParameter[[T]]>
636  void $Function_decl[[bar]]($TemplateParameter[[T]] $Parameter_decl[[F]]) {
637  $Parameter[[F]].$Unknown_dependentName[[foo]]();
638  }
639  )cpp",
640  // Dependent template name
641  R"cpp(
642  template <template <typename> class> struct $Class_decl[[A]] {};
643  template <typename $TemplateParameter_decl[[T]]>
644  using $Typedef_decl[[W]] = $Class[[A]]<
645  $TemplateParameter[[T]]::template $Class_dependentName[[Waldo]]
646  >;
647  )cpp",
648  R"cpp(
649  class $Class_decl_abstract[[Abstract]] {
650  public:
651  virtual void $Method_decl_abstract_virtual[[pure]]() = 0;
652  virtual void $Method_decl_virtual[[impl]]();
653  };
654  void $Function_decl[[foo]]($Class_abstract[[Abstract]]* $Parameter_decl[[A]]) {
655  $Parameter[[A]]->$Method_abstract_virtual[[pure]]();
656  $Parameter[[A]]->$Method_virtual[[impl]]();
657  }
658  )cpp",
659  R"cpp(
660  <:[deprecated]:> int $Variable_decl_deprecated[[x]];
661  )cpp",
662  R"cpp(
663  // ObjC: Classes and methods
664  @class $Class_decl[[Forward]];
665 
666  @interface $Class_decl[[Foo]]
667  @end
668  @interface $Class_decl[[Bar]] : $Class[[Foo]]
669  -(id) $Method_decl[[x]]:(int)$Parameter_decl[[a]] $Method_decl[[y]]:(int)$Parameter_decl[[b]];
670  +(instancetype)$StaticMethod_decl_static[[sharedInstance]];
671  +(void) $StaticMethod_decl_static[[explode]];
672  @end
673  @implementation $Class_decl[[Bar]]
674  -(id) $Method_decl[[x]]:(int)$Parameter_decl[[a]] $Method_decl[[y]]:(int)$Parameter_decl[[b]] {
675  return self;
676  }
677  +(instancetype)$StaticMethod_decl_static[[sharedInstance]] { return 0; }
678  +(void) $StaticMethod_decl_static[[explode]] {}
679  @end
680 
681  void $Function_decl[[m]]($Class[[Bar]] *$Parameter_decl[[b]]) {
682  [$Parameter[[b]] $Method[[x]]:1 $Method[[y]]:2];
683  [$Class[[Bar]] $StaticMethod_static[[explode]]];
684  }
685  )cpp",
686  R"cpp(
687  // ObjC: Protocols
688  @protocol $Interface_decl[[Protocol]]
689  @end
690  @protocol $Interface_decl[[Protocol2]] <$Interface[[Protocol]]>
691  @end
692  @interface $Class_decl[[Klass]] <$Interface[[Protocol]]>
693  @end
694  id<$Interface[[Protocol]]> $Variable_decl[[x]];
695  )cpp",
696  R"cpp(
697  // ObjC: Categories
698  @interface $Class_decl[[Foo]]
699  @end
700  @interface $Class[[Foo]]($Namespace_decl[[Bar]])
701  @end
702  @implementation $Class[[Foo]]($Namespace_decl[[Bar]])
703  @end
704  )cpp",
705  R"cpp(
706  // ObjC: Properties and Ivars.
707  @interface $Class_decl[[Foo]] {
708  int $Field_decl[[_someProperty]];
709  }
710  @property(nonatomic, assign) int $Field_decl[[someProperty]];
711  @property(readonly, class) $Class[[Foo]] *$Field_decl_readonly_static[[sharedInstance]];
712  @end
713  @implementation $Class_decl[[Foo]]
714  @synthesize someProperty = _someProperty;
715  - (int)$Method_decl[[otherMethod]] {
716  return 0;
717  }
718  - (int)$Method_decl[[doSomething]] {
719  $Class[[Foo]].$Field_static[[sharedInstance]].$Field[[someProperty]] = 1;
720  self.$Field[[someProperty]] = self.$Field[[someProperty]] + self.$Field[[otherMethod]] + 1;
721  self->$Field[[_someProperty]] = $Field[[_someProperty]] + 1;
722  }
723  @end
724  )cpp",
725  // Member imported from dependent base
726  R"cpp(
727  template <typename> struct $Class_decl[[Base]] {
728  int $Field_decl[[member]];
729  };
730  template <typename $TemplateParameter_decl[[T]]>
731  struct $Class_decl[[Derived]] : $Class[[Base]]<$TemplateParameter[[T]]> {
732  using $Class[[Base]]<$TemplateParameter[[T]]>::$Field_dependentName[[member]];
733 
734  void $Method_decl[[method]]() {
735  (void)$Field_dependentName[[member]];
736  }
737  };
738  )cpp",
739  // Modifier for variables passed as non-const references
740  R"cpp(
741  void $Function_decl[[fun]](int, const int,
742  int*, const int*,
743  int&, const int&,
744  int*&, const int*&, const int* const &,
745  int**, int**&, int** const &,
746  int = 123) {
747  int $LocalVariable_decl[[val]];
748  int* $LocalVariable_decl[[ptr]];
749  const int* $LocalVariable_decl_readonly[[constPtr]];
750  int** $LocalVariable_decl[[array]];
751  $Function[[fun]]($LocalVariable[[val]], $LocalVariable[[val]],
752  $LocalVariable[[ptr]], $LocalVariable_readonly[[constPtr]],
753  $LocalVariable_usedAsMutableReference[[val]], $LocalVariable[[val]],
754 
755  $LocalVariable_usedAsMutableReference[[ptr]],
756  $LocalVariable_readonly_usedAsMutableReference[[constPtr]],
757  $LocalVariable_readonly[[constPtr]],
758 
759  $LocalVariable[[array]], $LocalVariable_usedAsMutableReference[[array]],
760  $LocalVariable[[array]]
761  );
762  }
763  struct $Class_decl[[S]] {
764  $Class_decl[[S]](int&) {
765  $Class[[S]] $LocalVariable_decl[[s1]]($Field_usedAsMutableReference[[field]]);
766  $Class[[S]] $LocalVariable_decl[[s2]]($LocalVariable[[s1]].$Field_usedAsMutableReference[[field]]);
767 
768  $Class[[S]] $LocalVariable_decl[[s3]]($StaticField_static_usedAsMutableReference[[staticField]]);
769  $Class[[S]] $LocalVariable_decl[[s4]]($Class[[S]]::$StaticField_static_usedAsMutableReference[[staticField]]);
770  }
771  int $Field_decl[[field]];
772  static int $StaticField_decl_static[[staticField]];
773  };
774  template <typename $TemplateParameter_decl[[X]]>
775  void $Function_decl[[foo]]($TemplateParameter[[X]]& $Parameter_decl[[x]]) {
776  // We do not support dependent types, so this one should *not* get the modifier.
777  $Function[[foo]]($Parameter[[x]]);
778  }
779  )cpp",
780  // init-captures
781  R"cpp(
782  void $Function_decl[[foo]]() {
783  int $LocalVariable_decl[[a]], $LocalVariable_decl[[b]];
784  [ $LocalVariable_decl[[c]] = $LocalVariable[[a]],
785  $LocalVariable_decl[[d]]($LocalVariable[[b]]) ]() {}();
786  }
787  )cpp",
788  // Enum base specifier
789  R"cpp(
790  using $Primitive_decl[[MyTypedef]] = int;
791  enum $Enum_decl[[MyEnum]] : $Primitive[[MyTypedef]] {};
792  )cpp",
793  // Enum base specifier
794  R"cpp(
795  typedef int $Primitive_decl[[MyTypedef]];
796  enum $Enum_decl[[MyEnum]] : $Primitive[[MyTypedef]] {};
797  )cpp",
798  // Issue 1096
799  R"cpp(
800  void $Function_decl[[Foo]]();
801  // Use <: :> digraphs for deprecated attribute to avoid conflict with annotation syntax
802  <:<:deprecated:>:> void $Function_decl_deprecated[[Foo]](int* $Parameter_decl[[x]]);
803  void $Function_decl[[Foo]](int $Parameter_decl[[x]]);
804  template <typename $TemplateParameter_decl[[T]]>
805  void $Function_decl[[Bar]]($TemplateParameter[[T]] $Parameter_decl[[x]]) {
806  $Function_deprecated[[Foo]]($Parameter[[x]]);
807  $Function_deprecated[[Foo]]($Parameter[[x]]);
808  $Function_deprecated[[Foo]]($Parameter[[x]]);
809  }
810  )cpp"};
811  for (const auto &TestCase : TestCases)
812  // Mask off scope modifiers to keep the tests manageable.
813  // They're tested separately.
814  checkHighlightings(TestCase, {}, ~ScopeModifierMask);
815 
816  checkHighlightings(R"cpp(
817  class $Class_decl[[A]] {
818  #include "imp.h"
819  };
820  )cpp",
821  {{"imp.h", R"cpp(
822  int someMethod();
823  void otherMethod();
824  )cpp"}},
825  ~ScopeModifierMask);
826 
827  // A separate test for macros in headers.
828  checkHighlightings(R"cpp(
829  #include "imp.h"
830  $Macro[[DEFINE_Y]]
831  $Macro[[DXYZ_Y]](A);
832  )cpp",
833  {{"imp.h", R"cpp(
834  #define DXYZ(X) class X {};
835  #define DXYZ_Y(Y) DXYZ(x##Y)
836  #define DEFINE(X) int X;
837  #define DEFINE_Y DEFINE(Y)
838  )cpp"}},
839  ~ScopeModifierMask);
840 
841  checkHighlightings(R"cpp(
842  #include "SYSObject.h"
843  @interface $Class_defaultLibrary[[SYSObject]] ($Namespace_decl[[UserCategory]])
844  @property(nonatomic, readonly) int $Field_decl_readonly[[user_property]];
845  @end
846  int $Function_decl[[somethingUsingSystemSymbols]]() {
847  $Class_defaultLibrary[[SYSObject]] *$LocalVariable_decl[[obj]] = [$Class_defaultLibrary[[SYSObject]] $StaticMethod_static_defaultLibrary[[new]]];
848  return $LocalVariable[[obj]].$Field_defaultLibrary[[value]] + $LocalVariable[[obj]].$Field_readonly[[user_property]];
849  }
850  )cpp",
851  {{"SystemSDK/SYSObject.h", R"cpp(
852  @interface SYSObject
853  @property(nonatomic, assign) int value;
854  + (instancetype)new;
855  @end
856  )cpp"}},
857  ~ScopeModifierMask, {"-isystemSystemSDK/"});
858 }
859 
860 TEST(SemanticHighlighting, ScopeModifiers) {
861  const char *TestCases[] = {
862  R"cpp(
863  static int $Variable_fileScope[[x]];
864  namespace $Namespace_globalScope[[ns]] {
865  class $Class_globalScope[[x]];
866  }
867  namespace {
868  void $Function_fileScope[[foo]]();
869  }
870  )cpp",
871  R"cpp(
872  void $Function_globalScope[[foo]](int $Parameter_functionScope[[y]]) {
873  int $LocalVariable_functionScope[[z]];
874  }
875  )cpp",
876  R"cpp(
877  // Lambdas are considered functions, not classes.
878  auto $Variable_fileScope[[x]] = [$LocalVariable_functionScope[[m]](42)] {
879  return $LocalVariable_functionScope[[m]];
880  };
881  )cpp",
882  R"cpp(
883  // Classes in functions are classes.
884  void $Function_globalScope[[foo]]() {
885  class $Class_functionScope[[X]] {
886  int $Field_classScope[[x]];
887  };
888  };
889  )cpp",
890  R"cpp(
891  template <int $TemplateParameter_classScope[[T]]>
892  class $Class_globalScope[[X]] {
893  };
894  )cpp",
895  R"cpp(
896  // No useful scope for template parameters of variable templates.
897  template <typename $TemplateParameter[[A]]>
898  unsigned $Variable_globalScope[[X]] =
899  $TemplateParameter[[A]]::$Unknown_classScope[[x]];
900  )cpp",
901  R"cpp(
902  #define $Macro_globalScope[[X]] 1
903  int $Variable_globalScope[[Y]] = $Macro_globalScope[[X]];
904  )cpp",
905  };
906 
907  for (const char *Test : TestCases)
908  checkHighlightings(Test, {}, ScopeModifierMask);
909 }
910 
911 // Ranges are highlighted as variables, unless highlighted as $Function etc.
912 std::vector<HighlightingToken> tokens(llvm::StringRef MarkedText) {
913  Annotations A(MarkedText);
914  std::vector<HighlightingToken> Results;
915  for (const Range& R : A.ranges())
916  Results.push_back({HighlightingKind::Variable, 0, R});
917  for (unsigned I = 0; I < static_cast<unsigned>(HighlightingKind::LastKind); ++I) {
918  HighlightingKind Kind = static_cast<HighlightingKind>(I);
919  for (const Range& R : A.ranges(llvm::to_string(Kind)))
920  Results.push_back({Kind, 0, R});
921  }
922  llvm::sort(Results);
923  return Results;
924 }
925 
926 TEST(SemanticHighlighting, toSemanticTokens) {
927  auto Tokens = tokens(R"(
928  [[blah]]
929 
930  $Function[[big]] [[bang]]
931  )");
932  Tokens.front().Modifiers |= unsigned(HighlightingModifier::Declaration);
933  Tokens.front().Modifiers |= unsigned(HighlightingModifier::Readonly);
934  auto Results = toSemanticTokens(Tokens);
935 
936  ASSERT_THAT(Results, SizeIs(3));
937  EXPECT_EQ(Results[0].tokenType, unsigned(HighlightingKind::Variable));
938  EXPECT_EQ(Results[0].tokenModifiers,
941  EXPECT_EQ(Results[0].deltaLine, 1u);
942  EXPECT_EQ(Results[0].deltaStart, 1u);
943  EXPECT_EQ(Results[0].length, 4u);
944 
945  EXPECT_EQ(Results[1].tokenType, unsigned(HighlightingKind::Function));
946  EXPECT_EQ(Results[1].tokenModifiers, 0u);
947  EXPECT_EQ(Results[1].deltaLine, 2u);
948  EXPECT_EQ(Results[1].deltaStart, 4u);
949  EXPECT_EQ(Results[1].length, 3u);
950 
951  EXPECT_EQ(Results[2].tokenType, unsigned(HighlightingKind::Variable));
952  EXPECT_EQ(Results[1].tokenModifiers, 0u);
953  EXPECT_EQ(Results[2].deltaLine, 0u);
954  EXPECT_EQ(Results[2].deltaStart, 4u);
955  EXPECT_EQ(Results[2].length, 4u);
956 }
957 
958 TEST(SemanticHighlighting, diffSemanticTokens) {
959  auto Before = toSemanticTokens(tokens(R"(
960  [[foo]] [[bar]] [[baz]]
961  [[one]] [[two]] [[three]]
962  )"));
963  EXPECT_THAT(diffTokens(Before, Before), IsEmpty());
964 
965  auto After = toSemanticTokens(tokens(R"(
966  [[foo]] [[hello]] [[world]] [[baz]]
967  [[one]] [[two]] [[three]]
968  )"));
969 
970  // Replace [bar, baz] with [hello, world, baz]
971  auto Diff = diffTokens(Before, After);
972  ASSERT_THAT(Diff, SizeIs(1));
973  EXPECT_EQ(1u, Diff.front().startToken);
974  EXPECT_EQ(2u, Diff.front().deleteTokens);
975  ASSERT_THAT(Diff.front().tokens, SizeIs(3));
976  // hello
977  EXPECT_EQ(0u, Diff.front().tokens[0].deltaLine);
978  EXPECT_EQ(4u, Diff.front().tokens[0].deltaStart);
979  EXPECT_EQ(5u, Diff.front().tokens[0].length);
980  // world
981  EXPECT_EQ(0u, Diff.front().tokens[1].deltaLine);
982  EXPECT_EQ(6u, Diff.front().tokens[1].deltaStart);
983  EXPECT_EQ(5u, Diff.front().tokens[1].length);
984  // baz
985  EXPECT_EQ(0u, Diff.front().tokens[2].deltaLine);
986  EXPECT_EQ(6u, Diff.front().tokens[2].deltaStart);
987  EXPECT_EQ(3u, Diff.front().tokens[2].length);
988 }
989 
990 } // namespace
991 } // namespace clangd
992 } // namespace clang
Range
CharSourceRange Range
SourceRange for the file name.
Definition: IncludeOrderCheck.cpp:38
clang::clangd::HighlightingModifier::FunctionScope
@ FunctionScope
clang::clangd::HighlightingModifier::FileScope
@ FileScope
clang::clangd::TEST
TEST(BackgroundQueueTest, Priority)
Definition: BackgroundIndexTests.cpp:750
clang::clangd::HighlightingModifier
HighlightingModifier
Definition: SemanticHighlighting.h:61
clang::clangd::HighlightingModifier::LastModifier
@ LastModifier
TestTU.h
Kind
BindArgumentKind Kind
Definition: AvoidBindCheck.cpp:59
clang::clangd::HighlightingKind
HighlightingKind
Definition: SemanticHighlighting.h:30
clang::clangd::HighlightingKind::LastKind
@ LastKind
clang::clangd::HighlightingKind::Variable
@ Variable
Protocol.h
clang::clangd::ParsedAST::build
static llvm::Optional< ParsedAST > build(llvm::StringRef Filename, const ParseInputs &Inputs, std::unique_ptr< clang::CompilerInvocation > CI, llvm::ArrayRef< Diag > CompilerInvocationDiags, std::shared_ptr< const PreambleData > Preamble)
Attempts to run Clang and store the parsed AST.
Definition: ParsedAST.cpp:342
ns1::ns2::A
@ A
Definition: CategoricalFeature.h:3
Code
std::string Code
Definition: FindTargetTests.cpp:67
clang::clangd::HighlightingKind::Function
@ Function
clang::clangd::diffTokens
std::vector< SemanticTokensEdit > diffTokens(llvm::ArrayRef< SemanticToken > Old, llvm::ArrayRef< SemanticToken > New)
Definition: SemanticHighlighting.cpp:1032
clang::clangd::positionToOffset
llvm::Expected< size_t > positionToOffset(llvm::StringRef Code, Position P, bool AllowColumnsBeyondLineLength)
Turn a [line, column] pair into an offset in Code.
Definition: SourceCode.cpp:172
Results
std::vector< CodeCompletionResult > Results
Definition: CodeComplete.cpp:784
clang::clangd::HighlightingModifier::GlobalScope
@ GlobalScope
Annotations.h
clang::clangd::getSemanticHighlightings
std::vector< HighlightingToken > getSemanticHighlightings(ParsedAST &AST)
Definition: SemanticHighlighting.cpp:792
SourceCode.h
clang::clangd::toSemanticTokens
std::vector< SemanticToken > toSemanticTokens(llvm::ArrayRef< HighlightingToken > Tokens)
Definition: SemanticHighlighting.cpp:921
SemanticHighlighting.h
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
OS
llvm::raw_string_ostream OS
Definition: TraceTests.cpp:160
clang::clangd::HighlightingModifier::Readonly
@ Readonly
clang::clangd::HighlightingModifier::ClassScope
@ ClassScope
clang::clangd::HighlightingModifier::Declaration
@ Declaration