Index: include/clang/Frontend/ASTUnit.h =================================================================== --- include/clang/Frontend/ASTUnit.h +++ include/clang/Frontend/ASTUnit.h @@ -181,6 +181,12 @@ /// some number of calls. unsigned PreambleRebuildCounter; + /// \brief Cache pairs "filename - source location" + /// + /// This cache is used when loading preambule to increase performance + /// of that loading + std::map SrcLocCache; + public: class PreambleData { const FileEntry *File; Index: lib/Frontend/ASTUnit.cpp =================================================================== --- lib/Frontend/ASTUnit.cpp +++ lib/Frontend/ASTUnit.cpp @@ -455,7 +455,7 @@ } // Save the current top-level hash value. - CompletionCacheTopLevelHashValue = CurrentTopLevelHashValue; + CompletionCacheTopLevelHashValue = PreambleTopLevelHashValue; } void ASTUnit::ClearCachedCompletionResults() { @@ -1126,6 +1126,8 @@ if (SavedMainFileBuffer) TranslateStoredDiagnostics(getFileManager(), getSourceManager(), PreambleDiagnostics, StoredDiagnostics); + else + SrcLocCache.clear(); if (!Act->Execute()) goto error; @@ -1476,6 +1478,8 @@ SimpleTimer PreambleTimer(WantTiming); PreambleTimer.setOutput("Precompiling preamble"); + CompletionCacheTopLevelHashValue = 0; + // Save the preamble text for later; we'll need to compare against it for // subsequent reparses. StringRef MainFilename = FrontendOpts.Inputs[0].getFile(); @@ -1626,7 +1630,6 @@ // entities the last time we rebuilt the preamble, clear out the completion // cache. if (CurrentTopLevelHashValue != PreambleTopLevelHashValue) { - CompletionCacheTopLevelHashValue = 0; PreambleTopLevelHashValue = CurrentTopLevelHashValue; } @@ -2061,7 +2064,7 @@ // If we're caching global code-completion results, and the top-level // declarations have changed, clear out the code-completion cache. if (!Result && ShouldCacheCodeCompletionResults && - CurrentTopLevelHashValue != CompletionCacheTopLevelHashValue) + PreambleTopLevelHashValue != CompletionCacheTopLevelHashValue) CacheCodeCompletionResults(); // We now need to clear out the completion info related to this translation @@ -2531,8 +2534,7 @@ SmallVector Result; Result.reserve(Diags.size()); - const FileEntry *PreviousFE = nullptr; - FileID FID; + for (const StandaloneDiagnostic &SD : Diags) { // Rebuild the StoredDiagnostic. if (SD.Filename.empty()) @@ -2540,11 +2542,17 @@ const FileEntry *FE = FileMgr.getFile(SD.Filename); if (!FE) continue; - if (FE != PreviousFE) { + FileID FID; + SourceLocation FileLoc; + auto ItFileID = SrcLocCache.find(SD.Filename); + if (ItFileID == SrcLocCache.end()) { FID = SrcMgr.translateFile(FE); - PreviousFE = FE; + FileLoc = SrcMgr.getLocForStartOfFile(FID); + SrcLocCache.insert(std::make_pair(SD.Filename, FileLoc)); + } else { + FileLoc = ItFileID->second; } - SourceLocation FileLoc = SrcMgr.getLocForStartOfFile(FID); + if (FileLoc.isInvalid()) continue; SourceLocation L = FileLoc.getLocWithOffset(SD.LocOffset);