1234287Sdim//===--- DiagnosticRenderer.cpp - Diagnostic Pretty-Printing --------------===// 2234287Sdim// 3234287Sdim// The LLVM Compiler Infrastructure 4234287Sdim// 5234287Sdim// This file is distributed under the University of Illinois Open Source 6234287Sdim// License. See LICENSE.TXT for details. 7234287Sdim// 8234287Sdim//===----------------------------------------------------------------------===// 9234287Sdim 10234287Sdim#include "clang/Frontend/DiagnosticRenderer.h" 11243830Sdim#include "clang/Basic/DiagnosticOptions.h" 12234287Sdim#include "clang/Basic/FileManager.h" 13234287Sdim#include "clang/Basic/SourceManager.h" 14249423Sdim#include "clang/Edit/Commit.h" 15234287Sdim#include "clang/Edit/EditedSource.h" 16234287Sdim#include "clang/Edit/EditsReceiver.h" 17249423Sdim#include "clang/Lex/Lexer.h" 18249423Sdim#include "llvm/ADT/SmallSet.h" 19249423Sdim#include "llvm/ADT/SmallString.h" 20249423Sdim#include "llvm/Support/ErrorHandling.h" 21234287Sdim#include "llvm/Support/MemoryBuffer.h" 22234287Sdim#include "llvm/Support/raw_ostream.h" 23234287Sdim#include <algorithm> 24234287Sdimusing namespace clang; 25234287Sdim 26234287Sdim/// \brief Retrieve the name of the immediate macro expansion. 27234287Sdim/// 28234287Sdim/// This routine starts from a source location, and finds the name of the macro 29234287Sdim/// responsible for its immediate expansion. It looks through any intervening 30234287Sdim/// macro argument expansions to compute this. It returns a StringRef which 31234287Sdim/// refers to the SourceManager-owned buffer of the source where that macro 32234287Sdim/// name is spelled. Thus, the result shouldn't out-live that SourceManager. 33234287Sdim/// 34234287Sdim/// This differs from Lexer::getImmediateMacroName in that any macro argument 35234287Sdim/// location will result in the topmost function macro that accepted it. 36234287Sdim/// e.g. 37234287Sdim/// \code 38234287Sdim/// MAC1( MAC2(foo) ) 39234287Sdim/// \endcode 40234287Sdim/// for location of 'foo' token, this function will return "MAC1" while 41234287Sdim/// Lexer::getImmediateMacroName will return "MAC2". 42234287Sdimstatic StringRef getImmediateMacroName(SourceLocation Loc, 43234287Sdim const SourceManager &SM, 44234287Sdim const LangOptions &LangOpts) { 45234287Sdim assert(Loc.isMacroID() && "Only reasonble to call this on macros"); 46234287Sdim // Walk past macro argument expanions. 47234287Sdim while (SM.isMacroArgExpansion(Loc)) 48234287Sdim Loc = SM.getImmediateExpansionRange(Loc).first; 49234287Sdim 50249423Sdim // If the macro's spelling has no FileID, then it's actually a token paste 51249423Sdim // or stringization (or similar) and not a macro at all. 52249423Sdim if (!SM.getFileEntryForID(SM.getFileID(SM.getSpellingLoc(Loc)))) 53249423Sdim return StringRef(); 54249423Sdim 55234287Sdim // Find the spelling location of the start of the non-argument expansion 56234287Sdim // range. This is where the macro name was spelled in order to begin 57234287Sdim // expanding this macro. 58234287Sdim Loc = SM.getSpellingLoc(SM.getImmediateExpansionRange(Loc).first); 59234287Sdim 60234287Sdim // Dig out the buffer where the macro name was spelled and the extents of the 61234287Sdim // name so that we can render it into the expansion note. 62234287Sdim std::pair<FileID, unsigned> ExpansionInfo = SM.getDecomposedLoc(Loc); 63234287Sdim unsigned MacroTokenLength = Lexer::MeasureTokenLength(Loc, SM, LangOpts); 64234287Sdim StringRef ExpansionBuffer = SM.getBufferData(ExpansionInfo.first); 65234287Sdim return ExpansionBuffer.substr(ExpansionInfo.second, MacroTokenLength); 66234287Sdim} 67234287Sdim 68239462SdimDiagnosticRenderer::DiagnosticRenderer(const LangOptions &LangOpts, 69243830Sdim DiagnosticOptions *DiagOpts) 70243830Sdim : LangOpts(LangOpts), DiagOpts(DiagOpts), LastLevel() {} 71234287Sdim 72234287SdimDiagnosticRenderer::~DiagnosticRenderer() {} 73234287Sdim 74234287Sdimnamespace { 75234287Sdim 76234287Sdimclass FixitReceiver : public edit::EditsReceiver { 77234287Sdim SmallVectorImpl<FixItHint> &MergedFixits; 78234287Sdim 79234287Sdimpublic: 80234287Sdim FixitReceiver(SmallVectorImpl<FixItHint> &MergedFixits) 81234287Sdim : MergedFixits(MergedFixits) { } 82234287Sdim virtual void insert(SourceLocation loc, StringRef text) { 83234287Sdim MergedFixits.push_back(FixItHint::CreateInsertion(loc, text)); 84234287Sdim } 85234287Sdim virtual void replace(CharSourceRange range, StringRef text) { 86234287Sdim MergedFixits.push_back(FixItHint::CreateReplacement(range, text)); 87234287Sdim } 88234287Sdim}; 89234287Sdim 90234287Sdim} 91234287Sdim 92234287Sdimstatic void mergeFixits(ArrayRef<FixItHint> FixItHints, 93234287Sdim const SourceManager &SM, const LangOptions &LangOpts, 94234287Sdim SmallVectorImpl<FixItHint> &MergedFixits) { 95234287Sdim edit::Commit commit(SM, LangOpts); 96234287Sdim for (ArrayRef<FixItHint>::const_iterator 97234287Sdim I = FixItHints.begin(), E = FixItHints.end(); I != E; ++I) { 98234287Sdim const FixItHint &Hint = *I; 99234287Sdim if (Hint.CodeToInsert.empty()) { 100234287Sdim if (Hint.InsertFromRange.isValid()) 101234287Sdim commit.insertFromRange(Hint.RemoveRange.getBegin(), 102234287Sdim Hint.InsertFromRange, /*afterToken=*/false, 103234287Sdim Hint.BeforePreviousInsertions); 104234287Sdim else 105234287Sdim commit.remove(Hint.RemoveRange); 106234287Sdim } else { 107234287Sdim if (Hint.RemoveRange.isTokenRange() || 108234287Sdim Hint.RemoveRange.getBegin() != Hint.RemoveRange.getEnd()) 109234287Sdim commit.replace(Hint.RemoveRange, Hint.CodeToInsert); 110234287Sdim else 111234287Sdim commit.insert(Hint.RemoveRange.getBegin(), Hint.CodeToInsert, 112234287Sdim /*afterToken=*/false, Hint.BeforePreviousInsertions); 113234287Sdim } 114234287Sdim } 115234287Sdim 116234287Sdim edit::EditedSource Editor(SM, LangOpts); 117234287Sdim if (Editor.commit(commit)) { 118234287Sdim FixitReceiver Rec(MergedFixits); 119234287Sdim Editor.applyRewrites(Rec); 120234287Sdim } 121234287Sdim} 122234287Sdim 123234287Sdimvoid DiagnosticRenderer::emitDiagnostic(SourceLocation Loc, 124234287Sdim DiagnosticsEngine::Level Level, 125234287Sdim StringRef Message, 126234287Sdim ArrayRef<CharSourceRange> Ranges, 127234287Sdim ArrayRef<FixItHint> FixItHints, 128239462Sdim const SourceManager *SM, 129234287Sdim DiagOrStoredDiag D) { 130239462Sdim assert(SM || Loc.isInvalid()); 131249423Sdim 132234287Sdim beginDiagnostic(D, Level); 133249423Sdim 134249423Sdim if (!Loc.isValid()) 135249423Sdim // If we have no source location, just emit the diagnostic message. 136249423Sdim emitDiagnosticMessage(Loc, PresumedLoc(), Level, Message, Ranges, SM, D); 137249423Sdim else { 138234287Sdim // Get the ranges into a local array we can hack on. 139234287Sdim SmallVector<CharSourceRange, 20> MutableRanges(Ranges.begin(), 140234287Sdim Ranges.end()); 141249423Sdim 142249423Sdim SmallVector<FixItHint, 8> MergedFixits; 143234287Sdim if (!FixItHints.empty()) { 144239462Sdim mergeFixits(FixItHints, *SM, LangOpts, MergedFixits); 145234287Sdim FixItHints = MergedFixits; 146234287Sdim } 147234287Sdim 148234287Sdim for (ArrayRef<FixItHint>::const_iterator I = FixItHints.begin(), 149234287Sdim E = FixItHints.end(); 150234287Sdim I != E; ++I) 151234287Sdim if (I->RemoveRange.isValid()) 152234287Sdim MutableRanges.push_back(I->RemoveRange); 153249423Sdim 154249423Sdim SourceLocation UnexpandedLoc = Loc; 155249423Sdim 156249423Sdim // Find the ultimate expansion location for the diagnostic. 157249423Sdim Loc = SM->getFileLoc(Loc); 158249423Sdim 159249423Sdim PresumedLoc PLoc = SM->getPresumedLoc(Loc, DiagOpts->ShowPresumedLoc); 160249423Sdim 161249423Sdim // First, if this diagnostic is not in the main file, print out the 162249423Sdim // "included from" lines. 163249423Sdim emitIncludeStack(Loc, PLoc, Level, *SM); 164249423Sdim 165249423Sdim // Next, emit the actual diagnostic message and caret. 166249423Sdim emitDiagnosticMessage(Loc, PLoc, Level, Message, Ranges, SM, D); 167249423Sdim emitCaret(Loc, Level, MutableRanges, FixItHints, *SM); 168249423Sdim 169249423Sdim // If this location is within a macro, walk from UnexpandedLoc up to Loc 170249423Sdim // and produce a macro backtrace. 171249423Sdim if (UnexpandedLoc.isValid() && UnexpandedLoc.isMacroID()) { 172249423Sdim unsigned MacroDepth = 0; 173249423Sdim emitMacroExpansions(UnexpandedLoc, Level, MutableRanges, FixItHints, *SM, 174249423Sdim MacroDepth); 175249423Sdim } 176234287Sdim } 177249423Sdim 178234287Sdim LastLoc = Loc; 179234287Sdim LastLevel = Level; 180249423Sdim 181234287Sdim endDiagnostic(D, Level); 182234287Sdim} 183234287Sdim 184234287Sdim 185234287Sdimvoid DiagnosticRenderer::emitStoredDiagnostic(StoredDiagnostic &Diag) { 186234287Sdim emitDiagnostic(Diag.getLocation(), Diag.getLevel(), Diag.getMessage(), 187234287Sdim Diag.getRanges(), Diag.getFixIts(), 188239462Sdim Diag.getLocation().isValid() ? &Diag.getLocation().getManager() 189239462Sdim : 0, 190234287Sdim &Diag); 191234287Sdim} 192234287Sdim 193234287Sdim/// \brief Prints an include stack when appropriate for a particular 194234287Sdim/// diagnostic level and location. 195234287Sdim/// 196234287Sdim/// This routine handles all the logic of suppressing particular include 197234287Sdim/// stacks (such as those for notes) and duplicate include stacks when 198234287Sdim/// repeated warnings occur within the same file. It also handles the logic 199234287Sdim/// of customizing the formatting and display of the include stack. 200234287Sdim/// 201249423Sdim/// \param Loc The diagnostic location. 202249423Sdim/// \param PLoc The presumed location of the diagnostic location. 203234287Sdim/// \param Level The diagnostic level of the message this stack pertains to. 204234287Sdimvoid DiagnosticRenderer::emitIncludeStack(SourceLocation Loc, 205249423Sdim PresumedLoc PLoc, 206239462Sdim DiagnosticsEngine::Level Level, 207239462Sdim const SourceManager &SM) { 208249423Sdim SourceLocation IncludeLoc = PLoc.getIncludeLoc(); 209249423Sdim 210234287Sdim // Skip redundant include stacks altogether. 211249423Sdim if (LastIncludeLoc == IncludeLoc) 212234287Sdim return; 213234287Sdim 214249423Sdim LastIncludeLoc = IncludeLoc; 215249423Sdim 216243830Sdim if (!DiagOpts->ShowNoteIncludeStack && Level == DiagnosticsEngine::Note) 217234287Sdim return; 218249423Sdim 219249423Sdim if (IncludeLoc.isValid()) 220249423Sdim emitIncludeStackRecursively(IncludeLoc, SM); 221249423Sdim else { 222249423Sdim emitModuleBuildStack(SM); 223249423Sdim emitImportStack(Loc, SM); 224249423Sdim } 225234287Sdim} 226234287Sdim 227234287Sdim/// \brief Helper to recursivly walk up the include stack and print each layer 228234287Sdim/// on the way back down. 229239462Sdimvoid DiagnosticRenderer::emitIncludeStackRecursively(SourceLocation Loc, 230239462Sdim const SourceManager &SM) { 231249423Sdim if (Loc.isInvalid()) { 232249423Sdim emitModuleBuildStack(SM); 233234287Sdim return; 234249423Sdim } 235234287Sdim 236249423Sdim PresumedLoc PLoc = SM.getPresumedLoc(Loc, DiagOpts->ShowPresumedLoc); 237234287Sdim if (PLoc.isInvalid()) 238234287Sdim return; 239249423Sdim 240249423Sdim // If this source location was imported from a module, print the module 241249423Sdim // import stack rather than the 242249423Sdim // FIXME: We want submodule granularity here. 243249423Sdim std::pair<SourceLocation, StringRef> Imported = SM.getModuleImportLoc(Loc); 244249423Sdim if (Imported.first.isValid()) { 245249423Sdim // This location was imported by a module. Emit the module import stack. 246249423Sdim emitImportStackRecursively(Imported.first, Imported.second, SM); 247249423Sdim return; 248249423Sdim } 249249423Sdim 250234287Sdim // Emit the other include frames first. 251239462Sdim emitIncludeStackRecursively(PLoc.getIncludeLoc(), SM); 252234287Sdim 253234287Sdim // Emit the inclusion text/note. 254239462Sdim emitIncludeLocation(Loc, PLoc, SM); 255234287Sdim} 256234287Sdim 257249423Sdim/// \brief Emit the module import stack associated with the current location. 258249423Sdimvoid DiagnosticRenderer::emitImportStack(SourceLocation Loc, 259249423Sdim const SourceManager &SM) { 260249423Sdim if (Loc.isInvalid()) { 261249423Sdim emitModuleBuildStack(SM); 262249423Sdim return; 263249423Sdim } 264249423Sdim 265249423Sdim std::pair<SourceLocation, StringRef> NextImportLoc 266249423Sdim = SM.getModuleImportLoc(Loc); 267249423Sdim emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second, SM); 268249423Sdim} 269249423Sdim 270249423Sdim/// \brief Helper to recursivly walk up the import stack and print each layer 271249423Sdim/// on the way back down. 272249423Sdimvoid DiagnosticRenderer::emitImportStackRecursively(SourceLocation Loc, 273249423Sdim StringRef ModuleName, 274249423Sdim const SourceManager &SM) { 275249423Sdim if (Loc.isInvalid()) { 276249423Sdim return; 277249423Sdim } 278249423Sdim 279249423Sdim PresumedLoc PLoc = SM.getPresumedLoc(Loc, DiagOpts->ShowPresumedLoc); 280249423Sdim if (PLoc.isInvalid()) 281249423Sdim return; 282249423Sdim 283249423Sdim // Emit the other import frames first. 284249423Sdim std::pair<SourceLocation, StringRef> NextImportLoc 285249423Sdim = SM.getModuleImportLoc(Loc); 286249423Sdim emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second, SM); 287249423Sdim 288249423Sdim // Emit the inclusion text/note. 289249423Sdim emitImportLocation(Loc, PLoc, ModuleName, SM); 290249423Sdim} 291249423Sdim 292249423Sdim/// \brief Emit the module build stack, for cases where a module is (re-)built 293249423Sdim/// on demand. 294249423Sdimvoid DiagnosticRenderer::emitModuleBuildStack(const SourceManager &SM) { 295249423Sdim ModuleBuildStack Stack = SM.getModuleBuildStack(); 296249423Sdim for (unsigned I = 0, N = Stack.size(); I != N; ++I) { 297249423Sdim const SourceManager &CurSM = Stack[I].second.getManager(); 298249423Sdim SourceLocation CurLoc = Stack[I].second; 299249423Sdim emitBuildingModuleLocation(CurLoc, 300249423Sdim CurSM.getPresumedLoc(CurLoc, 301249423Sdim DiagOpts->ShowPresumedLoc), 302249423Sdim Stack[I].first, 303249423Sdim CurSM); 304249423Sdim } 305249423Sdim} 306249423Sdim 307243830Sdim// Helper function to fix up source ranges. It takes in an array of ranges, 308243830Sdim// and outputs an array of ranges where we want to draw the range highlighting 309243830Sdim// around the location specified by CaretLoc. 310243830Sdim// 311243830Sdim// To find locations which correspond to the caret, we crawl the macro caller 312243830Sdim// chain for the beginning and end of each range. If the caret location 313243830Sdim// is in a macro expansion, we search each chain for a location 314243830Sdim// in the same expansion as the caret; otherwise, we crawl to the top of 315243830Sdim// each chain. Two locations are part of the same macro expansion 316243830Sdim// iff the FileID is the same. 317243830Sdimstatic void mapDiagnosticRanges( 318243830Sdim SourceLocation CaretLoc, 319249423Sdim ArrayRef<CharSourceRange> Ranges, 320249423Sdim SmallVectorImpl<CharSourceRange> &SpellingRanges, 321243830Sdim const SourceManager *SM) { 322243830Sdim FileID CaretLocFileID = SM->getFileID(CaretLoc); 323243830Sdim 324249423Sdim for (ArrayRef<CharSourceRange>::const_iterator I = Ranges.begin(), 325243830Sdim E = Ranges.end(); 326243830Sdim I != E; ++I) { 327243830Sdim SourceLocation Begin = I->getBegin(), End = I->getEnd(); 328243830Sdim bool IsTokenRange = I->isTokenRange(); 329243830Sdim 330249423Sdim FileID BeginFileID = SM->getFileID(Begin); 331249423Sdim FileID EndFileID = SM->getFileID(End); 332243830Sdim 333249423Sdim // Find the common parent for the beginning and end of the range. 334249423Sdim 335249423Sdim // First, crawl the expansion chain for the beginning of the range. 336249423Sdim llvm::SmallDenseMap<FileID, SourceLocation> BeginLocsMap; 337249423Sdim while (Begin.isMacroID() && BeginFileID != EndFileID) { 338249423Sdim BeginLocsMap[BeginFileID] = Begin; 339249423Sdim Begin = SM->getImmediateExpansionRange(Begin).first; 340249423Sdim BeginFileID = SM->getFileID(Begin); 341249423Sdim } 342249423Sdim 343249423Sdim // Then, crawl the expansion chain for the end of the range. 344249423Sdim if (BeginFileID != EndFileID) { 345249423Sdim while (End.isMacroID() && !BeginLocsMap.count(EndFileID)) { 346249423Sdim End = SM->getImmediateExpansionRange(End).second; 347249423Sdim EndFileID = SM->getFileID(End); 348249423Sdim } 349249423Sdim if (End.isMacroID()) { 350249423Sdim Begin = BeginLocsMap[EndFileID]; 351249423Sdim BeginFileID = EndFileID; 352249423Sdim } 353249423Sdim } 354249423Sdim 355249423Sdim while (Begin.isMacroID() && BeginFileID != CaretLocFileID) { 356249423Sdim if (SM->isMacroArgExpansion(Begin)) { 357249423Sdim Begin = SM->getImmediateSpellingLoc(Begin); 358243830Sdim End = SM->getImmediateSpellingLoc(End); 359243830Sdim } else { 360249423Sdim Begin = SM->getImmediateExpansionRange(Begin).first; 361243830Sdim End = SM->getImmediateExpansionRange(End).second; 362243830Sdim } 363249423Sdim BeginFileID = SM->getFileID(Begin); 364249423Sdim if (BeginFileID != SM->getFileID(End)) { 365249423Sdim // FIXME: Ugly hack to stop a crash; this code is making bad 366249423Sdim // assumptions and it's too complicated for me to reason 367249423Sdim // about. 368249423Sdim Begin = End = SourceLocation(); 369249423Sdim break; 370249423Sdim } 371243830Sdim } 372243830Sdim 373243830Sdim // Return the spelling location of the beginning and end of the range. 374243830Sdim Begin = SM->getSpellingLoc(Begin); 375243830Sdim End = SM->getSpellingLoc(End); 376243830Sdim SpellingRanges.push_back(CharSourceRange(SourceRange(Begin, End), 377243830Sdim IsTokenRange)); 378243830Sdim } 379243830Sdim} 380243830Sdim 381249423Sdimvoid DiagnosticRenderer::emitCaret(SourceLocation Loc, 382249423Sdim DiagnosticsEngine::Level Level, 383249423Sdim ArrayRef<CharSourceRange> Ranges, 384249423Sdim ArrayRef<FixItHint> Hints, 385249423Sdim const SourceManager &SM) { 386249423Sdim SmallVector<CharSourceRange, 4> SpellingRanges; 387249423Sdim mapDiagnosticRanges(Loc, Ranges, SpellingRanges, &SM); 388249423Sdim emitCodeContext(Loc, Level, SpellingRanges, Hints, SM); 389249423Sdim} 390249423Sdim 391234287Sdim/// \brief Recursively emit notes for each macro expansion and caret 392234287Sdim/// diagnostics where appropriate. 393234287Sdim/// 394234287Sdim/// Walks up the macro expansion stack printing expansion notes, the code 395234287Sdim/// snippet, caret, underlines and FixItHint display as appropriate at each 396234287Sdim/// level. 397234287Sdim/// 398234287Sdim/// \param Loc The location for this caret. 399234287Sdim/// \param Level The diagnostic level currently being emitted. 400234287Sdim/// \param Ranges The underlined ranges for this code snippet. 401234287Sdim/// \param Hints The FixIt hints active for this diagnostic. 402234287Sdim/// \param OnMacroInst The current depth of the macro expansion stack. 403249423Sdimvoid DiagnosticRenderer::emitMacroExpansions(SourceLocation Loc, 404249423Sdim DiagnosticsEngine::Level Level, 405249423Sdim ArrayRef<CharSourceRange> Ranges, 406249423Sdim ArrayRef<FixItHint> Hints, 407249423Sdim const SourceManager &SM, 408249423Sdim unsigned &MacroDepth, 409249423Sdim unsigned OnMacroInst) { 410234287Sdim assert(!Loc.isInvalid() && "must have a valid source location here"); 411243830Sdim 412249423Sdim // Walk up to the caller of this macro, and produce a backtrace down to there. 413239462Sdim SourceLocation OneLevelUp = SM.getImmediateMacroCallerLoc(Loc); 414249423Sdim if (OneLevelUp.isMacroID()) 415249423Sdim emitMacroExpansions(OneLevelUp, Level, Ranges, Hints, SM, 416249423Sdim MacroDepth, OnMacroInst + 1); 417249423Sdim else 418249423Sdim MacroDepth = OnMacroInst + 1; 419243830Sdim 420234287Sdim unsigned MacroSkipStart = 0, MacroSkipEnd = 0; 421243830Sdim if (MacroDepth > DiagOpts->MacroBacktraceLimit && 422243830Sdim DiagOpts->MacroBacktraceLimit != 0) { 423243830Sdim MacroSkipStart = DiagOpts->MacroBacktraceLimit / 2 + 424243830Sdim DiagOpts->MacroBacktraceLimit % 2; 425243830Sdim MacroSkipEnd = MacroDepth - DiagOpts->MacroBacktraceLimit / 2; 426234287Sdim } 427249423Sdim 428234287Sdim // Whether to suppress printing this macro expansion. 429234287Sdim bool Suppressed = (OnMacroInst >= MacroSkipStart && 430234287Sdim OnMacroInst < MacroSkipEnd); 431249423Sdim 432234287Sdim if (Suppressed) { 433234287Sdim // Tell the user that we've skipped contexts. 434234287Sdim if (OnMacroInst == MacroSkipStart) { 435234287Sdim SmallString<200> MessageStorage; 436234287Sdim llvm::raw_svector_ostream Message(MessageStorage); 437234287Sdim Message << "(skipping " << (MacroSkipEnd - MacroSkipStart) 438234287Sdim << " expansions in backtrace; use -fmacro-backtrace-limit=0 to " 439234287Sdim "see all)"; 440234287Sdim emitBasicNote(Message.str()); 441234287Sdim } 442234287Sdim return; 443234287Sdim } 444243830Sdim 445249423Sdim // Find the spelling location for the macro definition. We must use the 446249423Sdim // spelling location here to avoid emitting a macro bactrace for the note. 447249423Sdim SourceLocation SpellingLoc = Loc; 448249423Sdim // If this is the expansion of a macro argument, point the caret at the 449249423Sdim // use of the argument in the definition of the macro, not the expansion. 450249423Sdim if (SM.isMacroArgExpansion(Loc)) 451249423Sdim SpellingLoc = SM.getImmediateExpansionRange(Loc).first; 452249423Sdim SpellingLoc = SM.getSpellingLoc(SpellingLoc); 453249423Sdim 454249423Sdim // Map the ranges into the FileID of the diagnostic location. 455243830Sdim SmallVector<CharSourceRange, 4> SpellingRanges; 456249423Sdim mapDiagnosticRanges(Loc, Ranges, SpellingRanges, &SM); 457243830Sdim 458234287Sdim SmallString<100> MessageStorage; 459234287Sdim llvm::raw_svector_ostream Message(MessageStorage); 460249423Sdim StringRef MacroName = getImmediateMacroName(Loc, SM, LangOpts); 461249423Sdim if (MacroName.empty()) 462249423Sdim Message << "expanded from here"; 463249423Sdim else 464249423Sdim Message << "expanded from macro '" << MacroName << "'"; 465251662Sdim emitDiagnostic(SpellingLoc, DiagnosticsEngine::Note, Message.str(), 466251662Sdim SpellingRanges, None, &SM); 467234287Sdim} 468234287Sdim 469234287SdimDiagnosticNoteRenderer::~DiagnosticNoteRenderer() {} 470234287Sdim 471234287Sdimvoid DiagnosticNoteRenderer::emitIncludeLocation(SourceLocation Loc, 472239462Sdim PresumedLoc PLoc, 473239462Sdim const SourceManager &SM) { 474234287Sdim // Generate a note indicating the include location. 475234287Sdim SmallString<200> MessageStorage; 476234287Sdim llvm::raw_svector_ostream Message(MessageStorage); 477234287Sdim Message << "in file included from " << PLoc.getFilename() << ':' 478234287Sdim << PLoc.getLine() << ":"; 479239462Sdim emitNote(Loc, Message.str(), &SM); 480234287Sdim} 481234287Sdim 482249423Sdimvoid DiagnosticNoteRenderer::emitImportLocation(SourceLocation Loc, 483249423Sdim PresumedLoc PLoc, 484249423Sdim StringRef ModuleName, 485249423Sdim const SourceManager &SM) { 486249423Sdim // Generate a note indicating the include location. 487249423Sdim SmallString<200> MessageStorage; 488249423Sdim llvm::raw_svector_ostream Message(MessageStorage); 489249423Sdim Message << "in module '" << ModuleName << "' imported from " 490249423Sdim << PLoc.getFilename() << ':' << PLoc.getLine() << ":"; 491249423Sdim emitNote(Loc, Message.str(), &SM); 492249423Sdim} 493249423Sdim 494249423Sdimvoid 495249423SdimDiagnosticNoteRenderer::emitBuildingModuleLocation(SourceLocation Loc, 496249423Sdim PresumedLoc PLoc, 497249423Sdim StringRef ModuleName, 498249423Sdim const SourceManager &SM) { 499249423Sdim // Generate a note indicating the include location. 500249423Sdim SmallString<200> MessageStorage; 501249423Sdim llvm::raw_svector_ostream Message(MessageStorage); 502249423Sdim Message << "while building module '" << ModuleName << "' imported from " 503249423Sdim << PLoc.getFilename() << ':' << PLoc.getLine() << ":"; 504249423Sdim emitNote(Loc, Message.str(), &SM); 505249423Sdim} 506249423Sdim 507249423Sdim 508234287Sdimvoid DiagnosticNoteRenderer::emitBasicNote(StringRef Message) { 509239462Sdim emitNote(SourceLocation(), Message, 0); 510234287Sdim} 511