clang API Documentation
00001 //===--- DiagnosticRenderer.cpp - Diagnostic Pretty-Printing --------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "clang/Frontend/DiagnosticRenderer.h" 00011 #include "clang/Basic/FileManager.h" 00012 #include "clang/Basic/SourceManager.h" 00013 #include "clang/Frontend/DiagnosticOptions.h" 00014 #include "clang/Lex/Lexer.h" 00015 #include "clang/Edit/EditedSource.h" 00016 #include "clang/Edit/Commit.h" 00017 #include "clang/Edit/EditsReceiver.h" 00018 #include "llvm/Support/MemoryBuffer.h" 00019 #include "llvm/Support/raw_ostream.h" 00020 #include "llvm/Support/ErrorHandling.h" 00021 #include "llvm/ADT/SmallString.h" 00022 #include <algorithm> 00023 using namespace clang; 00024 00025 /// Look through spelling locations for a macro argument expansion, and 00026 /// if found skip to it so that we can trace the argument rather than the macros 00027 /// in which that argument is used. If no macro argument expansion is found, 00028 /// don't skip anything and return the starting location. 00029 static SourceLocation skipToMacroArgExpansion(const SourceManager &SM, 00030 SourceLocation StartLoc) { 00031 for (SourceLocation L = StartLoc; L.isMacroID(); 00032 L = SM.getImmediateSpellingLoc(L)) { 00033 if (SM.isMacroArgExpansion(L)) 00034 return L; 00035 } 00036 00037 // Otherwise just return initial location, there's nothing to skip. 00038 return StartLoc; 00039 } 00040 00041 /// Gets the location of the immediate macro caller, one level up the stack 00042 /// toward the initial macro typed into the source. 00043 static SourceLocation getImmediateMacroCallerLoc(const SourceManager &SM, 00044 SourceLocation Loc) { 00045 if (!Loc.isMacroID()) return Loc; 00046 00047 // When we have the location of (part of) an expanded parameter, its spelling 00048 // location points to the argument as typed into the macro call, and 00049 // therefore is used to locate the macro caller. 00050 if (SM.isMacroArgExpansion(Loc)) 00051 return SM.getImmediateSpellingLoc(Loc); 00052 00053 // Otherwise, the caller of the macro is located where this macro is 00054 // expanded (while the spelling is part of the macro definition). 00055 return SM.getImmediateExpansionRange(Loc).first; 00056 } 00057 00058 /// Gets the location of the immediate macro callee, one level down the stack 00059 /// toward the leaf macro. 00060 static SourceLocation getImmediateMacroCalleeLoc(const SourceManager &SM, 00061 SourceLocation Loc) { 00062 if (!Loc.isMacroID()) return Loc; 00063 00064 // When we have the location of (part of) an expanded parameter, its 00065 // expansion location points to the unexpanded paramater reference within 00066 // the macro definition (or callee). 00067 if (SM.isMacroArgExpansion(Loc)) 00068 return SM.getImmediateExpansionRange(Loc).first; 00069 00070 // Otherwise, the callee of the macro is located where this location was 00071 // spelled inside the macro definition. 00072 return SM.getImmediateSpellingLoc(Loc); 00073 } 00074 00075 /// \brief Retrieve the name of the immediate macro expansion. 00076 /// 00077 /// This routine starts from a source location, and finds the name of the macro 00078 /// responsible for its immediate expansion. It looks through any intervening 00079 /// macro argument expansions to compute this. It returns a StringRef which 00080 /// refers to the SourceManager-owned buffer of the source where that macro 00081 /// name is spelled. Thus, the result shouldn't out-live that SourceManager. 00082 /// 00083 /// This differs from Lexer::getImmediateMacroName in that any macro argument 00084 /// location will result in the topmost function macro that accepted it. 00085 /// e.g. 00086 /// \code 00087 /// MAC1( MAC2(foo) ) 00088 /// \endcode 00089 /// for location of 'foo' token, this function will return "MAC1" while 00090 /// Lexer::getImmediateMacroName will return "MAC2". 00091 static StringRef getImmediateMacroName(SourceLocation Loc, 00092 const SourceManager &SM, 00093 const LangOptions &LangOpts) { 00094 assert(Loc.isMacroID() && "Only reasonble to call this on macros"); 00095 // Walk past macro argument expanions. 00096 while (SM.isMacroArgExpansion(Loc)) 00097 Loc = SM.getImmediateExpansionRange(Loc).first; 00098 00099 // Find the spelling location of the start of the non-argument expansion 00100 // range. This is where the macro name was spelled in order to begin 00101 // expanding this macro. 00102 Loc = SM.getSpellingLoc(SM.getImmediateExpansionRange(Loc).first); 00103 00104 // Dig out the buffer where the macro name was spelled and the extents of the 00105 // name so that we can render it into the expansion note. 00106 std::pair<FileID, unsigned> ExpansionInfo = SM.getDecomposedLoc(Loc); 00107 unsigned MacroTokenLength = Lexer::MeasureTokenLength(Loc, SM, LangOpts); 00108 StringRef ExpansionBuffer = SM.getBufferData(ExpansionInfo.first); 00109 return ExpansionBuffer.substr(ExpansionInfo.second, MacroTokenLength); 00110 } 00111 00112 /// Get the presumed location of a diagnostic message. This computes the 00113 /// presumed location for the top of any macro backtrace when present. 00114 static PresumedLoc getDiagnosticPresumedLoc(const SourceManager &SM, 00115 SourceLocation Loc) { 00116 // This is a condensed form of the algorithm used by emitCaretDiagnostic to 00117 // walk to the top of the macro call stack. 00118 while (Loc.isMacroID()) { 00119 Loc = skipToMacroArgExpansion(SM, Loc); 00120 Loc = getImmediateMacroCallerLoc(SM, Loc); 00121 } 00122 00123 return SM.getPresumedLoc(Loc); 00124 } 00125 00126 DiagnosticRenderer::DiagnosticRenderer(const LangOptions &LangOpts, 00127 const DiagnosticOptions &DiagOpts) 00128 : LangOpts(LangOpts), DiagOpts(DiagOpts), LastLevel() {} 00129 00130 DiagnosticRenderer::~DiagnosticRenderer() {} 00131 00132 namespace { 00133 00134 class FixitReceiver : public edit::EditsReceiver { 00135 SmallVectorImpl<FixItHint> &MergedFixits; 00136 00137 public: 00138 FixitReceiver(SmallVectorImpl<FixItHint> &MergedFixits) 00139 : MergedFixits(MergedFixits) { } 00140 virtual void insert(SourceLocation loc, StringRef text) { 00141 MergedFixits.push_back(FixItHint::CreateInsertion(loc, text)); 00142 } 00143 virtual void replace(CharSourceRange range, StringRef text) { 00144 MergedFixits.push_back(FixItHint::CreateReplacement(range, text)); 00145 } 00146 }; 00147 00148 } 00149 00150 static void mergeFixits(ArrayRef<FixItHint> FixItHints, 00151 const SourceManager &SM, const LangOptions &LangOpts, 00152 SmallVectorImpl<FixItHint> &MergedFixits) { 00153 edit::Commit commit(SM, LangOpts); 00154 for (ArrayRef<FixItHint>::const_iterator 00155 I = FixItHints.begin(), E = FixItHints.end(); I != E; ++I) { 00156 const FixItHint &Hint = *I; 00157 if (Hint.CodeToInsert.empty()) { 00158 if (Hint.InsertFromRange.isValid()) 00159 commit.insertFromRange(Hint.RemoveRange.getBegin(), 00160 Hint.InsertFromRange, /*afterToken=*/false, 00161 Hint.BeforePreviousInsertions); 00162 else 00163 commit.remove(Hint.RemoveRange); 00164 } else { 00165 if (Hint.RemoveRange.isTokenRange() || 00166 Hint.RemoveRange.getBegin() != Hint.RemoveRange.getEnd()) 00167 commit.replace(Hint.RemoveRange, Hint.CodeToInsert); 00168 else 00169 commit.insert(Hint.RemoveRange.getBegin(), Hint.CodeToInsert, 00170 /*afterToken=*/false, Hint.BeforePreviousInsertions); 00171 } 00172 } 00173 00174 edit::EditedSource Editor(SM, LangOpts); 00175 if (Editor.commit(commit)) { 00176 FixitReceiver Rec(MergedFixits); 00177 Editor.applyRewrites(Rec); 00178 } 00179 } 00180 00181 void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc, 00182 DiagnosticsEngine::Level Level, 00183 StringRef Message, 00184 ArrayRef<CharSourceRange> Ranges, 00185 ArrayRef<FixItHint> FixItHints, 00186 const SourceManager *SM, 00187 DiagOrStoredDiag D) { 00188 assert(SM || Loc.isInvalid()); 00189 00190 beginDiagnostic(D, Level); 00191 00192 PresumedLoc PLoc; 00193 if (Loc.isValid()) { 00194 PLoc = getDiagnosticPresumedLoc(*SM, Loc); 00195 00196 // First, if this diagnostic is not in the main file, print out the 00197 // "included from" lines. 00198 emitIncludeStack(PLoc.getIncludeLoc(), Level, *SM); 00199 } 00200 00201 // Next, emit the actual diagnostic message. 00202 emitDiagnosticMessage(Loc, PLoc, Level, Message, Ranges, SM, D); 00203 00204 // Only recurse if we have a valid location. 00205 if (Loc.isValid()) { 00206 // Get the ranges into a local array we can hack on. 00207 SmallVector<CharSourceRange, 20> MutableRanges(Ranges.begin(), 00208 Ranges.end()); 00209 00210 llvm::SmallVector<FixItHint, 8> MergedFixits; 00211 if (!FixItHints.empty()) { 00212 mergeFixits(FixItHints, *SM, LangOpts, MergedFixits); 00213 FixItHints = MergedFixits; 00214 } 00215 00216 for (ArrayRef<FixItHint>::const_iterator I = FixItHints.begin(), 00217 E = FixItHints.end(); 00218 I != E; ++I) 00219 if (I->RemoveRange.isValid()) 00220 MutableRanges.push_back(I->RemoveRange); 00221 00222 unsigned MacroDepth = 0; 00223 emitMacroExpansionsAndCarets(Loc, Level, MutableRanges, FixItHints, *SM, 00224 MacroDepth); 00225 } 00226 00227 LastLoc = Loc; 00228 LastLevel = Level; 00229 00230 endDiagnostic(D, Level); 00231 } 00232 00233 00234 void DiagnosticRenderer::emitStoredDiagnostic(StoredDiagnostic &Diag) { 00235 emitDiagnostic(Diag.getLocation(), Diag.getLevel(), Diag.getMessage(), 00236 Diag.getRanges(), Diag.getFixIts(), 00237 Diag.getLocation().isValid() ? &Diag.getLocation().getManager() 00238 : 0, 00239 &Diag); 00240 } 00241 00242 /// \brief Prints an include stack when appropriate for a particular 00243 /// diagnostic level and location. 00244 /// 00245 /// This routine handles all the logic of suppressing particular include 00246 /// stacks (such as those for notes) and duplicate include stacks when 00247 /// repeated warnings occur within the same file. It also handles the logic 00248 /// of customizing the formatting and display of the include stack. 00249 /// 00250 /// \param Level The diagnostic level of the message this stack pertains to. 00251 /// \param Loc The include location of the current file (not the diagnostic 00252 /// location). 00253 void DiagnosticRenderer::emitIncludeStack(SourceLocation Loc, 00254 DiagnosticsEngine::Level Level, 00255 const SourceManager &SM) { 00256 // Skip redundant include stacks altogether. 00257 if (LastIncludeLoc == Loc) 00258 return; 00259 LastIncludeLoc = Loc; 00260 00261 if (!DiagOpts.ShowNoteIncludeStack && Level == DiagnosticsEngine::Note) 00262 return; 00263 00264 emitIncludeStackRecursively(Loc, SM); 00265 } 00266 00267 /// \brief Helper to recursivly walk up the include stack and print each layer 00268 /// on the way back down. 00269 void DiagnosticRenderer::emitIncludeStackRecursively(SourceLocation Loc, 00270 const SourceManager &SM) { 00271 if (Loc.isInvalid()) 00272 return; 00273 00274 PresumedLoc PLoc = SM.getPresumedLoc(Loc); 00275 if (PLoc.isInvalid()) 00276 return; 00277 00278 // Emit the other include frames first. 00279 emitIncludeStackRecursively(PLoc.getIncludeLoc(), SM); 00280 00281 // Emit the inclusion text/note. 00282 emitIncludeLocation(Loc, PLoc, SM); 00283 } 00284 00285 /// \brief Recursively emit notes for each macro expansion and caret 00286 /// diagnostics where appropriate. 00287 /// 00288 /// Walks up the macro expansion stack printing expansion notes, the code 00289 /// snippet, caret, underlines and FixItHint display as appropriate at each 00290 /// level. 00291 /// 00292 /// \param Loc The location for this caret. 00293 /// \param Level The diagnostic level currently being emitted. 00294 /// \param Ranges The underlined ranges for this code snippet. 00295 /// \param Hints The FixIt hints active for this diagnostic. 00296 /// \param MacroSkipEnd The depth to stop skipping macro expansions. 00297 /// \param OnMacroInst The current depth of the macro expansion stack. 00298 void DiagnosticRenderer::emitMacroExpansionsAndCarets( 00299 SourceLocation Loc, 00300 DiagnosticsEngine::Level Level, 00301 SmallVectorImpl<CharSourceRange>& Ranges, 00302 ArrayRef<FixItHint> Hints, 00303 const SourceManager &SM, 00304 unsigned &MacroDepth, 00305 unsigned OnMacroInst) 00306 { 00307 assert(!Loc.isInvalid() && "must have a valid source location here"); 00308 00309 // If this is a file source location, directly emit the source snippet and 00310 // caret line. Also record the macro depth reached. 00311 if (Loc.isFileID()) { 00312 assert(MacroDepth == 0 && "We shouldn't hit a leaf node twice!"); 00313 MacroDepth = OnMacroInst; 00314 emitCodeContext(Loc, Level, Ranges, Hints, SM); 00315 return; 00316 } 00317 // Otherwise recurse through each macro expansion layer. 00318 00319 // When processing macros, skip over the expansions leading up to 00320 // a macro argument, and trace the argument's expansion stack instead. 00321 Loc = skipToMacroArgExpansion(SM, Loc); 00322 00323 SourceLocation OneLevelUp = getImmediateMacroCallerLoc(SM, Loc); 00324 00325 // FIXME: Map ranges? 00326 emitMacroExpansionsAndCarets(OneLevelUp, Level, Ranges, Hints, SM, MacroDepth, 00327 OnMacroInst + 1); 00328 00329 // Save the original location so we can find the spelling of the macro call. 00330 SourceLocation MacroLoc = Loc; 00331 00332 // Map the location. 00333 Loc = getImmediateMacroCalleeLoc(SM, Loc); 00334 00335 unsigned MacroSkipStart = 0, MacroSkipEnd = 0; 00336 if (MacroDepth > DiagOpts.MacroBacktraceLimit && 00337 DiagOpts.MacroBacktraceLimit != 0) { 00338 MacroSkipStart = DiagOpts.MacroBacktraceLimit / 2 + 00339 DiagOpts.MacroBacktraceLimit % 2; 00340 MacroSkipEnd = MacroDepth - DiagOpts.MacroBacktraceLimit / 2; 00341 } 00342 00343 // Whether to suppress printing this macro expansion. 00344 bool Suppressed = (OnMacroInst >= MacroSkipStart && 00345 OnMacroInst < MacroSkipEnd); 00346 00347 // Map the ranges. 00348 for (SmallVectorImpl<CharSourceRange>::iterator I = Ranges.begin(), 00349 E = Ranges.end(); 00350 I != E; ++I) { 00351 SourceLocation Start = I->getBegin(), End = I->getEnd(); 00352 if (Start.isMacroID()) 00353 I->setBegin(getImmediateMacroCalleeLoc(SM, Start)); 00354 if (End.isMacroID()) 00355 I->setEnd(getImmediateMacroCalleeLoc(SM, End)); 00356 } 00357 00358 if (Suppressed) { 00359 // Tell the user that we've skipped contexts. 00360 if (OnMacroInst == MacroSkipStart) { 00361 SmallString<200> MessageStorage; 00362 llvm::raw_svector_ostream Message(MessageStorage); 00363 Message << "(skipping " << (MacroSkipEnd - MacroSkipStart) 00364 << " expansions in backtrace; use -fmacro-backtrace-limit=0 to " 00365 "see all)"; 00366 emitBasicNote(Message.str()); 00367 } 00368 return; 00369 } 00370 00371 SmallString<100> MessageStorage; 00372 llvm::raw_svector_ostream Message(MessageStorage); 00373 Message << "expanded from macro '" 00374 << getImmediateMacroName(MacroLoc, SM, LangOpts) << "'"; 00375 emitDiagnostic(SM.getSpellingLoc(Loc), DiagnosticsEngine::Note, 00376 Message.str(), 00377 Ranges, ArrayRef<FixItHint>(), &SM); 00378 } 00379 00380 DiagnosticNoteRenderer::~DiagnosticNoteRenderer() {} 00381 00382 void DiagnosticNoteRenderer::emitIncludeLocation(SourceLocation Loc, 00383 PresumedLoc PLoc, 00384 const SourceManager &SM) { 00385 // Generate a note indicating the include location. 00386 SmallString<200> MessageStorage; 00387 llvm::raw_svector_ostream Message(MessageStorage); 00388 Message << "in file included from " << PLoc.getFilename() << ':' 00389 << PLoc.getLine() << ":"; 00390 emitNote(Loc, Message.str(), &SM); 00391 } 00392 00393 void DiagnosticNoteRenderer::emitBasicNote(StringRef Message) { 00394 emitNote(SourceLocation(), Message, 0); 00395 } 00396