diff options
author | Ted Kremenek <kremenek@apple.com> | 2012-02-14 02:46:03 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2012-02-14 02:46:03 +0000 |
commit | 7473b1c6e7ba2654d4a0d469198f0e01b485b51a (patch) | |
tree | dd0142b48cacb81c2d52e0e377aa73161aad429b /tools/libclang/CIndexDiagnostic.cpp | |
parent | 8be51eab5ad34515d2a40dcdc8558128ca1800ad (diff) |
Implement new DiagnosticsRenderer that packages notes retrieved by clang_getDiagnosticSetFromTU() as
child diagnostics of primary diagnostics. By using the DiagnosticRenderer, these Diagnostics now
match with those generated for serialized diagnostics.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150456 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/libclang/CIndexDiagnostic.cpp')
-rw-r--r-- | tools/libclang/CIndexDiagnostic.cpp | 113 |
1 files changed, 110 insertions, 3 deletions
diff --git a/tools/libclang/CIndexDiagnostic.cpp b/tools/libclang/CIndexDiagnostic.cpp index 1e6062ea71..a36ca8c5d3 100644 --- a/tools/libclang/CIndexDiagnostic.cpp +++ b/tools/libclang/CIndexDiagnostic.cpp @@ -18,6 +18,8 @@ #include "clang/Frontend/ASTUnit.h" #include "clang/Frontend/FrontendDiagnostic.h" +#include "clang/Frontend/DiagnosticRenderer.h" +#include "clang/Frontend/DiagnosticOptions.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/MemoryBuffer.h" @@ -40,6 +42,109 @@ CXDiagnosticSetImpl::~CXDiagnosticSetImpl() { CXDiagnosticImpl::~CXDiagnosticImpl() {} +namespace { +class CXDiagnosticCustomNoteImpl : public CXDiagnosticImpl { + CXString Message; + CXSourceLocation Loc; +public: + CXDiagnosticCustomNoteImpl(StringRef Msg, CXSourceLocation L) + : CXDiagnosticImpl(CustomNoteDiagnosticKind), + Message(createCXString(Msg)), Loc(L) {} + + virtual ~CXDiagnosticCustomNoteImpl() { + clang_disposeString(Message); + } + + CXDiagnosticSeverity getSeverity() const { + return CXDiagnostic_Note; + } + + CXSourceLocation getLocation() const { + return Loc; + } + + CXString getSpelling() const { + return Message; + } + + CXString getDiagnosticOption(CXString *Disable) const { + if (Disable) + *Disable = createCXString("", false); + return createCXString("", false); + } + + unsigned getCategory() const { return 0; } + unsigned getNumRanges() const { return 0; } + CXSourceRange getRange(unsigned Range) const { return clang_getNullRange(); } + unsigned getNumFixIts() const { return 0; } + CXString getFixIt(unsigned FixIt, CXSourceRange *ReplacementRange) const { + if (ReplacementRange) + *ReplacementRange = clang_getNullRange(); + return createCXString("", false); + } +}; + +class CXDiagnosticRenderer : public DiagnosticNoteRenderer { +public: + CXDiagnosticRenderer(const SourceManager &SM, + const LangOptions &LangOpts, + const DiagnosticOptions &DiagOpts, + CXDiagnosticSetImpl *mainSet) + : DiagnosticNoteRenderer(SM, LangOpts, DiagOpts), + CurrentSet(mainSet), MainSet(mainSet) {} + + virtual ~CXDiagnosticRenderer() {} + + virtual void beginDiagnostic(DiagOrStoredDiag D, + DiagnosticsEngine::Level Level) { + + const StoredDiagnostic *SD = D.dyn_cast<const StoredDiagnostic*>(); + if (!SD) + return; + + if (Level != DiagnosticsEngine::Note) + CurrentSet = MainSet; + + CXStoredDiagnostic *CD = new CXStoredDiagnostic(*SD, LangOpts); + CurrentSet->appendDiagnostic(CD); + + if (Level != DiagnosticsEngine::Note) + CurrentSet = &CD->getChildDiagnostics(); + } + + virtual void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc, + DiagnosticsEngine::Level Level, + StringRef Message, + ArrayRef<CharSourceRange> Ranges, + DiagOrStoredDiag D) { + if (!D.isNull()) + return; + + CXSourceLocation L = translateSourceLocation(SM, LangOpts, Loc); + CXDiagnosticImpl *CD = new CXDiagnosticCustomNoteImpl(Message, L); + CurrentSet->appendDiagnostic(CD); + } + + virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc, + DiagnosticsEngine::Level Level, + ArrayRef<CharSourceRange> Ranges) {} + + virtual void emitCodeContext(SourceLocation Loc, + DiagnosticsEngine::Level Level, + SmallVectorImpl<CharSourceRange>& Ranges, + ArrayRef<FixItHint> Hints) {}; + + virtual void emitNote(SourceLocation Loc, StringRef Message) { + CXSourceLocation L = translateSourceLocation(SM, LangOpts, Loc); + CurrentSet->appendDiagnostic(new CXDiagnosticCustomNoteImpl(Message, + L)); + } + + CXDiagnosticSetImpl *CurrentSet; + CXDiagnosticSetImpl *MainSet; +}; +} + CXDiagnosticSetImpl *cxdiag::lazyCreateDiags(CXTranslationUnit TU, bool checkIfChanged) { ASTUnit *AU = static_cast<ASTUnit *>(TU->TUData); @@ -75,12 +180,14 @@ CXDiagnosticSetImpl *cxdiag::lazyCreateDiags(CXTranslationUnit TU, if (!TU->Diagnostics) { CXDiagnosticSetImpl *Set = new CXDiagnosticSetImpl(); TU->Diagnostics = Set; + DiagnosticOptions DOpts; + CXDiagnosticRenderer Renderer(AU->getSourceManager(), + AU->getASTContext().getLangOptions(), + DOpts, Set); for (ASTUnit::stored_diag_iterator it = AU->stored_diag_begin(), ei = AU->stored_diag_end(); it != ei; ++it) { - CXStoredDiagnostic *D = - new CXStoredDiagnostic(*it, AU->getASTContext().getLangOptions()); - Set->appendDiagnostic(D); + Renderer.emitStoredDiagnostic(*it); } } return static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics); |