1*67e74705SXin Li /*===-- CIndexDiagnostics.cpp - Diagnostics C Interface ---------*- C++ -*-===*\
2*67e74705SXin Li |* *|
3*67e74705SXin Li |* The LLVM Compiler Infrastructure *|
4*67e74705SXin Li |* *|
5*67e74705SXin Li |* This file is distributed under the University of Illinois Open Source *|
6*67e74705SXin Li |* License. See LICENSE.TXT for details. *|
7*67e74705SXin Li |* *|
8*67e74705SXin Li |*===----------------------------------------------------------------------===*|
9*67e74705SXin Li |* *|
10*67e74705SXin Li |* Implements the diagnostic functions of the Clang C interface. *|
11*67e74705SXin Li |* *|
12*67e74705SXin Li \*===----------------------------------------------------------------------===*/
13*67e74705SXin Li #include "CIndexDiagnostic.h"
14*67e74705SXin Li #include "CIndexer.h"
15*67e74705SXin Li #include "CXTranslationUnit.h"
16*67e74705SXin Li #include "CXSourceLocation.h"
17*67e74705SXin Li #include "CXString.h"
18*67e74705SXin Li
19*67e74705SXin Li #include "clang/Frontend/ASTUnit.h"
20*67e74705SXin Li #include "clang/Frontend/FrontendDiagnostic.h"
21*67e74705SXin Li #include "clang/Frontend/DiagnosticRenderer.h"
22*67e74705SXin Li #include "clang/Basic/DiagnosticOptions.h"
23*67e74705SXin Li #include "llvm/ADT/SmallString.h"
24*67e74705SXin Li #include "llvm/ADT/Twine.h"
25*67e74705SXin Li #include "llvm/Support/MemoryBuffer.h"
26*67e74705SXin Li #include "llvm/Support/raw_ostream.h"
27*67e74705SXin Li
28*67e74705SXin Li using namespace clang;
29*67e74705SXin Li using namespace clang::cxloc;
30*67e74705SXin Li using namespace clang::cxdiag;
31*67e74705SXin Li using namespace llvm;
32*67e74705SXin Li
~CXDiagnosticSetImpl()33*67e74705SXin Li CXDiagnosticSetImpl::~CXDiagnosticSetImpl() {}
34*67e74705SXin Li
35*67e74705SXin Li void
appendDiagnostic(std::unique_ptr<CXDiagnosticImpl> D)36*67e74705SXin Li CXDiagnosticSetImpl::appendDiagnostic(std::unique_ptr<CXDiagnosticImpl> D) {
37*67e74705SXin Li Diagnostics.push_back(std::move(D));
38*67e74705SXin Li }
39*67e74705SXin Li
~CXDiagnosticImpl()40*67e74705SXin Li CXDiagnosticImpl::~CXDiagnosticImpl() {}
41*67e74705SXin Li
42*67e74705SXin Li namespace {
43*67e74705SXin Li class CXDiagnosticCustomNoteImpl : public CXDiagnosticImpl {
44*67e74705SXin Li std::string Message;
45*67e74705SXin Li CXSourceLocation Loc;
46*67e74705SXin Li public:
CXDiagnosticCustomNoteImpl(StringRef Msg,CXSourceLocation L)47*67e74705SXin Li CXDiagnosticCustomNoteImpl(StringRef Msg, CXSourceLocation L)
48*67e74705SXin Li : CXDiagnosticImpl(CustomNoteDiagnosticKind),
49*67e74705SXin Li Message(Msg), Loc(L) {}
50*67e74705SXin Li
~CXDiagnosticCustomNoteImpl()51*67e74705SXin Li ~CXDiagnosticCustomNoteImpl() override {}
52*67e74705SXin Li
getSeverity() const53*67e74705SXin Li CXDiagnosticSeverity getSeverity() const override {
54*67e74705SXin Li return CXDiagnostic_Note;
55*67e74705SXin Li }
56*67e74705SXin Li
getLocation() const57*67e74705SXin Li CXSourceLocation getLocation() const override {
58*67e74705SXin Li return Loc;
59*67e74705SXin Li }
60*67e74705SXin Li
getSpelling() const61*67e74705SXin Li CXString getSpelling() const override {
62*67e74705SXin Li return cxstring::createRef(Message.c_str());
63*67e74705SXin Li }
64*67e74705SXin Li
getDiagnosticOption(CXString * Disable) const65*67e74705SXin Li CXString getDiagnosticOption(CXString *Disable) const override {
66*67e74705SXin Li if (Disable)
67*67e74705SXin Li *Disable = cxstring::createEmpty();
68*67e74705SXin Li return cxstring::createEmpty();
69*67e74705SXin Li }
70*67e74705SXin Li
getCategory() const71*67e74705SXin Li unsigned getCategory() const override { return 0; }
getCategoryText() const72*67e74705SXin Li CXString getCategoryText() const override { return cxstring::createEmpty(); }
73*67e74705SXin Li
getNumRanges() const74*67e74705SXin Li unsigned getNumRanges() const override { return 0; }
getRange(unsigned Range) const75*67e74705SXin Li CXSourceRange getRange(unsigned Range) const override {
76*67e74705SXin Li return clang_getNullRange();
77*67e74705SXin Li }
getNumFixIts() const78*67e74705SXin Li unsigned getNumFixIts() const override { return 0; }
getFixIt(unsigned FixIt,CXSourceRange * ReplacementRange) const79*67e74705SXin Li CXString getFixIt(unsigned FixIt,
80*67e74705SXin Li CXSourceRange *ReplacementRange) const override {
81*67e74705SXin Li if (ReplacementRange)
82*67e74705SXin Li *ReplacementRange = clang_getNullRange();
83*67e74705SXin Li return cxstring::createEmpty();
84*67e74705SXin Li }
85*67e74705SXin Li };
86*67e74705SXin Li
87*67e74705SXin Li class CXDiagnosticRenderer : public DiagnosticNoteRenderer {
88*67e74705SXin Li public:
CXDiagnosticRenderer(const LangOptions & LangOpts,DiagnosticOptions * DiagOpts,CXDiagnosticSetImpl * mainSet)89*67e74705SXin Li CXDiagnosticRenderer(const LangOptions &LangOpts,
90*67e74705SXin Li DiagnosticOptions *DiagOpts,
91*67e74705SXin Li CXDiagnosticSetImpl *mainSet)
92*67e74705SXin Li : DiagnosticNoteRenderer(LangOpts, DiagOpts),
93*67e74705SXin Li CurrentSet(mainSet), MainSet(mainSet) {}
94*67e74705SXin Li
~CXDiagnosticRenderer()95*67e74705SXin Li ~CXDiagnosticRenderer() override {}
96*67e74705SXin Li
beginDiagnostic(DiagOrStoredDiag D,DiagnosticsEngine::Level Level)97*67e74705SXin Li void beginDiagnostic(DiagOrStoredDiag D,
98*67e74705SXin Li DiagnosticsEngine::Level Level) override {
99*67e74705SXin Li
100*67e74705SXin Li const StoredDiagnostic *SD = D.dyn_cast<const StoredDiagnostic*>();
101*67e74705SXin Li if (!SD)
102*67e74705SXin Li return;
103*67e74705SXin Li
104*67e74705SXin Li if (Level != DiagnosticsEngine::Note)
105*67e74705SXin Li CurrentSet = MainSet;
106*67e74705SXin Li
107*67e74705SXin Li auto Owner = llvm::make_unique<CXStoredDiagnostic>(*SD, LangOpts);
108*67e74705SXin Li CXStoredDiagnostic &CD = *Owner;
109*67e74705SXin Li CurrentSet->appendDiagnostic(std::move(Owner));
110*67e74705SXin Li
111*67e74705SXin Li if (Level != DiagnosticsEngine::Note)
112*67e74705SXin Li CurrentSet = &CD.getChildDiagnostics();
113*67e74705SXin Li }
114*67e74705SXin Li
emitDiagnosticMessage(SourceLocation Loc,PresumedLoc PLoc,DiagnosticsEngine::Level Level,StringRef Message,ArrayRef<CharSourceRange> Ranges,const SourceManager * SM,DiagOrStoredDiag D)115*67e74705SXin Li void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc,
116*67e74705SXin Li DiagnosticsEngine::Level Level,
117*67e74705SXin Li StringRef Message,
118*67e74705SXin Li ArrayRef<CharSourceRange> Ranges,
119*67e74705SXin Li const SourceManager *SM,
120*67e74705SXin Li DiagOrStoredDiag D) override {
121*67e74705SXin Li if (!D.isNull())
122*67e74705SXin Li return;
123*67e74705SXin Li
124*67e74705SXin Li CXSourceLocation L;
125*67e74705SXin Li if (SM)
126*67e74705SXin Li L = translateSourceLocation(*SM, LangOpts, Loc);
127*67e74705SXin Li else
128*67e74705SXin Li L = clang_getNullLocation();
129*67e74705SXin Li CurrentSet->appendDiagnostic(
130*67e74705SXin Li llvm::make_unique<CXDiagnosticCustomNoteImpl>(Message, L));
131*67e74705SXin Li }
132*67e74705SXin Li
emitDiagnosticLoc(SourceLocation Loc,PresumedLoc PLoc,DiagnosticsEngine::Level Level,ArrayRef<CharSourceRange> Ranges,const SourceManager & SM)133*67e74705SXin Li void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
134*67e74705SXin Li DiagnosticsEngine::Level Level,
135*67e74705SXin Li ArrayRef<CharSourceRange> Ranges,
136*67e74705SXin Li const SourceManager &SM) override {}
137*67e74705SXin Li
emitCodeContext(SourceLocation Loc,DiagnosticsEngine::Level Level,SmallVectorImpl<CharSourceRange> & Ranges,ArrayRef<FixItHint> Hints,const SourceManager & SM)138*67e74705SXin Li void emitCodeContext(SourceLocation Loc,
139*67e74705SXin Li DiagnosticsEngine::Level Level,
140*67e74705SXin Li SmallVectorImpl<CharSourceRange>& Ranges,
141*67e74705SXin Li ArrayRef<FixItHint> Hints,
142*67e74705SXin Li const SourceManager &SM) override {}
143*67e74705SXin Li
emitNote(SourceLocation Loc,StringRef Message,const SourceManager * SM)144*67e74705SXin Li void emitNote(SourceLocation Loc, StringRef Message,
145*67e74705SXin Li const SourceManager *SM) override {
146*67e74705SXin Li CXSourceLocation L;
147*67e74705SXin Li if (SM)
148*67e74705SXin Li L = translateSourceLocation(*SM, LangOpts, Loc);
149*67e74705SXin Li else
150*67e74705SXin Li L = clang_getNullLocation();
151*67e74705SXin Li CurrentSet->appendDiagnostic(
152*67e74705SXin Li llvm::make_unique<CXDiagnosticCustomNoteImpl>(Message, L));
153*67e74705SXin Li }
154*67e74705SXin Li
155*67e74705SXin Li CXDiagnosticSetImpl *CurrentSet;
156*67e74705SXin Li CXDiagnosticSetImpl *MainSet;
157*67e74705SXin Li };
158*67e74705SXin Li }
159*67e74705SXin Li
lazyCreateDiags(CXTranslationUnit TU,bool checkIfChanged)160*67e74705SXin Li CXDiagnosticSetImpl *cxdiag::lazyCreateDiags(CXTranslationUnit TU,
161*67e74705SXin Li bool checkIfChanged) {
162*67e74705SXin Li ASTUnit *AU = cxtu::getASTUnit(TU);
163*67e74705SXin Li
164*67e74705SXin Li if (TU->Diagnostics && checkIfChanged) {
165*67e74705SXin Li // In normal use, ASTUnit's diagnostics should not change unless we reparse.
166*67e74705SXin Li // Currently they can only change by using the internal testing flag
167*67e74705SXin Li // '-error-on-deserialized-decl' which will error during deserialization of
168*67e74705SXin Li // a declaration. What will happen is:
169*67e74705SXin Li //
170*67e74705SXin Li // -c-index-test gets a CXTranslationUnit
171*67e74705SXin Li // -checks the diagnostics, the diagnostics set is lazily created,
172*67e74705SXin Li // no errors are reported
173*67e74705SXin Li // -later does an operation, like annotation of tokens, that triggers
174*67e74705SXin Li // -error-on-deserialized-decl, that will emit a diagnostic error,
175*67e74705SXin Li // that ASTUnit will catch and add to its stored diagnostics vector.
176*67e74705SXin Li // -c-index-test wants to check whether an error occurred after performing
177*67e74705SXin Li // the operation but can only query the lazily created set.
178*67e74705SXin Li //
179*67e74705SXin Li // We check here if a new diagnostic was appended since the last time the
180*67e74705SXin Li // diagnostic set was created, in which case we reset it.
181*67e74705SXin Li
182*67e74705SXin Li CXDiagnosticSetImpl *
183*67e74705SXin Li Set = static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
184*67e74705SXin Li if (AU->stored_diag_size() != Set->getNumDiagnostics()) {
185*67e74705SXin Li // Diagnostics in the ASTUnit were updated, reset the associated
186*67e74705SXin Li // diagnostics.
187*67e74705SXin Li delete Set;
188*67e74705SXin Li TU->Diagnostics = nullptr;
189*67e74705SXin Li }
190*67e74705SXin Li }
191*67e74705SXin Li
192*67e74705SXin Li if (!TU->Diagnostics) {
193*67e74705SXin Li CXDiagnosticSetImpl *Set = new CXDiagnosticSetImpl();
194*67e74705SXin Li TU->Diagnostics = Set;
195*67e74705SXin Li IntrusiveRefCntPtr<DiagnosticOptions> DOpts = new DiagnosticOptions;
196*67e74705SXin Li CXDiagnosticRenderer Renderer(AU->getASTContext().getLangOpts(),
197*67e74705SXin Li &*DOpts, Set);
198*67e74705SXin Li
199*67e74705SXin Li for (ASTUnit::stored_diag_iterator it = AU->stored_diag_begin(),
200*67e74705SXin Li ei = AU->stored_diag_end(); it != ei; ++it) {
201*67e74705SXin Li Renderer.emitStoredDiagnostic(*it);
202*67e74705SXin Li }
203*67e74705SXin Li }
204*67e74705SXin Li return static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
205*67e74705SXin Li }
206*67e74705SXin Li
207*67e74705SXin Li //-----------------------------------------------------------------------------
208*67e74705SXin Li // C Interface Routines
209*67e74705SXin Li //-----------------------------------------------------------------------------
210*67e74705SXin Li extern "C" {
211*67e74705SXin Li
clang_getNumDiagnostics(CXTranslationUnit Unit)212*67e74705SXin Li unsigned clang_getNumDiagnostics(CXTranslationUnit Unit) {
213*67e74705SXin Li if (cxtu::isNotUsableTU(Unit)) {
214*67e74705SXin Li LOG_BAD_TU(Unit);
215*67e74705SXin Li return 0;
216*67e74705SXin Li }
217*67e74705SXin Li if (!cxtu::getASTUnit(Unit))
218*67e74705SXin Li return 0;
219*67e74705SXin Li return lazyCreateDiags(Unit, /*checkIfChanged=*/true)->getNumDiagnostics();
220*67e74705SXin Li }
221*67e74705SXin Li
clang_getDiagnostic(CXTranslationUnit Unit,unsigned Index)222*67e74705SXin Li CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, unsigned Index) {
223*67e74705SXin Li if (cxtu::isNotUsableTU(Unit)) {
224*67e74705SXin Li LOG_BAD_TU(Unit);
225*67e74705SXin Li return nullptr;
226*67e74705SXin Li }
227*67e74705SXin Li
228*67e74705SXin Li CXDiagnosticSet D = clang_getDiagnosticSetFromTU(Unit);
229*67e74705SXin Li if (!D)
230*67e74705SXin Li return nullptr;
231*67e74705SXin Li
232*67e74705SXin Li CXDiagnosticSetImpl *Diags = static_cast<CXDiagnosticSetImpl*>(D);
233*67e74705SXin Li if (Index >= Diags->getNumDiagnostics())
234*67e74705SXin Li return nullptr;
235*67e74705SXin Li
236*67e74705SXin Li return Diags->getDiagnostic(Index);
237*67e74705SXin Li }
238*67e74705SXin Li
clang_getDiagnosticSetFromTU(CXTranslationUnit Unit)239*67e74705SXin Li CXDiagnosticSet clang_getDiagnosticSetFromTU(CXTranslationUnit Unit) {
240*67e74705SXin Li if (cxtu::isNotUsableTU(Unit)) {
241*67e74705SXin Li LOG_BAD_TU(Unit);
242*67e74705SXin Li return nullptr;
243*67e74705SXin Li }
244*67e74705SXin Li if (!cxtu::getASTUnit(Unit))
245*67e74705SXin Li return nullptr;
246*67e74705SXin Li return static_cast<CXDiagnostic>(lazyCreateDiags(Unit));
247*67e74705SXin Li }
248*67e74705SXin Li
clang_disposeDiagnostic(CXDiagnostic Diagnostic)249*67e74705SXin Li void clang_disposeDiagnostic(CXDiagnostic Diagnostic) {
250*67e74705SXin Li // No-op. Kept as a legacy API. CXDiagnostics are now managed
251*67e74705SXin Li // by the enclosing CXDiagnosticSet.
252*67e74705SXin Li }
253*67e74705SXin Li
clang_formatDiagnostic(CXDiagnostic Diagnostic,unsigned Options)254*67e74705SXin Li CXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options) {
255*67e74705SXin Li if (!Diagnostic)
256*67e74705SXin Li return cxstring::createEmpty();
257*67e74705SXin Li
258*67e74705SXin Li CXDiagnosticSeverity Severity = clang_getDiagnosticSeverity(Diagnostic);
259*67e74705SXin Li
260*67e74705SXin Li SmallString<256> Str;
261*67e74705SXin Li llvm::raw_svector_ostream Out(Str);
262*67e74705SXin Li
263*67e74705SXin Li if (Options & CXDiagnostic_DisplaySourceLocation) {
264*67e74705SXin Li // Print source location (file:line), along with optional column
265*67e74705SXin Li // and source ranges.
266*67e74705SXin Li CXFile File;
267*67e74705SXin Li unsigned Line, Column;
268*67e74705SXin Li clang_getSpellingLocation(clang_getDiagnosticLocation(Diagnostic),
269*67e74705SXin Li &File, &Line, &Column, nullptr);
270*67e74705SXin Li if (File) {
271*67e74705SXin Li CXString FName = clang_getFileName(File);
272*67e74705SXin Li Out << clang_getCString(FName) << ":" << Line << ":";
273*67e74705SXin Li clang_disposeString(FName);
274*67e74705SXin Li if (Options & CXDiagnostic_DisplayColumn)
275*67e74705SXin Li Out << Column << ":";
276*67e74705SXin Li
277*67e74705SXin Li if (Options & CXDiagnostic_DisplaySourceRanges) {
278*67e74705SXin Li unsigned N = clang_getDiagnosticNumRanges(Diagnostic);
279*67e74705SXin Li bool PrintedRange = false;
280*67e74705SXin Li for (unsigned I = 0; I != N; ++I) {
281*67e74705SXin Li CXFile StartFile, EndFile;
282*67e74705SXin Li CXSourceRange Range = clang_getDiagnosticRange(Diagnostic, I);
283*67e74705SXin Li
284*67e74705SXin Li unsigned StartLine, StartColumn, EndLine, EndColumn;
285*67e74705SXin Li clang_getSpellingLocation(clang_getRangeStart(Range),
286*67e74705SXin Li &StartFile, &StartLine, &StartColumn,
287*67e74705SXin Li nullptr);
288*67e74705SXin Li clang_getSpellingLocation(clang_getRangeEnd(Range),
289*67e74705SXin Li &EndFile, &EndLine, &EndColumn, nullptr);
290*67e74705SXin Li
291*67e74705SXin Li if (StartFile != EndFile || StartFile != File)
292*67e74705SXin Li continue;
293*67e74705SXin Li
294*67e74705SXin Li Out << "{" << StartLine << ":" << StartColumn << "-"
295*67e74705SXin Li << EndLine << ":" << EndColumn << "}";
296*67e74705SXin Li PrintedRange = true;
297*67e74705SXin Li }
298*67e74705SXin Li if (PrintedRange)
299*67e74705SXin Li Out << ":";
300*67e74705SXin Li }
301*67e74705SXin Li
302*67e74705SXin Li Out << " ";
303*67e74705SXin Li }
304*67e74705SXin Li }
305*67e74705SXin Li
306*67e74705SXin Li /* Print warning/error/etc. */
307*67e74705SXin Li switch (Severity) {
308*67e74705SXin Li case CXDiagnostic_Ignored: llvm_unreachable("impossible");
309*67e74705SXin Li case CXDiagnostic_Note: Out << "note: "; break;
310*67e74705SXin Li case CXDiagnostic_Warning: Out << "warning: "; break;
311*67e74705SXin Li case CXDiagnostic_Error: Out << "error: "; break;
312*67e74705SXin Li case CXDiagnostic_Fatal: Out << "fatal error: "; break;
313*67e74705SXin Li }
314*67e74705SXin Li
315*67e74705SXin Li CXString Text = clang_getDiagnosticSpelling(Diagnostic);
316*67e74705SXin Li if (clang_getCString(Text))
317*67e74705SXin Li Out << clang_getCString(Text);
318*67e74705SXin Li else
319*67e74705SXin Li Out << "<no diagnostic text>";
320*67e74705SXin Li clang_disposeString(Text);
321*67e74705SXin Li
322*67e74705SXin Li if (Options & (CXDiagnostic_DisplayOption | CXDiagnostic_DisplayCategoryId |
323*67e74705SXin Li CXDiagnostic_DisplayCategoryName)) {
324*67e74705SXin Li bool NeedBracket = true;
325*67e74705SXin Li bool NeedComma = false;
326*67e74705SXin Li
327*67e74705SXin Li if (Options & CXDiagnostic_DisplayOption) {
328*67e74705SXin Li CXString OptionName = clang_getDiagnosticOption(Diagnostic, nullptr);
329*67e74705SXin Li if (const char *OptionText = clang_getCString(OptionName)) {
330*67e74705SXin Li if (OptionText[0]) {
331*67e74705SXin Li Out << " [" << OptionText;
332*67e74705SXin Li NeedBracket = false;
333*67e74705SXin Li NeedComma = true;
334*67e74705SXin Li }
335*67e74705SXin Li }
336*67e74705SXin Li clang_disposeString(OptionName);
337*67e74705SXin Li }
338*67e74705SXin Li
339*67e74705SXin Li if (Options & (CXDiagnostic_DisplayCategoryId |
340*67e74705SXin Li CXDiagnostic_DisplayCategoryName)) {
341*67e74705SXin Li if (unsigned CategoryID = clang_getDiagnosticCategory(Diagnostic)) {
342*67e74705SXin Li if (Options & CXDiagnostic_DisplayCategoryId) {
343*67e74705SXin Li if (NeedBracket)
344*67e74705SXin Li Out << " [";
345*67e74705SXin Li if (NeedComma)
346*67e74705SXin Li Out << ", ";
347*67e74705SXin Li Out << CategoryID;
348*67e74705SXin Li NeedBracket = false;
349*67e74705SXin Li NeedComma = true;
350*67e74705SXin Li }
351*67e74705SXin Li
352*67e74705SXin Li if (Options & CXDiagnostic_DisplayCategoryName) {
353*67e74705SXin Li CXString CategoryName = clang_getDiagnosticCategoryText(Diagnostic);
354*67e74705SXin Li if (NeedBracket)
355*67e74705SXin Li Out << " [";
356*67e74705SXin Li if (NeedComma)
357*67e74705SXin Li Out << ", ";
358*67e74705SXin Li Out << clang_getCString(CategoryName);
359*67e74705SXin Li NeedBracket = false;
360*67e74705SXin Li NeedComma = true;
361*67e74705SXin Li clang_disposeString(CategoryName);
362*67e74705SXin Li }
363*67e74705SXin Li }
364*67e74705SXin Li }
365*67e74705SXin Li
366*67e74705SXin Li (void) NeedComma; // Silence dead store warning.
367*67e74705SXin Li if (!NeedBracket)
368*67e74705SXin Li Out << "]";
369*67e74705SXin Li }
370*67e74705SXin Li
371*67e74705SXin Li return cxstring::createDup(Out.str());
372*67e74705SXin Li }
373*67e74705SXin Li
clang_defaultDiagnosticDisplayOptions()374*67e74705SXin Li unsigned clang_defaultDiagnosticDisplayOptions() {
375*67e74705SXin Li return CXDiagnostic_DisplaySourceLocation | CXDiagnostic_DisplayColumn |
376*67e74705SXin Li CXDiagnostic_DisplayOption;
377*67e74705SXin Li }
378*67e74705SXin Li
clang_getDiagnosticSeverity(CXDiagnostic Diag)379*67e74705SXin Li enum CXDiagnosticSeverity clang_getDiagnosticSeverity(CXDiagnostic Diag) {
380*67e74705SXin Li if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl*>(Diag))
381*67e74705SXin Li return D->getSeverity();
382*67e74705SXin Li return CXDiagnostic_Ignored;
383*67e74705SXin Li }
384*67e74705SXin Li
clang_getDiagnosticLocation(CXDiagnostic Diag)385*67e74705SXin Li CXSourceLocation clang_getDiagnosticLocation(CXDiagnostic Diag) {
386*67e74705SXin Li if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl*>(Diag))
387*67e74705SXin Li return D->getLocation();
388*67e74705SXin Li return clang_getNullLocation();
389*67e74705SXin Li }
390*67e74705SXin Li
clang_getDiagnosticSpelling(CXDiagnostic Diag)391*67e74705SXin Li CXString clang_getDiagnosticSpelling(CXDiagnostic Diag) {
392*67e74705SXin Li if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
393*67e74705SXin Li return D->getSpelling();
394*67e74705SXin Li return cxstring::createEmpty();
395*67e74705SXin Li }
396*67e74705SXin Li
clang_getDiagnosticOption(CXDiagnostic Diag,CXString * Disable)397*67e74705SXin Li CXString clang_getDiagnosticOption(CXDiagnostic Diag, CXString *Disable) {
398*67e74705SXin Li if (Disable)
399*67e74705SXin Li *Disable = cxstring::createEmpty();
400*67e74705SXin Li
401*67e74705SXin Li if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
402*67e74705SXin Li return D->getDiagnosticOption(Disable);
403*67e74705SXin Li
404*67e74705SXin Li return cxstring::createEmpty();
405*67e74705SXin Li }
406*67e74705SXin Li
clang_getDiagnosticCategory(CXDiagnostic Diag)407*67e74705SXin Li unsigned clang_getDiagnosticCategory(CXDiagnostic Diag) {
408*67e74705SXin Li if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
409*67e74705SXin Li return D->getCategory();
410*67e74705SXin Li return 0;
411*67e74705SXin Li }
412*67e74705SXin Li
clang_getDiagnosticCategoryName(unsigned Category)413*67e74705SXin Li CXString clang_getDiagnosticCategoryName(unsigned Category) {
414*67e74705SXin Li // Kept for backward compatibility.
415*67e74705SXin Li return cxstring::createRef(DiagnosticIDs::getCategoryNameFromID(Category));
416*67e74705SXin Li }
417*67e74705SXin Li
clang_getDiagnosticCategoryText(CXDiagnostic Diag)418*67e74705SXin Li CXString clang_getDiagnosticCategoryText(CXDiagnostic Diag) {
419*67e74705SXin Li if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
420*67e74705SXin Li return D->getCategoryText();
421*67e74705SXin Li return cxstring::createEmpty();
422*67e74705SXin Li }
423*67e74705SXin Li
clang_getDiagnosticNumRanges(CXDiagnostic Diag)424*67e74705SXin Li unsigned clang_getDiagnosticNumRanges(CXDiagnostic Diag) {
425*67e74705SXin Li if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
426*67e74705SXin Li return D->getNumRanges();
427*67e74705SXin Li return 0;
428*67e74705SXin Li }
429*67e74705SXin Li
clang_getDiagnosticRange(CXDiagnostic Diag,unsigned Range)430*67e74705SXin Li CXSourceRange clang_getDiagnosticRange(CXDiagnostic Diag, unsigned Range) {
431*67e74705SXin Li CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag);
432*67e74705SXin Li if (!D || Range >= D->getNumRanges())
433*67e74705SXin Li return clang_getNullRange();
434*67e74705SXin Li return D->getRange(Range);
435*67e74705SXin Li }
436*67e74705SXin Li
clang_getDiagnosticNumFixIts(CXDiagnostic Diag)437*67e74705SXin Li unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diag) {
438*67e74705SXin Li if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
439*67e74705SXin Li return D->getNumFixIts();
440*67e74705SXin Li return 0;
441*67e74705SXin Li }
442*67e74705SXin Li
clang_getDiagnosticFixIt(CXDiagnostic Diag,unsigned FixIt,CXSourceRange * ReplacementRange)443*67e74705SXin Li CXString clang_getDiagnosticFixIt(CXDiagnostic Diag, unsigned FixIt,
444*67e74705SXin Li CXSourceRange *ReplacementRange) {
445*67e74705SXin Li CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag);
446*67e74705SXin Li if (!D || FixIt >= D->getNumFixIts()) {
447*67e74705SXin Li if (ReplacementRange)
448*67e74705SXin Li *ReplacementRange = clang_getNullRange();
449*67e74705SXin Li return cxstring::createEmpty();
450*67e74705SXin Li }
451*67e74705SXin Li return D->getFixIt(FixIt, ReplacementRange);
452*67e74705SXin Li }
453*67e74705SXin Li
clang_disposeDiagnosticSet(CXDiagnosticSet Diags)454*67e74705SXin Li void clang_disposeDiagnosticSet(CXDiagnosticSet Diags) {
455*67e74705SXin Li if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl *>(Diags)) {
456*67e74705SXin Li if (D->isExternallyManaged())
457*67e74705SXin Li delete D;
458*67e74705SXin Li }
459*67e74705SXin Li }
460*67e74705SXin Li
clang_getDiagnosticInSet(CXDiagnosticSet Diags,unsigned Index)461*67e74705SXin Li CXDiagnostic clang_getDiagnosticInSet(CXDiagnosticSet Diags,
462*67e74705SXin Li unsigned Index) {
463*67e74705SXin Li if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags))
464*67e74705SXin Li if (Index < D->getNumDiagnostics())
465*67e74705SXin Li return D->getDiagnostic(Index);
466*67e74705SXin Li return nullptr;
467*67e74705SXin Li }
468*67e74705SXin Li
clang_getChildDiagnostics(CXDiagnostic Diag)469*67e74705SXin Li CXDiagnosticSet clang_getChildDiagnostics(CXDiagnostic Diag) {
470*67e74705SXin Li if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag)) {
471*67e74705SXin Li CXDiagnosticSetImpl &ChildDiags = D->getChildDiagnostics();
472*67e74705SXin Li return ChildDiags.empty() ? nullptr : (CXDiagnosticSet) &ChildDiags;
473*67e74705SXin Li }
474*67e74705SXin Li return nullptr;
475*67e74705SXin Li }
476*67e74705SXin Li
clang_getNumDiagnosticsInSet(CXDiagnosticSet Diags)477*67e74705SXin Li unsigned clang_getNumDiagnosticsInSet(CXDiagnosticSet Diags) {
478*67e74705SXin Li if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags))
479*67e74705SXin Li return D->getNumDiagnostics();
480*67e74705SXin Li return 0;
481*67e74705SXin Li }
482*67e74705SXin Li
483*67e74705SXin Li } // end extern "C"
484