aboutsummaryrefslogtreecommitdiff
path: root/tools/libclang/CIndexDiagnostic.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2012-02-14 02:46:03 +0000
committerTed Kremenek <kremenek@apple.com>2012-02-14 02:46:03 +0000
commit7473b1c6e7ba2654d4a0d469198f0e01b485b51a (patch)
treedd0142b48cacb81c2d52e0e377aa73161aad429b /tools/libclang/CIndexDiagnostic.cpp
parent8be51eab5ad34515d2a40dcdc8558128ca1800ad (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.cpp113
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);