1 //===--- TextDiagnostic.h - Text Diagnostic Pretty-Printing -----*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This is a utility class that provides support for textual pretty-printing of 10 // diagnostics. It is used to implement the different code paths which require 11 // such functionality in a consistent way. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H 16 #define LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H 17 18 #include "clang/Frontend/DiagnosticRenderer.h" 19 #include "llvm/Support/raw_ostream.h" 20 21 namespace clang { 22 23 /// Class to encapsulate the logic for formatting and printing a textual 24 /// diagnostic message. 25 /// 26 /// This class provides an interface for building and emitting a textual 27 /// diagnostic, including all of the macro backtraces, caret diagnostics, FixIt 28 /// Hints, and code snippets. In the presence of macros this involves 29 /// a recursive process, synthesizing notes for each macro expansion. 30 /// 31 /// The purpose of this class is to isolate the implementation of printing 32 /// beautiful text diagnostics from any particular interfaces. The Clang 33 /// DiagnosticClient is implemented through this class as is diagnostic 34 /// printing coming out of libclang. 35 class TextDiagnostic : public DiagnosticRenderer { 36 raw_ostream &OS; 37 const Preprocessor *PP; 38 39 public: 40 TextDiagnostic(raw_ostream &OS, const LangOptions &LangOpts, 41 DiagnosticOptions *DiagOpts, const Preprocessor *PP = nullptr); 42 43 ~TextDiagnostic() override; 44 45 struct StyleRange { 46 unsigned Start; 47 unsigned End; 48 enum llvm::raw_ostream::Colors Color; StyleRangeStyleRange49 StyleRange(unsigned S, unsigned E, enum llvm::raw_ostream::Colors C) 50 : Start(S), End(E), Color(C){}; 51 }; 52 53 /// Print the diagonstic level to a raw_ostream. 54 /// 55 /// This is a static helper that handles colorizing the level and formatting 56 /// it into an arbitrary output stream. This is used internally by the 57 /// TextDiagnostic emission code, but it can also be used directly by 58 /// consumers that don't have a source manager or other state that the full 59 /// TextDiagnostic logic requires. 60 static void printDiagnosticLevel(raw_ostream &OS, 61 DiagnosticsEngine::Level Level, 62 bool ShowColors); 63 64 /// Pretty-print a diagnostic message to a raw_ostream. 65 /// 66 /// This is a static helper to handle the line wrapping, colorizing, and 67 /// rendering of a diagnostic message to a particular ostream. It is 68 /// publicly visible so that clients which do not have sufficient state to 69 /// build a complete TextDiagnostic object can still get consistent 70 /// formatting of their diagnostic messages. 71 /// 72 /// \param OS Where the message is printed 73 /// \param IsSupplemental true if this is a continuation note diagnostic 74 /// \param Message The text actually printed 75 /// \param CurrentColumn The starting column of the first line, accounting 76 /// for any prefix. 77 /// \param Columns The number of columns to use in line-wrapping, 0 disables 78 /// all line-wrapping. 79 /// \param ShowColors Enable colorizing of the message. 80 static void printDiagnosticMessage(raw_ostream &OS, bool IsSupplemental, 81 StringRef Message, unsigned CurrentColumn, 82 unsigned Columns, bool ShowColors); 83 84 protected: 85 void emitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc, 86 DiagnosticsEngine::Level Level, StringRef Message, 87 ArrayRef<CharSourceRange> Ranges, 88 DiagOrStoredDiag D) override; 89 90 void emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc, 91 DiagnosticsEngine::Level Level, 92 ArrayRef<CharSourceRange> Ranges) override; 93 emitCodeContext(FullSourceLoc Loc,DiagnosticsEngine::Level Level,SmallVectorImpl<CharSourceRange> & Ranges,ArrayRef<FixItHint> Hints)94 void emitCodeContext(FullSourceLoc Loc, DiagnosticsEngine::Level Level, 95 SmallVectorImpl<CharSourceRange> &Ranges, 96 ArrayRef<FixItHint> Hints) override { 97 emitSnippetAndCaret(Loc, Level, Ranges, Hints); 98 } 99 100 void emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc) override; 101 102 void emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc, 103 StringRef ModuleName) override; 104 105 void emitBuildingModuleLocation(FullSourceLoc Loc, PresumedLoc PLoc, 106 StringRef ModuleName) override; 107 108 private: 109 void emitFilename(StringRef Filename, const SourceManager &SM); 110 111 void emitSnippetAndCaret(FullSourceLoc Loc, DiagnosticsEngine::Level Level, 112 SmallVectorImpl<CharSourceRange> &Ranges, 113 ArrayRef<FixItHint> Hints); 114 115 void emitSnippet(StringRef SourceLine, unsigned MaxLineNoDisplayWidth, 116 unsigned LineNo, unsigned DisplayLineNo, 117 ArrayRef<StyleRange> Styles); 118 119 void emitParseableFixits(ArrayRef<FixItHint> Hints, const SourceManager &SM); 120 }; 121 122 } // end namespace clang 123 124 #endif 125