[libclang] When indexing an AST file, only deserialize the file level

declarations of the current primary module.

llvm-svn: 165046
This commit is contained in:
Argyrios Kyrtzidis 2012-10-02 21:09:13 +00:00
parent 7768299b98
commit 10e7846abf
8 changed files with 117 additions and 26 deletions

View File

@ -613,6 +613,16 @@ public:
std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator> std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
getLocalPreprocessingEntities() const; getLocalPreprocessingEntities() const;
/// \brief Type for a function iterating over a number of declarations.
/// \returns true to continue iteration and false to abort.
typedef bool (*DeclReceiverFn)(void *context, const Decl *D);
/// \brief Iterate over local declarations (locally parsed if this is a parsed
/// source file or the loaded declarations of the primary module if this is an
/// AST file).
/// \returns true if the iteration was complete or false if it was aborted.
bool applyOnLocalTopLevelDecls(void *context, DeclReceiverFn Fn);
llvm::MemoryBuffer *getBufferForFile(StringRef Filename, llvm::MemoryBuffer *getBufferForFile(StringRef Filename,
std::string *ErrorStr = 0); std::string *ErrorStr = 0);

View File

@ -860,6 +860,64 @@ private:
std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator> std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
getModulePreprocessedEntities(ModuleFile &Mod) const; getModulePreprocessedEntities(ModuleFile &Mod) const;
class ModuleDeclIterator {
ASTReader *Reader;
ModuleFile *Mod;
const serialization::LocalDeclID *Pos;
public:
typedef const Decl *value_type;
typedef value_type& reference;
typedef value_type* pointer;
ModuleDeclIterator() : Reader(0), Mod(0), Pos(0) { }
ModuleDeclIterator(ASTReader *Reader, ModuleFile *Mod,
const serialization::LocalDeclID *Pos)
: Reader(Reader), Mod(Mod), Pos(Pos) { }
value_type operator*() const {
return Reader->GetDecl(Reader->getGlobalDeclID(*Mod, *Pos));
}
ModuleDeclIterator &operator++() {
++Pos;
return *this;
}
ModuleDeclIterator operator++(int) {
ModuleDeclIterator Prev(*this);
++Pos;
return Prev;
}
ModuleDeclIterator &operator--() {
--Pos;
return *this;
}
ModuleDeclIterator operator--(int) {
ModuleDeclIterator Prev(*this);
--Pos;
return Prev;
}
friend bool operator==(const ModuleDeclIterator &LHS,
const ModuleDeclIterator &RHS) {
assert(LHS.Reader == RHS.Reader && LHS.Mod == RHS.Mod);
return LHS.Pos == RHS.Pos;
}
friend bool operator!=(const ModuleDeclIterator &LHS,
const ModuleDeclIterator &RHS) {
assert(LHS.Reader == RHS.Reader && LHS.Mod == RHS.Mod);
return LHS.Pos != RHS.Pos;
}
};
std::pair<ModuleDeclIterator, ModuleDeclIterator>
getModuleFileLevelDecls(ModuleFile &Mod);
void PassInterestingDeclsToConsumer(); void PassInterestingDeclsToConsumer();
void PassInterestingDeclToConsumer(Decl *D); void PassInterestingDeclToConsumer(Decl *D);
@ -1081,7 +1139,8 @@ public:
/// \brief Map from a local declaration ID within a given module to a /// \brief Map from a local declaration ID within a given module to a
/// global declaration ID. /// global declaration ID.
serialization::DeclID getGlobalDeclID(ModuleFile &F, unsigned LocalID) const; serialization::DeclID getGlobalDeclID(ModuleFile &F,
serialization::LocalDeclID LocalID) const;
/// \brief Returns true if global DeclID \p ID originated from module \p M. /// \brief Returns true if global DeclID \p ID originated from module \p M.
bool isDeclIDFromModule(serialization::GlobalDeclID ID, ModuleFile &M) const; bool isDeclIDFromModule(serialization::GlobalDeclID ID, ModuleFile &M) const;

View File

@ -294,6 +294,7 @@ public:
/// \brief Array of file-level DeclIDs sorted by file. /// \brief Array of file-level DeclIDs sorted by file.
const serialization::DeclID *FileSortedDecls; const serialization::DeclID *FileSortedDecls;
unsigned NumFileSortedDecls;
/// \brief Array of redeclaration chain location information within this /// \brief Array of redeclaration chain location information within this
/// module file, sorted by the first declaration ID. /// module file, sorted by the first declaration ID.

View File

