PR21215: Support -fmodule-map-file being specified multiple times. Support

loading multiple module map files from the same directory.

llvm-svn: 220020
This commit is contained in:
Richard Smith 2014-10-17 01:42:53 +00:00
parent 32e9c6465b
commit 9887d79af5
8 changed files with 39 additions and 22 deletions

View File

@ -231,7 +231,11 @@ class HeaderSearch {
/// \brief Describes whether a given directory has a module map in it.
llvm::DenseMap<const DirectoryEntry *, bool> DirectoryHasModuleMap;
/// \brief Set of module map files we've already loaded, and a flag indicating
/// whether they were valid or not.
llvm::DenseMap<const FileEntry *, bool> LoadedModuleMaps;
/// \brief Uniqued set of framework names, which is used to track which
/// headers were included as framework headers.
llvm::StringSet<llvm::BumpPtrAllocator> FrameworkNames;

View File

@ -3826,13 +3826,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// -fmodule-name specifies the module that is currently being built (or
// used for header checking by -fmodule-maps).
if (Arg *A = Args.getLastArg(options::OPT_fmodule_name))
A->render(Args, CmdArgs);
Args.AddLastArg(CmdArgs, options::OPT_fmodule_name);
// -fmodule-map-file can be used to specify a file containing module
// -fmodule-map-file can be used to specify files containing module
// definitions.
if (Arg *A = Args.getLastArg(options::OPT_fmodule_map_file))
A->render(Args, CmdArgs);
Args.AddAllArgs(CmdArgs, options::OPT_fmodule_map_file);
// -fmodule-cache-path specifies where our module files should be written.
SmallString<128> ModuleCachePath;
@ -3867,9 +3865,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(Args.MakeArgString(VFSDir));
}
if (Arg *A = Args.getLastArg(options::OPT_fmodules_user_build_path))
if (HaveModules)
A->render(Args, CmdArgs);
if (HaveModules)
Args.AddLastArg(CmdArgs, options::OPT_fmodules_user_build_path);
// Pass through all -fmodules-ignore-macro arguments.
Args.AddAllArgs(CmdArgs, options::OPT_fmodules_ignore_macro);

View File

@ -1146,27 +1146,27 @@ HeaderSearch::LoadModuleMapResult
HeaderSearch::loadModuleMapFileImpl(const FileEntry *File, bool IsSystem) {
assert(File && "expected FileEntry");
const DirectoryEntry *Dir = File->getDir();
auto KnownDir = DirectoryHasModuleMap.find(Dir);
if (KnownDir != DirectoryHasModuleMap.end())
return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
// Check whether we've already loaded this module map, and mark it as being
// loaded in case we recursively try to load it from itself.
auto AddResult = LoadedModuleMaps.insert(std::make_pair(File, true));
if (!AddResult.second)
return AddResult.first->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
if (ModMap.parseModuleMapFile(File, IsSystem)) {
DirectoryHasModuleMap[Dir] = false;
LoadedModuleMaps[File] = false;
return LMM_InvalidModuleMap;
}
// Try to load a corresponding private module map.
if (const FileEntry *PMMFile =
getPrivateModuleMap(File->getName(), Dir, FileMgr)) {
getPrivateModuleMap(File->getName(), File->getDir(), FileMgr)) {
if (ModMap.parseModuleMapFile(PMMFile, IsSystem)) {
DirectoryHasModuleMap[Dir] = false;
LoadedModuleMaps[File] = false;
return LMM_InvalidModuleMap;
}
}
// This directory has a module map.
DirectoryHasModuleMap[Dir] = true;
return LMM_NewlyLoaded;
}
@ -1226,7 +1226,7 @@ HeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir, bool IsSystem,
bool IsFramework) {
auto KnownDir = DirectoryHasModuleMap.find(Dir);
if (KnownDir != DirectoryHasModuleMap.end())
return KnownDir->second? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
if (const FileEntry *ModuleMapFile = lookupModuleMapFile(Dir, IsFramework)) {
LoadModuleMapResult Result = loadModuleMapFileImpl(ModuleMapFile, IsSystem);
@ -1235,6 +1235,8 @@ HeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir, bool IsSystem,
// ^Dir ^ModuleMapFile
if (Result == LMM_NewlyLoaded)
DirectoryHasModuleMap[Dir] = true;
else if (Result == LMM_InvalidModuleMap)
DirectoryHasModuleMap[Dir] = false;
return Result;
}
return LMM_InvalidModuleMap;

View File

@ -33,3 +33,8 @@
// RUN: %clang -fmodules-validate-system-headers -### %s 2>&1 | FileCheck -check-prefix=MODULES_VALIDATE_SYSTEM_HEADERS %s
// MODULES_VALIDATE_SYSTEM_HEADERS: -fmodules-validate-system-headers
// RUN: %clang -fmodules -fmodule-map-file=foo.map -fmodule-map-file=bar.map -### %s 2>&1 | FileCheck -check-prefix=CHECK-MODULE-MAP-FILES %s
// CHECK-MODULE-MAP-FILES: "-fmodules"
// CHECK-MODULE-MAP-FILES: "-fmodule-map-file=" "foo.map"
// CHECK-MODULE-MAP-FILES: "-fmodule-map-file=" "bar.map"

View File

@ -0,0 +1,4 @@
#ifndef C_H
#define C_H
const int c = 5;
#endif

View File

@ -1,4 +1,4 @@
#ifndef COMMON_H
#define COMMON_H
const int c = 2;
const int x = 2;
#endif

View File

@ -0,0 +1,3 @@
module C {
header "c.h"
}

View File

@ -1,8 +1,10 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -x objective-c++ -fmodules-cache-path=%t -fmodules -fmodule-map-file=%S/Inputs/modular_maps/modulea.map -I %S/Inputs/modular_maps %s -verify
// RUN: %clang_cc1 -x objective-c++ -fmodules-cache-path=%t -fmodules -fmodule-map-file=%S/Inputs/modular_maps/modulea.map -fmodule-map-file=%S/Inputs/modular_maps/modulec.map -I %S/Inputs/modular_maps %s -verify
// RUN: %clang_cc1 -x objective-c++ -fmodules-cache-path=%t -fmodules -fmodule-map-file=%S/Inputs/modular_maps/modulec.map -fmodule-map-file=%S/Inputs/modular_maps/modulea.map -I %S/Inputs/modular_maps %s -verify
#include "common.h"
#include "a.h"
#include "b.h" // expected-error {{private header}}
const int v = a + c;
const int val = a + b + c; // expected-error {{undeclared identifier}}
@import C;
const int v = a + c + x;
const int val = a + b + c + x; // expected-error {{undeclared identifier}}