blob: 18031e53bf9978e4902c4f68b645fd46d0e044a8 [file] [log] [blame]
Douglas Gregor33cdd812010-02-18 18:08:43 +00001/*===-- CIndexDiagnostics.cpp - Diagnostics C Interface ---------*- C++ -*-===*\
Douglas Gregor4f9c3762010-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 Kremenek7df92ae2010-11-17 23:24:11 +000015#include "CXTranslationUnit.h"
Douglas Gregor4f9c3762010-01-28 00:27:43 +000016#include "CXSourceLocation.h"
Ted Kremenek4b4f3692010-11-16 01:56:27 +000017#include "CXString.h"
Douglas Gregor4f9c3762010-01-28 00:27:43 +000018
Douglas Gregor811db4e2012-10-23 22:26:28 +000019#include "clang/Basic/DiagnosticOptions.h"
Mehdi Amini9670f842016-07-18 19:02:11 +000020#include "clang/Frontend/ASTUnit.h"
21#include "clang/Frontend/DiagnosticRenderer.h"
22#include "clang/Frontend/FrontendDiagnostic.h"
Douglas Gregord770f732010-02-22 23:17:23 +000023#include "llvm/ADT/SmallString.h"
Douglas Gregord770f732010-02-22 23:17:23 +000024#include "llvm/Support/raw_ostream.h"
Douglas Gregorac0605e2010-01-28 06:00:51 +000025
Douglas Gregor4f9c3762010-01-28 00:27:43 +000026using namespace clang;
27using namespace clang::cxloc;
Argyrios Kyrtzidisf2d99b02011-12-01 02:42:50 +000028using namespace clang::cxdiag;
Douglas Gregor33cdd812010-02-18 18:08:43 +000029using namespace llvm;
Douglas Gregor4f9c3762010-01-28 00:27:43 +000030
Angel Garcia Gomez637d1e62015-10-20 13:23:58 +000031CXDiagnosticSetImpl::~CXDiagnosticSetImpl() {}
Ted Kremenekd010ba42011-11-10 08:43:12 +000032
David Blaikie759548b2014-08-29 18:43:24 +000033void
34CXDiagnosticSetImpl::appendDiagnostic(std::unique_ptr<CXDiagnosticImpl> D) {
35 Diagnostics.push_back(std::move(D));
Ted Kremenekd010ba42011-11-10 08:43:12 +000036}
37
Angel Garcia Gomez637d1e62015-10-20 13:23:58 +000038CXDiagnosticImpl::~CXDiagnosticImpl() {}
Ted Kremenekd010ba42011-11-10 08:43:12 +000039
Ted Kremenek914c7e62012-02-14 02:46:03 +000040namespace {
41class CXDiagnosticCustomNoteImpl : public CXDiagnosticImpl {
Ted Kremenekb05119c2012-02-14 06:54:46 +000042 std::string Message;
Ted Kremenek914c7e62012-02-14 02:46:03 +000043 CXSourceLocation Loc;
44public:
45 CXDiagnosticCustomNoteImpl(StringRef Msg, CXSourceLocation L)
46 : CXDiagnosticImpl(CustomNoteDiagnosticKind),
Ted Kremenekb05119c2012-02-14 06:54:46 +000047 Message(Msg), Loc(L) {}
Ted Kremenek914c7e62012-02-14 02:46:03 +000048
Angel Garcia Gomez637d1e62015-10-20 13:23:58 +000049 ~CXDiagnosticCustomNoteImpl() override {}
Craig Topper36835562014-03-15 07:47:46 +000050
51 CXDiagnosticSeverity getSeverity() const override {
Ted Kremenek914c7e62012-02-14 02:46:03 +000052 return CXDiagnostic_Note;
53 }
Craig Topper36835562014-03-15 07:47:46 +000054
55 CXSourceLocation getLocation() const override {
Ted Kremenek914c7e62012-02-14 02:46:03 +000056 return Loc;
57 }
Craig Topper36835562014-03-15 07:47:46 +000058
59 CXString getSpelling() const override {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +000060 return cxstring::createRef(Message.c_str());
Ted Kremenek914c7e62012-02-14 02:46:03 +000061 }
Craig Topper36835562014-03-15 07:47:46 +000062
63 CXString getDiagnosticOption(CXString *Disable) const override {
Ted Kremenek914c7e62012-02-14 02:46:03 +000064 if (Disable)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +000065 *Disable = cxstring::createEmpty();
66 return cxstring::createEmpty();
Ted Kremenek914c7e62012-02-14 02:46:03 +000067 }
Ted Kremenek26a6d492012-04-12 00:03:31 +000068
Craig Topper36835562014-03-15 07:47:46 +000069 unsigned getCategory() const override { return 0; }
70 CXString getCategoryText() const override { return cxstring::createEmpty(); }
71
72 unsigned getNumRanges() const override { return 0; }
73 CXSourceRange getRange(unsigned Range) const override {
74 return clang_getNullRange();
75 }
76 unsigned getNumFixIts() const override { return 0; }
77 CXString getFixIt(unsigned FixIt,
78 CXSourceRange *ReplacementRange) const override {
Ted Kremenek914c7e62012-02-14 02:46:03 +000079 if (ReplacementRange)
80 *ReplacementRange = clang_getNullRange();
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +000081 return cxstring::createEmpty();
Ted Kremenek914c7e62012-02-14 02:46:03 +000082 }
83};
84
85class CXDiagnosticRenderer : public DiagnosticNoteRenderer {
86public:
Argyrios Kyrtzidisb16ff5d2012-05-10 05:03:45 +000087 CXDiagnosticRenderer(const LangOptions &LangOpts,
Douglas Gregor811db4e2012-10-23 22:26:28 +000088 DiagnosticOptions *DiagOpts,
Ted Kremenek914c7e62012-02-14 02:46:03 +000089 CXDiagnosticSetImpl *mainSet)
Argyrios Kyrtzidisb16ff5d2012-05-10 05:03:45 +000090 : DiagnosticNoteRenderer(LangOpts, DiagOpts),
Ted Kremenek914c7e62012-02-14 02:46:03 +000091 CurrentSet(mainSet), MainSet(mainSet) {}
Alexander Kornienko34eb2072015-04-11 02:00:23 +000092
Angel Garcia Gomez637d1e62015-10-20 13:23:58 +000093 ~CXDiagnosticRenderer() override {}
Ted Kremenek914c7e62012-02-14 02:46:03 +000094
Craig Topper36835562014-03-15 07:47:46 +000095 void beginDiagnostic(DiagOrStoredDiag D,
96 DiagnosticsEngine::Level Level) override {
97
Ted Kremenek914c7e62012-02-14 02:46:03 +000098 const StoredDiagnostic *SD = D.dyn_cast<const StoredDiagnostic*>();
99 if (!SD)
100 return;
101
102 if (Level != DiagnosticsEngine::Note)
103 CurrentSet = MainSet;
David Blaikie759548b2014-08-29 18:43:24 +0000104
105 auto Owner = llvm::make_unique<CXStoredDiagnostic>(*SD, LangOpts);
106 CXStoredDiagnostic &CD = *Owner;
107 CurrentSet->appendDiagnostic(std::move(Owner));
108
Ted Kremenek914c7e62012-02-14 02:46:03 +0000109 if (Level != DiagnosticsEngine::Note)
David Blaikie759548b2014-08-29 18:43:24 +0000110 CurrentSet = &CD.getChildDiagnostics();
Ted Kremenek914c7e62012-02-14 02:46:03 +0000111 }
Craig Topper36835562014-03-15 07:47:46 +0000112
113 void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc,
114 DiagnosticsEngine::Level Level,
115 StringRef Message,
116 ArrayRef<CharSourceRange> Ranges,
117 const SourceManager *SM,
118 DiagOrStoredDiag D) override {
Ted Kremenek914c7e62012-02-14 02:46:03 +0000119 if (!D.isNull())
120 return;
121
Argyrios Kyrtzidisb16ff5d2012-05-10 05:03:45 +0000122 CXSourceLocation L;
123 if (SM)
124 L = translateSourceLocation(*SM, LangOpts, Loc);
125 else
126 L = clang_getNullLocation();
David Blaikie759548b2014-08-29 18:43:24 +0000127 CurrentSet->appendDiagnostic(
128 llvm::make_unique<CXDiagnosticCustomNoteImpl>(Message, L));
Ted Kremenek914c7e62012-02-14 02:46:03 +0000129 }
Ted Kremenek914c7e62012-02-14 02:46:03 +0000130
Craig Topper36835562014-03-15 07:47:46 +0000131 void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
132 DiagnosticsEngine::Level Level,
133 ArrayRef<CharSourceRange> Ranges,
134 const SourceManager &SM) override {}
135
136 void emitCodeContext(SourceLocation Loc,
137 DiagnosticsEngine::Level Level,
138 SmallVectorImpl<CharSourceRange>& Ranges,
139 ArrayRef<FixItHint> Hints,
140 const SourceManager &SM) override {}
141
142 void emitNote(SourceLocation Loc, StringRef Message,
143 const SourceManager *SM) override {
Argyrios Kyrtzidisb16ff5d2012-05-10 05:03:45 +0000144 CXSourceLocation L;
145 if (SM)
146 L = translateSourceLocation(*SM, LangOpts, Loc);
147 else
148 L = clang_getNullLocation();
David Blaikie759548b2014-08-29 18:43:24 +0000149 CurrentSet->appendDiagnostic(
150 llvm::make_unique<CXDiagnosticCustomNoteImpl>(Message, L));
Ted Kremenek914c7e62012-02-14 02:46:03 +0000151 }
152
153 CXDiagnosticSetImpl *CurrentSet;
154 CXDiagnosticSetImpl *MainSet;
155};
Alexander Kornienkoab9db512015-06-22 23:07:51 +0000156}
Ted Kremenek914c7e62012-02-14 02:46:03 +0000157
Argyrios Kyrtzidisf2d99b02011-12-01 02:42:50 +0000158CXDiagnosticSetImpl *cxdiag::lazyCreateDiags(CXTranslationUnit TU,
159 bool checkIfChanged) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000160 ASTUnit *AU = cxtu::getASTUnit(TU);
Argyrios Kyrtzidisf03e7342011-11-16 02:34:55 +0000161
162 if (TU->Diagnostics && checkIfChanged) {
Argyrios Kyrtzidis7ae5d9c2011-11-16 08:59:00 +0000163 // In normal use, ASTUnit's diagnostics should not change unless we reparse.
164 // Currently they can only change by using the internal testing flag
165 // '-error-on-deserialized-decl' which will error during deserialization of
166 // a declaration. What will happen is:
167 //
168 // -c-index-test gets a CXTranslationUnit
169 // -checks the diagnostics, the diagnostics set is lazily created,
170 // no errors are reported
171 // -later does an operation, like annotation of tokens, that triggers
172 // -error-on-deserialized-decl, that will emit a diagnostic error,
173 // that ASTUnit will catch and add to its stored diagnostics vector.
174 // -c-index-test wants to check whether an error occurred after performing
175 // the operation but can only query the lazily created set.
176 //
177 // We check here if a new diagnostic was appended since the last time the
178 // diagnostic set was created, in which case we reset it.
179
Argyrios Kyrtzidisf03e7342011-11-16 02:34:55 +0000180 CXDiagnosticSetImpl *
181 Set = static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
182 if (AU->stored_diag_size() != Set->getNumDiagnostics()) {
183 // Diagnostics in the ASTUnit were updated, reset the associated
184 // diagnostics.
185 delete Set;
Craig Topper69186e72014-06-08 08:38:04 +0000186 TU->Diagnostics = nullptr;
Argyrios Kyrtzidisf03e7342011-11-16 02:34:55 +0000187 }
188 }
189
Ted Kremenekd010ba42011-11-10 08:43:12 +0000190 if (!TU->Diagnostics) {
Ted Kremenekd010ba42011-11-10 08:43:12 +0000191 CXDiagnosticSetImpl *Set = new CXDiagnosticSetImpl();
192 TU->Diagnostics = Set;
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000193 IntrusiveRefCntPtr<DiagnosticOptions> DOpts = new DiagnosticOptions;
Argyrios Kyrtzidisb16ff5d2012-05-10 05:03:45 +0000194 CXDiagnosticRenderer Renderer(AU->getASTContext().getLangOpts(),
Douglas Gregor811db4e2012-10-23 22:26:28 +0000195 &*DOpts, Set);
Ted Kremenekd010ba42011-11-10 08:43:12 +0000196
197 for (ASTUnit::stored_diag_iterator it = AU->stored_diag_begin(),
198 ei = AU->stored_diag_end(); it != ei; ++it) {
Ted Kremenek914c7e62012-02-14 02:46:03 +0000199 Renderer.emitStoredDiagnostic(*it);
Ted Kremenekd010ba42011-11-10 08:43:12 +0000200 }
201 }
202 return static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
203}
204
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000205//-----------------------------------------------------------------------------
Ted Kremenek5cca6eb2010-02-17 00:41:08 +0000206// C Interface Routines
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000207//-----------------------------------------------------------------------------
208extern "C" {
Ted Kremenek5cca6eb2010-02-17 00:41:08 +0000209
Douglas Gregor33cdd812010-02-18 18:08:43 +0000210unsigned clang_getNumDiagnostics(CXTranslationUnit Unit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +0000211 if (cxtu::isNotUsableTU(Unit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +0000212 LOG_BAD_TU(Unit);
213 return 0;
214 }
Dmitri Gribenkod36209e2013-01-26 21:32:42 +0000215 if (!cxtu::getASTUnit(Unit))
Ted Kremenekd010ba42011-11-10 08:43:12 +0000216 return 0;
Argyrios Kyrtzidisf03e7342011-11-16 02:34:55 +0000217 return lazyCreateDiags(Unit, /*checkIfChanged=*/true)->getNumDiagnostics();
Douglas Gregor33cdd812010-02-18 18:08:43 +0000218}
219
220CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +0000221 if (cxtu::isNotUsableTU(Unit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +0000222 LOG_BAD_TU(Unit);
Craig Topper69186e72014-06-08 08:38:04 +0000223 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +0000224 }
225
Ted Kremenekb4a8b052011-12-09 22:28:32 +0000226 CXDiagnosticSet D = clang_getDiagnosticSetFromTU(Unit);
227 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +0000228 return nullptr;
Douglas Gregor33cdd812010-02-18 18:08:43 +0000229
Ted Kremenekb4a8b052011-12-09 22:28:32 +0000230 CXDiagnosticSetImpl *Diags = static_cast<CXDiagnosticSetImpl*>(D);
Ted Kremenekd010ba42011-11-10 08:43:12 +0000231 if (Index >= Diags->getNumDiagnostics())
Craig Topper69186e72014-06-08 08:38:04 +0000232 return nullptr;
Ted Kremenekd010ba42011-11-10 08:43:12 +0000233
234 return Diags->getDiagnostic(Index);
Douglas Gregor33cdd812010-02-18 18:08:43 +0000235}
Dmitri Gribenko256454f2014-02-11 14:34:14 +0000236
Ted Kremenekb4a8b052011-12-09 22:28:32 +0000237CXDiagnosticSet clang_getDiagnosticSetFromTU(CXTranslationUnit Unit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +0000238 if (cxtu::isNotUsableTU(Unit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +0000239 LOG_BAD_TU(Unit);
Craig Topper69186e72014-06-08 08:38:04 +0000240 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +0000241 }
Dmitri Gribenkod36209e2013-01-26 21:32:42 +0000242 if (!cxtu::getASTUnit(Unit))
Craig Topper69186e72014-06-08 08:38:04 +0000243 return nullptr;
Ted Kremenekb4a8b052011-12-09 22:28:32 +0000244 return static_cast<CXDiagnostic>(lazyCreateDiags(Unit));
245}
Douglas Gregor33cdd812010-02-18 18:08:43 +0000246
247void clang_disposeDiagnostic(CXDiagnostic Diagnostic) {
Ted Kremenekd010ba42011-11-10 08:43:12 +0000248 // No-op. Kept as a legacy API. CXDiagnostics are now managed
249 // by the enclosing CXDiagnosticSet.
Douglas Gregor33cdd812010-02-18 18:08:43 +0000250}
251
Douglas Gregord770f732010-02-22 23:17:23 +0000252CXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options) {
253 if (!Diagnostic)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +0000254 return cxstring::createEmpty();
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000255
256 CXDiagnosticSeverity Severity = clang_getDiagnosticSeverity(Diagnostic);
257
Dylan Noblesmithf1a13f22012-02-13 12:32:26 +0000258 SmallString<256> Str;
Douglas Gregord770f732010-02-22 23:17:23 +0000259 llvm::raw_svector_ostream Out(Str);
260
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000261 if (Options & CXDiagnostic_DisplaySourceLocation) {
262 // Print source location (file:line), along with optional column
263 // and source ranges.
264 CXFile File;
265 unsigned Line, Column;
Douglas Gregor229bebd2010-11-09 06:24:54 +0000266 clang_getSpellingLocation(clang_getDiagnosticLocation(Diagnostic),
Craig Topper69186e72014-06-08 08:38:04 +0000267 &File, &Line, &Column, nullptr);
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000268 if (File) {
269 CXString FName = clang_getFileName(File);
Douglas Gregord770f732010-02-22 23:17:23 +0000270 Out << clang_getCString(FName) << ":" << Line << ":";
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000271 clang_disposeString(FName);
272 if (Options & CXDiagnostic_DisplayColumn)
Douglas Gregord770f732010-02-22 23:17:23 +0000273 Out << Column << ":";
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000274
275 if (Options & CXDiagnostic_DisplaySourceRanges) {
276 unsigned N = clang_getDiagnosticNumRanges(Diagnostic);
277 bool PrintedRange = false;
278 for (unsigned I = 0; I != N; ++I) {
279 CXFile StartFile, EndFile;
280 CXSourceRange Range = clang_getDiagnosticRange(Diagnostic, I);
281
282 unsigned StartLine, StartColumn, EndLine, EndColumn;
Douglas Gregor229bebd2010-11-09 06:24:54 +0000283 clang_getSpellingLocation(clang_getRangeStart(Range),
284 &StartFile, &StartLine, &StartColumn,
Craig Topper69186e72014-06-08 08:38:04 +0000285 nullptr);
Douglas Gregor229bebd2010-11-09 06:24:54 +0000286 clang_getSpellingLocation(clang_getRangeEnd(Range),
Craig Topper69186e72014-06-08 08:38:04 +0000287 &EndFile, &EndLine, &EndColumn, nullptr);
288
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000289 if (StartFile != EndFile || StartFile != File)
290 continue;
291
Douglas Gregord770f732010-02-22 23:17:23 +0000292 Out << "{" << StartLine << ":" << StartColumn << "-"
293 << EndLine << ":" << EndColumn << "}";
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000294 PrintedRange = true;
295 }
296 if (PrintedRange)
Douglas Gregord770f732010-02-22 23:17:23 +0000297 Out << ":";
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000298 }
Douglas Gregor7bb8af62010-10-12 00:50:20 +0000299
300 Out << " ";
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000301 }
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000302 }
303
304 /* Print warning/error/etc. */
305 switch (Severity) {
David Blaikieaa347f92011-09-23 20:26:49 +0000306 case CXDiagnostic_Ignored: llvm_unreachable("impossible");
Douglas Gregord770f732010-02-22 23:17:23 +0000307 case CXDiagnostic_Note: Out << "note: "; break;
308 case CXDiagnostic_Warning: Out << "warning: "; break;
309 case CXDiagnostic_Error: Out << "error: "; break;
310 case CXDiagnostic_Fatal: Out << "fatal error: "; break;
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000311 }
312
313 CXString Text = clang_getDiagnosticSpelling(Diagnostic);
314 if (clang_getCString(Text))
Douglas Gregord770f732010-02-22 23:17:23 +0000315 Out << clang_getCString(Text);
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000316 else
Douglas Gregord770f732010-02-22 23:17:23 +0000317 Out << "<no diagnostic text>";
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000318 clang_disposeString(Text);
Douglas Gregora750e8e2010-11-19 16:18:16 +0000319
320 if (Options & (CXDiagnostic_DisplayOption | CXDiagnostic_DisplayCategoryId |
321 CXDiagnostic_DisplayCategoryName)) {
322 bool NeedBracket = true;
323 bool NeedComma = false;
324
325 if (Options & CXDiagnostic_DisplayOption) {
Craig Topper69186e72014-06-08 08:38:04 +0000326 CXString OptionName = clang_getDiagnosticOption(Diagnostic, nullptr);
Douglas Gregora750e8e2010-11-19 16:18:16 +0000327 if (const char *OptionText = clang_getCString(OptionName)) {
328 if (OptionText[0]) {
329 Out << " [" << OptionText;
330 NeedBracket = false;
331 NeedComma = true;
332 }
333 }
334 clang_disposeString(OptionName);
335 }
336
337 if (Options & (CXDiagnostic_DisplayCategoryId |
338 CXDiagnostic_DisplayCategoryName)) {
339 if (unsigned CategoryID = clang_getDiagnosticCategory(Diagnostic)) {
340 if (Options & CXDiagnostic_DisplayCategoryId) {
341 if (NeedBracket)
342 Out << " [";
343 if (NeedComma)
344 Out << ", ";
345 Out << CategoryID;
346 NeedBracket = false;
347 NeedComma = true;
348 }
349
350 if (Options & CXDiagnostic_DisplayCategoryName) {
Ted Kremenek26a6d492012-04-12 00:03:31 +0000351 CXString CategoryName = clang_getDiagnosticCategoryText(Diagnostic);
Douglas Gregora750e8e2010-11-19 16:18:16 +0000352 if (NeedBracket)
353 Out << " [";
354 if (NeedComma)
355 Out << ", ";
356 Out << clang_getCString(CategoryName);
357 NeedBracket = false;
358 NeedComma = true;
359 clang_disposeString(CategoryName);
360 }
361 }
362 }
Ted Kremenek34b45462012-04-04 00:55:33 +0000363
364 (void) NeedComma; // Silence dead store warning.
Douglas Gregora750e8e2010-11-19 16:18:16 +0000365 if (!NeedBracket)
366 Out << "]";
367 }
368
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +0000369 return cxstring::createDup(Out.str());
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000370}
371
372unsigned clang_defaultDiagnosticDisplayOptions() {
Douglas Gregora750e8e2010-11-19 16:18:16 +0000373 return CXDiagnostic_DisplaySourceLocation | CXDiagnostic_DisplayColumn |
374 CXDiagnostic_DisplayOption;
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000375}
376
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000377enum CXDiagnosticSeverity clang_getDiagnosticSeverity(CXDiagnostic Diag) {
Ted Kremenekbb2c7102011-10-31 21:40:19 +0000378 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl*>(Diag))
379 return D->getSeverity();
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000380 return CXDiagnostic_Ignored;
381}
Ted Kremenek5cca6eb2010-02-17 00:41:08 +0000382
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000383CXSourceLocation clang_getDiagnosticLocation(CXDiagnostic Diag) {
Ted Kremenekbb2c7102011-10-31 21:40:19 +0000384 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl*>(Diag))
385 return D->getLocation();
386 return clang_getNullLocation();
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000387}
388
389CXString clang_getDiagnosticSpelling(CXDiagnostic Diag) {
Ted Kremenekbb2c7102011-10-31 21:40:19 +0000390 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
391 return D->getSpelling();
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +0000392 return cxstring::createEmpty();
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000393}
394
Douglas Gregora750e8e2010-11-19 16:18:16 +0000395CXString clang_getDiagnosticOption(CXDiagnostic Diag, CXString *Disable) {
396 if (Disable)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +0000397 *Disable = cxstring::createEmpty();
Ted Kremenekbb2c7102011-10-31 21:40:19 +0000398
399 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
400 return D->getDiagnosticOption(Disable);
Douglas Gregora750e8e2010-11-19 16:18:16 +0000401
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +0000402 return cxstring::createEmpty();
Douglas Gregora750e8e2010-11-19 16:18:16 +0000403}
404
405unsigned clang_getDiagnosticCategory(CXDiagnostic Diag) {
Ted Kremenekbb2c7102011-10-31 21:40:19 +0000406 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
407 return D->getCategory();
408 return 0;
Douglas Gregora750e8e2010-11-19 16:18:16 +0000409}
410
411CXString clang_getDiagnosticCategoryName(unsigned Category) {
Alp Toker958027b2014-07-14 19:42:55 +0000412 // Kept for backward compatibility.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +0000413 return cxstring::createRef(DiagnosticIDs::getCategoryNameFromID(Category));
Douglas Gregora750e8e2010-11-19 16:18:16 +0000414}
415
Ted Kremenek26a6d492012-04-12 00:03:31 +0000416CXString clang_getDiagnosticCategoryText(CXDiagnostic Diag) {
417 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
418 return D->getCategoryText();
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +0000419 return cxstring::createEmpty();
Ted Kremenek26a6d492012-04-12 00:03:31 +0000420}
421
Douglas Gregor4b8fd6d2010-02-08 23:11:56 +0000422unsigned clang_getDiagnosticNumRanges(CXDiagnostic Diag) {
Ted Kremenekbb2c7102011-10-31 21:40:19 +0000423 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
424 return D->getNumRanges();
425 return 0;
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000426}
Ted Kremenek5cca6eb2010-02-17 00:41:08 +0000427
Douglas Gregor4b8fd6d2010-02-08 23:11:56 +0000428CXSourceRange clang_getDiagnosticRange(CXDiagnostic Diag, unsigned Range) {
Ted Kremenekbb2c7102011-10-31 21:40:19 +0000429 CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag);
430 if (!D || Range >= D->getNumRanges())
Douglas Gregor4b8fd6d2010-02-08 23:11:56 +0000431 return clang_getNullRange();
Ted Kremenekbb2c7102011-10-31 21:40:19 +0000432 return D->getRange(Range);
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000433}
434
435unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diag) {
Ted Kremenekbb2c7102011-10-31 21:40:19 +0000436 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
437 return D->getNumFixIts();
438 return 0;
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000439}
440
Ted Kremenekbb2c7102011-10-31 21:40:19 +0000441CXString clang_getDiagnosticFixIt(CXDiagnostic Diag, unsigned FixIt,
Douglas Gregor836ec942010-02-19 18:16:06 +0000442 CXSourceRange *ReplacementRange) {
Ted Kremenekbb2c7102011-10-31 21:40:19 +0000443 CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag);
444 if (!D || FixIt >= D->getNumFixIts()) {
Douglas Gregor836ec942010-02-19 18:16:06 +0000445 if (ReplacementRange)
446 *ReplacementRange = clang_getNullRange();
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +0000447 return cxstring::createEmpty();
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000448 }
Ted Kremenekbb2c7102011-10-31 21:40:19 +0000449 return D->getFixIt(FixIt, ReplacementRange);
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000450}
Ted Kremenek5cca6eb2010-02-17 00:41:08 +0000451
Ted Kremenekd010ba42011-11-10 08:43:12 +0000452void clang_disposeDiagnosticSet(CXDiagnosticSet Diags) {
Dmitri Gribenko371c2172014-02-12 14:17:58 +0000453 if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl *>(Diags)) {
454 if (D->isExternallyManaged())
455 delete D;
456 }
Ted Kremenekd010ba42011-11-10 08:43:12 +0000457}
458
459CXDiagnostic clang_getDiagnosticInSet(CXDiagnosticSet Diags,
460 unsigned Index) {
461 if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags))
462 if (Index < D->getNumDiagnostics())
463 return D->getDiagnostic(Index);
Craig Topper69186e72014-06-08 08:38:04 +0000464 return nullptr;
Ted Kremenekd010ba42011-11-10 08:43:12 +0000465}
466
467CXDiagnosticSet clang_getChildDiagnostics(CXDiagnostic Diag) {
468 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag)) {
469 CXDiagnosticSetImpl &ChildDiags = D->getChildDiagnostics();
Craig Topper69186e72014-06-08 08:38:04 +0000470 return ChildDiags.empty() ? nullptr : (CXDiagnosticSet) &ChildDiags;
Ted Kremenekd010ba42011-11-10 08:43:12 +0000471 }
Craig Topper69186e72014-06-08 08:38:04 +0000472 return nullptr;
Ted Kremenekd010ba42011-11-10 08:43:12 +0000473}
474
475unsigned clang_getNumDiagnosticsInSet(CXDiagnosticSet Diags) {
476 if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags))
477 return D->getNumDiagnostics();
478 return 0;
479}
480
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000481} // end extern "C"