[cfe-commits] r139833 - in /cfe/trunk: include/clang/Basic/DiagnosticCommonKinds.td include/clang/Frontend/PreprocessorOptions.h lib/Frontend/CompilerInstance.cpp
Douglas Gregor
dgregor at apple.com
Thu Sep 15 13:40:10 PDT 2011
Author: dgregor
Date: Thu Sep 15 15:40:10 2011
New Revision: 139833
URL: http://llvm.org/viewvc/llvm-project?rev=139833&view=rev
Log:
Detect cyclic module dependencies in a manner that is rather more
graceful than running out of stack space.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td
cfe/trunk/include/clang/Frontend/PreprocessorOptions.h
cfe/trunk/lib/Frontend/CompilerInstance.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td?rev=139833&r1=139832&r2=139833&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td Thu Sep 15 15:40:10 2011
@@ -61,7 +61,9 @@
"only functions can have deleted definitions">;
def err_module_not_found : Error<"module '%0' not found">, DefaultFatal;
def err_module_not_built : Error<"could not build module '%0'">, DefaultFatal;
-
+def err_module_cycle : Error<"cyclic dependency in module '%0': %1">,
+ DefaultFatal;
+
// Sema && Lex
def ext_longlong : Extension<
"'long long' is an extension when C99 mode is not enabled">,
Modified: cfe/trunk/include/clang/Frontend/PreprocessorOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PreprocessorOptions.h?rev=139833&r1=139832&r2=139833&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/PreprocessorOptions.h (original)
+++ cfe/trunk/include/clang/Frontend/PreprocessorOptions.h Thu Sep 15 15:40:10 2011
@@ -117,6 +117,14 @@
/// by providing appropriate definitions to retrofit the standard library
/// with support for lifetime-qualified pointers.
ObjCXXARCStandardLibraryKind ObjCXXARCStandardLibrary;
+
+ /// \brief The path of modules being build, which is used to detect
+ /// cycles in the module dependency graph as modules are being built.
+ ///
+ /// There is no way to set this value from the command line. If we ever need
+ /// to do so (e.g., if on-demand module construction moves out-of-process),
+ /// we can add a cc1-level option to do so.
+ SmallVector<std::string, 2> ModuleBuildPath;
typedef std::vector<std::pair<std::string, std::string> >::iterator
remapped_file_iterator;
Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=139833&r1=139832&r2=139833&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Thu Sep 15 15:40:10 2011
@@ -660,6 +660,7 @@
(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 @@
Invocation->getDiagnosticOpts().VerifyDiagnostics = 0;
+
assert(ImportingInstance.getInvocation().getModuleHash() ==
Invocation->getModuleHash() && "Module hash mismatch!");
@@ -691,6 +693,7 @@
// 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 @@
// 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());
More information about the cfe-commits
mailing list