DiagnosticRenderer.cpp revision 830ea5b7c75413526c19531f0180fa6e45b98919
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. 13516afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis emitIncludeStack(PLoc.getIncludeLoc(), 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/// 1872898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param Level The diagnostic level of the message this stack pertains to. 1882898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param Loc The include location of the current file (not the diagnostic 1892898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// location). 1902898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenekvoid DiagnosticRenderer::emitIncludeStack(SourceLocation Loc, 19116afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis DiagnosticsEngine::Level Level, 19216afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis const SourceManager &SM) { 1932898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Skip redundant include stacks altogether. 1942898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (LastIncludeLoc == Loc) 1952898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return; 1962898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek LastIncludeLoc = Loc; 1972898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 19802c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor if (!DiagOpts->ShowNoteIncludeStack && Level == DiagnosticsEngine::Note) 1992898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return; 2002898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 20116afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis emitIncludeStackRecursively(Loc, SM); 2022898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek} 2032898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 2042898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \brief Helper to recursivly walk up the include stack and print each layer 2052898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// on the way back down. 20616afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidisvoid DiagnosticRenderer::emitIncludeStackRecursively(SourceLocation Loc, 20716afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis const SourceManager &SM) { 208830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor if (Loc.isInvalid()) { 209830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor emitModuleBuildPath(SM); 2102898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return; 211830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor } 2122898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 21362221b17c90457df9ca0ff20bb54d634e8951defRichard Smith PresumedLoc PLoc = SM.getPresumedLoc(Loc, DiagOpts->ShowPresumedLoc); 2142898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (PLoc.isInvalid()) 2152898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return; 2162898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 2172898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Emit the other include frames first. 21816afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis emitIncludeStackRecursively(PLoc.getIncludeLoc(), SM); 2192898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 2202898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Emit the inclusion text/note. 22116afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis emitIncludeLocation(Loc, PLoc, SM); 2222898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek} 2232898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 224830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor/// \brief Emit the module build path, for cases where a module is (re-)built 225830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor/// on demand. 226830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregorvoid DiagnosticRenderer::emitModuleBuildPath(const SourceManager &SM) { 227830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor ModuleBuildPath Path = SM.getModuleBuildPath(); 228830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor for (unsigned I = 0, N = Path.size(); I != N; ++I) { 229830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor const SourceManager &CurSM = Path[I].second.getManager(); 230830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor SourceLocation CurLoc = Path[I].second; 231830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor emitBuildingModuleLocation(CurLoc, 232830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor CurSM.getPresumedLoc(CurLoc, 233830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor DiagOpts->ShowPresumedLoc), 234830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor Path[I].first, 235830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor CurSM); 236830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor } 237830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor} 238830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor 2399cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// Helper function to fix up source ranges. It takes in an array of ranges, 2409cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// and outputs an array of ranges where we want to draw the range highlighting 2419cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// around the location specified by CaretLoc. 2429cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// 2439cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// To find locations which correspond to the caret, we crawl the macro caller 2449cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// chain for the beginning and end of each range. If the caret location 2459cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// is in a macro expansion, we search each chain for a location 2469cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// in the same expansion as the caret; otherwise, we crawl to the top of 2479cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// each chain. Two locations are part of the same macro expansion 2489cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman// iff the FileID is the same. 2499cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedmanstatic void mapDiagnosticRanges( 2509cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman SourceLocation CaretLoc, 2519cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman const SmallVectorImpl<CharSourceRange>& Ranges, 2529cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman SmallVectorImpl<CharSourceRange>& SpellingRanges, 2539cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman const SourceManager *SM) { 2549cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman FileID CaretLocFileID = SM->getFileID(CaretLoc); 2559cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman 2569cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman for (SmallVectorImpl<CharSourceRange>::const_iterator I = Ranges.begin(), 2579cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman E = Ranges.end(); 2589cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman I != E; ++I) { 2599cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman SourceLocation Begin = I->getBegin(), End = I->getEnd(); 2609cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman bool IsTokenRange = I->isTokenRange(); 2619cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman 262ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman FileID BeginFileID = SM->getFileID(Begin); 263ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman FileID EndFileID = SM->getFileID(End); 2649cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman 265ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman // Find the common parent for the beginning and end of the range. 266ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman 267ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman // First, crawl the expansion chain for the beginning of the range. 268ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman llvm::SmallDenseMap<FileID, SourceLocation> BeginLocsMap; 269ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman while (Begin.isMacroID() && BeginFileID != EndFileID) { 270ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman BeginLocsMap[BeginFileID] = Begin; 271ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman Begin = SM->getImmediateExpansionRange(Begin).first; 272ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman BeginFileID = SM->getFileID(Begin); 273ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman } 274ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman 275ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman // Then, crawl the expansion chain for the end of the range. 276ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman if (BeginFileID != EndFileID) { 277ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman while (End.isMacroID() && !BeginLocsMap.count(EndFileID)) { 278ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman End = SM->getImmediateExpansionRange(End).second; 279ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman EndFileID = SM->getFileID(End); 280ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman } 281ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman if (End.isMacroID()) { 282ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman Begin = BeginLocsMap[EndFileID]; 283ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman BeginFileID = EndFileID; 284ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman } 285ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman } 286ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman 287ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman while (Begin.isMacroID() && BeginFileID != CaretLocFileID) { 288ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman if (SM->isMacroArgExpansion(Begin)) { 289ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman Begin = SM->getImmediateSpellingLoc(Begin); 2909cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman End = SM->getImmediateSpellingLoc(End); 2919cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman } else { 292ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman Begin = SM->getImmediateExpansionRange(Begin).first; 2939cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman End = SM->getImmediateExpansionRange(End).second; 2949cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman } 295ecdc8d3e0fc65610746a4e074491ca0807fca7b2Eli Friedman BeginFileID = SM->getFileID(Begin); 2969cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman } 2979cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman 2989cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman // Return the spelling location of the beginning and end of the range. 2999cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman Begin = SM->getSpellingLoc(Begin); 3009cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman End = SM->getSpellingLoc(End); 3019cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman SpellingRanges.push_back(CharSourceRange(SourceRange(Begin, End), 3029cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman IsTokenRange)); 3039cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman } 3049cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman} 3059cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman 3062898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \brief Recursively emit notes for each macro expansion and caret 3072898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// diagnostics where appropriate. 3082898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// 3092898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// Walks up the macro expansion stack printing expansion notes, the code 3102898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// snippet, caret, underlines and FixItHint display as appropriate at each 3112898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// level. 3122898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// 3132898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param Loc The location for this caret. 3142898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param Level The diagnostic level currently being emitted. 3152898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param Ranges The underlined ranges for this code snippet. 3162898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param Hints The FixIt hints active for this diagnostic. 3172898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param MacroSkipEnd The depth to stop skipping macro expansions. 3182898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param OnMacroInst The current depth of the macro expansion stack. 3192898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenekvoid DiagnosticRenderer::emitMacroExpansionsAndCarets( 3202898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek SourceLocation Loc, 3212898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek DiagnosticsEngine::Level Level, 3222898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek SmallVectorImpl<CharSourceRange>& Ranges, 3232898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek ArrayRef<FixItHint> Hints, 32416afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis const SourceManager &SM, 3252898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek unsigned &MacroDepth, 3262898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek unsigned OnMacroInst) 3272898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek{ 3282898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek assert(!Loc.isInvalid() && "must have a valid source location here"); 3292898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 3302898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // If this is a file source location, directly emit the source snippet and 3312898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // caret line. Also record the macro depth reached. 3322898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (Loc.isFileID()) { 3339cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman // Map the ranges. 3349cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman SmallVector<CharSourceRange, 4> SpellingRanges; 3359cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman mapDiagnosticRanges(Loc, Ranges, SpellingRanges, &SM); 3369cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman 3372898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek assert(MacroDepth == 0 && "We shouldn't hit a leaf node twice!"); 3382898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek MacroDepth = OnMacroInst; 3399cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman emitCodeContext(Loc, Level, SpellingRanges, Hints, SM); 3402898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return; 3412898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek } 3422898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Otherwise recurse through each macro expansion layer. 3432898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 3442898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // When processing macros, skip over the expansions leading up to 3452898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // a macro argument, and trace the argument's expansion stack instead. 34629271fbcef645117df05d5b60e593acb6562422cMatt Beaumont-Gay Loc = SM.skipToMacroArgExpansion(Loc); 3472898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 34829271fbcef645117df05d5b60e593acb6562422cMatt Beaumont-Gay SourceLocation OneLevelUp = SM.getImmediateMacroCallerLoc(Loc); 3499cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman 35016afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis emitMacroExpansionsAndCarets(OneLevelUp, Level, Ranges, Hints, SM, MacroDepth, 3512898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek OnMacroInst + 1); 3522898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 3532898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Save the original location so we can find the spelling of the macro call. 3542898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek SourceLocation MacroLoc = Loc; 3552898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 3562898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Map the location. 35729271fbcef645117df05d5b60e593acb6562422cMatt Beaumont-Gay Loc = SM.getImmediateMacroCalleeLoc(Loc); 3582898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 3592898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek unsigned MacroSkipStart = 0, MacroSkipEnd = 0; 36002c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor if (MacroDepth > DiagOpts->MacroBacktraceLimit && 36102c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor DiagOpts->MacroBacktraceLimit != 0) { 36202c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor MacroSkipStart = DiagOpts->MacroBacktraceLimit / 2 + 36302c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor DiagOpts->MacroBacktraceLimit % 2; 36402c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor MacroSkipEnd = MacroDepth - DiagOpts->MacroBacktraceLimit / 2; 3652898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek } 3662898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 3672898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Whether to suppress printing this macro expansion. 3682898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek bool Suppressed = (OnMacroInst >= MacroSkipStart && 3692898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek OnMacroInst < MacroSkipEnd); 3702898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 3712898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (Suppressed) { 3722898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Tell the user that we've skipped contexts. 3732898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (OnMacroInst == MacroSkipStart) { 374f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<200> MessageStorage; 3752898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek llvm::raw_svector_ostream Message(MessageStorage); 3762898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek Message << "(skipping " << (MacroSkipEnd - MacroSkipStart) 3772898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek << " expansions in backtrace; use -fmacro-backtrace-limit=0 to " 3782898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek "see all)"; 3792898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek emitBasicNote(Message.str()); 3802898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek } 3812898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return; 3822898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek } 3839cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman 3849cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman // Map the ranges. 3859cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman SmallVector<CharSourceRange, 4> SpellingRanges; 3869cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman mapDiagnosticRanges(MacroLoc, Ranges, SpellingRanges, &SM); 3879cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman 388f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<100> MessageStorage; 3892898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek llvm::raw_svector_ostream Message(MessageStorage); 3902898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek Message << "expanded from macro '" 3917f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis << getImmediateMacroName(MacroLoc, SM, LangOpts) << "'"; 3922898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek emitDiagnostic(SM.getSpellingLoc(Loc), DiagnosticsEngine::Note, 3932898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek Message.str(), 3949cb1c3de9df7d944f0c5cccaf03fa414036487ebEli Friedman SpellingRanges, ArrayRef<FixItHint>(), &SM); 3952898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek} 3962898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 3978be51eab5ad34515d2a40dcdc8558128ca1800adTed KremenekDiagnosticNoteRenderer::~DiagnosticNoteRenderer() {} 3988be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek 3998be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenekvoid DiagnosticNoteRenderer::emitIncludeLocation(SourceLocation Loc, 40016afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis PresumedLoc PLoc, 40116afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis const SourceManager &SM) { 4028be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek // Generate a note indicating the include location. 4038be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek SmallString<200> MessageStorage; 4048be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek llvm::raw_svector_ostream Message(MessageStorage); 4058be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek Message << "in file included from " << PLoc.getFilename() << ':' 4068be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek << PLoc.getLine() << ":"; 40716afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis emitNote(Loc, Message.str(), &SM); 4088be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek} 4098be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek 410830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregorvoid 411830ea5b7c75413526c19531f0180fa6e45b98919Douglas GregorDiagnosticNoteRenderer::emitBuildingModuleLocation(SourceLocation Loc, 412830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor PresumedLoc PLoc, 413830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor StringRef ModuleName, 414830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor const SourceManager &SM) { 415830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor // Generate a note indicating the include location. 416830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor SmallString<200> MessageStorage; 417830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor llvm::raw_svector_ostream Message(MessageStorage); 418830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor Message << "while building module '" << ModuleName << "' imported from " 419830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor << PLoc.getFilename() << ':' << PLoc.getLine() << ":"; 420830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor emitNote(Loc, Message.str(), &SM); 421830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor} 422830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor 423830ea5b7c75413526c19531f0180fa6e45b98919Douglas Gregor 4248be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenekvoid DiagnosticNoteRenderer::emitBasicNote(StringRef Message) { 42516afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis emitNote(SourceLocation(), Message, 0); 4268be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek} 427