diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h --- a/clang/include/clang/Basic/SourceManager.h +++ b/clang/include/clang/Basic/SourceManager.h @@ -1744,7 +1744,7 @@ assert(ID != -1 && "Using FileID sentinel value"); if (ID < 0) return getLoadedSLocEntryByID(ID, Invalid); - return getLocalSLocEntry(static_cast(ID), Invalid); + return getLocalSLocEntry(static_cast(ID)); } const SrcMgr::SLocEntry & @@ -1779,6 +1779,21 @@ return SLocOffset < getSLocEntryByID(FID.ID+1).getOffset(); } + /// A small optimization over isOffsetInFileID for when the caller has + /// already determined the FileID to be local, as opposed to loaded and the + /// SlocOffset to be before the NextLocalOffset. The more generic + /// isOffsetInFileID method should be preferred. + inline bool isOffsetInLocalFileID(FileID FID, unsigned SLocOffset) const { + assert(SLocOffset < NextLocalOffset && "SLocOffset non-local"); + assert(FID.ID > 0 && "FID non-local or invalid"); + const unsigned ID = static_cast(FID.ID); + if (SLocOffset < getLocalSLocEntry(ID).getOffset()) + return false; + if (ID + 1 == LocalSLocEntryTable.size()) + return true; + return SLocOffset < getLocalSLocEntry(ID + 1).getOffset(); + } + /// Returns the previous in-order FileID or an invalid FileID if there /// is no previous one. FileID getPreviousFileID(FileID FID) const; diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp --- a/clang/lib/Basic/SourceManager.cpp +++ b/clang/lib/Basic/SourceManager.cpp @@ -861,11 +861,8 @@ --I; if (I->getOffset() <= SLocOffset) { FileID Res = FileID::get(int(I - LocalSLocEntryTable.begin())); - - // If this isn't an expansion, remember it. We have good locality across - // FileID lookups. - if (!I->isExpansion()) - LastFileIDLookup = Res; + // Remember it. We have good locality across FileID lookups. + LastFileIDLookup = Res; NumLinearScans += NumProbes+1; return Res; } @@ -882,11 +879,8 @@ unsigned LessIndex = 0; NumProbes = 0; while (true) { - bool Invalid = false; unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex; - unsigned MidOffset = getLocalSLocEntry(MiddleIndex, &Invalid).getOffset(); - if (Invalid) - return FileID::get(0); + unsigned MidOffset = getLocalSLocEntry(MiddleIndex).getOffset(); ++NumProbes; @@ -898,15 +892,10 @@ } // If the middle index contains the value, succeed and return. - // FIXME: This could be made faster by using a function that's aware of - // being in the local area. - if (isOffsetInFileID(FileID::get(MiddleIndex), SLocOffset)) { - FileID Res = FileID::get(MiddleIndex); - - // If this isn't a macro expansion, remember it. We have good locality - // across FileID lookups. - if (!LocalSLocEntryTable[MiddleIndex].isExpansion()) - LastFileIDLookup = Res; + FileID Res = FileID::get(MiddleIndex); + if (isOffsetInLocalFileID(Res, SLocOffset)) { + // Remember it. We have good locality across FileID lookups. + LastFileIDLookup = Res; NumBinaryProbes += NumProbes; return Res; } @@ -944,9 +933,7 @@ const SrcMgr::SLocEntry &E = getLoadedSLocEntry(I); if (E.getOffset() <= SLocOffset) { FileID Res = FileID::get(-int(I) - 2); - - if (!E.isExpansion()) - LastFileIDLookup = Res; + LastFileIDLookup = Res; NumLinearScans += NumProbes + 1; return Res; } @@ -979,8 +966,7 @@ if (isOffsetInFileID(FileID::get(-int(MiddleIndex) - 2), SLocOffset)) { FileID Res = FileID::get(-int(MiddleIndex) - 2); - if (!E.isExpansion()) - LastFileIDLookup = Res; + LastFileIDLookup = Res; NumBinaryProbes += NumProbes; return Res; } @@ -1695,10 +1681,7 @@ // The location we're looking for isn't in the main file; look // through all of the local source locations. for (unsigned I = 0, N = local_sloc_entry_size(); I != N; ++I) { - bool Invalid = false; - const SLocEntry &SLoc = getLocalSLocEntry(I, &Invalid); - if (Invalid) - return FileID(); + const SLocEntry &SLoc = getLocalSLocEntry(I); if (SLoc.isFile() && SLoc.getFile().getContentCache() && SLoc.getFile().getContentCache()->OrigEntry == SourceFile)