summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization/ASTReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Serialization/ASTReader.cpp')
-rw-r--r--clang/lib/Serialization/ASTReader.cpp77
1 files changed, 69 insertions, 8 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index e24fddfd348..38ff3002bdb 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -40,6 +40,7 @@
#include "clang/Sema/Scope.h"
#include "clang/Sema/Sema.h"
#include "clang/Serialization/ASTDeserializationListener.h"
+#include "clang/Serialization/GlobalModuleIndex.h"
#include "clang/Serialization/ModuleManager.h"
#include "clang/Serialization/SerializationDiagnostic.h"
#include "llvm/ADT/StringExtras.h"
@@ -1377,15 +1378,17 @@ namespace {
class IdentifierLookupVisitor {
StringRef Name;
unsigned PriorGeneration;
+ GlobalModuleIndex::SkipSet &SkipSet;
unsigned &NumIdentifierLookups;
unsigned &NumIdentifierLookupHits;
IdentifierInfo *Found;
public:
IdentifierLookupVisitor(StringRef Name, unsigned PriorGeneration,
+ GlobalModuleIndex::SkipSet &SkipSet,
unsigned &NumIdentifierLookups,
unsigned &NumIdentifierLookupHits)
- : Name(Name), PriorGeneration(PriorGeneration),
+ : Name(Name), PriorGeneration(PriorGeneration), SkipSet(SkipSet),
NumIdentifierLookups(NumIdentifierLookups),
NumIdentifierLookupHits(NumIdentifierLookupHits),
Found()
@@ -1399,7 +1402,11 @@ namespace {
// If we've already searched this module file, skip it now.
if (M.Generation <= This->PriorGeneration)
return true;
-
+
+ // If this module file is in the skip set, don't bother looking in it.
+ if (This->SkipSet.count(M.File))
+ return false;
+
ASTIdentifierLookupTable *IdTable
= (ASTIdentifierLookupTable *)M.IdentifierLookupTable;
if (!IdTable)
@@ -1433,8 +1440,18 @@ void ASTReader::updateOutOfDateIdentifier(IdentifierInfo &II) {
unsigned PriorGeneration = 0;
if (getContext().getLangOpts().Modules)
PriorGeneration = IdentifierGeneration[&II];
-
- IdentifierLookupVisitor Visitor(II.getName(), PriorGeneration,
+
+ // If there is a global index, look there first to determine which modules
+ // provably do not have any results for this identifier.
+ GlobalModuleIndex::SkipSet SkipSet;
+ if (!loadGlobalIndex()) {
+ SmallVector<const FileEntry *, 4> ModuleFiles;
+ if (GlobalIndex->lookupIdentifier(II.getName(), ModuleFiles)) {
+ SkipSet = GlobalIndex->computeSkipSet(ModuleFiles);
+ }
+ }
+
+ IdentifierLookupVisitor Visitor(II.getName(), PriorGeneration, SkipSet,
NumIdentifierLookups,
NumIdentifierLookupHits);
ModuleMgr.visit(IdentifierLookupVisitor::visit, &Visitor);
@@ -2660,6 +2677,32 @@ void ASTReader::makeModuleVisible(Module *Mod,
}
}
+bool ASTReader::loadGlobalIndex() {
+ if (GlobalIndex)
+ return false;
+
+ if (TriedLoadingGlobalIndex || !UseGlobalIndex ||
+ !Context.getLangOpts().Modules)
+ return true;
+
+ // Try to load the global index.
+ TriedLoadingGlobalIndex = true;
+ StringRef ModuleCachePath
+ = getPreprocessor().getHeaderSearchInfo().getModuleCachePath();
+ std::pair<GlobalModuleIndex *, GlobalModuleIndex::ErrorCode> Result
+ = GlobalModuleIndex::readIndex(FileMgr, ModuleCachePath);
+ if (!Result.first)
+ return true;
+
+ GlobalIndex.reset(Result.first);
+ return false;
+}
+
+bool ASTReader::isGlobalIndexUnavailable() const {
+ return Context.getLangOpts().Modules && UseGlobalIndex &&
+ !hasGlobalIndex() && TriedLoadingGlobalIndex;
+}
+
ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName,
ModuleKind Type,
SourceLocation ImportLoc,
@@ -2678,6 +2721,10 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName,
case ConfigurationMismatch:
case HadErrors:
ModuleMgr.removeModules(ModuleMgr.begin() + NumModules, ModuleMgr.end());
+
+ // If we find that any modules are unusable, the global index is going
+ // to be out-of-date. Just remove it.
+ GlobalIndex.reset();
return ReadResult;
case Success:
@@ -2779,7 +2826,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName,
ObjCClassesLoaded[I],
PreviousGeneration);
}
-
+
return Success;
}
@@ -5605,6 +5652,11 @@ void ASTReader::PrintStats() {
(double)NumIdentifierLookupHits*100.0/NumIdentifierLookups);
}
+ if (GlobalIndex) {
+ std::fprintf(stderr, "\n");
+ GlobalIndex->printStats();
+ }
+
std::fprintf(stderr, "\n");
dump();
std::fprintf(stderr, "\n");
@@ -5705,9 +5757,18 @@ void ASTReader::InitializeSema(Sema &S) {
IdentifierInfo* ASTReader::get(const char *NameStart, const char *NameEnd) {
// Note that we are loading an identifier.
Deserializing AnIdentifier(this);
-
- IdentifierLookupVisitor Visitor(StringRef(NameStart, NameEnd - NameStart),
- /*PriorGeneration=*/0,
+ StringRef Name(NameStart, NameEnd - NameStart);
+
+ // If there is a global index, look there first to determine which modules
+ // provably do not have any results for this identifier.
+ GlobalModuleIndex::SkipSet SkipSet;
+ if (!loadGlobalIndex()) {
+ SmallVector<const FileEntry *, 4> ModuleFiles;
+ if (GlobalIndex->lookupIdentifier(Name, ModuleFiles)) {
+ SkipSet = GlobalIndex->computeSkipSet(ModuleFiles);
+ }
+ }
+ IdentifierLookupVisitor Visitor(Name, /*PriorGeneration=*/0, SkipSet,
NumIdentifierLookups,
NumIdentifierLookupHits);
ModuleMgr.visit(IdentifierLookupVisitor::visit, &Visitor);
OpenPOWER on IntegriCloud