[AMDGPU][AsmParser][NFC] Translate parsed MIMG instructions to MCInsts automatically.
[llvm-project.git] / clang-tools-extra / clangd / unittests / SelectionTests.cpp
blob422a89a49630d33368d518c26d73c13bbea7f0fd
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"
18 namespace clang {
19 namespace clangd {
20 namespace {
21 using ::testing::ElementsAreArray;
22 using ::testing::UnorderedElementsAreArray;
24 // Create a selection tree corresponding to a point or pair of points.
25 // This uses the precisely-defined createRight semantics. The fuzzier
26 // createEach is tested separately.
27 SelectionTree makeSelectionTree(const StringRef MarkedCode, ParsedAST &AST) {
28 Annotations Test(MarkedCode);
29 switch (Test.points().size()) {
30 case 1: { // Point selection.
31 unsigned Offset = cantFail(positionToOffset(Test.code(), Test.point()));
32 return SelectionTree::createRight(AST.getASTContext(), AST.getTokens(),
33 Offset, Offset);
35 case 2: // Range selection.
36 return SelectionTree::createRight(
37 AST.getASTContext(), AST.getTokens(),
38 cantFail(positionToOffset(Test.code(), Test.points()[0])),
39 cantFail(positionToOffset(Test.code(), Test.points()[1])));
40 default:
41 ADD_FAILURE() << "Expected 1-2 points for selection.\n" << MarkedCode;
42 return SelectionTree::createRight(AST.getASTContext(), AST.getTokens(), 0u,
43 0u);
47 Range nodeRange(const SelectionTree::Node *N, ParsedAST &AST) {
48 if (!N)
49 return Range{};
50 const SourceManager &SM = AST.getSourceManager();
51 const LangOptions &LangOpts = AST.getLangOpts();
52 StringRef Buffer = SM.getBufferData(SM.getMainFileID());
53 if (llvm::isa_and_nonnull<TranslationUnitDecl>(N->ASTNode.get<Decl>()))
54 return Range{Position{}, offsetToPosition(Buffer, Buffer.size())};
55 auto FileRange =
56 toHalfOpenFileRange(SM, LangOpts, N->ASTNode.getSourceRange());
57 assert(FileRange && "We should be able to get the File Range");
58 return Range{
59 offsetToPosition(Buffer, SM.getFileOffset(FileRange->getBegin())),
60 offsetToPosition(Buffer, SM.getFileOffset(FileRange->getEnd()))};
63 std::string nodeKind(const SelectionTree::Node *N) {
64 return N ? N->kind() : "<null>";
67 std::vector<const SelectionTree::Node *> allNodes(const SelectionTree &T) {
68 std::vector<const SelectionTree::Node *> Result = {&T.root()};
69 for (unsigned I = 0; I < Result.size(); ++I) {
70 const SelectionTree::Node *N = Result[I];
71 Result.insert(Result.end(), N->Children.begin(), N->Children.end());
73 return Result;
76 // Returns true if Common is a descendent of Root.
77 // Verifies nothing is selected above Common.
78 bool verifyCommonAncestor(const SelectionTree::Node &Root,
79 const SelectionTree::Node *Common,
80 StringRef MarkedCode) {
81 if (&Root == Common)
82 return true;
83 if (Root.Selected)
84 ADD_FAILURE() << "Selected nodes outside common ancestor\n" << MarkedCode;
85 bool Seen = false;
86 for (const SelectionTree::Node *Child : Root.Children)
87 if (verifyCommonAncestor(*Child, Common, MarkedCode)) {
88 if (Seen)
89 ADD_FAILURE() << "Saw common ancestor twice\n" << MarkedCode;
90 Seen = true;
92 return Seen;
95 TEST(SelectionTest, CommonAncestor) {
96 struct Case {
97 // Selection is between ^marks^.
98 // common ancestor marked with a [[range]].
99 const char *Code;
100 const char *CommonAncestorKind;
102 Case Cases[] = {
104 R"cpp(
105 template <typename T>
106 int x = [[T::^U::]]ccc();
107 )cpp",
108 "NestedNameSpecifierLoc",
111 R"cpp(
112 struct AAA { struct BBB { static int ccc(); };};
113 int x = AAA::[[B^B^B]]::ccc();
114 )cpp",
115 "RecordTypeLoc",
118 R"cpp(
119 struct AAA { struct BBB { static int ccc(); };};
120 int x = AAA::[[B^BB^]]::ccc();
121 )cpp",
122 "RecordTypeLoc",
125 R"cpp(
126 struct AAA { struct BBB { static int ccc(); };};
127 int x = [[AAA::BBB::c^c^c]]();
128 )cpp",
129 "DeclRefExpr",
132 R"cpp(
133 struct AAA { struct BBB { static int ccc(); };};
134 int x = [[AAA::BBB::cc^c(^)]];
135 )cpp",
136 "CallExpr",
140 R"cpp(
141 void foo() { [[if (1^11) { return; } else {^ }]] }
142 )cpp",
143 "IfStmt",
146 R"cpp(
147 int x(int);
148 #define M(foo) x(foo)
149 int a = 42;
150 int b = M([[^a]]);
151 )cpp",
152 "DeclRefExpr",
155 R"cpp(
156 void foo();
157 #define CALL_FUNCTION(X) X()
158 void bar() { CALL_FUNCTION([[f^o^o]]); }
159 )cpp",
160 "DeclRefExpr",
163 R"cpp(
164 void foo();
165 #define CALL_FUNCTION(X) X()
166 void bar() { [[CALL_FUNC^TION(fo^o)]]; }
167 )cpp",
168 "CallExpr",
171 R"cpp(
172 void foo();
173 #define CALL_FUNCTION(X) X()
174 void bar() { [[C^ALL_FUNC^TION(foo)]]; }
175 )cpp",
176 "CallExpr",
179 R"cpp(
180 void foo();
181 #^define CALL_FUNCTION(X) X(^)
182 void bar() { CALL_FUNCTION(foo); }
183 )cpp",
184 nullptr,
187 R"cpp(
188 void foo();
189 #define CALL_FUNCTION(X) X()
190 void bar() { CALL_FUNCTION(foo^)^; }
191 )cpp",
192 nullptr,
195 R"cpp(
196 namespace ns {
197 #if 0
198 void fo^o() {}
199 #endif
201 )cpp",
202 nullptr,
205 R"cpp(
206 #define TARGET void foo()
207 [[TAR^GET{ return; }]]
208 )cpp",
209 "FunctionDecl",
212 R"cpp(
213 struct S { S(const char*); };
214 [[S s ^= "foo"]];
215 )cpp",
216 // The AST says a CXXConstructExpr covers the = sign in C++14.
217 // But we consider CXXConstructExpr to only own brackets.
218 // (It's not the interesting constructor anyway, just S(&&)).
219 "VarDecl",
222 R"cpp(
223 struct S { S(const char*); };
224 [[S ^s = "foo"]];
225 )cpp",
226 "VarDecl",
229 R"cpp(
230 [[^void]] (*S)(int) = nullptr;
231 )cpp",
232 "BuiltinTypeLoc",
235 R"cpp(
236 [[void (*S)^(int)]] = nullptr;
237 )cpp",
238 "FunctionProtoTypeLoc",
241 R"cpp(
242 [[void (^*S)(int)]] = nullptr;
243 )cpp",
244 "PointerTypeLoc",
247 R"cpp(
248 [[void (*^S)(int) = nullptr]];
249 )cpp",
250 "VarDecl",
253 R"cpp(
254 [[void ^(*S)(int)]] = nullptr;
255 )cpp",
256 "ParenTypeLoc",
259 R"cpp(
260 struct S {
261 int foo() const;
262 int bar() { return [[f^oo]](); }
264 )cpp",
265 "MemberExpr", // Not implicit CXXThisExpr, or its implicit cast!
268 R"cpp(
269 auto lambda = [](const char*){ return 0; };
270 int x = lambda([["y^"]]);
271 )cpp",
272 "StringLiteral", // Not DeclRefExpr to operator()!
275 R"cpp(
276 struct Foo {};
277 struct Bar : [[v^ir^tual private Foo]] {};
278 )cpp",
279 "CXXBaseSpecifier",
282 R"cpp(
283 struct Foo {};
284 struct Bar : private [[Fo^o]] {};
285 )cpp",
286 "RecordTypeLoc",
289 R"cpp(
290 struct Foo {};
291 struct Bar : [[Fo^o]] {};
292 )cpp",
293 "RecordTypeLoc",
296 // Point selections.
297 {"void foo() { [[^foo]](); }", "DeclRefExpr"},
298 {"void foo() { [[f^oo]](); }", "DeclRefExpr"},
299 {"void foo() { [[fo^o]](); }", "DeclRefExpr"},
300 {"void foo() { [[foo^()]]; }", "CallExpr"},
301 {"void foo() { [[foo^]] (); }", "DeclRefExpr"},
302 {"int bar; void foo() [[{ foo (); }]]^", "CompoundStmt"},
303 {"int x = [[42]]^;", "IntegerLiteral"},
305 // Ignores whitespace, comments, and semicolons in the selection.
306 {"void foo() { [[foo^()]]; /*comment*/^}", "CallExpr"},
308 // Tricky case: FunctionTypeLoc in FunctionDecl has a hole in it.
309 {"[[^void]] foo();", "BuiltinTypeLoc"},
310 {"[[void foo^()]];", "FunctionProtoTypeLoc"},
311 {"[[^void foo^()]];", "FunctionDecl"},
312 {"[[void ^foo()]];", "FunctionDecl"},
313 // Tricky case: two VarDecls share a specifier.
314 {"[[int ^a]], b;", "VarDecl"},
315 {"[[int a, ^b]];", "VarDecl"},
316 // Tricky case: CXXConstructExpr wants to claim the whole init range.
318 R"cpp(
319 struct X { X(int); };
320 class Y {
321 X x;
322 Y() : [[^x(4)]] {}
324 )cpp",
325 "CXXCtorInitializer", // Not the CXXConstructExpr!
327 // Tricky case: anonymous struct is a sibling of the VarDecl.
328 {"[[st^ruct {int x;}]] y;", "CXXRecordDecl"},
329 {"[[struct {int x;} ^y]];", "VarDecl"},
330 {"struct {[[int ^x]];} y;", "FieldDecl"},
332 // Tricky case: nested ArrayTypeLocs have the same token range.
333 {"const int x = 1, y = 2; int array[^[[x]]][10][y];", "DeclRefExpr"},
334 {"const int x = 1, y = 2; int array[x][10][^[[y]]];", "DeclRefExpr"},
335 {"const int x = 1, y = 2; int array[x][^[[10]]][y];", "IntegerLiteral"},
336 {"const int x = 1, y = 2; [[i^nt]] array[x][10][y];", "BuiltinTypeLoc"},
337 {"void func(int x) { int v_array[^[[x]]][10]; }", "DeclRefExpr"},
339 {"int (*getFunc([[do^uble]]))(int);", "BuiltinTypeLoc"},
341 // Member pointers and pack expansion use declarator syntax, but are
342 // restricted so they don't need special casing.
343 {"class X{}; [[int X::^*]]y[10];", "MemberPointerTypeLoc"},
344 {"template<typename ...T> void foo([[T*^...]]x);",
345 "PackExpansionTypeLoc"},
346 {"template<typename ...T> void foo([[^T]]*...x);",
347 "TemplateTypeParmTypeLoc"},
349 // FIXME: the AST has no location info for qualifiers.
350 {"const [[a^uto]] x = 42;", "AutoTypeLoc"},
351 {"co^nst auto x = 42;", nullptr},
353 {"^", nullptr},
354 {"void foo() { [[foo^^]] (); }", "DeclRefExpr"},
356 // FIXME: Ideally we'd get a declstmt or the VarDecl itself here.
357 // This doesn't happen now; the RAV doesn't traverse a node containing ;.
358 {"int x = 42;^", nullptr},
360 // Common ancestor is logically TUDecl, but we never return that.
361 {"^int x; int y;^", nullptr},
363 // Node types that have caused problems in the past.
364 {"template <typename T> void foo() { [[^T]] t; }",
365 "TemplateTypeParmTypeLoc"},
367 // No crash
369 R"cpp(
370 template <class T> struct Foo {};
371 template <[[template<class> class /*cursor here*/^U]]>
372 struct Foo<U<int>*> {};
373 )cpp",
374 "TemplateTemplateParmDecl"},
376 // Foreach has a weird AST, ensure we can select parts of the range init.
377 // This used to fail, because the DeclStmt for C claimed the whole range.
379 R"cpp(
380 struct Str {
381 const char *begin();
382 const char *end();
384 Str makeStr(const char*);
385 void loop() {
386 for (const char C : [[mak^eStr("foo"^)]])
389 )cpp",
390 "CallExpr"},
392 // User-defined literals are tricky: is 12_i one token or two?
393 // For now we treat it as one, and the UserDefinedLiteral as a leaf.
395 R"cpp(
396 struct Foo{};
397 Foo operator""_ud(unsigned long long);
398 Foo x = [[^12_ud]];
399 )cpp",
400 "UserDefinedLiteral"},
403 R"cpp(
404 int a;
405 decltype([[^a]] + a) b;
406 )cpp",
407 "DeclRefExpr"},
408 {"[[decltype^(1)]] b;", "DecltypeTypeLoc"}, // Not the VarDecl.
409 // decltype(auto) is an AutoTypeLoc!
410 {"[[de^cltype(a^uto)]] a = 1;", "AutoTypeLoc"},
412 // Objective-C nullability attributes.
414 R"cpp(
415 @interface I{}
416 @property(nullable) [[^I]] *x;
417 @end
418 )cpp",
419 "ObjCInterfaceTypeLoc"},
421 R"cpp(
422 @interface I{}
423 - (void)doSomething:(nonnull [[i^d]])argument;
424 @end
425 )cpp",
426 "TypedefTypeLoc"},
428 // Objective-C OpaqueValueExpr/PseudoObjectExpr has weird ASTs.
429 // Need to traverse the contents of the OpaqueValueExpr to the POE,
430 // and ensure we traverse only the syntactic form of the PseudoObjectExpr.
432 R"cpp(
433 @interface I{}
434 @property(retain) I*x;
435 @property(retain) I*y;
436 @end
437 void test(I *f) { [[^f]].x.y = 0; }
438 )cpp",
439 "DeclRefExpr"},
441 R"cpp(
442 @interface I{}
443 @property(retain) I*x;
444 @property(retain) I*y;
445 @end
446 void test(I *f) { [[f.^x]].y = 0; }
447 )cpp",
448 "ObjCPropertyRefExpr"},
449 // Examples with implicit properties.
451 R"cpp(
452 @interface I{}
453 -(int)foo;
454 @end
455 int test(I *f) { return 42 + [[^f]].foo; }
456 )cpp",
457 "DeclRefExpr"},
459 R"cpp(
460 @interface I{}
461 -(int)foo;
462 @end
463 int test(I *f) { return 42 + [[f.^foo]]; }
464 )cpp",
465 "ObjCPropertyRefExpr"},
466 {"struct foo { [[int has^h<:32:>]]; };", "FieldDecl"},
467 {"struct foo { [[op^erator int()]]; };", "CXXConversionDecl"},
468 {"struct foo { [[^~foo()]]; };", "CXXDestructorDecl"},
469 {"struct foo { [[~^foo()]]; };", "CXXDestructorDecl"},
470 {"template <class T> struct foo { ~foo<[[^T]]>(){} };",
471 "TemplateTypeParmTypeLoc"},
472 {"struct foo {}; void bar(foo *f) { [[f->~^foo]](); }", "MemberExpr"},
473 {"struct foo { [[fo^o(){}]] };", "CXXConstructorDecl"},
475 {R"cpp(
476 struct S1 { void f(); };
477 struct S2 { S1 * operator->(); };
478 void test(S2 s2) {
479 s2[[-^>]]f();
481 )cpp",
482 "DeclRefExpr"}, // DeclRefExpr to the "operator->" method.
484 // Template template argument.
485 {R"cpp(
486 template <typename> class Vector {};
487 template <template <typename> class Container> class A {};
488 A<[[V^ector]]> a;
489 )cpp",
490 "TemplateArgumentLoc"},
492 // Attributes
493 {R"cpp(
494 void f(int * __attribute__(([[no^nnull]])) );
495 )cpp",
496 "NonNullAttr"},
498 {R"cpp(
499 // Digraph syntax for attributes to avoid accidental annotations.
500 class <:[gsl::Owner([[in^t]])]:> X{};
501 )cpp",
502 "BuiltinTypeLoc"},
504 // This case used to crash - AST has a null Attr
505 {R"cpp(
506 @interface I
507 [[@property(retain, nonnull) <:[My^Object2]:> *x]]; // error-ok
508 @end
509 )cpp",
510 "ObjCPropertyDecl"},
512 {R"cpp(
513 typedef int Foo;
514 enum Bar : [[Fo^o]] {};
515 )cpp",
516 "TypedefTypeLoc"},
517 {R"cpp(
518 typedef int Foo;
519 enum Bar : [[Fo^o]];
520 )cpp",
521 "TypedefTypeLoc"},
523 // lambda captured var-decl
524 {R"cpp(
525 void test(int bar) {
526 auto l = [^[[foo = bar]]] { };
527 })cpp",
528 "VarDecl"},
529 {R"cpp(
530 /*error-ok*/
531 void func() [[{^]])cpp",
532 "CompoundStmt"},
533 {R"cpp(
534 void func() { [[__^func__]]; }
535 )cpp",
536 "PredefinedExpr"},
538 // using enum
539 {R"cpp(
540 namespace ns { enum class A {}; };
541 using enum ns::[[^A]];
542 )cpp",
543 "EnumTypeLoc"},
544 {R"cpp(
545 namespace ns { enum class A {}; using B = A; };
546 using enum ns::[[^B]];
547 )cpp",
548 "TypedefTypeLoc"},
549 {R"cpp(
550 namespace ns { enum class A {}; };
551 using enum [[^ns::]]A;
552 )cpp",
553 "NestedNameSpecifierLoc"},
554 {R"cpp(
555 namespace ns { enum class A {}; };
556 [[using ^enum ns::A]];
557 )cpp",
558 "UsingEnumDecl"},
559 {R"cpp(
560 namespace ns { enum class A {}; };
561 [[^using enum ns::A]];
562 )cpp",
563 "UsingEnumDecl"},
566 for (const Case &C : Cases) {
567 trace::TestTracer Tracer;
568 Annotations Test(C.Code);
570 TestTU TU;
571 TU.Code = std::string(Test.code());
573 TU.ExtraArgs.push_back("-xobjective-c++");
574 TU.ExtraArgs.push_back("-std=c++20");
576 auto AST = TU.build();
577 auto T = makeSelectionTree(C.Code, AST);
578 EXPECT_EQ("TranslationUnitDecl", nodeKind(&T.root())) << C.Code;
580 if (Test.ranges().empty()) {
581 // If no [[range]] is marked in the example, there should be no selection.
582 EXPECT_FALSE(T.commonAncestor()) << C.Code << "\n" << T;
583 EXPECT_THAT(Tracer.takeMetric("selection_recovery", "C++"),
584 testing::IsEmpty());
585 } else {
586 // If there is an expected selection, common ancestor should exist
587 // with the appropriate node type.
588 EXPECT_EQ(C.CommonAncestorKind, nodeKind(T.commonAncestor()))
589 << C.Code << "\n"
590 << T;
591 // Convert the reported common ancestor to a range and verify it.
592 EXPECT_EQ(nodeRange(T.commonAncestor(), AST), Test.range())
593 << C.Code << "\n"
594 << T;
596 // Check that common ancestor is reachable on exactly one path from root,
597 // and no nodes outside it are selected.
598 EXPECT_TRUE(verifyCommonAncestor(T.root(), T.commonAncestor(), C.Code))
599 << C.Code;
600 EXPECT_THAT(Tracer.takeMetric("selection_recovery", "C++"),
601 ElementsAreArray({0}));
606 // Regression test: this used to match the injected X, not the outer X.
607 TEST(SelectionTest, InjectedClassName) {
608 const char *Code = "struct ^X { int x; };";
609 auto AST = TestTU::withCode(Annotations(Code).code()).build();
610 auto T = makeSelectionTree(Code, AST);
611 ASSERT_EQ("CXXRecordDecl", nodeKind(T.commonAncestor())) << T;
612 auto *D = dyn_cast<CXXRecordDecl>(T.commonAncestor()->ASTNode.get<Decl>());
613 EXPECT_FALSE(D->isInjectedClassName());
616 TEST(SelectionTree, Metrics) {
617 const char *Code = R"cpp(
618 // error-ok: testing behavior on recovery expression
619 int foo();
620 int foo(int, int);
621 int x = fo^o(42);
622 )cpp";
623 auto AST = TestTU::withCode(Annotations(Code).code()).build();
624 trace::TestTracer Tracer;
625 auto T = makeSelectionTree(Code, AST);
626 EXPECT_THAT(Tracer.takeMetric("selection_recovery", "C++"),
627 ElementsAreArray({1}));
628 EXPECT_THAT(Tracer.takeMetric("selection_recovery_type", "C++"),
629 ElementsAreArray({1}));
632 // FIXME: Doesn't select the binary operator node in
633 // #define FOO(X) X + 1
634 // int a, b = [[FOO(a)]];
635 TEST(SelectionTest, Selected) {
636 // Selection with ^marks^.
637 // Partially selected nodes marked with a [[range]].
638 // Completely selected nodes marked with a $C[[range]].
639 const char *Cases[] = {
640 R"cpp( int abc, xyz = [[^ab^c]]; )cpp",
641 R"cpp( int abc, xyz = [[a^bc^]]; )cpp",
642 R"cpp( int abc, xyz = $C[[^abc^]]; )cpp",
643 R"cpp(
644 void foo() {
645 [[if ([[1^11]]) $C[[{
646 $C[[return]];
647 }]] else [[{^
648 }]]]]
649 char z;
651 )cpp",
652 R"cpp(
653 template <class T>
654 struct unique_ptr {};
655 void foo(^$C[[unique_ptr<$C[[unique_ptr<$C[[int]]>]]>]]^ a) {}
656 )cpp",
657 R"cpp(int a = [[5 >^> 1]];)cpp",
658 R"cpp(
659 #define ECHO(X) X
660 ECHO(EC^HO($C[[int]]) EC^HO(a));
661 )cpp",
662 R"cpp( $C[[^$C[[int]] a^]]; )cpp",
663 R"cpp( $C[[^$C[[int]] a = $C[[5]]^]]; )cpp",
665 for (const char *C : Cases) {
666 Annotations Test(C);
667 auto AST = TestTU::withCode(Test.code()).build();
668 auto T = makeSelectionTree(C, AST);
670 std::vector<Range> Complete, Partial;
671 for (const SelectionTree::Node *N : allNodes(T))
672 if (N->Selected == SelectionTree::Complete)
673 Complete.push_back(nodeRange(N, AST));
674 else if (N->Selected == SelectionTree::Partial)
675 Partial.push_back(nodeRange(N, AST));
676 EXPECT_THAT(Complete, UnorderedElementsAreArray(Test.ranges("C"))) << C;
677 EXPECT_THAT(Partial, UnorderedElementsAreArray(Test.ranges())) << C;
681 TEST(SelectionTest, PathologicalPreprocessor) {
682 const char *Case = R"cpp(
683 #define MACRO while(1)
684 void test() {
685 #include "Expand.inc"
686 br^eak;
688 )cpp";
689 Annotations Test(Case);
690 auto TU = TestTU::withCode(Test.code());
691 TU.AdditionalFiles["Expand.inc"] = "MACRO\n";
692 auto AST = TU.build();
693 EXPECT_THAT(AST.getDiagnostics(), ::testing::IsEmpty());
694 auto T = makeSelectionTree(Case, AST);
696 EXPECT_EQ("BreakStmt", T.commonAncestor()->kind());
697 EXPECT_EQ("WhileStmt", T.commonAncestor()->Parent->kind());
700 TEST(SelectionTest, IncludedFile) {
701 const char *Case = R"cpp(
702 void test() {
703 #include "Exp^and.inc"
704 break;
706 )cpp";
707 Annotations Test(Case);
708 auto TU = TestTU::withCode(Test.code());
709 TU.AdditionalFiles["Expand.inc"] = "while(1)\n";
710 auto AST = TU.build();
711 auto T = makeSelectionTree(Case, AST);
713 EXPECT_EQ(nullptr, T.commonAncestor());
716 TEST(SelectionTest, MacroArgExpansion) {
717 // If a macro arg is expanded several times, we only consider the first one
718 // selected.
719 const char *Case = R"cpp(
720 int mul(int, int);
721 #define SQUARE(X) mul(X, X);
722 int nine = SQUARE(^3);
723 )cpp";
724 Annotations Test(Case);
725 auto AST = TestTU::withCode(Test.code()).build();
726 auto T = makeSelectionTree(Case, AST);
727 EXPECT_EQ("IntegerLiteral", T.commonAncestor()->kind());
728 EXPECT_TRUE(T.commonAncestor()->Selected);
730 // Verify that the common assert() macro doesn't suffer from this.
731 // (This is because we don't associate the stringified token with the arg).
732 Case = R"cpp(
733 void die(const char*);
734 #define assert(x) (x ? (void)0 : die(#x))
735 void foo() { assert(^42); }
736 )cpp";
737 Test = Annotations(Case);
738 AST = TestTU::withCode(Test.code()).build();
739 T = makeSelectionTree(Case, AST);
740 EXPECT_EQ("IntegerLiteral", T.commonAncestor()->kind());
742 // Reduced from private bug involving RETURN_IF_ERROR.
743 // Due to >>-splitting and a bug in isBeforeInTranslationUnit, the inner
744 // S<int> would claim way too many tokens.
745 Case = R"cpp(
746 #define ID(x) x
747 template <typename T> class S {};
749 ID(S<S<int>> x);
750 int ^y;
752 )cpp";
753 Test = Annotations(Case);
754 AST = TestTU::withCode(Test.code()).build();
755 T = makeSelectionTree(Case, AST);
756 // not TemplateSpecializationTypeLoc!
757 EXPECT_EQ("VarDecl", T.commonAncestor()->kind());
760 TEST(SelectionTest, Implicit) {
761 const char *Test = R"cpp(
762 struct S { S(const char*); };
763 int f(S);
764 int x = f("^");
765 )cpp";
766 auto TU = TestTU::withCode(Annotations(Test).code());
767 // C++14 AST contains some temporaries that C++17 elides.
768 TU.ExtraArgs.push_back("-std=c++17");
769 auto AST = TU.build();
770 auto T = makeSelectionTree(Test, AST);
772 const SelectionTree::Node *Str = T.commonAncestor();
773 EXPECT_EQ("StringLiteral", nodeKind(Str)) << "Implicit selected?";
774 EXPECT_EQ("ImplicitCastExpr", nodeKind(Str->Parent));
775 EXPECT_EQ("CXXConstructExpr", nodeKind(Str->Parent->Parent));
776 const SelectionTree::Node *ICE = Str->Parent->Parent->Parent;
777 EXPECT_EQ("ImplicitCastExpr", nodeKind(ICE));
778 EXPECT_EQ("CallExpr", nodeKind(ICE->Parent));
779 EXPECT_EQ(Str, &ICE->ignoreImplicit())
780 << "Didn't unwrap " << nodeKind(&ICE->ignoreImplicit());
782 EXPECT_EQ(ICE, &Str->outerImplicit());
785 TEST(SelectionTest, CreateAll) {
786 llvm::Annotations Test("int$unique^ a=1$ambiguous^+1; $empty^");
787 auto AST = TestTU::withCode(Test.code()).build();
788 unsigned Seen = 0;
789 SelectionTree::createEach(
790 AST.getASTContext(), AST.getTokens(), Test.point("ambiguous"),
791 Test.point("ambiguous"), [&](SelectionTree T) {
792 // Expect to see the right-biased tree first.
793 if (Seen == 0) {
794 EXPECT_EQ("BinaryOperator", nodeKind(T.commonAncestor()));
795 } else if (Seen == 1) {
796 EXPECT_EQ("IntegerLiteral", nodeKind(T.commonAncestor()));
798 ++Seen;
799 return false;
801 EXPECT_EQ(2u, Seen);
803 Seen = 0;
804 SelectionTree::createEach(AST.getASTContext(), AST.getTokens(),
805 Test.point("ambiguous"), Test.point("ambiguous"),
806 [&](SelectionTree T) {
807 ++Seen;
808 return true;
810 EXPECT_EQ(1u, Seen) << "Return true --> stop iterating";
812 Seen = 0;
813 SelectionTree::createEach(AST.getASTContext(), AST.getTokens(),
814 Test.point("unique"), Test.point("unique"),
815 [&](SelectionTree T) {
816 ++Seen;
817 return false;
819 EXPECT_EQ(1u, Seen) << "no ambiguity --> only one tree";
821 Seen = 0;
822 SelectionTree::createEach(AST.getASTContext(), AST.getTokens(),
823 Test.point("empty"), Test.point("empty"),
824 [&](SelectionTree T) {
825 EXPECT_FALSE(T.commonAncestor());
826 ++Seen;
827 return false;
829 EXPECT_EQ(1u, Seen) << "empty tree still created";
831 Seen = 0;
832 SelectionTree::createEach(AST.getASTContext(), AST.getTokens(),
833 Test.point("unique"), Test.point("ambiguous"),
834 [&](SelectionTree T) {
835 ++Seen;
836 return false;
838 EXPECT_EQ(1u, Seen) << "one tree for nontrivial selection";
841 TEST(SelectionTest, DeclContextIsLexical) {
842 llvm::Annotations Test("namespace a { void $1^foo(); } void a::$2^foo();");
843 auto AST = TestTU::withCode(Test.code()).build();
845 auto ST = SelectionTree::createRight(AST.getASTContext(), AST.getTokens(),
846 Test.point("1"), Test.point("1"));
847 EXPECT_FALSE(ST.commonAncestor()->getDeclContext().isTranslationUnit());
850 auto ST = SelectionTree::createRight(AST.getASTContext(), AST.getTokens(),
851 Test.point("2"), Test.point("2"));
852 EXPECT_TRUE(ST.commonAncestor()->getDeclContext().isTranslationUnit());
856 } // namespace
857 } // namespace clangd
858 } // namespace clang