DiagnosticRenderer.cpp revision 98cffc6b30dacd71434530fee368b1f7d03bd565
12898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek//===--- DiagnosticRenderer.cpp - Diagnostic Pretty-Printing --------------===// 22898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek// 32898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek// The LLVM Compiler Infrastructure 42898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek// 52898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek// This file is distributed under the University of Illinois Open Source 62898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek// License. See LICENSE.TXT for details. 72898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek// 82898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek//===----------------------------------------------------------------------===// 92898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 102898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek#include "clang/Frontend/DiagnosticRenderer.h" 1102c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor#include "clang/Basic/DiagnosticOptions.h" 122898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek#include "clang/Basic/FileManager.h" 132898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek#include "clang/Basic/SourceManager.h" 1430660a898545416f0fea2d717f16f75640001e38Ted Kremenek#include "clang/Edit/Commit.h" 1555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Edit/EditedSource.h" 1630660a898545416f0fea2d717f16f75640001e38Ted Kremenek#include "clang/Edit/EditsReceiver.h" 1755fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Lex/Lexer.h" 189cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman#include "llvm/ADT/SmallSet.h" 192898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek#include "llvm/ADT/SmallString.h" 2055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/ErrorHandling.h" 2155fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/MemoryBuffer.h" 2255fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/raw_ostream.h" 232898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek#include <algorithm> 242898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenekusing namespace clang; 252898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 267f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// \brief Retrieve the name of the immediate macro expansion. 277f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// 287f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// This routine starts from a source location, and finds the name of the macro 297f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// responsible for its immediate expansion. It looks through any intervening 307f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// macro argument expansions to compute this. It returns a StringRef which 317f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// refers to the SourceManager-owned buffer of the source where that macro 327f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// name is spelled. Thus, the result shouldn't out-live that SourceManager. 337f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// 347f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// This differs from Lexer::getImmediateMacroName in that any macro argument 357f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// location will result in the topmost function macro that accepted it. 367f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// e.g. 377f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// \code 387f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// MAC1( MAC2(foo) ) 397f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// \endcode 407f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// for location of 'foo' token, this function will return "MAC1" while 417f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// Lexer::getImmediateMacroName will return "MAC2". 427f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidisstatic StringRef getImmediateMacroName(SourceLocation Loc, 437f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis const SourceManager &SM, 447f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis const LangOptions &LangOpts) { 457f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis assert(Loc.isMacroID() && "Only reasonble to call this on macros"); 467f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis // Walk past macro argument expanions. 477f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis while (SM.isMacroArgExpansion(Loc)) 487f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis Loc = SM.getImmediateExpansionRange(Loc).first; 497f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis 507f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis // Find the spelling location of the start of the non-argument expansion 517f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis // range. This is where the macro name was spelled in order to begin 527f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis // expanding this macro. 537f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis Loc = SM.getSpellingLoc(SM.getImmediateExpansionRange(Loc).first); 547f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis 557f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis // Dig out the buffer where the macro name was spelled and the extents of the 567f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis // name so that we can render it into the expansion note. 577f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis std::pair<FileID, unsigned> ExpansionInfo = SM.getDecomposedLoc(Loc); 587f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis unsigned MacroTokenLength = Lexer::MeasureTokenLength(Loc, SM, LangOpts); 597f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis StringRef ExpansionBuffer = SM.getBufferData(ExpansionInfo.first); 607f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis return ExpansionBuffer.substr(ExpansionInfo.second, MacroTokenLength); 617f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis} 627f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis 6316afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios KyrtzidisDiagnosticRenderer::DiagnosticRenderer(const LangOptions &LangOpts, 6402c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor DiagnosticOptions *DiagOpts) 6502c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor : LangOpts(LangOpts), DiagOpts(DiagOpts), LastLevel() {} 662898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 672898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted KremenekDiagnosticRenderer::~DiagnosticRenderer() {} 682898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 6930660a898545416f0fea2d717f16f75640001e38Ted Kremeneknamespace { 7030660a898545416f0fea2d717f16f75640001e38Ted Kremenek 7130660a898545416f0fea2d717f16f75640001e38Ted Kremenekclass FixitReceiver : public edit::EditsReceiver { 7230660a898545416f0fea2d717f16f75640001e38Ted Kremenek SmallVectorImpl<FixItHint> &MergedFixits; 7330660a898545416f0fea2d717f16f75640001e38Ted Kremenek 7430660a898545416f0fea2d717f16f75640001e38Ted Kremenekpublic: 7530660a898545416f0fea2d717f16f75640001e38Ted Kremenek FixitReceiver(SmallVectorImpl<FixItHint> &MergedFixits) 7630660a898545416f0fea2d717f16f75640001e38Ted Kremenek : MergedFixits(MergedFixits) { } 7730660a898545416f0fea2d717f16f75640001e38Ted Kremenek virtual void insert(SourceLocation loc, StringRef text) { 7830660a898545416f0fea2d717f16f75640001e38Ted Kremenek MergedFixits.push_back(FixItHint::CreateInsertion(loc, text)); 7930660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 8030660a898545416f0fea2d717f16f75640001e38Ted Kremenek virtual void replace(CharSourceRange range, StringRef text) { 8130660a898545416f0fea2d717f16f75640001e38Ted Kremenek MergedFixits.push_back(FixItHint::CreateReplacement(range, text)); 8230660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 8330660a898545416f0fea2d717f16f75640001e38Ted Kremenek}; 8430660a898545416f0fea2d717f16f75640001e38Ted Kremenek 8530660a898545416f0fea2d717f16f75640001e38Ted Kremenek} 8630660a898545416f0fea2d717f16f75640001e38Ted Kremenek 8730660a898545416f0fea2d717f16f75640001e38Ted Kremenekstatic void mergeFixits(ArrayRef<FixItHint> FixItHints, 8830660a898545416f0fea2d717f16f75640001e38Ted Kremenek const SourceManager &SM, const LangOptions &LangOpts, 8930660a898545416f0fea2d717f16f75640001e38Ted Kremenek SmallVectorImpl<FixItHint> &MergedFixits) { 9030660a898545416f0fea2d717f16f75640001e38Ted Kremenek edit::Commit commit(SM, LangOpts); 9130660a898545416f0fea2d717f16f75640001e38Ted Kremenek for (ArrayRef<FixItHint>::const_iterator 9230660a898545416f0fea2d717f16f75640001e38Ted Kremenek I = FixItHints.begin(), E = FixItHints.end(); I != E; ++I) { 9330660a898545416f0fea2d717f16f75640001e38Ted Kremenek const FixItHint &Hint = *I; 9430660a898545416f0fea2d717f16f75640001e38Ted Kremenek if (Hint.CodeToInsert.empty()) { 9530660a898545416f0fea2d717f16f75640001e38Ted Kremenek if (Hint.InsertFromRange.isValid()) 9630660a898545416f0fea2d717f16f75640001e38Ted Kremenek commit.insertFromRange(Hint.RemoveRange.getBegin(), 9730660a898545416f0fea2d717f16f75640001e38Ted Kremenek Hint.InsertFromRange, /*afterToken=*/false, 9830660a898545416f0fea2d717f16f75640001e38Ted Kremenek Hint.BeforePreviousInsertions); 9930660a898545416f0fea2d717f16f75640001e38Ted Kremenek else 10030660a898545416f0fea2d717f16f75640001e38Ted Kremenek commit.remove(Hint.RemoveRange); 10130660a898545416f0fea2d717f16f75640001e38Ted Kremenek } else { 10230660a898545416f0fea2d717f16f75640001e38Ted Kremenek if (Hint.RemoveRange.isTokenRange() || 10330660a898545416f0fea2d717f16f75640001e38Ted Kremenek Hint.RemoveRange.getBegin() != Hint.RemoveRange.getEnd()) 10430660a898545416f0fea2d717f16f75640001e38Ted Kremenek commit.replace(Hint.RemoveRange, Hint.CodeToInsert); 10530660a898545416f0fea2d717f16f75640001e38Ted Kremenek else 10630660a898545416f0fea2d717f16f75640001e38Ted Kremenek commit.insert(Hint.RemoveRange.getBegin(), Hint.CodeToInsert, 10730660a898545416f0fea2d717f16f75640001e38Ted Kremenek /*afterToken=*/false, Hint.BeforePreviousInsertions); 10830660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 10930660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 11030660a898545416f0fea2d717f16f75640001e38Ted Kremenek 11130660a898545416f0fea2d717f16f75640001e38Ted Kremenek edit::EditedSource Editor(SM, LangOpts); 11230660a898545416f0fea2d717f16f75640001e38Ted Kremenek if (Editor.commit(commit)) { 11330660a898545416f0fea2d717f16f75640001e38Ted Kremenek FixitReceiver Rec(MergedFixits); 11430660a898545416f0fea2d717f16f75640001e38Ted Kremenek Editor.applyRewrites(Rec); 11530660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 11630660a898545416f0fea2d717f16f75640001e38Ted Kremenek} 1172898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 1182898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenekvoid DiagnosticRenderer::emitDiagnostic(SourceLocation Loc, 1192898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek DiagnosticsEngine::Level Level, 1202898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek StringRef Message, 1212898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek ArrayRef<CharSourceRange> Ranges, 1222898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek ArrayRef<FixItHint> FixItHints, 12316afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis const SourceManager *SM, 1248be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek DiagOrStoredDiag D) { 12516afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis assert(SM || Loc.isInvalid()); 12698cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith 1278be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek beginDiagnostic(D, Level); 12898cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith 12998cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith if (!Loc.isValid()) 13098cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith // If we have no source location, just emit the diagnostic message. 13198cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith emitDiagnosticMessage(Loc, PresumedLoc(), Level, Message, Ranges, SM, D); 13298cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith else { 1332898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Get the ranges into a local array we can hack on. 1342898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek SmallVector<CharSourceRange, 20> MutableRanges(Ranges.begin(), 1352898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek Ranges.end()); 13698cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith 13730660a898545416f0fea2d717f16f75640001e38Ted Kremenek llvm::SmallVector<FixItHint, 8> MergedFixits; 13830660a898545416f0fea2d717f16f75640001e38Ted Kremenek if (!FixItHints.empty()) { 13916afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis mergeFixits(FixItHints, *SM, LangOpts, MergedFixits); 14030660a898545416f0fea2d717f16f75640001e38Ted Kremenek FixItHints = MergedFixits; 14130660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 14230660a898545416f0fea2d717f16f75640001e38Ted Kremenek 1432898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek for (ArrayRef<FixItHint>::const_iterator I = FixItHints.begin(), 1442898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek E = FixItHints.end(); 1452898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek I != E; ++I) 1462898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (I->RemoveRange.isValid()) 1472898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek MutableRanges.push_back(I->RemoveRange); 148ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith 14998cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith SourceLocation UnexpandedLoc = Loc; 15098cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith 15198cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith // Perform the same walk as emitMacroExpansions, to find the ultimate 15298cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith // expansion location for the diagnostic. 15398cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith while (Loc.isMacroID()) 15498cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith Loc = SM->getImmediateMacroCallerLoc(Loc); 155ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith 15698cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith PresumedLoc PLoc = SM->getPresumedLoc(Loc, DiagOpts->ShowPresumedLoc); 15798cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith 15898cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith // First, if this diagnostic is not in the main file, print out the 15998cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith // "included from" lines. 16098cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith emitIncludeStack(Loc, PLoc, Level, *SM); 16198cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith 16298cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith // Next, emit the actual diagnostic message and caret. 16398cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith emitDiagnosticMessage(Loc, PLoc, Level, Message, Ranges, SM, D); 16498cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith emitCaret(Loc, Level, MutableRanges, FixItHints, *SM); 16598cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith 16698cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith // If this location is within a macro, walk from UnexpandedLoc up to Loc 16798cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith // and produce a macro backtrace. 16898cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith if (UnexpandedLoc.isValid() && UnexpandedLoc.isMacroID()) { 169ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith unsigned MacroDepth = 0; 17098cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith emitMacroExpansions(UnexpandedLoc, Level, MutableRanges, FixItHints, *SM, 171ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith MacroDepth); 172ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith } 1732898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek } 17498cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith 1752898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek LastLoc = Loc; 1762898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek LastLevel = Level; 17798cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith 1788be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek endDiagnostic(D, Level); 1798be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek} 1808be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek 1818be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek 1828be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenekvoid DiagnosticRenderer::emitStoredDiagnostic(StoredDiagnostic &Diag) { 1838be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek emitDiagnostic(Diag.getLocation(), Diag.getLevel(), Diag.getMessage(), 1848be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek Diag.getRanges(), Diag.getFixIts(), 18516afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis Diag.getLocation().isValid() ? &Diag.getLocation().getManager() 18616afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis : 0, 1878be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek &Diag); 1882898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek} 1892898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 1902898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \brief Prints an include stack when appropriate for a particular 1912898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// diagnostic level and location. 1922898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// 1932898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// This routine handles all the logic of suppressing particular include 1942898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// stacks (such as those for notes) and duplicate include stacks when 1952898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// repeated warnings occur within the same file. It also handles the logic 1962898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// of customizing the formatting and display of the include stack. 1972898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// 1986c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor/// \param Loc The diagnostic location. 1996c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor/// \param PLoc The presumed location of the diagnostic location. 2002898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param Level The diagnostic level of the message this stack pertains to. 2012898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenekvoid DiagnosticRenderer::emitIncludeStack(SourceLocation Loc, 2026c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor PresumedLoc PLoc, 20316afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis DiagnosticsEngine::Level Level, 20416afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis const SourceManager &SM) { 2056c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor SourceLocation IncludeLoc = PLoc.getIncludeLoc(); 2066c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor 2072898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Skip redundant include stacks altogether. 2086c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor if (LastIncludeLoc == IncludeLoc) 2092898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return; 2106c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor 2116c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor LastIncludeLoc = IncludeLoc; 2122898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 21302c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor if (!DiagOpts->ShowNoteIncludeStack && Level == DiagnosticsEngine::Note) 2142898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return; 2156c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor 2166c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor if (IncludeLoc.isValid()) 2176c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor emitIncludeStackRecursively(IncludeLoc, SM); 2186c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor else { 2194565e487531c7bf6d348dbe9f5529784966fc7aeDouglas Gregor emitModuleBuildStack(SM); 2206c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor emitImportStack(Loc, SM); 2216c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor } 2222898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek} 2232898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 2242898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \brief Helper to recursivly walk up the include stack and print each layer 2252898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// on the way back down. 22616afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidisvoid DiagnosticRenderer::emitIncludeStackRecursively(SourceLocation Loc, 22716afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis const SourceManager &SM) { 228830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor if (Loc.isInvalid()) { 2294565e487531c7bf6d348dbe9f5529784966fc7aeDouglas Gregor emitModuleBuildStack(SM); 2302898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return; 231830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor } 2322898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 23362221b17c90457df9ca0ff20bb54d634e8951defRichard Smith PresumedLoc PLoc = SM.getPresumedLoc(Loc, DiagOpts->ShowPresumedLoc); 2342898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (PLoc.isInvalid()) 2352898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return; 2366c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor 2376c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor // If this source location was imported from a module, print the module 2386c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor // import stack rather than the 2396c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor // FIXME: We want submodule granularity here. 2406c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor std::pair<SourceLocation, StringRef> Imported = SM.getModuleImportLoc(Loc); 2416c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor if (Imported.first.isValid()) { 2426c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor // This location was imported by a module. Emit the module import stack. 2436c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor emitImportStackRecursively(Imported.first, Imported.second, SM); 2446c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor return; 2456c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor } 2466c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor 2472898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Emit the other include frames first. 24816afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis emitIncludeStackRecursively(PLoc.getIncludeLoc(), SM); 2492898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 2502898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Emit the inclusion text/note. 25116afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis emitIncludeLocation(Loc, PLoc, SM); 2522898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek} 2532898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 2546c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor/// \brief Emit the module import stack associated with the current location. 2556c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregorvoid DiagnosticRenderer::emitImportStack(SourceLocation Loc, 2566c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor const SourceManager &SM) { 2576c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor if (Loc.isInvalid()) { 2584565e487531c7bf6d348dbe9f5529784966fc7aeDouglas Gregor emitModuleBuildStack(SM); 2596c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor return; 2606c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor } 2616c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor 2626c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor std::pair<SourceLocation, StringRef> NextImportLoc 2636c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor = SM.getModuleImportLoc(Loc); 2646c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second, SM); 2656c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor} 2666c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor 2676c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor/// \brief Helper to recursivly walk up the import stack and print each layer 2686c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor/// on the way back down. 2696c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregorvoid DiagnosticRenderer::emitImportStackRecursively(SourceLocation Loc, 2706c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor StringRef ModuleName, 2716c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor const SourceManager &SM) { 2726c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor if (Loc.isInvalid()) { 2736c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor return; 2746c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor } 2756c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor 2766c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor PresumedLoc PLoc = SM.getPresumedLoc(Loc, DiagOpts->ShowPresumedLoc); 2776c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor if (PLoc.isInvalid()) 2786c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor return; 2796c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor 2806c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor // Emit the other import frames first. 2816c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor std::pair<SourceLocation, StringRef> NextImportLoc 2826c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor = SM.getModuleImportLoc(Loc); 2836c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second, SM); 2846c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor 2856c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor // Emit the inclusion text/note. 2866c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor emitImportLocation(Loc, PLoc, ModuleName, SM); 2876c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor} 2886c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor 2894565e487531c7bf6d348dbe9f5529784966fc7aeDouglas Gregor/// \brief Emit the module build stack, for cases where a module is (re-)built 290830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor/// on demand. 2914565e487531c7bf6d348dbe9f5529784966fc7aeDouglas Gregorvoid DiagnosticRenderer::emitModuleBuildStack(const SourceManager &SM) { 2924565e487531c7bf6d348dbe9f5529784966fc7aeDouglas Gregor ModuleBuildStack Stack = SM.getModuleBuildStack(); 2934565e487531c7bf6d348dbe9f5529784966fc7aeDouglas Gregor for (unsigned I = 0, N = Stack.size(); I != N; ++I) { 2944565e487531c7bf6d348dbe9f5529784966fc7aeDouglas Gregor const SourceManager &CurSM = Stack[I].second.getManager(); 2954565e487531c7bf6d348dbe9f5529784966fc7aeDouglas Gregor SourceLocation CurLoc = Stack[I].second; 296830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor emitBuildingModuleLocation(CurLoc, 297830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor CurSM.getPresumedLoc(CurLoc, 298830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor DiagOpts->ShowPresumedLoc), 2994565e487531c7bf6d348dbe9f5529784966fc7aeDouglas Gregor Stack[I].first, 300830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor CurSM); 301830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor } 302830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor} 303830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor 3049cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// Helper function to fix up source ranges. It takes in an array of ranges, 3059cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// and outputs an array of ranges where we want to draw the range highlighting 3069cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// around the location specified by CaretLoc. 3079cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// 3089cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// To find locations which correspond to the caret, we crawl the macro caller 3099cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// chain for the beginning and end of each range. If the caret location 3109cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// is in a macro expansion, we search each chain for a location 3119cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// in the same expansion as the caret; otherwise, we crawl to the top of 3129cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// each chain. Two locations are part of the same macro expansion 3139cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// iff the FileID is the same. 3149cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedmanstatic void mapDiagnosticRanges( 3159cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman SourceLocation CaretLoc, 316ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith ArrayRef<CharSourceRange> Ranges, 31798cffc6b30dacd71434530fee368b1f7d03bd565Richard Smith SmallVectorImpl<CharSourceRange> &SpellingRanges, 3189cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman const SourceManager *SM) { 3199cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman FileID CaretLocFileID = SM->getFileID(CaretLoc); 3209cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman 321ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith for (ArrayRef<CharSourceRange>::const_iterator I = Ranges.begin(), 3229cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman E = Ranges.end(); 3239cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman I != E; ++I) { 3249cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman SourceLocation Begin = I->getBegin(), End = I->getEnd(); 3259cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman bool IsTokenRange = I->isTokenRange(); 3269cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman 327ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman FileID BeginFileID = SM->getFileID(Begin); 328ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman FileID EndFileID = SM->getFileID(End); 3299cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman 330ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman // Find the common parent for the beginning and end of the range. 331ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman 332ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman // First, crawl the expansion chain for the beginning of the range. 333ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman llvm::SmallDenseMap<FileID, SourceLocation> BeginLocsMap; 334ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman while (Begin.isMacroID() && BeginFileID != EndFileID) { 335ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman BeginLocsMap[BeginFileID] = Begin; 336ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman Begin = SM->getImmediateExpansionRange(Begin).first; 337ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman BeginFileID = SM->getFileID(Begin); 338ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman } 339ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman 340ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman // Then, crawl the expansion chain for the end of the range. 341ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman if (BeginFileID != EndFileID) { 342ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman while (End.isMacroID() && !BeginLocsMap.count(EndFileID)) { 343ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman End = SM->getImmediateExpansionRange(End).second; 344ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman EndFileID = SM->getFileID(End); 345ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman } 346ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman if (End.isMacroID()) { 347ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman Begin = BeginLocsMap[EndFileID]; 348ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman BeginFileID = EndFileID; 349ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman } 350ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman } 351ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman 352ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman while (Begin.isMacroID() && BeginFileID != CaretLocFileID) { 353ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman if (SM->isMacroArgExpansion(Begin)) { 354ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman Begin = SM->getImmediateSpellingLoc(Begin); 3559cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman End = SM->getImmediateSpellingLoc(End); 3569cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman } else { 357ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman Begin = SM->getImmediateExpansionRange(Begin).first; 3589cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman End = SM->getImmediateExpansionRange(End).second; 3599cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman } 360ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman BeginFileID = SM->getFileID(Begin); 3619cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman } 3629cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman 3639cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman // Return the spelling location of the beginning and end of the range. 3649cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman Begin = SM->getSpellingLoc(Begin); 3659cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman End = SM->getSpellingLoc(End); 3669cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman SpellingRanges.push_back(CharSourceRange(SourceRange(Begin, End), 3679cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman IsTokenRange)); 3689cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman } 3699cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman} 3709cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman 371ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smithvoid DiagnosticRenderer::emitCaret(SourceLocation Loc, 372ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith DiagnosticsEngine::Level Level, 373ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith ArrayRef<CharSourceRange> Ranges, 374ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith ArrayRef<FixItHint> Hints, 375ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith const SourceManager &SM) { 376ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith SmallVector<CharSourceRange, 4> SpellingRanges; 377ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith mapDiagnosticRanges(Loc, Ranges, SpellingRanges, &SM); 378ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith emitCodeContext(Loc, Level, SpellingRanges, Hints, SM); 379ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith} 380ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith 3812898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \brief Recursively emit notes for each macro expansion and caret 3822898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// diagnostics where appropriate. 3832898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// 3842898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// Walks up the macro expansion stack printing expansion notes, the code 3852898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// snippet, caret, underlines and FixItHint display as appropriate at each 3862898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// level. 3872898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// 3882898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param Loc The location for this caret. 3892898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param Level The diagnostic level currently being emitted. 3902898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param Ranges The underlined ranges for this code snippet. 3912898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param Hints The FixIt hints active for this diagnostic. 3922898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param MacroSkipEnd The depth to stop skipping macro expansions. 3932898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param OnMacroInst The current depth of the macro expansion stack. 394ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smithvoid DiagnosticRenderer::emitMacroExpansions(SourceLocation Loc, 395ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith DiagnosticsEngine::Level Level, 396ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith ArrayRef<CharSourceRange> Ranges, 397ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith ArrayRef<FixItHint> Hints, 398ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith const SourceManager &SM, 399ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith unsigned &MacroDepth, 400ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith unsigned OnMacroInst) { 4012898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek assert(!Loc.isInvalid() && "must have a valid source location here"); 402678839297204002df215e0be12bcd10b20a9a4a4Richard Smith 403678839297204002df215e0be12bcd10b20a9a4a4Richard Smith // Walk up to the caller of this macro, and produce a backtrace down to there. 404678839297204002df215e0be12bcd10b20a9a4a4Richard Smith SourceLocation OneLevelUp = SM.getImmediateMacroCallerLoc(Loc); 405ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith if (OneLevelUp.isMacroID()) 406ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith emitMacroExpansions(OneLevelUp, Level, Ranges, Hints, SM, 407ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith MacroDepth, OnMacroInst + 1); 408ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith else 409ac31c8346f1ce3628b5a7fb862fefab5b94f8e82Richard Smith MacroDepth = OnMacroInst + 1; 410678839297204002df215e0be12bcd10b20a9a4a4Richard Smith 4112898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek unsigned MacroSkipStart = 0, MacroSkipEnd = 0; 41202c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor if (MacroDepth > DiagOpts->MacroBacktraceLimit && 41302c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor DiagOpts->MacroBacktraceLimit != 0) { 41402c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor MacroSkipStart = DiagOpts->MacroBacktraceLimit / 2 + 41502c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor DiagOpts->MacroBacktraceLimit % 2; 41602c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor MacroSkipEnd = MacroDepth - DiagOpts->MacroBacktraceLimit / 2; 4172898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek } 418678839297204002df215e0be12bcd10b20a9a4a4Richard Smith 4192898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Whether to suppress printing this macro expansion. 4202898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek bool Suppressed = (OnMacroInst >= MacroSkipStart && 4212898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek OnMacroInst < MacroSkipEnd); 422678839297204002df215e0be12bcd10b20a9a4a4Richard Smith 4232898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (Suppressed) { 4242898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Tell the user that we've skipped contexts. 4252898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (OnMacroInst == MacroSkipStart) { 426f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<200> MessageStorage; 4272898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek llvm::raw_svector_ostream Message(MessageStorage); 4282898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek Message << "(skipping " << (MacroSkipEnd - MacroSkipStart) 4292898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek << " expansions in backtrace; use -fmacro-backtrace-limit=0 to " 4302898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek "see all)"; 4312898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek emitBasicNote(Message.str()); 4322898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek } 4332898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return; 4342898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek } 4359cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman 436678839297204002df215e0be12bcd10b20a9a4a4Richard Smith // Find the spelling location for the macro definition. We must use the 437678839297204002df215e0be12bcd10b20a9a4a4Richard Smith // spelling location here to avoid emitting a macro bactrace for the note. 438678839297204002df215e0be12bcd10b20a9a4a4Richard Smith SourceLocation SpellingLoc = Loc; 439678839297204002df215e0be12bcd10b20a9a4a4Richard Smith // If this is the expansion of a macro argument, point the caret at the 440678839297204002df215e0be12bcd10b20a9a4a4Richard Smith // use of the argument in the definition of the macro, not the expansion. 441678839297204002df215e0be12bcd10b20a9a4a4Richard Smith if (SM.isMacroArgExpansion(Loc)) 442678839297204002df215e0be12bcd10b20a9a4a4Richard Smith SpellingLoc = SM.getImmediateExpansionRange(Loc).first; 443678839297204002df215e0be12bcd10b20a9a4a4Richard Smith SpellingLoc = SM.getSpellingLoc(SpellingLoc); 444678839297204002df215e0be12bcd10b20a9a4a4Richard Smith 445678839297204002df215e0be12bcd10b20a9a4a4Richard Smith // Map the ranges into the FileID of the diagnostic location. 4469cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman SmallVector<CharSourceRange, 4> SpellingRanges; 447678839297204002df215e0be12bcd10b20a9a4a4Richard Smith mapDiagnosticRanges(Loc, Ranges, SpellingRanges, &SM); 4489cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman 449f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<100> MessageStorage; 4502898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek llvm::raw_svector_ostream Message(MessageStorage); 4512898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek Message << "expanded from macro '" 452678839297204002df215e0be12bcd10b20a9a4a4Richard Smith << getImmediateMacroName(Loc, SM, LangOpts) << "'"; 453678839297204002df215e0be12bcd10b20a9a4a4Richard Smith emitDiagnostic(SpellingLoc, DiagnosticsEngine::Note, 4542898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek Message.str(), 4559cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman SpellingRanges, ArrayRef<FixItHint>(), &SM); 4562898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek} 4572898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 4588be51eab5ad34515d2a40dcdc8558128ca1800adTed KremenekDiagnosticNoteRenderer::~DiagnosticNoteRenderer() {} 4598be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek 4608be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenekvoid DiagnosticNoteRenderer::emitIncludeLocation(SourceLocation Loc, 46116afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis PresumedLoc PLoc, 46216afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis const SourceManager &SM) { 4638be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek // Generate a note indicating the include location. 4648be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek SmallString<200> MessageStorage; 4658be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek llvm::raw_svector_ostream Message(MessageStorage); 4668be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek Message << "in file included from " << PLoc.getFilename() << ':' 4678be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek << PLoc.getLine() << ":"; 46816afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis emitNote(Loc, Message.str(), &SM); 4698be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek} 4708be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek 4716c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregorvoid DiagnosticNoteRenderer::emitImportLocation(SourceLocation Loc, 4726c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor PresumedLoc PLoc, 4736c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor StringRef ModuleName, 4746c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor const SourceManager &SM) { 4756c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor // Generate a note indicating the include location. 4766c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor SmallString<200> MessageStorage; 4776c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor llvm::raw_svector_ostream Message(MessageStorage); 4786c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor Message << "in module '" << ModuleName << "' imported from " 4796c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor << PLoc.getFilename() << ':' << PLoc.getLine() << ":"; 4806c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor emitNote(Loc, Message.str(), &SM); 4816c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor} 4826c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor 483830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregorvoid 484830ea5b7c75413526c19531f0180fa6e45b98919Douglas GregorDiagnosticNoteRenderer::emitBuildingModuleLocation(SourceLocation Loc, 485830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor PresumedLoc PLoc, 486830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor StringRef ModuleName, 487830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor const SourceManager &SM) { 488830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor // Generate a note indicating the include location. 489830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor SmallString<200> MessageStorage; 490830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor llvm::raw_svector_ostream Message(MessageStorage); 491830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor Message << "while building module '" << ModuleName << "' imported from " 492830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor << PLoc.getFilename() << ':' << PLoc.getLine() << ":"; 493830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor emitNote(Loc, Message.str(), &SM); 494830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor} 495830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor 496830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor 4978be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenekvoid DiagnosticNoteRenderer::emitBasicNote(StringRef Message) { 49816afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis emitNote(SourceLocation(), Message, 0); 4998be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek} 500