Index: include/clang/Frontend/ASTUnit.h =================================================================== --- include/clang/Frontend/ASTUnit.h +++ include/clang/Frontend/ASTUnit.h @@ -185,6 +185,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 @@ -470,7 +470,7 @@ } // Save the current top-level hash value. - CompletionCacheTopLevelHashValue = CurrentTopLevelHashValue; + CompletionCacheTopLevelHashValue = PreambleTopLevelHashValue; } void ASTUnit::ClearCachedCompletionResults() { @@ -1148,6 +1148,8 @@ if (SavedMainFileBuffer) TranslateStoredDiagnostics(getFileManager(), getSourceManager(), PreambleDiagnostics, StoredDiagnostics); + else + SrcLocCache.clear(); if (!Act->Execute()) goto error; @@ -1506,6 +1508,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(); @@ -1656,7 +1660,6 @@ // entities the last time we rebuilt the preamble, clear out the completion // cache. if (CurrentTopLevelHashValue != PreambleTopLevelHashValue) { - CompletionCacheTopLevelHashValue = 0; PreambleTopLevelHashValue = CurrentTopLevelHashValue; } @@ -2105,7 +2108,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 @@ -2579,8 +2582,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()) @@ -2588,11 +2590,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);