From 1edabbc32a07654d9b9fe44f50533ff146abd03e Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Mon, 31 Oct 2011 21:40:19 +0000 Subject: [PATCH] [libclang] Add CXDiagnosticImpl to represent a super class for the implementation backing a CXDiagnostic. This allows CXStoredDiagnostic to be just one possible implementation of a CXDiagnostic. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143368 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/libclang/CIndexDiagnostic.cpp | 119 ++++++-------------------- tools/libclang/CIndexDiagnostic.h | 84 +++++++++++++++++- tools/libclang/CMakeLists.txt | 10 +++ tools/libclang/CXStoredDiagnostic.cpp | 118 +++++++++++++++++++++++++ 4 files changed, 238 insertions(+), 93 deletions(-) create mode 100644 tools/libclang/CXStoredDiagnostic.cpp diff --git a/tools/libclang/CIndexDiagnostic.cpp b/tools/libclang/CIndexDiagnostic.cpp index 26f69b06c1..1beb993863 100644 --- a/tools/libclang/CIndexDiagnostic.cpp +++ b/tools/libclang/CIndexDiagnostic.cpp @@ -48,8 +48,7 @@ CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, unsigned Index) { } void clang_disposeDiagnostic(CXDiagnostic Diagnostic) { - CXStoredDiagnostic *Stored = static_cast(Diagnostic); - delete Stored; + delete static_cast(Diagnostic); } CXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options) { @@ -177,76 +176,37 @@ unsigned clang_defaultDiagnosticDisplayOptions() { } enum CXDiagnosticSeverity clang_getDiagnosticSeverity(CXDiagnostic Diag) { - CXStoredDiagnostic *StoredDiag = static_cast(Diag); - if (!StoredDiag) - return CXDiagnostic_Ignored; - - switch (StoredDiag->Diag.getLevel()) { - case DiagnosticsEngine::Ignored: return CXDiagnostic_Ignored; - case DiagnosticsEngine::Note: return CXDiagnostic_Note; - case DiagnosticsEngine::Warning: return CXDiagnostic_Warning; - case DiagnosticsEngine::Error: return CXDiagnostic_Error; - case DiagnosticsEngine::Fatal: return CXDiagnostic_Fatal; - } - - llvm_unreachable("Invalid diagnostic level"); + if (CXDiagnosticImpl *D = static_cast(Diag)) + return D->getSeverity(); return CXDiagnostic_Ignored; } CXSourceLocation clang_getDiagnosticLocation(CXDiagnostic Diag) { - CXStoredDiagnostic *StoredDiag = static_cast(Diag); - if (!StoredDiag || StoredDiag->Diag.getLocation().isInvalid()) - return clang_getNullLocation(); - - return translateSourceLocation(StoredDiag->Diag.getLocation().getManager(), - StoredDiag->LangOpts, - StoredDiag->Diag.getLocation()); + if (CXDiagnosticImpl *D = static_cast(Diag)) + return D->getLocation(); + return clang_getNullLocation(); } CXString clang_getDiagnosticSpelling(CXDiagnostic Diag) { - CXStoredDiagnostic *StoredDiag = static_cast(Diag); - if (!StoredDiag) - return createCXString(""); - - return createCXString(StoredDiag->Diag.getMessage(), false); + if (CXDiagnosticImpl *D = static_cast(Diag)) + return D->getSpelling(); + return createCXString(""); } CXString clang_getDiagnosticOption(CXDiagnostic Diag, CXString *Disable) { if (Disable) *Disable = createCXString(""); - - CXStoredDiagnostic *StoredDiag = static_cast(Diag); - if (!StoredDiag) - return createCXString(""); - - unsigned ID = StoredDiag->Diag.getID(); - StringRef Option = DiagnosticIDs::getWarningOptionForDiag(ID); - if (!Option.empty()) { - if (Disable) - *Disable = createCXString((Twine("-Wno-") + Option).str()); - return createCXString((Twine("-W") + Option).str()); - } - - if (ID == diag::fatal_too_many_errors) { - if (Disable) - *Disable = createCXString("-ferror-limit=0"); - return createCXString("-ferror-limit="); - } - - bool EnabledByDefault; - if (DiagnosticIDs::isBuiltinExtensionDiag(ID, EnabledByDefault) && - !EnabledByDefault) - return createCXString("-pedantic"); + + if (CXDiagnosticImpl *D = static_cast(Diag)) + return D->getDiagnosticOption(Disable); return createCXString(""); } unsigned clang_getDiagnosticCategory(CXDiagnostic Diag) { - CXStoredDiagnostic *StoredDiag = static_cast(Diag); - if (!StoredDiag) - return 0; - - return DiagnosticIDs::getCategoryNumberForDiag(StoredDiag->Diag.getID()); + if (CXDiagnosticImpl *D = static_cast(Diag)) + return D->getCategory(); + return 0; } CXString clang_getDiagnosticCategoryName(unsigned Category) { @@ -254,56 +214,33 @@ CXString clang_getDiagnosticCategoryName(unsigned Category) { } unsigned clang_getDiagnosticNumRanges(CXDiagnostic Diag) { - CXStoredDiagnostic *StoredDiag = static_cast(Diag); - if (!StoredDiag || StoredDiag->Diag.getLocation().isInvalid()) - return 0; - - return StoredDiag->Diag.range_size(); + if (CXDiagnosticImpl *D = static_cast(Diag)) + return D->getNumRanges(); + return 0; } CXSourceRange clang_getDiagnosticRange(CXDiagnostic Diag, unsigned Range) { - CXStoredDiagnostic *StoredDiag = static_cast(Diag); - if (!StoredDiag || Range >= StoredDiag->Diag.range_size() || - StoredDiag->Diag.getLocation().isInvalid()) + CXDiagnosticImpl *D = static_cast(Diag); + if (!D || Range >= D->getNumRanges()) return clang_getNullRange(); - - return translateSourceRange(StoredDiag->Diag.getLocation().getManager(), - StoredDiag->LangOpts, - StoredDiag->Diag.range_begin()[Range]); + return D->getRange(Range); } unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diag) { - CXStoredDiagnostic *StoredDiag = static_cast(Diag); - if (!StoredDiag) - return 0; - - return StoredDiag->Diag.fixit_size(); + if (CXDiagnosticImpl *D = static_cast(Diag)) + return D->getNumFixIts(); + return 0; } -CXString clang_getDiagnosticFixIt(CXDiagnostic Diagnostic, unsigned FixIt, +CXString clang_getDiagnosticFixIt(CXDiagnostic Diag, unsigned FixIt, CXSourceRange *ReplacementRange) { - CXStoredDiagnostic *StoredDiag - = static_cast(Diagnostic); - if (!StoredDiag || FixIt >= StoredDiag->Diag.fixit_size() || - StoredDiag->Diag.getLocation().isInvalid()) { + CXDiagnosticImpl *D = static_cast(Diag); + if (!D || FixIt >= D->getNumFixIts()) { if (ReplacementRange) *ReplacementRange = clang_getNullRange(); - return createCXString(""); } - - const FixItHint &Hint = StoredDiag->Diag.fixit_begin()[FixIt]; - if (ReplacementRange) { - // Create a range that covers the entire replacement (or - // removal) range, adjusting the end of the range to point to - // the end of the token. - *ReplacementRange - = translateSourceRange(StoredDiag->Diag.getLocation().getManager(), - StoredDiag->LangOpts, - Hint.RemoveRange); - } - - return createCXString(Hint.CodeToInsert); + return D->getFixIt(FixIt, ReplacementRange); } } // end extern "C" diff --git a/tools/libclang/CIndexDiagnostic.h b/tools/libclang/CIndexDiagnostic.h index 0d935fae66..07b6b15968 100644 --- a/tools/libclang/CIndexDiagnostic.h +++ b/tools/libclang/CIndexDiagnostic.h @@ -13,19 +13,99 @@ #ifndef LLVM_CLANG_CINDEX_DIAGNOSTIC_H #define LLVM_CLANG_CINDEX_DIAGNOSTIC_H +#include "clang-c/Index.h" + namespace clang { class LangOptions; class StoredDiagnostic; +class CXDiagnosticImpl { +public: + enum Kind { StoredDiagnosticKind, SerializedDiagnosticKind }; + + virtual ~CXDiagnosticImpl(); + + /// \brief Return the severity of the diagnostic. + virtual CXDiagnosticSeverity getSeverity() const = 0; + + /// \brief Return the location of the diagnostic. + virtual CXSourceLocation getLocation() const = 0; + + /// \brief Return the spelling of the diagnostic. + virtual CXString getSpelling() const = 0; + + /// \brief Return the text for the diagnostic option. + virtual CXString getDiagnosticOption(CXString *Disable) const = 0; + + /// \brief Return the category of the diagnostic. + virtual unsigned getCategory() const = 0; + + /// \brief Return the number of source ranges for the diagnostic. + virtual unsigned getNumRanges() const = 0; + + /// \brief Return the source ranges for the diagnostic. + virtual CXSourceRange getRange(unsigned Range) const = 0; + + /// \brief Return the number of FixIts. + virtual unsigned getNumFixIts() const = 0; + + /// \brief Return the FixIt information (source range and inserted text). + virtual CXString getFixIt(unsigned FixIt, + CXSourceRange *ReplacementRange) const = 0; + + Kind getKind() const { return K; } + +protected: + CXDiagnosticImpl(Kind k) : K(k) {} + +private: + Kind K; +}; + /// \brief The storage behind a CXDiagnostic -struct CXStoredDiagnostic { +struct CXStoredDiagnostic : public CXDiagnosticImpl { const StoredDiagnostic &Diag; const LangOptions &LangOpts; CXStoredDiagnostic(const StoredDiagnostic &Diag, const LangOptions &LangOpts) - : Diag(Diag), LangOpts(LangOpts) { } + : CXDiagnosticImpl(StoredDiagnosticKind), + Diag(Diag), LangOpts(LangOpts) { } + + virtual ~CXStoredDiagnostic() {} + + /// \brief Return the severity of the diagnostic. + virtual CXDiagnosticSeverity getSeverity() const; + + /// \brief Return the location of the diagnostic. + virtual CXSourceLocation getLocation() const; + + /// \brief Return the spelling of the diagnostic. + virtual CXString getSpelling() const; + + /// \brief Return the text for the diagnostic option. + virtual CXString getDiagnosticOption(CXString *Disable) const; + + /// \brief Return the category of the diagnostic. + virtual unsigned getCategory() const; + + /// \brief Return the number of source ranges for the diagnostic. + virtual unsigned getNumRanges() const; + + /// \brief Return the source ranges for the diagnostic. + virtual CXSourceRange getRange(unsigned Range) const; + + /// \brief Return the number of FixIts. + virtual unsigned getNumFixIts() const; + + /// \brief Return the FixIt information (source range and inserted text). + virtual CXString getFixIt(unsigned FixIt, + CXSourceRange *ReplacementRange) const; + + static bool classof(const CXDiagnosticImpl *D) { + return D->getKind() == StoredDiagnosticKind; + } }; } // end namespace clang diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt index 00b4692ebc..6f62d236ee 100644 --- a/tools/libclang/CMakeLists.txt +++ b/tools/libclang/CMakeLists.txt @@ -21,18 +21,28 @@ set(SOURCES CIndexCXX.cpp CIndexCodeCompletion.cpp CIndexDiagnostic.cpp + CIndexDiagnostic.h CIndexHigh.cpp CIndexInclusionStack.cpp CIndexUSRs.cpp CIndexer.cpp + CIndexer.h CXCursor.cpp + CXCursor.h + CXSourceLocation.h + CXStoredDiagnostic.cpp CXString.cpp + CXString.h + CXTranslationUnit.h CXType.cpp + CXType.h IndexBody.cpp IndexDecl.cpp IndexTypeSourceInfo.cpp + Index_Internal.h Indexing.cpp IndexingContext.cpp + IndexingContext.h ../../include/clang-c/Index.h ) diff --git a/tools/libclang/CXStoredDiagnostic.cpp b/tools/libclang/CXStoredDiagnostic.cpp new file mode 100644 index 0000000000..117e5398be --- /dev/null +++ b/tools/libclang/CXStoredDiagnostic.cpp @@ -0,0 +1,118 @@ +/*===-- CXStoreDiagnostic.cpp - Diagnostics C Interface ----------*- C++ -*-===*\ +|* *| +|* The LLVM Compiler Infrastructure *| +|* *| +|* This file is distributed under the University of Illinois Open Source *| +|* License. See LICENSE.TXT for details. *| +|* *| +|*===----------------------------------------------------------------------===*| +|* *| +|* Implements part of the diagnostic functions of the Clang C interface. *| +|* *| +\*===----------------------------------------------------------------------===*/ + +#include "CIndexDiagnostic.h" +#include "CIndexer.h" +#include "CXTranslationUnit.h" +#include "CXSourceLocation.h" +#include "CXString.h" + +#include "clang/Frontend/ASTUnit.h" +#include "clang/Frontend/FrontendDiagnostic.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/raw_ostream.h" + +using namespace clang; +using namespace clang::cxloc; +using namespace clang::cxstring; + +// Needed for vtable of CXPersisetntDiagnostic. +CXDiagnosticImpl::~CXDiagnosticImpl() {} + +CXDiagnosticSeverity CXStoredDiagnostic::getSeverity() const { + switch (Diag.getLevel()) { + case DiagnosticsEngine::Ignored: return CXDiagnostic_Ignored; + case DiagnosticsEngine::Note: return CXDiagnostic_Note; + case DiagnosticsEngine::Warning: return CXDiagnostic_Warning; + case DiagnosticsEngine::Error: return CXDiagnostic_Error; + case DiagnosticsEngine::Fatal: return CXDiagnostic_Fatal; + } + + llvm_unreachable("Invalid diagnostic level"); + return CXDiagnostic_Ignored; +} + +CXSourceLocation CXStoredDiagnostic::getLocation() const { + if (Diag.getLocation().isInvalid()) + return clang_getNullLocation(); + + return translateSourceLocation(Diag.getLocation().getManager(), + LangOpts, Diag.getLocation()); +} + +CXString CXStoredDiagnostic::getSpelling() const { + return createCXString(Diag.getMessage(), false); +} + +CXString CXStoredDiagnostic::getDiagnosticOption(CXString *Disable) const { + unsigned ID = Diag.getID(); + StringRef Option = DiagnosticIDs::getWarningOptionForDiag(ID); + if (!Option.empty()) { + if (Disable) + *Disable = createCXString((Twine("-Wno-") + Option).str()); + return createCXString((Twine("-W") + Option).str()); + } + + if (ID == diag::fatal_too_many_errors) { + if (Disable) + *Disable = createCXString("-ferror-limit=0"); + return createCXString("-ferror-limit="); + } + + bool EnabledByDefault; + if (DiagnosticIDs::isBuiltinExtensionDiag(ID, EnabledByDefault) && + !EnabledByDefault) + return createCXString("-pedantic"); + + return createCXString(""); +} + +unsigned CXStoredDiagnostic::getCategory() const { + return DiagnosticIDs::getCategoryNumberForDiag(Diag.getID()); +} + +unsigned CXStoredDiagnostic::getNumRanges() const { + if (Diag.getLocation().isInvalid()) + return 0; + + return Diag.range_size(); +} + +CXSourceRange CXStoredDiagnostic::getRange(unsigned int Range) const { + assert(Diag.getLocation().isValid()); + return translateSourceRange(Diag.getLocation().getManager(), + LangOpts, + Diag.range_begin()[Range]); +} + +unsigned CXStoredDiagnostic::getNumFixIts() const { + if (Diag.getLocation().isInvalid()) + return 0; + return Diag.fixit_size(); +} + +CXString CXStoredDiagnostic::getFixIt(unsigned FixIt, + CXSourceRange *ReplacementRange) const { + const FixItHint &Hint = Diag.fixit_begin()[FixIt]; + if (ReplacementRange) { + // Create a range that covers the entire replacement (or + // removal) range, adjusting the end of the range to point to + // the end of the token. + *ReplacementRange = translateSourceRange(Diag.getLocation().getManager(), + LangOpts, Hint.RemoveRange); + } + return createCXString(Hint.CodeToInsert); +} + -- 2.50.1