140 lines
4.7 KiB
C++
140 lines
4.7 KiB
C++
//------------------------------------------------------------------------------
|
|
// CLING - the C++ LLVM-based InterpreterG :)
|
|
// author: Axel Naumann <axel@cern.ch>
|
|
//
|
|
// This file is dual-licensed: you can choose to license it under the University
|
|
// of Illinois Open Source License or the GNU Lesser General Public License. See
|
|
// LICENSE.TXT for details.
|
|
//------------------------------------------------------------------------------
|
|
|
|
#include "cling/Interpreter/Value.h"
|
|
|
|
#include "llvm/ExecutionEngine/GenericValue.h"
|
|
|
|
#include "clang/AST/Type.h"
|
|
#include "clang/AST/CanonicalType.h"
|
|
|
|
namespace cling {
|
|
|
|
Value::Value() :m_ClangType() {
|
|
assert(sizeof(llvm::GenericValue) <= sizeof(m_GV)
|
|
&& "GlobalValue buffer too small");
|
|
new (m_GV) llvm::GenericValue();
|
|
}
|
|
|
|
Value::Value(const Value& other) : m_ClangType(other.m_ClangType) {
|
|
assert(sizeof(llvm::GenericValue) <= sizeof(m_GV)
|
|
&& "GlobalValue buffer too small");
|
|
new (m_GV) llvm::GenericValue(other.getGV());
|
|
}
|
|
|
|
Value::Value(const llvm::GenericValue& v, clang::QualType t)
|
|
: m_ClangType(t.getAsOpaquePtr())
|
|
{
|
|
<<<<<<< HEAD
|
|
=======
|
|
assert(sizeof(llvm::GenericValue) <= sizeof(m_GV)
|
|
&& "GlobalValue buffer too small");
|
|
new (m_GV) llvm::GenericValue(v);
|
|
}
|
|
|
|
Value::Value(const llvm::GenericValue& v, clang::QualType clangTy,
|
|
const llvm::Type* llvmTy) : m_ClangType(clangTy.getAsOpaquePtr()) {
|
|
>>>>>>> Remove llvm::Type from the cling::Value
|
|
assert(sizeof(llvm::GenericValue) <= sizeof(m_GV)
|
|
&& "GlobalValue buffer too small");
|
|
new (m_GV) llvm::GenericValue(v);
|
|
}
|
|
|
|
Value& Value::operator =(const Value& other) {
|
|
m_ClangType = other.m_ClangType;
|
|
setGV(other.getGV());
|
|
return *this;
|
|
}
|
|
|
|
const llvm::GenericValue& Value::getGV() const {
|
|
return reinterpret_cast<const llvm::GenericValue&>(m_GV);
|
|
}
|
|
|
|
llvm::GenericValue& Value::getGV() {
|
|
return reinterpret_cast<llvm::GenericValue&>(m_GV);
|
|
}
|
|
|
|
void Value::setGV(const llvm::GenericValue& GV) {
|
|
assert(sizeof(llvm::GenericValue) <= sizeof(m_GV)
|
|
&& "GlobalValue buffer too small");
|
|
reinterpret_cast<llvm::GenericValue&>(m_GV) = GV;
|
|
}
|
|
|
|
clang::QualType Value::getClangType() const {
|
|
return clang::QualType::getFromOpaquePtr(m_ClangType);
|
|
}
|
|
|
|
bool Value::isValid() const { return !getClangType().isNull(); }
|
|
|
|
bool Value::isVoid(const clang::ASTContext& ASTContext) const {
|
|
return isValid()
|
|
&& getClangType().getDesugaredType(ASTContext)->isVoidType();
|
|
}
|
|
|
|
Value::EStorageType Value::getStorageType() const {
|
|
const clang::Type* desugCanon = getClangType()->getUnqualifiedDesugaredType();
|
|
desugCanon = desugCanon->getCanonicalTypeUnqualified()->getTypePtr()
|
|
->getUnqualifiedDesugaredType();
|
|
if (desugCanon->isSignedIntegerOrEnumerationType())
|
|
return kSignedIntegerOrEnumerationType;
|
|
else if (desugCanon->isUnsignedIntegerOrEnumerationType())
|
|
return kUnsignedIntegerOrEnumerationType;
|
|
else if (desugCanon->isRealFloatingType()) {
|
|
const clang::BuiltinType* BT = desugCanon->getAs<clang::BuiltinType>();
|
|
if (BT->getKind() == clang::BuiltinType::Double)
|
|
return kDoubleType;
|
|
else if (BT->getKind() == clang::BuiltinType::Float)
|
|
return kFloatType;
|
|
else if (BT->getKind() == clang::BuiltinType::LongDouble)
|
|
return kLongDoubleType;
|
|
} else if (desugCanon->isPointerType() || desugCanon->isObjectType() || desugCanon->isReferenceType())
|
|
return kPointerType;
|
|
return kUnsupportedType;
|
|
}
|
|
|
|
void* Value::getAs(void**) const { return getGV().PointerVal; }
|
|
double Value::getAs(double*) const { return getGV().DoubleVal; }
|
|
long double Value::getAs(long double*) const {
|
|
return getAs((double*)0);
|
|
}
|
|
float Value::getAs(float*) const { return getGV().FloatVal; }
|
|
bool Value::getAs(bool*) const { return getGV().IntVal.getBoolValue(); }
|
|
signed char Value::getAs(signed char*) const {
|
|
return (signed char) getAs((signed long long*)0);
|
|
}
|
|
unsigned char Value::getAs(unsigned char*) const {
|
|
return (unsigned char) getAs((unsigned long long*)0);
|
|
}
|
|
signed short Value::getAs(signed short*) const {
|
|
return (signed short) getAs((signed long long*)0);
|
|
}
|
|
unsigned short Value::getAs(unsigned short*) const {
|
|
return (unsigned short) getAs((unsigned long long*)0);
|
|
}
|
|
signed int Value::getAs(signed int*) const {
|
|
return (signed int) getAs((signed long long*)0);
|
|
}
|
|
unsigned int Value::getAs(unsigned int*) const {
|
|
return (unsigned int) getAs((unsigned long long*)0);
|
|
}
|
|
signed long Value::getAs(signed long*) const {
|
|
return (long) getAs((signed long long*)0);
|
|
}
|
|
unsigned long Value::getAs(unsigned long*) const {
|
|
return (signed long) getAs((unsigned long long*)0);
|
|
}
|
|
signed long long Value::getAs(signed long long*) const {
|
|
return getGV().IntVal.getSExtValue();
|
|
}
|
|
unsigned long long Value::getAs(unsigned long long*) const {
|
|
return getGV().IntVal.getZExtValue();
|
|
}
|
|
|
|
} // namespace cling
|