summaryrefslogtreecommitdiffstats
path: root/clang/lib/Frontend/CompilerInstance.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-09-15 20:40:10 +0000
committerDouglas Gregor <dgregor@apple.com>2011-09-15 20:40:10 +0000
commitdff0e892db7c39ec39c61317bba368532f643077 (patch)
tree25f28deebf039effe7e98c7ede75933d7b535e3d /clang/lib/Frontend/CompilerInstance.cpp
parent207c68012ab26e1d9d95ec0ba3b6fb18b69a96c9 (diff)
downloadbcm5719-llvm-dff0e892db7c39ec39c61317bba368532f643077.tar.gz
bcm5719-llvm-dff0e892db7c39ec39c61317bba368532f643077.zip
Detect cyclic module dependencies in a manner that is rather more
graceful than running out of stack space. llvm-svn: 139833
Diffstat (limited to 'clang/lib/Frontend/CompilerInstance.cpp')
-rw-r--r--clang/lib/Frontend/CompilerInstance.cpp23
1 files changed, 23 insertions, 0 deletions
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index 07d438b556a..e3689c0c52a 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -660,6 +660,7 @@ static void compileModule(CompilerInstance &ImportingInstance,
(new CompilerInvocation(ImportingInstance.getInvocation()));
Invocation->getLangOpts().resetNonModularOptions();
Invocation->getPreprocessorOpts().resetNonModularOptions();
+ Invocation->getPreprocessorOpts().ModuleBuildPath.push_back(ModuleName);
FrontendOptions &FrontendOpts = Invocation->getFrontendOpts();
FrontendOpts.OutputFile = ModuleFileName.str();
@@ -671,6 +672,7 @@ static void compileModule(CompilerInstance &ImportingInstance,
Invocation->getDiagnosticOpts().VerifyDiagnostics = 0;
+
assert(ImportingInstance.getInvocation().getModuleHash() ==
Invocation->getModuleHash() && "Module hash mismatch!");
@@ -691,6 +693,7 @@ static void compileModule(CompilerInstance &ImportingInstance,
// Tell the diagnostic client that it's (re-)starting to process a source
// file.
+ // FIXME: This is a hack. We probably want to clone the diagnostic client.
ImportingInstance.getDiagnosticClient()
.BeginSourceFile(ImportingInstance.getLangOpts(),
&ImportingInstance.getPreprocessor());
@@ -720,6 +723,26 @@ ModuleKey CompilerInstance::loadModule(SourceLocation ImportLoc,
// We didn't find the module, but there is an umbrella header that
// can be used to create the module file. Create a separate compilation
// module to do so.
+
+ // Check whether there is a cycle in the module graph.
+ SmallVectorImpl<std::string> &ModuleBuildPath
+ = getPreprocessorOpts().ModuleBuildPath;
+ SmallVectorImpl<std::string>::iterator Pos
+ = std::find(ModuleBuildPath.begin(), ModuleBuildPath.end(),
+ ModuleName.getName());
+ if (Pos != ModuleBuildPath.end()) {
+ llvm::SmallString<256> CyclePath;
+ for (; Pos != ModuleBuildPath.end(); ++Pos) {
+ CyclePath += *Pos;
+ CyclePath += " -> ";
+ }
+ CyclePath += ModuleName.getName();
+
+ getDiagnostics().Report(ModuleNameLoc, diag::err_module_cycle)
+ << ModuleName.getName() << CyclePath;
+ return 0;
+ }
+
BuildingModule = true;
compileModule(*this, ModuleName.getName(), ModuleFileName, UmbrellaHeader);
ModuleFile = PP->getHeaderSearchInfo().lookupModule(ModuleName.getName());
OpenPOWER on IntegriCloud