summaryrefslogtreecommitdiffstats
path: root/clang/lib/Frontend/CompilerInstance.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-11-29 21:59:16 +0000
committerDouglas Gregor <dgregor@apple.com>2011-11-29 21:59:16 +0000
commitf545f67de3a1bfdbbfad88acde5b540ce3b82f4f (patch)
tree9f39023a08b932b6e913787046a2d7c7c4fd83a5 /clang/lib/Frontend/CompilerInstance.cpp
parent9c978444049decdd2cd0abb917fd7e0d92dd1db7 (diff)
downloadbcm5719-llvm-f545f67de3a1bfdbbfad88acde5b540ce3b82f4f.tar.gz
bcm5719-llvm-f545f67de3a1bfdbbfad88acde5b540ce3b82f4f.zip
Switch on-demand module building over to use module maps, always. When
we infer the module map, we'll just print the module map to a temporary file and generate the module using that. llvm-svn: 145436
Diffstat (limited to 'clang/lib/Frontend/CompilerInstance.cpp')
-rw-r--r--clang/lib/Frontend/CompilerInstance.cpp118
1 files changed, 46 insertions, 72 deletions
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index 433b2cceb7d..35f82174b2e 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -696,20 +696,6 @@ static InputKind getSourceInputKindFromOptions(const LangOptions &LangOpts) {
}
namespace {
- struct CompileModuleData {
- CompilerInstance &Instance;
- GeneratePCHAction &CreateModuleAction;
- };
-}
-
-/// \brief Helper function that executes the module-generating action under
-/// a crash recovery context.
-static void doCompileModule(void *UserData) {
- CompileModuleData &Data = *reinterpret_cast<CompileModuleData *>(UserData);
- Data.Instance.ExecuteAction(Data.CreateModuleAction);
-}
-
-namespace {
struct CompileModuleMapData {
CompilerInstance &Instance;
GenerateModuleAction &CreateModuleAction;
@@ -1001,79 +987,60 @@ static void compileModule(CompilerInstance &ImportingInstance,
llvm::IntrusiveRefCntPtr<CompilerInvocation> Invocation
(new CompilerInvocation(ImportingInstance.getInvocation()));
+ PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
+
// For any options that aren't intended to affect how a module is built,
// reset them to their default values.
Invocation->getLangOpts()->resetNonModularOptions();
- Invocation->getPreprocessorOpts().resetNonModularOptions();
+ PPOpts.resetNonModularOptions();
// Note the name of the module we're building.
Invocation->getLangOpts()->CurrentModule = Module->getTopLevelModuleName();
// Note that this module is part of the module build path, so that we
// can detect cycles in the module graph.
- Invocation->getPreprocessorOpts().ModuleBuildPath
- .push_back(Module->getTopLevelModuleName());
-
- if (const FileEntry *ModuleMapFile
- = ModMap.getContainingModuleMapFile(Module)) {
- // If there is a module map file, build the module using the module map.
- // Set up the inputs/outputs so that we build the module from its umbrella
- // header.
- FrontendOptions &FrontendOpts = Invocation->getFrontendOpts();
- FrontendOpts.OutputFile = ModuleFileName.str();
- FrontendOpts.DisableFree = false;
- FrontendOpts.Inputs.clear();
- FrontendOpts.Inputs.push_back(
- std::make_pair(getSourceInputKindFromOptions(*Invocation->getLangOpts()),
- ModuleMapFile->getName()));
-
- Invocation->getDiagnosticOpts().VerifyDiagnostics = 0;
-
-
- assert(ImportingInstance.getInvocation().getModuleHash() ==
- Invocation->getModuleHash() && "Module hash mismatch!");
-
- // Construct a compiler instance that will be used to actually create the
- // module.
- CompilerInstance Instance;
- Instance.setInvocation(&*Invocation);
- Instance.createDiagnostics(/*argc=*/0, /*argv=*/0,
- &ImportingInstance.getDiagnosticClient(),
- /*ShouldOwnClient=*/true,
- /*ShouldCloneClient=*/true);
-
- // Construct a module-generating action.
- GenerateModuleAction CreateModuleAction;
-
- // Execute the action to actually build the module in-place. Use a separate
- // thread so that we get a stack large enough.
- const unsigned ThreadStackSize = 8 << 20;
- llvm::CrashRecoveryContext CRC;
- CompileModuleMapData Data = { Instance, CreateModuleAction };
- CRC.RunSafelyOnThread(&doCompileMapModule, &Data, ThreadStackSize);
- return;
- }
-
- // FIXME: Temporary fallback: generate the module from the umbrella header.
- // This is currently used when we infer a module map from a framework.
- assert(Module->UmbrellaHeader && "Inferred module map needs umbrella header");
+ PPOpts.ModuleBuildPath.push_back(Module->getTopLevelModuleName());
+ // If there is a module map file, build the module using the module map.
// Set up the inputs/outputs so that we build the module from its umbrella
// header.
FrontendOptions &FrontendOpts = Invocation->getFrontendOpts();
FrontendOpts.OutputFile = ModuleFileName.str();
FrontendOpts.DisableFree = false;
FrontendOpts.Inputs.clear();
- FrontendOpts.Inputs.push_back(
- std::make_pair(getSourceInputKindFromOptions(*Invocation->getLangOpts()),
- Module->UmbrellaHeader->getName()));
+ InputKind IK = getSourceInputKindFromOptions(*Invocation->getLangOpts());
- Invocation->getDiagnosticOpts().VerifyDiagnostics = 0;
+ // Get or create the module map that we'll use to build this module.
+ llvm::SmallString<128> TempModuleMapFileName;
+ if (const FileEntry *ModuleMapFile
+ = ModMap.getContainingModuleMapFile(Module)) {
+ // Use the module map where this module resides.
+ FrontendOpts.Inputs.push_back(std::make_pair(IK, ModuleMapFile->getName()));
+ } else {
+ // Create a temporary module map file.
+ TempModuleMapFileName = Module->Name;
+ TempModuleMapFileName += "-%%%%%%%%.map";
+ int FD;
+ if (llvm::sys::fs::unique_file(TempModuleMapFileName.str(), FD,
+ TempModuleMapFileName,
+ /*makeAbsolute=*/false)
+ != llvm::errc::success)
+ return;
+ // Print the module map to this file.
+ llvm::raw_fd_ostream OS(FD, /*shouldClose=*/true);
+ Module->print(OS);
+ FrontendOpts.Inputs.push_back(
+ std::make_pair(IK, TempModuleMapFileName.str().str()));
+ }
+ // Don't free the remapped file buffers; they are owned by our caller.
+ PPOpts.RetainRemappedFileBuffers = true;
+
+ Invocation->getDiagnosticOpts().VerifyDiagnostics = 0;
assert(ImportingInstance.getInvocation().getModuleHash() ==
- Invocation->getModuleHash() && "Module hash mismatch!");
-
+ Invocation->getModuleHash() && "Module hash mismatch!");
+
// Construct a compiler instance that will be used to actually create the
// module.
CompilerInstance Instance;
@@ -1082,16 +1049,23 @@ static void compileModule(CompilerInstance &ImportingInstance,
&ImportingInstance.getDiagnosticClient(),
/*ShouldOwnClient=*/true,
/*ShouldCloneClient=*/true);
-
+
// Construct a module-generating action.
- GeneratePCHAction CreateModuleAction(true);
-
+ GenerateModuleAction CreateModuleAction;
+
// Execute the action to actually build the module in-place. Use a separate
// thread so that we get a stack large enough.
const unsigned ThreadStackSize = 8 << 20;
llvm::CrashRecoveryContext CRC;
- CompileModuleData Data = { Instance, CreateModuleAction };
- CRC.RunSafelyOnThread(&doCompileModule, &Data, ThreadStackSize);
+ CompileModuleMapData Data = { Instance, CreateModuleAction };
+ CRC.RunSafelyOnThread(&doCompileMapModule, &Data, ThreadStackSize);
+
+ // Delete the temporary module map file.
+ // FIXME: Even though we're executing under crash protection, it would still
+ // be nice to do this with RemoveFileOnSignal when we can. However, that
+ // doesn't make sense for all clients, so clean this up manually.
+ if (!TempModuleMapFileName.empty())
+ llvm::sys::Path(TempModuleMapFileName).eraseFromDisk();
}
ModuleKey CompilerInstance::loadModule(SourceLocation ImportLoc,
OpenPOWER on IntegriCloud