[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.

llvm-svn: 143368
This commit is contained in:
Ted Kremenek 2011-10-31 21:40:19 +00:00
parent 3689337c8e
commit bb2c7101b5
4 changed files with 238 additions and 93 deletions

View File

@ -48,8 +48,7 @@ CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, unsigned Index) {
}
void clang_disposeDiagnostic(CXDiagnostic Diagnostic) {
CXStoredDiagnostic *Stored = static_cast<CXStoredDiagnostic *>(Diagnostic);
delete Stored;
delete static_cast<CXDiagnosticImpl *>(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<CXStoredDiagnostic *>(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<CXDiagnosticImpl*>(Diag))
return D->getSeverity();
return CXDiagnostic_Ignored;
}
CXSourceLocation clang_getDiagnosticLocation(CXDiagnostic Diag) {
CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(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<CXDiagnosticImpl*>(Diag))
return D->getLocation();
return clang_getNullLocation();
}
CXString clang_getDiagnosticSpelling(CXDiagnostic Diag) {
CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
if (!StoredDiag)
return createCXString("");
return createCXString(StoredDiag->Diag.getMessage(), false);
if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
return D->getSpelling();
return createCXString("");
}
CXString clang_getDiagnosticOption(CXDiagnostic Diag, CXString *Disable) {
if (Disable)
*Disable = createCXString("");
CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(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<CXDiagnosticImpl *>(Diag))
return D->getDiagnosticOption(Disable);
return createCXString("");
}
unsigned clang_getDiagnosticCategory(CXDiagnostic Diag) {
CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
if (!StoredDiag)
return 0;
return DiagnosticIDs::getCategoryNumberForDiag(StoredDiag->Diag.getID());
if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(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<CXStoredDiagnostic *>(Diag);
if (!StoredDiag || StoredDiag->Diag.getLocation().isInvalid())
return 0;
return StoredDiag->Diag.range_size();
if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
return D->getNumRanges();
return 0;
}
CXSourceRange clang_getDiagnosticRange(CXDiagnostic Diag, unsigned Range) {
CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
if (!StoredDiag || Range >= StoredDiag->Diag.range_size() ||
StoredDiag->Diag.getLocation().isInvalid())
CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(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<CXStoredDiagnostic *>(Diag);
if (!StoredDiag)
return 0;
return StoredDiag->Diag.fixit_size();
if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(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<CXStoredDiagnostic *>(Diagnostic);
if (!StoredDiag || FixIt >= StoredDiag->Diag.fixit_size() ||
StoredDiag->Diag.getLocation().isInvalid()) {
CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(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"

View File

@ -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

View File

@ -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
)

View File

@ -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);
}