DiagnosticRenderer.cpp revision 6c3254316de2d0d554b19702f4b10117ae46b77b
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" 142898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek#include "clang/Lex/Lexer.h" 1530660a898545416f0fea2d717f16f75640001e38Ted Kremenek#include "clang/Edit/EditedSource.h" 1630660a898545416f0fea2d717f16f75640001e38Ted Kremenek#include "clang/Edit/Commit.h" 1730660a898545416f0fea2d717f16f75640001e38Ted Kremenek#include "clang/Edit/EditsReceiver.h" 182898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek#include "llvm/Support/MemoryBuffer.h" 192898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek#include "llvm/Support/raw_ostream.h" 202898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek#include "llvm/Support/ErrorHandling.h" 219cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman#include "llvm/ADT/SmallSet.h" 222898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek#include "llvm/ADT/SmallString.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()); 1262898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 1278be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek beginDiagnostic(D, Level); 1282898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 12916afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis PresumedLoc PLoc; 13016afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis if (Loc.isValid()) { 13162221b17c90457df9ca0ff20bb54d634e8951defRichard Smith PLoc = SM->getPresumedLocForDisplay(Loc, DiagOpts->ShowPresumedLoc); 1322898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 13316afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis // First, if this diagnostic is not in the main file, print out the 13416afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis // "included from" lines. 1356c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor emitIncludeStack(Loc, PLoc, Level, *SM); 13616afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis } 1372898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 1382898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Next, emit the actual diagnostic message. 13916afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis emitDiagnosticMessage(Loc, PLoc, Level, Message, Ranges, SM, D); 1402898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 1412898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Only recurse if we have a valid location. 1422898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (Loc.isValid()) { 1432898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Get the ranges into a local array we can hack on. 1442898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek SmallVector<CharSourceRange, 20> MutableRanges(Ranges.begin(), 1452898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek Ranges.end()); 1462898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 14730660a898545416f0fea2d717f16f75640001e38Ted Kremenek llvm::SmallVector<FixItHint, 8> MergedFixits; 14830660a898545416f0fea2d717f16f75640001e38Ted Kremenek if (!FixItHints.empty()) { 14916afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis mergeFixits(FixItHints, *SM, LangOpts, MergedFixits); 15030660a898545416f0fea2d717f16f75640001e38Ted Kremenek FixItHints = MergedFixits; 15130660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 15230660a898545416f0fea2d717f16f75640001e38Ted Kremenek 1532898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek for (ArrayRef<FixItHint>::const_iterator I = FixItHints.begin(), 1542898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek E = FixItHints.end(); 1552898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek I != E; ++I) 1562898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (I->RemoveRange.isValid()) 1572898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek MutableRanges.push_back(I->RemoveRange); 1582898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 1592898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek unsigned MacroDepth = 0; 16016afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis emitMacroExpansionsAndCarets(Loc, Level, MutableRanges, FixItHints, *SM, 1612898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek MacroDepth); 1622898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek } 1632898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 1642898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek LastLoc = Loc; 1652898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek LastLevel = Level; 1662898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 1678be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek endDiagnostic(D, Level); 1688be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek} 1698be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek 1708be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek 1718be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenekvoid DiagnosticRenderer::emitStoredDiagnostic(StoredDiagnostic &Diag) { 1728be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek emitDiagnostic(Diag.getLocation(), Diag.getLevel(), Diag.getMessage(), 1738be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek Diag.getRanges(), Diag.getFixIts(), 17416afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis Diag.getLocation().isValid() ? &Diag.getLocation().getManager() 17516afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis : 0, 1768be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek &Diag); 1772898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek} 1782898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 1792898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \brief Prints an include stack when appropriate for a particular 1802898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// diagnostic level and location. 1812898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// 1822898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// This routine handles all the logic of suppressing particular include 1832898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// stacks (such as those for notes) and duplicate include stacks when 1842898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// repeated warnings occur within the same file. It also handles the logic 1852898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// of customizing the formatting and display of the include stack. 1862898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// 1876c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor/// \param Loc The diagnostic location. 1886c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor/// \param PLoc The presumed location of the diagnostic location. 1892898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param Level The diagnostic level of the message this stack pertains to. 1902898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenekvoid DiagnosticRenderer::emitIncludeStack(SourceLocation Loc, 1916c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor PresumedLoc PLoc, 19216afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis DiagnosticsEngine::Level Level, 19316afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis const SourceManager &SM) { 1946c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor SourceLocation IncludeLoc = PLoc.getIncludeLoc(); 1956c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor 1962898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Skip redundant include stacks altogether. 1976c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor if (LastIncludeLoc == IncludeLoc) 1982898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return; 1996c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor 2006c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor LastIncludeLoc = IncludeLoc; 2012898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 20202c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor if (!DiagOpts->ShowNoteIncludeStack && Level == DiagnosticsEngine::Note) 2032898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return; 2046c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor 2056c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor if (IncludeLoc.isValid()) 2066c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor emitIncludeStackRecursively(IncludeLoc, SM); 2076c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor else { 2086c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor emitModuleBuildPath(SM); 2096c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor emitImportStack(Loc, SM); 2106c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor } 2112898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek} 2122898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 2132898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \brief Helper to recursivly walk up the include stack and print each layer 2142898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// on the way back down. 21516afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidisvoid DiagnosticRenderer::emitIncludeStackRecursively(SourceLocation Loc, 21616afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis const SourceManager &SM) { 217830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor if (Loc.isInvalid()) { 218830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor emitModuleBuildPath(SM); 2192898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return; 220830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor } 2212898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 22262221b17c90457df9ca0ff20bb54d634e8951defRichard Smith PresumedLoc PLoc = SM.getPresumedLoc(Loc, DiagOpts->ShowPresumedLoc); 2232898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (PLoc.isInvalid()) 2242898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return; 2256c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor 2266c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor // If this source location was imported from a module, print the module 2276c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor // import stack rather than the 2286c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor // FIXME: We want submodule granularity here. 2296c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor std::pair<SourceLocation, StringRef> Imported = SM.getModuleImportLoc(Loc); 2306c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor if (Imported.first.isValid()) { 2316c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor // This location was imported by a module. Emit the module import stack. 2326c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor emitImportStackRecursively(Imported.first, Imported.second, SM); 2336c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor return; 2346c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor } 2356c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor 2362898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Emit the other include frames first. 23716afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis emitIncludeStackRecursively(PLoc.getIncludeLoc(), SM); 2382898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 2392898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Emit the inclusion text/note. 24016afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis emitIncludeLocation(Loc, PLoc, SM); 2412898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek} 2422898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 2436c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor/// \brief Emit the module import stack associated with the current location. 2446c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregorvoid DiagnosticRenderer::emitImportStack(SourceLocation Loc, 2456c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor const SourceManager &SM) { 2466c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor if (Loc.isInvalid()) { 2476c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor emitModuleBuildPath(SM); 2486c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor return; 2496c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor } 2506c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor 2516c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor std::pair<SourceLocation, StringRef> NextImportLoc 2526c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor = SM.getModuleImportLoc(Loc); 2536c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second, SM); 2546c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor} 2556c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor 2566c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor/// \brief Helper to recursivly walk up the import stack and print each layer 2576c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor/// on the way back down. 2586c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregorvoid DiagnosticRenderer::emitImportStackRecursively(SourceLocation Loc, 2596c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor StringRef ModuleName, 2606c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor const SourceManager &SM) { 2616c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor if (Loc.isInvalid()) { 2626c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor return; 2636c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor } 2646c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor 2656c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor PresumedLoc PLoc = SM.getPresumedLoc(Loc, DiagOpts->ShowPresumedLoc); 2666c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor if (PLoc.isInvalid()) 2676c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor return; 2686c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor 2696c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor // Emit the other import frames first. 2706c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor std::pair<SourceLocation, StringRef> NextImportLoc 2716c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor = SM.getModuleImportLoc(Loc); 2726c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second, SM); 2736c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor 2746c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor // Emit the inclusion text/note. 2756c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor emitImportLocation(Loc, PLoc, ModuleName, SM); 2766c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor} 2776c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor 278830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor/// \brief Emit the module build path, for cases where a module is (re-)built 279830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor/// on demand. 280830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregorvoid DiagnosticRenderer::emitModuleBuildPath(const SourceManager &SM) { 281830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor ModuleBuildPath Path = SM.getModuleBuildPath(); 282830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor for (unsigned I = 0, N = Path.size(); I != N; ++I) { 283830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor const SourceManager &CurSM = Path[I].second.getManager(); 284830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor SourceLocation CurLoc = Path[I].second; 285830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor emitBuildingModuleLocation(CurLoc, 286830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor CurSM.getPresumedLoc(CurLoc, 287830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor DiagOpts->ShowPresumedLoc), 288830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor Path[I].first, 289830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor CurSM); 290830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor } 291830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor} 292830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor 2939cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// Helper function to fix up source ranges. It takes in an array of ranges, 2949cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// and outputs an array of ranges where we want to draw the range highlighting 2959cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// around the location specified by CaretLoc. 2969cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// 2979cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// To find locations which correspond to the caret, we crawl the macro caller 2989cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// chain for the beginning and end of each range. If the caret location 2999cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// is in a macro expansion, we search each chain for a location 3009cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// in the same expansion as the caret; otherwise, we crawl to the top of 3019cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// each chain. Two locations are part of the same macro expansion 3029cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// iff the FileID is the same. 3039cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedmanstatic void mapDiagnosticRanges( 3049cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman SourceLocation CaretLoc, 3059cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman const SmallVectorImpl<CharSourceRange>& Ranges, 3069cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman SmallVectorImpl<CharSourceRange>& SpellingRanges, 3079cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman const SourceManager *SM) { 3089cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman FileID CaretLocFileID = SM->getFileID(CaretLoc); 3099cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman 3109cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman for (SmallVectorImpl<CharSourceRange>::const_iterator I = Ranges.begin(), 3119cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman E = Ranges.end(); 3129cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman I != E; ++I) { 3139cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman SourceLocation Begin = I->getBegin(), End = I->getEnd(); 3149cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman bool IsTokenRange = I->isTokenRange(); 3159cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman 316ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman FileID BeginFileID = SM->getFileID(Begin); 317ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman FileID EndFileID = SM->getFileID(End); 3189cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman 319ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman // Find the common parent for the beginning and end of the range. 320ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman 321ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman // First, crawl the expansion chain for the beginning of the range. 322ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman llvm::SmallDenseMap<FileID, SourceLocation> BeginLocsMap; 323ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman while (Begin.isMacroID() && BeginFileID != EndFileID) { 324ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman BeginLocsMap[BeginFileID] = Begin; 325ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman Begin = SM->getImmediateExpansionRange(Begin).first; 326ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman BeginFileID = SM->getFileID(Begin); 327ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman } 328ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman 329ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman // Then, crawl the expansion chain for the end of the range. 330ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman if (BeginFileID != EndFileID) { 331ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman while (End.isMacroID() && !BeginLocsMap.count(EndFileID)) { 332ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman End = SM->getImmediateExpansionRange(End).second; 333ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman EndFileID = SM->getFileID(End); 334ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman } 335ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman if (End.isMacroID()) { 336ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman Begin = BeginLocsMap[EndFileID]; 337ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman BeginFileID = EndFileID; 338ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman } 339ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman } 340ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman 341ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman while (Begin.isMacroID() && BeginFileID != CaretLocFileID) { 342ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman if (SM->isMacroArgExpansion(Begin)) { 343ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman Begin = SM->getImmediateSpellingLoc(Begin); 3449cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman End = SM->getImmediateSpellingLoc(End); 3459cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman } else { 346ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman Begin = SM->getImmediateExpansionRange(Begin).first; 3479cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman End = SM->getImmediateExpansionRange(End).second; 3489cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman } 349ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman BeginFileID = SM->getFileID(Begin); 3509cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman } 3519cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman 3529cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman // Return the spelling location of the beginning and end of the range. 3539cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman Begin = SM->getSpellingLoc(Begin); 3549cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman End = SM->getSpellingLoc(End); 3559cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman SpellingRanges.push_back(CharSourceRange(SourceRange(Begin, End), 3569cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman IsTokenRange)); 3579cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman } 3589cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman} 3599cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman 3602898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \brief Recursively emit notes for each macro expansion and caret 3612898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// diagnostics where appropriate. 3622898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// 3632898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// Walks up the macro expansion stack printing expansion notes, the code 3642898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// snippet, caret, underlines and FixItHint display as appropriate at each 3652898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// level. 3662898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// 3672898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param Loc The location for this caret. 3682898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param Level The diagnostic level currently being emitted. 3692898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param Ranges The underlined ranges for this code snippet. 3702898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param Hints The FixIt hints active for this diagnostic. 3712898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param MacroSkipEnd The depth to stop skipping macro expansions. 3722898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param OnMacroInst The current depth of the macro expansion stack. 3732898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenekvoid DiagnosticRenderer::emitMacroExpansionsAndCarets( 3742898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek SourceLocation Loc, 3752898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek DiagnosticsEngine::Level Level, 3762898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek SmallVectorImpl<CharSourceRange>& Ranges, 3772898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek ArrayRef<FixItHint> Hints, 37816afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis const SourceManager &SM, 3792898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek unsigned &MacroDepth, 3802898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek unsigned OnMacroInst) 3812898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek{ 3822898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek assert(!Loc.isInvalid() && "must have a valid source location here"); 3832898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 3842898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // If this is a file source location, directly emit the source snippet and 3852898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // caret line. Also record the macro depth reached. 3862898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (Loc.isFileID()) { 3879cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman // Map the ranges. 3889cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman SmallVector<CharSourceRange, 4> SpellingRanges; 3899cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman mapDiagnosticRanges(Loc, Ranges, SpellingRanges, &SM); 3909cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman 3912898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek assert(MacroDepth == 0 && "We shouldn't hit a leaf node twice!"); 3922898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek MacroDepth = OnMacroInst; 3939cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman emitCodeContext(Loc, Level, SpellingRanges, Hints, SM); 3942898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return; 3952898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek } 3962898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Otherwise recurse through each macro expansion layer. 3972898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 3982898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // When processing macros, skip over the expansions leading up to 3992898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // a macro argument, and trace the argument's expansion stack instead. 40029271fbcef645117df05d5b60e593acb6562422cMatt Beaumont-Gay Loc = SM.skipToMacroArgExpansion(Loc); 4012898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 40229271fbcef645117df05d5b60e593acb6562422cMatt Beaumont-Gay SourceLocation OneLevelUp = SM.getImmediateMacroCallerLoc(Loc); 4039cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman 40416afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis emitMacroExpansionsAndCarets(OneLevelUp, Level, Ranges, Hints, SM, MacroDepth, 4052898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek OnMacroInst + 1); 4062898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 4072898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Save the original location so we can find the spelling of the macro call. 4082898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek SourceLocation MacroLoc = Loc; 4092898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 4102898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Map the location. 41129271fbcef645117df05d5b60e593acb6562422cMatt Beaumont-Gay Loc = SM.getImmediateMacroCalleeLoc(Loc); 4122898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 4132898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek unsigned MacroSkipStart = 0, MacroSkipEnd = 0; 41402c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor if (MacroDepth > DiagOpts->MacroBacktraceLimit && 41502c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor DiagOpts->MacroBacktraceLimit != 0) { 41602c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor MacroSkipStart = DiagOpts->MacroBacktraceLimit / 2 + 41702c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor DiagOpts->MacroBacktraceLimit % 2; 41802c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor MacroSkipEnd = MacroDepth - DiagOpts->MacroBacktraceLimit / 2; 4192898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek } 4202898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 4212898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Whether to suppress printing this macro expansion. 4222898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek bool Suppressed = (OnMacroInst >= MacroSkipStart && 4232898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek OnMacroInst < MacroSkipEnd); 4242898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 4252898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (Suppressed) { 4262898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Tell the user that we've skipped contexts. 4272898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (OnMacroInst == MacroSkipStart) { 428f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<200> MessageStorage; 4292898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek llvm::raw_svector_ostream Message(MessageStorage); 4302898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek Message << "(skipping " << (MacroSkipEnd - MacroSkipStart) 4312898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek << " expansions in backtrace; use -fmacro-backtrace-limit=0 to " 4322898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek "see all)"; 4332898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek emitBasicNote(Message.str()); 4342898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek } 4352898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return; 4362898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek } 4379cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman 4389cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman // Map the ranges. 4399cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman SmallVector<CharSourceRange, 4> SpellingRanges; 4409cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman mapDiagnosticRanges(MacroLoc, Ranges, SpellingRanges, &SM); 4419cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman 442f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<100> MessageStorage; 4432898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek llvm::raw_svector_ostream Message(MessageStorage); 4442898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek Message << "expanded from macro '" 4457f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis << getImmediateMacroName(MacroLoc, SM, LangOpts) << "'"; 4462898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek emitDiagnostic(SM.getSpellingLoc(Loc), DiagnosticsEngine::Note, 4472898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek Message.str(), 4489cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman SpellingRanges, ArrayRef<FixItHint>(), &SM); 4492898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek} 4502898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 4518be51eab5ad34515d2a40dcdc8558128ca1800adTed KremenekDiagnosticNoteRenderer::~DiagnosticNoteRenderer() {} 4528be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek 4538be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenekvoid DiagnosticNoteRenderer::emitIncludeLocation(SourceLocation Loc, 45416afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis PresumedLoc PLoc, 45516afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis const SourceManager &SM) { 4568be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek // Generate a note indicating the include location. 4578be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek SmallString<200> MessageStorage; 4588be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek llvm::raw_svector_ostream Message(MessageStorage); 4598be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek Message << "in file included from " << PLoc.getFilename() << ':' 4608be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek << PLoc.getLine() << ":"; 46116afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis emitNote(Loc, Message.str(), &SM); 4628be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek} 4638be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek 4646c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregorvoid DiagnosticNoteRenderer::emitImportLocation(SourceLocation Loc, 4656c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor PresumedLoc PLoc, 4666c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor StringRef ModuleName, 4676c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor const SourceManager &SM) { 4686c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor // Generate a note indicating the include location. 4696c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor SmallString<200> MessageStorage; 4706c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor llvm::raw_svector_ostream Message(MessageStorage); 4716c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor Message << "in module '" << ModuleName << "' imported from " 4726c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor << PLoc.getFilename() << ':' << PLoc.getLine() << ":"; 4736c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor emitNote(Loc, Message.str(), &SM); 4746c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor} 4756c3254316de2d0d554b19702f4b10117ae46b77bDouglas Gregor 476830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregorvoid 477830ea5b7c75413526c19531f0180fa6e45b98919Douglas GregorDiagnosticNoteRenderer::emitBuildingModuleLocation(SourceLocation Loc, 478830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor PresumedLoc PLoc, 479830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor StringRef ModuleName, 480830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor const SourceManager &SM) { 481830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor // Generate a note indicating the include location. 482830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor SmallString<200> MessageStorage; 483830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor llvm::raw_svector_ostream Message(MessageStorage); 484830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor Message << "while building module '" << ModuleName << "' imported from " 485830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor << PLoc.getFilename() << ':' << PLoc.getLine() << ":"; 486830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor emitNote(Loc, Message.str(), &SM); 487830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor} 488830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor 489830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor 4908be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenekvoid DiagnosticNoteRenderer::emitBasicNote(StringRef Message) { 49116afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis emitNote(SourceLocation(), Message, 0); 4928be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek} 493