if (IsOnlyRef && !CollectRef)
return true;
- // ND is the canonical (i.e. first) declaration. If it's in the main file,
- // then no public declaration was visible, so assume it's main-file only.
+ // ND is the canonical (i.e. first) declaration. If it's in the main file
+ // (which is not a header), then no public declaration was visible, so assume
+ // it's main-file only.
bool IsMainFileOnly =
- SM.isWrittenInMainFile(SM.getExpansionLoc(ND->getBeginLoc()));
+ SM.isWrittenInMainFile(SM.getExpansionLoc(ND->getBeginLoc())) &&
+ !ASTCtx->getLangOpts().IsHeaderFile;
// In C, printf is a redecl of an implicit builtin! So check OrigD instead.
if (ASTNode.OrigD->isImplicit() ||
!shouldCollectSymbol(*ND, *ASTCtx, Opts, IsMainFileOnly))
void setIncludeLocation(const Symbol &S, SourceLocation);
// Indexed macros, to be erased if they turned out to be include guards.
llvm::DenseSet<const IdentifierInfo *> IndexedMacros;
- // All refs collected from the AST.
- // Only symbols declared in preamble (from #include) and referenced from the
- // main file will be included.
+ // All refs collected from the AST. It includes:
+ // 1) symbols declared in the preamble and referenced from the main file (
+ // which is not a header), or
+ // 2) symbols declared and referenced from the main file (which is a header)
RefSlab::Builder Refs;
// All relations collected from the AST.
RelationSlab::Builder Relations;
EXPECT_THAT(Refs, Not(Contains(Pair(findSymbol(MainSymbols, "c").ID, _))));
}
+
+TEST_F(SymbolCollectorTest, HeaderAsMainFile) {
+ CollectorOpts.RefFilter = RefKind::All;
+ Annotations Header(R"(
+ class $Foo[[Foo]] {};
+
+ void $Func[[Func]]() {
+ $Foo[[Foo]] fo;
+ }
+ )");
+ // The main file is normal .cpp file, we shouldn't collect any refs of symbols
+ // which are not declared in the preamble.
+ TestFileName = testPath("foo.cpp");
+ runSymbolCollector("", Header.code());
+ EXPECT_THAT(Refs, UnorderedElementsAre());
+
+ // Run the .h file as main file, we should collect the refs.
+ TestFileName = testPath("foo.h");
+ runSymbolCollector("", Header.code(),
+ /*ExtraArgs=*/{"-xobjective-c++-header"});
+ EXPECT_THAT(Symbols, UnorderedElementsAre(QName("Foo"), QName("Func")));
+ EXPECT_THAT(Refs, UnorderedElementsAre(Pair(findSymbol(Symbols, "Foo").ID,
+ HaveRanges(Header.ranges("Foo"))),
+ Pair(findSymbol(Symbols, "Func").ID,
+ HaveRanges(Header.ranges("Func")))));
+}
+
TEST_F(SymbolCollectorTest, RefsInHeaders) {
CollectorOpts.RefFilter = RefKind::All;
CollectorOpts.RefsInHeaders = true;