[libclang] When indexing an AST file, only deserialize the preprocessing record
entities of the current primary module.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@165023 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index 5e69abb..22cc581 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -607,6 +607,12 @@
     return CachedCompletionResults.size(); 
   }
 
+  /// \brief Returns an iterator range for the local preprocessing entities
+  /// of the local Preprocessor, if this is a parsed source file, or the loaded
+  /// preprocessing entities of the primary module if this is an AST file.
+  std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
+    getLocalPreprocessingEntities() const;
+
   llvm::MemoryBuffer *getBufferForFile(StringRef Filename,
                                        std::string *ErrorStr = 0);
 
diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h
index 1a0734b..a569575 100644
--- a/include/clang/Lex/PreprocessingRecord.h
+++ b/include/clang/Lex/PreprocessingRecord.h
@@ -548,6 +548,17 @@
       return iterator(this, PreprocessedEntities.size());
     }
 
+    /// \brief begin/end iterator pair for the given range of loaded
+    /// preprocessed entities.
+    std::pair<iterator, iterator>
+    getIteratorsForLoadedRange(unsigned start, unsigned count) {
+      unsigned end = start + count;
+      assert(end <= LoadedPreprocessedEntities.size());
+      return std::make_pair(
+                   iterator(this, int(start)-LoadedPreprocessedEntities.size()),
+                   iterator(this, int(end)-LoadedPreprocessedEntities.size()));
+    }
+
     /// \brief Returns a pair of [Begin, End) iterators of preprocessed entities
     /// that source range \p R encompasses.
     ///
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index a3abce1..b5d1e62 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -855,6 +855,11 @@
   std::pair<ModuleFile *, unsigned>
     getModulePreprocessedEntity(unsigned GlobalIndex);
 
+  /// \brief Returns (begin, end) pair for the preprocessed entities of a
+  /// particular module.
+  std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
+    getModulePreprocessedEntities(ModuleFile &Mod) const;
+
   void PassInterestingDeclsToConsumer();
   void PassInterestingDeclToConsumer(Decl *D);
 
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index 22476ca..2cf25eb 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -2777,6 +2777,21 @@
   return SourceMgr->getLocForStartOfFile(FID);
 }
 
+std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
+ASTUnit::getLocalPreprocessingEntities() const {
+  if (isMainFileAST()) {
+    serialization::ModuleFile &
+      Mod = Reader->getModuleManager().getPrimaryModule();
+    return Reader->getModulePreprocessedEntities(Mod);
+  }
+
+  if (PreprocessingRecord *PPRec = PP->getPreprocessingRecord())
+    return std::make_pair(PPRec->local_begin(), PPRec->local_end());
+
+  return std::make_pair(PreprocessingRecord::iterator(),
+                        PreprocessingRecord::iterator());
+}
+
 void ASTUnit::PreambleData::countLines() const {
   NumLines = 0;
   if (empty())
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index b5e5795..6bf6f94 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -3381,6 +3381,16 @@
   return std::make_pair(M, LocalIndex);
 }
 
+std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
+ASTReader::getModulePreprocessedEntities(ModuleFile &Mod) const {
+  if (PreprocessingRecord *PPRec = PP.getPreprocessingRecord())
+    return PPRec->getIteratorsForLoadedRange(Mod.BasePreprocessedEntityID,
+                                             Mod.NumPreprocessedEntities);
+
+  return std::make_pair(PreprocessingRecord::iterator(),
+                        PreprocessingRecord::iterator());
+}
+
 PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) {
   PreprocessedEntityID PPID = Index+1;
   std::pair<ModuleFile *, unsigned> PPInfo = getModulePreprocessedEntity(Index);
diff --git a/tools/libclang/Indexing.cpp b/tools/libclang/Indexing.cpp
index f6314b9..8c19aeb 100644
--- a/tools/libclang/Indexing.cpp
+++ b/tools/libclang/Indexing.cpp
@@ -455,21 +455,10 @@
   if (!PP.getPreprocessingRecord())
     return;
 
-  PreprocessingRecord &PPRec = *PP.getPreprocessingRecord();
-
   // FIXME: Only deserialize inclusion directives.
-  // FIXME: Only deserialize stuff from the last chained PCH, not the PCH/Module
-  // that it depends on.
 
-  bool OnlyLocal = !Unit.isMainFileAST() && Unit.getOnlyLocalDecls();
   PreprocessingRecord::iterator I, E;
-  if (OnlyLocal) {
-    I = PPRec.local_begin();
-    E = PPRec.local_end();
-  } else {
-    I = PPRec.begin();
-    E = PPRec.end();
-  }
+  llvm::tie(I, E) = Unit.getLocalPreprocessingEntities();
 
   for (; I != E; ++I) {
     PreprocessedEntity *PPE = *I;