clang API Documentation
00001 //===--- DiagnosticRenderer.h - Diagnostic Pretty-Printing ------*- C++ -*-===// 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 // This is a utility class that provides support for pretty-printing of 00011 // diagnostics. It is used to implement the different code paths which require 00012 // such functionality in a consistent way. 00013 // 00014 //===----------------------------------------------------------------------===// 00015 00016 #ifndef LLVM_CLANG_FRONTEND_DIAGNOSTIC_RENDERER_H_ 00017 #define LLVM_CLANG_FRONTEND_DIAGNOSTIC_RENDERER_H_ 00018 00019 #include "clang/Basic/Diagnostic.h" 00020 #include "clang/Basic/LLVM.h" 00021 #include "clang/Basic/SourceLocation.h" 00022 #include "llvm/ADT/PointerUnion.h" 00023 00024 namespace clang { 00025 00026 class DiagnosticOptions; 00027 class LangOptions; 00028 class SourceManager; 00029 00030 typedef llvm::PointerUnion<const Diagnostic *, 00031 const StoredDiagnostic *> DiagOrStoredDiag; 00032 00033 /// \brief Class to encapsulate the logic for formatting a diagnostic message. 00034 /// Actual "printing" logic is implemented by subclasses. 00035 /// 00036 /// This class provides an interface for building and emitting 00037 /// diagnostic, including all of the macro backtraces, caret diagnostics, FixIt 00038 /// Hints, and code snippets. In the presence of macros this involves 00039 /// a recursive process, synthesizing notes for each macro expansion. 00040 /// 00041 /// A brief worklist: 00042 /// FIXME: Sink the recursive printing of template instantiations into this 00043 /// class. 00044 class DiagnosticRenderer { 00045 protected: 00046 const LangOptions &LangOpts; 00047 const DiagnosticOptions &DiagOpts; 00048 00049 /// \brief The location of the previous diagnostic if known. 00050 /// 00051 /// This will be invalid in cases where there is no (known) previous 00052 /// diagnostic location, or that location itself is invalid or comes from 00053 /// a different source manager than SM. 00054 SourceLocation LastLoc; 00055 00056 /// \brief The location of the last include whose stack was printed if known. 00057 /// 00058 /// Same restriction as \see LastLoc essentially, but tracking include stack 00059 /// root locations rather than diagnostic locations. 00060 SourceLocation LastIncludeLoc; 00061 00062 /// \brief The level of the last diagnostic emitted. 00063 /// 00064 /// The level of the last diagnostic emitted. Used to detect level changes 00065 /// which change the amount of information displayed. 00066 DiagnosticsEngine::Level LastLevel; 00067 00068 DiagnosticRenderer(const LangOptions &LangOpts, 00069 const DiagnosticOptions &DiagOpts); 00070 00071 virtual ~DiagnosticRenderer(); 00072 00073 virtual void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc, 00074 DiagnosticsEngine::Level Level, 00075 StringRef Message, 00076 ArrayRef<CharSourceRange> Ranges, 00077 const SourceManager *SM, 00078 DiagOrStoredDiag Info) = 0; 00079 00080 virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc, 00081 DiagnosticsEngine::Level Level, 00082 ArrayRef<CharSourceRange> Ranges, 00083 const SourceManager &SM) = 0; 00084 00085 virtual void emitBasicNote(StringRef Message) = 0; 00086 00087 virtual void emitCodeContext(SourceLocation Loc, 00088 DiagnosticsEngine::Level Level, 00089 SmallVectorImpl<CharSourceRange>& Ranges, 00090 ArrayRef<FixItHint> Hints, 00091 const SourceManager &SM) = 0; 00092 00093 virtual void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc, 00094 const SourceManager &SM) = 0; 00095 00096 virtual void beginDiagnostic(DiagOrStoredDiag D, 00097 DiagnosticsEngine::Level Level) {} 00098 virtual void endDiagnostic(DiagOrStoredDiag D, 00099 DiagnosticsEngine::Level Level) {} 00100 00101 00102 private: 00103 void emitIncludeStack(SourceLocation Loc, DiagnosticsEngine::Level Level, 00104 const SourceManager &SM); 00105 void emitIncludeStackRecursively(SourceLocation Loc, const SourceManager &SM); 00106 void emitMacroExpansionsAndCarets(SourceLocation Loc, 00107 DiagnosticsEngine::Level Level, 00108 SmallVectorImpl<CharSourceRange>& Ranges, 00109 ArrayRef<FixItHint> Hints, 00110 const SourceManager &SM, 00111 unsigned &MacroDepth, 00112 unsigned OnMacroInst = 0); 00113 public: 00114 /// \brief Emit a diagnostic. 00115 /// 00116 /// This is the primary entry point for emitting diagnostic messages. 00117 /// It handles formatting and rendering the message as well as any ancillary 00118 /// information needed based on macros whose expansions impact the 00119 /// diagnostic. 00120 /// 00121 /// \param Loc The location for this caret. 00122 /// \param Level The level of the diagnostic to be emitted. 00123 /// \param Message The diagnostic message to emit. 00124 /// \param Ranges The underlined ranges for this code snippet. 00125 /// \param FixItHints The FixIt hints active for this diagnostic. 00126 /// \param SM The SourceManager; will be null if the diagnostic came from the 00127 /// frontend, thus \param Loc will be invalid. 00128 void emitDiagnostic(SourceLocation Loc, DiagnosticsEngine::Level Level, 00129 StringRef Message, ArrayRef<CharSourceRange> Ranges, 00130 ArrayRef<FixItHint> FixItHints, 00131 const SourceManager *SM, 00132 DiagOrStoredDiag D = (Diagnostic *)0); 00133 00134 void emitStoredDiagnostic(StoredDiagnostic &Diag); 00135 }; 00136 00137 /// Subclass of DiagnosticRender that turns all subdiagostics into explicit 00138 /// notes. It is up to subclasses to further define the behavior. 00139 class DiagnosticNoteRenderer : public DiagnosticRenderer { 00140 public: 00141 DiagnosticNoteRenderer(const LangOptions &LangOpts, 00142 const DiagnosticOptions &DiagOpts) 00143 : DiagnosticRenderer(LangOpts, DiagOpts) {} 00144 00145 virtual ~DiagnosticNoteRenderer(); 00146 00147 virtual void emitBasicNote(StringRef Message); 00148 00149 virtual void emitIncludeLocation(SourceLocation Loc, 00150 PresumedLoc PLoc, 00151 const SourceManager &SM); 00152 00153 virtual void emitNote(SourceLocation Loc, StringRef Message, 00154 const SourceManager *SM) = 0; 00155 }; 00156 } // end clang namespace 00157 #endif