diff --git a/src/clang_tu.cc b/src/clang_tu.cc index 4092372bf..a2d982b42 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -93,7 +93,7 @@ Range FromTokenRangeDefaulted(const SourceManager &SM, const LangOptions &Lang, } std::unique_ptr -BuildCompilerInvocation(std::vector args, +BuildCompilerInvocation(const std::string &main, std::vector args, IntrusiveRefCntPtr VFS) { std::string save = "-resource-dir=" + g_config->clang.resourceDir; args.push_back(save.c_str()); @@ -106,6 +106,9 @@ BuildCompilerInvocation(std::vector args, CI->getDiagnosticOpts().IgnoreWarnings = true; CI->getFrontendOpts().DisableFree = false; CI->getLangOpts()->SpellChecking = false; + auto &IS = CI->getFrontendOpts().Inputs; + if (IS.size()) + IS[0] = FrontendInputFile(main, IS[0].getKind(), IS[0].isSystem()); } return CI; } diff --git a/src/clang_tu.hh b/src/clang_tu.hh index 2bfa23659..05096c1e1 100644 --- a/src/clang_tu.hh +++ b/src/clang_tu.hh @@ -51,7 +51,8 @@ Range FromTokenRangeDefaulted(const clang::SourceManager &SM, Range range); std::unique_ptr -BuildCompilerInvocation(std::vector args, +BuildCompilerInvocation(const std::string &main, + std::vector args, llvm::IntrusiveRefCntPtr VFS); const char *ClangBuiltinTypeName(int); diff --git a/src/indexer.cc b/src/indexer.cc index 83c8cbc20..43969f234 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1230,14 +1230,15 @@ void Init() { std::vector> Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs, - const std::string &opt_wdir, const std::string &file, + const std::string &opt_wdir, const std::string &main, const std::vector &args, const std::vector> &remapped, bool &ok) { ok = true; auto PCH = std::make_shared(); llvm::IntrusiveRefCntPtr FS = llvm::vfs::getRealFileSystem(); - std::shared_ptr CI = BuildCompilerInvocation(args, FS); + std::shared_ptr CI = + BuildCompilerInvocation(main, args, FS); // e.g. .s if (!CI) return {}; @@ -1257,35 +1258,13 @@ Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs, // HSOpts.UseBuiltinIncludes) // HSOpts.ResourceDir = g_config->clang.resourceDir; } - std::string buf = wfiles->GetContent(file); + std::string buf = wfiles->GetContent(main); std::vector> Bufs; - if (buf.size()) { - // If there is a completion session, reuse its preamble if exists. - bool done_remap = false; -#if 0 - std::shared_ptr session = - manager->TryGetSession(file, false, false); - if (session) - if (auto preamble = session->GetPreamble()) { - Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(buf)); - auto Bounds = ComputePreambleBounds(*CI->getLangOpts(), Bufs.back().get(), 0); - if (preamble->Preamble.CanReuse(*CI, Bufs.back().get(), Bounds, - FS.get())) { - preamble->Preamble.AddImplicitPreamble(*CI, FS, Bufs.back().get()); - done_remap = true; - } - } -#endif + if (buf.size()) for (auto &[filename, content] : remapped) { - if (filename == file && done_remap) - continue; Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(content)); - CI->getPreprocessorOpts().addRemappedFile( - filename == file ? CI->getFrontendOpts().Inputs[0].getFile() - : StringRef(filename), - Bufs.back().get()); + CI->getPreprocessorOpts().addRemappedFile(filename, Bufs.back().get()); } - } DiagnosticConsumer DC; auto Clang = std::make_unique(PCH); @@ -1314,20 +1293,20 @@ Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs, { llvm::CrashRecoveryContext CRC; auto parse = [&]() { - if (!Action->BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) - return; - if (!Action->Execute()) - return; - Action->EndSourceFile(); - ok = true; - }; + if (!Action->BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) + return; + if (!Action->Execute()) + return; + Action->EndSourceFile(); + ok = true; + }; if (!CRC.RunSafely(parse)) { - LOG_S(ERROR) << "clang crashed for " << file; + LOG_S(ERROR) << "clang crashed for " << main; return {}; } } if (!ok) { - LOG_S(ERROR) << "failed to index " << file; + LOG_S(ERROR) << "failed to index " << main; return {}; } for (auto &Buf : Bufs) @@ -1338,7 +1317,7 @@ Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs, if (!it.second.db) continue; std::unique_ptr &entry = it.second.db; - entry->import_file = file; + entry->import_file = main; entry->args = args; for (auto &[_, it] : entry->uid2lid_and_path) entry->lid2path.emplace_back(it.first, std::move(it.second)); diff --git a/src/pipeline.cc b/src/pipeline.cc index 72ec3bb47..dd59697e9 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -29,6 +29,7 @@ limitations under the License. #include #include +#include #include #include using namespace llvm; @@ -122,9 +123,11 @@ bool CacheInvalid(VFS *vfs, IndexFile *prev, const std::string &path, } } + // For inferred files, allow -o a a.cc -> -o b b.cc + std::string stem = sys::path::stem(path); bool changed = prev->args.size() != args.size(); for (size_t i = 0; !changed && i < args.size(); i++) - if (strcmp(prev->args[i], args[i])) + if (strcmp(prev->args[i], args[i]) && sys::path::stem(args[i]) != stem) changed = true; if (changed) LOG_S(INFO) << "args changed for " << path diff --git a/src/project.cc b/src/project.cc index 5c00765f2..a6126c917 100644 --- a/src/project.cc +++ b/src/project.cc @@ -426,12 +426,11 @@ Project::Entry Project::FindEntry(const std::string &path, bool must_exist) { std::shared_lock lock(mtx); for (auto &[root, folder] : root2folder) { + // The entry may have different filename but it doesn't matter when building + // CompilerInvocation. The main filename is specified separately. auto it = folder.path2entry_index.find(path); - if (it != folder.path2entry_index.end()) { - Project::Entry &entry = folder.entries[it->second]; - if (!must_exist || entry.filename == path) - return entry; - } + if (it != folder.path2entry_index.end()) + return folder.entries[it->second]; } std::string dir; @@ -490,14 +489,6 @@ Project::Entry Project::FindEntry(const std::string &path, ret.root = best->root; ret.directory = best->directory; ret.args = best->args; - std::string base_name = sys::path::filename(best->filename); - for (const char *&arg : ret.args) { - try { - if (arg == best->filename || sys::path::filename(arg) == base_name) - arg = Intern(path); - } catch (...) { - } - } ret.args.resize(best->compdb_size); if (extra && extra->size()) ret.args.insert(ret.args.end(), extra->begin() + 1, extra->end()); diff --git a/src/sema_manager.cc b/src/sema_manager.cc index 89388ee01..585319e6b 100644 --- a/src/sema_manager.cc +++ b/src/sema_manager.cc @@ -420,7 +420,7 @@ void *PreambleMain(void *manager_) { IntrusiveRefCntPtr FS = stat_cache->Producer(session->FS); if (std::unique_ptr CI = - BuildCompilerInvocation(session->file.args, FS)) + BuildCompilerInvocation(task.path, session->file.args, FS)) BuildPreamble(*session, *CI, FS, task, std::move(stat_cache)); if (task.from_diag) { @@ -460,7 +460,7 @@ void *CompletionMain(void *manager_) { IntrusiveRefCntPtr FS = preamble ? preamble->stat_cache->Consumer(session->FS) : session->FS; std::unique_ptr CI = - BuildCompilerInvocation(session->file.args, FS); + BuildCompilerInvocation(task->path, session->file.args, FS); if (!CI) continue; auto &FOpts = CI->getFrontendOpts(); @@ -562,7 +562,7 @@ void *DiagnosticMain(void *manager_) { } std::unique_ptr CI = - BuildCompilerInvocation(session->file.args, FS); + BuildCompilerInvocation(task.path, session->file.args, FS); if (!CI) continue; // If main file is a header, add -Wno-unused-function