13 #include "clang/Basic/FileManager.h" 14 #include "clang/Basic/FileSystemOptions.h" 15 #include "clang/Frontend/CompilerInstance.h" 16 #include "clang/Index/IndexingAction.h" 17 #include "clang/Index/IndexingOptions.h" 18 #include "clang/Tooling/Tooling.h" 19 #include "llvm/ADT/IntrusiveRefCntPtr.h" 20 #include "llvm/ADT/STLExtras.h" 21 #include "llvm/ADT/StringRef.h" 22 #include "llvm/Support/MemoryBuffer.h" 23 #include "llvm/Support/VirtualFileSystem.h" 24 #include "gmock/gmock-matchers.h" 25 #include "gmock/gmock-more-matchers.h" 26 #include "gmock/gmock.h" 27 #include "gtest/gtest.h" 37 using ::testing::AllOf;
38 using ::testing::Contains;
39 using ::testing::Each;
40 using ::testing::ElementsAre;
41 using ::testing::Field;
42 using ::testing::IsEmpty;
44 using ::testing::Pair;
45 using ::testing::UnorderedElementsAre;
46 using ::testing::UnorderedElementsAreArray;
50 return (arg.Name + arg.Signature).str() == Label;
53 MATCHER_P(Doc,
D,
"") {
return arg.Documentation ==
D; }
55 return (arg.Name + arg.CompletionSnippetSuffix).str() == S;
59 return arg.TemplateSpecializationArgs == TemplArgs;
62 return StringRef(arg.CanonicalDeclaration.FileURI) == P;
64 MATCHER_P(DefURI, P,
"") {
return StringRef(arg.Definition.FileURI) == P; }
65 MATCHER(IncludeHeader,
"") {
return !arg.IncludeHeaders.empty(); }
67 return (arg.IncludeHeaders.size() == 1) &&
68 (arg.IncludeHeaders.begin()->IncludeHeader == P);
71 return (arg.IncludeHeader == IncludeHeader) && (arg.References ==
References);
73 bool rangesMatch(
const SymbolLocation &
Loc,
const Range &R) {
74 return std::make_tuple(
Loc.Start.line(),
Loc.Start.column(),
Loc.End.line(),
76 std::make_tuple(R.start.line, R.start.character, R.end.line,
80 return rangesMatch(arg.CanonicalDeclaration,
Pos);
82 MATCHER_P(DefRange,
Pos,
"") {
return rangesMatch(arg.Definition,
Pos); }
83 MATCHER_P(RefCount, R,
"") {
return int(arg.References) == R; }
84 MATCHER_P(ForCodeCompletion, IsIndexedForCodeCompletion,
"") {
86 IsIndexedForCodeCompletion;
89 MATCHER(ImplementationDetail,
"") {
92 MATCHER(VisibleOutsideFile,
"") {
96 const Ref &
Pos = ::testing::get<0>(arg);
98 return rangesMatch(
Pos.Location,
Range);
100 MATCHER_P2(OverriddenBy, Subject, Object,
"") {
103 ::testing::Matcher<const std::vector<Ref> &>
104 HaveRanges(
const std::vector<Range> Ranges) {
105 return ::testing::UnorderedPointwise(RefRange(), Ranges);
108 class ShouldCollectSymbolTest :
public ::testing::Test {
110 void build(llvm::StringRef HeaderCode, llvm::StringRef
Code =
"") {
113 File.HeaderCode = std::string(HeaderCode);
119 bool shouldCollect(llvm::StringRef
Name,
bool Qualified =
true) {
120 assert(
AST.hasValue());
121 const NamedDecl &ND =
123 const SourceManager &SM =
AST->getSourceManager();
126 ND,
AST->getASTContext(), SymbolCollector::Options(),
MainFile);
133 llvm::Optional<ParsedAST>
AST;
136 TEST_F(ShouldCollectSymbolTest, ShouldCollectSymbol) {
140 auto f() { int Local; } // auto ensures function body is parsed. 141 struct { int x; } var; 146 namespace { class InAnonymous {}; } 149 auto AST = File.build();
150 EXPECT_TRUE(shouldCollect(
"nx"));
151 EXPECT_TRUE(shouldCollect(
"nx::X"));
152 EXPECT_TRUE(shouldCollect(
"nx::f"));
153 EXPECT_TRUE(shouldCollect(
"InMain"));
154 EXPECT_TRUE(shouldCollect(
"InAnonymous",
false));
155 EXPECT_TRUE(shouldCollect(
"g"));
157 EXPECT_FALSE(shouldCollect(
"Local",
false));
160 TEST_F(ShouldCollectSymbolTest, NoPrivateProtoSymbol) {
163 R
"(// Generated by the protocol buffer compiler. DO NOT EDIT! 172 EXPECT_TRUE(shouldCollect("nx::TopLevel"));
173 EXPECT_TRUE(shouldCollect(
"nx::Kind::KIND_OK"));
174 EXPECT_TRUE(shouldCollect(
"nx::Kind"));
176 EXPECT_FALSE(shouldCollect(
"nx::Top_Level"));
177 EXPECT_FALSE(shouldCollect(
"nx::Kind::Kind_Not_Ok"));
180 TEST_F(ShouldCollectSymbolTest, DoubleCheckProtoHeaderComment) {
190 EXPECT_TRUE(shouldCollect("nx::Top_Level"));
191 EXPECT_TRUE(shouldCollect(
"nx::Kind_Fine"));
194 class SymbolIndexActionFactory :
public tooling::FrontendActionFactory {
196 SymbolIndexActionFactory(SymbolCollector::Options
COpts,
200 std::unique_ptr<FrontendAction> create()
override {
201 class IndexAction :
public ASTFrontendAction {
203 IndexAction(std::shared_ptr<index::IndexDataConsumer> DataConsumer,
204 const index::IndexingOptions &Opts,
206 : DataConsumer(std::move(DataConsumer)), Opts(Opts),
209 std::unique_ptr<ASTConsumer>
210 CreateASTConsumer(CompilerInstance &
CI, llvm::StringRef InFile)
override {
213 return createIndexingASTConsumer(DataConsumer, Opts,
214 CI.getPreprocessorPtr());
217 bool BeginInvocation(CompilerInstance &
CI)
override {
219 CI.getLangOpts().CommentOpts.ParseAllComments =
true;
224 std::shared_ptr<index::IndexDataConsumer> DataConsumer;
225 index::IndexingOptions Opts;
228 index::IndexingOptions IndexOpts;
229 IndexOpts.SystemSymbolFilter =
230 index::IndexingOptions::SystemSymbolFilterKind::All;
231 IndexOpts.IndexFunctionLocals =
false;
233 return std::make_unique<IndexAction>(
Collector, std::move(IndexOpts),
242 class SymbolCollectorTest :
public ::testing::Test {
244 SymbolCollectorTest()
254 bool runSymbolCollector(llvm::StringRef HeaderCode, llvm::StringRef MainCode,
255 const std::vector<std::string> &ExtraArgs = {}) {
256 llvm::IntrusiveRefCntPtr<FileManager> Files(
259 auto Factory = std::make_unique<SymbolIndexActionFactory>(
262 std::vector<std::string>
Args = {
"symbol_collector",
"-fsyntax-only",
264 Args.insert(
Args.end(), ExtraArgs.begin(), ExtraArgs.end());
269 tooling::ToolInvocation Invocation(
270 Args, Factory->create(), Files.get(),
271 std::make_shared<PCHContainerOperations>());
274 llvm::MemoryBuffer::getMemBuffer(HeaderCode));
276 llvm::MemoryBuffer::getMemBuffer(MainCode));
278 Symbols = Factory->Collector->takeSymbols();
279 Refs = Factory->Collector->takeRefs();
280 Relations = Factory->Collector->takeRelations();
297 TEST_F(SymbolCollectorTest, CollectSymbols) {
298 const std::string Header = R
"( 305 Foo& operator=(const Foo&); 316 static const int KInt = 2; 317 const char* kStr = "123"; 320 void ff() {} // ignore 328 using int32_t = int32; 343 runSymbolCollector(Header, "");
345 UnorderedElementsAreArray(
346 {AllOf(QName(
"Foo"), ForCodeCompletion(
true)),
347 AllOf(QName(
"Foo::Foo"), ForCodeCompletion(
false)),
348 AllOf(QName(
"Foo::Foo"), ForCodeCompletion(
false)),
349 AllOf(QName(
"Foo::f"), ForCodeCompletion(
false)),
350 AllOf(QName(
"Foo::~Foo"), ForCodeCompletion(
false)),
351 AllOf(QName(
"Foo::operator="), ForCodeCompletion(
false)),
352 AllOf(QName(
"Foo::Nested"), ForCodeCompletion(
false)),
353 AllOf(QName(
"Foo::Nested::f"), ForCodeCompletion(
false)),
355 AllOf(QName(
"Friend"), ForCodeCompletion(
true)),
356 AllOf(QName(
"f1"), ForCodeCompletion(
true)),
357 AllOf(QName(
"f2"), ForCodeCompletion(
true)),
358 AllOf(QName(
"KInt"), ForCodeCompletion(
true)),
359 AllOf(QName(
"kStr"), ForCodeCompletion(
true)),
360 AllOf(QName(
"foo"), ForCodeCompletion(
true)),
361 AllOf(QName(
"foo::bar"), ForCodeCompletion(
true)),
362 AllOf(QName(
"foo::int32"), ForCodeCompletion(
true)),
363 AllOf(QName(
"foo::int32_t"), ForCodeCompletion(
true)),
364 AllOf(QName(
"foo::v1"), ForCodeCompletion(
true)),
365 AllOf(QName(
"foo::bar::v2"), ForCodeCompletion(
true)),
366 AllOf(QName(
"foo::v2"), ForCodeCompletion(
true)),
367 AllOf(QName(
"foo::baz"), ForCodeCompletion(
true))}));
370 TEST_F(SymbolCollectorTest, FileLocal) {
371 const std::string Header = R
"( 378 const std::string Main = R
"( 387 runSymbolCollector(Header, Main); 389 UnorderedElementsAre( 390 AllOf(QName("Foo"), VisibleOutsideFile()),
391 AllOf(QName(
"bar"), VisibleOutsideFile()),
392 AllOf(QName(
"a"), Not(VisibleOutsideFile())),
393 AllOf(QName(
"B"), Not(VisibleOutsideFile())),
394 AllOf(QName(
"c"), Not(VisibleOutsideFile())),
396 AllOf(QName(
"ForwardDecl"), Not(VisibleOutsideFile()))));
399 TEST_F(SymbolCollectorTest, Template) {
400 Annotations Header(R
"( 401 // Primary template and explicit specialization are indexed, instantiation 403 template <class T, class U> struct [[Tmpl]] {T $xdecl[[x]] = 0;}; 404 template <> struct $specdecl[[Tmpl]]<int, bool> {}; 405 template <class U> struct $partspecdecl[[Tmpl]]<bool, U> {}; 406 extern template struct Tmpl<float, bool>; 407 template struct Tmpl<double, bool>; 409 runSymbolCollector(Header.code(), "");
411 UnorderedElementsAre(
412 AllOf(QName(
"Tmpl"), DeclRange(Header.range()),
413 ForCodeCompletion(
true)),
414 AllOf(QName(
"Tmpl"), DeclRange(Header.range(
"specdecl")),
415 ForCodeCompletion(
false)),
416 AllOf(QName(
"Tmpl"), DeclRange(Header.range(
"partspecdecl")),
417 ForCodeCompletion(
false)),
418 AllOf(QName(
"Tmpl::x"), DeclRange(Header.range(
"xdecl")),
419 ForCodeCompletion(
false))));
422 TEST_F(SymbolCollectorTest, TemplateArgs) {
423 Annotations Header(R
"( 424 template <class X> class $barclasstemp[[Bar]] {}; 425 template <class T, class U, template<typename> class Z, int Q> 426 struct [[Tmpl]] { T $xdecl[[x]] = 0; }; 428 // template-template, non-type and type full spec 429 template <> struct $specdecl[[Tmpl]]<int, bool, Bar, 3> {}; 431 // template-template, non-type and type partial spec 432 template <class U, int T> struct $partspecdecl[[Tmpl]]<bool, U, Bar, T> {}; 434 extern template struct Tmpl<float, bool, Bar, 8>; 436 template struct Tmpl<double, bool, Bar, 2>; 438 template <typename ...> class $fooclasstemp[[Foo]] {}; 439 // parameter-packs full spec 440 template<> class $parampack[[Foo]]<Bar<int>, int, double> {}; 441 // parameter-packs partial spec 442 template<class T> class $parampackpartial[[Foo]]<T, T> {}; 444 template <int ...> class $bazclasstemp[[Baz]] {}; 445 // non-type parameter-packs full spec 446 template<> class $parampacknontype[[Baz]]<3, 5, 8> {}; 447 // non-type parameter-packs partial spec 448 template<int T> class $parampacknontypepartial[[Baz]]<T, T> {}; 450 template <template <class> class ...> class $fozclasstemp[[Foz]] {}; 451 // template-template parameter-packs full spec 452 template<> class $parampacktempltempl[[Foz]]<Bar, Bar> {}; 453 // template-template parameter-packs partial spec 454 template<template <class> class T> 455 class $parampacktempltemplpartial[[Foz]]<T, T> {}; 457 runSymbolCollector(Header.code(), "");
461 Contains(AllOf(QName(
"Tmpl"), TemplateArgs(
"<int, bool, Bar, 3>"),
462 DeclRange(Header.range(
"specdecl")),
463 ForCodeCompletion(
false))),
464 Contains(AllOf(QName(
"Tmpl"), TemplateArgs(
"<bool, U, Bar, T>"),
465 DeclRange(Header.range(
"partspecdecl")),
466 ForCodeCompletion(
false))),
467 Contains(AllOf(QName(
"Foo"), TemplateArgs(
"<Bar<int>, int, double>"),
468 DeclRange(Header.range(
"parampack")),
469 ForCodeCompletion(
false))),
470 Contains(AllOf(QName(
"Foo"), TemplateArgs(
"<T, T>"),
471 DeclRange(Header.range(
"parampackpartial")),
472 ForCodeCompletion(
false))),
473 Contains(AllOf(QName(
"Baz"), TemplateArgs(
"<3, 5, 8>"),
474 DeclRange(Header.range(
"parampacknontype")),
475 ForCodeCompletion(
false))),
476 Contains(AllOf(QName(
"Baz"), TemplateArgs(
"<T, T>"),
477 DeclRange(Header.range(
"parampacknontypepartial")),
478 ForCodeCompletion(
false))),
479 Contains(AllOf(QName(
"Foz"), TemplateArgs(
"<Bar, Bar>"),
480 DeclRange(Header.range(
"parampacktempltempl")),
481 ForCodeCompletion(
false))),
482 Contains(AllOf(QName(
"Foz"), TemplateArgs(
"<T, T>"),
483 DeclRange(Header.range(
"parampacktempltemplpartial")),
484 ForCodeCompletion(
false)))));
487 TEST_F(SymbolCollectorTest, ObjCSymbols) {
488 const std::string Header = R
"( 490 - (void)someMethodName:(void*)name1 lastName:(void*)lName; 493 @implementation Person 494 - (void)someMethodName:(void*)name1 lastName:(void*)lName{ 496 ^(int param){ int bar; }; 500 @interface Person (MyCategory) 501 - (void)someMethodName2:(void*)name2; 504 @implementation Person (MyCategory) 505 - (void)someMethodName2:(void*)name2 { 511 - (void)someMethodName3:(void*)name3; 515 runSymbolCollector(Header,
"", {
"-fblocks",
"-xobjective-c++"});
517 UnorderedElementsAre(
518 QName(
"Person"), QName(
"Person::someMethodName:lastName:"),
519 QName(
"MyCategory"), QName(
"Person::someMethodName2:"),
520 QName(
"MyProtocol"), QName(
"MyProtocol::someMethodName3:")));
523 TEST_F(SymbolCollectorTest, ObjCPropertyImpl) {
524 const std::string Header = R
"( 526 @property(nonatomic) int magic; 529 @implementation Container 533 runSymbolCollector(Header,
"", {
"-xobjective-c++"});
534 EXPECT_THAT(
Symbols, Contains(QName(
"Container")));
535 EXPECT_THAT(
Symbols, Contains(QName(
"Container::magic")));
540 TEST_F(SymbolCollectorTest, ObjCLocations) {
541 Annotations Header(R
"( 542 // Declared in header, defined in main. 543 @interface $dogdecl[[Dog]] 545 @interface $fluffydecl[[Dog]] (Fluffy) 551 @implementation $dogdef[[Dog]] 553 @implementation $fluffydef[[Dog]] (Fluffy) 555 // Category with no declaration (only implementation). 556 @implementation $ruff[[Dog]] (Ruff) 558 // Implicitly defined interface. 559 @implementation $catdog[[CatDog]] 562 runSymbolCollector(Header.code(), Main.code(), 563 {"-xobjective-c++",
"-Wno-objc-root-class"});
565 UnorderedElementsAre(
566 AllOf(QName(
"Dog"), DeclRange(Header.range(
"dogdecl")),
567 DefRange(Main.range(
"dogdef"))),
568 AllOf(QName(
"Fluffy"), DeclRange(Header.range(
"fluffydecl")),
569 DefRange(Main.range(
"fluffydef"))),
570 AllOf(QName(
"CatDog"), DeclRange(Main.range(
"catdog")),
571 DefRange(Main.range(
"catdog"))),
572 AllOf(QName(
"Ruff"), DeclRange(Main.range(
"ruff")),
573 DefRange(Main.range(
"ruff")))));
576 TEST_F(SymbolCollectorTest, ObjCForwardDecls) {
577 Annotations Header(R
"( 578 // Forward declared in header, declared and defined in main. 581 // Never fully declared so Clang latches onto this decl. 582 @class $catdogdecl[[CatDog]]; 585 @protocol $barkerdecl[[Barker]] 588 @interface $dogdecl[[Dog]]<Barker> 591 @implementation $dogdef[[Dog]] 594 @implementation $catdogdef[[CatDog]] 597 runSymbolCollector(Header.code(), Main.code(), 598 {"-xobjective-c++",
"-Wno-objc-root-class"});
600 UnorderedElementsAre(
601 AllOf(QName(
"CatDog"), DeclRange(Header.range(
"catdogdecl")),
602 DefRange(Main.range(
"catdogdef"))),
603 AllOf(QName(
"Dog"), DeclRange(Main.range(
"dogdecl")),
604 DefRange(Main.range(
"dogdef"))),
605 AllOf(QName(
"Barker"), DeclRange(Main.range(
"barkerdecl"))),
606 QName(
"Barker::woof"), QName(
"Dog::woof")));
609 TEST_F(SymbolCollectorTest, ObjCClassExtensions) {
610 Annotations Header(R
"( 611 @interface $catdecl[[Cat]] 622 runSymbolCollector(Header.code(), Main.code(), 623 {"-xobjective-c++",
"-Wno-objc-root-class"});
625 UnorderedElementsAre(
626 AllOf(QName(
"Cat"), DeclRange(Header.range(
"catdecl"))),
627 QName(
"Cat::meow"), QName(
"Cat::pur")));
630 TEST_F(SymbolCollectorTest, Locations) {
631 Annotations Header(R
"cpp( 632 // Declared in header, defined in main. 633 extern int $xdecl[[X]]; 634 class $clsdecl[[Cls]]; 635 void $printdecl[[print]](); 637 // Declared in header, defined nowhere. 638 extern int $zdecl[[Z]]; 643 Annotations Main(R"cpp( 645 class $clsdef[[Cls]] {}; 646 void $printdef[[print]]() {} 648 // Declared/defined in main only. 651 runSymbolCollector(Header.code(), Main.code()); 653 UnorderedElementsAre( 654 AllOf(QName("X"), DeclRange(Header.range(
"xdecl")),
655 DefRange(Main.range(
"xdef"))),
656 AllOf(QName(
"Cls"), DeclRange(Header.range(
"clsdecl")),
657 DefRange(Main.range(
"clsdef"))),
658 AllOf(QName(
"print"), DeclRange(Header.range(
"printdecl")),
659 DefRange(Main.range(
"printdef"))),
660 AllOf(QName(
"Z"), DeclRange(Header.range(
"zdecl"))),
661 AllOf(QName(
"foo"), DeclRange(Header.range(
"foodecl"))),
662 AllOf(QName(
"Y"), DeclRange(Main.range(
"ydecl")))));
666 Annotations Header(R
"( 667 #define MACRO(X) (X + 1) 676 namespace NS {} // namespace ref is ignored 679 class $bar[[Bar]] {}; 681 void $func[[func]](); 688 $foo[[Foo]] foo2 = abc; 689 abc = $macro[[MACRO]](1); 692 Annotations SymbolsOnlyInMainCode(R"( 693 #define FUNC(X) (X+1) 696 static const int c = FUNC(1); 701 runSymbolCollector(Header.code(),
702 (Main.code() + SymbolsOnlyInMainCode.code()).str());
704 HaveRanges(Main.ranges(
"foo")))));
706 HaveRanges(Main.ranges(
"bar")))));
708 HaveRanges(Main.ranges(
"func")))));
711 HaveRanges(Main.ranges(
"macro")))));
719 EXPECT_THAT(
Refs, Not(Contains(Pair(
findSymbol(MainSymbols,
"FUNC").
ID, _))));
727 runSymbolCollector(Header.code(),
728 (Main.code() + SymbolsOnlyInMainCode.code()).str());
736 TEST_F(SymbolCollectorTest, RefContainers) {
737 Annotations
Code(R
"cpp( 738 int $toplevel1[[f1]](int); 740 (void) $ref1a[[f1]](1); 741 auto fptr = &$ref1b[[f1]]; 743 int $toplevel2[[v1]] = $ref2[[f1]](2); 744 void f3(int arg = $ref3[[f1]](3)); 746 int $classscope1[[member1]] = $ref4[[f1]](4); 747 int $classscope2[[member2]] = 42; 749 constexpr int f4(int x) { return x + 1; } 750 template <int I = $ref5[[f4]](0)> struct S2 {}; 751 S2<$ref6[[f4]](0)> v2; 752 S2<$ref7a[[f4]](0)> f5(S2<$ref7b[[f4]](0)>); 754 void $namespacescope1[[f6]](); 755 int $namespacescope2[[v3]]; 760 runSymbolCollector(
"",
Code.code());
761 auto FindRefWithRange = [&](
Range R) -> Optional<Ref> {
763 for (
auto &Ref :
Entry.second) {
764 if (rangesMatch(Ref.Location, R))
770 auto Container = [&](llvm::StringRef RangeName) {
771 auto Ref = FindRefWithRange(
Code.range(RangeName));
772 EXPECT_TRUE(
bool(Ref));
773 return Ref->Container;
775 EXPECT_EQ(Container(
"ref1a"),
777 EXPECT_EQ(Container(
"ref1b"),
779 EXPECT_EQ(Container(
"ref2"),
781 EXPECT_EQ(Container(
"ref3"),
783 EXPECT_EQ(Container(
"ref4"),
785 EXPECT_EQ(Container(
"ref5"),
787 EXPECT_EQ(Container(
"ref6"),
789 EXPECT_EQ(Container(
"ref7a"),
791 EXPECT_EQ(Container(
"ref7b"),
794 EXPECT_FALSE(Container(
"classscope1").isNull());
795 EXPECT_FALSE(Container(
"namespacescope1").isNull());
797 EXPECT_EQ(Container(
"toplevel1"), Container(
"toplevel2"));
798 EXPECT_EQ(Container(
"classscope1"), Container(
"classscope2"));
799 EXPECT_EQ(Container(
"namespacescope1"), Container(
"namespacescope2"));
801 EXPECT_NE(Container(
"toplevel1"), Container(
"namespacescope1"));
802 EXPECT_NE(Container(
"toplevel1"), Container(
"classscope1"));
803 EXPECT_NE(Container(
"classscope1"), Container(
"namespacescope1"));
806 TEST_F(SymbolCollectorTest, MacroRefInHeader) {
807 Annotations Header(R
"( 808 #define $foo[[FOO]](X) (X + 1) 809 #define $bar[[BAR]](X) (X + 2) 811 // Macro defined multiple times. 813 int ud_1 = $ud1[[UD]]; 817 int ud_2 = $ud2[[UD]]; 820 // Macros from token concatenations not included. 821 #define $concat[[CONCAT]](X) X##A() 822 #define $prepend[[PREPEND]](X) MACRO##X() 823 #define $macroa[[MACROA]]() 123 824 int B = $concat[[CONCAT]](MACRO); 825 int D = $prepend[[PREPEND]](A); 828 int abc = $foo[[FOO]](1) + $bar[[BAR]]($foo[[FOO]](1)); 836 runSymbolCollector(Header.code(),
"");
839 HaveRanges(Header.ranges(
"foo")))));
841 HaveRanges(Header.ranges(
"bar")))));
843 EXPECT_THAT(
Refs, Contains(Pair(_, HaveRanges(Header.ranges(
"ud1")))));
844 EXPECT_THAT(
Refs, Contains(Pair(_, HaveRanges(Header.ranges(
"ud2")))));
846 HaveRanges(Header.ranges(
"concat")))));
848 HaveRanges(Header.ranges(
"prepend")))));
850 HaveRanges(Header.ranges(
"macroa")))));
853 TEST_F(SymbolCollectorTest, MacroRefWithoutCollectingSymbol) {
854 Annotations Header(R
"( 855 #define $foo[[FOO]](X) (X + 1) 856 int abc = $foo[[FOO]](1); 861 runSymbolCollector(Header.code(),
"");
862 EXPECT_THAT(
Refs, Contains(Pair(_, HaveRanges(Header.ranges(
"foo")))));
865 TEST_F(SymbolCollectorTest, MacrosWithRefFilter) {
866 Annotations Header(
"#define $macro[[MACRO]](X) (X + 1)");
867 Annotations Main(
"void foo() { int x = $macro[[MACRO]](1); }");
869 runSymbolCollector(Header.code(), Main.code());
870 EXPECT_THAT(
Refs, IsEmpty());
873 TEST_F(SymbolCollectorTest, SpelledReferences) {
875 llvm::StringRef Header;
876 llvm::StringRef Main;
877 llvm::StringRef TargetSymbolName;
885 struct $spelled[[Foo]] { 889 $spelled[[Foo]] Variable1; 890 $implicit[[MACRO]] Variable2; 902 void f() { Foo $implicit[[f]]; f = $spelled[[Foo]]();} 909 for (
const auto& T : TestCases) {
910 Annotations Header(T.Header);
911 Annotations Main(T.Main);
914 runSymbolCollector(Header.code(), Main.code());
916 const auto SpelledRanges = Main.ranges(
"spelled");
917 const auto ImplicitRanges = Main.ranges(
"implicit");
920 for (
const auto &SymbolAndRefs :
Refs) {
921 const auto ID = SymbolAndRefs.first;
924 for (
const auto &Ref : SymbolAndRefs.second)
926 SpelledSlabBuilder.insert(
ID, Ref);
928 ImplicitSlabBuilder.insert(
ID, Ref);
930 const auto SpelledRefs = std::move(SpelledSlabBuilder).build(),
931 ImplicitRefs = std::move(ImplicitSlabBuilder).build();
932 EXPECT_THAT(SpelledRefs,
933 Contains(Pair(TargetID, HaveRanges(SpelledRanges))));
934 EXPECT_THAT(ImplicitRefs,
935 Contains(Pair(TargetID, HaveRanges(ImplicitRanges))));
939 TEST_F(SymbolCollectorTest, NameReferences) {
942 Annotations Header(R
"( 950 runSymbolCollector(Header.code(), "");
954 HaveRanges(Header.ranges()))));
957 TEST_F(SymbolCollectorTest, RefsOnMacros) {
962 Annotations Header(R
"( 965 #define CAT(X, Y) X##Y 970 TYPE(TYPE([[Foo]])) foo3; 975 runSymbolCollector(Header.code(), "");
977 HaveRanges(Header.ranges()))));
980 TEST_F(SymbolCollectorTest, HeaderAsMainFile) {
982 Annotations Header(R
"( 983 class $Foo[[Foo]] {}; 985 void $Func[[Func]]() { 993 runSymbolCollector(
"", Header.code());
996 HaveRanges(Header.ranges(
"Foo"))),
998 HaveRanges(Header.ranges(
"Func")))));
1002 runSymbolCollector(
"", Header.code(),
1003 {
"-xobjective-c++-header"});
1004 EXPECT_THAT(
Symbols, UnorderedElementsAre(QName(
"Foo"), QName(
"Func")));
1007 HaveRanges(Header.ranges(
"Foo"))),
1009 HaveRanges(Header.ranges(
"Func")))));
1013 runSymbolCollector(
"", Header.code());
1014 EXPECT_THAT(
Symbols, UnorderedElementsAre(QName(
"Foo"), QName(
"Func")));
1017 HaveRanges(Header.ranges(
"Foo"))),
1019 HaveRanges(Header.ranges(
"Func")))));
1022 TEST_F(SymbolCollectorTest, RefsInHeaders) {
1026 Annotations Header(R
"( 1027 #define $macro[[MACRO]](x) (x+1) 1028 class $foo[[Foo]] {}; 1030 runSymbolCollector(Header.code(), "");
1032 HaveRanges(Header.ranges(
"foo")))));
1034 HaveRanges(Header.ranges(
"macro")))));
1037 TEST_F(SymbolCollectorTest, BaseOfRelations) {
1038 std::string Header = R
"( 1040 class Derived : public Base {}; 1042 runSymbolCollector(Header, "");
1049 TEST_F(SymbolCollectorTest, OverrideRelationsSimpleInheritance) {
1050 std::string Header = R
"cpp( 1054 class B : public A { 1055 void foo() override; // A::foo 1058 class C : public B { 1059 void bar() override; // B::bar 1062 void foo() override; // B::foo 1063 void bar() override; // C::bar 1066 runSymbolCollector(Header, "");
1075 std::vector<Relation> Result;
1078 Result.push_back(R);
1079 EXPECT_THAT(Result, UnorderedElementsAre(
1084 TEST_F(SymbolCollectorTest, OverrideRelationsMultipleInheritance) {
1085 std::string Header = R
"cpp( 1092 class C : public B { 1093 void bar() override; // B::bar 1096 class D : public A, C { 1097 void foo() override; // A::foo 1098 void bar() override; // C::bar 1099 void baz() override; // C::baz 1102 runSymbolCollector(Header, "");
1111 std::vector<Relation> Result;
1114 Result.push_back(R);
1115 EXPECT_THAT(Result, UnorderedElementsAre(
1120 TEST_F(SymbolCollectorTest, CountReferences) {
1121 const std::string Header = R
"( 1125 class Z {}; // not used anywhere 1126 Y* y = nullptr; // used in header doesn't count 1127 #define GLOBAL_Z(name) Z name; 1129 const std::string Main = R
"( 1131 W* w2 = nullptr; // only one usage counts 1134 class Y{}; // definition doesn't count as a reference 1136 GLOBAL_Z(z); // Not a reference to Z, we don't spell the type. 1139 runSymbolCollector(Header, Main);
1142 UnorderedElementsAreArray(
1143 {AllOf(QName(
"W"), RefCount(1)), AllOf(QName(
"X"), RefCount(1)),
1144 AllOf(QName(
"Y"), RefCount(0)), AllOf(QName(
"Z"), RefCount(0)),
1145 AllOf(QName(
"y"), RefCount(0)), AllOf(QName(
"z"), RefCount(0)),
1146 AllOf(QName(
"x"), RefCount(0)), AllOf(QName(
"w"), RefCount(0)),
1147 AllOf(QName(
"w2"), RefCount(0)), AllOf(QName(
"V"), RefCount(1)),
1148 AllOf(QName(
"v"), RefCount(0))}));
1151 TEST_F(SymbolCollectorTest, SymbolRelativeNoFallback) {
1152 runSymbolCollector(
"class Foo {};",
"");
1153 EXPECT_THAT(
Symbols, UnorderedElementsAre(
1157 TEST_F(SymbolCollectorTest, SymbolRelativeWithFallback) {
1162 runSymbolCollector(
"class Foo {};",
"");
1163 EXPECT_THAT(
Symbols, UnorderedElementsAre(
1167 TEST_F(SymbolCollectorTest, UnittestURIScheme) {
1171 runSymbolCollector(
"class Foo {};",
"");
1172 EXPECT_THAT(
Symbols, UnorderedElementsAre(
1173 AllOf(QName(
"Foo"), DeclURI(
"unittest:///x.h"))));
1176 TEST_F(SymbolCollectorTest, IncludeEnums) {
1177 const std::string Header = R
"( 1193 runSymbolCollector(Header, "");
1195 UnorderedElementsAre(
1196 AllOf(QName(
"Red"), ForCodeCompletion(
true)),
1197 AllOf(QName(
"Color"), ForCodeCompletion(
true)),
1198 AllOf(QName(
"Green"), ForCodeCompletion(
true)),
1199 AllOf(QName(
"Color2"), ForCodeCompletion(
true)),
1200 AllOf(QName(
"Color2::Yellow"), ForCodeCompletion(
false)),
1201 AllOf(QName(
"ns"), ForCodeCompletion(
true)),
1202 AllOf(QName(
"ns::Black"), ForCodeCompletion(
true))));
1205 TEST_F(SymbolCollectorTest, NamelessSymbols) {
1206 const std::string Header = R
"( 1211 runSymbolCollector(Header, "");
1212 EXPECT_THAT(
Symbols, UnorderedElementsAre(QName(
"Foo"),
1213 QName(
"(anonymous struct)::a")));
1216 TEST_F(SymbolCollectorTest, SymbolFormedFromRegisteredSchemeFromMacro) {
1218 Annotations Header(R
"( 1220 class name##_Test {}; 1222 $expansion[[FF]](abc); 1225 class $spelling[[Test]] {}; 1230 runSymbolCollector(Header.code(), "");
1232 UnorderedElementsAre(
1233 AllOf(QName(
"abc_Test"), DeclRange(Header.range(
"expansion")),
1235 AllOf(QName(
"Test"), DeclRange(Header.range(
"spelling")),
1239 TEST_F(SymbolCollectorTest, SymbolFormedByCLI) {
1240 Annotations Header(R
"( 1242 class $expansion[[NAME]] {}; 1245 runSymbolCollector(Header.code(), "", {
"-DNAME=name"});
1246 EXPECT_THAT(
Symbols, UnorderedElementsAre(AllOf(
1247 QName(
"name"), DeclRange(Header.range(
"expansion")),
1251 TEST_F(SymbolCollectorTest, SymbolsInMainFile) {
1252 const std::string Main = R
"( 1268 runSymbolCollector("", Main);
1269 EXPECT_THAT(
Symbols, UnorderedElementsAre(
1270 QName(
"Foo"), QName(
"f1"), QName(
"f2"), QName(
"ff"),
1271 QName(
"foo"), QName(
"foo::Bar"), QName(
"main_f")));
1274 TEST_F(SymbolCollectorTest, Documentation) {
1275 const std::string Header = R
"( 1283 runSymbolCollector(Header,
"");
1285 UnorderedElementsAre(
1286 AllOf(QName(
"Foo"), Doc(
"Doc Foo"), ForCodeCompletion(
true)),
1287 AllOf(QName(
"Foo::f"), Doc(
""),
ReturnType(
""),
1288 ForCodeCompletion(
false))));
1291 runSymbolCollector(Header,
"");
1293 UnorderedElementsAre(
1294 AllOf(QName(
"Foo"), Doc(
"Doc Foo"), ForCodeCompletion(
true)),
1295 AllOf(QName(
"Foo::f"), Doc(
"Doc f"),
ReturnType(
""),
1296 ForCodeCompletion(
false))));
1299 TEST_F(SymbolCollectorTest, ClassMembers) {
1300 const std::string Header = R
"( 1309 const std::string Main = R
"( 1313 runSymbolCollector(Header, Main); 1316 UnorderedElementsAre( 1318 AllOf(QName(
"Foo::f"),
ReturnType(
""), ForCodeCompletion(
false)),
1319 AllOf(QName(
"Foo::g"),
ReturnType(
""), ForCodeCompletion(
false)),
1320 AllOf(QName(
"Foo::sf"),
ReturnType(
""), ForCodeCompletion(
false)),
1321 AllOf(QName(
"Foo::ssf"),
ReturnType(
""), ForCodeCompletion(
false)),
1322 AllOf(QName(
"Foo::x"),
ReturnType(
""), ForCodeCompletion(
false))));
1325 TEST_F(SymbolCollectorTest, Scopes) {
1326 const std::string Header = R
"( 1334 runSymbolCollector(Header, "");
1336 UnorderedElementsAre(QName(
"na"), QName(
"na::nb"),
1337 QName(
"na::Foo"), QName(
"na::nb::Bar")));
1340 TEST_F(SymbolCollectorTest, ExternC) {
1341 const std::string Header = R
"( 1342 extern "C" { class Foo {}; } 1344 extern "C" { class Bar {}; } 1347 runSymbolCollector(Header, "");
1348 EXPECT_THAT(
Symbols, UnorderedElementsAre(QName(
"na"), QName(
"Foo"),
1352 TEST_F(SymbolCollectorTest, SkipInlineNamespace) {
1353 const std::string Header = R
"( 1355 inline namespace nb { 1360 // This is still inlined. 1366 runSymbolCollector(Header, "");
1368 UnorderedElementsAre(QName(
"na"), QName(
"na::nb"),
1369 QName(
"na::Foo"), QName(
"na::Bar")));
1372 TEST_F(SymbolCollectorTest, SymbolWithDocumentation) {
1373 const std::string Header = R
"( 1376 int ff(int x, double y) { return 0; }
1379 runSymbolCollector(Header,
"");
1382 UnorderedElementsAre(
1383 QName(
"nx"), AllOf(QName(
"nx::ff"), Labeled(
"ff(int x, double y)"),
1387 TEST_F(SymbolCollectorTest, Snippet) {
1388 const std::string Header = R
"( 1391 int ff(int x, double y) { return 0; } 1394 runSymbolCollector(Header, "");
1396 UnorderedElementsAre(
1398 AllOf(QName(
"nx::f"), Labeled(
"f()"),
Snippet(
"f()")),
1399 AllOf(QName(
"nx::ff"), Labeled(
"ff(int x, double y)"),
1400 Snippet(
"ff(${1:int x}, ${2:double y})"))));
1403 TEST_F(SymbolCollectorTest, IncludeHeaderSameAsFileURI) {
1405 runSymbolCollector(
"#pragma once\nclass Foo {};",
"");
1406 EXPECT_THAT(
Symbols, UnorderedElementsAre(
1409 UnorderedElementsAre(IncludeHeaderWithRef(
TestHeaderURI, 1u)));
1412 TEST_F(SymbolCollectorTest, CanonicalSTLHeader) {
1414 CanonicalIncludes Includes;
1415 auto Language = LangOptions();
1416 Language.CPlusPlus =
true;
1417 Includes.addSystemHeadersMapping(Language);
1423 // Move overloads have special handling. 1424 template <typename T> T&& move(T&&); 1425 template <typename I, typename O> O move(I, I, O); 1430 llvm::errs() << S.Scope << S.Name <<
" in " << S.IncludeHeaders.size()
1434 UnorderedElementsAre(
1437 IncludeHeader(
"<string>")),
1438 AllOf(Labeled(
"move(T &&)"), IncludeHeader(
"<utility>")),
1439 AllOf(Labeled(
"move(I, I, O)"), IncludeHeader(
"<algorithm>"))));
1442 TEST_F(SymbolCollectorTest, IWYUPragma) {
1444 CanonicalIncludes Includes;
1447 const std::string Header = R
"( 1448 // IWYU pragma: private, include the/good/header.h 1451 runSymbolCollector(Header, "");
1452 EXPECT_THAT(
Symbols, UnorderedElementsAre(
1454 IncludeHeader(
"\"the/good/header.h\""))));
1457 TEST_F(SymbolCollectorTest, IWYUPragmaWithDoubleQuotes) {
1459 CanonicalIncludes Includes;
1462 const std::string Header = R
"( 1463 // IWYU pragma: private, include "the/good/header.h" 1466 runSymbolCollector(Header, "");
1467 EXPECT_THAT(
Symbols, UnorderedElementsAre(
1469 IncludeHeader(
"\"the/good/header.h\""))));
1472 TEST_F(SymbolCollectorTest, SkipIncFileWhenCanonicalizeHeaders) {
1474 CanonicalIncludes Includes;
1477 auto IncFile =
testPath(
"test.inc");
1480 llvm::MemoryBuffer::getMemBuffer(
"class X {};"));
1481 runSymbolCollector(
"#include \"test.inc\"\nclass Y {};",
"",
1484 UnorderedElementsAre(AllOf(QName(
"X"), DeclURI(IncURI),
1485 IncludeHeader(
"<canonical>")),
1487 IncludeHeader(
"<canonical>"))));
1490 TEST_F(SymbolCollectorTest, MainFileIsHeaderWhenSkipIncFile) {
1496 auto IncFile =
testPath(
"test.inc");
1499 llvm::MemoryBuffer::getMemBuffer(
"class X {};"));
1500 runSymbolCollector(
"", R
"cpp( 1501 // Can't use #pragma once in a main file clang doesn't think is a header. 1508 EXPECT_THAT(
Symbols, UnorderedElementsAre(AllOf(QName(
"X"), DeclURI(IncURI),
1512 TEST_F(SymbolCollectorTest, IncFileInNonHeader) {
1516 auto IncFile =
testPath(
"test.inc");
1519 llvm::MemoryBuffer::getMemBuffer(
"class X {};"));
1520 runSymbolCollector(
"", R
"cpp( 1524 EXPECT_THAT(
Symbols, UnorderedElementsAre(AllOf(QName(
"X"), DeclURI(IncURI),
1525 Not(IncludeHeader()))));
1530 TEST_F(SymbolCollectorTest, HeaderGuardDetected) {
1533 runSymbolCollector(R
"cpp( 1534 #ifndef HEADER_GUARD_ 1535 #define HEADER_GUARD_ 1537 // Symbols are seen before the header guard is complete. 1541 #endif // Header guard is recognized here. 1544 EXPECT_THAT(
Symbols, Not(Contains(QName(
"HEADER_GUARD_"))));
1545 EXPECT_THAT(
Symbols, Each(IncludeHeader()));
1548 TEST_F(SymbolCollectorTest, NonModularHeader) {
1550 EXPECT_THAT(TU.headerSymbols(), ElementsAre(IncludeHeader()));
1553 TU.ImplicitHeaderGuard =
false;
1554 EXPECT_THAT(TU.headerSymbols(), ElementsAre(Not(IncludeHeader())));
1559 #error "This file isn't safe to include directly" 1563 TU.ExtraArgs.push_back("-DSECRET");
1564 EXPECT_THAT(TU.headerSymbols(), ElementsAre(Not(IncludeHeader())));
1567 TEST_F(SymbolCollectorTest, AvoidUsingFwdDeclsAsCanonicalDecls) {
1569 Annotations Header(R
"( 1571 // Forward declarations of TagDecls. 1576 // Canonical declarations. 1577 class $cdecl[[C]] {}; 1578 struct $sdecl[[S]] {}; 1579 union $udecl[[U]] {int $xdecl[[x]]; bool $ydecl[[y]];}; 1581 runSymbolCollector(Header.code(), "");
1584 UnorderedElementsAre(
1586 DeclRange(Header.range(
"cdecl")), IncludeHeader(
TestHeaderURI),
1589 DeclRange(Header.range(
"sdecl")), IncludeHeader(
TestHeaderURI),
1592 DeclRange(Header.range(
"udecl")), IncludeHeader(
TestHeaderURI),
1596 DefRange(Header.range(
"xdecl"))),
1599 DefRange(Header.range(
"ydecl")))));
1602 TEST_F(SymbolCollectorTest, ClassForwardDeclarationIsCanonical) {
1604 runSymbolCollector(
"#pragma once\nclass X;",
1606 EXPECT_THAT(
Symbols, UnorderedElementsAre(AllOf(
1611 TEST_F(SymbolCollectorTest, UTF16Character) {
1613 Annotations Header(
"class [[pörk]] {};");
1614 runSymbolCollector(Header.code(),
"");
1615 EXPECT_THAT(
Symbols, UnorderedElementsAre(
1616 AllOf(QName(
"pörk"), DeclRange(Header.range()))));
1619 TEST_F(SymbolCollectorTest, DoNotIndexSymbolsInFriendDecl) {
1620 Annotations Header(R
"( 1627 friend void $bar[[bar]]() {} 1633 runSymbolCollector(Header.code(), "");
1636 UnorderedElementsAre(
1637 QName(
"nx"), QName(
"nx::X"),
1638 AllOf(QName(
"nx::Y"), DeclRange(Header.range(
"y"))),
1639 AllOf(QName(
"nx::Z"), DeclRange(Header.range(
"z"))),
1640 AllOf(QName(
"nx::foo"), DeclRange(Header.range(
"foo"))),
1641 AllOf(QName(
"nx::bar"), DeclRange(Header.range(
"bar")))));
1644 TEST_F(SymbolCollectorTest, ReferencesInFriendDecl) {
1645 const std::string Header = R
"( 1649 const std::string Main = R
"( 1656 runSymbolCollector(Header, Main);
1657 EXPECT_THAT(
Symbols, UnorderedElementsAre(AllOf(QName(
"X"), RefCount(1)),
1658 AllOf(QName(
"Y"), RefCount(1)),
1659 AllOf(QName(
"C"), RefCount(0))));
1662 TEST_F(SymbolCollectorTest, Origin) {
1664 runSymbolCollector(
"class Foo {};",
"");
1665 EXPECT_THAT(
Symbols, UnorderedElementsAre(
1667 runSymbolCollector(
"#define FOO",
"");
1668 EXPECT_THAT(
Symbols, UnorderedElementsAre(
1672 TEST_F(SymbolCollectorTest, CollectMacros) {
1674 Annotations Header(R
"( 1677 #define $mac[[MAC]](x) int x 1678 #define $used[[USED]](y) float y; 1683 Annotations Main(R"( 1684 #define $main[[MAIN]] 1 1689 runSymbolCollector(Header.code(), Main.code());
1692 UnorderedElementsAre(
1693 QName(
"p"), QName(
"t"),
1696 AllOf(Labeled(
"MAC(x)"), RefCount(0),
1698 DeclRange(Header.range(
"mac")), VisibleOutsideFile()),
1699 AllOf(Labeled(
"USED(y)"), RefCount(1),
1700 DeclRange(Header.range(
"used")), VisibleOutsideFile()),
1701 AllOf(Labeled(
"MAIN"), RefCount(0), DeclRange(Main.range(
"main")),
1702 Not(VisibleOutsideFile()))));
1705 TEST_F(SymbolCollectorTest, DeprecatedSymbols) {
1706 const std::string Header = R
"( 1707 void TestClangc() __attribute__((deprecated("", ""))); 1710 runSymbolCollector(Header, "");
1711 EXPECT_THAT(
Symbols, UnorderedElementsAre(
1713 AllOf(QName(
"TestClangd"), Not(
Deprecated()))));
1716 TEST_F(SymbolCollectorTest, ImplementationDetail) {
1717 const std::string Header = R
"( 1718 #define DECL_NAME(x, y) x##_##y##_Decl 1719 #define DECL(x, y) class DECL_NAME(x, y) {}; 1720 DECL(X, Y); // X_Y_Decl 1724 runSymbolCollector(Header, "");
1726 UnorderedElementsAre(
1727 AllOf(QName(
"X_Y_Decl"), ImplementationDetail()),
1728 AllOf(QName(
"Public"), Not(ImplementationDetail()))));
1731 TEST_F(SymbolCollectorTest, UsingDecl) {
1732 const char *Header = R
"( 1737 runSymbolCollector(Header, "");
1738 EXPECT_THAT(
Symbols, Contains(QName(
"std::foo")));
1741 TEST_F(SymbolCollectorTest, CBuiltins) {
1743 const char *Header = R
"( 1744 extern int printf(const char*, ...); 1746 runSymbolCollector(Header, "", {
"-xc"});
1747 EXPECT_THAT(
Symbols, Contains(QName(
"printf")));
1750 TEST_F(SymbolCollectorTest, InvalidSourceLoc) {
1751 const char *Header = R
"( 1752 void operator delete(void*) 1753 __attribute__((__externally_visible__));)"; 1754 runSymbolCollector(Header, "");
1755 EXPECT_THAT(
Symbols, Contains(QName(
"operator delete")));
1758 TEST_F(SymbolCollectorTest, BadUTF8) {
1761 const char *Header =
"int PUNCT = 0;\n" 1762 "/* \xa1 */ int types[] = { /* \xa1 */PUNCT };";
1765 runSymbolCollector(Header,
"");
1766 EXPECT_THAT(
Symbols, Contains(AllOf(QName(
"types"), Doc(
"\xef\xbf\xbd "))));
1767 EXPECT_THAT(
Symbols, Contains(QName(
"PUNCT")));
1772 TEST_F(SymbolCollectorTest, MacrosInHeaders) {
1775 runSymbolCollector(
"",
"#define X");
1777 UnorderedElementsAre(AllOf(QName(
"X"), ForCodeCompletion(
true))));
1781 TEST_F(SymbolCollectorTest, UndefOfModuleMacro) {
1783 TU.AdditionalFiles["bar.h"] = R
"cpp( 1787 TU.AdditionalFiles["foo.h"] =
"#define X 1";
1788 TU.AdditionalFiles[
"module.map"] = R
"cpp( 1794 TU.ExtraArgs.push_back("-fmodules");
1795 TU.ExtraArgs.push_back(
"-fmodule-map-file=" +
testPath(
"module.map"));
1796 TU.OverlayRealFileSystemForModules =
true;
1801 EXPECT_THAT(TU.headerSymbols(), Not(Contains(QName(
"X"))));
std::unique_ptr< CommentHandler > collectIWYUHeaderMaps(CanonicalIncludes *Includes)
Returns a CommentHandler that parses pragma comment on include files to determine when we should incl...
bool CollectMacro
Collect macros.
SymbolCollector::Options CollectorOpts
llvm::IntrusiveRefCntPtr< llvm::vfs::InMemoryFileSystem > InMemoryFileSystem
std::string TestHeaderName
bool isInsideMainFile(SourceLocation Loc, const SourceManager &SM)
Returns true iff Loc is inside the main file.
Symbol is visible to other files (not e.g. a static helper function).
Documents should not be synced at all.
const NamedDecl & findUnqualifiedDecl(ParsedAST &AST, llvm::StringRef Name)
std::string TestHeaderURI
SymbolID ID
The ID of the symbol.
std::unique_ptr< CompilerInvocation > CI
TEST_F(BackgroundIndexTest, NoCrashOnErrorFile)
Symbol is an implementation detail.
SymbolCollector::Options COpts
std::string FallbackDir
When symbol paths cannot be resolved to absolute paths (e.g.
static TestTU withHeaderCode(llvm::StringRef HeaderCode)
Whether or not this symbol is meant to be used for the code completion.
MATCHER_P2(hasFlag, Flag, Path, "")
bool StoreAllDocumentation
If set to true, SymbolCollector will collect doc for all symbols.
std::string testPath(PathRef File, llvm::sys::path::Style Style)
static constexpr llvm::StringLiteral Name
std::shared_ptr< SymbolCollector > Collector
bool CollectMainFileRefs
Collect references to main-file symbols.
static TestTU withCode(llvm::StringRef Code)
CodeCompletionBuilder Builder
static bool shouldCollectSymbol(const NamedDecl &ND, const ASTContext &ASTCtx, const Options &Opts, bool IsMainFileSymbol)
Returns true is ND should be collected.
static llvm::Expected< URI > create(llvm::StringRef AbsolutePath, llvm::StringRef Scheme)
Creates a URI for a file in the given scheme.
bool RefsInHeaders
If set to true, SymbolCollector will collect all refs (from main file and included headers); otherwis...
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
const Symbol & findSymbol(const SymbolSlab &Slab, llvm::StringRef QName)
const_iterator begin() const
CharSourceRange Range
SourceRange for the file name.
Indicates if the symbol is deprecated.
std::unique_ptr< GlobalCompilationDatabase > Base
SymbolOrigin Origin
Where this symbol came from. Usually an index provides a constant value.
const CanonicalIncludes * Includes
If set, this is used to map symbol #include path to a potentially different #include path.
RefKind RefFilter
The symbol ref kinds that will be collected.
const NamedDecl & findDecl(ParsedAST &AST, llvm::StringRef QName)
CommentHandler * PragmaHandler