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
33176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesCXDiagnosticSetImpl::~CXDiagnosticSetImpl() {}
34153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
35176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid
36176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesCXDiagnosticSetImpl::appendDiagnostic(std::unique_ptr<CXDiagnosticImpl> D) {
37176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  Diagnostics.push_back(std::move(D));
38153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek}
39153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
40153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekCXDiagnosticImpl::~CXDiagnosticImpl() {}
41153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
427473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremeneknamespace {
437473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenekclass CXDiagnosticCustomNoteImpl : public CXDiagnosticImpl {
447b8290f7e53e1b9f5521dd284e78ad488a12f0d0Ted Kremenek  std::string Message;
457473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  CXSourceLocation Loc;
467473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenekpublic:
477473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  CXDiagnosticCustomNoteImpl(StringRef Msg, CXSourceLocation L)
487473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    : CXDiagnosticImpl(CustomNoteDiagnosticKind),
497b8290f7e53e1b9f5521dd284e78ad488a12f0d0Ted Kremenek      Message(Msg), Loc(L) {}
507473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
5133337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  ~CXDiagnosticCustomNoteImpl() override {}
52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
53651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CXDiagnosticSeverity getSeverity() const override {
547473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    return CXDiagnostic_Note;
557473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  }
56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
57651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CXSourceLocation getLocation() const override {
587473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    return Loc;
597473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  }
60651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
61651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CXString getSpelling() const override {
625595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko    return cxstring::createRef(Message.c_str());
637473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  }
64651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
65651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CXString getDiagnosticOption(CXString *Disable) const override {
667473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    if (Disable)
67dc66adb40ee871b4c578ba615f45d82476c7119eDmitri Gribenko      *Disable = cxstring::createEmpty();
68dc66adb40ee871b4c578ba615f45d82476c7119eDmitri Gribenko    return cxstring::createEmpty();
697473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  }
7078d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek
71651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned getCategory() const override { return 0; }
72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CXString getCategoryText() const override { return cxstring::createEmpty(); }
73651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned getNumRanges() const override { return 0; }
75651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CXSourceRange getRange(unsigned Range) const override {
76651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return clang_getNullRange();
77651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
78651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned getNumFixIts() const override { return 0; }
79651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CXString getFixIt(unsigned FixIt,
80651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    CXSourceRange *ReplacementRange) const override {
817473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    if (ReplacementRange)
827473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek      *ReplacementRange = clang_getNullRange();
83dc66adb40ee871b4c578ba615f45d82476c7119eDmitri Gribenko    return cxstring::createEmpty();
847473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  }
857473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek};
867473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
877473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenekclass CXDiagnosticRenderer : public DiagnosticNoteRenderer {
887473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenekpublic:
8916afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis  CXDiagnosticRenderer(const LangOptions &LangOpts,
9002c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor                       DiagnosticOptions *DiagOpts,
917473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek                       CXDiagnosticSetImpl *mainSet)
9216afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis  : DiagnosticNoteRenderer(LangOpts, DiagOpts),
937473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    CurrentSet(mainSet), MainSet(mainSet) {}
9433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar
9533337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar  ~CXDiagnosticRenderer() override {}
967473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
97651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void beginDiagnostic(DiagOrStoredDiag D,
98651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                       DiagnosticsEngine::Level Level) override {
99651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
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;
106176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
107176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    auto Owner = llvm::make_unique<CXStoredDiagnostic>(*SD, LangOpts);
108176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    CXStoredDiagnostic &CD = *Owner;
109176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    CurrentSet->appendDiagnostic(std::move(Owner));
110176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
1117473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    if (Level != DiagnosticsEngine::Note)
112176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      CurrentSet = &CD.getChildDiagnostics();
1137473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  }
114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc,
116651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                             DiagnosticsEngine::Level Level,
117651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                             StringRef Message,
118651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                             ArrayRef<CharSourceRange> Ranges,
119651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                             const SourceManager *SM,
120651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                             DiagOrStoredDiag D) override {
1217473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek    if (!D.isNull())
1227473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek      return;
1237473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
12416afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis    CXSourceLocation L;
12516afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis    if (SM)
12616afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis      L = translateSourceLocation(*SM, LangOpts, Loc);
12716afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis    else
12816afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis      L = clang_getNullLocation();
129176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    CurrentSet->appendDiagnostic(
130176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        llvm::make_unique<CXDiagnosticCustomNoteImpl>(Message, L));
1317473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  }
132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                         DiagnosticsEngine::Level Level,
135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                         ArrayRef<CharSourceRange> Ranges,
136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                         const SourceManager &SM) override {}
137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void emitCodeContext(SourceLocation Loc,
139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                       DiagnosticsEngine::Level Level,
140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                       SmallVectorImpl<CharSourceRange>& Ranges,
141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                       ArrayRef<FixItHint> Hints,
142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                       const SourceManager &SM) override {}
143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void emitNote(SourceLocation Loc, StringRef Message,
145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                const SourceManager *SM) override {
14616afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis    CXSourceLocation L;
14716afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis    if (SM)
14816afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis      L = translateSourceLocation(*SM, LangOpts, Loc);
14916afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis    else
15016afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis      L = clang_getNullLocation();
151176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    CurrentSet->appendDiagnostic(
152176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        llvm::make_unique<CXDiagnosticCustomNoteImpl>(Message, L));
1537473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  }
1547473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
1557473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  CXDiagnosticSetImpl *CurrentSet;
1567473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek  CXDiagnosticSetImpl *MainSet;
1577473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek};
1587473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek}
1597473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek
160996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios KyrtzidisCXDiagnosticSetImpl *cxdiag::lazyCreateDiags(CXTranslationUnit TU,
161996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidis                                             bool checkIfChanged) {
1625694feb5ccd6eb862cb600b55753cecc13794471Dmitri Gribenko  ASTUnit *AU = cxtu::getASTUnit(TU);
163220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis
164220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis  if (TU->Diagnostics && checkIfChanged) {
165c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    // In normal use, ASTUnit's diagnostics should not change unless we reparse.
166c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    // Currently they can only change by using the internal testing flag
167c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    // '-error-on-deserialized-decl' which will error during deserialization of
168c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    // a declaration. What will happen is:
169c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //
170c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //  -c-index-test gets a CXTranslationUnit
171c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //  -checks the diagnostics, the diagnostics set is lazily created,
172c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //     no errors are reported
173c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //  -later does an operation, like annotation of tokens, that triggers
174c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //     -error-on-deserialized-decl, that will emit a diagnostic error,
175c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //     that ASTUnit will catch and add to its stored diagnostics vector.
176c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //  -c-index-test wants to check whether an error occurred after performing
177c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //     the operation but can only query the lazily created set.
178c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    //
179c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    // We check here if a new diagnostic was appended since the last time the
180c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis    // diagnostic set was created, in which case we reset it.
181c88e58c0db75e7b5f9f14da0a255a0be01acf877Argyrios Kyrtzidis
182220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis    CXDiagnosticSetImpl *
183220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis      Set = static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
184220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis    if (AU->stored_diag_size() != Set->getNumDiagnostics()) {
185220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis      // Diagnostics in the ASTUnit were updated, reset the associated
186220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis      // diagnostics.
187220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis      delete Set;
188c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      TU->Diagnostics = nullptr;
189220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis    }
190220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis  }
191220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis
192153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (!TU->Diagnostics) {
193153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    CXDiagnosticSetImpl *Set = new CXDiagnosticSetImpl();
194153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    TU->Diagnostics = Set;
195cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko    IntrusiveRefCntPtr<DiagnosticOptions> DOpts = new DiagnosticOptions;
19616afdf76b6f12e41ff6f6e6828bfb1d4732523baArgyrios Kyrtzidis    CXDiagnosticRenderer Renderer(AU->getASTContext().getLangOpts(),
19702c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor                                  &*DOpts, Set);
198153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
199153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    for (ASTUnit::stored_diag_iterator it = AU->stored_diag_begin(),
200153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek         ei = AU->stored_diag_end(); it != ei; ++it) {
2017473b1c6e7ba2654d4a0d469198f0e01b485b51aTed Kremenek      Renderer.emitStoredDiagnostic(*it);
202153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    }
203153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  }
204153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  return static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
205153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek}
206153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
2075352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor//-----------------------------------------------------------------------------
208a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor// C Interface Routines
2095352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor//-----------------------------------------------------------------------------
210a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorextern "C" {
2114914612675787cda11ad6b31735e130a81a1d7a1Daniel Dunbar
212a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorunsigned clang_getNumDiagnostics(CXTranslationUnit Unit) {
213651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (cxtu::isNotUsableTU(Unit)) {
214651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    LOG_BAD_TU(Unit);
215651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return 0;
216651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
217e42e578ad8a36ad5bd06c8a3110cbd3119aaee36Dmitri Gribenko  if (!cxtu::getASTUnit(Unit))
218153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    return 0;
219220b45c95edc0ea86cd157426e0edc7f6a288620Argyrios Kyrtzidis  return lazyCreateDiags(Unit, /*checkIfChanged=*/true)->getNumDiagnostics();
2205352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor}
2215352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor
222a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas GregorCXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, unsigned Index) {
223651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (cxtu::isNotUsableTU(Unit)) {
224651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    LOG_BAD_TU(Unit);
225c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    return nullptr;
226651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
227651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
2280373fcc3e5b205cc26656c70d7dff737b0e08345Ted Kremenek  CXDiagnosticSet D = clang_getDiagnosticSetFromTU(Unit);
2290373fcc3e5b205cc26656c70d7dff737b0e08345Ted Kremenek  if (!D)
230c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    return nullptr;
231153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
2320373fcc3e5b205cc26656c70d7dff737b0e08345Ted Kremenek  CXDiagnosticSetImpl *Diags = static_cast<CXDiagnosticSetImpl*>(D);
233153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (Index >= Diags->getNumDiagnostics())
234c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    return nullptr;
2354914612675787cda11ad6b31735e130a81a1d7a1Daniel Dunbar
236153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  return Diags->getDiagnostic(Index);
2375352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor}
238651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
2390373fcc3e5b205cc26656c70d7dff737b0e08345Ted KremenekCXDiagnosticSet clang_getDiagnosticSetFromTU(CXTranslationUnit Unit) {
240651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (cxtu::isNotUsableTU(Unit)) {
241651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    LOG_BAD_TU(Unit);
242c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    return nullptr;
243651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
244e42e578ad8a36ad5bd06c8a3110cbd3119aaee36Dmitri Gribenko  if (!cxtu::getASTUnit(Unit))
245c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    return nullptr;
2460373fcc3e5b205cc26656c70d7dff737b0e08345Ted Kremenek  return static_cast<CXDiagnostic>(lazyCreateDiags(Unit));
2470373fcc3e5b205cc26656c70d7dff737b0e08345Ted Kremenek}
2485352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor
249a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorvoid clang_disposeDiagnostic(CXDiagnostic Diagnostic) {
250153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  // No-op.  Kept as a legacy API.  CXDiagnostics are now managed
251153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  // by the enclosing CXDiagnosticSet.
252a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor}
253ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek
254274f1906f12ebf8fcc179701deeda6d3271120c1Douglas GregorCXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options) {
255274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor  if (!Diagnostic)
256dc66adb40ee871b4c578ba615f45d82476c7119eDmitri Gribenko    return cxstring::createEmpty();
2570a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
2580a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  CXDiagnosticSeverity Severity = clang_getDiagnosticSeverity(Diagnostic);
2590a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
26036d592718ff342f762e32cbde73d1113f88cb275Dylan Noblesmith  SmallString<256> Str;
261274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor  llvm::raw_svector_ostream Out(Str);
262274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor
2630a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  if (Options & CXDiagnostic_DisplaySourceLocation) {
2640a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor    // Print source location (file:line), along with optional column
2650a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor    // and source ranges.
2660a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor    CXFile File;
2670a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor    unsigned Line, Column;
268a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor    clang_getSpellingLocation(clang_getDiagnosticLocation(Diagnostic),
269c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                              &File, &Line, &Column, nullptr);
2700a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor    if (File) {
2710a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor      CXString FName = clang_getFileName(File);
272274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor      Out << clang_getCString(FName) << ":" << Line << ":";
2730a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor      clang_disposeString(FName);
2740a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor      if (Options & CXDiagnostic_DisplayColumn)
275274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor        Out << Column << ":";
2760a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
2770a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor      if (Options & CXDiagnostic_DisplaySourceRanges) {
2780a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor        unsigned N = clang_getDiagnosticNumRanges(Diagnostic);
2790a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor        bool PrintedRange = false;
2800a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor        for (unsigned I = 0; I != N; ++I) {
2810a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor          CXFile StartFile, EndFile;
2820a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor          CXSourceRange Range = clang_getDiagnosticRange(Diagnostic, I);
2830a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
2840a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor          unsigned StartLine, StartColumn, EndLine, EndColumn;
285a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor          clang_getSpellingLocation(clang_getRangeStart(Range),
286a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor                                    &StartFile, &StartLine, &StartColumn,
287c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                                    nullptr);
288a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor          clang_getSpellingLocation(clang_getRangeEnd(Range),
289c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                                    &EndFile, &EndLine, &EndColumn, nullptr);
290c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
2910a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor          if (StartFile != EndFile || StartFile != File)
2920a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor            continue;
2930a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
294274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor          Out << "{" << StartLine << ":" << StartColumn << "-"
295274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor              << EndLine << ":" << EndColumn << "}";
2960a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor          PrintedRange = true;
2970a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor        }
2980a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor        if (PrintedRange)
299274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor          Out << ":";
3000a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor      }
3014cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor
3024cd912aa94656697a44c3ebb159f05060300524eDouglas Gregor      Out << " ";
3030a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor    }
3040a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  }
3050a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
3060a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  /* Print warning/error/etc. */
3070a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  switch (Severity) {
308eb2d1f1c88836bd5382e5d7aa8f6b85148a88b27David Blaikie  case CXDiagnostic_Ignored: llvm_unreachable("impossible");
309274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor  case CXDiagnostic_Note: Out << "note: "; break;
310274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor  case CXDiagnostic_Warning: Out << "warning: "; break;
311274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor  case CXDiagnostic_Error: Out << "error: "; break;
312274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor  case CXDiagnostic_Fatal: Out << "fatal error: "; break;
3130a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  }
3140a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
3150a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  CXString Text = clang_getDiagnosticSpelling(Diagnostic);
3160a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  if (clang_getCString(Text))
317274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor    Out << clang_getCString(Text);
3180a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  else
319274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor    Out << "<no diagnostic text>";
3200a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  clang_disposeString(Text);
321aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
322aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor  if (Options & (CXDiagnostic_DisplayOption | CXDiagnostic_DisplayCategoryId |
323aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor                 CXDiagnostic_DisplayCategoryName)) {
324aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor    bool NeedBracket = true;
325aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor    bool NeedComma = false;
326aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
327aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor    if (Options & CXDiagnostic_DisplayOption) {
328c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines      CXString OptionName = clang_getDiagnosticOption(Diagnostic, nullptr);
329aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor      if (const char *OptionText = clang_getCString(OptionName)) {
330aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor        if (OptionText[0]) {
331aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          Out << " [" << OptionText;
332aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          NeedBracket = false;
333aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          NeedComma = true;
334aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor        }
335aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor      }
336aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor      clang_disposeString(OptionName);
337aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor    }
338aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
339aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor    if (Options & (CXDiagnostic_DisplayCategoryId |
340aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor                   CXDiagnostic_DisplayCategoryName)) {
341aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor      if (unsigned CategoryID = clang_getDiagnosticCategory(Diagnostic)) {
342aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor        if (Options & CXDiagnostic_DisplayCategoryId) {
343aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          if (NeedBracket)
344aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor            Out << " [";
345aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          if (NeedComma)
346aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor            Out << ", ";
347aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          Out << CategoryID;
348aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          NeedBracket = false;
349aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          NeedComma = true;
350aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor        }
351aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
352aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor        if (Options & CXDiagnostic_DisplayCategoryName) {
35378d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek          CXString CategoryName = clang_getDiagnosticCategoryText(Diagnostic);
354aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          if (NeedBracket)
355aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor            Out << " [";
356aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          if (NeedComma)
357aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor            Out << ", ";
358aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          Out << clang_getCString(CategoryName);
359aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          NeedBracket = false;
360aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          NeedComma = true;
361aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor          clang_disposeString(CategoryName);
362aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor        }
363aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor      }
364aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor    }
3658e59838ed66eb8a853927a43fc25f974ee2ee838Ted Kremenek
3668e59838ed66eb8a853927a43fc25f974ee2ee838Ted Kremenek    (void) NeedComma; // Silence dead store warning.
367aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor    if (!NeedBracket)
368aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor      Out << "]";
369aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor  }
370aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
3715595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko  return cxstring::createDup(Out.str());
3720a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor}
3730a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
3740a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregorunsigned clang_defaultDiagnosticDisplayOptions() {
375aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor  return CXDiagnostic_DisplaySourceLocation | CXDiagnostic_DisplayColumn |
376aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor         CXDiagnostic_DisplayOption;
3770a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor}
3780a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
3795352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregorenum CXDiagnosticSeverity clang_getDiagnosticSeverity(CXDiagnostic Diag) {
3801edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl*>(Diag))
3811edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek    return D->getSeverity();
3825352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor  return CXDiagnostic_Ignored;
3835352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor}
384ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek
3855352ac06d8f6194825bb2a99ffa009b61bafb503Douglas GregorCXSourceLocation clang_getDiagnosticLocation(CXDiagnostic Diag) {
3861edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl*>(Diag))
3871edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek    return D->getLocation();
3881edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  return clang_getNullLocation();
3895352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor}
3905352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor
3915352ac06d8f6194825bb2a99ffa009b61bafb503Douglas GregorCXString clang_getDiagnosticSpelling(CXDiagnostic Diag) {
3921edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
3931edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek    return D->getSpelling();
394dc66adb40ee871b4c578ba615f45d82476c7119eDmitri Gribenko  return cxstring::createEmpty();
3955352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor}
3965352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor
397aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas GregorCXString clang_getDiagnosticOption(CXDiagnostic Diag, CXString *Disable) {
398aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor  if (Disable)
399dc66adb40ee871b4c578ba615f45d82476c7119eDmitri Gribenko    *Disable = cxstring::createEmpty();
4001edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek
4011edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
4021edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek    return D->getDiagnosticOption(Disable);
403aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
404dc66adb40ee871b4c578ba615f45d82476c7119eDmitri Gribenko  return cxstring::createEmpty();
405aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor}
406aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
407aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregorunsigned clang_getDiagnosticCategory(CXDiagnostic Diag) {
4081edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
4091edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek    return D->getCategory();
4101edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  return 0;
411aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor}
412aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
413aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas GregorCXString clang_getDiagnosticCategoryName(unsigned Category) {
414176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // Kept for backward compatibility.
4155595ded882b22d77fdf535bd1a4c6c090110348aDmitri Gribenko  return cxstring::createRef(DiagnosticIDs::getCategoryNameFromID(Category));
416aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor}
417aa5f135f8db82b5e5fb1640fd51f8078e0b2d82dDouglas Gregor
41878d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted KremenekCXString clang_getDiagnosticCategoryText(CXDiagnostic Diag) {
41978d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
42078d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek    return D->getCategoryText();
421dc66adb40ee871b4c578ba615f45d82476c7119eDmitri Gribenko  return cxstring::createEmpty();
42278d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek}
42378d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek
424a3890baf1256ff26081306c7fef70202f8223f41Douglas Gregorunsigned clang_getDiagnosticNumRanges(CXDiagnostic Diag) {
4251edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
4261edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek    return D->getNumRanges();
4271edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  return 0;
428a3890baf1256ff26081306c7fef70202f8223f41Douglas Gregor}
429ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek
430a3890baf1256ff26081306c7fef70202f8223f41Douglas GregorCXSourceRange clang_getDiagnosticRange(CXDiagnostic Diag, unsigned Range) {
4311edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag);
4321edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (!D || Range >= D->getNumRanges())
433a3890baf1256ff26081306c7fef70202f8223f41Douglas Gregor    return clang_getNullRange();
4341edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  return D->getRange(Range);
4355352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor}
4365352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor
4375352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregorunsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diag) {
4381edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
4391edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek    return D->getNumFixIts();
4401edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  return 0;
4415352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor}
4425352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor
4431edabbc32a07654d9b9fe44f50533ff146abd03eTed KremenekCXString clang_getDiagnosticFixIt(CXDiagnostic Diag, unsigned FixIt,
444473d7019bb54f8a2f0140dca9e9644a935cc6b20Douglas Gregor                                  CXSourceRange *ReplacementRange) {
4451edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag);
4461edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  if (!D || FixIt >= D->getNumFixIts()) {
447473d7019bb54f8a2f0140dca9e9644a935cc6b20Douglas Gregor    if (ReplacementRange)
448473d7019bb54f8a2f0140dca9e9644a935cc6b20Douglas Gregor      *ReplacementRange = clang_getNullRange();
449dc66adb40ee871b4c578ba615f45d82476c7119eDmitri Gribenko    return cxstring::createEmpty();
4505352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor  }
4511edabbc32a07654d9b9fe44f50533ff146abd03eTed Kremenek  return D->getFixIt(FixIt, ReplacementRange);
4525352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor}
453ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek
454153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenekvoid clang_disposeDiagnosticSet(CXDiagnosticSet Diags) {
455651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl *>(Diags)) {
456651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (D->isExternallyManaged())
457651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      delete D;
458651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
459153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek}
460153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
461153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekCXDiagnostic clang_getDiagnosticInSet(CXDiagnosticSet Diags,
462153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek                                      unsigned Index) {
463153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags))
464153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    if (Index < D->getNumDiagnostics())
465153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek      return D->getDiagnostic(Index);
466c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  return nullptr;
467153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek}
468153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
469153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekCXDiagnosticSet clang_getChildDiagnostics(CXDiagnostic Diag) {
470153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag)) {
471153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    CXDiagnosticSetImpl &ChildDiags = D->getChildDiagnostics();
472c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    return ChildDiags.empty() ? nullptr : (CXDiagnosticSet) &ChildDiags;
473153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  }
474c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  return nullptr;
475153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek}
476153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
477153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenekunsigned clang_getNumDiagnosticsInSet(CXDiagnosticSet Diags) {
478153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags))
479153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    return D->getNumDiagnostics();
480153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  return 0;
481153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek}
482153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
4835352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor} // end extern "C"
484