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