CIndexDiagnostic.cpp revision 7473b1c6e7ba2654d4a0d469198f0e01b485b51a
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*===-- CIndexDiagnostics.cpp - Diagnostics C Interface ---------*- C++ -*-===*\ 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)|* *| 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)|* The LLVM Compiler Infrastructure *| 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)|* *| 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)|* This file is distributed under the University of Illinois Open Source *| 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)|* License. See LICENSE.TXT for details. *| 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)|* *| 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)|*===----------------------------------------------------------------------===*| 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)|* *| 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)|* Implements the diagnostic functions of the Clang C interface. *| 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)|* *| 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)\*===----------------------------------------------------------------------===*/ 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "CIndexDiagnostic.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "CIndexer.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "CXTranslationUnit.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "CXSourceLocation.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "CXString.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/Frontend/ASTUnit.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/Frontend/FrontendDiagnostic.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/Frontend/DiagnosticRenderer.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/Frontend/DiagnosticOptions.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/ADT/SmallString.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/ADT/Twine.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/MemoryBuffer.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/raw_ostream.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using namespace clang; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using namespace clang::cxloc; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using namespace clang::cxstring; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using namespace clang::cxdiag; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using namespace llvm; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CXDiagnosticSetImpl::~CXDiagnosticSetImpl() { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<CXDiagnosticImpl *>::iterator it = Diagnostics.begin(), 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) et = Diagnostics.end(); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != et; ++it) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete *it; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CXDiagnosticImpl::~CXDiagnosticImpl() {} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CXDiagnosticCustomNoteImpl : public CXDiagnosticImpl { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXString Message; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXSourceLocation Loc; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public: 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXDiagnosticCustomNoteImpl(StringRef Msg, CXSourceLocation L) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : CXDiagnosticImpl(CustomNoteDiagnosticKind), 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message(createCXString(Msg)), Loc(L) {} 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~CXDiagnosticCustomNoteImpl() { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clang_disposeString(Message); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXDiagnosticSeverity getSeverity() const { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CXDiagnostic_Note; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXSourceLocation getLocation() const { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Loc; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXString getSpelling() const { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Message; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXString getDiagnosticOption(CXString *Disable) const { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Disable) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *Disable = createCXString("", false); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return createCXString("", false); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned getCategory() const { return 0; } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned getNumRanges() const { return 0; } 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXSourceRange getRange(unsigned Range) const { return clang_getNullRange(); } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned getNumFixIts() const { return 0; } 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXString getFixIt(unsigned FixIt, CXSourceRange *ReplacementRange) const { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ReplacementRange) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *ReplacementRange = clang_getNullRange(); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return createCXString("", false); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CXDiagnosticRenderer : public DiagnosticNoteRenderer { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public: 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXDiagnosticRenderer(const SourceManager &SM, 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LangOptions &LangOpts, 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DiagnosticOptions &DiagOpts, 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXDiagnosticSetImpl *mainSet) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : DiagnosticNoteRenderer(SM, LangOpts, DiagOpts), 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurrentSet(mainSet), MainSet(mainSet) {} 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~CXDiagnosticRenderer() {} 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void beginDiagnostic(DiagOrStoredDiag D, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DiagnosticsEngine::Level Level) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const StoredDiagnostic *SD = D.dyn_cast<const StoredDiagnostic*>(); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SD) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Level != DiagnosticsEngine::Note) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurrentSet = MainSet; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXStoredDiagnostic *CD = new CXStoredDiagnostic(*SD, LangOpts); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurrentSet->appendDiagnostic(CD); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Level != DiagnosticsEngine::Note) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurrentSet = &CD->getChildDiagnostics(); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DiagnosticsEngine::Level Level, 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringRef Message, 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayRef<CharSourceRange> Ranges, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DiagOrStoredDiag D) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!D.isNull()) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXSourceLocation L = translateSourceLocation(SM, LangOpts, Loc); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXDiagnosticImpl *CD = new CXDiagnosticCustomNoteImpl(Message, L); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurrentSet->appendDiagnostic(CD); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc, 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DiagnosticsEngine::Level Level, 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayRef<CharSourceRange> Ranges) {} 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void emitCodeContext(SourceLocation Loc, 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DiagnosticsEngine::Level Level, 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SmallVectorImpl<CharSourceRange>& Ranges, 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayRef<FixItHint> Hints) {}; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void emitNote(SourceLocation Loc, StringRef Message) { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXSourceLocation L = translateSourceLocation(SM, LangOpts, Loc); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurrentSet->appendDiagnostic(new CXDiagnosticCustomNoteImpl(Message, 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L)); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXDiagnosticSetImpl *CurrentSet; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXDiagnosticSetImpl *MainSet; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CXDiagnosticSetImpl *cxdiag::lazyCreateDiags(CXTranslationUnit TU, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool checkIfChanged) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASTUnit *AU = static_cast<ASTUnit *>(TU->TUData); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (TU->Diagnostics && checkIfChanged) { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In normal use, ASTUnit's diagnostics should not change unless we reparse. 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Currently they can only change by using the internal testing flag 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // '-error-on-deserialized-decl' which will error during deserialization of 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a declaration. What will happen is: 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // -c-index-test gets a CXTranslationUnit 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // -checks the diagnostics, the diagnostics set is lazily created, 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // no errors are reported 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // -later does an operation, like annotation of tokens, that triggers 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // -error-on-deserialized-decl, that will emit a diagnostic error, 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that ASTUnit will catch and add to its stored diagnostics vector. 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // -c-index-test wants to check whether an error occurred after performing 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the operation but can only query the lazily created set. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We check here if a new diagnostic was appended since the last time the 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // diagnostic set was created, in which case we reset it. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXDiagnosticSetImpl * 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Set = static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (AU->stored_diag_size() != Set->getNumDiagnostics()) { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Diagnostics in the ASTUnit were updated, reset the associated 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // diagnostics. 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete Set; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TU->Diagnostics = 0; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!TU->Diagnostics) { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXDiagnosticSetImpl *Set = new CXDiagnosticSetImpl(); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TU->Diagnostics = Set; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DiagnosticOptions DOpts; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXDiagnosticRenderer Renderer(AU->getSourceManager(), 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AU->getASTContext().getLangOptions(), 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DOpts, Set); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ASTUnit::stored_diag_iterator it = AU->stored_diag_begin(), 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ei = AU->stored_diag_end(); it != ei; ++it) { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Renderer.emitStoredDiagnostic(*it); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//----------------------------------------------------------------------------- 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// C Interface Routines 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//----------------------------------------------------------------------------- 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C" { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)unsigned clang_getNumDiagnostics(CXTranslationUnit Unit) { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Unit->TUData) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return lazyCreateDiags(Unit, /*checkIfChanged=*/true)->getNumDiagnostics(); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, unsigned Index) { 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXDiagnosticSet D = clang_getDiagnosticSetFromTU(Unit); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!D) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXDiagnosticSetImpl *Diags = static_cast<CXDiagnosticSetImpl*>(D); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Index >= Diags->getNumDiagnostics()) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Diags->getDiagnostic(Index); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CXDiagnosticSet clang_getDiagnosticSetFromTU(CXTranslationUnit Unit) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Unit->TUData) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<CXDiagnostic>(lazyCreateDiags(Unit)); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void clang_disposeDiagnostic(CXDiagnostic Diagnostic) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No-op. Kept as a legacy API. CXDiagnostics are now managed 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // by the enclosing CXDiagnosticSet. 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options) { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Diagnostic) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return createCXString(""); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXDiagnosticSeverity Severity = clang_getDiagnosticSeverity(Diagnostic); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SmallString<256> Str; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) llvm::raw_svector_ostream Out(Str); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Options & CXDiagnostic_DisplaySourceLocation) { 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Print source location (file:line), along with optional column 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and source ranges. 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXFile File; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned Line, Column; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clang_getSpellingLocation(clang_getDiagnosticLocation(Diagnostic), 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &File, &Line, &Column, 0); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (File) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXString FName = clang_getFileName(File); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Out << clang_getCString(FName) << ":" << Line << ":"; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clang_disposeString(FName); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Options & CXDiagnostic_DisplayColumn) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Out << Column << ":"; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Options & CXDiagnostic_DisplaySourceRanges) { 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned N = clang_getDiagnosticNumRanges(Diagnostic); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool PrintedRange = false; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned I = 0; I != N; ++I) { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXFile StartFile, EndFile; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CXSourceRange Range = clang_getDiagnosticRange(Diagnostic, I); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned StartLine, StartColumn, EndLine, EndColumn; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clang_getSpellingLocation(clang_getRangeStart(Range), 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &StartFile, &StartLine, &StartColumn, 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clang_getSpellingLocation(clang_getRangeEnd(Range), 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &EndFile, &EndLine, &EndColumn, 0); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (StartFile != EndFile || StartFile != File) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Out << "{" << StartLine << ":" << StartColumn << "-" 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << EndLine << ":" << EndColumn << "}"; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintedRange = true; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PrintedRange) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Out << ":"; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Out << " "; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Print warning/error/etc. */ 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (Severity) { 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CXDiagnostic_Ignored: llvm_unreachable("impossible"); 285 case CXDiagnostic_Note: Out << "note: "; break; 286 case CXDiagnostic_Warning: Out << "warning: "; break; 287 case CXDiagnostic_Error: Out << "error: "; break; 288 case CXDiagnostic_Fatal: Out << "fatal error: "; break; 289 } 290 291 CXString Text = clang_getDiagnosticSpelling(Diagnostic); 292 if (clang_getCString(Text)) 293 Out << clang_getCString(Text); 294 else 295 Out << "<no diagnostic text>"; 296 clang_disposeString(Text); 297 298 if (Options & (CXDiagnostic_DisplayOption | CXDiagnostic_DisplayCategoryId | 299 CXDiagnostic_DisplayCategoryName)) { 300 bool NeedBracket = true; 301 bool NeedComma = false; 302 303 if (Options & CXDiagnostic_DisplayOption) { 304 CXString OptionName = clang_getDiagnosticOption(Diagnostic, 0); 305 if (const char *OptionText = clang_getCString(OptionName)) { 306 if (OptionText[0]) { 307 Out << " [" << OptionText; 308 NeedBracket = false; 309 NeedComma = true; 310 } 311 } 312 clang_disposeString(OptionName); 313 } 314 315 if (Options & (CXDiagnostic_DisplayCategoryId | 316 CXDiagnostic_DisplayCategoryName)) { 317 if (unsigned CategoryID = clang_getDiagnosticCategory(Diagnostic)) { 318 if (Options & CXDiagnostic_DisplayCategoryId) { 319 if (NeedBracket) 320 Out << " ["; 321 if (NeedComma) 322 Out << ", "; 323 Out << CategoryID; 324 NeedBracket = false; 325 NeedComma = true; 326 } 327 328 if (Options & CXDiagnostic_DisplayCategoryName) { 329 CXString CategoryName = clang_getDiagnosticCategoryName(CategoryID); 330 if (NeedBracket) 331 Out << " ["; 332 if (NeedComma) 333 Out << ", "; 334 Out << clang_getCString(CategoryName); 335 NeedBracket = false; 336 NeedComma = true; 337 clang_disposeString(CategoryName); 338 } 339 } 340 } 341 342 if (!NeedBracket) 343 Out << "]"; 344 } 345 346 return createCXString(Out.str(), true); 347} 348 349unsigned clang_defaultDiagnosticDisplayOptions() { 350 return CXDiagnostic_DisplaySourceLocation | CXDiagnostic_DisplayColumn | 351 CXDiagnostic_DisplayOption; 352} 353 354enum CXDiagnosticSeverity clang_getDiagnosticSeverity(CXDiagnostic Diag) { 355 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl*>(Diag)) 356 return D->getSeverity(); 357 return CXDiagnostic_Ignored; 358} 359 360CXSourceLocation clang_getDiagnosticLocation(CXDiagnostic Diag) { 361 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl*>(Diag)) 362 return D->getLocation(); 363 return clang_getNullLocation(); 364} 365 366CXString clang_getDiagnosticSpelling(CXDiagnostic Diag) { 367 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag)) 368 return D->getSpelling(); 369 return createCXString(""); 370} 371 372CXString clang_getDiagnosticOption(CXDiagnostic Diag, CXString *Disable) { 373 if (Disable) 374 *Disable = createCXString(""); 375 376 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag)) 377 return D->getDiagnosticOption(Disable); 378 379 return createCXString(""); 380} 381 382unsigned clang_getDiagnosticCategory(CXDiagnostic Diag) { 383 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag)) 384 return D->getCategory(); 385 return 0; 386} 387 388CXString clang_getDiagnosticCategoryName(unsigned Category) { 389 return createCXString(DiagnosticIDs::getCategoryNameFromID(Category)); 390} 391 392unsigned clang_getDiagnosticNumRanges(CXDiagnostic Diag) { 393 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag)) 394 return D->getNumRanges(); 395 return 0; 396} 397 398CXSourceRange clang_getDiagnosticRange(CXDiagnostic Diag, unsigned Range) { 399 CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag); 400 if (!D || Range >= D->getNumRanges()) 401 return clang_getNullRange(); 402 return D->getRange(Range); 403} 404 405unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diag) { 406 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag)) 407 return D->getNumFixIts(); 408 return 0; 409} 410 411CXString clang_getDiagnosticFixIt(CXDiagnostic Diag, unsigned FixIt, 412 CXSourceRange *ReplacementRange) { 413 CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag); 414 if (!D || FixIt >= D->getNumFixIts()) { 415 if (ReplacementRange) 416 *ReplacementRange = clang_getNullRange(); 417 return createCXString(""); 418 } 419 return D->getFixIt(FixIt, ReplacementRange); 420} 421 422void clang_disposeDiagnosticSet(CXDiagnosticSet Diags) { 423 CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags); 424 if (D->isExternallyManaged()) 425 delete D; 426} 427 428CXDiagnostic clang_getDiagnosticInSet(CXDiagnosticSet Diags, 429 unsigned Index) { 430 if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags)) 431 if (Index < D->getNumDiagnostics()) 432 return D->getDiagnostic(Index); 433 return 0; 434} 435 436CXDiagnosticSet clang_getChildDiagnostics(CXDiagnostic Diag) { 437 if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag)) { 438 CXDiagnosticSetImpl &ChildDiags = D->getChildDiagnostics(); 439 return ChildDiags.empty() ? 0 : (CXDiagnosticSet) &ChildDiags; 440 } 441 return 0; 442} 443 444unsigned clang_getNumDiagnosticsInSet(CXDiagnosticSet Diags) { 445 if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags)) 446 return D->getNumDiagnostics(); 447 return 0; 448} 449 450} // end extern "C" 451