DiagnosticRenderer.cpp revision 30660a898545416f0fea2d717f16f75640001e38
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" 112898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek#include "clang/Basic/FileManager.h" 122898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek#include "clang/Basic/SourceManager.h" 132898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek#include "clang/Frontend/DiagnosticOptions.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" 212898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek#include "llvm/ADT/SmallString.h" 222898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek#include <algorithm> 232898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenekusing namespace clang; 242898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 252898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// Look through spelling locations for a macro argument expansion, and 262898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// if found skip to it so that we can trace the argument rather than the macros 272898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// in which that argument is used. If no macro argument expansion is found, 282898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// don't skip anything and return the starting location. 292898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenekstatic SourceLocation skipToMacroArgExpansion(const SourceManager &SM, 302898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek SourceLocation StartLoc) { 312898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek for (SourceLocation L = StartLoc; L.isMacroID(); 322898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek L = SM.getImmediateSpellingLoc(L)) { 332898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (SM.isMacroArgExpansion(L)) 342898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return L; 352898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek } 362898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 372898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Otherwise just return initial location, there's nothing to skip. 382898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return StartLoc; 392898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek} 402898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 412898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// Gets the location of the immediate macro caller, one level up the stack 422898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// toward the initial macro typed into the source. 432898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenekstatic SourceLocation getImmediateMacroCallerLoc(const SourceManager &SM, 442898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek SourceLocation Loc) { 452898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (!Loc.isMacroID()) return Loc; 462898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 472898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // When we have the location of (part of) an expanded parameter, its spelling 482898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // location points to the argument as typed into the macro call, and 492898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // therefore is used to locate the macro caller. 502898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (SM.isMacroArgExpansion(Loc)) 512898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return SM.getImmediateSpellingLoc(Loc); 522898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 532898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Otherwise, the caller of the macro is located where this macro is 542898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // expanded (while the spelling is part of the macro definition). 552898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return SM.getImmediateExpansionRange(Loc).first; 562898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek} 572898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 582898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// Gets the location of the immediate macro callee, one level down the stack 592898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// toward the leaf macro. 602898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenekstatic SourceLocation getImmediateMacroCalleeLoc(const SourceManager &SM, 612898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek SourceLocation Loc) { 622898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (!Loc.isMacroID()) return Loc; 632898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 642898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // When we have the location of (part of) an expanded parameter, its 652898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // expansion location points to the unexpanded paramater reference within 662898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // the macro definition (or callee). 672898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (SM.isMacroArgExpansion(Loc)) 682898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return SM.getImmediateExpansionRange(Loc).first; 692898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 702898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Otherwise, the callee of the macro is located where this location was 712898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // spelled inside the macro definition. 722898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return SM.getImmediateSpellingLoc(Loc); 732898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek} 742898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 757f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// \brief Retrieve the name of the immediate macro expansion. 767f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// 777f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// This routine starts from a source location, and finds the name of the macro 787f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// responsible for its immediate expansion. It looks through any intervening 797f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// macro argument expansions to compute this. It returns a StringRef which 807f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// refers to the SourceManager-owned buffer of the source where that macro 817f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// name is spelled. Thus, the result shouldn't out-live that SourceManager. 827f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// 837f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// This differs from Lexer::getImmediateMacroName in that any macro argument 847f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// location will result in the topmost function macro that accepted it. 857f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// e.g. 867f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// \code 877f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// MAC1( MAC2(foo) ) 887f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// \endcode 897f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// for location of 'foo' token, this function will return "MAC1" while 907f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis/// Lexer::getImmediateMacroName will return "MAC2". 917f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidisstatic StringRef getImmediateMacroName(SourceLocation Loc, 927f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis const SourceManager &SM, 937f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis const LangOptions &LangOpts) { 947f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis assert(Loc.isMacroID() && "Only reasonble to call this on macros"); 957f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis // Walk past macro argument expanions. 967f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis while (SM.isMacroArgExpansion(Loc)) 977f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis Loc = SM.getImmediateExpansionRange(Loc).first; 987f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis 997f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis // Find the spelling location of the start of the non-argument expansion 1007f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis // range. This is where the macro name was spelled in order to begin 1017f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis // expanding this macro. 1027f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis Loc = SM.getSpellingLoc(SM.getImmediateExpansionRange(Loc).first); 1037f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis 1047f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis // Dig out the buffer where the macro name was spelled and the extents of the 1057f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis // name so that we can render it into the expansion note. 1067f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis std::pair<FileID, unsigned> ExpansionInfo = SM.getDecomposedLoc(Loc); 1077f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis unsigned MacroTokenLength = Lexer::MeasureTokenLength(Loc, SM, LangOpts); 1087f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis StringRef ExpansionBuffer = SM.getBufferData(ExpansionInfo.first); 1097f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis return ExpansionBuffer.substr(ExpansionInfo.second, MacroTokenLength); 1107f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis} 1117f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis 1122898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// Get the presumed location of a diagnostic message. This computes the 1132898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// presumed location for the top of any macro backtrace when present. 1142898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenekstatic PresumedLoc getDiagnosticPresumedLoc(const SourceManager &SM, 1152898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek SourceLocation Loc) { 1162898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // This is a condensed form of the algorithm used by emitCaretDiagnostic to 1172898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // walk to the top of the macro call stack. 1182898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek while (Loc.isMacroID()) { 1192898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek Loc = skipToMacroArgExpansion(SM, Loc); 1202898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek Loc = getImmediateMacroCallerLoc(SM, Loc); 1212898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek } 1222898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 1232898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return SM.getPresumedLoc(Loc); 1242898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek} 1252898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 1262898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted KremenekDiagnosticRenderer::DiagnosticRenderer(const SourceManager &SM, 1272898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek const LangOptions &LangOpts, 1282898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek const DiagnosticOptions &DiagOpts) 1292898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek: SM(SM), LangOpts(LangOpts), DiagOpts(DiagOpts), LastLevel() {} 1302898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 1312898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted KremenekDiagnosticRenderer::~DiagnosticRenderer() {} 1322898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 13330660a898545416f0fea2d717f16f75640001e38Ted Kremeneknamespace { 13430660a898545416f0fea2d717f16f75640001e38Ted Kremenek 13530660a898545416f0fea2d717f16f75640001e38Ted Kremenekclass FixitReceiver : public edit::EditsReceiver { 13630660a898545416f0fea2d717f16f75640001e38Ted Kremenek SmallVectorImpl<FixItHint> &MergedFixits; 13730660a898545416f0fea2d717f16f75640001e38Ted Kremenek 13830660a898545416f0fea2d717f16f75640001e38Ted Kremenekpublic: 13930660a898545416f0fea2d717f16f75640001e38Ted Kremenek FixitReceiver(SmallVectorImpl<FixItHint> &MergedFixits) 14030660a898545416f0fea2d717f16f75640001e38Ted Kremenek : MergedFixits(MergedFixits) { } 14130660a898545416f0fea2d717f16f75640001e38Ted Kremenek virtual void insert(SourceLocation loc, StringRef text) { 14230660a898545416f0fea2d717f16f75640001e38Ted Kremenek MergedFixits.push_back(FixItHint::CreateInsertion(loc, text)); 14330660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 14430660a898545416f0fea2d717f16f75640001e38Ted Kremenek virtual void replace(CharSourceRange range, StringRef text) { 14530660a898545416f0fea2d717f16f75640001e38Ted Kremenek MergedFixits.push_back(FixItHint::CreateReplacement(range, text)); 14630660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 14730660a898545416f0fea2d717f16f75640001e38Ted Kremenek}; 14830660a898545416f0fea2d717f16f75640001e38Ted Kremenek 14930660a898545416f0fea2d717f16f75640001e38Ted Kremenek} 15030660a898545416f0fea2d717f16f75640001e38Ted Kremenek 15130660a898545416f0fea2d717f16f75640001e38Ted Kremenekstatic void mergeFixits(ArrayRef<FixItHint> FixItHints, 15230660a898545416f0fea2d717f16f75640001e38Ted Kremenek const SourceManager &SM, const LangOptions &LangOpts, 15330660a898545416f0fea2d717f16f75640001e38Ted Kremenek SmallVectorImpl<FixItHint> &MergedFixits) { 15430660a898545416f0fea2d717f16f75640001e38Ted Kremenek edit::Commit commit(SM, LangOpts); 15530660a898545416f0fea2d717f16f75640001e38Ted Kremenek for (ArrayRef<FixItHint>::const_iterator 15630660a898545416f0fea2d717f16f75640001e38Ted Kremenek I = FixItHints.begin(), E = FixItHints.end(); I != E; ++I) { 15730660a898545416f0fea2d717f16f75640001e38Ted Kremenek const FixItHint &Hint = *I; 15830660a898545416f0fea2d717f16f75640001e38Ted Kremenek if (Hint.CodeToInsert.empty()) { 15930660a898545416f0fea2d717f16f75640001e38Ted Kremenek if (Hint.InsertFromRange.isValid()) 16030660a898545416f0fea2d717f16f75640001e38Ted Kremenek commit.insertFromRange(Hint.RemoveRange.getBegin(), 16130660a898545416f0fea2d717f16f75640001e38Ted Kremenek Hint.InsertFromRange, /*afterToken=*/false, 16230660a898545416f0fea2d717f16f75640001e38Ted Kremenek Hint.BeforePreviousInsertions); 16330660a898545416f0fea2d717f16f75640001e38Ted Kremenek else 16430660a898545416f0fea2d717f16f75640001e38Ted Kremenek commit.remove(Hint.RemoveRange); 16530660a898545416f0fea2d717f16f75640001e38Ted Kremenek } else { 16630660a898545416f0fea2d717f16f75640001e38Ted Kremenek if (Hint.RemoveRange.isTokenRange() || 16730660a898545416f0fea2d717f16f75640001e38Ted Kremenek Hint.RemoveRange.getBegin() != Hint.RemoveRange.getEnd()) 16830660a898545416f0fea2d717f16f75640001e38Ted Kremenek commit.replace(Hint.RemoveRange, Hint.CodeToInsert); 16930660a898545416f0fea2d717f16f75640001e38Ted Kremenek else 17030660a898545416f0fea2d717f16f75640001e38Ted Kremenek commit.insert(Hint.RemoveRange.getBegin(), Hint.CodeToInsert, 17130660a898545416f0fea2d717f16f75640001e38Ted Kremenek /*afterToken=*/false, Hint.BeforePreviousInsertions); 17230660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 17330660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 17430660a898545416f0fea2d717f16f75640001e38Ted Kremenek 17530660a898545416f0fea2d717f16f75640001e38Ted Kremenek edit::EditedSource Editor(SM, LangOpts); 17630660a898545416f0fea2d717f16f75640001e38Ted Kremenek if (Editor.commit(commit)) { 17730660a898545416f0fea2d717f16f75640001e38Ted Kremenek FixitReceiver Rec(MergedFixits); 17830660a898545416f0fea2d717f16f75640001e38Ted Kremenek Editor.applyRewrites(Rec); 17930660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 18030660a898545416f0fea2d717f16f75640001e38Ted Kremenek} 1812898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 1822898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenekvoid DiagnosticRenderer::emitDiagnostic(SourceLocation Loc, 1832898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek DiagnosticsEngine::Level Level, 1842898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek StringRef Message, 1852898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek ArrayRef<CharSourceRange> Ranges, 1862898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek ArrayRef<FixItHint> FixItHints, 1878be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek DiagOrStoredDiag D) { 1882898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 1898be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek beginDiagnostic(D, Level); 1902898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 1912898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek PresumedLoc PLoc = getDiagnosticPresumedLoc(SM, Loc); 1922898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 1932898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // First, if this diagnostic is not in the main file, print out the 1942898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // "included from" lines. 1952898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek emitIncludeStack(PLoc.getIncludeLoc(), Level); 1962898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 1972898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Next, emit the actual diagnostic message. 1988be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek emitDiagnosticMessage(Loc, PLoc, Level, Message, Ranges, D); 1992898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 2002898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Only recurse if we have a valid location. 2012898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (Loc.isValid()) { 2022898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Get the ranges into a local array we can hack on. 2032898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek SmallVector<CharSourceRange, 20> MutableRanges(Ranges.begin(), 2042898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek Ranges.end()); 2052898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 20630660a898545416f0fea2d717f16f75640001e38Ted Kremenek llvm::SmallVector<FixItHint, 8> MergedFixits; 20730660a898545416f0fea2d717f16f75640001e38Ted Kremenek if (!FixItHints.empty()) { 20830660a898545416f0fea2d717f16f75640001e38Ted Kremenek mergeFixits(FixItHints, SM, LangOpts, MergedFixits); 20930660a898545416f0fea2d717f16f75640001e38Ted Kremenek FixItHints = MergedFixits; 21030660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 21130660a898545416f0fea2d717f16f75640001e38Ted Kremenek 2122898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek for (ArrayRef<FixItHint>::const_iterator I = FixItHints.begin(), 2132898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek E = FixItHints.end(); 2142898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek I != E; ++I) 2152898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (I->RemoveRange.isValid()) 2162898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek MutableRanges.push_back(I->RemoveRange); 2172898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 2182898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek unsigned MacroDepth = 0; 2192898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek emitMacroExpansionsAndCarets(Loc, Level, MutableRanges, FixItHints, 2202898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek MacroDepth); 2212898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek } 2222898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 2232898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek LastLoc = Loc; 2242898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek LastLevel = Level; 2252898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 2268be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek endDiagnostic(D, Level); 2278be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek} 2288be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek 2298be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek 2308be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenekvoid DiagnosticRenderer::emitStoredDiagnostic(StoredDiagnostic &Diag) { 2318be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek emitDiagnostic(Diag.getLocation(), Diag.getLevel(), Diag.getMessage(), 2328be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek Diag.getRanges(), Diag.getFixIts(), 2338be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek &Diag); 2342898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek} 2352898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 2362898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \brief Prints an include stack when appropriate for a particular 2372898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// diagnostic level and location. 2382898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// 2392898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// This routine handles all the logic of suppressing particular include 2402898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// stacks (such as those for notes) and duplicate include stacks when 2412898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// repeated warnings occur within the same file. It also handles the logic 2422898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// of customizing the formatting and display of the include stack. 2432898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// 2442898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param Level The diagnostic level of the message this stack pertains to. 2452898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param Loc The include location of the current file (not the diagnostic 2462898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// location). 2472898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenekvoid DiagnosticRenderer::emitIncludeStack(SourceLocation Loc, 2482898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek DiagnosticsEngine::Level Level) { 2492898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Skip redundant include stacks altogether. 2502898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (LastIncludeLoc == Loc) 2512898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return; 2522898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek LastIncludeLoc = Loc; 2532898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 2542898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (!DiagOpts.ShowNoteIncludeStack && Level == DiagnosticsEngine::Note) 2552898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return; 2562898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 2572898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek emitIncludeStackRecursively(Loc); 2582898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek} 2592898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 2602898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \brief Helper to recursivly walk up the include stack and print each layer 2612898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// on the way back down. 2622898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenekvoid DiagnosticRenderer::emitIncludeStackRecursively(SourceLocation Loc) { 2632898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (Loc.isInvalid()) 2642898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return; 2652898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 2662898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek PresumedLoc PLoc = SM.getPresumedLoc(Loc); 2672898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (PLoc.isInvalid()) 2682898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return; 2692898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 2702898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Emit the other include frames first. 2712898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek emitIncludeStackRecursively(PLoc.getIncludeLoc()); 2722898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 2732898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Emit the inclusion text/note. 2742898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek emitIncludeLocation(Loc, PLoc); 2752898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek} 2762898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 2772898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \brief Recursively emit notes for each macro expansion and caret 2782898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// diagnostics where appropriate. 2792898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// 2802898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// Walks up the macro expansion stack printing expansion notes, the code 2812898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// snippet, caret, underlines and FixItHint display as appropriate at each 2822898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// level. 2832898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// 2842898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param Loc The location for this caret. 2852898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param Level The diagnostic level currently being emitted. 2862898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param Ranges The underlined ranges for this code snippet. 2872898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param Hints The FixIt hints active for this diagnostic. 2882898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param MacroSkipEnd The depth to stop skipping macro expansions. 2892898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \param OnMacroInst The current depth of the macro expansion stack. 2902898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenekvoid DiagnosticRenderer::emitMacroExpansionsAndCarets( 2912898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek SourceLocation Loc, 2922898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek DiagnosticsEngine::Level Level, 2932898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek SmallVectorImpl<CharSourceRange>& Ranges, 2942898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek ArrayRef<FixItHint> Hints, 2952898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek unsigned &MacroDepth, 2962898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek unsigned OnMacroInst) 2972898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek{ 2982898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek assert(!Loc.isInvalid() && "must have a valid source location here"); 2992898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 3002898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // If this is a file source location, directly emit the source snippet and 3012898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // caret line. Also record the macro depth reached. 3022898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (Loc.isFileID()) { 3032898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek assert(MacroDepth == 0 && "We shouldn't hit a leaf node twice!"); 3042898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek MacroDepth = OnMacroInst; 3052898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek emitCodeContext(Loc, Level, Ranges, Hints); 3062898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return; 3072898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek } 3082898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Otherwise recurse through each macro expansion layer. 3092898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 3102898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // When processing macros, skip over the expansions leading up to 3112898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // a macro argument, and trace the argument's expansion stack instead. 3122898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek Loc = skipToMacroArgExpansion(SM, Loc); 3132898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 3142898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek SourceLocation OneLevelUp = getImmediateMacroCallerLoc(SM, Loc); 3152898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 3162898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // FIXME: Map ranges? 3172898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek emitMacroExpansionsAndCarets(OneLevelUp, Level, Ranges, Hints, MacroDepth, 3182898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek OnMacroInst + 1); 3192898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 3202898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Save the original location so we can find the spelling of the macro call. 3212898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek SourceLocation MacroLoc = Loc; 3222898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 3232898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Map the location. 3242898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek Loc = getImmediateMacroCalleeLoc(SM, Loc); 3252898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 3262898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek unsigned MacroSkipStart = 0, MacroSkipEnd = 0; 327cf2362b76b624b90e2649497ab8019bcce959bf4Ted Kremenek if (MacroDepth > DiagOpts.MacroBacktraceLimit && 328cf2362b76b624b90e2649497ab8019bcce959bf4Ted Kremenek DiagOpts.MacroBacktraceLimit != 0) { 3292898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek MacroSkipStart = DiagOpts.MacroBacktraceLimit / 2 + 3302898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek DiagOpts.MacroBacktraceLimit % 2; 3312898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek MacroSkipEnd = MacroDepth - DiagOpts.MacroBacktraceLimit / 2; 3322898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek } 3332898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 3342898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Whether to suppress printing this macro expansion. 3352898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek bool Suppressed = (OnMacroInst >= MacroSkipStart && 3362898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek OnMacroInst < MacroSkipEnd); 3372898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 3382898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Map the ranges. 3392898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek for (SmallVectorImpl<CharSourceRange>::iterator I = Ranges.begin(), 3402898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek E = Ranges.end(); 3412898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek I != E; ++I) { 3422898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek SourceLocation Start = I->getBegin(), End = I->getEnd(); 3432898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (Start.isMacroID()) 3442898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek I->setBegin(getImmediateMacroCalleeLoc(SM, Start)); 3452898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (End.isMacroID()) 3462898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek I->setEnd(getImmediateMacroCalleeLoc(SM, End)); 3472898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek } 3482898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 3492898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (Suppressed) { 3502898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek // Tell the user that we've skipped contexts. 3512898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek if (OnMacroInst == MacroSkipStart) { 352f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<200> MessageStorage; 3532898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek llvm::raw_svector_ostream Message(MessageStorage); 3542898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek Message << "(skipping " << (MacroSkipEnd - MacroSkipStart) 3552898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek << " expansions in backtrace; use -fmacro-backtrace-limit=0 to " 3562898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek "see all)"; 3572898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek emitBasicNote(Message.str()); 3582898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek } 3592898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek return; 3602898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek } 3612898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 362f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<100> MessageStorage; 3632898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek llvm::raw_svector_ostream Message(MessageStorage); 3642898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek Message << "expanded from macro '" 3657f6cf9764b33381e03fcf7c44f7985a333212b06Argyrios Kyrtzidis << getImmediateMacroName(MacroLoc, SM, LangOpts) << "'"; 3662898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek emitDiagnostic(SM.getSpellingLoc(Loc), DiagnosticsEngine::Note, 3672898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek Message.str(), 3682898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek Ranges, ArrayRef<FixItHint>()); 3692898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek} 3702898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 3718be51eab5ad34515d2a40dcdc8558128ca1800adTed KremenekDiagnosticNoteRenderer::~DiagnosticNoteRenderer() {} 3728be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek 3738be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenekvoid DiagnosticNoteRenderer::emitIncludeLocation(SourceLocation Loc, 3748be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek PresumedLoc PLoc) { 3758be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek // Generate a note indicating the include location. 3768be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek SmallString<200> MessageStorage; 3778be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek llvm::raw_svector_ostream Message(MessageStorage); 3788be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek Message << "in file included from " << PLoc.getFilename() << ':' 3798be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek << PLoc.getLine() << ":"; 3808be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek emitNote(Loc, Message.str()); 3818be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek} 3828be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek 3838be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenekvoid DiagnosticNoteRenderer::emitBasicNote(StringRef Message) { 3848be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek emitNote(SourceLocation(), Message); 3858be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek} 3868be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek 387