1a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor/*===-- CIndexDiagnostics.cpp - Diagnostics C Interface ---------*- C++ -*-===*\
25352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor|*                                                                            *|
35352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor|*                     The LLVM Compiler Infrastructure                       *|
45352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor|*                                                                            *|
55352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor|* This file is distributed under the University of Illinois Open Source      *|
65352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor|* License. See LICENSE.TXT for details.                                      *|
75352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor|*                                                                            *|
85352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor|*===----------------------------------------------------------------------===*|
95352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor|*                                                                            *|
105352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor|* Implements the diagnostic functions of the Clang C interface.              *|
115352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor|*                                                                            *|
125352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor\*===----------------------------------------------------------------------===*/
135352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor#include "CIndexDiagnostic.h"
145352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor#include "CIndexer.h"
150a90d32523bfe5fa63e11b648686c9699f786d15Ted Kremenek#include "CXTranslationUnit.h"
165352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor#include "CXSourceLocation.h"
17ed122735639d83c10f18c28c7fd117bfcd0f62cbTed Kremenek#include "CXString.h"
185352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor
19b846debc1b22a37228efe4aa87b34482d15b6a3cBenjamin Kramer#include "clang/Frontend/ASTUnit.h"
20d93256e55673a17d18543397ec462416acb13792Douglas Gregor#include "clang/Frontend/FrontendDiagnostic.h"
217473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek#include "clang/Frontend/DiagnosticRenderer.h"
2202c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor#include "clang/Basic/DiagnosticOptions.h"
23274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor#include "llvm/ADT/SmallString.h"
24a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor#include "llvm/ADT/Twine.h"
25d93256e55673a17d18543397ec462416acb13792Douglas Gregor#include "llvm/Support/MemoryBuffer.h"
26274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor#include "llvm/Support/raw_ostream.h"
27d93256e55673a17d18543397ec462416acb13792Douglas Gregor
285352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregorusing namespace clang;
295352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregorusing namespace clang::cxloc;
30996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidisusing namespace clang::cxdiag;
31a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorusing namespace llvm;
325352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor
33153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
34153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekCXDiagnosticSetImpl::~CXDiagnosticSetImpl() {
35153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  for (std::vector<CXDiagnosticImpl *>::iterator it = Diagnostics.begin(),
36153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek       et = Diagnostics.end();
37153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek       it != et; ++it) {
38153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    delete *it;
39153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  }
40153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek}
41153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
42153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekCXDiagnosticImpl::~CXDiagnosticImpl() {}
43153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
447473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremeneknamespace {
457473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenekclass CXDiagnosticCustomNoteImpl : public CXDiagnosticImpl {
467b8290f7e53e1b9f5521dd284e78ad488a12f0d0Ted Kremenek  std::string Message;
477473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  CXSourceLocation Loc;
487473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenekpublic:
497473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  CXDiagnosticCustomNoteImpl(StringRef Msg, CXSourceLocation L)
507473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    : CXDiagnosticImpl(CustomNoteDiagnosticKind),
517b8290f7e53e1b9f5521dd284e78ad488a12f0d0Ted Kremenek      Message(Msg), Loc(L) {}
527473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
537b8290f7e53e1b9f5521dd284e78ad488a12f0d0Ted Kremenek  virtual ~CXDiagnosticCustomNoteImpl() {}
547473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
557473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  CXDiagnosticSeverity getSeverity() const {
567473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    return CXDiagnostic_Note;
577473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  }
587473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
597473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  CXSourceLocation getLocation() const {
607473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    return Loc;
617473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  }
627473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
637473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  CXString getSpelling() const {
645595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko    return cxstring::createRef(Message.c_str());
657473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  }
667473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
677473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  CXString getDiagnosticOption(CXString *Disable) const {
687473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    if (Disable)
69dc66adb40ee871b4c578ba615f45d82476c7119eDmitri Gribenko      *Disable = cxstring::createEmpty();
70dc66adb40ee871b4c578ba615f45d82476c7119eDmitri Gribenko    return cxstring::createEmpty();
717473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  }
727473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
737473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  unsigned getCategory() const { return 0; }
74dc66adb40ee871b4c578ba615f45d82476c7119eDmitri Gribenko  CXString getCategoryText() const { return cxstring::createEmpty(); }
7578d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek
767473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  unsigned getNumRanges() const { return 0; }
777473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  CXSourceRange getRange(unsigned Range) const { return clang_getNullRange(); }
787473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  unsigned getNumFixIts() const { return 0; }
797473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  CXString getFixIt(unsigned FixIt, CXSourceRange *ReplacementRange) const {
807473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    if (ReplacementRange)
817473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek      *ReplacementRange = clang_getNullRange();
82dc66adb40ee871b4c578ba615f45d82476c7119eDmitri Gribenko    return cxstring::createEmpty();
837473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  }
847473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek};
857473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
867473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenekclass CXDiagnosticRenderer : public DiagnosticNoteRenderer {
877473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenekpublic:
8816afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis  CXDiagnosticRenderer(const LangOptions &LangOpts,
8902c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor                       DiagnosticOptions *DiagOpts,
907473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek                       CXDiagnosticSetImpl *mainSet)
9116afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis  : DiagnosticNoteRenderer(LangOpts, DiagOpts),
927473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    CurrentSet(mainSet), MainSet(mainSet) {}
937473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
947473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  virtual ~CXDiagnosticRenderer() {}
957473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
967473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  virtual void beginDiagnostic(DiagOrStoredDiag D,
977473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek                               DiagnosticsEngine::Level Level) {
987473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
997473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    const StoredDiagnostic *SD = D.dyn_cast<const StoredDiagnostic*>();
1007473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    if (!SD)
1017473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek      return;
1027473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
1037473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    if (Level != DiagnosticsEngine::Note)
1047473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek      CurrentSet = MainSet;
1057473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
1067473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    CXStoredDiagnostic *CD = new CXStoredDiagnostic(*SD, LangOpts);
1077473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    CurrentSet->appendDiagnostic(CD);
1087473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
1097473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    if (Level != DiagnosticsEngine::Note)
1107473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek      CurrentSet = &CD->getChildDiagnostics();
1117473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  }
1127473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
1137473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  virtual void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc,
1147473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek                                     DiagnosticsEngine::Level Level,
1157473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek                                     StringRef Message,
1167473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek                                     ArrayRef<CharSourceRange> Ranges,
11716afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis                                     const SourceManager *SM,
1187473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek                                     DiagOrStoredDiag D) {
1197473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    if (!D.isNull())
1207473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek      return;
1217473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
12216afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis    CXSourceLocation L;
12316afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis    if (SM)
12416afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis      L = translateSourceLocation(*SM, LangOpts, Loc);
12516afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis    else
12616afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis      L = clang_getNullLocation();
1277473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    CXDiagnosticImpl *CD = new CXDiagnosticCustomNoteImpl(Message, L);
1287473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    CurrentSet->appendDiagnostic(CD);
1297473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  }
1307473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
1317473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
1327473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek                                 DiagnosticsEngine::Level Level,
13316afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis                                 ArrayRef<CharSourceRange> Ranges,
13416afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis                                 const SourceManager &SM) {}
1357473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
1367473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  virtual void emitCodeContext(SourceLocation Loc,
1377473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek                               DiagnosticsEngine::Level Level,
1387473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek                               SmallVectorImpl<CharSourceRange>& Ranges,
13916afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis                               ArrayRef<FixItHint> Hints,
14016afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis                               const SourceManager &SM) {}
1417473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
14216afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis  virtual void emitNote(SourceLocation Loc, StringRef Message,
14316afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis                        const SourceManager *SM) {
14416afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis    CXSourceLocation L;
14516afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis    if (SM)
14616afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis      L = translateSourceLocation(*SM, LangOpts, Loc);
14716afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis    else
14816afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis      L = clang_getNullLocation();
1497473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    CurrentSet->appendDiagnostic(new CXDiagnosticCustomNoteImpl(Message,
1507473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek                                                                L));
1517473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  }
1527473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
1537473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  CXDiagnosticSetImpl *CurrentSet;
1547473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  CXDiagnosticSetImpl *MainSet;
1557473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek};
1567473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek}
1577473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
158996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios KyrtzidisCXDiagnosticSetImpl *cxdiag::lazyCreateDiags(CXTranslationUnit TU,
159996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidis                                             bool checkIfChanged) {
1605694feb5ccd6eb862cb600b55753cecc13794471Dmitri Gribenko  ASTUnit *AU = cxtu::getASTUnit(TU);
161220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis
162220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis  if (TU->Diagnostics && checkIfChanged) {
163c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    // In normal use, ASTUnit's diagnostics should not change unless we reparse.
164c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    // Currently they can only change by using the internal testing flag
165c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    // '-error-on-deserialized-decl' which will error during deserialization of
166c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    // a declaration. What will happen is:
167c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //
168c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //  -c-index-test gets a CXTranslationUnit
169c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //  -checks the diagnostics, the diagnostics set is lazily created,
170c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //     no errors are reported
171c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //  -later does an operation, like annotation of tokens, that triggers
172c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //     -error-on-deserialized-decl, that will emit a diagnostic error,
173c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //     that ASTUnit will catch and add to its stored diagnostics vector.
174c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //  -c-index-test wants to check whether an error occurred after performing
175c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //     the operation but can only query the lazily created set.
176c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //
177c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    // We check here if a new diagnostic was appended since the last time the
178c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    // diagnostic set was created, in which case we reset it.
179c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis
180220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis    CXDiagnosticSetImpl *
181220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis      Set = static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
182220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis    if (AU->stored_diag_size() != Set->getNumDiagnostics()) {
183220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis      // Diagnostics in the ASTUnit were updated, reset the associated
184220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis      // diagnostics.
185220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis      delete Set;
186220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis      TU->Diagnostics = 0;
187220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis    }
188220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis  }
189220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis
190153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (!TU->Diagnostics) {
191153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    CXDiagnosticSetImpl *Set = new CXDiagnosticSetImpl();
192153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    TU->Diagnostics = Set;
193cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko    IntrusiveRefCntPtr<DiagnosticOptions> DOpts = new DiagnosticOptions;
19416afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis    CXDiagnosticRenderer Renderer(AU->getASTContext().getLangOpts(),
19502c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor                                  &*DOpts, Set);
196153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
197153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    for (ASTUnit::stored_diag_iterator it = AU->stored_diag_begin(),
198153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek         ei = AU->stored_diag_end(); it != ei; ++it) {
1997473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek      Renderer.emitStoredDiagnostic(*it);
200153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    }
201153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  }
202153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  return static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
203153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek}
204153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
2055352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor//-----------------------------------------------------------------------------
206a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor// C Interface Routines
2075352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor//-----------------------------------------------------------------------------
208a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorextern "C" {
2094914612675787cda11ad6b31735e130a81a1d7a1Daniel Dunbar
210a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorunsigned clang_getNumDiagnostics(CXTranslationUnit Unit) {
211e42e578ad8a36ad5bd06c8a3110cbd3119aaee36Dmitri Gribenko  if (!cxtu::getASTUnit(Unit))
212153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    return 0;
213220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis  return lazyCreateDiags(Unit, /*checkIfChanged=*/true)->getNumDiagnostics();
2145352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor}
2155352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor
216a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas GregorCXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, unsigned Index) {
2170373fcc3e5b205cc26656c70d7dff737b0e08345Ted Kremenek  CXDiagnosticSet D = clang_getDiagnosticSetFromTU(Unit);
2180373fcc3e5b205cc26656c70d7dff737b0e08345Ted Kremenek  if (!D)
219153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    return 0;
220153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
2210373fcc3e5b205cc26656c70d7dff737b0e08345Ted Kremenek  CXDiagnosticSetImpl *Diags = static_cast<CXDiagnosticSetImpl*>(D);
222153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (Index >= Diags->getNumDiagnostics())
223a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor    return 0;
2244914612675787cda11ad6b31735e130a81a1d7a1Daniel Dunbar
225153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  return Diags->getDiagnostic(Index);
2265352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor}
2270373fcc3e5b205cc26656c70d7dff737b0e08345Ted Kremenek
2280373fcc3e5b205cc26656c70d7dff737b0e08345Ted KremenekCXDiagnosticSet clang_getDiagnosticSetFromTU(CXTranslationUnit Unit) {
229e42e578ad8a36ad5bd06c8a3110cbd3119aaee36Dmitri Gribenko  if (!cxtu::getASTUnit(Unit))
2300373fcc3e5b205cc26656c70d7dff737b0e08345Ted Kremenek    return 0;
2310373fcc3e5b205cc26656c70d7dff737b0e08345Ted Kremenek  return static_cast<CXDiagnostic>(lazyCreateDiags(Unit));
2320373fcc3e5b205cc26656c70d7dff737b0e08345Ted Kremenek}
2335352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor
234a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorvoid clang_disposeDiagnostic(CXDiagnostic Diagnostic) {
235153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  // No-op.  Kept as a legacy API.  CXDiagnostics are now managed
236153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  // by the enclosing CXDiagnosticSet.
237a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor}
238ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek
239274f1906f12ebf8fcc179701deeda6d3271120c1Douglas GregorCXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options) {
240274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor  if (!Diagnostic)
241dc66adb40ee871b4c578ba615f45d82476c7119eDmitri Gribenko    return cxstring::createEmpty();
2420a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
2430a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  CXDiagnosticSeverity Severity = clang_getDiagnosticSeverity(Diagnostic);
2440a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
24536d592718ff342f762e32cbde73d1113f88cb275Dylan Noblesmith  SmallString<256> Str;
246274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor  llvm::raw_svector_ostream Out(Str);
247274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor
2480a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  if (Options & CXDiagnostic_DisplaySourceLocation) {
2490a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor    // Print source location (file:line), along with optional column
2500a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor    // and source ranges.
2510a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor    CXFile File;
2520a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor    unsigned Line, Column;
253a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor    clang_getSpellingLocation(clang_getDiagnosticLocation(Diagnostic),
254a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor                              &File, &Line, &Column, 0);
2550a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor    if (File) {
2560a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor      CXString FName = clang_getFileName(File);
257274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor      Out << clang_getCString(FName) << ":" << Line << ":";
2580a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor      clang_disposeString(FName);
2590a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor      if (Options & CXDiagnostic_DisplayColumn)
260274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor        Out << Column << ":";
2610a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
2620a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor      if (Options & CXDiagnostic_DisplaySourceRanges) {
2630a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor        unsigned N = clang_getDiagnosticNumRanges(Diagnostic);
2640a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor        bool PrintedRange = false;
2650a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor        for (unsigned I = 0; I != N; ++I) {
2660a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor          CXFile StartFile, EndFile;
2670a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor          CXSourceRange Range = clang_getDiagnosticRange(Diagnostic, I);
2680a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
2690a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor          unsigned StartLine, StartColumn, EndLine, EndColumn;
270a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor          clang_getSpellingLocation(clang_getRangeStart(Range),
271a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor                                    &StartFile, &StartLine, &StartColumn,
272a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor                                    0);
273a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor          clang_getSpellingLocation(clang_getRangeEnd(Range),
274a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor                                    &EndFile, &EndLine, &EndColumn, 0);
2750a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
2760a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor          if (StartFile != EndFile || StartFile != File)
2770a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor            continue;
2780a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
279274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor          Out << "{" << StartLine << ":" << StartColumn << "-"
280274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor              << EndLine << ":" << EndColumn << "}";
2810a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor          PrintedRange = true;
2820a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor        }
2830a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor        if (PrintedRange)
284274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor          Out << ":";
2850a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor      }
2864cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor
2874cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor      Out << " ";
2880a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor    }
2890a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  }
2900a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
2910a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  /* Print warning/error/etc. */
2920a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  switch (Severity) {
293eb2d1f1c88836bd5382e5d7aa8f6b85148a88b27David Blaikie  case CXDiagnostic_Ignored: llvm_unreachable("impossible");
294274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor  case CXDiagnostic_Note: Out << "note: "; break;
295274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor  case CXDiagnostic_Warning: Out << "warning: "; break;
296274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor  case CXDiagnostic_Error: Out << "error: "; break;
297274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor  case CXDiagnostic_Fatal: Out << "fatal error: "; break;
2980a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  }
2990a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
3000a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  CXString Text = clang_getDiagnosticSpelling(Diagnostic);
3010a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  if (clang_getCString(Text))
302274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor    Out << clang_getCString(Text);
3030a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  else
304274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor    Out << "<no diagnostic text>";
3050a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  clang_disposeString(Text);
306aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
307aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor  if (Options & (CXDiagnostic_DisplayOption | CXDiagnostic_DisplayCategoryId |
308aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor                 CXDiagnostic_DisplayCategoryName)) {
309aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor    bool NeedBracket = true;
310aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor    bool NeedComma = false;
311aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
312aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor    if (Options & CXDiagnostic_DisplayOption) {
313aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor      CXString OptionName = clang_getDiagnosticOption(Diagnostic, 0);
314aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor      if (const char *OptionText = clang_getCString(OptionName)) {
315aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor        if (OptionText[0]) {
316aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          Out << " [" << OptionText;
317aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          NeedBracket = false;
318aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          NeedComma = true;
319aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor        }
320aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor      }
321aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor      clang_disposeString(OptionName);
322aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor    }
323aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
324aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor    if (Options & (CXDiagnostic_DisplayCategoryId |
325aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor                   CXDiagnostic_DisplayCategoryName)) {
326aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor      if (unsigned CategoryID = clang_getDiagnosticCategory(Diagnostic)) {
327aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor        if (Options & CXDiagnostic_DisplayCategoryId) {
328aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          if (NeedBracket)
329aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor            Out << " [";
330aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          if (NeedComma)
331aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor            Out << ", ";
332aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          Out << CategoryID;
333aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          NeedBracket = false;
334aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          NeedComma = true;
335aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor        }
336aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
337aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor        if (Options & CXDiagnostic_DisplayCategoryName) {
33878d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek          CXString CategoryName = clang_getDiagnosticCategoryText(Diagnostic);
339aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          if (NeedBracket)
340aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor            Out << " [";
341aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          if (NeedComma)
342aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor            Out << ", ";
343aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          Out << clang_getCString(CategoryName);
344aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          NeedBracket = false;
345aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          NeedComma = true;
346aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          clang_disposeString(CategoryName);
347aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor        }
348aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor      }
349aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor    }
3508e59838ed66eb8a853927a43fc25f974ee2ee838Ted Kremenek
3518e59838ed66eb8a853927a43fc25f974ee2ee838Ted Kremenek    (void) NeedComma; // Silence dead store warning.
352aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor    if (!NeedBracket)
353aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor      Out << "]";
354aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor  }
355aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
3565595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko  return cxstring::createDup(Out.str());
3570a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor}
3580a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
3590a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregorunsigned clang_defaultDiagnosticDisplayOptions() {
360aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor  return CXDiagnostic_DisplaySourceLocation | CXDiagnostic_DisplayColumn |
361aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor         CXDiagnostic_DisplayOption;
3620a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor}
3630a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
3645352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregorenum CXDiagnosticSeverity clang_getDiagnosticSeverity(CXDiagnostic Diag) {
3651edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl*>(Diag))
3661edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek    return D->getSeverity();
3675352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor  return CXDiagnostic_Ignored;
3685352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor}
369ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek
3705352ac06d8f6194825bb2a99ffa009b61bafb503Douglas GregorCXSourceLocation clang_getDiagnosticLocation(CXDiagnostic Diag) {
3711edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl*>(Diag))
3721edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek    return D->getLocation();
3731edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  return clang_getNullLocation();
3745352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor}
3755352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor
3765352ac06d8f6194825bb2a99ffa009b61bafb503Douglas GregorCXString clang_getDiagnosticSpelling(CXDiagnostic Diag) {
3771edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
3781edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek    return D->getSpelling();
379dc66adb40ee871b4c578ba615f45d82476c7119eDmitri Gribenko  return cxstring::createEmpty();
3805352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor}
3815352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor
382aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas GregorCXString clang_getDiagnosticOption(CXDiagnostic Diag, CXString *Disable) {
383aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor  if (Disable)
384dc66adb40ee871b4c578ba615f45d82476c7119eDmitri Gribenko    *Disable = cxstring::createEmpty();
3851edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek
3861edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
3871edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek    return D->getDiagnosticOption(Disable);
388aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
389dc66adb40ee871b4c578ba615f45d82476c7119eDmitri Gribenko  return cxstring::createEmpty();
390aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor}
391aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
392aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregorunsigned clang_getDiagnosticCategory(CXDiagnostic Diag) {
3931edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
3941edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek    return D->getCategory();
3951edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  return 0;
396aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor}
397aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
398aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas GregorCXString clang_getDiagnosticCategoryName(unsigned Category) {
39978d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek  // Kept for backwards compatibility.
4005595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko  return cxstring::createRef(DiagnosticIDs::getCategoryNameFromID(Category));
401aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor}
402aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
40378d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted KremenekCXString clang_getDiagnosticCategoryText(CXDiagnostic Diag) {
40478d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
40578d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek    return D->getCategoryText();
406dc66adb40ee871b4c578ba615f45d82476c7119eDmitri Gribenko  return cxstring::createEmpty();
40778d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek}
40878d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek
409a3890baf1256ff26081306c7fef70202f8223f41Douglas Gregorunsigned clang_getDiagnosticNumRanges(CXDiagnostic Diag) {
4101edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
4111edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek    return D->getNumRanges();
4121edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  return 0;
413a3890baf1256ff26081306c7fef70202f8223f41Douglas Gregor}
414ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek
415a3890baf1256ff26081306c7fef70202f8223f41Douglas GregorCXSourceRange clang_getDiagnosticRange(CXDiagnostic Diag, unsigned Range) {
4161edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag);
4171edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (!D || Range >= D->getNumRanges())
418a3890baf1256ff26081306c7fef70202f8223f41Douglas Gregor    return clang_getNullRange();
4191edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  return D->getRange(Range);
4205352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor}
4215352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor
4225352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregorunsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diag) {
4231edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
4241edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek    return D->getNumFixIts();
4251edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  return 0;
4265352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor}
4275352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor
4281edabbc32a07654d9b9fe44f50533ff146abd03eTed KremenekCXString clang_getDiagnosticFixIt(CXDiagnostic Diag, unsigned FixIt,
429473d7019bb54f8a2f0140dca9e9644a935cc6b20Douglas Gregor                                  CXSourceRange *ReplacementRange) {
4301edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag);
4311edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (!D || FixIt >= D->getNumFixIts()) {
432473d7019bb54f8a2f0140dca9e9644a935cc6b20Douglas Gregor    if (ReplacementRange)
433473d7019bb54f8a2f0140dca9e9644a935cc6b20Douglas Gregor      *ReplacementRange = clang_getNullRange();
434dc66adb40ee871b4c578ba615f45d82476c7119eDmitri Gribenko    return cxstring::createEmpty();
4355352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor  }
4361edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  return D->getFixIt(FixIt, ReplacementRange);
4375352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor}
438ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek
439153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenekvoid clang_disposeDiagnosticSet(CXDiagnosticSet Diags) {
440153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags);
441153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (D->isExternallyManaged())
442153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    delete D;
443153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek}
444153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
445153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekCXDiagnostic clang_getDiagnosticInSet(CXDiagnosticSet Diags,
446153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek                                      unsigned Index) {
447153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags))
448153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    if (Index < D->getNumDiagnostics())
449153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek      return D->getDiagnostic(Index);
450153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  return 0;
451153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek}
452153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
453153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekCXDiagnosticSet clang_getChildDiagnostics(CXDiagnostic Diag) {
454153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag)) {
455153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    CXDiagnosticSetImpl &ChildDiags = D->getChildDiagnostics();
456153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    return ChildDiags.empty() ? 0 : (CXDiagnosticSet) &ChildDiags;
457153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  }
458153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  return 0;
459153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek}
460153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
461153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenekunsigned clang_getNumDiagnosticsInSet(CXDiagnosticSet Diags) {
462153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags))
463153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    return D->getNumDiagnostics();
464153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  return 0;
465153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek}
466153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
4675352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor} // end extern "C"
468