summaryrefslogtreecommitdiffstats
path: root/clang/lib/Lex/ModuleMap.cpp
diff options
context:
space:
mode:
authorBen Langmuir <blangmuir@apple.com>2014-04-14 18:00:01 +0000
committerBen Langmuir <blangmuir@apple.com>2014-04-14 18:00:01 +0000
commitbeee15e721f6b192db90e068be40dfb24df98713 (patch)
treef52690678905dec887909f618b04b8604c3a1278 /clang/lib/Lex/ModuleMap.cpp
parent8f80ccc6353f929c9861586b27f165b7ac66273b (diff)
downloadbcm5719-llvm-beee15e721f6b192db90e068be40dfb24df98713.tar.gz
bcm5719-llvm-beee15e721f6b192db90e068be40dfb24df98713.zip
Allow multiple modules with the same name to coexist in the module cache
To differentiate between two modules with the same name, we will consider the path the module map file that they are defined by* part of the ‘key’ for looking up the precompiled module (pcm file). Specifically, this patch renames the precompiled module (pcm) files from cache-path/<module hash>/Foo.pcm to cache-path/<module hash>/Foo-<hash of module map path>.pcm In addition, I’ve taught the ASTReader to re-resolve the names of imported modules during module loading so that if the header search context changes between when a module was originally built and when it is loaded we can rebuild it if necessary. For example, if module A imports module B first time: clang -I /path/to/A -I /path/to/B ... second time: clang -I /path/to/A -I /different/path/to/B ... will now rebuild A as expected. * in the case of inferred modules, we use the module map file that allowed the inference, not the __inferred_module.map file, since the inferred file path is the same for every inferred module. llvm-svn: 206201
Diffstat (limited to 'clang/lib/Lex/ModuleMap.cpp')
-rw-r--r--clang/lib/Lex/ModuleMap.cpp45
1 files changed, 30 insertions, 15 deletions
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index 689ef73b466..810fcf05472 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -363,8 +363,8 @@ ModuleMap::findModuleForHeader(const FileEntry *File,
SmallString<32> NameBuf;
StringRef Name = sanitizeFilenameAsIdentifier(
llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
- Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
- Explicit).first;
+ Result = findOrCreateModule(Name, Result, UmbrellaModule->ModuleMap,
+ /*IsFramework=*/false, Explicit).first;
// Associate the module and the directory.
UmbrellaDirs[SkippedDirs[I-1]] = Result;
@@ -378,9 +378,9 @@ ModuleMap::findModuleForHeader(const FileEntry *File,
// Infer a submodule with the same name as this header file.
SmallString<32> NameBuf;
StringRef Name = sanitizeFilenameAsIdentifier(
- llvm::sys::path::stem(File->getName()), NameBuf);
- Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
- Explicit).first;
+ llvm::sys::path::stem(File->getName()), NameBuf);
+ Result = findOrCreateModule(Name, Result, UmbrellaModule->ModuleMap,
+ /*IsFramework=*/false, Explicit).first;
Result->addTopHeader(File);
// If inferred submodules export everything they import, add a
@@ -518,15 +518,16 @@ Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
}
std::pair<Module *, bool>
-ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
+ModuleMap::findOrCreateModule(StringRef Name, Module *Parent,
+ const FileEntry *ModuleMap, bool IsFramework,
bool IsExplicit) {
// Try to find an existing module with this name.
if (Module *Sub = lookupModuleQualified(Name, Parent))
return std::make_pair(Sub, false);
// Create a new module with this name.
- Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
- IsExplicit);
+ Module *Result = new Module(Name, SourceLocation(), Parent, ModuleMap,
+ IsFramework, IsExplicit);
if (LangOpts.CurrentModule == Name) {
SourceModule = Result;
SourceModuleName = Name;
@@ -595,6 +596,7 @@ ModuleMap::inferFrameworkModule(StringRef ModuleName,
// If the framework has a parent path from which we're allowed to infer
// a framework module, do so.
+ const FileEntry *ModuleMapFile = nullptr;
if (!Parent) {
// Determine whether we're allowed to infer a module map.
@@ -639,6 +641,7 @@ ModuleMap::inferFrameworkModule(StringRef ModuleName,
if (inferred->second.InferSystemModules)
IsSystem = true;
+ ModuleMapFile = inferred->second.ModuleMapFile;
}
}
}
@@ -646,7 +649,8 @@ ModuleMap::inferFrameworkModule(StringRef ModuleName,
// If we're not allowed to infer a framework module, don't.
if (!canInfer)
return 0;
- }
+ } else
+ ModuleMapFile = Parent->ModuleMap;
// Look for an umbrella header.
@@ -660,7 +664,7 @@ ModuleMap::inferFrameworkModule(StringRef ModuleName,
if (!UmbrellaHeader)
return 0;
- Module *Result = new Module(ModuleName, SourceLocation(), Parent,
+ Module *Result = new Module(ModuleName, SourceLocation(), Parent, ModuleMapFile,
/*IsFramework=*/true, /*IsExplicit=*/false);
if (LangOpts.CurrentModule == ModuleName) {
SourceModule = Result;
@@ -954,6 +958,9 @@ namespace clang {
DiagnosticsEngine &Diags;
ModuleMap &Map;
+
+ /// \brief The current module map file.
+ const FileEntry *ModuleMapFile;
/// \brief The directory that this module map resides in.
const DirectoryEntry *Directory;
@@ -1007,12 +1014,14 @@ namespace clang {
const TargetInfo *Target,
DiagnosticsEngine &Diags,
ModuleMap &Map,
+ const FileEntry *ModuleMapFile,
const DirectoryEntry *Directory,
const DirectoryEntry *BuiltinIncludeDir,
bool IsSystem)
: L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
- Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
- IsSystem(IsSystem), HadError(false), ActiveModule(0)
+ ModuleMapFile(ModuleMapFile), Directory(Directory),
+ BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
+ HadError(false), ActiveModule(0)
{
Tok.clear();
consumeToken();
@@ -1359,9 +1368,14 @@ void ModuleMapParser::parseModuleDecl() {
return;
}
+ // If this is a submodule, use the parent's module map, since we don't want
+ // the private module map file.
+ const FileEntry *ModuleMap = ActiveModule ? ActiveModule->ModuleMap
+ : ModuleMapFile;
+
// Start defining this module.
- ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
- Explicit).first;
+ ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, ModuleMap,
+ Framework, Explicit).first;
ActiveModule->DefinitionLoc = ModuleNameLoc;
if (Attrs.IsSystem || IsSystem)
ActiveModule->IsSystem = true;
@@ -2020,6 +2034,7 @@ void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
// We'll be inferring framework modules for this directory.
Map.InferredDirectories[Directory].InferModules = true;
Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
+ Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
// FIXME: Handle the 'framework' keyword.
}
@@ -2256,7 +2271,7 @@ bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) {
// Parse this module map file.
Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
- ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, Dir,
+ ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
BuiltinIncludeDir, IsSystem);
bool Result = Parser.parseModuleMapFile();
ParsedModuleMap[File] = Result;
OpenPOWER on IntegriCloud