[PCH] Overhaul how preprocessed entities are [de]serialized.

-Use an array of offsets for all preprocessed entities
-Get rid of the separate array of offsets for just macro definitions;
 for references to macro definitions use an index inside the preprocessed
 entities array.
-Deserialize each preprocessed entity lazily, at first request; not in bulk.

Paves the way for binary searching of preprocessed entities that will offer
efficiency and will simplify things on the libclang side a lot.

llvm-svn: 139809
diff --git a/clang/lib/Lex/PreprocessingRecord.cpp b/clang/lib/Lex/PreprocessingRecord.cpp
index d02db25..8d96fb0 100644
--- a/clang/lib/Lex/PreprocessingRecord.cpp
+++ b/clang/lib/Lex/PreprocessingRecord.cpp
@@ -37,17 +37,9 @@
   this->FileName = StringRef(Memory, FileName.size());
 }
 
-void PreprocessingRecord::MaybeLoadPreallocatedEntities() const {
-  if (!ExternalSource || LoadedPreallocatedEntities)
-    return;
-  
-  LoadedPreallocatedEntities = true;
-  ExternalSource->ReadPreprocessedEntities();
-}
-
 PreprocessingRecord::PreprocessingRecord(bool IncludeNestedMacroExpansions)
   : IncludeNestedMacroExpansions(IncludeNestedMacroExpansions),
-    ExternalSource(0), LoadedPreallocatedEntities(false)
+    ExternalSource(0)
 {
 }
 
@@ -56,14 +48,10 @@
   if (OnlyLocalEntities)
     return iterator(this, 0);
   
-  MaybeLoadPreallocatedEntities();
   return iterator(this, -(int)LoadedPreprocessedEntities.size());
 }
 
 PreprocessingRecord::iterator PreprocessingRecord::end(bool OnlyLocalEntities) {
-  if (!OnlyLocalEntities)
-    MaybeLoadPreallocatedEntities();
-  
   return iterator(this, PreprocessedEntities.size());
 }
 
@@ -85,26 +73,49 @@
   return Result;
 }
 
-void 
-PreprocessingRecord::setLoadedPreallocatedEntity(unsigned Index, 
-                                                 PreprocessedEntity *Entity) {
-  assert(Index < LoadedPreprocessedEntities.size() &&
-         "Out-of-bounds preallocated entity");
-  LoadedPreprocessedEntities[Index] = Entity;
+void PreprocessingRecord::RegisterMacroDefinition(MacroInfo *Macro,
+                                                  PPEntityID PPID) {
+  MacroDefinitions[Macro] = PPID;
 }
 
-void PreprocessingRecord::RegisterMacroDefinition(MacroInfo *Macro, 
-                                                  MacroDefinition *MD) {
-  MacroDefinitions[Macro] = MD;
+/// \brief Retrieve the preprocessed entity at the given ID.
+PreprocessedEntity *PreprocessingRecord::getPreprocessedEntity(PPEntityID PPID){
+  if (PPID < 0) {
+    assert(unsigned(-PPID-1) < LoadedPreprocessedEntities.size() &&
+           "Out-of bounds loaded preprocessed entity");
+    return getLoadedPreprocessedEntity(LoadedPreprocessedEntities.size()+PPID);
+  }
+  assert(unsigned(PPID) < PreprocessedEntities.size() &&
+         "Out-of bounds local preprocessed entity");
+  return PreprocessedEntities[PPID];
+}
+
+/// \brief Retrieve the loaded preprocessed entity at the given index.
+PreprocessedEntity *
+PreprocessingRecord::getLoadedPreprocessedEntity(unsigned Index) {
+  assert(Index < LoadedPreprocessedEntities.size() && 
+         "Out-of bounds loaded preprocessed entity");
+  assert(ExternalSource && "No external source to load from");
+  PreprocessedEntity *&Entity = LoadedPreprocessedEntities[Index];
+  if (!Entity) {
+    Entity = ExternalSource->ReadPreprocessedEntity(Index);
+    if (!Entity) // Failed to load.
+      Entity = new (*this)
+         PreprocessedEntity(PreprocessedEntity::InvalidKind, SourceRange());
+  }
+  return Entity;
 }
 
 MacroDefinition *PreprocessingRecord::findMacroDefinition(const MacroInfo *MI) {
-  llvm::DenseMap<const MacroInfo *, MacroDefinition *>::iterator Pos
+  llvm::DenseMap<const MacroInfo *, PPEntityID>::iterator Pos
     = MacroDefinitions.find(MI);
   if (Pos == MacroDefinitions.end())
     return 0;
   
-  return Pos->second;
+  PreprocessedEntity *Entity = getPreprocessedEntity(Pos->second);
+  if (Entity->isInvalid())
+    return 0;
+  return cast<MacroDefinition>(Entity);
 }
 
 void PreprocessingRecord::MacroExpands(const Token &Id, const MacroInfo* MI,
@@ -127,13 +138,14 @@
       = new (*this) MacroDefinition(Id.getIdentifierInfo(),
                                     MI->getDefinitionLoc(),
                                     R);
-  MacroDefinitions[MI] = Def;
   PreprocessedEntities.push_back(Def);
+  MacroDefinitions[MI] = getPPEntityID(PreprocessedEntities.size()-1,
+                                       /*isLoaded=*/false);
 }
 
 void PreprocessingRecord::MacroUndefined(const Token &Id,
                                          const MacroInfo *MI) {
-  llvm::DenseMap<const MacroInfo *, MacroDefinition *>::iterator Pos
+  llvm::DenseMap<const MacroInfo *, PPEntityID>::iterator Pos
     = MacroDefinitions.find(MI);
   if (Pos != MacroDefinitions.end())
     MacroDefinitions.erase(Pos);