diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-09-15 20:40:10 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-09-15 20:40:10 +0000 |
commit | 4ebd45f4279d84416568ada6adf56044bdf391b7 (patch) | |
tree | fddd149d63dc34932172754cc809902023a7df65 /lib/Frontend/CompilerInstance.cpp | |
parent | f2b4e6652f15ed3b9492216badc9688ba7ccfe38 (diff) |
Detect cyclic module dependencies in a manner that is rather more
graceful than running out of stack space.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139833 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Frontend/CompilerInstance.cpp')
-rw-r--r-- | lib/Frontend/CompilerInstance.cpp | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index 07d438b556..e3689c0c52 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/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()); |