diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 61 |
1 files changed, 49 insertions, 12 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index aa672b3a7ec..e33cccbd95c 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -7014,19 +7014,20 @@ namespace clang { /// the current AST file. ASTIdentifierLookupTable::key_iterator End; + /// \brief Whether to skip any modules in the ASTReader. + bool SkipModules; + public: - explicit ASTIdentifierIterator(const ASTReader &Reader); + explicit ASTIdentifierIterator(const ASTReader &Reader, + bool SkipModules = false); StringRef Next() override; }; } -ASTIdentifierIterator::ASTIdentifierIterator(const ASTReader &Reader) - : Reader(Reader), Index(Reader.ModuleMgr.size() - 1) { - ASTIdentifierLookupTable *IdTable - = (ASTIdentifierLookupTable *)Reader.ModuleMgr[Index].IdentifierLookupTable; - Current = IdTable->key_begin(); - End = IdTable->key_end(); +ASTIdentifierIterator::ASTIdentifierIterator(const ASTReader &Reader, + bool SkipModules) + : Reader(Reader), Index(Reader.ModuleMgr.size()), SkipModules(SkipModules) { } StringRef ASTIdentifierIterator::Next() { @@ -7036,9 +7037,12 @@ StringRef ASTIdentifierIterator::Next() { return StringRef(); --Index; - ASTIdentifierLookupTable *IdTable - = (ASTIdentifierLookupTable *)Reader.ModuleMgr[Index]. - IdentifierLookupTable; + ModuleFile &F = Reader.ModuleMgr[Index]; + if (SkipModules && F.isModule()) + continue; + + ASTIdentifierLookupTable *IdTable = + (ASTIdentifierLookupTable *)F.IdentifierLookupTable; Current = IdTable->key_begin(); End = IdTable->key_end(); } @@ -7050,9 +7054,42 @@ StringRef ASTIdentifierIterator::Next() { return Result; } +namespace { +/// A utility for appending two IdentifierIterators. +class ChainedIdentifierIterator : public IdentifierIterator { + std::unique_ptr<IdentifierIterator> Current; + std::unique_ptr<IdentifierIterator> Queued; + +public: + ChainedIdentifierIterator(std::unique_ptr<IdentifierIterator> First, + std::unique_ptr<IdentifierIterator> Second) + : Current(std::move(First)), Queued(std::move(Second)) {} + + StringRef Next() override { + if (!Current) + return StringRef(); + + StringRef result = Current->Next(); + if (!result.empty()) + return result; + + // Try the queued iterator, which may itself be empty. + Current.reset(); + std::swap(Current, Queued); + return Next(); + } +}; +} // end anonymous namespace. + IdentifierIterator *ASTReader::getIdentifiers() { - if (!loadGlobalIndex()) - return GlobalIndex->createIdentifierIterator(); + if (!loadGlobalIndex()) { + std::unique_ptr<IdentifierIterator> ReaderIter( + new ASTIdentifierIterator(*this, /*SkipModules=*/true)); + std::unique_ptr<IdentifierIterator> ModulesIter( + GlobalIndex->createIdentifierIterator()); + return new ChainedIdentifierIterator(std::move(ReaderIter), + std::move(ModulesIter)); + } return new ASTIdentifierIterator(*this); } |