1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
//===--- TextDiagnostic.h - Text Diagnostic Pretty-Printing -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This is a utility class that provides support for textual pretty-printing of
// diagnostics. It is used to implement the different code paths which require
// such functionality in a consistent way.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_FRONTEND_TEXT_DIAGNOSTIC_H_
#define LLVM_CLANG_FRONTEND_TEXT_DIAGNOSTIC_H_
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
namespace clang {
class DiagnosticOptions;
class LangOptions;
class SourceManager;
/// \brief Class to encapsulate the logic for formatting and printing a textual
/// diagnostic message.
///
/// This class provides an interface for building and emitting a textual
/// diagnostic, including all of the macro backtraces, caret diagnostics, FixIt
/// Hints, and code snippets. In the presence of macros this involves
/// a recursive process, synthesizing notes for each macro expansion.
///
/// The purpose of this class is to isolate the implementation of printing
/// beautiful text diagnostics from any particular interfaces. The Clang
/// DiagnosticClient is implemented through this class as is diagnostic
/// printing coming out of libclang.
///
/// A brief worklist:
/// FIXME: Sink the recursive printing of template instantiations into this
/// class.
class TextDiagnostic {
raw_ostream &OS;
const SourceManager &SM;
const LangOptions &LangOpts;
const DiagnosticOptions &DiagOpts;
/// \brief The location of the previous diagnostic if known.
///
/// This will be invalid in cases where there is no (known) previous
/// diagnostic location, or that location itself is invalid or comes from
/// a different source manager than SM.
SourceLocation LastLoc;
/// \brief The location of the last include whose stack was printed if known.
///
/// Same restriction as \see LastLoc essentially, but tracking include stack
/// root locations rather than diagnostic locations.
SourceLocation LastIncludeLoc;
/// \brief The level of the last diagnostic emitted.
///
/// The level of the last diagnostic emitted. Used to detect level changes
/// which change the amount of information displayed.
DiagnosticsEngine::Level LastLevel;
public:
TextDiagnostic(raw_ostream &OS,
const SourceManager &SM,
const LangOptions &LangOpts,
const DiagnosticOptions &DiagOpts,
FullSourceLoc LastLoc = FullSourceLoc(),
FullSourceLoc LastIncludeLoc = FullSourceLoc(),
DiagnosticsEngine::Level LastLevel
= DiagnosticsEngine::Level());
/// \brief Get the last diagnostic location emitted.
SourceLocation getLastLoc() const { return LastLoc; }
/// \brief Get the last emitted include stack location.
SourceLocation getLastIncludeLoc() const { return LastIncludeLoc; }
/// \brief Get the last diagnostic level.
DiagnosticsEngine::Level getLastLevel() const { return LastLevel; }
void emitDiagnostic(SourceLocation Loc, DiagnosticsEngine::Level Level,
StringRef Message, ArrayRef<CharSourceRange> Ranges,
ArrayRef<FixItHint> FixItHints,
bool LastCaretDiagnosticWasNote = false);
/// \brief Print the diagonstic level to a raw_ostream.
///
/// This is a static helper that handles colorizing the level and formatting
/// it into an arbitrary output stream. This is used internally by the
/// TextDiagnostic emission code, but it can also be used directly by
/// consumers that don't have a source manager or other state that the full
/// TextDiagnostic logic requires.
static void printDiagnosticLevel(raw_ostream &OS,
DiagnosticsEngine::Level Level,
bool ShowColors);
/// \brief Pretty-print a diagnostic message to a raw_ostream.
///
/// This is a static helper to handle the line wrapping, colorizing, and
/// rendering of a diagnostic message to a particular ostream. It is
/// publically visible so that clients which do not have sufficient state to
/// build a complete TextDiagnostic object can still get consistent
/// formatting of their diagnostic messages.
///
/// \param OS Where the message is printed
/// \param Level Used to colorizing the message
/// \param Message The text actually printed
/// \param CurrentColumn The starting column of the first line, accounting
/// for any prefix.
/// \param Columns The number of columns to use in line-wrapping, 0 disables
/// all line-wrapping.
/// \param ShowColors Enable colorizing of the message.
static void printDiagnosticMessage(raw_ostream &OS,
DiagnosticsEngine::Level Level,
StringRef Message,
unsigned CurrentColumn, unsigned Columns,
bool ShowColors);
private:
void emitIncludeStack(SourceLocation Loc, DiagnosticsEngine::Level Level);
void emitIncludeStackRecursively(SourceLocation Loc);
void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges);
void emitCaret(SourceLocation Loc,
SmallVectorImpl<CharSourceRange>& Ranges,
ArrayRef<FixItHint> Hints,
unsigned &MacroDepth,
unsigned OnMacroInst = 0);
void emitSnippetAndCaret(SourceLocation Loc,
SmallVectorImpl<CharSourceRange>& Ranges,
ArrayRef<FixItHint> Hints);
void highlightRange(const CharSourceRange &R,
unsigned LineNo, FileID FID,
const std::string &SourceLine,
std::string &CaretLine);
std::string buildFixItInsertionLine(unsigned LineNo,
const char *LineStart,
const char *LineEnd,
ArrayRef<FixItHint> Hints);
void expandTabs(std::string &SourceLine, std::string &CaretLine);
void emitParseableFixits(ArrayRef<FixItHint> Hints);
};
} // end namespace clang
#endif
|