 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
54.5% |
61 / 112 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
92.9% |
104 / 112 |
| |
|
Line Coverage: |
84.8% |
95 / 112 |
| |
 |
|
 |
1 : /*===-- CIndexDiagnostics.cpp - Diagnostics C Interface -----------*- 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 : |* Implements the diagnostic functions of the Clang C interface. *|
11 : |* *|
12 : \*===----------------------------------------------------------------------===*/
13 : #include "CIndexDiagnostic.h"
14 : #include "CIndexer.h"
15 : #include "CXSourceLocation.h"
16 :
17 : #include "clang/Frontend/FrontendDiagnostic.h"
18 : #include "llvm/Support/MemoryBuffer.h"
19 :
20 : using namespace clang;
21 : using namespace clang::cxloc;
22 :
23 : //-----------------------------------------------------------------------------
24 : // Opaque data structures
25 : //-----------------------------------------------------------------------------
26 : namespace {
27 : /// \brief The storage behind a CXDiagnostic
28 : struct CXStoredDiagnostic {
29 : /// \brief The translation unit this diagnostic came from.
30 : const LangOptions *LangOptsPtr;
31 :
32 : /// \brief The severity level of this diagnostic.
33 : Diagnostic::Level Level;
34 :
35 : /// \brief A reference to the diagnostic information.
36 : const DiagnosticInfo &Info;
37 : };
38 : }
39 :
40 : //-----------------------------------------------------------------------------
41 : // CIndex Diagnostic Client
42 : //-----------------------------------------------------------------------------
0: branch 1 not taken
0: branch 2 not taken
0: branch 5 not taken
69: branch 6 taken
0: branch 9 not taken
0: branch 10 not taken
43 69: CIndexDiagnosticClient::~CIndexDiagnosticClient() { }
44 :
45 : void CIndexDiagnosticClient::BeginSourceFile(const LangOptions &LangOpts,
46 61: const Preprocessor *PP) {
0: branch 0 not taken
61: branch 1 taken
47 61: assert(!LangOptsPtr && "Invalid state!");
48 61: LangOptsPtr = &LangOpts;
49 61: }
50 :
51 42: void CIndexDiagnosticClient::EndSourceFile() {
0: branch 0 not taken
42: branch 1 taken
52 42: assert(LangOptsPtr && "Invalid state!");
53 42: LangOptsPtr = 0;
54 42: }
55 :
56 : void CIndexDiagnosticClient::HandleDiagnostic(Diagnostic::Level DiagLevel,
57 55: const DiagnosticInfo &Info) {
55: branch 0 taken
0: branch 1 not taken
58 55: if (!Callback)
59 0: return;
60 :
61 : assert((LangOptsPtr || Info.getLocation().isInvalid()) &&
0: branch 0 not taken
55: branch 1 taken
0: branch 4 not taken
0: branch 5 not taken
62 55: "Missing language options with located diagnostic!");
63 55: CXStoredDiagnostic Stored = { this->LangOptsPtr, DiagLevel, Info };
64 55: Callback(&Stored, ClientData);
65 : }
66 :
67 : //-----------------------------------------------------------------------------
68 : // C Interface Routines
69 : //-----------------------------------------------------------------------------
70 : extern "C" {
71 :
72 55: enum CXDiagnosticSeverity clang_getDiagnosticSeverity(CXDiagnostic Diag) {
73 55: CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
0: branch 0 not taken
55: branch 1 taken
74 55: if (!StoredDiag)
75 0: return CXDiagnostic_Ignored;
76 :
0: branch 0 not taken
3: branch 1 taken
44: branch 2 taken
6: branch 3 taken
2: branch 4 taken
0: branch 5 not taken
77 55: switch (StoredDiag->Level) {
78 0: case Diagnostic::Ignored: return CXDiagnostic_Ignored;
79 3: case Diagnostic::Note: return CXDiagnostic_Note;
80 44: case Diagnostic::Warning: return CXDiagnostic_Warning;
81 6: case Diagnostic::Error: return CXDiagnostic_Error;
82 2: case Diagnostic::Fatal: return CXDiagnostic_Fatal;
83 : }
84 :
85 0: llvm_unreachable("Invalid diagnostic level");
86 : return CXDiagnostic_Ignored;
87 : }
88 :
89 55: CXSourceLocation clang_getDiagnosticLocation(CXDiagnostic Diag) {
90 55: CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
55: branch 0 taken
0: branch 1 not taken
0: branch 4 not taken
55: branch 5 taken
0: branch 6 not taken
55: branch 7 taken
91 55: if (!StoredDiag || StoredDiag->Info.getLocation().isInvalid())
92 0: return clang_getNullLocation();
93 :
94 : return translateSourceLocation(StoredDiag->Info.getLocation().getManager(),
95 : *StoredDiag->LangOptsPtr,
96 55: StoredDiag->Info.getLocation());
97 : }
98 :
99 55: CXString clang_getDiagnosticSpelling(CXDiagnostic Diag) {
100 55: CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
0: branch 0 not taken
55: branch 1 taken
101 55: if (!StoredDiag)
102 0: return CIndexer::createCXString("");
103 :
104 55: llvm::SmallString<64> Spelling;
105 55: StoredDiag->Info.FormatDiagnostic(Spelling);
106 55: return CIndexer::createCXString(Spelling.str(), true);
107 : }
108 :
109 55: unsigned clang_getDiagnosticNumRanges(CXDiagnostic Diag) {
110 55: CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
55: branch 0 taken
0: branch 1 not taken
0: branch 4 not taken
55: branch 5 taken
0: branch 6 not taken
55: branch 7 taken
111 55: if (!StoredDiag || StoredDiag->Info.getLocation().isInvalid())
112 0: return 0;
113 :
114 55: return StoredDiag->Info.getNumRanges();
115 : }
116 :
117 11: CXSourceRange clang_getDiagnosticRange(CXDiagnostic Diag, unsigned Range) {
118 11: CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
11: branch 0 taken
0: branch 1 not taken
11: branch 3 taken
0: branch 4 not taken
0: branch 7 not taken
11: branch 8 taken
0: branch 9 not taken
11: branch 10 taken
119 11: if (!StoredDiag || Range >= StoredDiag->Info.getNumRanges() ||
120 : StoredDiag->Info.getLocation().isInvalid())
121 0: return clang_getNullRange();
122 :
123 : return translateSourceRange(StoredDiag->Info.getLocation().getManager(),
124 : *StoredDiag->LangOptsPtr,
125 11: StoredDiag->Info.getRange(Range));
126 : }
127 :
128 55: unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diag) {
129 55: CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
0: branch 0 not taken
55: branch 1 taken
130 55: if (!StoredDiag)
131 0: return 0;
132 :
133 55: return StoredDiag->Info.getNumCodeModificationHints();
134 : }
135 :
136 : enum CXFixItKind clang_getDiagnosticFixItKind(CXDiagnostic Diag,
137 3: unsigned FixIt) {
138 3: CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
3: branch 0 taken
0: branch 1 not taken
0: branch 3 not taken
3: branch 4 taken
0: branch 5 not taken
3: branch 6 taken
139 3: if (!StoredDiag || FixIt >= StoredDiag->Info.getNumCodeModificationHints())
140 0: return CXFixIt_Insertion;
141 :
142 : const CodeModificationHint &Hint
143 3: = StoredDiag->Info.getCodeModificationHint(FixIt);
1: branch 1 taken
2: branch 2 taken
144 3: if (Hint.RemoveRange.isInvalid())
145 1: return CXFixIt_Insertion;
1: branch 1 taken
1: branch 2 taken
146 2: if (Hint.InsertionLoc.isInvalid())
147 1: return CXFixIt_Removal;
148 :
149 1: return CXFixIt_Replacement;
150 : }
151 :
152 : CXString clang_getDiagnosticFixItInsertion(CXDiagnostic Diag,
153 : unsigned FixIt,
154 1: CXSourceLocation *Location) {
1: branch 0 taken
0: branch 1 not taken
155 1: if (Location)
156 1: *Location = clang_getNullLocation();
157 :
158 1: CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
1: branch 0 taken
0: branch 1 not taken
0: branch 3 not taken
1: branch 4 taken
0: branch 5 not taken
1: branch 6 taken
159 1: if (!StoredDiag || FixIt >= StoredDiag->Info.getNumCodeModificationHints())
160 0: return CIndexer::createCXString("");
161 :
162 : const CodeModificationHint &Hint
163 1: = StoredDiag->Info.getCodeModificationHint(FixIt);
164 :
1: branch 0 taken
0: branch 1 not taken
1: branch 4 taken
0: branch 5 not taken
1: branch 6 taken
0: branch 7 not taken
165 1: if (Location && StoredDiag->Info.getLocation().isValid())
166 : *Location = translateSourceLocation(
167 : StoredDiag->Info.getLocation().getManager(),
168 : *StoredDiag->LangOptsPtr,
169 1: Hint.InsertionLoc);
170 1: return CIndexer::createCXString(Hint.CodeToInsert);
171 : }
172 :
173 : CXSourceRange clang_getDiagnosticFixItRemoval(CXDiagnostic Diag,
174 1: unsigned FixIt) {
175 1: CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
1: branch 0 taken
0: branch 1 not taken
1: branch 3 taken
0: branch 4 not taken
0: branch 7 not taken
1: branch 8 taken
0: branch 9 not taken
1: branch 10 taken
176 1: if (!StoredDiag || FixIt >= StoredDiag->Info.getNumCodeModificationHints() ||
177 : StoredDiag->Info.getLocation().isInvalid())
178 0: return clang_getNullRange();
179 :
180 : const CodeModificationHint &Hint
181 1: = StoredDiag->Info.getCodeModificationHint(FixIt);
182 : return translateSourceRange(StoredDiag->Info.getLocation().getManager(),
183 : *StoredDiag->LangOptsPtr,
184 1: Hint.RemoveRange);
185 : }
186 :
187 : CXString clang_getDiagnosticFixItReplacement(CXDiagnostic Diag,
188 : unsigned FixIt,
189 1: CXSourceRange *Range) {
1: branch 0 taken
0: branch 1 not taken
190 1: if (Range)
191 1: *Range = clang_getNullRange();
192 :
193 1: CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
1: branch 0 taken
0: branch 1 not taken
1: branch 3 taken
0: branch 4 not taken
0: branch 7 not taken
1: branch 8 taken
0: branch 9 not taken
1: branch 10 taken
194 1: if (!StoredDiag || FixIt >= StoredDiag->Info.getNumCodeModificationHints() ||
195 : StoredDiag->Info.getLocation().isInvalid()) {
0: branch 0 not taken
0: branch 1 not taken
196 0: if (Range)
197 0: *Range = clang_getNullRange();
198 :
199 0: return CIndexer::createCXString("");
200 : }
201 :
202 : const CodeModificationHint &Hint
203 1: = StoredDiag->Info.getCodeModificationHint(FixIt);
1: branch 0 taken
0: branch 1 not taken
204 1: if (Range)
205 : *Range = translateSourceRange(StoredDiag->Info.getLocation().getManager(),
206 : *StoredDiag->LangOptsPtr,
207 1: Hint.RemoveRange);
208 1: return CIndexer::createCXString(Hint.CodeToInsert);
209 : }
210 :
211 : } // end extern "C"
212 :
213 : void clang::ReportSerializedDiagnostics(const llvm::sys::Path &DiagnosticsPath,
214 : Diagnostic &Diags,
215 : unsigned num_unsaved_files,
216 : struct CXUnsavedFile *unsaved_files,
217 52: const LangOptions &LangOpts) {
218 : using llvm::MemoryBuffer;
219 : using llvm::StringRef;
220 52: MemoryBuffer *F = MemoryBuffer::getFile(DiagnosticsPath.c_str());
0: branch 0 not taken
52: branch 1 taken
221 52: if (!F)
222 0: return;
223 :
224 : // Enter the unsaved files into the file manager.
225 52: SourceManager SourceMgr;
226 52: FileManager FileMgr;
2: branch 0 taken
52: branch 1 taken
227 54: for (unsigned I = 0; I != num_unsaved_files; ++I) {
228 : const FileEntry *File = FileMgr.getVirtualFile(unsaved_files[I].Filename,
229 : unsaved_files[I].Length,
230 2: 0);
0: branch 0 not taken
2: branch 1 taken
231 2: if (!File) {
232 : Diags.Report(diag::err_fe_remap_missing_from_file)
233 0: << unsaved_files[I].Filename;
234 19: return;
235 : }
236 :
237 : MemoryBuffer *Buffer
238 : = MemoryBuffer::getMemBuffer(unsaved_files[I].Contents,
239 2: unsaved_files[I].Contents + unsaved_files[I].Length);
0: branch 0 not taken
2: branch 1 taken
240 2: if (!Buffer)
241 : return;
242 :
243 2: SourceMgr.overrideFileContents(File, Buffer);
244 : }
245 :
246 52: Diags.getClient()->BeginSourceFile(LangOpts, 0);
247 :
248 : // Parse the diagnostics, emitting them one by one until we've
249 : // exhausted the data.
250 52: StringRef Buffer = F->getBuffer();
251 52: const char *Memory = Buffer.data(), *MemoryEnd = Memory + Buffer.size();
54: branch 1 taken
19: branch 2 taken
73: branch 3 taken
33: branch 4 taken
252 125: while (Memory != MemoryEnd) {
253 : DiagnosticBuilder DB = Diags.Deserialize(FileMgr, SourceMgr,
254 73: Memory, MemoryEnd);
19: branch 1 taken
54: branch 2 taken
255 73: if (!DB.isActive())
256 : return;
257 : }
258 :
33: branch 3 taken
19: branch 4 taken
33: branch 6 taken
19: branch 7 taken
259 33: Diags.getClient()->EndSourceFile();
260 : }
Generated: 2010-02-10 01:31 by zcov