blob: 9ba36a6a0f8a600ef5e6bfeec71e8214d0e8d788 [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
Benjamin Kramer064414532010-04-12 19:45:50 +000019#include "clang/Frontend/ASTUnit.h"
Douglas Gregorac0605e2010-01-28 06:00:51 +000020#include "clang/Frontend/FrontendDiagnostic.h"
Ted Kremenek914c7e62012-02-14 02:46:03 +000021#include "clang/Frontend/DiagnosticRenderer.h"
Douglas Gregor811db4e2012-10-23 22:26:28 +000022#include "clang/Basic/DiagnosticOptions.h"
Douglas Gregord770f732010-02-22 23:17:23 +000023#include "llvm/ADT/SmallString.h"
Douglas Gregor33cdd812010-02-18 18:08:43 +000024#include "llvm/ADT/Twine.h"
Douglas Gregorac0605e2010-01-28 06:00:51 +000025#include "llvm/Support/MemoryBuffer.h"
Douglas Gregord770f732010-02-22 23:17:23 +000026#include "llvm/Support/raw_ostream.h"
Douglas Gregorac0605e2010-01-28 06:00:51 +000027
Douglas Gregor4f9c3762010-01-28 00:27:43 +000028using namespace clang;
29using namespace clang::cxloc;
Argyrios Kyrtzidisf2d99b02011-12-01 02:42:50 +000030using namespace clang::cxdiag;
Douglas Gregor33cdd812010-02-18 18:08:43 +000031using namespace llvm;
Douglas Gregor4f9c3762010-01-28 00:27:43 +000032
David Blaikie759548b2014-08-29 18:43:24 +000033CXDiagnosticSetImpl::~CXDiagnosticSetImpl() {}
Ted Kremenekd010ba42011-11-10 08:43:12 +000034
David Blaikie759548b2014-08-29 18:43:24 +000035void
36CXDiagnosticSetImpl::appendDiagnostic(std::unique_ptr<CXDiagnosticImpl> D) {
37 Diagnostics.push_back(std::move(D));
Ted Kremenekd010ba42011-11-10 08:43:12 +000038}
39
40CXDiagnosticImpl::~CXDiagnosticImpl() {}
41
Ted Kremenek914c7e62012-02-14 02:46:03 +000042namespace {
43class CXDiagnosticCustomNoteImpl : public CXDiagnosticImpl {
Ted Kremenekb05119c2012-02-14 06:54:46 +000044 std::string Message;
Ted Kremenek914c7e62012-02-14 02:46:03 +000045 CXSourceLocation Loc;
46public:
47 CXDiagnosticCustomNoteImpl(StringRef Msg, CXSourceLocation L)
48 : CXDiagnosticImpl(CustomNoteDiagnosticKind),
Ted Kremenekb05119c2012-02-14 06:54:46 +000049 Message(Msg), Loc(L) {}
Ted Kremenek914c7e62012-02-14 02:46:03 +000050
Alexander Kornienko34eb2072015-04-11 02:00:23 +000051 ~CXDiagnosticCustomNoteImpl() override {}
Craig Topper36835562014-03-15 07:47:46 +000052
53 CXDiagnosticSeverity getSeverity() const override {
Ted Kremenek914c7e62012-02-14 02:46:03 +000054 return CXDiagnostic_Note;
55 }
Craig Topper36835562014-03-15 07:47:46 +000056
57 CXSourceLocation getLocation() const override {
Ted Kremenek914c7e62012-02-14 02:46:03 +000058 return Loc;
59 }
Craig Topper36835562014-03-15 07:47:46 +000060
61 CXString getSpelling() const override {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +000062 return cxstring::createRef(Message.c_str());
Ted Kremenek914c7e62012-02-14 02:46:03 +000063 }
Craig Topper36835562014-03-15 07:47:46 +000064
65 CXString getDiagnosticOption(CXString *Disable) const override {
Ted Kremenek914c7e62012-02-14 02:46:03 +000066 if (Disable)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +000067 *Disable = cxstring::createEmpty();
68 return cxstring::createEmpty();
Ted Kremenek914c7e62012-02-14 02:46:03 +000069 }
Ted Kremenek26a6d492012-04-12 00:03:31 +000070
Craig Topper36835562014-03-15 07:47:46 +000071 unsigned getCategory() const override { return 0; }
72 CXString getCategoryText() const override { return cxstring::createEmpty(); }
73
74 unsigned getNumRanges() const override { return 0; }
75 CXSourceRange getRange(unsigned Range) const override {
76 return clang_getNullRange();
77 }
78 unsigned getNumFixIts() const override { return 0; }
79 CXString getFixIt(unsigned FixIt,
80 CXSourceRange *ReplacementRange) const override {
Ted Kremenek914c7e62012-02-14 02:46:03 +000081 if (ReplacementRange)
82 *ReplacementRange = clang_getNullRange();
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +000083 return cxstring::createEmpty();
Ted Kremenek914c7e62012-02-14 02:46:03 +000084 }
85};
86
87class CXDiagnosticRenderer : public DiagnosticNoteRenderer {
88public:
Argyrios Kyrtzidisb16ff5d2012-05-10 05:03:45 +000089 CXDiagnosticRenderer(const LangOptions &LangOpts,
Douglas Gregor811db4e2012-10-23 22:26:28 +000090 DiagnosticOptions *DiagOpts,
Ted Kremenek914c7e62012-02-14 02:46:03 +000091 CXDiagnosticSetImpl *mainSet)
Argyrios Kyrtzidisb16ff5d2012-05-10 05:03:45 +000092 : DiagnosticNoteRenderer(LangOpts, DiagOpts),
Ted Kremenek914c7e62012-02-14 02:46:03 +000093 CurrentSet(mainSet), MainSet(mainSet) {}
Alexander Kornienko34eb2072015-04-11 02:00:23 +000094
95 ~CXDiagnosticRenderer() override {}
Ted Kremenek914c7e62012-02-14 02:46:03 +000096
Craig Topper36835562014-03-15 07:47:46 +000097 void beginDiagnostic(DiagOrStoredDiag D,
98 DiagnosticsEngine::Level Level) override {
99
Ted Kremenek914c7e62012-02-14 02:46:03 +0000100 const StoredDiagnostic *SD = D.dyn_cast<const StoredDiagnostic*>();
101 if (!SD)
102 return;
103
104 if (Level != DiagnosticsEngine::Note)
105 CurrentSet = MainSet;
David Blaikie759548b2014-08-29 18:43:24 +0000106
107 auto Owner = llvm::make_unique<CXStoredDiagnostic>(*SD, LangOpts);
108 CXStoredDiagnostic &CD = *Owner;
109 CurrentSet->appendDiagnostic(std::move(Owner));
110
Ted Kremenek914c7e62012-02-14 02:46:03 +0000111 if (Level != DiagnosticsEngine::Note)
David Blaikie759548b2014-08-29 18:43:24 +0000112 CurrentSet = &CD.getChildDiagnostics();
Ted Kremenek914c7e62012-02-14 02:46:03 +0000113 }
Craig Topper36835562014-03-15 07:47:46 +0000114
115 void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc,
116 DiagnosticsEngine::Level Level,
117 StringRef Message,
118 ArrayRef<CharSourceRange> Ranges,
119 const SourceManager *SM,
120 DiagOrStoredDiag D) override {
Ted Kremenek914c7e62012-02-14 02:46:03 +0000121 if (!D.isNull())
122 return;
123
Argyrios Kyrtzidisb16ff5d2012-05-10 05:03:45 +0000124 CXSourceLocation L;
125 if (SM)
126 L = translateSourceLocation(*SM, LangOpts, Loc);
127 else
128 L = clang_getNullLocation();
David Blaikie759548b2014-08-29 18:43:24 +0000129 CurrentSet->appendDiagnostic(
130 llvm::make_unique<CXDiagnosticCustomNoteImpl>(Message, L));
Ted Kremenek914c7e62012-02-14 02:46:03 +0000131 }
Ted Kremenek914c7e62012-02-14 02:46:03 +0000132
Craig Topper36835562014-03-15 07:47:46 +0000133 void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
134 DiagnosticsEngine::Level Level,
135 ArrayRef<CharSourceRange> Ranges,
136 const SourceManager &SM) override {}
137
138 void emitCodeContext(SourceLocation Loc,
139 DiagnosticsEngine::Level Level,
140 SmallVectorImpl<CharSourceRange>& Ranges,
141 ArrayRef<FixItHint> Hints,
142 const SourceManager &SM) override {}
143
144 void emitNote(SourceLocation Loc, StringRef Message,
145 const SourceManager *SM) override {
Argyrios Kyrtzidisb16ff5d2012-05-10 05:03:45 +0000146 CXSourceLocation L;
147 if (SM)
148 L = translateSourceLocation(*SM, LangOpts, Loc);
149 else
150 L = clang_getNullLocation();
David Blaikie759548b2014-08-29 18:43:24 +0000151 CurrentSet->appendDiagnostic(
152 llvm::make_unique<CXDiagnosticCustomNoteImpl>(Message, L));
Ted Kremenek914c7e62012-02-14 02:46:03 +0000153 }
154
155 CXDiagnosticSetImpl *CurrentSet;
156 CXDiagnosticSetImpl *MainSet;
157};
158}
159
Argyrios Kyrtzidisf2d99b02011-12-01 02:42:50 +0000160CXDiagnosticSetImpl *cxdiag::lazyCreateDiags(CXTranslationUnit TU,
161 bool checkIfChanged) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000162 ASTUnit *AU = cxtu::getASTUnit(TU);
Argyrios Kyrtzidisf03e7342011-11-16 02:34:55 +0000163
164 if (TU->Diagnostics && checkIfChanged) {
Argyrios Kyrtzidis7ae5d9c2011-11-16 08:59:00 +0000165 // In normal use, ASTUnit's diagnostics should not change unless we reparse.
166 // Currently they can only change by using the internal testing flag
167 // '-error-on-deserialized-decl' which will error during deserialization of
168 // a declaration. What will happen is:
169 //
170 // -c-index-test gets a CXTranslationUnit
171 // -checks the diagnostics, the diagnostics set is lazily created,
172 // no errors are reported
173 // -later does an operation, like annotation of tokens, that triggers
174 // -error-on-deserialized-decl, that will emit a diagnostic error,
175 // that ASTUnit will catch and add to its stored diagnostics vector.
176 // -c-index-test wants to check whether an error occurred after performing
177 // the operation but can only query the lazily created set.
178 //
179 // We check here if a new diagnostic was appended since the last time the
180 // diagnostic set was created, in which case we reset it.
181
Argyrios Kyrtzidisf03e7342011-11-16 02:34:55 +0000182 CXDiagnosticSetImpl *
183 Set = static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
184 if (AU->stored_diag_size() != Set->getNumDiagnostics()) {
185 // Diagnostics in the ASTUnit were updated, reset the associated
186 // diagnostics.
187 delete Set;
Craig Topper69186e72014-06-08 08:38:04 +0000188 TU->Diagnostics = nullptr;
Argyrios Kyrtzidisf03e7342011-11-16 02:34:55 +0000189 }
190 }
191
Ted Kremenekd010ba42011-11-10 08:43:12 +0000192 if (!TU->Diagnostics) {
Ted Kremenekd010ba42011-11-10 08:43:12 +0000193 CXDiagnosticSetImpl *Set = new CXDiagnosticSetImpl();
194 TU->Diagnostics = Set;
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000195 IntrusiveRefCntPtr<DiagnosticOptions> DOpts = new DiagnosticOptions;
Argyrios Kyrtzidisb16ff5d2012-05-10 05:03:45 +0000196 CXDiagnosticRenderer Renderer(AU->getASTContext().getLangOpts(),
Douglas Gregor811db4e2012-10-23 22:26:28 +0000197 &*DOpts, Set);
Ted Kremenekd010ba42011-11-10 08:43:12 +0000198
199 for (ASTUnit::stored_diag_iterator it = AU->stored_diag_begin(),
200 ei = AU->stored_diag_end(); it != ei; ++it) {
Ted Kremenek914c7e62012-02-14 02:46:03 +0000201 Renderer.emitStoredDiagnostic(*it);
Ted Kremenekd010ba42011-11-10 08:43:12 +0000202 }
203 }
204 return static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
205}
206
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000207//-----------------------------------------------------------------------------
Ted Kremenek5cca6eb2010-02-17 00:41:08 +0000208// C Interface Routines
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000209//-----------------------------------------------------------------------------
210extern "C" {
Ted Kremenek5cca6eb2010-02-17 00:41:08 +0000211
Douglas Gregor33cdd812010-02-18 18:08:43 +0000212unsigned clang_getNumDiagnostics(CXTranslationUnit Unit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +0000213 if (cxtu::isNotUsableTU(Unit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +0000214 LOG_BAD_TU(Unit);
215 return 0;
216 }
Dmitri Gribenkod36209e2013-01-26 21:32:42 +0000217 if (!cxtu::getASTUnit(Unit))
Ted Kremenekd010ba42011-11-10 08:43:12 +0000218 return 0;
Argyrios Kyrtzidisf03e7342011-11-16 02:34:55 +0000219 return lazyCreateDiags(Unit, /*checkIfChanged=*/true)->getNumDiagnostics();
Douglas Gregor33cdd812010-02-18 18:08:43 +0000220}
221
222CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +0000223 if (cxtu::isNotUsableTU(Unit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +0000224 LOG_BAD_TU(Unit);
Craig Topper69186e72014-06-08 08:38:04 +0000225 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +0000226 }
227
Ted Kremenekb4a8b052011-12-09 22:28:32 +0000228 CXDiagnosticSet D = clang_getDiagnosticSetFromTU(Unit);
229 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +0000230 return nullptr;
Douglas Gregor33cdd812010-02-18 18:08:43 +0000231
Ted Kremenekb4a8b052011-12-09 22:28:32 +0000232 CXDiagnosticSetImpl *Diags = static_cast<CXDiagnosticSetImpl*>(D);
Ted Kremenekd010ba42011-11-10 08:43:12 +0000233 if (Index >= Diags->getNumDiagnostics())
Craig Topper69186e72014-06-08 08:38:04 +0000234 return nullptr;
Ted Kremenekd010ba42011-11-10 08:43:12 +0000235
236 return Diags->getDiagnostic(Index);
Douglas Gregor33cdd812010-02-18 18:08:43 +0000237}
Dmitri Gribenko256454f2014-02-11 14:34:14 +0000238
Ted Kremenekb4a8b052011-12-09 22:28:32 +0000239CXDiagnosticSet clang_getDiagnosticSetFromTU(CXTranslationUnit Unit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +0000240 if (cxtu::isNotUsableTU(Unit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +0000241 LOG_BAD_TU(Unit);
Craig Topper69186e72014-06-08 08:38:04 +0000242 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +0000243 }
Dmitri Gribenkod36209e2013-01-26 21:32:42 +0000244 if (!cxtu::getASTUnit(Unit))
Craig Topper69186e72014-06-08 08:38:04 +0000245 return nullptr;
Ted Kremenekb4a8b052011-12-09 22:28:32 +0000246 return static_cast<CXDiagnostic>(lazyCreateDiags(Unit));
247}
Douglas Gregor33cdd812010-02-18 18:08:43 +0000248
249void clang_disposeDiagnostic(CXDiagnostic Diagnostic) {
Ted Kremenekd010ba42011-11-10 08:43:12 +0000250 // No-op. Kept as a legacy API. CXDiagnostics are now managed
251 // by the enclosing CXDiagnosticSet.
Douglas Gregor33cdd812010-02-18 18:08:43 +0000252}
253
Douglas Gregord770f732010-02-22 23:17:23 +0000254CXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options) {
255 if (!Diagnostic)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +0000256 return cxstring::createEmpty();
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000257
258 CXDiagnosticSeverity Severity = clang_getDiagnosticSeverity(Diagnostic);
259
Dylan Noblesmithf1a13f22012-02-13 12:32:26 +0000260 SmallString<256> Str;
Douglas Gregord770f732010-02-22 23:17:23 +0000261 llvm::raw_svector_ostream Out(Str);
262
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000263 if (Options & CXDiagnostic_DisplaySourceLocation) {
264 // Print source location (file:line), along with optional column
265 // and source ranges.
266 CXFile File;
267 unsigned Line, Column;
Douglas Gregor229bebd2010-11-09 06:24:54 +0000268 clang_getSpellingLocation(clang_getDiagnosticLocation(Diagnostic),
Craig Topper69186e72014-06-08 08:38:04 +0000269 &File, &Line, &Column, nullptr);
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000270 if (File) {
271 CXString FName = clang_getFileName(File);
Douglas Gregord770f732010-02-22 23:17:23 +0000272 Out << clang_getCString(FName) << ":" << Line << ":";
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000273 clang_disposeString(FName);
274 if (Options & CXDiagnostic_DisplayColumn)
Douglas Gregord770f732010-02-22 23:17:23 +0000275 Out << Column << ":";
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000276
277 if (Options & CXDiagnostic_DisplaySourceRanges) {
278 unsigned N = clang_getDiagnosticNumRanges(Diagnostic);
279 bool PrintedRange = false;
280 for (unsigned I = 0; I != N; ++I) {
281 CXFile StartFile, EndFile;
282 CXSourceRange Range = clang_getDiagnosticRange(Diagnostic, I);
283
284 unsigned StartLine, StartColumn, EndLine, EndColumn;
Douglas Gregor229bebd2010-11-09 06:24:54 +0000285 clang_getSpellingLocation(clang_getRangeStart(Range),
286 &StartFile, &StartLine, &StartColumn,
Craig Topper69186e72014-06-08 08:38:04 +0000287 nullptr);
Douglas Gregor229bebd2010-11-09 06:24:54 +0000288 clang_getSpellingLocation(clang_getRangeEnd(Range),
Craig Topper69186e72014-06-08 08:38:04 +0000289 &EndFile, &EndLine, &EndColumn, nullptr);
290
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000291 if (StartFile != EndFile || StartFile != File)
292 continue;
293
Douglas Gregord770f732010-02-22 23:17:23 +0000294 Out << "{" << StartLine << ":" << StartColumn << "-"
295 << EndLine << ":" << EndColumn << "}";
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000296 PrintedRange = true;
297 }
298 if (PrintedRange)
Douglas Gregord770f732010-02-22 23:17:23 +0000299 Out << ":";
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000300 }
Douglas Gregor7bb8af62010-10-12 00:50:20 +0000301
302 Out << " ";
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000303 }
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000304 }
305
306 /* Print warning/error/etc. */
307 switch (Severity) {
David Blaikieaa347f92011-09-23 20:26:49 +0000308 case CXDiagnostic_Ignored: llvm_unreachable("impossible");
Douglas Gregord770f732010-02-22 23:17:23 +0000309 case CXDiagnostic_Note: Out << "note: "; break;
310 case CXDiagnostic_Warning: Out << "warning: "; break;
311 case CXDiagnostic_Error: Out << "error: "; break;
312 case CXDiagnostic_Fatal: Out << "fatal error: "; break;
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000313 }
314
315 CXString Text = clang_getDiagnosticSpelling(Diagnostic);
316 if (clang_getCString(Text))
Douglas Gregord770f732010-02-22 23:17:23 +0000317 Out << clang_getCString(Text);
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000318 else
Douglas Gregord770f732010-02-22 23:17:23 +0000319 Out << "<no diagnostic text>";
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000320 clang_disposeString(Text);
Douglas Gregora750e8e2010-11-19 16:18:16 +0000321
322 if (Options & (CXDiagnostic_DisplayOption | CXDiagnostic_DisplayCategoryId |
323 CXDiagnostic_DisplayCategoryName)) {
324 bool NeedBracket = true;
325 bool NeedComma = false;
326
327 if (Options & CXDiagnostic_DisplayOption) {
Craig Topper69186e72014-06-08 08:38:04 +0000328 CXString OptionName = clang_getDiagnosticOption(Diagnostic, nullptr);
Douglas Gregora750e8e2010-11-19 16:18:16 +0000329 if (const char *OptionText = clang_getCString(OptionName)) {
330 if (OptionText[0]) {
331 Out << " [" << OptionText;
332 NeedBracket = false;
333 NeedComma = true;
334 }
335 }
336 clang_disposeString(OptionName);
337 }
338
339 if (Options & (CXDiagnostic_DisplayCategoryId |
340 CXDiagnostic_DisplayCategoryName)) {
341 if (unsigned CategoryID = clang_getDiagnosticCategory(Diagnostic)) {
342 if (Options & CXDiagnostic_DisplayCategoryId) {
343 if (NeedBracket)
344 Out << " [";
345 if (NeedComma)
346 Out << ", ";
347 Out << CategoryID;
348 NeedBracket = false;
349 NeedComma = true;
350 }
351
352 if (Options & CXDiagnostic_DisplayCategoryName) {
Ted Kremenek26a6d492012-04-12 00:03:31 +0000353 CXString CategoryName = clang_getDiagnosticCategoryText(Diagnostic);
Douglas Gregora750e8e2010-11-19 16:18:16 +0000354 if (NeedBracket)
355 Out << " [";
356 if (NeedComma)
357 Out << ", ";
358 Out << clang_getCString(CategoryName);
359 NeedBracket = false;
360 NeedComma = true;
361 clang_disposeString(CategoryName);
362 }
363 }
364 }
Ted Kremenek34b45462012-04-04 00:55:33 +0000365
366 (void) NeedComma; // Silence dead store warning.
Douglas Gregora750e8e2010-11-19 16:18:16 +0000367 if (!NeedBracket)
368 Out << "]";
369 }
370
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +0000371 return cxstring::createDup(Out.str());
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000372}
373
374unsigned clang_defaultDiagnosticDisplayOptions() {
Douglas Gregora750e8e2010-11-19 16:18:16 +0000375 return CXDiagnostic_DisplaySourceLocation | CXDiagnostic_DisplayColumn |
376 CXDiagnostic_DisplayOption;
Douglas Gregor1e21cc72010-02-18 23:07:20 +0000377}
378
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000379enum CXDiagnosticSeverity clang_getDiagnosticSeverity(CXDiagnostic Diag) {
Ted Kremenekbb2c7102011-10-31 21:40:19 +0000380 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl*>(Diag))
381 return D->getSeverity();
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000382 return CXDiagnostic_Ignored;
383}
Ted Kremenek5cca6eb2010-02-17 00:41:08 +0000384
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000385CXSourceLocation clang_getDiagnosticLocation(CXDiagnostic Diag) {
Ted Kremenekbb2c7102011-10-31 21:40:19 +0000386 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl*>(Diag))
387 return D->getLocation();
388 return clang_getNullLocation();
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000389}
390
391CXString clang_getDiagnosticSpelling(CXDiagnostic Diag) {
Ted Kremenekbb2c7102011-10-31 21:40:19 +0000392 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
393 return D->getSpelling();
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +0000394 return cxstring::createEmpty();
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000395}
396
Douglas Gregora750e8e2010-11-19 16:18:16 +0000397CXString clang_getDiagnosticOption(CXDiagnostic Diag, CXString *Disable) {
398 if (Disable)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +0000399 *Disable = cxstring::createEmpty();
Ted Kremenekbb2c7102011-10-31 21:40:19 +0000400
401 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
402 return D->getDiagnosticOption(Disable);
Douglas Gregora750e8e2010-11-19 16:18:16 +0000403
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +0000404 return cxstring::createEmpty();
Douglas Gregora750e8e2010-11-19 16:18:16 +0000405}
406
407unsigned clang_getDiagnosticCategory(CXDiagnostic Diag) {
Ted Kremenekbb2c7102011-10-31 21:40:19 +0000408 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
409 return D->getCategory();
410 return 0;
Douglas Gregora750e8e2010-11-19 16:18:16 +0000411}
412
413CXString clang_getDiagnosticCategoryName(unsigned Category) {
Alp Toker958027b2014-07-14 19:42:55 +0000414 // Kept for backward compatibility.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +0000415 return cxstring::createRef(DiagnosticIDs::getCategoryNameFromID(Category));
Douglas Gregora750e8e2010-11-19 16:18:16 +0000416}
417
Ted Kremenek26a6d492012-04-12 00:03:31 +0000418CXString clang_getDiagnosticCategoryText(CXDiagnostic Diag) {
419 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
420 return D->getCategoryText();
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +0000421 return cxstring::createEmpty();
Ted Kremenek26a6d492012-04-12 00:03:31 +0000422}
423
Douglas Gregor4b8fd6d2010-02-08 23:11:56 +0000424unsigned clang_getDiagnosticNumRanges(CXDiagnostic Diag) {
Ted Kremenekbb2c7102011-10-31 21:40:19 +0000425 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
426 return D->getNumRanges();
427 return 0;
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000428}
Ted Kremenek5cca6eb2010-02-17 00:41:08 +0000429
Douglas Gregor4b8fd6d2010-02-08 23:11:56 +0000430CXSourceRange clang_getDiagnosticRange(CXDiagnostic Diag, unsigned Range) {
Ted Kremenekbb2c7102011-10-31 21:40:19 +0000431 CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag);
432 if (!D || Range >= D->getNumRanges())
Douglas Gregor4b8fd6d2010-02-08 23:11:56 +0000433 return clang_getNullRange();
Ted Kremenekbb2c7102011-10-31 21:40:19 +0000434 return D->getRange(Range);
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000435}
436
437unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diag) {
Ted Kremenekbb2c7102011-10-31 21:40:19 +0000438 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
439 return D->getNumFixIts();
440 return 0;
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000441}
442
Ted Kremenekbb2c7102011-10-31 21:40:19 +0000443CXString clang_getDiagnosticFixIt(CXDiagnostic Diag, unsigned FixIt,
Douglas Gregor836ec942010-02-19 18:16:06 +0000444 CXSourceRange *ReplacementRange) {
Ted Kremenekbb2c7102011-10-31 21:40:19 +0000445 CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag);
446 if (!D || FixIt >= D->getNumFixIts()) {
Douglas Gregor836ec942010-02-19 18:16:06 +0000447 if (ReplacementRange)
448 *ReplacementRange = clang_getNullRange();
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +0000449 return cxstring::createEmpty();
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000450 }
Ted Kremenekbb2c7102011-10-31 21:40:19 +0000451 return D->getFixIt(FixIt, ReplacementRange);
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000452}
Ted Kremenek5cca6eb2010-02-17 00:41:08 +0000453
Ted Kremenekd010ba42011-11-10 08:43:12 +0000454void clang_disposeDiagnosticSet(CXDiagnosticSet Diags) {
Dmitri Gribenko371c2172014-02-12 14:17:58 +0000455 if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl *>(Diags)) {
456 if (D->isExternallyManaged())
457 delete D;
458 }
Ted Kremenekd010ba42011-11-10 08:43:12 +0000459}
460
461CXDiagnostic clang_getDiagnosticInSet(CXDiagnosticSet Diags,
462 unsigned Index) {
463 if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags))
464 if (Index < D->getNumDiagnostics())
465 return D->getDiagnostic(Index);
Craig Topper69186e72014-06-08 08:38:04 +0000466 return nullptr;
Ted Kremenekd010ba42011-11-10 08:43:12 +0000467}
468
469CXDiagnosticSet clang_getChildDiagnostics(CXDiagnostic Diag) {
470 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag)) {
471 CXDiagnosticSetImpl &ChildDiags = D->getChildDiagnostics();
Craig Topper69186e72014-06-08 08:38:04 +0000472 return ChildDiags.empty() ? nullptr : (CXDiagnosticSet) &ChildDiags;
Ted Kremenekd010ba42011-11-10 08:43:12 +0000473 }
Craig Topper69186e72014-06-08 08:38:04 +0000474 return nullptr;
Ted Kremenekd010ba42011-11-10 08:43:12 +0000475}
476
477unsigned clang_getNumDiagnosticsInSet(CXDiagnosticSet Diags) {
478 if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags))
479 return D->getNumDiagnostics();
480 return 0;
481}
482
Douglas Gregor4f9c3762010-01-28 00:27:43 +0000483} // end extern "C"