SourceManager: Use the same fake SLocEntry whenever it fails to load
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Mon, 19 Oct 2020 22:30:49 +0000 (18:30 -0400)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Tue, 27 Oct 2020 00:56:28 +0000 (20:56 -0400)
Instead of putting a fake `SLocEntry` at `LoadedSLocEntryTable[Index]`
when it fails to load in `SourceManager::loadSLocEntry`, allocate a fake
one. Unless someone is sniffing the address of the returned `SLocEntry`
(doubtful), this won't be a functionality change. Note that
`SLocEntryLoaded[Index]` wasn't being set to `true` either before or
after this change so no accessor is every going to look at
`LoadedSLocEntryTable[Index]`.

As a side effect, drop the `mutable` from `LoadedSLocEntryTable`.

Differential Revision: https://reviews.llvm.org/D89748

clang/include/clang/Basic/SourceManager.h
clang/lib/Basic/SourceManager.cpp

index ec9b2b7d0cfd7795fb66f015ea2a7897949d00a5..765cec465f9d1969039aab15f1e94d43663d82d0 100644 (file)
@@ -693,7 +693,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
   ///
   /// Negative FileIDs are indexes into this table. To get from ID to an index,
   /// use (-ID - 2).
-  mutable SmallVector<SrcMgr::SLocEntry, 0> LoadedSLocEntryTable;
+  SmallVector<SrcMgr::SLocEntry, 0> LoadedSLocEntryTable;
 
   /// The starting offset of the next local SLocEntry.
   ///
@@ -775,6 +775,8 @@ class SourceManager : public RefCountedBase<SourceManager> {
 
   mutable std::unique_ptr<SrcMgr::ContentCache> FakeContentCacheForRecovery;
 
+  mutable std::unique_ptr<SrcMgr::SLocEntry> FakeSLocEntryForRecovery;
+
   /// Lazily computed map of macro argument chunks to their expanded
   /// source location.
   using MacroArgsMap = std::map<unsigned, SourceLocation>;
index 6eae0f06a122af333db02ace7c5f3c886c332539..88f95d18ddf1e6de14c7a20d29973c68e36e83b4 100644 (file)
@@ -434,9 +434,11 @@ const SrcMgr::SLocEntry &SourceManager::loadSLocEntry(unsigned Index,
     // If the file of the SLocEntry changed we could still have loaded it.
     if (!SLocEntryLoaded[Index]) {
       // Try to recover; create a SLocEntry so the rest of clang can handle it.
-      LoadedSLocEntryTable[Index] = SLocEntry::get(
-          0, FileInfo::get(SourceLocation(), getFakeContentCacheForRecovery(),
-                           SrcMgr::C_User, ""));
+      if (!FakeSLocEntryForRecovery)
+        FakeSLocEntryForRecovery = std::make_unique<SLocEntry>(SLocEntry::get(
+            0, FileInfo::get(SourceLocation(), getFakeContentCacheForRecovery(),
+                             SrcMgr::C_User, "")));
+      return *FakeSLocEntryForRecovery;
     }
   }