clang-tools  11.0.0
SelectionTests.cpp
Go to the documentation of this file.
1 //===-- SelectionTests.cpp - ----------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 #include "Annotations.h"
9 #include "Selection.h"
10 #include "SourceCode.h"
11 #include "TestTU.h"
12 #include "support/TestTracer.h"
13 #include "clang/AST/Decl.h"
14 #include "llvm/Support/Casting.h"
15 #include "gmock/gmock.h"
16 #include "gtest/gtest.h"
17 
18 namespace clang {
19 namespace clangd {
20 namespace {
21 using ::testing::UnorderedElementsAreArray;
22 
23 // Create a selection tree corresponding to a point or pair of points.
24 // This uses the precisely-defined createRight semantics. The fuzzier
25 // createEach is tested separately.
26 SelectionTree makeSelectionTree(const StringRef MarkedCode, ParsedAST &AST) {
27  Annotations Test(MarkedCode);
28  switch (Test.points().size()) {
29  case 1: { // Point selection.
30  unsigned Offset = cantFail(positionToOffset(Test.code(), Test.point()));
32  Offset, Offset);
33  }
34  case 2: // Range selection.
36  AST.getASTContext(), AST.getTokens(),
37  cantFail(positionToOffset(Test.code(), Test.points()[0])),
38  cantFail(positionToOffset(Test.code(), Test.points()[1])));
39  default:
40  ADD_FAILURE() << "Expected 1-2 points for selection.\n" << MarkedCode;
41  return SelectionTree::createRight(AST.getASTContext(), AST.getTokens(), 0u,
42  0u);
43  }
44 }
45 
46 Range nodeRange(const SelectionTree::Node *N, ParsedAST &AST) {
47  if (!N)
48  return Range{};
49  const SourceManager &SM = AST.getSourceManager();
50  const LangOptions &LangOpts = AST.getLangOpts();
51  StringRef Buffer = SM.getBufferData(SM.getMainFileID());
52  if (llvm::isa_and_nonnull<TranslationUnitDecl>(N->ASTNode.get<Decl>()))
53  return Range{Position{}, offsetToPosition(Buffer, Buffer.size())};
54  auto FileRange =
55  toHalfOpenFileRange(SM, LangOpts, N->ASTNode.getSourceRange());
56  assert(FileRange && "We should be able to get the File Range");
57  return Range{
58  offsetToPosition(Buffer, SM.getFileOffset(FileRange->getBegin())),
59  offsetToPosition(Buffer, SM.getFileOffset(FileRange->getEnd()))};
60 }
61 
62 std::string nodeKind(const SelectionTree::Node *N) {
63  return N ? N->kind() : "<null>";
64 }
65 
66 std::vector<const SelectionTree::Node *> allNodes(const SelectionTree &T) {
67  std::vector<const SelectionTree::Node *> Result = {&T.root()};
68  for (unsigned I = 0; I < Result.size(); ++I) {
69  const SelectionTree::Node *N = Result[I];
70  Result.insert(Result.end(), N->Children.begin(), N->Children.end());
71  }
72  return Result;
73 }
74 
75 // Returns true if Common is a descendent of Root.
76 // Verifies nothing is selected above Common.
77 bool verifyCommonAncestor(const SelectionTree::Node &Root,
78  const SelectionTree::Node *Common,
79  StringRef MarkedCode) {
80  if (&Root == Common)
81  return true;
82  if (Root.Selected)
83  ADD_FAILURE() << "Selected nodes outside common ancestor\n" << MarkedCode;
84  bool Seen = false;
85  for (const SelectionTree::Node *Child : Root.Children)
86  if (verifyCommonAncestor(*Child, Common, MarkedCode)) {
87  if (Seen)
88  ADD_FAILURE() << "Saw common ancestor twice\n" << MarkedCode;
89  Seen = true;
90  }
91  return Seen;
92 }
93 
94 TEST(SelectionTest, CommonAncestor) {
95  struct Case {
96  // Selection is between ^marks^.
97  // common ancestor marked with a [[range]].
98  const char *Code;
99  const char *CommonAncestorKind;
100  };
101  Case Cases[] = {
102  {
103  R"cpp(
104  template <typename T>
105  int x = [[T::^U::]]ccc();
106  )cpp",
107  "NestedNameSpecifierLoc",
108  },
109  {
110  R"cpp(
111  struct AAA { struct BBB { static int ccc(); };};
112  int x = AAA::[[B^B^B]]::ccc();
113  )cpp",
114  "RecordTypeLoc",
115  },
116  {
117  R"cpp(
118  struct AAA { struct BBB { static int ccc(); };};
119  int x = AAA::[[B^BB^]]::ccc();
120  )cpp",
121  "RecordTypeLoc",
122  },
123  {
124  R"cpp(
125  struct AAA { struct BBB { static int ccc(); };};
126  int x = [[AAA::BBB::c^c^c]]();
127  )cpp",
128  "DeclRefExpr",
129  },
130  {
131  R"cpp(
132  struct AAA { struct BBB { static int ccc(); };};
133  int x = [[AAA::BBB::cc^c(^)]];
134  )cpp",
135  "CallExpr",
136  },
137 
138  {
139  R"cpp(
140  void foo() { [[if (1^11) { return; } else {^ }]] }
141  )cpp",
142  "IfStmt",
143  },
144  {
145  R"cpp(
146  int x(int);
147  #define M(foo) x(foo)
148  int a = 42;
149  int b = M([[^a]]);
150  )cpp",
151  "DeclRefExpr",
152  },
153  {
154  R"cpp(
155  void foo();
156  #define CALL_FUNCTION(X) X()
157  void bar() { CALL_FUNCTION([[f^o^o]]); }
158  )cpp",
159  "DeclRefExpr",
160  },
161  {
162  R"cpp(
163  void foo();
164  #define CALL_FUNCTION(X) X()
165  void bar() { [[CALL_FUNC^TION(fo^o)]]; }
166  )cpp",
167  "CallExpr",
168  },
169  {
170  R"cpp(
171  void foo();
172  #define CALL_FUNCTION(X) X()
173  void bar() { [[C^ALL_FUNC^TION(foo)]]; }
174  )cpp",
175  "CallExpr",
176  },
177  {
178  R"cpp(
179  void foo();
180  #define CALL_FUNCTION(X) X^()^
181  void bar() { CALL_FUNCTION(foo); }
182  )cpp",
183  nullptr,
184  },
185  {
186  R"cpp(
187  struct S { S(const char*); };
188  S [[s ^= "foo"]];
189  )cpp",
190  "CXXConstructExpr",
191  },
192  {
193  R"cpp(
194  struct S { S(const char*); };
195  [[S ^s = "foo"]];
196  )cpp",
197  "VarDecl",
198  },
199  {
200  R"cpp(
201  [[^void]] (*S)(int) = nullptr;
202  )cpp",
203  "BuiltinTypeLoc",
204  },
205  {
206  R"cpp(
207  [[void (*S)^(int)]] = nullptr;
208  )cpp",
209  "FunctionProtoTypeLoc",
210  },
211  {
212  R"cpp(
213  [[void (^*S)(int)]] = nullptr;
214  )cpp",
215  "FunctionProtoTypeLoc",
216  },
217  {
218  R"cpp(
219  [[void (*^S)(int) = nullptr]];
220  )cpp",
221  "VarDecl",
222  },
223  {
224  R"cpp(
225  [[void ^(*S)(int)]] = nullptr;
226  )cpp",
227  "FunctionProtoTypeLoc",
228  },
229  {
230  R"cpp(
231  struct S {
232  int foo() const;
233  int bar() { return [[f^oo]](); }
234  };
235  )cpp",
236  "MemberExpr", // Not implicit CXXThisExpr, or its implicit cast!
237  },
238  {
239  R"cpp(
240  auto lambda = [](const char*){ return 0; };
241  int x = lambda([["y^"]]);
242  )cpp",
243  "StringLiteral", // Not DeclRefExpr to operator()!
244  },
245 
246  // Point selections.
247  {"void foo() { [[^foo]](); }", "DeclRefExpr"},
248  {"void foo() { [[f^oo]](); }", "DeclRefExpr"},
249  {"void foo() { [[fo^o]](); }", "DeclRefExpr"},
250  {"void foo() { [[foo^()]]; }", "CallExpr"},
251  {"void foo() { [[foo^]] (); }", "DeclRefExpr"},
252  {"int bar; void foo() [[{ foo (); }]]^", "CompoundStmt"},
253  {"int x = [[42]]^;", "IntegerLiteral"},
254 
255  // Ignores whitespace, comments, and semicolons in the selection.
256  {"void foo() { [[foo^()]]; /*comment*/^}", "CallExpr"},
257 
258  // Tricky case: FunctionTypeLoc in FunctionDecl has a hole in it.
259  {"[[^void]] foo();", "BuiltinTypeLoc"},
260  {"[[void foo^()]];", "FunctionProtoTypeLoc"},
261  {"[[^void foo^()]];", "FunctionDecl"},
262  {"[[void ^foo()]];", "FunctionDecl"},
263  // Tricky case: two VarDecls share a specifier.
264  {"[[int ^a]], b;", "VarDecl"},
265  {"[[int a, ^b]];", "VarDecl"},
266  // Tricky case: CXXConstructExpr wants to claim the whole init range.
267  {
268  R"cpp(
269  struct X { X(int); };
270  class Y {
271  X x;
272  Y() : [[^x(4)]] {}
273  };
274  )cpp",
275  "CXXCtorInitializer", // Not the CXXConstructExpr!
276  },
277  // Tricky case: anonymous struct is a sibling of the VarDecl.
278  {"[[st^ruct {int x;}]] y;", "CXXRecordDecl"},
279  {"[[struct {int x;} ^y]];", "VarDecl"},
280  {"struct {[[int ^x]];} y;", "FieldDecl"},
281  // FIXME: the AST has no location info for qualifiers.
282  {"const [[a^uto]] x = 42;", "AutoTypeLoc"},
283  {"[[co^nst auto x = 42]];", "VarDecl"},
284 
285  {"^", nullptr},
286  {"void foo() { [[foo^^]] (); }", "DeclRefExpr"},
287 
288  // FIXME: Ideally we'd get a declstmt or the VarDecl itself here.
289  // This doesn't happen now; the RAV doesn't traverse a node containing ;.
290  {"int x = 42;^", nullptr},
291 
292  // Common ancestor is logically TUDecl, but we never return that.
293  {"^int x; int y;^", nullptr},
294 
295  // Node types that have caused problems in the past.
296  {"template <typename T> void foo() { [[^T]] t; }",
297  "TemplateTypeParmTypeLoc"},
298 
299  // No crash
300  {
301  R"cpp(
302  template <class T> struct Foo {};
303  template <[[template<class> class /*cursor here*/^U]]>
304  struct Foo<U<int>*> {};
305  )cpp",
306  "TemplateTemplateParmDecl"},
307 
308  // Foreach has a weird AST, ensure we can select parts of the range init.
309  // This used to fail, because the DeclStmt for C claimed the whole range.
310  {
311  R"cpp(
312  struct Str {
313  const char *begin();
314  const char *end();
315  };
316  Str makeStr(const char*);
317  void loop() {
318  for (const char C : [[mak^eStr("foo"^)]])
319  ;
320  }
321  )cpp",
322  "CallExpr"},
323 
324  // User-defined literals are tricky: is 12_i one token or two?
325  // For now we treat it as one, and the UserDefinedLiteral as a leaf.
326  {
327  R"cpp(
328  struct Foo{};
329  Foo operator""_ud(unsigned long long);
330  Foo x = [[^12_ud]];
331  )cpp",
332  "UserDefinedLiteral"},
333 
334  {
335  R"cpp(
336  int a;
337  decltype([[^a]] + a) b;
338  )cpp",
339  "DeclRefExpr"},
340 
341  // Objective-C OpaqueValueExpr/PseudoObjectExpr has weird ASTs.
342  // Need to traverse the contents of the OpaqueValueExpr to the POE,
343  // and ensure we traverse only the syntactic form of the PseudoObjectExpr.
344  {
345  R"cpp(
346  @interface I{}
347  @property(retain) I*x;
348  @property(retain) I*y;
349  @end
350  void test(I *f) { [[^f]].x.y = 0; }
351  )cpp",
352  "DeclRefExpr"},
353  {
354  R"cpp(
355  @interface I{}
356  @property(retain) I*x;
357  @property(retain) I*y;
358  @end
359  void test(I *f) { [[f.^x]].y = 0; }
360  )cpp",
361  "ObjCPropertyRefExpr"},
362  // Examples with implicit properties.
363  {
364  R"cpp(
365  @interface I{}
366  -(int)foo;
367  @end
368  int test(I *f) { return 42 + [[^f]].foo; }
369  )cpp",
370  "DeclRefExpr"},
371  {
372  R"cpp(
373  @interface I{}
374  -(int)foo;
375  @end
376  int test(I *f) { return 42 + [[f.^foo]]; }
377  )cpp",
378  "ObjCPropertyRefExpr"},
379  {"struct foo { [[int has^h<:32:>]]; };", "FieldDecl"},
380  {"struct foo { [[op^erator int()]]; };", "CXXConversionDecl"},
381  {"struct foo { [[^~foo()]]; };", "CXXDestructorDecl"},
382  // FIXME: The following to should be class itself instead.
383  {"struct foo { [[fo^o(){}]] };", "CXXConstructorDecl"},
384 
385  {R"cpp(
386  struct S1 { void f(); };
387  struct S2 { S1 * operator->(); };
388  void test(S2 s2) {
389  s2[[-^>]]f();
390  }
391  )cpp", "DeclRefExpr"} // DeclRefExpr to the "operator->" method.
392  };
393  for (const Case &C : Cases) {
394  trace::TestTracer Tracer;
395  Annotations Test(C.Code);
396 
397  TestTU TU;
398  TU.Code = std::string(Test.code());
399 
400  // FIXME: Auto-completion in a template requires disabling delayed template
401  // parsing.
402  TU.ExtraArgs.push_back("-fno-delayed-template-parsing");
403  TU.ExtraArgs.push_back("-xobjective-c++");
404 
405  auto AST = TU.build();
406  auto T = makeSelectionTree(C.Code, AST);
407  EXPECT_EQ("TranslationUnitDecl", nodeKind(&T.root())) << C.Code;
408 
409  if (Test.ranges().empty()) {
410  // If no [[range]] is marked in the example, there should be no selection.
411  EXPECT_FALSE(T.commonAncestor()) << C.Code << "\n" << T;
412  EXPECT_THAT(Tracer.takeMetric("selection_recovery"), testing::IsEmpty());
413  } else {
414  // If there is an expected selection, common ancestor should exist
415  // with the appropriate node type.
416  EXPECT_EQ(C.CommonAncestorKind, nodeKind(T.commonAncestor()))
417  << C.Code << "\n"
418  << T;
419  // Convert the reported common ancestor to a range and verify it.
420  EXPECT_EQ(nodeRange(T.commonAncestor(), AST), Test.range())
421  << C.Code << "\n"
422  << T;
423 
424  // Check that common ancestor is reachable on exactly one path from root,
425  // and no nodes outside it are selected.
426  EXPECT_TRUE(verifyCommonAncestor(T.root(), T.commonAncestor(), C.Code))
427  << C.Code;
428  EXPECT_THAT(Tracer.takeMetric("selection_recovery"),
429  testing::ElementsAreArray({0}));
430  }
431  }
432 }
433 
434 // Regression test: this used to match the injected X, not the outer X.
435 TEST(SelectionTest, InjectedClassName) {
436  const char *Code = "struct ^X { int x; };";
437  auto AST = TestTU::withCode(Annotations(Code).code()).build();
438  auto T = makeSelectionTree(Code, AST);
439  ASSERT_EQ("CXXRecordDecl", nodeKind(T.commonAncestor())) << T;
440  auto *D = dyn_cast<CXXRecordDecl>(T.commonAncestor()->ASTNode.get<Decl>());
441  EXPECT_FALSE(D->isInjectedClassName());
442 }
443 
444 TEST(SelectionTree, Metrics) {
445  const char *Code = R"cpp(
446  // error-ok: testing behavior on recovery expression
447  int foo();
448  int foo(int, int);
449  int x = fo^o(42);
450  )cpp";
451  auto AST = TestTU::withCode(Annotations(Code).code()).build();
452  trace::TestTracer Tracer;
453  auto T = makeSelectionTree(Code, AST);
454  EXPECT_THAT(Tracer.takeMetric("selection_recovery"),
455  testing::ElementsAreArray({1}));
456  EXPECT_THAT(Tracer.takeMetric("selection_recovery_type"),
457  testing::ElementsAreArray({1}));
458 }
459 
460 // FIXME: Doesn't select the binary operator node in
461 // #define FOO(X) X + 1
462 // int a, b = [[FOO(a)]];
463 TEST(SelectionTest, Selected) {
464  // Selection with ^marks^.
465  // Partially selected nodes marked with a [[range]].
466  // Completely selected nodes marked with a $C[[range]].
467  const char *Cases[] = {
468  R"cpp( int abc, xyz = [[^ab^c]]; )cpp",
469  R"cpp( int abc, xyz = [[a^bc^]]; )cpp",
470  R"cpp( int abc, xyz = $C[[^abc^]]; )cpp",
471  R"cpp(
472  void foo() {
473  [[if ([[1^11]]) $C[[{
474  $C[[return]];
475  }]] else [[{^
476  }]]]]
477  char z;
478  }
479  )cpp",
480  R"cpp(
481  template <class T>
482  struct unique_ptr {};
483  void foo(^$C[[unique_ptr<$C[[unique_ptr<$C[[int]]>]]>]]^ a) {}
484  )cpp",
485  R"cpp(int a = [[5 >^> 1]];)cpp",
486  R"cpp(
487  #define ECHO(X) X
488  ECHO(EC^HO($C[[int]]) EC^HO(a));
489  )cpp",
490  R"cpp( $C[[^$C[[int]] a^]]; )cpp",
491  R"cpp( $C[[^$C[[int]] a = $C[[5]]^]]; )cpp",
492  };
493  for (const char *C : Cases) {
494  Annotations Test(C);
495  auto AST = TestTU::withCode(Test.code()).build();
496  auto T = makeSelectionTree(C, AST);
497 
498  std::vector<Range> Complete, Partial;
499  for (const SelectionTree::Node *N : allNodes(T))
500  if (N->Selected == SelectionTree::Complete)
501  Complete.push_back(nodeRange(N, AST));
502  else if (N->Selected == SelectionTree::Partial)
503  Partial.push_back(nodeRange(N, AST));
504  EXPECT_THAT(Complete, UnorderedElementsAreArray(Test.ranges("C"))) << C;
505  EXPECT_THAT(Partial, UnorderedElementsAreArray(Test.ranges())) << C;
506  }
507 }
508 
509 TEST(SelectionTest, PathologicalPreprocessor) {
510  const char *Case = R"cpp(
511 #define MACRO while(1)
512  void test() {
513 #include "Expand.inc"
514  br^eak;
515  }
516  )cpp";
517  Annotations Test(Case);
518  auto TU = TestTU::withCode(Test.code());
519  TU.AdditionalFiles["Expand.inc"] = "MACRO\n";
520  auto AST = TU.build();
521  EXPECT_THAT(AST.getDiagnostics(), ::testing::IsEmpty());
522  auto T = makeSelectionTree(Case, AST);
523 
524  EXPECT_EQ("BreakStmt", T.commonAncestor()->kind());
525  EXPECT_EQ("WhileStmt", T.commonAncestor()->Parent->kind());
526 }
527 
528 TEST(SelectionTest, IncludedFile) {
529  const char *Case = R"cpp(
530  void test() {
531 #include "Exp^and.inc"
532  break;
533  }
534  )cpp";
535  Annotations Test(Case);
536  auto TU = TestTU::withCode(Test.code());
537  TU.AdditionalFiles["Expand.inc"] = "while(1)\n";
538  auto AST = TU.build();
539  auto T = makeSelectionTree(Case, AST);
540 
541  EXPECT_EQ("WhileStmt", T.commonAncestor()->kind());
542 }
543 
544 TEST(SelectionTest, MacroArgExpansion) {
545  // If a macro arg is expanded several times, we only consider the first one
546  // selected.
547  const char *Case = R"cpp(
548  int mul(int, int);
549  #define SQUARE(X) mul(X, X);
550  int nine = SQUARE(^3);
551  )cpp";
552  Annotations Test(Case);
553  auto AST = TestTU::withCode(Test.code()).build();
554  auto T = makeSelectionTree(Case, AST);
555  EXPECT_EQ("IntegerLiteral", T.commonAncestor()->kind());
556  EXPECT_TRUE(T.commonAncestor()->Selected);
557 
558  // Verify that the common assert() macro doesn't suffer from this.
559  // (This is because we don't associate the stringified token with the arg).
560  Case = R"cpp(
561  void die(const char*);
562  #define assert(x) (x ? (void)0 : die(#x))
563  void foo() { assert(^42); }
564  )cpp";
565  Test = Annotations(Case);
566  AST = TestTU::withCode(Test.code()).build();
567  T = makeSelectionTree(Case, AST);
568 
569  EXPECT_EQ("IntegerLiteral", T.commonAncestor()->kind());
570 }
571 
572 TEST(SelectionTest, Implicit) {
573  const char *Test = R"cpp(
574  struct S { S(const char*); };
575  int f(S);
576  int x = f("^");
577  )cpp";
578  auto AST = TestTU::withCode(Annotations(Test).code()).build();
579  auto T = makeSelectionTree(Test, AST);
580 
581  const SelectionTree::Node *Str = T.commonAncestor();
582  EXPECT_EQ("StringLiteral", nodeKind(Str)) << "Implicit selected?";
583  EXPECT_EQ("ImplicitCastExpr", nodeKind(Str->Parent));
584  EXPECT_EQ("CXXConstructExpr", nodeKind(Str->Parent->Parent));
585  EXPECT_EQ(Str, &Str->Parent->Parent->ignoreImplicit())
586  << "Didn't unwrap " << nodeKind(&Str->Parent->Parent->ignoreImplicit());
587 
588  EXPECT_EQ("CXXConstructExpr", nodeKind(&Str->outerImplicit()));
589 }
590 
591 TEST(SelectionTest, CreateAll) {
592  llvm::Annotations Test("int$unique^ a=1$ambiguous^+1; $empty^");
593  auto AST = TestTU::withCode(Test.code()).build();
594  unsigned Seen = 0;
596  AST.getASTContext(), AST.getTokens(), Test.point("ambiguous"),
597  Test.point("ambiguous"), [&](SelectionTree T) {
598  // Expect to see the right-biased tree first.
599  if (Seen == 0)
600  EXPECT_EQ("BinaryOperator", nodeKind(T.commonAncestor()));
601  else if (Seen == 1)
602  EXPECT_EQ("IntegerLiteral", nodeKind(T.commonAncestor()));
603  ++Seen;
604  return false;
605  });
606  EXPECT_EQ(2u, Seen);
607 
608  Seen = 0;
610  Test.point("ambiguous"), Test.point("ambiguous"),
611  [&](SelectionTree T) {
612  ++Seen;
613  return true;
614  });
615  EXPECT_EQ(1u, Seen) << "Return true --> stop iterating";
616 
617  Seen = 0;
619  Test.point("unique"), Test.point("unique"),
620  [&](SelectionTree T) {
621  ++Seen;
622  return false;
623  });
624  EXPECT_EQ(1u, Seen) << "no ambiguity --> only one tree";
625 
626  Seen = 0;
628  Test.point("empty"), Test.point("empty"),
629  [&](SelectionTree T) {
630  EXPECT_FALSE(T.commonAncestor());
631  ++Seen;
632  return false;
633  });
634  EXPECT_EQ(1u, Seen) << "empty tree still created";
635 
636  Seen = 0;
638  Test.point("unique"), Test.point("ambiguous"),
639  [&](SelectionTree T) {
640  ++Seen;
641  return false;
642  });
643  EXPECT_EQ(1u, Seen) << "one tree for nontrivial selection";
644 }
645 
646 } // namespace
647 } // namespace clangd
648 } // namespace clang
Range
CharSourceRange Range
SourceRange for the file name.
Definition: IncludeOrderCheck.cpp:38
clang::clangd::TEST
TEST(BackgroundQueueTest, Priority)
Definition: BackgroundIndexTests.cpp:704
Selection.h
clang::clangd::toHalfOpenFileRange
llvm::Optional< SourceRange > toHalfOpenFileRange(const SourceManager &SM, const LangOptions &LangOpts, SourceRange R)
Turns a token range into a half-open range and checks its correctness.
Definition: SourceCode.cpp:428
clang::clangd::ParsedAST::getASTContext
ASTContext & getASTContext()
Note that the returned ast will not contain decls from the preamble that were not deserialized during...
Definition: ParsedAST.cpp:471
clang::clangd::TestTU::build
ParsedAST build() const
Definition: TestTU.cpp:80
Tracer
std::unique_ptr< trace::EventTracer > Tracer
Definition: TraceTests.cpp:163
clang::clangd::SelectionTree::createEach
static bool createEach(ASTContext &AST, const syntax::TokenBuffer &Tokens, unsigned Begin, unsigned End, llvm::function_ref< bool(SelectionTree)> Func)
Definition: Selection.cpp:775
TestTU.h
Selected
SelectionTree::Selection Selected
Definition: Selection.cpp:368
clang::clangd::ParsedAST::getLangOpts
const LangOptions & getLangOpts() const
Definition: ParsedAST.h:81
clang::clangd::SelectionTree::Complete
Definition: Selection.h:118
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:246
Offset
size_t Offset
Definition: CodeComplete.cpp:1044
Code
std::string Code
Definition: FindTargetTests.cpp:67
Decl
const FunctionDecl * Decl
Definition: AvoidBindCheck.cpp:100
clang::clangd::SelectionTree::createRight
static SelectionTree createRight(ASTContext &AST, const syntax::TokenBuffer &Tokens, unsigned Begin, unsigned End)
Definition: Selection.cpp:787
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:175
clang::clangd::offsetToPosition
Position offsetToPosition(llvm::StringRef Code, size_t Offset)
Turn an offset in Code into a [line, column] pair.
Definition: SourceCode.cpp:208
clang::clangd::TestTU::withCode
static TestTU withCode(llvm::StringRef Code)
Definition: TestTU.h:35
Annotations.h
TestTracer.h
SourceCode.h
clang::clangd::ParsedAST::getDiagnostics
const std::vector< Diag > & getDiagnostics() const
Definition: ParsedAST.cpp:493
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::clangd::ParsedAST::getTokens
const syntax::TokenBuffer & getTokens() const
Tokens recorded while parsing the main file.
Definition: ParsedAST.h:103
clang::clangd::SelectionTree::Partial
Definition: Selection.h:116
clang::clangd::ParsedAST::getSourceManager
SourceManager & getSourceManager()
Definition: ParsedAST.h:74
clang::clangd::TestTU::AdditionalFiles
llvm::StringMap< std::string > AdditionalFiles
Definition: TestTU.h:56