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
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to