Implement a rigorous type checking when we call getX and setX.
These interfaces assume we know the type and we should compare if the underlying type is the one we expect when using the setters and getters. Unfortunately, this is not the case and we need to further investigate.
This commit is contained in:
parent
5add0d7732
commit
632aba9c56
@ -158,6 +158,7 @@ namespace cling {
|
||||
/// \brief Get a reference to the value with type checking.
|
||||
template <typename T> T getAs() const;
|
||||
|
||||
void AssertTypeMismatch(const char* Type) const;
|
||||
public:
|
||||
/// \brief Default constructor, creates a value that IsInvalid().
|
||||
Value():
|
||||
@ -223,23 +224,35 @@ namespace cling {
|
||||
/// \brief Determine whether the Value is set and not void.
|
||||
//
|
||||
/// Determine whether the Value is set and not void.
|
||||
/// Only in this case can getAs() or simplisticCastAs() be called.
|
||||
/// Only in this case can we can get the represented value.
|
||||
bool hasValue() const { return isValid() && !isVoid(); }
|
||||
|
||||
/// \brief Get a reference to the value without type checking.
|
||||
/// T *must* correspond to type. Else use simplisticCastAs()!
|
||||
template <typename T> T getAs() const;
|
||||
|
||||
// FIXME: If the cling::Value is destroyed and it handed out an address that
|
||||
// might be accessing invalid memory.
|
||||
void** getPtrAddress() { return &m_Storage.m_Ptr; }
|
||||
void* getPtr() const { return m_Storage.m_Ptr; }
|
||||
void setPtr(void* Val) { m_Storage.m_Ptr = Val; }
|
||||
|
||||
// FIXME: Add AssertInvalid("##name")
|
||||
#ifndef NDEBUG
|
||||
#define _STRINGIFY(x) #x
|
||||
#define STRINGIFY(x) _STRINGIFY(x)
|
||||
// FIXME: Uncomment and debug the various type mismatches.
|
||||
//#define ASSERT_TYPE_MISMATCH(name) AssertTypeMismatch(STRINGIFY(name))
|
||||
#define ASSERT_TYPE_MISMATCH(name)
|
||||
#undef STRINGIFY
|
||||
#undef _STRINGIFY
|
||||
#else
|
||||
#define ASSERT_TYPE_MISMATCH(name)
|
||||
#endif // NDEBUG
|
||||
#define X(type, name) \
|
||||
type get##name() const {return m_Storage.m_##name;} \
|
||||
void set##name(type Val) {m_Storage.m_##name = Val;} \
|
||||
type get##name() const { \
|
||||
ASSERT_TYPE_MISMATCH(name); \
|
||||
return m_Storage.m_##name; \
|
||||
} \
|
||||
void set##name(type Val) { \
|
||||
ASSERT_TYPE_MISMATCH(name); \
|
||||
m_Storage.m_##name = Val; \
|
||||
} \
|
||||
|
||||
BUILTIN_TYPES
|
||||
|
||||
|
@ -251,6 +251,15 @@ namespace cling {
|
||||
return QT.getCanonicalType();
|
||||
}
|
||||
|
||||
void Value::AssertTypeMismatch(const char* Type) const {
|
||||
#ifndef NDEBUG
|
||||
assert(hasBuiltinType() && "Must be a builtin!");
|
||||
const clang::BuiltinType *BT = getType()->castAs<clang::BuiltinType>();
|
||||
clang::PrintingPolicy Policy = getASTContext().getPrintingPolicy();
|
||||
#endif // NDEBUG
|
||||
assert(BT->getName(Policy).equals(Type));
|
||||
}
|
||||
|
||||
template <typename T> T convert(clang::QualType QT, Value::Storage& S) {
|
||||
QT = getBuiltinCanonicalType(QT);
|
||||
assert(QT->isBuiltinType());
|
||||
@ -310,7 +319,7 @@ namespace cling {
|
||||
}
|
||||
|
||||
void Value::AssertOnUnsupportedTypeCast() const {
|
||||
assert("unsupported type in Value, cannot cast simplistically!" && 0);
|
||||
assert("unsupported type in Value, cannot cast!" && 0);
|
||||
}
|
||||
|
||||
namespace valuePrinterInternal {
|
||||
|
Loading…
Reference in New Issue
Block a user