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