@@ -100,9 +100,11 @@ TEST(ParseCommandLineTest, HashInsideDoubleQuotes) {
100100} // namespace frontend_internal
101101
102102namespace {
103+ typedef void (*TExtraSourceTreeAction)(const std::filesystem::path&);
104+
103105std::unique_ptr<InMemoryIndex> GetSnippetIndex (
104106 std::string code, const std::vector<std::string>& extra_args = {},
105- bool fail_on_error = false ) {
107+ bool fail_on_error = false , TExtraSourceTreeAction extra_action = nullptr ) {
106108 auto source_dir = std::filesystem::path (::testing::TempDir ()) / " src" ;
107109 std::filesystem::remove_all (source_dir);
108110 CHECK (std::filesystem::create_directory (source_dir));
@@ -114,14 +116,16 @@ std::unique_ptr<InMemoryIndex> GetSnippetIndex(
114116 std::string source_file_path = (source_dir / " snippet.cc" ).string ();
115117 std::string source_dir_path = source_dir.string ();
116118
119+ if (extra_action != nullptr ) {
120+ extra_action (source_dir);
121+ }
122+
117123 auto index_dir = std::filesystem::path (::testing::TempDir ()) / " idx" ;
118124 std::filesystem::remove_all (index_dir);
119125 CHECK (std::filesystem::create_directory (index_dir));
120126 std::string index_dir_path = index_dir.string ();
121127 std::string sysroot_path = " /" ;
122-
123128 FileCopier file_copier (source_dir_path, index_dir_path, {sysroot_path});
124-
125129 std::unique_ptr<MergeQueue> merge_queue = MergeQueue::Create (1 );
126130 auto index_action = std::make_unique<IndexAction>(file_copier, *merge_queue);
127131 const bool result = clang::tooling::runToolOnCodeWithArgs (
@@ -3863,5 +3867,40 @@ TEST(FrontendTest, AliasedSymbol) {
38633867 EXPECT_HAS_ENTITY (index, Entity::Kind::kFunction , " " , " bar" , " ()" ,
38643868 " snippet.cc" , 2 , 2 );
38653869}
3870+
3871+ TEST (FrontendTest, GhostFileLocations) {
3872+ FlatIndex index =
3873+ std::move (
3874+ *GetSnippetIndex (
3875+ /* code=*/ " #include \" ghostfile.h\"\n " ,
3876+ /* extra_args=*/ {},
3877+ /* fail_on_error=*/ true ,
3878+ /* extra_action=*/
3879+ [](const std::filesystem::path& source_dir) {
3880+ std::ofstream ghost_file (source_dir / " ghostfile.h" );
3881+ ghost_file
3882+ << " // Copyright 2025 Google Inc. All rights reserved." ;
3883+ CHECK (ghost_file.good ());
3884+ }))
3885+ .Export ();
3886+
3887+ bool found_self = false ;
3888+ bool found_include = false ;
3889+ bool found_other = false ;
3890+ for (const Location& location : index.locations ) {
3891+ if (location.is_whole_file ()) {
3892+ if (location.path ().ends_with (" snippet.cc" )) {
3893+ found_self = true ;
3894+ } else if (location.path ().ends_with (" ghostfile.h" )) {
3895+ found_include = true ;
3896+ }
3897+ } else if (location.is_real ()) {
3898+ found_other = true ;
3899+ }
3900+ }
3901+ EXPECT_TRUE (found_self);
3902+ EXPECT_TRUE (found_include);
3903+ EXPECT_FALSE (found_other);
3904+ }
38663905} // namespace indexer
38673906} // namespace oss_fuzz
0 commit comments