 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
63.2% |
24 / 38 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
78.9% |
30 / 38 |
| |
|
Line Coverage: |
84.7% |
61 / 72 |
| |
 |
|
 |
1 : //===--- PartialDiagnostic.h - Diagnostic "closures" ------------*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file implements a partial diagnostic that can be emitted anwyhere
11 : // in a DiagnosticBuilder stream.
12 : //
13 : //===----------------------------------------------------------------------===//
14 :
15 : #ifndef LLVM_CLANG_PARTIALDIAGNOSTIC_H
16 : #define LLVM_CLANG_PARTIALDIAGNOSTIC_H
17 :
18 : #include "clang/AST/Type.h"
19 : #include "clang/Basic/Diagnostic.h"
20 : #include "clang/Basic/SourceLocation.h"
21 : #include "llvm/ADT/STLExtras.h"
22 :
23 : namespace clang {
24 :
25 : class DeclarationName;
26 :
27 : class PartialDiagnostic {
1140: branch 0 taken
114: branch 1 taken
342: branch 2 taken
114: branch 3 taken
74433: branch 5 taken
0: branch 6 not taken
223299: branch 8 taken
74433: branch 9 taken
0: branch 11 not taken
0: branch 12 not taken
28 74547: struct Storage {
743190: branch 1 taken
74319: branch 2 taken
222957: branch 4 taken
74319: branch 5 taken
29 74319: Storage() : NumDiagArgs(0), NumDiagRanges(0), NumCodeModificationHints(0) {
30 74319: }
31 :
32 : enum {
33 : /// MaxArguments - The maximum number of arguments we can hold. We
34 : /// currently only support up to 10 arguments (%0-%9).
35 : /// A single diagnostic with more than that almost certainly has to
36 : /// be simplified anyway.
37 : MaxArguments = 10
38 : };
39 :
40 : /// NumDiagArgs - This contains the number of entries in Arguments.
41 : unsigned char NumDiagArgs;
42 :
43 : /// NumDiagRanges - This is the number of ranges in the DiagRanges array.
44 : unsigned char NumDiagRanges;
45 :
46 : /// \brief The number of code modifications hints in the
47 : /// CodeModificationHints array.
48 : unsigned char NumCodeModificationHints;
49 :
50 : /// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum
51 : /// values, with one for each argument. This specifies whether the argument
52 : /// is in DiagArgumentsStr or in DiagArguments.
53 : unsigned char DiagArgumentsKind[MaxArguments];
54 :
55 : /// DiagArgumentsVal - The values for the various substitution positions.
56 : /// This is used when the argument is not an std::string. The specific value
57 : /// is mangled into an intptr_t and the intepretation depends on exactly
58 : /// what sort of argument kind it is.
59 : intptr_t DiagArgumentsVal[MaxArguments];
60 :
61 : /// DiagRanges - The list of ranges added to this diagnostic. It currently
62 : /// only support 10 ranges, could easily be extended if needed.
63 : SourceRange DiagRanges[10];
64 :
65 : enum { MaxCodeModificationHints = 3 };
66 :
67 : /// CodeModificationHints - If valid, provides a hint with some code
68 : /// to insert, remove, or modify at a particular position.
69 : CodeModificationHint CodeModificationHints[MaxCodeModificationHints];
70 : };
71 :
72 : /// DiagID - The diagnostic ID.
73 : mutable unsigned DiagID;
74 :
75 : /// DiagStorare - Storge for args and ranges.
76 : mutable Storage *DiagStorage;
77 :
78 45158: void AddTaggedVal(intptr_t V, Diagnostic::ArgumentKind Kind) const {
44582: branch 0 taken
576: branch 1 taken
79 45158: if (!DiagStorage)
80 44582: DiagStorage = new Storage;
81 :
82 : assert(DiagStorage->NumDiagArgs < Storage::MaxArguments &&
0: branch 0 not taken
45158: branch 1 taken
83 45158: "Too many arguments to diagnostic!");
84 45158: DiagStorage->DiagArgumentsKind[DiagStorage->NumDiagArgs] = Kind;
85 45158: DiagStorage->DiagArgumentsVal[DiagStorage->NumDiagArgs++] = V;
86 45158: }
87 :
88 30415: void AddSourceRange(const SourceRange &R) const {
29737: branch 0 taken
678: branch 1 taken
89 30415: if (!DiagStorage)
90 29737: DiagStorage = new Storage;
91 :
92 : assert(DiagStorage->NumDiagRanges <
93 : llvm::array_lengthof(DiagStorage->DiagRanges) &&
30415: branch 1 taken
0: branch 2 not taken
94 30415: "Too many arguments to diagnostic!");
95 30415: DiagStorage->DiagRanges[DiagStorage->NumDiagRanges++] = R;
96 30415: }
97 :
98 15: void AddCodeModificationHint(const CodeModificationHint &Hint) const {
0: branch 1 not taken
15: branch 2 taken
99 15: if (Hint.isNull())
100 0: return;
101 :
0: branch 0 not taken
15: branch 1 taken
102 15: if (!DiagStorage)
103 0: DiagStorage = new Storage;
104 :
105 : assert(DiagStorage->NumCodeModificationHints <
106 : Storage::MaxCodeModificationHints &&
0: branch 0 not taken
15: branch 1 taken
107 15: "Too many code modification hints!");
108 : DiagStorage->CodeModificationHints[DiagStorage->NumCodeModificationHints++]
109 15: = Hint;
110 : }
111 :
112 : public:
113 268016: PartialDiagnostic(unsigned DiagID)
114 268016: : DiagID(DiagID), DiagStorage(0) { }
115 :
116 109022: PartialDiagnostic(const PartialDiagnostic &Other)
117 109022: : DiagID(Other.DiagID), DiagStorage(0)
118 : {
114: branch 0 taken
108908: branch 1 taken
119 109022: if (Other.DiagStorage)
120 114: DiagStorage = new Storage(*Other.DiagStorage);
121 109022: }
122 :
123 0: PartialDiagnostic &operator=(const PartialDiagnostic &Other) {
124 0: DiagID = Other.DiagID;
0: branch 0 not taken
0: branch 1 not taken
125 0: if (Other.DiagStorage) {
0: branch 0 not taken
0: branch 1 not taken
126 0: if (DiagStorage)
127 0: *DiagStorage = *Other.DiagStorage;
128 : else
129 0: DiagStorage = new Storage(*Other.DiagStorage);
130 : } else {
0: branch 0 not taken
0: branch 1 not taken
131 0: delete DiagStorage;
132 0: DiagStorage = 0;
133 : }
134 :
135 0: return *this;
136 : }
137 :
138 377038: ~PartialDiagnostic() {
74433: branch 0 taken
302605: branch 1 taken
139 377038: delete DiagStorage;
140 377038: }
141 :
142 :
143 109338: unsigned getDiagID() const { return DiagID; }
144 :
145 367: void Emit(const DiagnosticBuilder &DB) const {
146 367: if (!DiagStorage)
147 175: return;
148 :
149 : // Add all arguments.
150 331: for (unsigned i = 0, e = DiagStorage->NumDiagArgs; i != e; ++i) {
151 : DB.AddTaggedVal(DiagStorage->DiagArgumentsVal[i],
152 139: (Diagnostic::ArgumentKind)DiagStorage->DiagArgumentsKind[i]);
153 : }
154 :
155 : // Add all ranges.
156 314: for (unsigned i = 0, e = DiagStorage->NumDiagRanges; i != e; ++i)
157 122: DB.AddSourceRange(DiagStorage->DiagRanges[i]);
158 :
159 : // Add all code modification hints
160 204: for (unsigned i = 0, e = DiagStorage->NumCodeModificationHints; i != e; ++i)
161 12: DB.AddCodeModificationHint(DiagStorage->CodeModificationHints[i]);
162 : }
163 :
164 : friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
165 472: QualType T) {
166 : PD.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
167 472: Diagnostic::ak_qualtype);
168 472: return PD;
169 : }
170 :
171 : friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
172 4: unsigned I) {
173 4: PD.AddTaggedVal(I, Diagnostic::ak_uint);
174 4: return PD;
175 : }
176 :
177 : friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
178 44257: int I) {
179 44257: PD.AddTaggedVal(I, Diagnostic::ak_sint);
180 44257: return PD;
181 : }
182 :
183 : friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
184 27: const char *S) {
185 27: PD.AddTaggedVal(reinterpret_cast<intptr_t>(S), Diagnostic::ak_c_string);
186 27: return PD;
187 : }
188 :
189 : friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
190 30415: const SourceRange &R) {
191 30415: PD.AddSourceRange(R);
192 30415: return PD;
193 : }
194 :
195 : friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
196 : DeclarationName N);
197 :
198 : friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
199 15: const CodeModificationHint &Hint) {
200 15: PD.AddCodeModificationHint(Hint);
201 15: return PD;
202 : }
203 :
204 : };
205 :
206 225342: inline PartialDiagnostic PDiag(unsigned DiagID = 0) {
207 225342: return PartialDiagnostic(DiagID);
208 : }
209 :
210 : inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
211 : const PartialDiagnostic &PD) {
212 : PD.Emit(DB);
213 : return DB;
214 : }
215 :
216 :
217 : } // end namespace clang
218 : #endif
Generated: 2010-02-10 01:31 by zcov