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