diff --git a/src/command_line.cc b/src/command_line.cc index 0045fee2..cdfb2704 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -895,8 +895,8 @@ bool IndexMain_DoIndex(IndexerConfig* config, dep_index_request.args = index_request->args; queue_do_index->PriorityEnqueue(std::move(dep_index_request)); } - - project->UpdateFileState(index_request->path, old_index->import_file, old_index->last_modification_time); + + project->UpdateFileState(index_request->path, old_index->import_file, old_index->dependencies, old_index->last_modification_time); Index_DoIdMap response(nullptr, std::move(old_index)); queue_do_id_map->Enqueue(std::move(response)); @@ -913,11 +913,13 @@ bool IndexMain_DoIndex(IndexerConfig* config, // Parse request and send a response. std::string import_file = index_request->path; + std::vector import_dependencies; // Skip index if file modification time didn't change. optional entry = project->FindCompilationEntryForFile(index_request->path); if (entry && entry->last_modification_time) { import_file = entry->import_file; + import_dependencies = entry->import_dependencies; int64_t modification_time = GetLastModificationTime(index_request->path); if (modification_time == *entry->last_modification_time) { @@ -926,13 +928,16 @@ bool IndexMain_DoIndex(IndexerConfig* config, } } - std::vector> indexes = Parse(config, file_consumer_shared, index_request->path, import_file, index_request->args); + std::vector> indexes = Parse( + config, file_consumer_shared, + index_request->path, import_file, import_dependencies, + index_request->args); time.ResetAndPrint("Parsing/indexing " + index_request->path); for (auto& current_index : indexes) { std::cerr << "Got index for " << current_index->path << std::endl; - project->UpdateFileState(current_index->path, current_index->import_file, current_index->last_modification_time); + project->UpdateFileState(current_index->path, current_index->import_file, current_index->dependencies, current_index->last_modification_time); std::unique_ptr old_index = LoadCachedFile(config, current_index->path); time.ResetAndPrint("Loading cached index"); diff --git a/src/file_consumer.cc b/src/file_consumer.cc index 680e6ebc..a3605148 100644 --- a/src/file_consumer.cc +++ b/src/file_consumer.cc @@ -50,6 +50,16 @@ IndexedFile* FileConsumer::TryConsumeFile(CXFile file, bool* is_first_ownership) } IndexedFile* FileConsumer::ForceLocal(CXFile file) { + // Try to fetch the file using the normal system, which will insert the file + // usage into global storage. + { + bool is_first; + IndexedFile* cache = TryConsumeFile(file, &is_first); + if (cache) + return cache; + } + + // It's already been taken before, just create a local copy. CXFileUniqueID file_id; if (clang_getFileUniqueID(file, &file_id) != 0) { std::cerr << "Could not get unique file id for " << FileName(file) << std::endl; @@ -57,7 +67,7 @@ IndexedFile* FileConsumer::ForceLocal(CXFile file) { } auto it = local_.find(file_id); - if (it == local_.end()) + if (it == local_.end() || !it->second) local_[file_id] = MakeUnique(FileName(file)); assert(local_.find(file_id) != local_.end()); return local_[file_id].get(); diff --git a/src/indexer.cc b/src/indexer.cc index e38722d4..ad07b7d3 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -1337,7 +1337,8 @@ void indexEntityReference(CXClientData client_data, std::vector> Parse( IndexerConfig* config, FileConsumer::SharedState* file_consumer_shared, - std::string desired_index_file, std::string import_file, std::vector args, + std::string desired_index_file, std::string import_file, const std::vector& existing_dependencies, + std::vector args, bool dump_ast) { if (!config->enableIndexing) @@ -1391,6 +1392,9 @@ std::vector> Parse( entry->last_modification_time = GetLastModificationTime(entry->path); entry->import_file = import_file; + + if (entry->path == import_file && !existing_dependencies.empty()) + AddRange(&entry->dependencies, existing_dependencies); } // TODO: Fix interesting checks. diff --git a/src/indexer.h b/src/indexer.h index 2ca728a8..2bcda253 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -502,8 +502,10 @@ struct IndexedFile { // |import_file| is the cc file which is what gets passed to clang. // |desired_index_file| is the (h or cc) file which has actually changed. +// |dependencies| are the existing dependencies of |import_file| if this is a reparse. std::vector> Parse( IndexerConfig* config, FileConsumer::SharedState* file_consumer_shared, - std::string desired_index_file, std::string import_file, std::vector args, + std::string desired_index_file, std::string import_file, const std::vector& existing_dependencies, + std::vector args, bool dump_ast = false); void IndexInit(); diff --git a/src/project.cc b/src/project.cc index 65b6e9ac..afc129dd 100644 --- a/src/project.cc +++ b/src/project.cc @@ -259,7 +259,7 @@ optional Project::FindCompilationEntryForFile(const std::string& return nullopt; } -void Project::UpdateFileState(const std::string& filename, const std::string& import_file, uint64_t modification_time) { +void Project::UpdateFileState(const std::string& filename, const std::string& import_file, const std::vector& import_dependencies, uint64_t modification_time) { { // TODO: There might be a lot of thread contention here. std::lock_guard lock(entries_modification_mutex_); @@ -267,6 +267,7 @@ void Project::UpdateFileState(const std::string& filename, const std::string& im if (it != absolute_path_to_entry_index_.end()) { auto& entry = entries[it->second]; entry.import_file = import_file; + entry.import_dependencies = import_dependencies; entry.last_modification_time = modification_time; return; } @@ -277,10 +278,12 @@ void Project::UpdateFileState(const std::string& filename, const std::string& im Project::Entry entry; entry.filename = filename; - if (import_entry) + if (import_entry) { entry.args = import_entry->args; + } entry.import_file = import_file; + entry.import_dependencies = import_dependencies; entry.last_modification_time = modification_time; // TODO: There might be a lot of thread contention here. diff --git a/src/project.h b/src/project.h index 3727ed76..77c5752b 100644 --- a/src/project.h +++ b/src/project.h @@ -16,6 +16,7 @@ struct Project { std::vector args; std::string import_file; + std::vector import_dependencies; optional last_modification_time; }; @@ -35,6 +36,6 @@ struct Project { optional FindCompilationEntryForFile(const std::string& filename); // Update the modification time for the given filename. This is thread-safe. - void UpdateFileState(const std::string& filename, const std::string& import_file, uint64_t modification_time); + void UpdateFileState(const std::string& filename, const std::string& import_file, const std::vector& import_dependencies, uint64_t modification_time); }; diff --git a/src/test.cc b/src/test.cc index 5abfe7ce..5be523cd 100644 --- a/src/test.cc +++ b/src/test.cc @@ -139,7 +139,7 @@ void RunTests() { std::cout << "[START] " << path << std::endl; std::vector> dbs = Parse( &config, &file_consumer_shared, - path, path, + path, path, {}, { "-xc++", "-std=c++11",