12898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek//===--- DiagnosticRenderer.h - Diagnostic Pretty-Printing ------*- C++ -*-===// 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// This is a utility class that provides support for pretty-printing of 112898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek// diagnostics. It is used to implement the different code paths which require 122898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek// such functionality in a consistent way. 132898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek// 142898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek//===----------------------------------------------------------------------===// 152898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 162898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek#ifndef LLVM_CLANG_FRONTEND_DIAGNOSTIC_RENDERER_H_ 172898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek#define LLVM_CLANG_FRONTEND_DIAGNOSTIC_RENDERER_H_ 182898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 192898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek#include "clang/Basic/Diagnostic.h" 202898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek#include "clang/Basic/LLVM.h" 212898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek#include "clang/Basic/SourceLocation.h" 228be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek#include "llvm/ADT/PointerUnion.h" 232898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 242898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremeneknamespace clang { 252898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 268be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenekclass DiagnosticOptions; 278be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenekclass LangOptions; 288be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenekclass SourceManager; 298be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek 308be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenektypedef llvm::PointerUnion<const Diagnostic *, 318be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek const StoredDiagnostic *> DiagOrStoredDiag; 328be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek 332898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// \brief Class to encapsulate the logic for formatting a diagnostic message. 342898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// Actual "printing" logic is implemented by subclasses. 352898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// 362898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// This class provides an interface for building and emitting 372898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// diagnostic, including all of the macro backtraces, caret diagnostics, FixIt 382898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// Hints, and code snippets. In the presence of macros this involves 392898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// a recursive process, synthesizing notes for each macro expansion. 402898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// 412898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// A brief worklist: 422898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// FIXME: Sink the recursive printing of template instantiations into this 432898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek/// class. 442898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenekclass DiagnosticRenderer { 452898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenekprotected: 462898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek const SourceManager &SM; 472898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek const LangOptions &LangOpts; 482898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek const DiagnosticOptions &DiagOpts; 492898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 502898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek /// \brief The location of the previous diagnostic if known. 512898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek /// 522898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek /// This will be invalid in cases where there is no (known) previous 532898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek /// diagnostic location, or that location itself is invalid or comes from 542898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek /// a different source manager than SM. 552898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek SourceLocation LastLoc; 562898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 572898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek /// \brief The location of the last include whose stack was printed if known. 582898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek /// 592898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek /// Same restriction as \see LastLoc essentially, but tracking include stack 602898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek /// root locations rather than diagnostic locations. 612898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek SourceLocation LastIncludeLoc; 622898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 632898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek /// \brief The level of the last diagnostic emitted. 642898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek /// 652898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek /// The level of the last diagnostic emitted. Used to detect level changes 662898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek /// which change the amount of information displayed. 672898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek DiagnosticsEngine::Level LastLevel; 682898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 692898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek DiagnosticRenderer(const SourceManager &SM, 702898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek const LangOptions &LangOpts, 712898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek const DiagnosticOptions &DiagOpts); 722898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 732898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek virtual ~DiagnosticRenderer(); 742898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 752898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek virtual void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc, 762898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek DiagnosticsEngine::Level Level, 772898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek StringRef Message, 782898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek ArrayRef<CharSourceRange> Ranges, 798be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek DiagOrStoredDiag Info) = 0; 802898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 812898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc, 822898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek DiagnosticsEngine::Level Level, 832898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek ArrayRef<CharSourceRange> Ranges) = 0; 842898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 852898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek virtual void emitBasicNote(StringRef Message) = 0; 862898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 872898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek virtual void emitCodeContext(SourceLocation Loc, 882898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek DiagnosticsEngine::Level Level, 892898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek SmallVectorImpl<CharSourceRange>& Ranges, 902898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek ArrayRef<FixItHint> Hints) = 0; 912898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 922898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek virtual void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc) = 0; 932898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 948be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek virtual void beginDiagnostic(DiagOrStoredDiag D, 952898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek DiagnosticsEngine::Level Level) {} 968be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek virtual void endDiagnostic(DiagOrStoredDiag D, 972898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek DiagnosticsEngine::Level Level) {} 982898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 992898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek 1002898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenekprivate: 1012898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek void emitIncludeStack(SourceLocation Loc, DiagnosticsEngine::Level Level); 1022898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek void emitIncludeStackRecursively(SourceLocation Loc); 1032898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek void emitMacroExpansionsAndCarets(SourceLocation Loc, 1042898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek DiagnosticsEngine::Level Level, 1052898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek SmallVectorImpl<CharSourceRange>& Ranges, 1062898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek ArrayRef<FixItHint> Hints, 1072898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek unsigned &MacroDepth, 1082898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek unsigned OnMacroInst = 0); 1092898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenekpublic: 1102898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek /// \brief Emit a diagnostic. 1112898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek /// 1122898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek /// This is the primary entry point for emitting diagnostic messages. 1132898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek /// It handles formatting and rendering the message as well as any ancillary 1142898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek /// information needed based on macros whose expansions impact the 1152898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek /// diagnostic. 1162898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek /// 1172898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek /// \param Loc The location for this caret. 1182898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek /// \param Level The level of the diagnostic to be emitted. 1192898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek /// \param Message The diagnostic message to emit. 1202898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek /// \param Ranges The underlined ranges for this code snippet. 1212898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek /// \param FixItHints The FixIt hints active for this diagnostic. 1222898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek void emitDiagnostic(SourceLocation Loc, DiagnosticsEngine::Level Level, 1232898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek StringRef Message, ArrayRef<CharSourceRange> Ranges, 1242898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek ArrayRef<FixItHint> FixItHints, 1258be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek DiagOrStoredDiag D = (Diagnostic *)0); 1268be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek 1278be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek void emitStoredDiagnostic(StoredDiagnostic &Diag); 1288be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek}; 1298be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek 1308be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek/// Subclass of DiagnosticRender that turns all subdiagostics into explicit 1318be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek/// notes. It is up to subclasses to further define the behavior. 1328be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenekclass DiagnosticNoteRenderer : public DiagnosticRenderer { 1338be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenekpublic: 1348be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek DiagnosticNoteRenderer(const SourceManager &SM, 1358be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek const LangOptions &LangOpts, 1368be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek const DiagnosticOptions &DiagOpts) 1378be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek : DiagnosticRenderer(SM, LangOpts, DiagOpts) {} 1388be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek 1398be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek virtual ~DiagnosticNoteRenderer(); 1408be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek 1418be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek virtual void emitBasicNote(StringRef Message); 1428be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek 1438be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek virtual void emitIncludeLocation(SourceLocation Loc, 1448be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek PresumedLoc PLoc); 1458be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek 1468be51eab5ad34515d2a40dcdc8558128ca1800adTed Kremenek virtual void emitNote(SourceLocation Loc, StringRef Message) = 0; 1472898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek}; 1482898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek} // end clang namespace 1492898d4f7648e6ed5e9047068f1e8ee2f3c2bcd75Ted Kremenek#endif 150