@ -2792,6 +2792,30 @@ ASTUnit::getLocalPreprocessingEntities() const {
PreprocessingRecord::iterator()); PreprocessingRecord::iterator());
} }
bool ASTUnit::applyOnLocalTopLevelDecls(void *context, DeclReceiverFn Fn) {
if (isMainFileAST()) {
serialization::ModuleFile &
Mod = Reader->getModuleManager().getPrimaryModule();
ASTReader::ModuleDeclIterator MDI, MDE;
llvm::tie(MDI, MDE) = Reader->getModuleFileLevelDecls(Mod);
for (; MDI != MDE; ++MDI) {
if (!Fn(context, *MDI))
return false;
}
return true;
}
for (ASTUnit::top_level_iterator TL = top_level_begin(),
TLEnd = top_level_end();
TL != TLEnd; ++TL) {
if (!Fn(context, *TL))
return false;
}
return true;
}
void ASTUnit::PreambleData::countLines() const { void ASTUnit::PreambleData::countLines() const {
NumLines = 0; NumLines = 0;
if (empty()) if (empty())

View File

@ -2063,6 +2063,7 @@ ASTReader::ReadASTBlock(ModuleFile &F) {
case FILE_SORTED_DECLS: case FILE_SORTED_DECLS:
F.FileSortedDecls = (const DeclID *)BlobStart; F.FileSortedDecls = (const DeclID *)BlobStart;
F.NumFileSortedDecls = Record[0];
break; break;
case SOURCE_LOCATION_OFFSETS: { case SOURCE_LOCATION_OFFSETS: {
@ -3391,6 +3392,13 @@ ASTReader::getModulePreprocessedEntities(ModuleFile &Mod) const {
PreprocessingRecord::iterator()); PreprocessingRecord::iterator());
} }
std::pair<ASTReader::ModuleDeclIterator, ASTReader::ModuleDeclIterator>
ASTReader::getModuleFileLevelDecls(ModuleFile &Mod) {
return std::make_pair(ModuleDeclIterator(this, &Mod, Mod.FileSortedDecls),
ModuleDeclIterator(this, &Mod,
Mod.FileSortedDecls + Mod.NumFileSortedDecls));
}
PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) { PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) {
PreprocessedEntityID PPID = Index+1; PreprocessedEntityID PPID = Index+1;
std::pair<ModuleFile *, unsigned> PPInfo = getModulePreprocessedEntity(Index); std::pair<ModuleFile *, unsigned> PPInfo = getModulePreprocessedEntity(Index);
@ -4625,7 +4633,7 @@ CXXBaseSpecifier *ASTReader::GetExternalCXXBaseSpecifiers(uint64_t Offset) {
} }
serialization::DeclID serialization::DeclID
ASTReader::getGlobalDeclID(ModuleFile &F, unsigned LocalID) const { ASTReader::getGlobalDeclID(ModuleFile &F, LocalDeclID LocalID) const {
if (LocalID < NUM_PREDEF_DECL_IDS) if (LocalID < NUM_PREDEF_DECL_IDS)
return LocalID; return LocalID;

View File

@ -2251,9 +2251,11 @@ void ASTWriter::WriteFileDeclIDsMap() {
BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
Abbrev->Add(BitCodeAbbrevOp(FILE_SORTED_DECLS)); Abbrev->Add(BitCodeAbbrevOp(FILE_SORTED_DECLS));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev); unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev);
Record.push_back(FILE_SORTED_DECLS); Record.push_back(FILE_SORTED_DECLS);
Record.push_back(FileSortedIDs.size());
Stream.EmitRecordWithBlob(AbbrevCode, Record, data(FileSortedIDs)); Stream.EmitRecordWithBlob(AbbrevCode, Record, data(FileSortedIDs));
} }

View File

@ -35,7 +35,8 @@ ModuleFile::ModuleFile(ModuleKind Kind, unsigned Generation)
SelectorLookupTableData(0), SelectorLookupTable(0), LocalNumDecls(0), SelectorLookupTableData(0), SelectorLookupTable(0), LocalNumDecls(0),
DeclOffsets(0), BaseDeclID(0), DeclOffsets(0), BaseDeclID(0),
LocalNumCXXBaseSpecifiers(0), CXXBaseSpecifiersOffsets(0), LocalNumCXXBaseSpecifiers(0), CXXBaseSpecifiersOffsets(0),
FileSortedDecls(0), RedeclarationsMap(0), LocalNumRedeclarationsInMap(0), FileSortedDecls(0), NumFileSortedDecls(0),
RedeclarationsMap(0), LocalNumRedeclarationsInMap(0),
ObjCCategoriesMap(0), LocalNumObjCCategoriesInMap(0), ObjCCategoriesMap(0), LocalNumObjCCategoriesInMap(0),
LocalNumTypes(0), TypeOffsets(0), BaseTypeIndex(0), StatCache(0) LocalNumTypes(0), TypeOffsets(0), BaseTypeIndex(0), StatCache(0)
{} {}

View File

@ -472,30 +472,16 @@ static void indexPreprocessingRecord(ASTUnit &Unit, IndexingContext &IdxCtx) {
} }
} }
static bool topLevelDeclReceiver(void *context, const Decl *D) {
IndexingContext &IdxCtx = *static_cast<IndexingContext*>(context);
IdxCtx.indexTopLevelDecl(D);
if (IdxCtx.shouldAbort())
return false;
return true;
}
static void indexTranslationUnit(ASTUnit &Unit, IndexingContext &IdxCtx) { static void indexTranslationUnit(ASTUnit &Unit, IndexingContext &IdxCtx) {
// FIXME: Only deserialize stuff from the last chained PCH, not the PCH/Module Unit.applyOnLocalTopLevelDecls(&IdxCtx, topLevelDeclReceiver);
// that it depends on.
bool OnlyLocal = !Unit.isMainFileAST() && Unit.getOnlyLocalDecls();
if (OnlyLocal) {
for (ASTUnit::top_level_iterator TL = Unit.top_level_begin(),
TLEnd = Unit.top_level_end();
TL != TLEnd; ++TL) {
IdxCtx.indexTopLevelDecl(*TL);
if (IdxCtx.shouldAbort())
return;
}
} else {
TranslationUnitDecl *TUDecl = Unit.getASTContext().getTranslationUnitDecl();
for (TranslationUnitDecl::decl_iterator
I = TUDecl->decls_begin(), E = TUDecl->decls_end(); I != E; ++I) {
IdxCtx.indexTopLevelDecl(*I);
if (IdxCtx.shouldAbort())
return;
}
}
} }
static void indexDiagnostics(CXTranslationUnit TU, IndexingContext &IdxCtx) { static void indexDiagnostics(CXTranslationUnit TU, IndexingContext &IdxCtx) {