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"
227473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek#include "clang/Frontend/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;
30ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenekusing namespace clang::cxstring;
31996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidisusing namespace clang::cxdiag;
32a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorusing namespace llvm;
335352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor
34153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
35153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekCXDiagnosticSetImpl::~CXDiagnosticSetImpl() {
36153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  for (std::vector<CXDiagnosticImpl *>::iterator it = Diagnostics.begin(),
37153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek       et = Diagnostics.end();
38153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek       it != et; ++it) {
39153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    delete *it;
40153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  }
41153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek}
42153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
43153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekCXDiagnosticImpl::~CXDiagnosticImpl() {}
44153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
457473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremeneknamespace {
467473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenekclass CXDiagnosticCustomNoteImpl : public CXDiagnosticImpl {
477b8290f7e53e1b9f5521dd284e78ad488a12f0d0Ted Kremenek  std::string Message;
487473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  CXSourceLocation Loc;
497473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenekpublic:
507473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  CXDiagnosticCustomNoteImpl(StringRef Msg, CXSourceLocation L)
517473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    : CXDiagnosticImpl(CustomNoteDiagnosticKind),
527b8290f7e53e1b9f5521dd284e78ad488a12f0d0Ted Kremenek      Message(Msg), Loc(L) {}
537473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
547b8290f7e53e1b9f5521dd284e78ad488a12f0d0Ted Kremenek  virtual ~CXDiagnosticCustomNoteImpl() {}
557473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
567473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  CXDiagnosticSeverity getSeverity() const {
577473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    return CXDiagnostic_Note;
587473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  }
597473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
607473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  CXSourceLocation getLocation() const {
617473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    return Loc;
627473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  }
637473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
647473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  CXString getSpelling() const {
657b8290f7e53e1b9f5521dd284e78ad488a12f0d0Ted Kremenek    return createCXString(StringRef(Message), false);
667473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  }
677473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
687473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  CXString getDiagnosticOption(CXString *Disable) const {
697473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    if (Disable)
707473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek      *Disable = createCXString("", false);
717473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    return createCXString("", false);
727473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  }
737473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
747473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  unsigned getCategory() const { return 0; }
7578d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek  CXString getCategoryText() const { return createCXString(""); }
7678d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek
777473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  unsigned getNumRanges() const { return 0; }
787473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  CXSourceRange getRange(unsigned Range) const { return clang_getNullRange(); }
797473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  unsigned getNumFixIts() const { return 0; }
807473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  CXString getFixIt(unsigned FixIt, CXSourceRange *ReplacementRange) const {
817473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    if (ReplacementRange)
827473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek      *ReplacementRange = clang_getNullRange();
837473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    return createCXString("", false);
847473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  }
857473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek};
867473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
877473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenekclass CXDiagnosticRenderer : public DiagnosticNoteRenderer {
887473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenekpublic:
8916afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis  CXDiagnosticRenderer(const LangOptions &LangOpts,
907473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek                       const DiagnosticOptions &DiagOpts,
917473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek                       CXDiagnosticSetImpl *mainSet)
9216afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis  : DiagnosticNoteRenderer(LangOpts, DiagOpts),
937473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    CurrentSet(mainSet), MainSet(mainSet) {}
947473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
957473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  virtual ~CXDiagnosticRenderer() {}
967473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
977473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  virtual void beginDiagnostic(DiagOrStoredDiag D,
987473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek                               DiagnosticsEngine::Level Level) {
997473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
1007473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    const StoredDiagnostic *SD = D.dyn_cast<const StoredDiagnostic*>();
1017473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    if (!SD)
1027473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek      return;
1037473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
1047473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    if (Level != DiagnosticsEngine::Note)
1057473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek      CurrentSet = MainSet;
1067473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
1077473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    CXStoredDiagnostic *CD = new CXStoredDiagnostic(*SD, LangOpts);
1087473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    CurrentSet->appendDiagnostic(CD);
1097473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
1107473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    if (Level != DiagnosticsEngine::Note)
1117473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek      CurrentSet = &CD->getChildDiagnostics();
1127473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  }
1137473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
1147473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  virtual void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc,
1157473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek                                     DiagnosticsEngine::Level Level,
1167473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek                                     StringRef Message,
1177473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek                                     ArrayRef<CharSourceRange> Ranges,
11816afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis                                     const SourceManager *SM,
1197473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek                                     DiagOrStoredDiag D) {
1207473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    if (!D.isNull())
1217473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek      return;
1227473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
12316afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis    CXSourceLocation L;
12416afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis    if (SM)
12516afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis      L = translateSourceLocation(*SM, LangOpts, Loc);
12616afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis    else
12716afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis      L = clang_getNullLocation();
1287473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    CXDiagnosticImpl *CD = new CXDiagnosticCustomNoteImpl(Message, L);
1297473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    CurrentSet->appendDiagnostic(CD);
1307473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  }
1317473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
1327473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
1337473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek                                 DiagnosticsEngine::Level Level,
13416afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis                                 ArrayRef<CharSourceRange> Ranges,
13516afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis                                 const SourceManager &SM) {}
1367473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
1377473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  virtual void emitCodeContext(SourceLocation Loc,
1387473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek                               DiagnosticsEngine::Level Level,
1397473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek                               SmallVectorImpl<CharSourceRange>& Ranges,
14016afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis                               ArrayRef<FixItHint> Hints,
14116afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis                               const SourceManager &SM) {}
1427473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
14316afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis  virtual void emitNote(SourceLocation Loc, StringRef Message,
14416afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis                        const SourceManager *SM) {
14516afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis    CXSourceLocation L;
14616afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis    if (SM)
14716afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis      L = translateSourceLocation(*SM, LangOpts, Loc);
14816afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis    else
14916afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis      L = clang_getNullLocation();
1507473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    CurrentSet->appendDiagnostic(new CXDiagnosticCustomNoteImpl(Message,
1517473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek                                                                L));
1527473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  }
1537473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
1547473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  CXDiagnosticSetImpl *CurrentSet;
1557473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  CXDiagnosticSetImpl *MainSet;
1567473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek};
1577473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek}
1587473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
159996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios KyrtzidisCXDiagnosticSetImpl *cxdiag::lazyCreateDiags(CXTranslationUnit TU,
160996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidis                                             bool checkIfChanged) {
161220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis  ASTUnit *AU = static_cast<ASTUnit *>(TU->TUData);
162220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis
163220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis  if (TU->Diagnostics && checkIfChanged) {
164c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    // In normal use, ASTUnit's diagnostics should not change unless we reparse.
165c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    // Currently they can only change by using the internal testing flag
166c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    // '-error-on-deserialized-decl' which will error during deserialization of
167c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    // a declaration. What will happen is:
168c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //
169c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //  -c-index-test gets a CXTranslationUnit
170c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //  -checks the diagnostics, the diagnostics set is lazily created,
171c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //     no errors are reported
172c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //  -later does an operation, like annotation of tokens, that triggers
173c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //     -error-on-deserialized-decl, that will emit a diagnostic error,
174c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //     that ASTUnit will catch and add to its stored diagnostics vector.
175c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //  -c-index-test wants to check whether an error occurred after performing
176c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //     the operation but can only query the lazily created set.
177c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //
178c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    // We check here if a new diagnostic was appended since the last time the
179c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    // diagnostic set was created, in which case we reset it.
180c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis
181220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis    CXDiagnosticSetImpl *
182220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis      Set = static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
183220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis    if (AU->stored_diag_size() != Set->getNumDiagnostics()) {
184220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis      // Diagnostics in the ASTUnit were updated, reset the associated
185220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis      // diagnostics.
186220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis      delete Set;
187220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis      TU->Diagnostics = 0;
188220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis    }
189220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis  }
190220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis
191153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (!TU->Diagnostics) {
192153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    CXDiagnosticSetImpl *Set = new CXDiagnosticSetImpl();
193153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    TU->Diagnostics = Set;
1947473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    DiagnosticOptions DOpts;
19516afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis    CXDiagnosticRenderer Renderer(AU->getASTContext().getLangOpts(),
1967473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek                                  DOpts, Set);
197153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
198153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    for (ASTUnit::stored_diag_iterator it = AU->stored_diag_begin(),
199153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek         ei = AU->stored_diag_end(); it != ei; ++it) {
2007473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek      Renderer.emitStoredDiagnostic(*it);
201153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    }
202153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  }
203153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  return static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
204153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek}
205153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
2065352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor//-----------------------------------------------------------------------------
207a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor// C Interface Routines
2085352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor//-----------------------------------------------------------------------------
209a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorextern "C" {
2104914612675787cda11ad6b31735e130a81a1d7a1Daniel Dunbar
211a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorunsigned clang_getNumDiagnostics(CXTranslationUnit Unit) {
212153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (!Unit->TUData)
213153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    return 0;
214220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis  return lazyCreateDiags(Unit, /*checkIfChanged=*/true)->getNumDiagnostics();
2155352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor}
2165352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor
217a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas GregorCXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, unsigned Index) {
2180373fcc3e5b205cc26656c70d7dff737b0e08345Ted Kremenek  CXDiagnosticSet D = clang_getDiagnosticSetFromTU(Unit);
2190373fcc3e5b205cc26656c70d7dff737b0e08345Ted Kremenek  if (!D)
220153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    return 0;
221153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
2220373fcc3e5b205cc26656c70d7dff737b0e08345Ted Kremenek  CXDiagnosticSetImpl *Diags = static_cast<CXDiagnosticSetImpl*>(D);
223153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (Index >= Diags->getNumDiagnostics())
224a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor    return 0;
2254914612675787cda11ad6b31735e130a81a1d7a1Daniel Dunbar
226153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  return Diags->getDiagnostic(Index);
2275352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor}
2280373fcc3e5b205cc26656c70d7dff737b0e08345Ted Kremenek
2290373fcc3e5b205cc26656c70d7dff737b0e08345Ted KremenekCXDiagnosticSet clang_getDiagnosticSetFromTU(CXTranslationUnit Unit) {
2300373fcc3e5b205cc26656c70d7dff737b0e08345Ted Kremenek  if (!Unit->TUData)
2310373fcc3e5b205cc26656c70d7dff737b0e08345Ted Kremenek    return 0;
2320373fcc3e5b205cc26656c70d7dff737b0e08345Ted Kremenek  return static_cast<CXDiagnostic>(lazyCreateDiags(Unit));
2330373fcc3e5b205cc26656c70d7dff737b0e08345Ted Kremenek}
2345352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor
235a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorvoid clang_disposeDiagnostic(CXDiagnostic Diagnostic) {
236153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  // No-op.  Kept as a legacy API.  CXDiagnostics are now managed
237153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  // by the enclosing CXDiagnosticSet.
238a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor}
239ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek
240274f1906f12ebf8fcc179701deeda6d3271120c1Douglas GregorCXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options) {
241274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor  if (!Diagnostic)
242274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor    return createCXString("");
2430a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
2440a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  CXDiagnosticSeverity Severity = clang_getDiagnosticSeverity(Diagnostic);
2450a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
24636d592718ff342f762e32cbde73d1113f88cb275Dylan Noblesmith  SmallString<256> Str;
247274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor  llvm::raw_svector_ostream Out(Str);
248274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor
2490a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  if (Options & CXDiagnostic_DisplaySourceLocation) {
2500a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor    // Print source location (file:line), along with optional column
2510a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor    // and source ranges.
2520a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor    CXFile File;
2530a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor    unsigned Line, Column;
254a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor    clang_getSpellingLocation(clang_getDiagnosticLocation(Diagnostic),
255a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor                              &File, &Line, &Column, 0);
2560a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor    if (File) {
2570a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor      CXString FName = clang_getFileName(File);
258274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor      Out << clang_getCString(FName) << ":" << Line << ":";
2590a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor      clang_disposeString(FName);
2600a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor      if (Options & CXDiagnostic_DisplayColumn)
261274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor        Out << Column << ":";
2620a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
2630a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor      if (Options & CXDiagnostic_DisplaySourceRanges) {
2640a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor        unsigned N = clang_getDiagnosticNumRanges(Diagnostic);
2650a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor        bool PrintedRange = false;
2660a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor        for (unsigned I = 0; I != N; ++I) {
2670a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor          CXFile StartFile, EndFile;
2680a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor          CXSourceRange Range = clang_getDiagnosticRange(Diagnostic, I);
2690a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
2700a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor          unsigned StartLine, StartColumn, EndLine, EndColumn;
271a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor          clang_getSpellingLocation(clang_getRangeStart(Range),
272a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor                                    &StartFile, &StartLine, &StartColumn,
273a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor                                    0);
274a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor          clang_getSpellingLocation(clang_getRangeEnd(Range),
275a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor                                    &EndFile, &EndLine, &EndColumn, 0);
2760a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
2770a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor          if (StartFile != EndFile || StartFile != File)
2780a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor            continue;
2790a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
280274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor          Out << "{" << StartLine << ":" << StartColumn << "-"
281274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor              << EndLine << ":" << EndColumn << "}";
2820a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor          PrintedRange = true;
2830a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor        }
2840a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor        if (PrintedRange)
285274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor          Out << ":";
2860a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor      }
2874cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor
2884cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor      Out << " ";
2890a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor    }
2900a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  }
2910a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
2920a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  /* Print warning/error/etc. */
2930a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  switch (Severity) {
294eb2d1f1c88836bd5382e5d7aa8f6b85148a88b27David Blaikie  case CXDiagnostic_Ignored: llvm_unreachable("impossible");
295274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor  case CXDiagnostic_Note: Out << "note: "; break;
296274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor  case CXDiagnostic_Warning: Out << "warning: "; break;
297274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor  case CXDiagnostic_Error: Out << "error: "; break;
298274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor  case CXDiagnostic_Fatal: Out << "fatal error: "; break;
2990a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  }
3000a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
3010a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  CXString Text = clang_getDiagnosticSpelling(Diagnostic);
3020a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  if (clang_getCString(Text))
303274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor    Out << clang_getCString(Text);
3040a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  else
305274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor    Out << "<no diagnostic text>";
3060a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  clang_disposeString(Text);
307aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
308aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor  if (Options & (CXDiagnostic_DisplayOption | CXDiagnostic_DisplayCategoryId |
309aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor                 CXDiagnostic_DisplayCategoryName)) {
310aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor    bool NeedBracket = true;
311aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor    bool NeedComma = false;
312aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
313aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor    if (Options & CXDiagnostic_DisplayOption) {
314aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor      CXString OptionName = clang_getDiagnosticOption(Diagnostic, 0);
315aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor      if (const char *OptionText = clang_getCString(OptionName)) {
316aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor        if (OptionText[0]) {
317aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          Out << " [" << OptionText;
318aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          NeedBracket = false;
319aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          NeedComma = true;
320aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor        }
321aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor      }
322aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor      clang_disposeString(OptionName);
323aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor    }
324aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
325aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor    if (Options & (CXDiagnostic_DisplayCategoryId |
326aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor                   CXDiagnostic_DisplayCategoryName)) {
327aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor      if (unsigned CategoryID = clang_getDiagnosticCategory(Diagnostic)) {
328aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor        if (Options & CXDiagnostic_DisplayCategoryId) {
329aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          if (NeedBracket)
330aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor            Out << " [";
331aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          if (NeedComma)
332aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor            Out << ", ";
333aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          Out << CategoryID;
334aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          NeedBracket = false;
335aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          NeedComma = true;
336aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor        }
337aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
338aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor        if (Options & CXDiagnostic_DisplayCategoryName) {
33978d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek          CXString CategoryName = clang_getDiagnosticCategoryText(Diagnostic);
340aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          if (NeedBracket)
341aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor            Out << " [";
342aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          if (NeedComma)
343aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor            Out << ", ";
344aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          Out << clang_getCString(CategoryName);
345aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          NeedBracket = false;
346aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          NeedComma = true;
347aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          clang_disposeString(CategoryName);
348aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor        }
349aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor      }
350aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor    }
3518e59838ed66eb8a853927a43fc25f974ee2ee838Ted Kremenek
3528e59838ed66eb8a853927a43fc25f974ee2ee838Ted Kremenek    (void) NeedComma; // Silence dead store warning.
353aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor    if (!NeedBracket)
354aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor      Out << "]";
355aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor  }
356aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
357274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor  return createCXString(Out.str(), true);
3580a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor}
3590a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
3600a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregorunsigned clang_defaultDiagnosticDisplayOptions() {
361aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor  return CXDiagnostic_DisplaySourceLocation | CXDiagnostic_DisplayColumn |
362aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor         CXDiagnostic_DisplayOption;
3630a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor}
3640a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
3655352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregorenum CXDiagnosticSeverity clang_getDiagnosticSeverity(CXDiagnostic Diag) {
3661edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl*>(Diag))
3671edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek    return D->getSeverity();
3685352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor  return CXDiagnostic_Ignored;
3695352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor}
370ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek
3715352ac06d8f6194825bb2a99ffa009b61bafb503Douglas GregorCXSourceLocation clang_getDiagnosticLocation(CXDiagnostic Diag) {
3721edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl*>(Diag))
3731edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek    return D->getLocation();
3741edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  return clang_getNullLocation();
3755352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor}
3765352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor
3775352ac06d8f6194825bb2a99ffa009b61bafb503Douglas GregorCXString clang_getDiagnosticSpelling(CXDiagnostic Diag) {
3781edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
3791edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek    return D->getSpelling();
3801edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  return createCXString("");
3815352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor}
3825352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor
383aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas GregorCXString clang_getDiagnosticOption(CXDiagnostic Diag, CXString *Disable) {
384aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor  if (Disable)
385aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor    *Disable = createCXString("");
3861edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek
3871edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
3881edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek    return D->getDiagnosticOption(Disable);
389aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
390aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor  return createCXString("");
391aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor}
392aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
393aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregorunsigned clang_getDiagnosticCategory(CXDiagnostic Diag) {
3941edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
3951edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek    return D->getCategory();
3961edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  return 0;
397aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor}
398aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
399aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas GregorCXString clang_getDiagnosticCategoryName(unsigned Category) {
40078d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek  // Kept for backwards compatibility.
401aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor  return createCXString(DiagnosticIDs::getCategoryNameFromID(Category));
402aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor}
403aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
40478d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted KremenekCXString clang_getDiagnosticCategoryText(CXDiagnostic Diag) {
40578d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
40678d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek    return D->getCategoryText();
40778d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek  return createCXString("");
40878d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek}
40978d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek
410a3890baf1256ff26081306c7fef70202f8223f41Douglas Gregorunsigned clang_getDiagnosticNumRanges(CXDiagnostic Diag) {
4111edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
4121edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek    return D->getNumRanges();
4131edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  return 0;
414a3890baf1256ff26081306c7fef70202f8223f41Douglas Gregor}
415ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek
416a3890baf1256ff26081306c7fef70202f8223f41Douglas GregorCXSourceRange clang_getDiagnosticRange(CXDiagnostic Diag, unsigned Range) {
4171edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag);
4181edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (!D || Range >= D->getNumRanges())
419a3890baf1256ff26081306c7fef70202f8223f41Douglas Gregor    return clang_getNullRange();
4201edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  return D->getRange(Range);
4215352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor}
4225352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor
4235352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregorunsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diag) {
4241edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
4251edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek    return D->getNumFixIts();
4261edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  return 0;
4275352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor}
4285352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor
4291edabbc32a07654d9b9fe44f50533ff146abd03eTed KremenekCXString clang_getDiagnosticFixIt(CXDiagnostic Diag, unsigned FixIt,
430473d7019bb54f8a2f0140dca9e9644a935cc6b20Douglas Gregor                                  CXSourceRange *ReplacementRange) {
4311edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag);
4321edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (!D || FixIt >= D->getNumFixIts()) {
433473d7019bb54f8a2f0140dca9e9644a935cc6b20Douglas Gregor    if (ReplacementRange)
434473d7019bb54f8a2f0140dca9e9644a935cc6b20Douglas Gregor      *ReplacementRange = clang_getNullRange();
435ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek    return createCXString("");
4365352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor  }
4371edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  return D->getFixIt(FixIt, ReplacementRange);
4385352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor}
439ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek
440153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenekvoid clang_disposeDiagnosticSet(CXDiagnosticSet Diags) {
441153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags);
442153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (D->isExternallyManaged())
443153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    delete D;
444153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek}
445153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
446153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekCXDiagnostic clang_getDiagnosticInSet(CXDiagnosticSet Diags,
447153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek                                      unsigned Index) {
448153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags))
449153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    if (Index < D->getNumDiagnostics())
450153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek      return D->getDiagnostic(Index);
451153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  return 0;
452153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek}
453153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
454153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekCXDiagnosticSet clang_getChildDiagnostics(CXDiagnostic Diag) {
455153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag)) {
456153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    CXDiagnosticSetImpl &ChildDiags = D->getChildDiagnostics();
457153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    return ChildDiags.empty() ? 0 : (CXDiagnosticSet) &ChildDiags;
458153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  }
459153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  return 0;
460153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek}
461153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
462153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenekunsigned clang_getNumDiagnosticsInSet(CXDiagnosticSet Diags) {
463153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags))
464153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    return D->getNumDiagnostics();
465153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  return 0;
466153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek}
467153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
4685352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor} // end extern "C"
469