[cfe-commits] r145436 - in /cfe/trunk/lib: Frontend/CompilerInstance.cpp Lex/ModuleMap.cpp
Douglas Gregor
dgregor at apple.com
Tue Nov 29 13:59:16 PST 2011
Author: dgregor
Date: Tue Nov 29 15:59:16 2011
New Revision: 145436
URL: http://llvm.org/viewvc/llvm-project?rev=145436&view=rev
Log:
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.
Modified:
cfe/trunk/lib/Frontend/CompilerInstance.cpp
cfe/trunk/lib/Lex/ModuleMap.cpp
Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=145436&r1=145435&r2=145436&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Tue Nov 29 15:59:16 2011
@@ -696,20 +696,6 @@
}
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 @@
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 @@
&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,
Modified: cfe/trunk/lib/Lex/ModuleMap.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ModuleMap.cpp?rev=145436&r1=145435&r2=145436&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/ModuleMap.cpp (original)
+++ cfe/trunk/lib/Lex/ModuleMap.cpp Tue Nov 29 15:59:16 2011
@@ -69,7 +69,7 @@
}
static void indent(llvm::raw_ostream &OS, unsigned Spaces) {
- OS << std::string(' ', Spaces);
+ OS << std::string(Spaces, ' ');
}
void ModuleMap::Module::print(llvm::raw_ostream &OS, unsigned Indent) const {
@@ -78,7 +78,7 @@
OS << "framework ";
if (IsExplicit)
OS << "explicit ";
- OS << Name << " {\n";
+ OS << "module " << Name << " {\n";
if (UmbrellaHeader) {
indent(OS, Indent + 2);
@@ -586,28 +586,35 @@
// Look for this file.
llvm::SmallString<128> PathName;
- PathName += Directory->getName();
- unsigned PathLength = PathName.size();
const FileEntry *File = 0;
- if (ActiveModule->isPartOfFramework()) {
- // Check whether this file is in the public headers.
- llvm::sys::path::append(PathName, "Headers");
- llvm::sys::path::append(PathName, FileName);
+
+ if (llvm::sys::path::is_absolute(FileName)) {
+ PathName = FileName;
File = SourceMgr.getFileManager().getFile(PathName);
+ } else {
+ // Search for the header file within the search directory.
+ PathName += Directory->getName();
+ unsigned PathLength = PathName.size();
+ if (ActiveModule->isPartOfFramework()) {
+ // Check whether this file is in the public headers.
+ llvm::sys::path::append(PathName, "Headers");
+ llvm::sys::path::append(PathName, FileName);
+ File = SourceMgr.getFileManager().getFile(PathName);
- if (!File) {
- // Check whether this file is in the private headers.
- PathName.resize(PathLength);
- llvm::sys::path::append(PathName, "PrivateHeaders");
+ if (!File) {
+ // Check whether this file is in the private headers.
+ PathName.resize(PathLength);
+ llvm::sys::path::append(PathName, "PrivateHeaders");
+ llvm::sys::path::append(PathName, FileName);
+ File = SourceMgr.getFileManager().getFile(PathName);
+ }
+
+ // FIXME: Deal with subframeworks.
+ } else {
+ // Lookup for normal headers.
llvm::sys::path::append(PathName, FileName);
File = SourceMgr.getFileManager().getFile(PathName);
}
-
- // FIXME: Deal with subframeworks.
- } else {
- // Lookup for normal headers.
- llvm::sys::path::append(PathName, FileName);
- File = SourceMgr.getFileManager().getFile(PathName);
}
// FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
@@ -654,11 +661,14 @@
// Look for this file.
llvm::SmallString<128> PathName;
- PathName += Directory->getName();
+ if (llvm::sys::path::is_relative(FileName)) {
+ // FIXME: Change this search to also look for private headers!
+ PathName += Directory->getName();
+
+ if (ActiveModule->isPartOfFramework())
+ llvm::sys::path::append(PathName, "Headers");
+ }
- if (ActiveModule->isPartOfFramework())
- llvm::sys::path::append(PathName, "Headers");
-
llvm::sys::path::append(PathName, FileName);
// FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
More information about the cfe-commits
mailing list