dexonsmith updated this revision to Diff 300740.
dexonsmith added a comment.
Fix name of `LoadedSLocEntryIndices` (I documented it with this name, but was
using `SLocEntryIndices` previously).
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D89749/new/
https://reviews.llvm.org/D89749
Files:
clang/include/clang/Basic/SourceManager.h
clang/lib/Basic/SourceManager.cpp
clang/unittests/Basic/SourceManagerTest.cpp
Index: clang/unittests/Basic/SourceManagerTest.cpp
===================================================================
--- clang/unittests/Basic/SourceManagerTest.cpp
+++ clang/unittests/Basic/SourceManagerTest.cpp
@@ -514,6 +514,38 @@
EXPECT_FALSE(SourceMgr.isMainFile(*SecondFile));
}
+TEST_F(SourceManagerTest, LoadedSLocEntryIndex) {
+ using SrcMgr::LoadedSLocEntryIndex;
+
+ // Check operator bool.
+ EXPECT_FALSE(LoadedSLocEntryIndex());
+ EXPECT_TRUE(LoadedSLocEntryIndex(0U));
+ EXPECT_TRUE(LoadedSLocEntryIndex(1U));
+ EXPECT_TRUE(LoadedSLocEntryIndex(-2U));
+#if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST
+ EXPECT_DEATH(LoadedSLocEntryIndex(-1U), "Index too big");
+#endif
+ EXPECT_FALSE(LoadedSLocEntryIndex(None));
+
+ // Check operator*.
+#if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST
+ EXPECT_DEATH(*LoadedSLocEntryIndex(), "Dereferencing None?");
+#endif
+ EXPECT_EQ(0U, *LoadedSLocEntryIndex(0U));
+ EXPECT_EQ(1U, *LoadedSLocEntryIndex(1U));
+ EXPECT_EQ(-2U, *LoadedSLocEntryIndex(-2U));
+
+ // Check operator=.
+ LoadedSLocEntryIndex I;
+ EXPECT_EQ(0U, *(I = 0U));
+ EXPECT_EQ(1U, *(I = 1U));
+ EXPECT_EQ(-2U, *(I = -2U));
+#if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST
+ EXPECT_DEATH((I = -1U), "Index too big");
+#endif
+ EXPECT_FALSE((I = None));
+}
+
#endif
} // anonymous namespace
Index: clang/lib/Basic/SourceManager.cpp
===================================================================
--- clang/lib/Basic/SourceManager.cpp
+++ clang/lib/Basic/SourceManager.cpp
@@ -331,7 +331,7 @@
MainFileID = FileID();
LocalSLocEntryTable.clear();
LoadedSLocEntryTable.clear();
- SLocEntryLoaded.clear();
+ LoadedSLocEntryIndices.clear();
LastLineNoFileIDQuery = FileID();
LastLineNoContentCache = nullptr;
LastFileIDLookup = FileID();
@@ -367,8 +367,8 @@
};
// Ensure all SLocEntries are loaded from the external source.
- for (unsigned I = 0, N = Old.LoadedSLocEntryTable.size(); I != N; ++I)
- if (!Old.SLocEntryLoaded[I])
+ for (unsigned I = 0, N = Old.LoadedSLocEntryIndices.size(); I != N; ++I)
+ if (!Old.LoadedSLocEntryIndices[I])
Old.loadSLocEntry(I, nullptr);
// Inherit any content cache data from the old source manager.
@@ -429,12 +429,12 @@
const SrcMgr::SLocEntry &SourceManager::loadSLocEntry(unsigned Index,
bool *Invalid) const {
- assert(!SLocEntryLoaded[Index]);
+ assert(!LoadedSLocEntryIndices[Index]);
if (ExternalSLocEntries->ReadSLocEntry(-(static_cast<int>(Index) + 2))) {
if (Invalid)
*Invalid = true;
// If the file of the SLocEntry changed we could still have loaded it.
- if (!SLocEntryLoaded[Index]) {
+ if (!LoadedSLocEntryIndices[Index]) {
// Try to recover; create a SLocEntry so the rest of clang can handle it.
if (!FakeSLocEntryForRecovery)
FakeSLocEntryForRecovery = std::make_unique<SLocEntry>(
@@ -445,7 +445,8 @@
}
}
- return LoadedSLocEntryTable[Index];
+ assert(LoadedSLocEntryIndices[Index] && "Failed to load but returned success");
+ return LoadedSLocEntryTable[*LoadedSLocEntryIndices[Index]];
}
std::pair<int, unsigned>
@@ -455,10 +456,9 @@
// Make sure we're not about to run out of source locations.
if (CurrentLoadedOffset - TotalSize < NextLocalOffset)
return std::make_pair(0, 0);
- LoadedSLocEntryTable.resize(LoadedSLocEntryTable.size() + NumSLocEntries);
- SLocEntryLoaded.resize(LoadedSLocEntryTable.size());
+ LoadedSLocEntryIndices.resize(LoadedSLocEntryIndices.size() + NumSLocEntries);
CurrentLoadedOffset -= TotalSize;
- int ID = LoadedSLocEntryTable.size();
+ int ID = LoadedSLocEntryIndices.size();
return std::make_pair(-ID - 1, CurrentLoadedOffset);
}
@@ -497,7 +497,7 @@
if (ID > 0) {
if (ID-1 == 0)
return FileID();
- } else if (unsigned(-(ID-1) - 2) >= LoadedSLocEntryTable.size()) {
+ } else if (unsigned(-(ID - 1) - 2) >= LoadedSLocEntryIndices.size()) {
return FileID();
}
@@ -598,11 +598,12 @@
if (LoadedID < 0) {
assert(LoadedID != -1 && "Loading sentinel FileID");
unsigned Index = unsigned(-LoadedID) - 2;
- assert(Index < LoadedSLocEntryTable.size() && "FileID out of range");
- assert(!SLocEntryLoaded[Index] && "FileID already loaded");
- LoadedSLocEntryTable[Index] = SLocEntry::get(
- LoadedOffset, FileInfo::get(IncludePos, File, FileCharacter, Filename));
- SLocEntryLoaded[Index] = true;
+ assert(Index < LoadedSLocEntryIndices.size() && "FileID out of range");
+ assert(!LoadedSLocEntryIndices[Index] && "FileID already loaded");
+ LoadedSLocEntryIndices[Index] = LoadedSLocEntryTable.size();
+ LoadedSLocEntryTable.push_back(
+ SLocEntry::get(LoadedOffset, FileInfo::get(IncludePos, File,
+ FileCharacter, Filename)));
return FileID::get(LoadedID);
}
unsigned FileSize = File.getSize();
@@ -664,10 +665,10 @@
if (LoadedID < 0) {
assert(LoadedID != -1 && "Loading sentinel FileID");
unsigned Index = unsigned(-LoadedID) - 2;
- assert(Index < LoadedSLocEntryTable.size() && "FileID out of range");
- assert(!SLocEntryLoaded[Index] && "FileID already loaded");
- LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset, Info);
- SLocEntryLoaded[Index] = true;
+ assert(Index < LoadedSLocEntryIndices.size() && "FileID out of range");
+ assert(!LoadedSLocEntryIndices[Index] && "FileID already loaded");
+ LoadedSLocEntryIndices[Index] = LoadedSLocEntryTable.size();
+ LoadedSLocEntryTable.push_back(SLocEntry::get(LoadedOffset, Info));
return SourceLocation::getMacroLoc(LoadedOffset);
}
LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
@@ -899,7 +900,7 @@
// table: GreaterIndex is the one where the offset is greater, which is
// actually a lower index!
unsigned GreaterIndex = I;
- unsigned LessIndex = LoadedSLocEntryTable.size();
+ unsigned LessIndex = LoadedSLocEntryIndices.size();
NumProbes = 0;
while (true) {
++NumProbes;
@@ -2090,8 +2091,8 @@
<< llvm::capacity_in_bytes(LocalSLocEntryTable)
<< " bytes of capacity), "
<< NextLocalOffset << "B of Sloc address space used.\n";
- llvm::errs() << LoadedSLocEntryTable.size()
- << " loaded SLocEntries allocated, "
+ llvm::errs() << LoadedSLocEntryIndices.size() << " loaded SLocEntries ("
+ << LoadedSLocEntryTable.size() << " allocated), "
<< MaxLoadedOffset - CurrentLoadedOffset
<< "B of Sloc address space used.\n";
@@ -2155,11 +2156,11 @@
}
// Dump loaded SLocEntries.
llvm::Optional<unsigned> NextStart;
- for (unsigned Index = 0; Index != LoadedSLocEntryTable.size(); ++Index) {
+ for (unsigned Index = 0; Index != LoadedSLocEntryIndices.size(); ++Index) {
int ID = -(int)Index - 2;
- if (SLocEntryLoaded[Index]) {
- DumpSLocEntry(ID, LoadedSLocEntryTable[Index], NextStart);
- NextStart = LoadedSLocEntryTable[Index].getOffset();
+ if (auto I = LoadedSLocEntryIndices[Index]) {
+ DumpSLocEntry(ID, LoadedSLocEntryTable[*I], NextStart);
+ NextStart = LoadedSLocEntryTable[*I].getOffset();
} else {
NextStart = None;
}
@@ -2192,7 +2193,7 @@
size_t size = llvm::capacity_in_bytes(MemBufferInfos)
+ llvm::capacity_in_bytes(LocalSLocEntryTable)
+ llvm::capacity_in_bytes(LoadedSLocEntryTable)
- + llvm::capacity_in_bytes(SLocEntryLoaded)
+ + llvm::capacity_in_bytes(LoadedSLocEntryIndices)
+ llvm::capacity_in_bytes(FileInfos);
if (OverriddenFilesInfo)
Index: clang/include/clang/Basic/SourceManager.h
===================================================================
--- clang/include/clang/Basic/SourceManager.h
+++ clang/include/clang/Basic/SourceManager.h
@@ -69,6 +69,33 @@
/// SourceManager implementation.
namespace SrcMgr {
+ /// Optional index for loadable SLoc entries. Semantics of Optional<unsigned>
+ /// but without storage overhead.
+ class LoadedSLocEntryIndex {
+ public:
+ explicit operator bool() const { return Data; }
+ unsigned operator*() const {
+ assert(*this && "Dereferencing None?");
+ return Data - 1;
+ }
+
+ LoadedSLocEntryIndex &operator=(llvm::NoneType) {
+ return *this = LoadedSLocEntryIndex(None);
+ }
+ LoadedSLocEntryIndex &operator=(unsigned I) {
+ return *this = LoadedSLocEntryIndex(I);
+ }
+ LoadedSLocEntryIndex(llvm::NoneType = None) : Data(0) {}
+ LoadedSLocEntryIndex(unsigned I) : Data(I + 1) {
+ assert(*this && "Index too big");
+ }
+
+ private:
+ /// Index stored off-by-one with 0 as a sentinel to enable
+ /// zero-initialization.
+ unsigned Data;
+ };
+
/// Indicates whether a file or directory holds normal user code,
/// system code, or system code which is implicitly 'extern "C"' in C++ mode.
///
@@ -677,8 +704,8 @@
/// The table of SLocEntries that are loaded from other modules.
///
- /// Negative FileIDs are indexes into this table. To get from ID to an index,
- /// use (-ID - 2).
+ /// Negative FileIDs are indexes into LoadedSLocEntryIndices, which contains the
+ /// index into this table.
SmallVector<SrcMgr::SLocEntry, 0> LoadedSLocEntryTable;
/// The starting offset of the next local SLocEntry.
@@ -688,19 +715,21 @@
/// The starting offset of the latest batch of loaded SLocEntries.
///
- /// This is LoadedSLocEntryTable.back().Offset, except that that entry might
- /// not have been loaded, so that value would be unknown.
+ /// This is LoadedSLocEntryTable[LoadedSLocEntryIndices.back()].Offset,
+ /// except that that entry might not have been loaded, so that value would be
+ /// unknown.
unsigned CurrentLoadedOffset;
/// The highest possible offset is 2^31-1, so CurrentLoadedOffset
/// starts at 2^31.
static const unsigned MaxLoadedOffset = 1U << 31U;
- /// A bitmap that indicates whether the entries of LoadedSLocEntryTable
- /// have already been loaded from the external source.
+ /// An optional index into LoadedSLocEntryTable, where None indicates that an
+ /// SLocEntry has not yet been allocated.
///
- /// Same indexing as LoadedSLocEntryTable.
- llvm::BitVector SLocEntryLoaded;
+ /// Negative FileIDs are indexes into this table. To get from ID to an index,
+ /// use (-ID - 2).
+ SmallVector<SrcMgr::LoadedSLocEntryIndex, 0> LoadedSLocEntryIndices;
/// An external source for source location entries.
ExternalSLocEntrySource *ExternalSLocEntries = nullptr;
@@ -1659,14 +1688,14 @@
}
/// Get the number of loaded SLocEntries we have.
- unsigned loaded_sloc_entry_size() const { return LoadedSLocEntryTable.size();}
+ unsigned loaded_sloc_entry_size() const { return LoadedSLocEntryIndices.size(); }
/// Get a loaded SLocEntry. This is exposed for indexing.
const SrcMgr::SLocEntry &getLoadedSLocEntry(unsigned Index,
bool *Invalid = nullptr) const {
- assert(Index < LoadedSLocEntryTable.size() && "Invalid index");
- if (SLocEntryLoaded[Index])
- return LoadedSLocEntryTable[Index];
+ assert(Index < LoadedSLocEntryIndices.size() && "Invalid index");
+ if (auto I = LoadedSLocEntryIndices[Index])
+ return LoadedSLocEntryTable[*I];
return loadSLocEntry(Index, Invalid);
}
@@ -1682,7 +1711,7 @@
unsigned getNextLocalOffset() const { return NextLocalOffset; }
void setExternalSLocEntrySource(ExternalSLocEntrySource *Source) {
- assert(LoadedSLocEntryTable.empty() &&
+ assert(LoadedSLocEntryIndices.empty() &&
"Invalidating existing loaded entries");
ExternalSLocEntries = Source;
}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits