diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Driver/Tools.cpp | 3 | ||||
-rw-r--r-- | lib/Frontend/CompilerInstance.cpp | 30 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 24 |
3 files changed, 55 insertions, 2 deletions
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 71e50a5c9e..7932ba2827 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -428,6 +428,9 @@ void Clang::AddPreprocessingOptions(Compilation &C, CmdArgs.push_back("-fmodule-cache-path"); CmdArgs.push_back(Args.MakeArgString(DefaultModuleCache)); } + + // Pass through all -fmodules-ignore-macro arguments. + Args.AddAllArgs(CmdArgs, options::OPT_fmodules_ignore_macro); // Parse additional include paths from environment variables. // FIXME: We should probably sink the logic for handling these from the diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index b6115ec6ff..356bf3171c 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -743,6 +743,28 @@ static void doCompileMapModule(void *UserData) { Data.Instance.ExecuteAction(Data.CreateModuleAction); } +namespace { + /// \brief Function object that checks with the given macro definition should + /// be removed, because it is one of the ignored macros. + class RemoveIgnoredMacro { + const HeaderSearchOptions &HSOpts; + + public: + explicit RemoveIgnoredMacro(const HeaderSearchOptions &HSOpts) + : HSOpts(HSOpts) { } + + bool operator()(const std::pair<std::string, bool> &def) const { + // Dig out the macro name. + StringRef MacroName = def.first; + StringRef::size_type EqPos = MacroName.find('='); + if (EqPos != StringRef::npos) + MacroName = MacroName.substr(0, EqPos); + + return HSOpts.ModulesIgnoreMacros.count(MacroName) > 0; + } + }; +} + /// \brief Compile a module file for the given module, using the options /// provided by the importing compiler instance. static void compileModule(CompilerInstance &ImportingInstance, @@ -779,6 +801,14 @@ static void compileModule(CompilerInstance &ImportingInstance, Invocation->getLangOpts()->resetNonModularOptions(); PPOpts.resetNonModularOptions(); + // Remove any macro definitions that are explicitly ignored by the module. + // They aren't supposed to affect how the module is built anyway. + const HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts(); + PPOpts.Macros.erase(std::remove_if(PPOpts.Macros.begin(), PPOpts.Macros.end(), + RemoveIgnoredMacro(HSOpts)), + PPOpts.Macros.end()); + + // Note the name of the module we're building. Invocation->getLangOpts()->CurrentModule = Module->getTopLevelModuleName(); diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index a4597fd84d..34496ede26 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -813,7 +813,13 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) { Opts.ResourceDir = Args.getLastArgValue(OPT_resource_dir); Opts.ModuleCachePath = Args.getLastArgValue(OPT_fmodule_cache_path); Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash); - + + for (arg_iterator it = Args.filtered_begin(OPT_fmodules_ignore_macro), + ie = Args.filtered_end(); it != ie; ++it) { + const Arg *A = *it; + Opts.ModulesIgnoreMacros.insert(A->getValue()); + } + // Add -I..., -F..., and -index-header-map options in order. bool IsIndexHeaderMap = false; for (arg_iterator it = Args.filtered_begin(OPT_I, OPT_F, @@ -1600,6 +1606,7 @@ std::string CompilerInvocation::getModuleHash() const { // Extend the signature with preprocessor options. const PreprocessorOptions &ppOpts = getPreprocessorOpts(); + const HeaderSearchOptions &hsOpts = getHeaderSearchOpts(); code = hash_combine(code, ppOpts.UsePredefines, ppOpts.DetailedRecord); std::vector<StringRef> MacroDefs; @@ -1607,11 +1614,24 @@ std::string CompilerInvocation::getModuleHash() const { I = getPreprocessorOpts().Macros.begin(), IEnd = getPreprocessorOpts().Macros.end(); I != IEnd; ++I) { + // If we're supposed to ignore this macro for the purposes of modules, + // don't put it into the hash. + if (!hsOpts.ModulesIgnoreMacros.empty()) { + // Dig out the macro name. + StringRef MacroName = I->first; + StringRef::size_type EqPos = MacroName.find('='); + if (EqPos != StringRef::npos) + MacroName = MacroName.substr(0, EqPos); + + // Check whether we're ignoring this macro. + if (hsOpts.ModulesIgnoreMacros.count(MacroName)) + continue; + } + code = hash_combine(code, I->first, I->second); } // Extend the signature with the sysroot. - const HeaderSearchOptions &hsOpts = getHeaderSearchOpts(); code = hash_combine(code, hsOpts.Sysroot, hsOpts.UseBuiltinIncludes, hsOpts.UseStandardSystemIncludes, hsOpts.UseStandardCXXIncludes, |