diff options
author | Douglas Gregor <dgregor@apple.com> | 2013-02-07 00:21:12 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2013-02-07 00:21:12 +0000 |
commit | 2a06085281d1b6aee628f85e8676eec04542cbc9 (patch) | |
tree | 555fd6e3a34befb20718444336bf6667927a6261 /lib/Frontend | |
parent | 712f5b3bef988e8d3dd38fdf2264e7cc1a3f6bf9 (diff) |
Introduce -fmodules-ignore-macro=NNN to ignore a macro when building/loading modules.
The use of this flag enables a modules optimization where a given set
of macros can be labeled as "ignored" by the modules
system. Definitions of those macros will be completely ignored when
building the module hash and will be stripped when actually building
modules. The overall effect is that this flag can be used to
drastically reduce the number of
Eventually, we'll want modules to tell us what set of macros they
respond to (the "configuration macros"), and anything not in that set
will be excluded. However, that requires a lot of per-module
information that must be accurate, whereas this option can be used
more readily.
Fixes the rest of <rdar://problem/13165109>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174560 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Frontend')
-rw-r--r-- | lib/Frontend/CompilerInstance.cpp | 30 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 24 |
2 files changed, 52 insertions, 2 deletions
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, |