diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-11-30 21:58:49 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-11-30 21:58:49 +0000 |
commit | 22103e3416cfba9780fcd25c9182df5a8acae634 (patch) | |
tree | 2dbef767b712674939978d25be74c87eb56e604f /clang/lib/Frontend | |
parent | f505d554725faa8737ac01104518310f53f405c8 (diff) | |
download | bcm5719-llvm-22103e3416cfba9780fcd25c9182df5a8acae634.tar.gz bcm5719-llvm-22103e3416cfba9780fcd25c9182df5a8acae634.zip |
When we're emitting a diagnostic with a source location in an imported
module, provide a module import stack similar to what we would get for
an include stack, e.g.,
In module 'DependsOnModule' imported from build-fail-notes.m:4:
In module 'Module' imported from DependsOnModule.framework/Headers/DependsOnModule.h:1:
Inputs/Module.framework/Headers/Module.h:15:12: note: previous definition is here
@interface Module
<rdar://problem/12696425>
llvm-svn: 169042
Diffstat (limited to 'clang/lib/Frontend')
-rw-r--r-- | clang/lib/Frontend/DiagnosticRenderer.cpp | 82 | ||||
-rw-r--r-- | clang/lib/Frontend/TextDiagnostic.cpp | 10 |
2 files changed, 84 insertions, 8 deletions
diff --git a/clang/lib/Frontend/DiagnosticRenderer.cpp b/clang/lib/Frontend/DiagnosticRenderer.cpp index 3599df82c79..4a332ae82fa 100644 --- a/clang/lib/Frontend/DiagnosticRenderer.cpp +++ b/clang/lib/Frontend/DiagnosticRenderer.cpp @@ -132,7 +132,7 @@ void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc, // First, if this diagnostic is not in the main file, print out the // "included from" lines. - emitIncludeStack(PLoc.getIncludeLoc(), Level, *SM); + emitIncludeStack(Loc, PLoc, Level, *SM); } // Next, emit the actual diagnostic message. @@ -184,21 +184,30 @@ void DiagnosticRenderer::emitStoredDiagnostic(StoredDiagnostic &Diag) { /// repeated warnings occur within the same file. It also handles the logic /// of customizing the formatting and display of the include stack. /// +/// \param Loc The diagnostic location. +/// \param PLoc The presumed location of the diagnostic location. /// \param Level The diagnostic level of the message this stack pertains to. -/// \param Loc The include location of the current file (not the diagnostic -/// location). void DiagnosticRenderer::emitIncludeStack(SourceLocation Loc, + PresumedLoc PLoc, DiagnosticsEngine::Level Level, const SourceManager &SM) { + SourceLocation IncludeLoc = PLoc.getIncludeLoc(); + // Skip redundant include stacks altogether. - if (LastIncludeLoc == Loc) + if (LastIncludeLoc == IncludeLoc) return; - LastIncludeLoc = Loc; + + LastIncludeLoc = IncludeLoc; if (!DiagOpts->ShowNoteIncludeStack && Level == DiagnosticsEngine::Note) return; - - emitIncludeStackRecursively(Loc, SM); + + if (IncludeLoc.isValid()) + emitIncludeStackRecursively(IncludeLoc, SM); + else { + emitModuleBuildPath(SM); + emitImportStack(Loc, SM); + } } /// \brief Helper to recursivly walk up the include stack and print each layer @@ -213,7 +222,17 @@ void DiagnosticRenderer::emitIncludeStackRecursively(SourceLocation Loc, PresumedLoc PLoc = SM.getPresumedLoc(Loc, DiagOpts->ShowPresumedLoc); if (PLoc.isInvalid()) return; - + + // If this source location was imported from a module, print the module + // import stack rather than the + // FIXME: We want submodule granularity here. + std::pair<SourceLocation, StringRef> Imported = SM.getModuleImportLoc(Loc); + if (Imported.first.isValid()) { + // This location was imported by a module. Emit the module import stack. + emitImportStackRecursively(Imported.first, Imported.second, SM); + return; + } + // Emit the other include frames first. emitIncludeStackRecursively(PLoc.getIncludeLoc(), SM); @@ -221,6 +240,41 @@ void DiagnosticRenderer::emitIncludeStackRecursively(SourceLocation Loc, emitIncludeLocation(Loc, PLoc, SM); } +/// \brief Emit the module import stack associated with the current location. +void DiagnosticRenderer::emitImportStack(SourceLocation Loc, + const SourceManager &SM) { + if (Loc.isInvalid()) { + emitModuleBuildPath(SM); + return; + } + + std::pair<SourceLocation, StringRef> NextImportLoc + = SM.getModuleImportLoc(Loc); + emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second, SM); +} + +/// \brief Helper to recursivly walk up the import stack and print each layer +/// on the way back down. +void DiagnosticRenderer::emitImportStackRecursively(SourceLocation Loc, + StringRef ModuleName, + const SourceManager &SM) { + if (Loc.isInvalid()) { + return; + } + + PresumedLoc PLoc = SM.getPresumedLoc(Loc, DiagOpts->ShowPresumedLoc); + if (PLoc.isInvalid()) + return; + + // Emit the other import frames first. + std::pair<SourceLocation, StringRef> NextImportLoc + = SM.getModuleImportLoc(Loc); + emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second, SM); + + // Emit the inclusion text/note. + emitImportLocation(Loc, PLoc, ModuleName, SM); +} + /// \brief Emit the module build path, for cases where a module is (re-)built /// on demand. void DiagnosticRenderer::emitModuleBuildPath(const SourceManager &SM) { @@ -407,6 +461,18 @@ void DiagnosticNoteRenderer::emitIncludeLocation(SourceLocation Loc, emitNote(Loc, Message.str(), &SM); } +void DiagnosticNoteRenderer::emitImportLocation(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 << "in module '" << ModuleName << "' imported from " + << PLoc.getFilename() << ':' << PLoc.getLine() << ":"; + emitNote(Loc, Message.str(), &SM); +} + void DiagnosticNoteRenderer::emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc, diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp index 65df875aea3..fe82229c919 100644 --- a/clang/lib/Frontend/TextDiagnostic.cpp +++ b/clang/lib/Frontend/TextDiagnostic.cpp @@ -884,6 +884,16 @@ void TextDiagnostic::emitIncludeLocation(SourceLocation Loc, OS << "In included file:\n"; } +void TextDiagnostic::emitImportLocation(SourceLocation Loc, PresumedLoc PLoc, + StringRef ModuleName, + const SourceManager &SM) { + if (DiagOpts->ShowLocation) + OS << "In module '" << ModuleName << "' imported from " + << PLoc.getFilename() << ':' << PLoc.getLine() << ":\n"; + else + OS << "In module " << ModuleName << "':\n"; +} + void TextDiagnostic::emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc, StringRef ModuleName, |