aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-11-30 18:38:50 +0000
committerDouglas Gregor <dgregor@apple.com>2012-11-30 18:38:50 +0000
commit830ea5b7c75413526c19531f0180fa6e45b98919 (patch)
treefbc998f5090d858324e3c4d014248eccf2f87863 /lib
parent7f2d4804510799a1a19d72b2b089e48370ab8686 (diff)
When an error occurs while building a module on demand, provide "While
building module 'Foo' imported from..." notes (the same we we provide "In file included from..." notes) in the diagnostic, so that we know how this module got included in the first place. This is part of <rdar://problem/12696425>. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@169021 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Frontend/CompilerInstance.cpp39
-rw-r--r--lib/Frontend/DiagnosticRenderer.cpp33
-rw-r--r--lib/Frontend/TextDiagnostic.cpp11
3 files changed, 68 insertions, 15 deletions
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index f87a635420..150f99578c 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -762,6 +762,7 @@ static void doCompileMapModule(void *UserData) {
/// \brief Compile a module file for the given module, using the options
/// provided by the importing compiler instance.
static void compileModule(CompilerInstance &ImportingInstance,
+ SourceLocation ImportLoc,
Module *Module,
StringRef ModuleFileName) {
llvm::LockFileManager Locked(ModuleFileName);
@@ -797,10 +798,6 @@ static void compileModule(CompilerInstance &ImportingInstance,
// 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.
- PPOpts.ModuleBuildPath.push_back(Module->getTopLevelModuleName());
-
// Make sure that the failed-module structure has been allocated in
// the importing instance, and propagate the pointer to the newly-created
// instance.
@@ -861,7 +858,18 @@ static void compileModule(CompilerInstance &ImportingInstance,
&ImportingInstance.getDiagnosticClient(),
/*ShouldOwnClient=*/true,
/*ShouldCloneClient=*/true);
-
+
+ // Note that this module is part of the module build path, so that we
+ // can detect cycles in the module graph.
+ Instance.createFileManager(); // FIXME: Adopt file manager from importer?
+ Instance.createSourceManager(Instance.getFileManager());
+ SourceManager &SourceMgr = Instance.getSourceManager();
+ SourceMgr.setModuleBuildPath(
+ ImportingInstance.getSourceManager().getModuleBuildPath());
+ SourceMgr.appendModuleBuildPath(Module->getTopLevelModuleName(),
+ FullSourceLoc(ImportLoc, ImportingInstance.getSourceManager()));
+
+
// Construct a module-generating action.
GenerateModuleAction CreateModuleAction;
@@ -939,14 +947,17 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
// build the module.
// 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);
- if (Pos != ModuleBuildPath.end()) {
+ ModuleBuildPath Path = getSourceManager().getModuleBuildPath();
+ ModuleBuildPath::iterator Pos = Path.begin(), PosEnd = Path.end();
+ for (; Pos != PosEnd; ++Pos) {
+ if (Pos->first == ModuleName)
+ break;
+ }
+
+ if (Pos != PosEnd) {
SmallString<256> CyclePath;
- for (; Pos != ModuleBuildPath.end(); ++Pos) {
- CyclePath += *Pos;
+ for (; Pos != PosEnd; ++Pos) {
+ CyclePath += Pos->first;
CyclePath += " -> ";
}
CyclePath += ModuleName;
@@ -970,7 +981,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
getDiagnostics().Report(ModuleNameLoc, diag::warn_module_build)
<< ModuleName;
BuildingModule = true;
- compileModule(*this, Module, ModuleFileName);
+ compileModule(*this, ModuleNameLoc, Module, ModuleFileName);
ModuleFile = FileMgr->getFile(ModuleFileName);
if (!ModuleFile)
@@ -1040,7 +1051,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
return ModuleLoadResult();
}
- compileModule(*this, Module, ModuleFileName);
+ compileModule(*this, ModuleNameLoc, Module, ModuleFileName);
// Try loading the module again.
ModuleFile = FileMgr->getFile(ModuleFileName);
diff --git a/lib/Frontend/DiagnosticRenderer.cpp b/lib/Frontend/DiagnosticRenderer.cpp
index 3143cc7b32..3599df82c7 100644
--- a/lib/Frontend/DiagnosticRenderer.cpp
+++ b/lib/Frontend/DiagnosticRenderer.cpp
@@ -205,8 +205,10 @@ void DiagnosticRenderer::emitIncludeStack(SourceLocation Loc,
/// on the way back down.
void DiagnosticRenderer::emitIncludeStackRecursively(SourceLocation Loc,
const SourceManager &SM) {
- if (Loc.isInvalid())
+ if (Loc.isInvalid()) {
+ emitModuleBuildPath(SM);
return;
+ }
PresumedLoc PLoc = SM.getPresumedLoc(Loc, DiagOpts->ShowPresumedLoc);
if (PLoc.isInvalid())
@@ -219,6 +221,21 @@ void DiagnosticRenderer::emitIncludeStackRecursively(SourceLocation Loc,
emitIncludeLocation(Loc, PLoc, SM);
}
+/// \brief Emit the module build path, for cases where a module is (re-)built
+/// on demand.
+void DiagnosticRenderer::emitModuleBuildPath(const SourceManager &SM) {
+ ModuleBuildPath Path = SM.getModuleBuildPath();
+ for (unsigned I = 0, N = Path.size(); I != N; ++I) {
+ const SourceManager &CurSM = Path[I].second.getManager();
+ SourceLocation CurLoc = Path[I].second;
+ emitBuildingModuleLocation(CurLoc,
+ CurSM.getPresumedLoc(CurLoc,
+ DiagOpts->ShowPresumedLoc),
+ Path[I].first,
+ CurSM);
+ }
+}
+
// Helper function to fix up source ranges. It takes in an array of ranges,
// and outputs an array of ranges where we want to draw the range highlighting
// around the location specified by CaretLoc.
@@ -390,6 +407,20 @@ void DiagnosticNoteRenderer::emitIncludeLocation(SourceLocation Loc,
emitNote(Loc, Message.str(), &SM);
}
+void
+DiagnosticNoteRenderer::emitBuildingModuleLocation(SourceLocation Loc,
+ PresumedLoc PLoc,
+ StringRef ModuleName,
+ const SourceManager &SM) {
+ // Generate a note indicating the include location.
+ SmallString<200> MessageStorage;
+ llvm::raw_svector_ostream Message(MessageStorage);
+ Message << "while building module '" << ModuleName << "' imported from "
+ << PLoc.getFilename() << ':' << PLoc.getLine() << ":";
+ emitNote(Loc, Message.str(), &SM);
+}
+
+
void DiagnosticNoteRenderer::emitBasicNote(StringRef Message) {
emitNote(SourceLocation(), Message, 0);
}
diff --git a/lib/Frontend/TextDiagnostic.cpp b/lib/Frontend/TextDiagnostic.cpp
index 35dabad606..65df875aea 100644
--- a/lib/Frontend/TextDiagnostic.cpp
+++ b/lib/Frontend/TextDiagnostic.cpp
@@ -884,6 +884,17 @@ void TextDiagnostic::emitIncludeLocation(SourceLocation Loc,
OS << "In included file:\n";
}
+void TextDiagnostic::emitBuildingModuleLocation(SourceLocation Loc,
+ PresumedLoc PLoc,
+ StringRef ModuleName,
+ const SourceManager &SM) {
+ if (DiagOpts->ShowLocation)
+ OS << "While building module '" << ModuleName << "' imported from "
+ << PLoc.getFilename() << ':' << PLoc.getLine() << ":\n";
+ else
+ OS << "While building module '" << ModuleName << "':\n";
+}
+
/// \brief Emit a code snippet and caret line.
///
/// This routine emits a single line's code snippet and caret line..