Index: cfe/trunk/include/clang/Frontend/ASTUnit.h =================================================================== --- cfe/trunk/include/clang/Frontend/ASTUnit.h +++ cfe/trunk/include/clang/Frontend/ASTUnit.h @@ -188,6 +188,14 @@ /// some number of calls. unsigned PreambleRebuildCounter; + /// \brief Cache pairs "filename - source location" + /// + /// Cache contains only source locations from preamble so it is + /// guaranteed that they stay valid when the SourceManager is recreated. + /// This cache is used when loading preambule to increase performance + /// of that loading. It must be cleared when preamble is recreated. + llvm::StringMap PreambleSrcLocCache; + public: class PreambleData { const FileEntry *File; Index: cfe/trunk/lib/Frontend/ASTUnit.cpp =================================================================== --- cfe/trunk/lib/Frontend/ASTUnit.cpp +++ cfe/trunk/lib/Frontend/ASTUnit.cpp @@ -1159,6 +1159,8 @@ if (SavedMainFileBuffer) TranslateStoredDiagnostics(getFileManager(), getSourceManager(), PreambleDiagnostics, StoredDiagnostics); + else + PreambleSrcLocCache.clear(); if (!Act->Execute()) goto error; @@ -2602,11 +2604,9 @@ // remap all the locations to the new view. This includes the diag location, // any associated source ranges, and the source ranges of associated fix-its. // FIXME: There should be a cleaner way to do this. - SmallVector Result; Result.reserve(Diags.size()); - const FileEntry *PreviousFE = nullptr; - FileID FID; + for (const StandaloneDiagnostic &SD : Diags) { // Rebuild the StoredDiagnostic. if (SD.Filename.empty()) @@ -2614,11 +2614,16 @@ const FileEntry *FE = FileMgr.getFile(SD.Filename); if (!FE) continue; - if (FE != PreviousFE) { - FID = SrcMgr.translateFile(FE); - PreviousFE = FE; + SourceLocation FileLoc; + auto ItFileID = PreambleSrcLocCache.find(SD.Filename); + if (ItFileID == PreambleSrcLocCache.end()) { + FileID FID = SrcMgr.translateFile(FE); + FileLoc = SrcMgr.getLocForStartOfFile(FID); + PreambleSrcLocCache[SD.Filename] = FileLoc; + } else { + FileLoc = ItFileID->getValue(); } - SourceLocation FileLoc = SrcMgr.getLocForStartOfFile(FID); + if (FileLoc.isInvalid()) continue; SourceLocation L = FileLoc.getLocWithOffset(SD.LocOffset);