summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Lex/HeaderSearch.h6
-rw-r--r--clang/lib/Driver/Tools.cpp13
-rw-r--r--clang/lib/Lex/HeaderSearch.cpp20
-rw-r--r--clang/test/Driver/modules.m5
-rw-r--r--clang/test/Modules/Inputs/modular_maps/c.h4
-rw-r--r--clang/test/Modules/Inputs/modular_maps/common.h2
-rw-r--r--clang/test/Modules/Inputs/modular_maps/modulec.map3
-rw-r--r--clang/test/Modules/modular_maps.cpp8
8 files changed, 39 insertions, 22 deletions
diff --git a/clang/include/clang/Lex/HeaderSearch.h b/clang/include/clang/Lex/HeaderSearch.h
index ad76714d4d3..086d3481b88 100644
--- a/clang/include/clang/Lex/HeaderSearch.h
+++ b/clang/include/clang/Lex/HeaderSearch.h
@@ -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;
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index da2b651a10a..28cb4df0033 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -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);
diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp
index bdec26fa521..e16b537c92d 100644
--- a/clang/lib/Lex/HeaderSearch.cpp
+++ b/clang/lib/Lex/HeaderSearch.cpp
@@ -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;
diff --git a/clang/test/Driver/modules.m b/clang/test/Driver/modules.m
index fbd41d8e7d5..dafb9349923 100644
--- a/clang/test/Driver/modules.m
+++ b/clang/test/Driver/modules.m
@@ -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"
diff --git a/clang/test/Modules/Inputs/modular_maps/c.h b/clang/test/Modules/Inputs/modular_maps/c.h
new file mode 100644
index 00000000000..6e3468e7260
--- /dev/null
+++ b/clang/test/Modules/Inputs/modular_maps/c.h
@@ -0,0 +1,4 @@
+#ifndef C_H
+#define C_H
+const int c = 5;
+#endif
diff --git a/clang/test/Modules/Inputs/modular_maps/common.h b/clang/test/Modules/Inputs/modular_maps/common.h
index f690bcbd399..349bf5f7c47 100644
--- a/clang/test/Modules/Inputs/modular_maps/common.h
+++ b/clang/test/Modules/Inputs/modular_maps/common.h
@@ -1,4 +1,4 @@
#ifndef COMMON_H
#define COMMON_H
-const int c = 2;
+const int x = 2;
#endif
diff --git a/clang/test/Modules/Inputs/modular_maps/modulec.map b/clang/test/Modules/Inputs/modular_maps/modulec.map
new file mode 100644
index 00000000000..c5a1ffe4577
--- /dev/null
+++ b/clang/test/Modules/Inputs/modular_maps/modulec.map
@@ -0,0 +1,3 @@
+module C {
+ header "c.h"
+}
diff --git a/clang/test/Modules/modular_maps.cpp b/clang/test/Modules/modular_maps.cpp
index 9c9aba85a91..484e727c13e 100644
--- a/clang/test/Modules/modular_maps.cpp
+++ b/clang/test/Modules/modular_maps.cpp
@@ -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}}
OpenPOWER on IntegriCloud