Revert r312105 [modules] Add ability to specify module name to module file mapping

Looks like it breaks win10 builder.

llvm-svn: 312112
This commit is contained in:
Victor Leschuk 2017-08-30 11:31:56 +00:00
parent 89df797ee9
commit db68911b07
16 changed files with 49 additions and 208 deletions

View File

@ -213,14 +213,8 @@ Command-line parameters
``-fno-implicit-modules``
All modules used by the build must be specified with ``-fmodule-file``.
``-fmodule-file=[<name>=]<file>``
Specify the mapping of module names to precompiled module files. If the
name is omitted, then the module file is loaded whether actually required
or not. If the name is specified, then the mapping is treated as another
prebuilt module search mechanism (in addition to ``-fprebuilt-module-path``)
and the module is only loaded if required. Note that in this case the
specified file also overrides this module's paths that might be embedded
in other precompiled module files.
``-fmodule-file=<file>``
Load the given precompiled module file.
``-fprebuilt-module-path=<directory>``
Specify the path to the prebuilt modules. If specified, we will look for modules in this directory for a given top-level module name. We don't need a module map for loading prebuilt modules in this directory and the compiler will not try to rebuild these modules. This can be specified multiple times.
@ -951,3 +945,4 @@ PCHInternals_
.. [#] The preprocessing context in which the modules are parsed is actually dependent on the command-line options provided to the compiler, including the language dialect and any ``-D`` options. However, the compiled modules for different command-line options are kept distinct, and any preprocessor directives that occur within the translation unit are ignored. See the section on the `Configuration macros declaration`_ for more information.
.. _PCHInternals: PCHInternals.html

View File

@ -1125,8 +1125,8 @@ def fmodule_map_file : Joined<["-"], "fmodule-map-file=">,
Group<f_Group>, Flags<[DriverOption,CC1Option]>, MetaVarName<"<file>">,
HelpText<"Load this module map file">;
def fmodule_file : Joined<["-"], "fmodule-file=">,
Group<i_Group>, Flags<[DriverOption,CC1Option]>, MetaVarName<"[<name>=]<file>">,
HelpText<"Specify the mapping of module name to precompiled module file, or load a module file if name is omitted.">;
Group<f_Group>, Flags<[DriverOption,CC1Option]>,
HelpText<"Load this precompiled module file">, MetaVarName<"<file>">;
def fmodules_ignore_macro : Joined<["-"], "fmodules-ignore-macro=">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Ignore the definition of the given macro when building and loading modules">;
def fmodules_decluse : Flag <["-"], "fmodules-decluse">, Group<f_Group>,

View File

@ -471,41 +471,29 @@ public:
/// \brief Get filenames for all registered header maps.
void getHeaderMapFileNames(SmallVectorImpl<std::string> &Names) const;
/// \brief Retrieve the name of the cached module file that should be used
/// to load the given module.
/// \brief Retrieve the name of the module file that should be used to
/// load the given module.
///
/// \param Module The module whose module file name will be returned.
///
/// \returns The name of the module file that corresponds to this module,
/// or an empty string if this module does not correspond to any module file.
std::string getCachedModuleFileName(Module *Module);
std::string getModuleFileName(Module *Module);
/// \brief Retrieve the name of the prebuilt module file that should be used
/// to load a module with the given name.
///
/// \param ModuleName The module whose module file name will be returned.
///
/// \param FileMapOnly If true, then only look in the explicit module name
// to file name map and skip the directory search.
///
/// \returns The name of the module file that corresponds to this module,
/// or an empty string if this module does not correspond to any module file.
std::string getPrebuiltModuleFileName(StringRef ModuleName,
bool FileMapOnly = false);
/// \brief Retrieve the name of the (to-be-)cached module file that should
/// be used to load a module with the given name.
/// \brief Retrieve the name of the module file that should be used to
/// load a module with the given name.
///
/// \param ModuleName The module whose module file name will be returned.
///
/// \param ModuleMapPath A path that when combined with \c ModuleName
/// uniquely identifies this module. See Module::ModuleMap.
///
/// \param UsePrebuiltPath Whether we should use the prebuilt module path.
///
/// \returns The name of the module file that corresponds to this module,
/// or an empty string if this module does not correspond to any module file.
std::string getCachedModuleFileName(StringRef ModuleName,
StringRef ModuleMapPath);
std::string getModuleFileName(StringRef ModuleName, StringRef ModuleMapPath,
bool UsePrebuiltPath);
/// \brief Lookup a module Search for a module with the given name.
///

View File

@ -17,7 +17,6 @@
#include "llvm/ADT/StringRef.h"
#include <string>
#include <vector>
#include <map>
namespace clang {
@ -95,9 +94,6 @@ public:
/// \brief The directory used for a user build.
std::string ModuleUserBuildPath;
/// \brief The mapping of module names to prebuilt module files.
std::map<std::string, std::string> PrebuiltModuleFiles;
/// \brief The directories used to load prebuilt module files.
std::vector<std::string> PrebuiltModulePaths;

View File

@ -2142,19 +2142,9 @@ public:
// \brief Read a string
static std::string ReadString(const RecordData &Record, unsigned &Idx);
// \brief Skip a string
static void SkipString(const RecordData &Record, unsigned &Idx) {
Idx += Record[Idx] + 1;
}
// \brief Read a path
std::string ReadPath(ModuleFile &F, const RecordData &Record, unsigned &Idx);
// \brief Skip a path
static void SkipPath(const RecordData &Record, unsigned &Idx) {
SkipString(Record, Idx);
}
/// \brief Read a version tuple.
static VersionTuple ReadVersionTuple(const RecordData &Record, unsigned &Idx);

View File

@ -27,7 +27,6 @@ class GlobalModuleIndex;
class MemoryBufferCache;
class ModuleMap;
class PCHContainerReader;
class HeaderSearch;
namespace serialization {
@ -59,9 +58,6 @@ class ModuleManager {
/// \brief Knows how to unwrap module containers.
const PCHContainerReader &PCHContainerRdr;
/// \brief Preprocessor's HeaderSearchInfo containing the module map.
const HeaderSearch &HeaderSearchInfo;
/// \brief A lookup of in-memory (virtual file) buffers
llvm::DenseMap<const FileEntry *, std::unique_ptr<llvm::MemoryBuffer>>
InMemoryBuffers;
@ -132,8 +128,7 @@ public:
typedef std::pair<uint32_t, StringRef> ModuleOffset;
explicit ModuleManager(FileManager &FileMgr, MemoryBufferCache &PCMCache,
const PCHContainerReader &PCHContainerRdr,
const HeaderSearch &HeaderSearchInfo);
const PCHContainerReader &PCHContainerRdr);
~ModuleManager();
/// \brief Forward iterator to traverse all loaded modules.
@ -168,11 +163,8 @@ public:
/// \brief Returns the module associated with the given index
ModuleFile &operator[](unsigned Index) const { return *Chain[Index]; }
/// \brief Returns the module associated with the given file name.
ModuleFile *lookupByFileName(StringRef FileName) const;
/// \brief Returns the module associated with the given module name.
ModuleFile *lookupByModuleName(StringRef ModName) const;
/// \brief Returns the module associated with the given name
ModuleFile *lookup(StringRef Name) const;
/// \brief Returns the module associated with the given module file.
ModuleFile *lookup(const FileEntry *File) const;

View File

@ -3649,11 +3649,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (HaveAnyModules) {
// -fprebuilt-module-path specifies where to load the prebuilt module files.
for (const Arg *A : Args.filtered(options::OPT_fprebuilt_module_path)) {
for (const Arg *A : Args.filtered(options::OPT_fprebuilt_module_path))
CmdArgs.push_back(Args.MakeArgString(
std::string("-fprebuilt-module-path=") + A->getValue()));
A->claim();
}
}
// -fmodule-name specifies the module that is currently being built (or
@ -3676,10 +3674,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
}
// The -fmodule-file=<name>=<file> form specifies the mapping of module
// names to precompiled module files (the module is loaded only if used).
// The -fmodule-file=<file> form can be used to unconditionally load
// precompiled module files (whether used or not).
// -fmodule-file can be used to specify files containing precompiled modules.
if (HaveAnyModules)
Args.AddAllArgs(CmdArgs, options::OPT_fmodule_file);
else

View File

@ -1641,14 +1641,6 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
} else if (ModuleName == getLangOpts().CurrentModule) {
// This is the module we're building.
Module = PP->getHeaderSearchInfo().lookupModule(ModuleName);
/// FIXME: perhaps we should (a) look for a module using the module name
// to file map (PrebuiltModuleFiles) and (b) diagnose if still not found?
//if (Module == nullptr) {
// getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found)
// << ModuleName;
// ModuleBuildFailed = true;
// return ModuleLoadResult();
//}
Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
} else {
// Search for a module with the given name.
@ -1670,17 +1662,16 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
}
// Try to load the module from the prebuilt module path.
if (Source == ModuleNotFound && (!HSOpts.PrebuiltModuleFiles.empty() ||
!HSOpts.PrebuiltModulePaths.empty())) {
ModuleFileName =
PP->getHeaderSearchInfo().getPrebuiltModuleFileName(ModuleName);
if (Source == ModuleNotFound && !HSOpts.PrebuiltModulePaths.empty()) {
ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(
ModuleName, "", /*UsePrebuiltPath*/ true);
if (!ModuleFileName.empty())
Source = PrebuiltModulePath;
}
// Try to load the module from the module cache.
if (Source == ModuleNotFound && Module) {
ModuleFileName = PP->getHeaderSearchInfo().getCachedModuleFileName(Module);
ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(Module);
Source = ModuleCache;
}

View File

@ -1009,12 +1009,9 @@ static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts,
// They won't be discovered by the regular preprocessor, so
// we let make / ninja to know about this implicit dependency.
Opts.ExtraDeps = Args.getAllArgValues(OPT_fdepfile_entry);
// Only the -fmodule-file=<file> form.
for (const Arg *A : Args.filtered(OPT_fmodule_file)) {
StringRef Val = A->getValue();
if (Val.find('=') == StringRef::npos)
Opts.ExtraDeps.push_back(Val);
}
auto ModuleFiles = Args.getAllArgValues(OPT_fmodule_file);
Opts.ExtraDeps.insert(Opts.ExtraDeps.end(), ModuleFiles.begin(),
ModuleFiles.end());
}
static bool parseShowColorsArgs(const ArgList &Args, bool DefaultColor) {
@ -1343,12 +1340,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
Opts.UseGlobalModuleIndex = !Args.hasArg(OPT_fno_modules_global_index);
Opts.GenerateGlobalModuleIndex = Opts.UseGlobalModuleIndex;
Opts.ModuleMapFiles = Args.getAllArgValues(OPT_fmodule_map_file);
// Only the -fmodule-file=<file> form.
for (const Arg *A : Args.filtered(OPT_fmodule_file)) {
StringRef Val = A->getValue();
if (Val.find('=') == StringRef::npos)
Opts.ModuleFiles.push_back(Val);
}
Opts.ModuleFiles = Args.getAllArgValues(OPT_fmodule_file);
Opts.ModulesEmbedFiles = Args.getAllArgValues(OPT_fmodules_embed_file_EQ);
Opts.ModulesEmbedAllFiles = Args.hasArg(OPT_fmodules_embed_all_files);
Opts.IncludeTimestamps = !Args.hasArg(OPT_fno_pch_timestamp);
@ -1552,12 +1544,6 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
Opts.ModuleCachePath = P.str();
Opts.ModuleUserBuildPath = Args.getLastArgValue(OPT_fmodules_user_build_path);
// Only the -fmodule-file=<name>=<file> form.
for (const Arg *A : Args.filtered(OPT_fmodule_file)) {
StringRef Val = A->getValue();
if (Val.find('=') != StringRef::npos)
Opts.PrebuiltModuleFiles.insert(Val.split('='));
}
for (const Arg *A : Args.filtered(OPT_fprebuilt_module_path))
Opts.AddPrebuiltModulePath(A->getValue());
Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash);

View File

@ -185,8 +185,8 @@ GenerateModuleFromModuleMapAction::CreateOutputFile(CompilerInstance &CI,
HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
CI.getFrontendOpts().OutputFile =
HS.getCachedModuleFileName(CI.getLangOpts().CurrentModule,
ModuleMapFile);
HS.getModuleFileName(CI.getLangOpts().CurrentModule, ModuleMapFile,
/*UsePrebuiltPath=*/false);
}
// We use createOutputFile here because this is exposed via libclang, and we

View File

@ -128,24 +128,21 @@ void HeaderSearch::getHeaderMapFileNames(
Names.push_back(HM.first->getName());
}
std::string HeaderSearch::getCachedModuleFileName(Module *Module) {
std::string HeaderSearch::getModuleFileName(Module *Module) {
const FileEntry *ModuleMap =
getModuleMap().getModuleMapFileForUniquing(Module);
return getCachedModuleFileName(Module->Name, ModuleMap->getName());
return getModuleFileName(Module->Name, ModuleMap->getName(),
/*UsePrebuiltPath*/false);
}
std::string HeaderSearch::getPrebuiltModuleFileName(StringRef ModuleName,
bool FileMapOnly) {
// First check the module name to pcm file map.
auto i (HSOpts->PrebuiltModuleFiles.find(ModuleName));
if (i != HSOpts->PrebuiltModuleFiles.end())
return i->second;
if (FileMapOnly || HSOpts->PrebuiltModulePaths.empty())
std::string HeaderSearch::getModuleFileName(StringRef ModuleName,
StringRef ModuleMapPath,
bool UsePrebuiltPath) {
if (UsePrebuiltPath) {
if (HSOpts->PrebuiltModulePaths.empty())
return std::string();
// Then go through each prebuilt module directory and try to find the pcm
// file.
// Go though each prebuilt module path and try to find the pcm file.
for (const std::string &Dir : HSOpts->PrebuiltModulePaths) {
SmallString<256> Result(Dir);
llvm::sys::fs::make_absolute(Result);
@ -157,8 +154,6 @@ std::string HeaderSearch::getPrebuiltModuleFileName(StringRef ModuleName,
return std::string();
}
std::string HeaderSearch::getCachedModuleFileName(StringRef ModuleName,
StringRef ModuleMapPath) {
// If we don't have a module cache path or aren't supposed to use one, we
// can't do anything.
if (getModuleCachePath().empty())

View File

@ -2485,23 +2485,7 @@ ASTReader::ReadControlBlock(ModuleFile &F,
{{(uint32_t)Record[Idx++], (uint32_t)Record[Idx++],
(uint32_t)Record[Idx++], (uint32_t)Record[Idx++],
(uint32_t)Record[Idx++]}}};
std::string ImportedName = ReadString(Record, Idx);
std::string ImportedFile;
// For prebuilt and explicit modules first consult the file map for
// an override. Note that here we don't search prebuilt module
// directories, only the explicit name to file mappings. Also, we will
// still verify the size/signature making sure it is essentially the
// same file but perhaps in a different location.
if (ImportedKind == MK_PrebuiltModule || ImportedKind == MK_ExplicitModule)
ImportedFile = PP.getHeaderSearchInfo().getPrebuiltModuleFileName(
ImportedName, /*FileMapOnly*/ true);
if (ImportedFile.empty())
ImportedFile = ReadPath(F, Record, Idx);
else
SkipPath(Record, Idx);
auto ImportedFile = ReadPath(F, Record, Idx);
// If our client can't cope with us being out of date, we can't cope with
// our dependency being missing.
@ -3436,18 +3420,12 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const {
RemapBuilder TypeRemap(F.TypeRemap);
while (Data < DataEnd) {
// FIXME: Looking up dependency modules by filename is horrible. Let's
// start fixing this with prebuilt and explicit modules and see how it
// goes...
// FIXME: Looking up dependency modules by filename is horrible.
using namespace llvm::support;
ModuleKind Kind = static_cast<ModuleKind>(
endian::readNext<uint8_t, little, unaligned>(Data));
uint16_t Len = endian::readNext<uint16_t, little, unaligned>(Data);
StringRef Name = StringRef((const char*)Data, Len);
Data += Len;
ModuleFile *OM = (Kind == MK_PrebuiltModule || Kind == MK_ExplicitModule
? ModuleMgr.lookupByModuleName(Name)
: ModuleMgr.lookupByFileName(Name));
ModuleFile *OM = ModuleMgr.lookup(Name);
if (!OM) {
std::string Msg =
"SourceLocation remap refers to unknown module, cannot find ";
@ -4778,7 +4756,6 @@ bool ASTReader::readASTFileControlBlock(
while (Idx < N) {
// Read information about the AST file.
Idx += 5; // ImportLoc, Size, ModTime, Signature
SkipString(Record, Idx); // Module name; FIXME: pass to listener?
std::string Filename = ReadString(Record, Idx);
ResolveImportedPath(Filename, ModuleDir);
Listener.visitImport(Filename);
@ -10369,8 +10346,7 @@ ASTReader::ASTReader(Preprocessor &PP, ASTContext *Context,
SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
PCHContainerRdr(PCHContainerRdr), Diags(PP.getDiagnostics()), PP(PP),
ContextObj(Context),
ModuleMgr(PP.getFileManager(), PP.getPCMCache(), PCHContainerRdr,
PP.getHeaderSearchInfo()),
ModuleMgr(PP.getFileManager(), PP.getPCMCache(), PCHContainerRdr),
PCMCache(PP.getPCMCache()), DummyIdResolver(PP),
ReadTimer(std::move(ReadTimer)), isysroot(isysroot),
DisableValidation(DisableValidation),

View File

@ -1505,7 +1505,6 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
for (auto I : M.Signature)
Record.push_back(I);
AddString(M.ModuleName, Record);
AddPath(M.FileName, Record);
}
Stream.EmitRecord(IMPORTS, Record);
@ -4780,8 +4779,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
// each of those modules were mapped into our own offset/ID space, so that
// the reader can build the appropriate mapping to its own offset/ID space.
// The map consists solely of a blob with the following format:
// *(module-kind:i8
// module-name-len:i16 module-name:len*i8
// *(module-name-len:i16 module-name:len*i8
// source-location-offset:i32
// identifier-id:i32
// preprocessed-entity-id:i32
@ -4792,10 +4790,6 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
// c++-base-specifiers-id:i32
// type-id:i32)
//
// module-kind is the ModuleKind enum value. If it is MK_PrebuiltModule or
// MK_ExplicitModule, then the module-name is the module name. Otherwise,
// it is the module file name.
//
auto Abbrev = std::make_shared<BitCodeAbbrev>();
Abbrev->Add(BitCodeAbbrevOp(MODULE_OFFSET_MAP));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
@ -4806,13 +4800,9 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
for (ModuleFile &M : Chain->ModuleMgr) {
using namespace llvm::support;
endian::Writer<little> LE(Out);
LE.write<uint8_t>(static_cast<uint8_t>(M.Kind));
StringRef Name =
M.Kind == MK_PrebuiltModule || M.Kind == MK_ExplicitModule
? M.ModuleName
: M.FileName;
LE.write<uint16_t>(Name.size());
Out.write(Name.data(), Name.size());
StringRef FileName = M.FileName;
LE.write<uint16_t>(FileName.size());
Out.write(FileName.data(), FileName.size());
// Note: if a base ID was uint max, it would not be possible to load
// another module after it or have more than one entity inside it.

View File

@ -619,10 +619,6 @@ bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) {
(uint32_t)Record[Idx++], (uint32_t)Record[Idx++],
(uint32_t)Record[Idx++]}}};
// Skip the module name (currently this is only used for prebuilt
// modules while here we are only dealing with cached).
Idx += Record[Idx] + 1;
// Retrieve the imported file name.
unsigned Length = Record[Idx++];
SmallString<128> ImportedFile(Record.begin() + Idx,

View File

@ -28,7 +28,7 @@
using namespace clang;
using namespace serialization;
ModuleFile *ModuleManager::lookupByFileName(StringRef Name) const {
ModuleFile *ModuleManager::lookup(StringRef Name) const {
const FileEntry *Entry = FileMgr.getFile(Name, /*openFile=*/false,
/*cacheFailure=*/false);
if (Entry)
@ -37,14 +37,6 @@ ModuleFile *ModuleManager::lookupByFileName(StringRef Name) const {
return nullptr;
}
ModuleFile *ModuleManager::lookupByModuleName(StringRef Name) const {
if (const Module *Mod = HeaderSearchInfo.getModuleMap().findModule(Name))
if (const FileEntry *File = Mod->getASTFile())
return lookup(File);
return nullptr;
}
ModuleFile *ModuleManager::lookup(const FileEntry *File) const {
auto Known = Modules.find(File);
if (Known == Modules.end())
@ -314,11 +306,9 @@ void ModuleManager::moduleFileAccepted(ModuleFile *MF) {
}
ModuleManager::ModuleManager(FileManager &FileMgr, MemoryBufferCache &PCMCache,
const PCHContainerReader &PCHContainerRdr,
const HeaderSearch& HeaderSearchInfo)
const PCHContainerReader &PCHContainerRdr)
: FileMgr(FileMgr), PCMCache(&PCMCache), PCHContainerRdr(PCHContainerRdr),
HeaderSearchInfo (HeaderSearchInfo), GlobalIndex(),
FirstVisitState(nullptr) {}
GlobalIndex(), FirstVisitState(nullptr) {}
ModuleManager::~ModuleManager() { delete FirstVisitState; }

View File

@ -1,39 +0,0 @@
// Tests for imported module search.
//
// RUN: rm -rf %t
// RUN: mkdir -p %t
// RUN: echo 'export module x; int a, b;' > %t/x.cppm
// RUN: echo 'export module y; import x; int c;' > %t/y.cppm
// RUN: echo 'export module z; import y; int d;' > %t/z.cppm
//
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %t/x.cppm -o %t/x.pcm
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface -fmodule-file=%t/x.pcm %t/y.cppm -o %t/y.pcm
//
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.pcm -verify %s \
// RUN: -DMODULE_NAME=x
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/y.pcm -verify %s \
// RUN: -DMODULE_NAME=y
//
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=x=%t/x.pcm -verify %s \
// RUN: -DMODULE_NAME=x
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=y=%t/y.pcm -verify %s \
// RUN: -DMODULE_NAME=y
//
// RUN: mv %t/x.pcm %t/a.pcm
//
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=x=%t/a.pcm -verify %s \
// RUN: -DMODULE_NAME=x
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/y.pcm -fmodule-file=x=%t/a.pcm -verify %s \
// RUN: -DMODULE_NAME=y
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=y=%t/y.pcm -fmodule-file=x=%t/a.pcm -verify %s \
// RUN: -DMODULE_NAME=y
//
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface -fmodule-file=y=%t/y.pcm -fmodule-file=x=%t/a.pcm %t/z.cppm -o %t/z.pcm
//
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=z=%t/z.pcm -fmodule-file=y=%t/y.pcm -fmodule-file=x=%t/a.pcm -verify %s \
// RUN: -DMODULE_NAME=z
//
import MODULE_NAME;
// expected-no-diagnostics