aboutsummaryrefslogtreecommitdiff
path: root/lib/Frontend/CompilerInstance.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-11-30 17:33:56 +0000
committerDouglas Gregor <dgregor@apple.com>2011-11-30 17:33:56 +0000
commit392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87 (patch)
treebcb3eaee26ddf777965589a13e04aafe08235bc4 /lib/Frontend/CompilerInstance.cpp
parentd699ade396154238d2fa89bb09fdcfb79e5587d2 (diff)
Implement (de-)serialization of the description of a module and its
submodules. This information will eventually be used for name hiding when dealing with submodules. For now, we only use it to ensure that the module "key" returned when loading a module will always be a module (rather than occasionally being a FileEntry). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145497 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Frontend/CompilerInstance.cpp')
-rw-r--r--lib/Frontend/CompilerInstance.cpp60
1 files changed, 34 insertions, 26 deletions
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index 66b381e522..cb66aadfa9 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -1074,7 +1074,7 @@ ModuleKey CompilerInstance::loadModule(SourceLocation ImportLoc,
// This one-element cache is important to eliminate redundant diagnostics
// when both the preprocessor and parser see the same import declaration.
if (!ImportLoc.isInvalid() && LastModuleImportLoc == ImportLoc)
- return LastModuleImportResult.getOpaqueValue();
+ return LastModuleImportResult;
// Determine what file we're searching from.
SourceManager &SourceMgr = getSourceManager();
@@ -1091,8 +1091,9 @@ ModuleKey CompilerInstance::loadModule(SourceLocation ImportLoc,
const FileEntry *ModuleFile = 0;
// If we don't already have information on this module, load the module now.
- KnownModule &Known = KnownModules[Path[0].first];
- if (Known.isNull()) {
+ llvm::DenseMap<const IdentifierInfo *, ModuleMap::Module *>::iterator Known
+ = KnownModules.find(Path[0].first);
+ if (Known == KnownModules.end()) {
// Search for a module with the given name.
std::string ModuleFileName;
ModuleFile
@@ -1173,39 +1174,49 @@ ModuleKey CompilerInstance::loadModule(SourceLocation ImportLoc,
case ASTReader::IgnorePCH:
// FIXME: The ASTReader will already have complained, but can we showhorn
// that diagnostic information into a more useful form?
+ KnownModules[Path[0].first] = 0;
return 0;
case ASTReader::Failure:
- // Already complained.
+ // Already complained, but note now that we failed.
+ KnownModules[Path[0].first] = 0;
return 0;
}
- if (Module)
- Known = Module;
- else
- Known = ModuleFile;
+ if (!Module) {
+ // If we loaded the module directly, without finding a module map first,
+ // we'll have loaded the module's information from the module itself.
+ Module = PP->getHeaderSearchInfo().getModuleMap()
+ .findModule((Path[0].first->getName()));
+ }
+
+ // Cache the result of this top-level module lookup for later.
+ Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
} else {
- Module = Known.dyn_cast<ModuleMap::Module *>();
+ // Retrieve the cached top-level module.
+ Module = Known->second;
}
+ // If we never found the module, fail.
+ if (!Module)
+ return 0;
+
// Verify that the rest of the module path actually corresponds to
// a submodule.
- ModuleMap::Module *Sub = 0;
- if (Module && Path.size() > 1) {
- Sub = Module;
+ if (Path.size() > 1) {
for (unsigned I = 1, N = Path.size(); I != N; ++I) {
StringRef Name = Path[I].first->getName();
llvm::StringMap<ModuleMap::Module *>::iterator Pos
- = Sub->SubModules.find(Name);
+ = Module->SubModules.find(Name);
- if (Pos == Sub->SubModules.end()) {
+ if (Pos == Module->SubModules.end()) {
// Attempt to perform typo correction to find a module name that works.
llvm::SmallVector<StringRef, 2> Best;
unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)();
for (llvm::StringMap<ModuleMap::Module *>::iterator
- I = Sub->SubModules.begin(),
- IEnd = Sub->SubModules.end();
+ I = Module->SubModules.begin(),
+ IEnd = Module->SubModules.end();
I != IEnd; ++I) {
unsigned ED = Name.edit_distance(I->getValue()->Name,
/*AllowReplacements=*/true,
@@ -1221,34 +1232,31 @@ ModuleKey CompilerInstance::loadModule(SourceLocation ImportLoc,
if (Best.size() == 1) {
getDiagnostics().Report(Path[I].second,
diag::err_no_submodule_suggest)
- << Path[I].first << Sub->getFullModuleName() << Best[0]
+ << Path[I].first << Module->getFullModuleName() << Best[0]
<< SourceRange(Path[0].second, Path[I-1].second)
<< FixItHint::CreateReplacement(SourceRange(Path[I].second),
Best[0]);
- Pos = Sub->SubModules.find(Best[0]);
+ Pos = Module->SubModules.find(Best[0]);
}
}
- if (Pos == Sub->SubModules.end()) {
+ if (Pos == Module->SubModules.end()) {
// No submodule by this name. Complain, and don't look for further
// submodules.
getDiagnostics().Report(Path[I].second, diag::err_no_submodule)
- << Path[I].first << Sub->getFullModuleName()
+ << Path[I].first << Module->getFullModuleName()
<< SourceRange(Path[0].second, Path[I-1].second);
break;
}
- Sub = Pos->getValue();
+ Module = Pos->getValue();
}
}
// FIXME: Tell the AST reader to make the named submodule visible.
- // FIXME: The module file's FileEntry makes a poor key indeed! Once we
- // eliminate the need for FileEntry here, the module itself will become the
- // key (which does make sense).
LastModuleImportLoc = ImportLoc;
- LastModuleImportResult = Known;
- return Known.getOpaqueValue();
+ LastModuleImportResult = Module;
+ return Module;
}