diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h index 5e69abb9aeba..22cc581531f4 100644 --- a/clang/include/clang/Frontend/ASTUnit.h +++ b/clang/include/clang/Frontend/ASTUnit.h @@ -607,6 +607,12 @@ public: 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 + getLocalPreprocessingEntities() const; + llvm::MemoryBuffer *getBufferForFile(StringRef Filename, std::string *ErrorStr = 0); diff --git a/clang/include/clang/Lex/PreprocessingRecord.h b/clang/include/clang/Lex/PreprocessingRecord.h index 1a0734b54386..a569575aa352 100644 --- a/clang/include/clang/Lex/PreprocessingRecord.h +++ b/clang/include/clang/Lex/PreprocessingRecord.h @@ -548,6 +548,17 @@ namespace clang { return iterator(this, PreprocessedEntities.size()); } + /// \brief begin/end iterator pair for the given range of loaded + /// preprocessed entities. + std::pair + 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/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index a3abce11684e..b5d1e62a2068 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -855,6 +855,11 @@ private: std::pair getModulePreprocessedEntity(unsigned GlobalIndex); + /// \brief Returns (begin, end) pair for the preprocessed entities of a + /// particular module. + std::pair + getModulePreprocessedEntities(ModuleFile &Mod) const; + void PassInterestingDeclsToConsumer(); void PassInterestingDeclToConsumer(Decl *D); diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index 22476cae0aac..2cf25ebd9ac4 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -2777,6 +2777,21 @@ SourceLocation ASTUnit::getStartOfMainFileID() { return SourceMgr->getLocForStartOfFile(FID); } +std::pair +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/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index b5e579566afa..6bf6f94fbbaf 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -3381,6 +3381,16 @@ ASTReader::getModulePreprocessedEntity(unsigned GlobalIndex) { return std::make_pair(M, LocalIndex); } +std::pair +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 PPInfo = getModulePreprocessedEntity(Index); diff --git a/clang/tools/libclang/Indexing.cpp b/clang/tools/libclang/Indexing.cpp index f6314b90ec91..8c19aeba2855 100644 --- a/clang/tools/libclang/Indexing.cpp +++ b/clang/tools/libclang/Indexing.cpp @@ -455,21 +455,10 @@ static void indexPreprocessingRecord(ASTUnit &Unit, IndexingContext &IdxCtx) { 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;