blob: 67aa77027fa99a404b9ede5082a23f9ecf29d9a5 [file] [log] [blame]
Douglas Gregora88084b2010-02-18 18:08:43 +00001/*===-- CIndexDiagnostics.cpp - Diagnostics C Interface ---------*- C++ -*-===*\
Douglas Gregor5352ac02010-01-28 00:27:43 +00002|* *|
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"
Ted Kremenek0a90d322010-11-17 23:24:11 +000015#include "CXTranslationUnit.h"
Douglas Gregor5352ac02010-01-28 00:27:43 +000016#include "CXSourceLocation.h"
Ted Kremeneked122732010-11-16 01:56:27 +000017#include "CXString.h"
Douglas Gregor5352ac02010-01-28 00:27:43 +000018
Benjamin Kramerb846deb2010-04-12 19:45:50 +000019#include "clang/Frontend/ASTUnit.h"
Douglas Gregord93256e2010-01-28 06:00:51 +000020#include "clang/Frontend/FrontendDiagnostic.h"
Ted Kremenek7473b1c2012-02-14 02:46:03 +000021#include "clang/Frontend/DiagnosticRenderer.h"
22#include "clang/Frontend/DiagnosticOptions.h"
Douglas Gregor274f1902010-02-22 23:17:23 +000023#include "llvm/ADT/SmallString.h"
Douglas Gregora88084b2010-02-18 18:08:43 +000024#include "llvm/ADT/Twine.h"
Douglas Gregord93256e2010-01-28 06:00:51 +000025#include "llvm/Support/MemoryBuffer.h"
Douglas Gregor274f1902010-02-22 23:17:23 +000026#include "llvm/Support/raw_ostream.h"
Douglas Gregord93256e2010-01-28 06:00:51 +000027
Douglas Gregor5352ac02010-01-28 00:27:43 +000028using namespace clang;
29using namespace clang::cxloc;
Ted Kremenekee4db4f2010-02-17 00:41:08 +000030using namespace clang::cxstring;
Argyrios Kyrtzidis996e6e52011-12-01 02:42:50 +000031using namespace clang::cxdiag;
Douglas Gregora88084b2010-02-18 18:08:43 +000032using namespace llvm;
Douglas Gregor5352ac02010-01-28 00:27:43 +000033
Ted Kremenek15322172011-11-10 08:43:12 +000034
35CXDiagnosticSetImpl::~CXDiagnosticSetImpl() {
36 for (std::vector<CXDiagnosticImpl *>::iterator it = Diagnostics.begin(),
37 et = Diagnostics.end();
38 it != et; ++it) {
39 delete *it;
40 }
41}
42
43CXDiagnosticImpl::~CXDiagnosticImpl() {}
44
Ted Kremenek7473b1c2012-02-14 02:46:03 +000045namespace {
46class CXDiagnosticCustomNoteImpl : public CXDiagnosticImpl {
Ted Kremenek7b8290f2012-02-14 06:54:46 +000047 std::string Message;
Ted Kremenek7473b1c2012-02-14 02:46:03 +000048 CXSourceLocation Loc;
49public:
50 CXDiagnosticCustomNoteImpl(StringRef Msg, CXSourceLocation L)
51 : CXDiagnosticImpl(CustomNoteDiagnosticKind),
Ted Kremenek7b8290f2012-02-14 06:54:46 +000052 Message(Msg), Loc(L) {}
Ted Kremenek7473b1c2012-02-14 02:46:03 +000053
Ted Kremenek7b8290f2012-02-14 06:54:46 +000054 virtual ~CXDiagnosticCustomNoteImpl() {}
Ted Kremenek7473b1c2012-02-14 02:46:03 +000055
56 CXDiagnosticSeverity getSeverity() const {
57 return CXDiagnostic_Note;
58 }
59
60 CXSourceLocation getLocation() const {
61 return Loc;
62 }
63
64 CXString getSpelling() const {
Ted Kremenek7b8290f2012-02-14 06:54:46 +000065 return createCXString(StringRef(Message), false);
Ted Kremenek7473b1c2012-02-14 02:46:03 +000066 }
67
68 CXString getDiagnosticOption(CXString *Disable) const {
69 if (Disable)
70 *Disable = createCXString("", false);
71 return createCXString("", false);
72 }
73
74 unsigned getCategory() const { return 0; }
75 unsigned getNumRanges() const { return 0; }
76 CXSourceRange getRange(unsigned Range) const { return clang_getNullRange(); }
77 unsigned getNumFixIts() const { return 0; }
78 CXString getFixIt(unsigned FixIt, CXSourceRange *ReplacementRange) const {
79 if (ReplacementRange)
80 *ReplacementRange = clang_getNullRange();
81 return createCXString("", false);
82 }
83};
84
85class CXDiagnosticRenderer : public DiagnosticNoteRenderer {
86public:
87 CXDiagnosticRenderer(const SourceManager &SM,
88 const LangOptions &LangOpts,
89 const DiagnosticOptions &DiagOpts,
90 CXDiagnosticSetImpl *mainSet)
91 : DiagnosticNoteRenderer(SM, LangOpts, DiagOpts),
92 CurrentSet(mainSet), MainSet(mainSet) {}
93
94 virtual ~CXDiagnosticRenderer() {}
95
96 virtual void beginDiagnostic(DiagOrStoredDiag D,
97 DiagnosticsEngine::Level Level) {
98
99 const StoredDiagnostic *SD = D.dyn_cast<const StoredDiagnostic*>();
100 if (!SD)
101 return;
102
103 if (Level != DiagnosticsEngine::Note)
104 CurrentSet = MainSet;
105
106 CXStoredDiagnostic *CD = new CXStoredDiagnostic(*SD, LangOpts);
107 CurrentSet->appendDiagnostic(CD);
108
109 if (Level != DiagnosticsEngine::Note)
110 CurrentSet = &CD->getChildDiagnostics();
111 }
112
113 virtual void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc,
114 DiagnosticsEngine::Level Level,
115 StringRef Message,
116 ArrayRef<CharSourceRange> Ranges,
117 DiagOrStoredDiag D) {
118 if (!D.isNull())
119 return;
120
121 CXSourceLocation L = translateSourceLocation(SM, LangOpts, Loc);
122 CXDiagnosticImpl *CD = new CXDiagnosticCustomNoteImpl(Message, L);
123 CurrentSet->appendDiagnostic(CD);
124 }
125
126 virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
127 DiagnosticsEngine::Level Level,
128 ArrayRef<CharSourceRange> Ranges) {}
129
130 virtual void emitCodeContext(SourceLocation Loc,
131 DiagnosticsEngine::Level Level,
132 SmallVectorImpl<CharSourceRange>& Ranges,
Daniel Dunbarfc399c72012-02-29 00:20:42 +0000133 ArrayRef<FixItHint> Hints) {}
Ted Kremenek7473b1c2012-02-14 02:46:03 +0000134
135 virtual void emitNote(SourceLocation Loc, StringRef Message) {
136 CXSourceLocation L = translateSourceLocation(SM, LangOpts, Loc);
137 CurrentSet->appendDiagnostic(new CXDiagnosticCustomNoteImpl(Message,
138 L));
139 }
140
141 CXDiagnosticSetImpl *CurrentSet;
142 CXDiagnosticSetImpl *MainSet;
143};
144}
145
Argyrios Kyrtzidis996e6e52011-12-01 02:42:50 +0000146CXDiagnosticSetImpl *cxdiag::lazyCreateDiags(CXTranslationUnit TU,
147 bool checkIfChanged) {
Argyrios Kyrtzidis220b45c2011-11-16 02:34:55 +0000148 ASTUnit *AU = static_cast<ASTUnit *>(TU->TUData);
149
150 if (TU->Diagnostics && checkIfChanged) {
Argyrios Kyrtzidisc88e58c2011-11-16 08:59:00 +0000151 // In normal use, ASTUnit's diagnostics should not change unless we reparse.
152 // Currently they can only change by using the internal testing flag
153 // '-error-on-deserialized-decl' which will error during deserialization of
154 // a declaration. What will happen is:
155 //
156 // -c-index-test gets a CXTranslationUnit
157 // -checks the diagnostics, the diagnostics set is lazily created,
158 // no errors are reported
159 // -later does an operation, like annotation of tokens, that triggers
160 // -error-on-deserialized-decl, that will emit a diagnostic error,
161 // that ASTUnit will catch and add to its stored diagnostics vector.
162 // -c-index-test wants to check whether an error occurred after performing
163 // the operation but can only query the lazily created set.
164 //
165 // We check here if a new diagnostic was appended since the last time the
166 // diagnostic set was created, in which case we reset it.
167
Argyrios Kyrtzidis220b45c2011-11-16 02:34:55 +0000168 CXDiagnosticSetImpl *
169 Set = static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
170 if (AU->stored_diag_size() != Set->getNumDiagnostics()) {
171 // Diagnostics in the ASTUnit were updated, reset the associated
172 // diagnostics.
173 delete Set;
174 TU->Diagnostics = 0;
175 }
176 }
177
Ted Kremenek15322172011-11-10 08:43:12 +0000178 if (!TU->Diagnostics) {
Ted Kremenek15322172011-11-10 08:43:12 +0000179 CXDiagnosticSetImpl *Set = new CXDiagnosticSetImpl();
180 TU->Diagnostics = Set;
Ted Kremenek7473b1c2012-02-14 02:46:03 +0000181 DiagnosticOptions DOpts;
182 CXDiagnosticRenderer Renderer(AU->getSourceManager(),
David Blaikie4e4d0842012-03-11 07:00:24 +0000183 AU->getASTContext().getLangOpts(),
Ted Kremenek7473b1c2012-02-14 02:46:03 +0000184 DOpts, Set);
Ted Kremenek15322172011-11-10 08:43:12 +0000185
186 for (ASTUnit::stored_diag_iterator it = AU->stored_diag_begin(),
187 ei = AU->stored_diag_end(); it != ei; ++it) {
Ted Kremenek7473b1c2012-02-14 02:46:03 +0000188 Renderer.emitStoredDiagnostic(*it);
Ted Kremenek15322172011-11-10 08:43:12 +0000189 }
190 }
191 return static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
192}
193
Douglas Gregor5352ac02010-01-28 00:27:43 +0000194//-----------------------------------------------------------------------------
Ted Kremenekee4db4f2010-02-17 00:41:08 +0000195// C Interface Routines
Douglas Gregor5352ac02010-01-28 00:27:43 +0000196//-----------------------------------------------------------------------------
197extern "C" {
Ted Kremenekee4db4f2010-02-17 00:41:08 +0000198
Douglas Gregora88084b2010-02-18 18:08:43 +0000199unsigned clang_getNumDiagnostics(CXTranslationUnit Unit) {
Ted Kremenek15322172011-11-10 08:43:12 +0000200 if (!Unit->TUData)
201 return 0;
Argyrios Kyrtzidis220b45c2011-11-16 02:34:55 +0000202 return lazyCreateDiags(Unit, /*checkIfChanged=*/true)->getNumDiagnostics();
Douglas Gregora88084b2010-02-18 18:08:43 +0000203}
204
205CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, unsigned Index) {
Ted Kremenek0373fcc2011-12-09 22:28:32 +0000206 CXDiagnosticSet D = clang_getDiagnosticSetFromTU(Unit);
207 if (!D)
Douglas Gregora88084b2010-02-18 18:08:43 +0000208 return 0;
209
Ted Kremenek0373fcc2011-12-09 22:28:32 +0000210 CXDiagnosticSetImpl *Diags = static_cast<CXDiagnosticSetImpl*>(D);
Ted Kremenek15322172011-11-10 08:43:12 +0000211 if (Index >= Diags->getNumDiagnostics())
212 return 0;
213
214 return Diags->getDiagnostic(Index);
Douglas Gregora88084b2010-02-18 18:08:43 +0000215}
Ted Kremenek0373fcc2011-12-09 22:28:32 +0000216
217CXDiagnosticSet clang_getDiagnosticSetFromTU(CXTranslationUnit Unit) {
218 if (!Unit->TUData)
219 return 0;
220 return static_cast<CXDiagnostic>(lazyCreateDiags(Unit));
221}
Douglas Gregora88084b2010-02-18 18:08:43 +0000222
223void clang_disposeDiagnostic(CXDiagnostic Diagnostic) {
Ted Kremenek15322172011-11-10 08:43:12 +0000224 // No-op. Kept as a legacy API. CXDiagnostics are now managed
225 // by the enclosing CXDiagnosticSet.
Douglas Gregora88084b2010-02-18 18:08:43 +0000226}
227
Douglas Gregor274f1902010-02-22 23:17:23 +0000228CXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options) {
229 if (!Diagnostic)
230 return createCXString("");
Douglas Gregor0a812cf2010-02-18 23:07:20 +0000231
232 CXDiagnosticSeverity Severity = clang_getDiagnosticSeverity(Diagnostic);
233
Dylan Noblesmith36d59272012-02-13 12:32:26 +0000234 SmallString<256> Str;
Douglas Gregor274f1902010-02-22 23:17:23 +0000235 llvm::raw_svector_ostream Out(Str);
236
Douglas Gregor0a812cf2010-02-18 23:07:20 +0000237 if (Options & CXDiagnostic_DisplaySourceLocation) {
238 // Print source location (file:line), along with optional column
239 // and source ranges.
240 CXFile File;
241 unsigned Line, Column;
Douglas Gregora9b06d42010-11-09 06:24:54 +0000242 clang_getSpellingLocation(clang_getDiagnosticLocation(Diagnostic),
243 &File, &Line, &Column, 0);
Douglas Gregor0a812cf2010-02-18 23:07:20 +0000244 if (File) {
245 CXString FName = clang_getFileName(File);
Douglas Gregor274f1902010-02-22 23:17:23 +0000246 Out << clang_getCString(FName) << ":" << Line << ":";
Douglas Gregor0a812cf2010-02-18 23:07:20 +0000247 clang_disposeString(FName);
248 if (Options & CXDiagnostic_DisplayColumn)
Douglas Gregor274f1902010-02-22 23:17:23 +0000249 Out << Column << ":";
Douglas Gregor0a812cf2010-02-18 23:07:20 +0000250
251 if (Options & CXDiagnostic_DisplaySourceRanges) {
252 unsigned N = clang_getDiagnosticNumRanges(Diagnostic);
253 bool PrintedRange = false;
254 for (unsigned I = 0; I != N; ++I) {
255 CXFile StartFile, EndFile;
256 CXSourceRange Range = clang_getDiagnosticRange(Diagnostic, I);
257
258 unsigned StartLine, StartColumn, EndLine, EndColumn;
Douglas Gregora9b06d42010-11-09 06:24:54 +0000259 clang_getSpellingLocation(clang_getRangeStart(Range),
260 &StartFile, &StartLine, &StartColumn,
261 0);
262 clang_getSpellingLocation(clang_getRangeEnd(Range),
263 &EndFile, &EndLine, &EndColumn, 0);
Douglas Gregor0a812cf2010-02-18 23:07:20 +0000264
265 if (StartFile != EndFile || StartFile != File)
266 continue;
267
Douglas Gregor274f1902010-02-22 23:17:23 +0000268 Out << "{" << StartLine << ":" << StartColumn << "-"
269 << EndLine << ":" << EndColumn << "}";
Douglas Gregor0a812cf2010-02-18 23:07:20 +0000270 PrintedRange = true;
271 }
272 if (PrintedRange)
Douglas Gregor274f1902010-02-22 23:17:23 +0000273 Out << ":";
Douglas Gregor0a812cf2010-02-18 23:07:20 +0000274 }
Douglas Gregor4cd912a2010-10-12 00:50:20 +0000275
276 Out << " ";
Douglas Gregor0a812cf2010-02-18 23:07:20 +0000277 }
Douglas Gregor0a812cf2010-02-18 23:07:20 +0000278 }
279
280 /* Print warning/error/etc. */
281 switch (Severity) {
David Blaikieeb2d1f12011-09-23 20:26:49 +0000282 case CXDiagnostic_Ignored: llvm_unreachable("impossible");
Douglas Gregor274f1902010-02-22 23:17:23 +0000283 case CXDiagnostic_Note: Out << "note: "; break;
284 case CXDiagnostic_Warning: Out << "warning: "; break;
285 case CXDiagnostic_Error: Out << "error: "; break;
286 case CXDiagnostic_Fatal: Out << "fatal error: "; break;
Douglas Gregor0a812cf2010-02-18 23:07:20 +0000287 }
288
289 CXString Text = clang_getDiagnosticSpelling(Diagnostic);
290 if (clang_getCString(Text))
Douglas Gregor274f1902010-02-22 23:17:23 +0000291 Out << clang_getCString(Text);
Douglas Gregor0a812cf2010-02-18 23:07:20 +0000292 else
Douglas Gregor274f1902010-02-22 23:17:23 +0000293 Out << "<no diagnostic text>";
Douglas Gregor0a812cf2010-02-18 23:07:20 +0000294 clang_disposeString(Text);
Douglas Gregoraa5f1352010-11-19 16:18:16 +0000295
296 if (Options & (CXDiagnostic_DisplayOption | CXDiagnostic_DisplayCategoryId |
297 CXDiagnostic_DisplayCategoryName)) {
298 bool NeedBracket = true;
299 bool NeedComma = false;
300
301 if (Options & CXDiagnostic_DisplayOption) {
302 CXString OptionName = clang_getDiagnosticOption(Diagnostic, 0);
303 if (const char *OptionText = clang_getCString(OptionName)) {
304 if (OptionText[0]) {
305 Out << " [" << OptionText;
306 NeedBracket = false;
307 NeedComma = true;
308 }
309 }
310 clang_disposeString(OptionName);
311 }
312
313 if (Options & (CXDiagnostic_DisplayCategoryId |
314 CXDiagnostic_DisplayCategoryName)) {
315 if (unsigned CategoryID = clang_getDiagnosticCategory(Diagnostic)) {
316 if (Options & CXDiagnostic_DisplayCategoryId) {
317 if (NeedBracket)
318 Out << " [";
319 if (NeedComma)
320 Out << ", ";
321 Out << CategoryID;
322 NeedBracket = false;
323 NeedComma = true;
324 }
325
326 if (Options & CXDiagnostic_DisplayCategoryName) {
327 CXString CategoryName = clang_getDiagnosticCategoryName(CategoryID);
328 if (NeedBracket)
329 Out << " [";
330 if (NeedComma)
331 Out << ", ";
332 Out << clang_getCString(CategoryName);
333 NeedBracket = false;
334 NeedComma = true;
335 clang_disposeString(CategoryName);
336 }
337 }
338 }
339
340 if (!NeedBracket)
341 Out << "]";
342 }
343
Douglas Gregor274f1902010-02-22 23:17:23 +0000344 return createCXString(Out.str(), true);
Douglas Gregor0a812cf2010-02-18 23:07:20 +0000345}
346
347unsigned clang_defaultDiagnosticDisplayOptions() {
Douglas Gregoraa5f1352010-11-19 16:18:16 +0000348 return CXDiagnostic_DisplaySourceLocation | CXDiagnostic_DisplayColumn |
349 CXDiagnostic_DisplayOption;
Douglas Gregor0a812cf2010-02-18 23:07:20 +0000350}
351
Douglas Gregor5352ac02010-01-28 00:27:43 +0000352enum CXDiagnosticSeverity clang_getDiagnosticSeverity(CXDiagnostic Diag) {
Ted Kremenek1edabbc2011-10-31 21:40:19 +0000353 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl*>(Diag))
354 return D->getSeverity();
Douglas Gregor5352ac02010-01-28 00:27:43 +0000355 return CXDiagnostic_Ignored;
356}
Ted Kremenekee4db4f2010-02-17 00:41:08 +0000357
Douglas Gregor5352ac02010-01-28 00:27:43 +0000358CXSourceLocation clang_getDiagnosticLocation(CXDiagnostic Diag) {
Ted Kremenek1edabbc2011-10-31 21:40:19 +0000359 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl*>(Diag))
360 return D->getLocation();
361 return clang_getNullLocation();
Douglas Gregor5352ac02010-01-28 00:27:43 +0000362}
363
364CXString clang_getDiagnosticSpelling(CXDiagnostic Diag) {
Ted Kremenek1edabbc2011-10-31 21:40:19 +0000365 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
366 return D->getSpelling();
367 return createCXString("");
Douglas Gregor5352ac02010-01-28 00:27:43 +0000368}
369
Douglas Gregoraa5f1352010-11-19 16:18:16 +0000370CXString clang_getDiagnosticOption(CXDiagnostic Diag, CXString *Disable) {
371 if (Disable)
372 *Disable = createCXString("");
Ted Kremenek1edabbc2011-10-31 21:40:19 +0000373
374 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
375 return D->getDiagnosticOption(Disable);
Douglas Gregoraa5f1352010-11-19 16:18:16 +0000376
377 return createCXString("");
378}
379
380unsigned clang_getDiagnosticCategory(CXDiagnostic Diag) {
Ted Kremenek1edabbc2011-10-31 21:40:19 +0000381 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
382 return D->getCategory();
383 return 0;
Douglas Gregoraa5f1352010-11-19 16:18:16 +0000384}
385
386CXString clang_getDiagnosticCategoryName(unsigned Category) {
387 return createCXString(DiagnosticIDs::getCategoryNameFromID(Category));
388}
389
Douglas Gregora3890ba2010-02-08 23:11:56 +0000390unsigned clang_getDiagnosticNumRanges(CXDiagnostic Diag) {
Ted Kremenek1edabbc2011-10-31 21:40:19 +0000391 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
392 return D->getNumRanges();
393 return 0;
Douglas Gregor5352ac02010-01-28 00:27:43 +0000394}
Ted Kremenekee4db4f2010-02-17 00:41:08 +0000395
Douglas Gregora3890ba2010-02-08 23:11:56 +0000396CXSourceRange clang_getDiagnosticRange(CXDiagnostic Diag, unsigned Range) {
Ted Kremenek1edabbc2011-10-31 21:40:19 +0000397 CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag);
398 if (!D || Range >= D->getNumRanges())
Douglas Gregora3890ba2010-02-08 23:11:56 +0000399 return clang_getNullRange();
Ted Kremenek1edabbc2011-10-31 21:40:19 +0000400 return D->getRange(Range);
Douglas Gregor5352ac02010-01-28 00:27:43 +0000401}
402
403unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diag) {
Ted Kremenek1edabbc2011-10-31 21:40:19 +0000404 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
405 return D->getNumFixIts();
406 return 0;
Douglas Gregor5352ac02010-01-28 00:27:43 +0000407}
408
Ted Kremenek1edabbc2011-10-31 21:40:19 +0000409CXString clang_getDiagnosticFixIt(CXDiagnostic Diag, unsigned FixIt,
Douglas Gregor473d7012010-02-19 18:16:06 +0000410 CXSourceRange *ReplacementRange) {
Ted Kremenek1edabbc2011-10-31 21:40:19 +0000411 CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag);
412 if (!D || FixIt >= D->getNumFixIts()) {
Douglas Gregor473d7012010-02-19 18:16:06 +0000413 if (ReplacementRange)
414 *ReplacementRange = clang_getNullRange();
Ted Kremenekee4db4f2010-02-17 00:41:08 +0000415 return createCXString("");
Douglas Gregor5352ac02010-01-28 00:27:43 +0000416 }
Ted Kremenek1edabbc2011-10-31 21:40:19 +0000417 return D->getFixIt(FixIt, ReplacementRange);
Douglas Gregor5352ac02010-01-28 00:27:43 +0000418}
Ted Kremenekee4db4f2010-02-17 00:41:08 +0000419
Ted Kremenek15322172011-11-10 08:43:12 +0000420void clang_disposeDiagnosticSet(CXDiagnosticSet Diags) {
421 CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags);
422 if (D->isExternallyManaged())
423 delete D;
424}
425
426CXDiagnostic clang_getDiagnosticInSet(CXDiagnosticSet Diags,
427 unsigned Index) {
428 if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags))
429 if (Index < D->getNumDiagnostics())
430 return D->getDiagnostic(Index);
431 return 0;
432}
433
434CXDiagnosticSet clang_getChildDiagnostics(CXDiagnostic Diag) {
435 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag)) {
436 CXDiagnosticSetImpl &ChildDiags = D->getChildDiagnostics();
437 return ChildDiags.empty() ? 0 : (CXDiagnosticSet) &ChildDiags;
438 }
439 return 0;
440}
441
442unsigned clang_getNumDiagnosticsInSet(CXDiagnosticSet Diags) {
443 if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags))
444 return D->getNumDiagnostics();
445 return 0;
446}
447
Douglas Gregor5352ac02010-01-28 00:27:43 +0000448} // end extern "C"