From 1813c28738705c7363dc307a52711d2a440f22ce Mon Sep 17 00:00:00 2001 From: Axel Naumann <Axel.Naumann@cern.ch> Date: Sun, 9 Mar 2014 13:53:19 +0100 Subject: [PATCH] Simplify; adapt to new Value. --- core/meta/inc/TInterpreterValue.h | 9 +- core/meta/src/TCling.cxx | 26 +- core/meta/src/TCling.h | 6 +- core/meta/src/TClingCallFunc.cxx | 1070 ++++------------- core/meta/src/TClingCallFunc.h | 23 +- core/meta/src/TClingClassInfo.cxx | 1 - core/meta/src/TClingValue.cxx | 43 +- core/meta/src/TClingValue.h | 19 +- interpreter/cling/Module.mk | 2 +- .../DynamicLookupRuntimeUniverse.h | 6 +- .../cling/Interpreter/RuntimeUniverse.h | 36 +- .../cling/include/cling/Interpreter/Value.h | 35 +- .../cling/lib/Interpreter/CMakeLists.txt | 1 - .../cling/lib/Interpreter/Interpreter.cpp | 4 - interpreter/cling/lib/Interpreter/Value.cpp | 21 +- .../Interpreter/ValueExtractionSynthesizer.h | 2 +- interpreter/cling/test/Interfaces/evaluate.C | 61 +- interpreter/cling/test/Prompt/Regression.C | 6 +- 18 files changed, 418 insertions(+), 953 deletions(-) diff --git a/core/meta/inc/TInterpreterValue.h b/core/meta/inc/TInterpreterValue.h index a4a4123d0fc..91f9dd06b76 100644 --- a/core/meta/inc/TInterpreterValue.h +++ b/core/meta/inc/TInterpreterValue.h @@ -30,14 +30,15 @@ class TInterpreterValue { -public: - TInterpreterValue() { } +private: TInterpreterValue(const TInterpreterValue &); // not implemented TInterpreterValue& operator=(TInterpreterValue &); // not implemented +public: + TInterpreterValue() { } virtual ~TInterpreterValue() { } - virtual void* const& Get() const = 0; - virtual void*& Get() = 0; + virtual const void* GetValAddr() const = 0; + virtual void* GetValAddr() = 0; virtual Bool_t IsValid() const = 0; virtual Double_t GetAsDouble() const = 0; diff --git a/core/meta/src/TCling.cxx b/core/meta/src/TCling.cxx index c3f87cb8a1f..ebe3b31db0d 100644 --- a/core/meta/src/TCling.cxx +++ b/core/meta/src/TCling.cxx @@ -90,7 +90,7 @@ #include "cling/Interpreter/DynamicLibraryManager.h" #include "cling/Interpreter/Interpreter.h" #include "cling/Interpreter/LookupHelper.h" -#include "cling/Interpreter/StoredValueRef.h" +#include "cling/Interpreter/Value.h" #include "cling/Interpreter/Transaction.h" #include "cling/MetaProcessor/MetaProcessor.h" #include "cling/Utils/AST.h" @@ -765,7 +765,7 @@ TCling::TCling(const char *name, const char *title) llvm::install_fatal_error_handler(&exceptionErrorHandler); - fTemporaries = new std::vector<cling::StoredValueRef>(); + fTemporaries = new std::vector<cling::Value>(); std::vector<std::string> clingArgsStorage; clingArgsStorage.push_back("cling4root"); @@ -1242,7 +1242,7 @@ Long_t TCling::ProcessLine(const char* line, EErrorCode* error/*=0*/) // not a complete statement. int indent = 0; // This will hold the resulting value of the evaluation the given line. - cling::StoredValueRef result; + cling::Value result; cling::Interpreter::CompilationResult compRes = cling::Interpreter::kSuccess; if (!strncmp(sLine.Data(), ".L", 2) || !strncmp(sLine.Data(), ".x", 2) || !strncmp(sLine.Data(), ".X", 2)) { @@ -1333,10 +1333,10 @@ Long_t TCling::ProcessLine(const char* line, EErrorCode* error/*=0*/) } if (compRes == cling::Interpreter::kSuccess && result.isValid() - && !result.get().isVoid(fInterpreter->getCI()->getASTContext())) + && !result.isVoid(fInterpreter->getCI()->getASTContext())) { gROOT->SetLineHasBeenProcessed(); - return result.get().simplisticCastAs<long>(); + return result.simplisticCastAs<long>(); } gROOT->SetLineHasBeenProcessed(); return 0; @@ -1607,7 +1607,7 @@ void TCling::ClearStack() { // Delete existing temporary values. - // No-op for cling due to StoredValueRef. + // No-op for cling due to cling::Value. } //______________________________________________________________________________ @@ -1927,7 +1927,7 @@ Long_t TCling::Calc(const char* line, EErrorCode* error) if (error) { *error = TInterpreter::kNoError; } - cling::StoredValueRef valRef; + cling::Value valRef; cling::Interpreter::CompilationResult cr = fInterpreter->evaluate(line, valRef); if (cr != cling::Interpreter::kSuccess) { // Failure in compilation. @@ -1946,7 +1946,7 @@ Long_t TCling::Calc(const char* line, EErrorCode* error) return 0L; } - if (valRef.get().isVoid(fInterpreter->getCI()->getASTContext())) { + if (valRef.isVoid(fInterpreter->getCI()->getASTContext())) { return 0; } @@ -1956,7 +1956,7 @@ Long_t TCling::Calc(const char* line, EErrorCode* error) gROOT->SetLineHasBeenProcessed(); } #endif // R__WIN32 - return valRef.get().simplisticCastAs<long>(); + return valRef.simplisticCastAs<long>(); } //______________________________________________________________________________ @@ -5004,7 +5004,7 @@ void TCling::SetRTLD_LAZY() const void TCling::SetTempLevel(int val) const { // Create / close a scope for temporaries. No-op for cling; use - // StoredValueRef instead. + // cling::Value instead. } //______________________________________________________________________________ @@ -5069,12 +5069,12 @@ TInterpreterValue *TCling::CreateTemporary() void TCling::RegisterTemporary(const TInterpreterValue& value) { using namespace cling; - const StoredValueRef& SVR = reinterpret_cast<const StoredValueRef&>(value.Get()); - RegisterTemporary(SVR); + const Value* V = reinterpret_cast<const Value*>(value.GetValAddr()); + RegisterTemporary(*V); } //______________________________________________________________________________ -void TCling::RegisterTemporary(const cling::StoredValueRef& value) +void TCling::RegisterTemporary(const cling::Value& value) { // Register value as a temporary, extending its lifetime to that of the // interpreter. This is needed for TCling's compatibility interfaces diff --git a/core/meta/src/TCling.h b/core/meta/src/TCling.h index f046a73e7b6..65f0019eb7c 100644 --- a/core/meta/src/TCling.h +++ b/core/meta/src/TCling.h @@ -54,8 +54,8 @@ namespace clang { namespace cling { class Interpreter; class MetaProcessor; - class StoredValueRef; class Transaction; + class Value; } class TClingCallbacks; @@ -106,7 +106,7 @@ private: // Data Members cling::Interpreter* fInterpreter; // The interpreter. cling::MetaProcessor* fMetaProcessor; // The metaprocessor. - std::vector<cling::StoredValueRef> *fTemporaries; // Stack of temporaries + std::vector<cling::Value> *fTemporaries; // Stack of temporaries ROOT::TMetaUtils::TNormalizedCtxt *fNormalizedCtxt; // Which typedef to avoid stripping. ROOT::TMetaUtils::TClingLookupHelper *fLookupHelper; // lookup helper used by TClassEdit @@ -283,7 +283,7 @@ public: // Public Interface TInterpreterValue *CreateTemporary(); void RegisterTemporary(const TInterpreterValue& value); - void RegisterTemporary(const cling::StoredValueRef& value); + void RegisterTemporary(const cling::Value& value); const ROOT::TMetaUtils::TNormalizedCtxt& GetNormalizedContext() const {return *fNormalizedCtxt;}; // core/meta helper functions. diff --git a/core/meta/src/TClingCallFunc.cxx b/core/meta/src/TClingCallFunc.cxx index c508ff5ea45..15d1921dda5 100644 --- a/core/meta/src/TClingCallFunc.cxx +++ b/core/meta/src/TClingCallFunc.cxx @@ -40,8 +40,8 @@ #include "cling/Interpreter/CompilationOptions.h" #include "cling/Interpreter/Interpreter.h" #include "cling/Interpreter/LookupHelper.h" -#include "cling/Interpreter/StoredValueRef.h" #include "cling/Interpreter/Transaction.h" +#include "cling/Interpreter/Value.h" #include "cling/Utils/AST.h" #include "clang/AST/ASTContext.h" @@ -99,16 +99,17 @@ indent(ostringstream& buf, int indent_level) } static -cling::StoredValueRef -EvaluateExpr(cling::Interpreter* interp, const Expr* E) +void +EvaluateExpr(cling::Interpreter* interp, const Expr* E, cling::Value& V) { - // Evaluate an Expr* and return its cling::StoredValueRef + // Evaluate an Expr* and return its cling::Value ASTContext& C = interp->getCI()->getASTContext(); APSInt res; if (E->EvaluateAsInt(res, C, /*AllowSideEffects*/Expr::SE_NoSideEffects)) { - GenericValue gv; - gv.IntVal = res; - return cling::StoredValueRef::bitwiseCopy(*interp, cling::Value(gv, C.IntTy)); + // IntTy or maybe better E->getType()? + V = cling::Value(C.IntTy, 0); + V.getULL() = res.getZExtValue(); + return; } // TODO: Build a wrapper around the expression to avoid decompilation and // compilation and other string operations. @@ -122,104 +123,31 @@ EvaluateExpr(cling::Interpreter* interp, const Expr* E) E->printPretty(out, /*Helper=*/0, Policy, /*Indentation=*/0); out << ';'; // no value printing out.flush(); - cling::StoredValueRef valref; - cling::Interpreter::CompilationResult cr = interp->evaluate(buf, valref); - if (cr != cling::Interpreter::kSuccess) { - return cling::StoredValueRef::invalidValue(); - } - return valref; + // Evaluate() will set V to invalid if evaluation fails. + interp->evaluate(buf, V); } namespace { -template <typename T> -T sv_to_long_long_u_or_not(const cling::StoredValueRef& svref) +template <typename returnType> +returnType sv_to(const cling::Value& val) { - const cling::Value& valref = svref.get(); - QualType QT = valref.getClangType(); - if (QT.isNull()) { - Error("TClingCallFunc::sv_to_long_long", "Null Type!"); - return 0; - } - GenericValue gv = valref.getGV(); + QualType QT = val.getType(); if (QT->isMemberPointerType()) { - const MemberPointerType* MPT = - QT->getAs<MemberPointerType>(); + const MemberPointerType* MPT = QT->getAs<MemberPointerType>(); if (MPT->isMemberDataPointer()) { - return (T) (ptrdiff_t) gv.PointerVal; + return (returnType) (ptrdiff_t)val.getPtr(); } - return (T) gv.PointerVal; + return (returnType) (long) val.getPtr(); } if (QT->isPointerType() || QT->isArrayType() || QT->isRecordType() || QT->isReferenceType()) { - return (T) gv.PointerVal; + return (returnType) (long) val.getPtr(); } if (const EnumType* ET = dyn_cast<EnumType>(&*QT)) { if (ET->getDecl()->getIntegerType()->hasSignedIntegerRepresentation()) - return (T) gv.IntVal.getSExtValue(); + return (returnType) val.getLL(); else - return (T) gv.IntVal.getZExtValue(); - } - if (const BuiltinType* BT = - dyn_cast<BuiltinType>(&*QT)) { - if (BT->isSignedInteger()) { - return gv.IntVal.getSExtValue(); - } else if (BT->isUnsignedInteger()) { - return (T) gv.IntVal.getZExtValue(); - } else { - switch (BT->getKind()) { - case BuiltinType::Float: - return (T) gv.FloatVal; - case BuiltinType::Double: - return (T) gv.DoubleVal; - case BuiltinType::LongDouble: - // FIXME: Implement this! - break; - case BuiltinType::NullPtr: - // C++11 nullptr - return 0; - default: break; - } - } - } - Error("TClingCallFunc::sv_to_long_long", "Cannot handle this type!"); - QT->dump(); - return 0; -} -} - -static -long long sv_to_long_long(const cling::StoredValueRef& svref) { - return sv_to_long_long_u_or_not<long long>(svref); -} -static -unsigned long long sv_to_ulong_long(const cling::StoredValueRef& svref) { - return sv_to_long_long_u_or_not<unsigned long long>(svref); -} - -namespace { -template <typename returnType> -returnType sv_to(const cling::StoredValueRef& svref) -{ - const cling::Value& valref = svref.get(); - QualType QT = valref.getClangType(); - GenericValue gv = valref.getGV(); - if (QT->isMemberPointerType()) { - const MemberPointerType* MPT = - QT->getAs<MemberPointerType>(); - if (MPT->isMemberDataPointer()) { - return (returnType) *(ptrdiff_t*)gv.PointerVal; - } - return (returnType) (long) gv.PointerVal; - } - if (QT->isPointerType() || QT->isArrayType() || QT->isRecordType() || - QT->isReferenceType()) { - return (returnType) (long) gv.PointerVal; - } - if (const EnumType* ET = dyn_cast<EnumType>(&*QT)) { - // Note: We may need to worry about the underlying type - // of the enum here. - (void) ET; - return (returnType) gv.IntVal.getSExtValue(); + return (returnType) val.getULL(); } if (const BuiltinType* BT = dyn_cast<BuiltinType>(&*QT)) { @@ -231,234 +159,97 @@ returnType sv_to(const cling::StoredValueRef& svref) // Do not reorder! // switch (BT->getKind()) { - // - // Builtin Types - // - case BuiltinType::Void: { - // void - } + case BuiltinType::Void: break; // // Unsigned Types // - case BuiltinType::Bool: { - // bool - return (returnType) gv.IntVal.getZExtValue(); - } - break; - case BuiltinType::Char_U: { - // char on targets where it is unsigned - return (returnType) gv.IntVal.getZExtValue(); - } - break; - case BuiltinType::UChar: { - // unsigned char - return (returnType) gv.IntVal.getZExtValue(); - } - break; - case BuiltinType::WChar_U: { - // wchar_t on targets where it is unsigned - // The standard doesn't allow to specify signednedd of wchar_t - // thus this maps simply to wchar_t. - return (returnType) (wchar_t) gv.IntVal.getZExtValue(); - } + case BuiltinType::Bool: + case BuiltinType::Char_U: // char on targets where it is unsigned + case BuiltinType::UChar: + return (returnType) val.getULL(); break; - case BuiltinType::Char16: { - // char16_t - return (returnType) gv.IntVal.getZExtValue(); - } - break; - case BuiltinType::Char32: { - // char32_t - return (returnType) gv.IntVal.getZExtValue(); - } - break; - case BuiltinType::UShort: { - // unsigned short - return (returnType) gv.IntVal.getZExtValue(); - } - break; - case BuiltinType::UInt: { - // unsigned int - return (returnType) gv.IntVal.getZExtValue(); - } - break; - case BuiltinType::ULong: { - // unsigned long - return (returnType) gv.IntVal.getZExtValue(); - } + + case BuiltinType::WChar_U: + // wchar_t on targets where it is unsigned + // The standard doesn't allow to specify signednedd of wchar_t + // thus this maps simply to wchar_t. + return (returnType) (wchar_t) val.getULL(); break; - case BuiltinType::ULongLong: { - // unsigned long long - return (returnType) gv.IntVal.getZExtValue(); - } + + case BuiltinType::Char16: + case BuiltinType::Char32: + case BuiltinType::UShort: + case BuiltinType::UInt: + case BuiltinType::ULong: + case BuiltinType::ULongLong: + return (returnType) val.getULL(); break; - case BuiltinType::UInt128: { - // __uint128_t - } + + case BuiltinType::UInt128: + // __uint128_t break; + // // Signed Types // - case BuiltinType::Char_S: { - // char on targets where it is signed - return (returnType) gv.IntVal.getSExtValue(); - } + case BuiltinType::Char_S: // char on targets where it is signed + case BuiltinType::SChar: + return (returnType) val.getLL(); break; - case BuiltinType::SChar: { - // signed char - return (returnType) gv.IntVal.getSExtValue(); - } - break; - case BuiltinType::WChar_S: { + + case BuiltinType::WChar_S: // wchar_t on targets where it is signed // The standard doesn't allow to specify signednedd of wchar_t // thus this maps simply to wchar_t. - return (returnType) (wchar_t) gv.IntVal.getSExtValue(); - } - break; - case BuiltinType::Short: { - // short - return (returnType) gv.IntVal.getSExtValue(); - } + return (returnType) (wchar_t) val.getLL(); break; - case BuiltinType::Int: { - // int - return (returnType) gv.IntVal.getSExtValue(); - } - break; - case BuiltinType::Long: { - // long - return (returnType) gv.IntVal.getSExtValue(); - } - break; - case BuiltinType::LongLong: { - // long long - return (returnType) gv.IntVal.getSExtValue(); - } - break; - case BuiltinType::Int128: { - // __int128_t - } - break; - case BuiltinType::Half: { - // half in OpenCL, __fp16 in ARM NEON - } - break; - case BuiltinType::Float: { - // float - return (returnType) gv.FloatVal; - } - break; - case BuiltinType::Double: { - // double - return (returnType) gv.DoubleVal; - } - break; - case BuiltinType::LongDouble: { - // long double - // FIXME: Implement this! - } - break; - // - // Language-Specific Types - // - case BuiltinType::NullPtr: { - // C++11 nullptr - } - break; - case BuiltinType::ObjCId: { - // Objective C 'id' type - } - break; - case BuiltinType::ObjCClass: { - // Objective C 'Class' type - } - break; - case BuiltinType::ObjCSel: { - // Objective C 'SEL' type - } - break; - case BuiltinType::OCLImage1d: { - // OpenCL image type - } - break; - case BuiltinType::OCLImage1dArray: { - // OpenCL image type - } - break; - case BuiltinType::OCLImage1dBuffer: { - // OpenCL image type - } - break; - case BuiltinType::OCLImage2d: { - // OpenCL image type - } - break; - case BuiltinType::OCLImage2dArray: { - // OpenCL image type - } - break; - case BuiltinType::OCLImage3d: { - // OpenCL image type - } - break; - case BuiltinType::OCLSampler: { - // OpenCL sampler_t - } - break; - case BuiltinType::OCLEvent: { - // OpenCL event_t - } - break; - // - // Placeholder types. - // - // These types are used during intermediate phases - // of semantic analysis. They are eventually resolved - // to one of the preceeding types. - // - case BuiltinType::Dependent: { - // dependent on a template argument - } - break; - case BuiltinType::Overload: { - // an unresolved function overload set - } + + case BuiltinType::Short: + case BuiltinType::Int: + case BuiltinType::Long: + case BuiltinType::LongLong: + return (returnType) val.getLL(); break; - case BuiltinType::BoundMember: { - // a bound C++ non-static member function - } + + case BuiltinType::Int128: break; - case BuiltinType::PseudoObject: { - // Object C @property or VS.NET __property - } + + case BuiltinType::Half: + // half in OpenCL, __fp16 in ARM NEON break; - case BuiltinType::UnknownAny: { - // represents an unknown type - } + + case BuiltinType::Float: + return (returnType) val.getFloat(); + case BuiltinType::Double: + return (returnType) val.getDouble(); break; - case BuiltinType::BuiltinFn: { - // a compiler builtin function - } + case BuiltinType::LongDouble: + return (returnType) val.getLongDouble(); break; - case BuiltinType::ARCUnbridgedCast: { - // Objective C Automatic Reference Counting cast - // which would normally require __bridge, but which - // may be ok because of the context. - } + + case BuiltinType::NullPtr: + return (returnType) 0; break; - default: { - // There should be no others. This is here in case - // this changes in the future. - } + + default: break; } } Error("TClingCallFunc::sv_to", "Invalid Type!"); QT->dump(); - return 0.0; + return 0; } + +static +long long sv_to_long_long(const cling::Value& val) { + return sv_to<long long>(val); +} +static +unsigned long long sv_to_ulong_long(const cling::Value& val) { + return sv_to<unsigned long long>(val); +} + } // unnamed namespace. void* @@ -1688,7 +1479,7 @@ TClingCallFunc::exec(void* address, void* ret) const const FunctionDecl* FD = fMethod->GetMethodDecl(); // - // Convert the arguments from cling::StoredValueRef to their + // Convert the arguments from cling::Value to their // actual type and store them in a holder for passing to the // wrapper function by pointer to value. // @@ -1719,7 +1510,7 @@ TClingCallFunc::exec(void* address, void* ret) const Ty = PVD->getType(); } else { - Ty = fArgVals[i].get().getClangType(); + Ty = fArgVals[i].getType(); } QualType QT = Ty.getCanonicalType(); if (QT->isReferenceType()) { @@ -1972,7 +1763,7 @@ TClingCallFunc::exec(void* address, void* ret) const case BuiltinType::NullPtr: { // C++11 nullptr ValHolder vh; - vh.u.vp = (void*) fArgVals[i].get().getGV().PointerVal; + vh.u.vp = fArgVals[i].getPtr(); vh_ary.push_back(vh); vp_ary.push_back(&vh_ary.back()); } @@ -2133,8 +1924,24 @@ TClingCallFunc::exec(void* address, void* ret) const (*fWrapper)(address, (int)num_args, (void**)vp_ary.data(), ret); } +template <typename T> +void TClingCallFunc::execWithLL(void* address, clang::QualType QT, + cling::Value* val) const { + T ret; // leave uninit for valgrind's sake! + exec(address, &ret); + val->getLL() = ret; +} + +template <typename T> +void TClingCallFunc::execWithULL(void* address, clang::QualType QT, + cling::Value* val) const { + T ret; // leave uninit for valgrind's sake! + exec(address, &ret); + val->getULL() = ret; +} + void -TClingCallFunc::exec_with_valref_return(void* address, cling::StoredValueRef* ret) const +TClingCallFunc::exec_with_valref_return(void* address, cling::Value* ret) const { if (!ret) { exec(address, 0); @@ -2147,525 +1954,182 @@ TClingCallFunc::exec_with_valref_return(void* address, cling::StoredValueRef* re const TypeDecl* TD = dyn_cast<TypeDecl>(CD->getDeclContext()); QualType ClassTy(TD->getTypeForDecl(), 0); QualType QT = Context.getLValueReferenceType(ClassTy); - GenericValue gv; - exec(address, &gv.PointerVal); - *ret = cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT)); + *ret = cling::Value(QT, fInterp); + // Store the new()'ed address in getPtr() + exec(address, &ret->getPtr()); return; } QualType QT = FD->getReturnType().getCanonicalType(); if (QT->isReferenceType()) { - GenericValue gv; - exec(address, &gv.PointerVal); - *ret = cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT)); + *ret = cling::Value(QT, fInterp); + exec(address, &ret->getPtr()); return; } else if (QT->isMemberPointerType()) { - const MemberPointerType* MPT = - QT->getAs<MemberPointerType>(); + const MemberPointerType* MPT = QT->getAs<MemberPointerType>(); if (MPT->isMemberDataPointer()) { // A member data pointer is a actually a struct with one // member of ptrdiff_t, the offset from the base of the object // storage to the storage for the designated data member. - GenericValue gv; - exec(address, &gv.PointerVal); - *ret = cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT)); + // But that's not relevant: we use it as a non-builtin, allocated + // type. + *ret = cling::Value(QT, fInterp); + exec(address, ret->getPtr()); return; } // We are a function member pointer. - GenericValue gv; - exec(address, &gv.PointerVal); - *ret = cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT)); + *ret = cling::Value(QT, fInterp); + exec(address, &ret->getPtr()); return; } else if (QT->isPointerType() || QT->isArrayType()) { // Note: ArrayType is an illegal function return value type. - GenericValue gv; - exec(address, &gv.PointerVal); - *ret = cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT)); + *ret = cling::Value(QT, fInterp); + exec(address, &ret->getPtr()); return; } else if (QT->isRecordType()) { - *ret = cling::StoredValueRef::allocate(*fInterp, QT); - exec(address, ret->get().getAs<void*>()); + *ret = cling::Value(QT, fInterp); + exec(address, ret->getPtr()); return; } - else if (const EnumType* ET = - dyn_cast<EnumType>(&*QT)) { + else if (const EnumType* ET = dyn_cast<EnumType>(&*QT)) { // Note: We may need to worry about the underlying type // of the enum here. (void) ET; - uint64_t numBits = Context.getTypeSize(QT); - int retVal = 0; - exec(address, &retVal); - GenericValue gv; - gv.IntVal = APInt(numBits, (uint64_t) retVal, - true/*isSigned*/); - *ret = cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT)); + execWithLL<int>(address, QT, ret); return; } - else if (const BuiltinType* BT = - dyn_cast<BuiltinType>(&*QT)) { - uint64_t numBits = Context.getTypeSize(QT); + else if (const BuiltinType* BT = dyn_cast<BuiltinType>(&*QT)) { + *ret = cling::Value(QT, 0); switch (BT->getKind()) { - // - // Builtin Types - // - case BuiltinType::Void: { - // void - exec(address, 0); - return; - } + case BuiltinType::Void: + exec(address, 0); + return; break; + // // Unsigned Types // - case BuiltinType::Bool: { - // bool - bool retVal = false; - exec(address, &retVal); - GenericValue gv; - gv.IntVal = APInt(numBits, (uint64_t) retVal, false/*isSigned*/); - *ret = cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT)); - return; - } - break; - case BuiltinType::Char_U: { - // char on targets where it is unsigned - char retVal = '\0'; - exec(address, &retVal); - GenericValue gv; - gv.IntVal = APInt(numBits, (uint64_t) retVal, false/*isSigned*/); - *ret = cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT)); - return; - } - break; - case BuiltinType::UChar: { - // unsigned char - unsigned char retVal = '\0'; - exec(address, &retVal); - GenericValue gv; - gv.IntVal = APInt(numBits, (uint64_t) retVal, false/*isSigned*/); - *ret = cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT)); - return; - } - break; - case BuiltinType::WChar_U: { - // wchar_t on targets where it is unsigned. - // The standard doesn't allow to specify signednedd of wchar_t - // thus this maps simply to wchar_t. - wchar_t retVal = L'\0'; - exec(address, &retVal); - GenericValue gv; - gv.IntVal = APInt(numBits, (uint64_t) retVal, false/*isSigned*/); - *ret = cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT)); - return; - } - break; - case BuiltinType::Char16: { - // char16_t - Error("TClingCallFunc::exec_with_valref_return", - "Invalid type 'char16_t'!"); - return; - //char16_t retVal = u'\0'; - //exec(address, &retVal); - //GenericValue gv; - //gv.IntVal = APInt(numBits, (uint64_t) retVal, - // false/*isSigned*/); - //*ret = cling::StoredValueRef::bitwiseCopy(Context, - // cling::Value(gv, QT)); - //return; - } - break; - case BuiltinType::Char32: { - // char32_t - Error("TClingCallFunc::exec_with_valref_return", - "Invalid type 'char32_t'!"); - return; - //char32_t retVal = U'\0'; - //exec(address, &retVal); - //GenericValue gv; - //gv.IntVal = APInt(numBits, (uint64_t) retVal, - // false/*isSigned*/); - //*ret = cling::StoredValueRef::bitwiseCopy(Context, - // cling::Value(gv, QT)); - //return; - } - break; - case BuiltinType::UShort: { - // unsigned short - unsigned short retVal = 0; - exec(address, &retVal); - GenericValue gv; - gv.IntVal = APInt(numBits, (uint64_t) retVal, false/*isSigned*/); - *ret = cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT)); - return; - } - break; - case BuiltinType::UInt: { - // unsigned int - unsigned int retVal = 0; - exec(address, &retVal); - GenericValue gv; - gv.IntVal = APInt(numBits, (uint64_t) retVal, false/*isSigned*/); - *ret = cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT)); - return; - } - break; - case BuiltinType::ULong: { - // unsigned long - unsigned long retVal = 0; - exec(address, &retVal); - GenericValue gv; - gv.IntVal = APInt(numBits, (uint64_t) retVal, false/*isSigned*/); - *ret = cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT)); - return; - } - break; - case BuiltinType::ULongLong: { - // unsigned long long - unsigned long long retVal = 0; - exec(address, &retVal); - GenericValue gv; - gv.IntVal = APInt(numBits, (uint64_t) retVal, false/*isSigned*/); - *ret = cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT)); - return; - } + case BuiltinType::Bool: + execWithULL<bool>(address, QT, ret); + return; + break; + case BuiltinType::Char_U: // char on targets where it is unsigned + case BuiltinType::UChar: + execWithULL<char>(address, QT, ret); + return; + break; + case BuiltinType::WChar_U: + // wchar_t on targets where it is unsigned. + // The standard doesn't allow to specify signednedd of wchar_t + // thus this maps simply to wchar_t. + execWithULL<wchar_t>(address, QT, ret); + return; + break; + case BuiltinType::Char16: + Error("TClingCallFunc::exec_with_valref_return", + "Invalid type 'char16_t'!"); + return; + break; + case BuiltinType::Char32: + Error("TClingCallFunc::exec_with_valref_return", + "Invalid type 'char32_t'!"); + return; + break; + case BuiltinType::UShort: + execWithULL<unsigned short>(address, QT, ret); + return; + break; + case BuiltinType::UInt: + execWithULL<unsigned int>(address, QT, ret); + return; + break; + case BuiltinType::ULong: + execWithULL<unsigned long>(address, QT, ret); + return; + break; + case BuiltinType::ULongLong: + execWithULL<unsigned long long>(address, QT, ret); + return; break; case BuiltinType::UInt128: { - // __uint128_t Error("TClingCallFunc::exec_with_valref_return", "Invalid type '__uint128_t'!"); return; - //__uint128_t retVal = 0; - //exec(address, &retVal); - //GenericValue gv; - //gv.IntVal = APInt(numBits, (uint64_t) retVal, - // false/*isSigned*/); - //*ret = cling::StoredValueRef::bitwiseCopy(Context, - // cling::Value(gv, QT)); - //return; } break; + // // Signed Types // - // - // Signed Types - // - case BuiltinType::Char_S: { - // char on targets where it is signed - char retVal = '\0'; - exec(address, &retVal); - GenericValue gv; - gv.IntVal = APInt(numBits, (uint64_t) retVal, true/*isSigned*/); - *ret = cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT)); - return; - } + case BuiltinType::Char_S: // char on targets where it is signed + case BuiltinType::SChar: + execWithLL<signed char>(address, QT, ret); + return; + break; + case BuiltinType::WChar_S: + // wchar_t on targets where it is signed. + // The standard doesn't allow to specify signednedd of wchar_t + // thus this maps simply to wchar_t. + execWithLL<wchar_t>(address, QT, ret); + return; + break; + case BuiltinType::Short: + execWithLL<short>(address, QT, ret); + return; + break; + case BuiltinType::Int: + execWithLL<int>(address, QT, ret); + return; + break; + case BuiltinType::Long: + execWithLL<long>(address, QT, ret); + return; + break; + case BuiltinType::LongLong: + execWithLL<long long>(address, QT, ret); + return; + break; + case BuiltinType::Int128: + Error("TClingCallFunc::exec_with_valref_return", + "Invalid type '__int128_t'!"); + return; + break; + case BuiltinType::Half: + // half in OpenCL, __fp16 in ARM NEON + Error("TClingCallFunc::exec_with_valref_return", + "Invalid type 'Half'!"); + return; break; - case BuiltinType::SChar: { - // signed char - signed char retVal = '\0'; - exec(address, &retVal); - GenericValue gv; - gv.IntVal = APInt(numBits, (uint64_t) retVal, true/*isSigned*/); - *ret = cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT)); - return; - } - break; - case BuiltinType::WChar_S: { - // wchar_t on targets where it is signed. - // The standard doesn't allow to specify signednedd of wchar_t - // thus this maps simply to wchar_t. - wchar_t retVal = L'\0'; - exec(address, &retVal); - GenericValue gv; - gv.IntVal = APInt(numBits, (uint64_t) retVal, true/*isSigned*/); - *ret = cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT)); - return; - } - break; - case BuiltinType::Short: { - // short - short retVal = 0; - exec(address, &retVal); - GenericValue gv; - gv.IntVal = APInt(numBits, (uint64_t) retVal, true/*isSigned*/); - *ret = cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT)); - return; - } - break; - case BuiltinType::Int: { - // int - int retVal = 0; - exec(address, &retVal); - GenericValue gv; - gv.IntVal = APInt(numBits, (uint64_t) retVal, true/*isSigned*/); - *ret = cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT)); - return; - } - break; - case BuiltinType::Long: { - // long - long retVal = 0; - exec(address, &retVal); - GenericValue gv; - gv.IntVal = APInt(numBits, (uint64_t) retVal, true/*isSigned*/); - *ret = cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT)); - return; - } - break; - case BuiltinType::LongLong: { - // long long - long long retVal = 0; - exec(address, &retVal); - GenericValue gv; - gv.IntVal = APInt(numBits, (uint64_t) retVal, true/*isSigned*/); - *ret = cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT)); - return; - } - break; - case BuiltinType::Int128: { - // __int128_t - Error("TClingCallFunc::exec_with_valref_return", - "Invalid type '__int128_t'!"); - return; - //__int128_t retVal = 0; - //exec(address, &retVal); - //GenericValue gv; - //gv.IntVal = APInt(numBits, (uint64_t) retVal, - // true/*isSigned*/); - //*ret = cling::StoredValueRef::bitwiseCopy(Context, - // cling::Value(gv, QT)); - //return; - } - break; - case BuiltinType::Half: { - // half in OpenCL, __fp16 in ARM NEON - Error("TClingCallFunc::exec_with_valref_return", - "Invalid type 'Half'!"); - return; - //half retVal = 0; - //__fp16 retVal = 0; - //exec(address, &retVal); - //GenericValue gv; - //gv.IntVal = APInt(numBits, (uint64_t) retVal, - // true/*isSigned*/); - //*ret = cling::StoredValueRef::bitwiseCopy(Context, - // cling::Value(gv, QT)); - //return; - } - break; - case BuiltinType::Float: { - // float - GenericValue gv; - exec(address, &gv.FloatVal); - *ret = cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT)); - return; - } + case BuiltinType::Float: + exec(address, &ret->getFloat()); + return; break; - case BuiltinType::Double: { - // double - GenericValue gv; - exec(address, &gv.DoubleVal); - *ret = cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT)); - return; - } + case BuiltinType::Double: + exec(address, &ret->getDouble()); + return; break; - case BuiltinType::LongDouble: { - // long double - Error("TClingCallFunc::exec_with_valref_return", - "Invalid type 'LongDouble'!"); - return; - //long double retVal = 0.0L; - //exec(address, &retVal); - //GenericValue gv; - //gv.IntVal = APInt(numBits, (uint64_t) retVal, - // false/*isSigned*/); - //*ret = cling::StoredValueRef::bitwiseCopy(Context, - // cling::Value(gv, QT)); - //return; - } + case BuiltinType::LongDouble: + exec(address, &ret->getLongDouble()); + return; break; // // Language-Specific Types // - case BuiltinType::NullPtr: { - // C++11 nullptr - Error("TClingCallFunc::exec_with_valref_return", - "Invalid type 'nullptr'!"); - return; - } - break; - case BuiltinType::ObjCId: { - // Objective C 'id' type - Error("TClingCallFunc::exec_with_valref_return", - "Invalid type 'ObjCId'!"); - return; - } - break; - case BuiltinType::ObjCClass: { - // Objective C 'Class' type - Error("TClingCallFunc::exec_with_valref_return", - "Invalid type 'ObjCClass'!"); - return; - } - break; - case BuiltinType::ObjCSel: { - // Objective C 'SEL' type - Error("TClingCallFunc::exec_with_valref_return", - "Invalid type 'ObjCSel'!"); - return; - } - break; - case BuiltinType::OCLImage1d: { - // OpenCL image type - Error("TClingCallFunc::exec_with_valref_return", - "Invalid type 'OCLImage1d'!"); - return; - } - break; - case BuiltinType::OCLImage1dArray: { - // OpenCL image type - Error("TClingCallFunc::exec_with_valref_return", - "Invalid type 'OCLImage1dArray'!"); - return; - } - break; - case BuiltinType::OCLImage1dBuffer: { - // OpenCL image type - Error("TClingCallFunc::exec_with_valref_return", - "Invalid type 'OCLImage1dBuffer'!"); - return; - } - break; - case BuiltinType::OCLImage2d: { - // OpenCL image type - Error("TClingCallFunc::exec_with_valref_return", - "Invalid type 'OCLImage2d'!"); - return; - } - break; - case BuiltinType::OCLImage2dArray: { - // OpenCL image type - Error("TClingCallFunc::exec_with_valref_return", - "Invalid type 'OCLImage2dArray'!"); - return; - } - break; - case BuiltinType::OCLImage3d: { - // OpenCL image type - Error("TClingCallFunc::exec_with_valref_return", - "Invalid type 'OCLImage3d'!"); - return; - } - break; - case BuiltinType::OCLSampler: { - // OpenCL sampler_t - Error("TClingCallFunc::exec_with_valref_return", - "Invalid type 'OCLSampler'!"); - return; - } - break; - case BuiltinType::OCLEvent: { - // OpenCL event_t - Error("TClingCallFunc::exec_with_valref_return", - "Invalid type 'OCLEvent'!"); - return; - } - break; - // - // Placeholder types. - // - // These types are used during intermediate phases - // of semantic analysis. They are eventually resolved - // to one of the preceeding types. - // - case BuiltinType::Dependent: { - // dependent on a template argument - Error("TClingCallFunc::exec_with_valref_return", - "Invalid type 'Dependent'!"); - return; - } - break; - case BuiltinType::Overload: { - // an unresolved function overload set - Error("TClingCallFunc::exec_with_valref_return", - "Invalid type 'Overload'!"); - return; - } - break; - case BuiltinType::BoundMember: { - // a bound C++ non-static member function - Error("TClingCallFunc::exec_with_valref_return", - "Invalid type 'BoundMember'!"); - return; - } - break; - case BuiltinType::PseudoObject: { - // Object C @property or VS.NET __property - Error("TClingCallFunc::exec_with_valref_return", - "Invalid type 'PseudoObject'!"); - return; - } - break; - case BuiltinType::UnknownAny: { - // represents an unknown type - Error("TClingCallFunc::exec_with_valref_return", - "Invalid type 'UnknownAny'!"); - return; - } - break; - case BuiltinType::BuiltinFn: { - // a compiler builtin function - Error("TClingCallFunc::exec_with_valref_return", - "Invalid type 'BuiltinFn'!"); - return; - } - break; - case BuiltinType::ARCUnbridgedCast: { - // Objective C Automatic Reference Counting cast - // which would normally require __bridge, but which - // may be ok because of the context. - Error("TClingCallFunc::exec_with_valref_return", - "Invalid type 'ARCUnbridgedCast'!"); - return; - } + case BuiltinType::NullPtr: + // C++11 nullptr + Error("TClingCallFunc::exec_with_valref_return", + "Invalid type 'nullptr'!"); + return; break; - default: { - // There should be no others. This is here in case - // this changes in the future. - Error("TClingCallFunc::exec_with_valref_return", - "Unrecognized builtin type!"); - return; - } + default: break; } } Error("TClingCallFunc::exec_with_valref_return", "Unrecognized return type!"); + QT->dump(); return; } @@ -2689,7 +2153,8 @@ TClingCallFunc::EvaluateArgList(const string& ArgList) : cling::LookupHelper::NoDiagnostics); for (SmallVector<Expr*, 4>::const_iterator I = exprs.begin(), E = exprs.end(); I != E; ++I) { - cling::StoredValueRef val = EvaluateExpr(fInterp, *I); + cling::Value val; + EvaluateExpr(fInterp, *I, val); if (!val.isValid()) { // Bad expression, all done. Error("TClingCallFunc::EvaluateArgList", @@ -2715,70 +2180,47 @@ TClingCallFunc::Exec(void* address, TInterpreterValue* interpVal/*=0*/) exec(address, 0); return; } - cling::StoredValueRef valref; - exec_with_valref_return(address, &valref); - reinterpret_cast<cling::StoredValueRef&>(interpVal->Get()) = valref; - return; + cling::Value* val = reinterpret_cast<cling::Value*>(interpVal->GetValAddr()); + exec_with_valref_return(address, val); } -Long_t -TClingCallFunc::ExecInt(void* address) +template <typename T> +T TClingCallFunc::ExecT(void* address) { IFacePtr(); if (!fWrapper) { - Error("TClingCallFunc::ExecInt", + Error("TClingCallFunc::ExecT", "Called with no wrapper, not implemented!"); - return 0L; + return 0; } - cling::StoredValueRef ret; + cling::Value ret; exec_with_valref_return(address, &ret); if (!ret.isValid()) { // Sometimes we are called on a function returning void! - return 0L; + return 0; } const FunctionDecl* decl = fMethod->GetMethodDecl(); if (decl->getReturnType().getCanonicalType()->isRecordType()) ((TCling*)gCling)->RegisterTemporary(ret); - return static_cast<Long_t>(sv_to_long_long(ret)); + return sv_to<T>(ret); +} + +Long_t +TClingCallFunc::ExecInt(void* address) +{ + return ExecT<long>(address); } long long TClingCallFunc::ExecInt64(void* address) { - IFacePtr(); - if (!fWrapper) { - Error("TClingCallFunc::ExecInt64", - "Called with no wrapper, not implemented!"); - return 0LL; - } - cling::StoredValueRef ret; - exec_with_valref_return(address, &ret); - if (!ret.isValid()) { - // Sometimes we are called on a function returning void! - return 0LL; - } - const FunctionDecl* decl = fMethod->GetMethodDecl(); - if (decl->getReturnType().getCanonicalType()->isRecordType()) - ((TCling*)gCling)->RegisterTemporary(ret); - return sv_to_long_long(ret); + return ExecT<long long>(address); } double TClingCallFunc::ExecDouble(void* address) { - IFacePtr(); - if (!fWrapper) { - Error("TClingCallFunc::ExecDouble", - "Called with no wrapper, not implemented!"); - return 0.0; - } - cling::StoredValueRef ret; - exec_with_valref_return(address, &ret); - if (!ret.isValid()) { - // Sometimes we are called on a function returning void! - return 0.0; - } - return sv_to<double>(ret); + return ExecT<double>(address); } void @@ -2792,7 +2234,6 @@ TClingCallFunc::ExecWithArgsAndReturn(void* address, const vector<void*>& args return; } exec_with_args_and_return(address, args, ret); - return; } void @@ -2805,7 +2246,6 @@ TClingCallFunc::ExecWithReturn(void* address, void* ret/*= 0*/) return; } exec(address, ret); - return; } void* @@ -2949,44 +2389,32 @@ void TClingCallFunc::SetArg(long param) { ASTContext& C = fInterp->getCI()->getASTContext(); - GenericValue gv; - QualType QT = C.LongTy; - gv.IntVal = APInt(C.getTypeSize(QT), param); - fArgVals.push_back(cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT))); + fArgVals.push_back(cling::Value(C.LongTy, 0)); + fArgVals.back().getLL() = param; } void TClingCallFunc::SetArg(double param) { ASTContext& C = fInterp->getCI()->getASTContext(); - GenericValue gv; - QualType QT = C.DoubleTy; - gv.DoubleVal = param; - fArgVals.push_back(cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT))); + fArgVals.push_back(cling::Value(C.DoubleTy, 0)); + fArgVals.back().getDouble() = param; } void TClingCallFunc::SetArg(long long param) { ASTContext& C = fInterp->getCI()->getASTContext(); - GenericValue gv; - QualType QT = C.LongLongTy; - gv.IntVal = APInt(C.getTypeSize(QT), param); - fArgVals.push_back(cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT))); + fArgVals.push_back(cling::Value(C.LongLongTy, 0)); + fArgVals.back().getLL() = param; } void TClingCallFunc::SetArg(unsigned long long param) { ASTContext& C = fInterp->getCI()->getASTContext(); - GenericValue gv; - QualType QT = C.UnsignedLongLongTy; - gv.IntVal = APInt(C.getTypeSize(QT), param); - fArgVals.push_back(cling::StoredValueRef::bitwiseCopy(*fInterp, - cling::Value(gv, QT))); + fArgVals.push_back(cling::Value(C.UnsignedLongLongTy, 0)); + fArgVals.back().getLL() = param; } void diff --git a/core/meta/src/TClingCallFunc.h b/core/meta/src/TClingCallFunc.h index 75f71747fce..b947e52b8bf 100644 --- a/core/meta/src/TClingCallFunc.h +++ b/core/meta/src/TClingCallFunc.h @@ -32,8 +32,7 @@ #include "TClingClassInfo.h" #include "TInterpreter.h" -#include "llvm/ExecutionEngine/GenericValue.h" -#include "cling/Interpreter/StoredValueRef.h" +#include "cling/Interpreter/Value.h" #include <vector> @@ -45,7 +44,6 @@ class CXXMethodDecl; namespace cling { class Interpreter; -class Value; } class TClingClassInfo; @@ -68,7 +66,7 @@ private: /// Pointer to compiled wrapper, we do *not* own. tcling_callfunc_Wrapper_t fWrapper; /// Stored function arguments, we own. - mutable std::vector<cling::StoredValueRef> fArgVals; + mutable std::vector<cling::Value> fArgVals; /// If true, do not limit number of function arguments to declared number. bool fIgnoreExtraArgs; @@ -106,15 +104,28 @@ private: tcling_callfunc_dtor_Wrapper_t make_dtor_wrapper(const TClingClassInfo* info); + // Implemented in source file. + template <typename T> + void execWithLL(void* address, clang::QualType QT, + cling::Value* val) const; + // Implemented in source file. + template <typename T> + void execWithULL(void* address, clang::QualType QT, + cling::Value* val) const; void exec(void* address, void* ret) const; void exec_with_valref_return(void* address, - cling::StoredValueRef* ret) const; + cling::Value* ret) const; void exec_with_args_and_return(void* address, const std::vector<void*>& args, void* ret) const; void EvaluateArgList(const std::string& ArgList); + // Implemented in source file. + template <typename T> + T ExecT(void* address); + + public: ~TClingCallFunc() { @@ -153,7 +164,7 @@ public: void Init(); void Init(const clang::FunctionDecl *); void Init(TClingMethodInfo*); - void Invoke(cling::StoredValueRef* result = 0) const; + void Invoke(cling::Value* result = 0) const; void* InterfaceMethod(); bool IsValid() const; TInterpreter::CallFuncIFacePtr_t IFacePtr(); diff --git a/core/meta/src/TClingClassInfo.cxx b/core/meta/src/TClingClassInfo.cxx index 9361f65febf..b269ad33d79 100644 --- a/core/meta/src/TClingClassInfo.cxx +++ b/core/meta/src/TClingClassInfo.cxx @@ -35,7 +35,6 @@ #include "cling/Interpreter/Interpreter.h" #include "cling/Interpreter/LookupHelper.h" -#include "cling/Interpreter/StoredValueRef.h" #include "cling/Utils/AST.h" #include "clang/AST/ASTContext.h" diff --git a/core/meta/src/TClingValue.cxx b/core/meta/src/TClingValue.cxx index b4c57cd02e1..efa49b8df9c 100644 --- a/core/meta/src/TClingValue.cxx +++ b/core/meta/src/TClingValue.cxx @@ -13,59 +13,54 @@ // // // TClingValue // // // -// Bridge between cling::StoredValueRef and ROOT. // +// Bridge between cling::Value and ROOT. // // // //////////////////////////////////////////////////////////////////////////////// #include "TClingValue.h" -#include "cling/Interpreter/StoredValueRef.h" +#include "cling/Interpreter/Value.h" +#include <cassert> -static const cling::StoredValueRef& GetAsStoredValueRef(void* const& value) { - return reinterpret_cast<const cling::StoredValueRef&>(value); -} - -static cling::StoredValueRef& GetAsStoredValueRef(void*& value) { - return reinterpret_cast<cling::StoredValueRef&>(value); -} - -TClingValue::TClingValue() : fValue(0) { +TClingValue::TClingValue() { // We default initialize to invalid value so that we could keep a "sane" state. - new (&fValue) cling::StoredValueRef(); + assert(sizeof(fValue) >= sizeof(cling::Value) + && "sizeof(fValue) too small!"); + new (&fValue) cling::Value(); } -TClingValue::TClingValue(const TClingValue& Other) : TInterpreterValue(), fValue(0) { - using namespace cling; - new (&fValue) StoredValueRef(GetAsStoredValueRef(Other.fValue)); +TClingValue::TClingValue(const TClingValue& Other) { + assert(sizeof(fValue) >= sizeof(cling::Value) + && "sizeof(fValue) too small!"); + new (&fValue) cling::Value(Other.ToCV()); } TClingValue::~TClingValue() { - GetAsStoredValueRef(fValue).~StoredValueRef(); + ToCV().~Value(); } TClingValue& TClingValue::operator=(TClingValue &Other) { using namespace cling; - StoredValueRef& That = reinterpret_cast<StoredValueRef&>(Other.fValue); - GetAsStoredValueRef(fValue) = (GetAsStoredValueRef(fValue).operator=(That)); + ToCV() = Other.ToCV(); return *this; } Bool_t TClingValue::IsValid() const { - return GetAsStoredValueRef(fValue).isValid(); + return ToCV().isValid(); } Double_t TClingValue::GetAsDouble() const { - return GetAsStoredValueRef(fValue).get().getAs<double>(); + return ToCV().getDouble(); } Long_t TClingValue::GetAsLong() const { - return GetAsStoredValueRef(fValue).get().getAs<long>(); + return ToCV().getLL(); } - ULong_t TClingValue::GetAsUnsignedLong() const { - return GetAsStoredValueRef(fValue).get().getAs<unsigned long>(); +ULong_t TClingValue::GetAsUnsignedLong() const { + return ToCV().getULL(); } void* TClingValue::GetAsPointer() const { - return GetAsStoredValueRef(fValue).get().getAs<void*>(); + return ToCV().getPtr(); } diff --git a/core/meta/src/TClingValue.h b/core/meta/src/TClingValue.h index 454d8cb41c2..934ec3279ee 100644 --- a/core/meta/src/TClingValue.h +++ b/core/meta/src/TClingValue.h @@ -31,17 +31,30 @@ #include "TInterpreterValue.h" #endif +namespace cling { + class Value; +} + class TClingValue : public TInterpreterValue { private: - void* fValue; + struct HasTheSameSizeAsClingValue { + long double fBiggestElementOfUnion; + void* fType; + } fValue; + + cling::Value& ToCV() { + return reinterpret_cast<cling::Value&>(fValue); } + const cling::Value& ToCV() const { + return reinterpret_cast<const cling::Value&>(fValue); } + public: TClingValue(); TClingValue(const TClingValue& Other); TClingValue& operator=(TClingValue &Other); ~TClingValue(); - void* const& Get() const { return fValue; } - void*& Get() { return fValue; } + const void* GetValAddr() const { return &fValue; } + void* GetValAddr() { return &fValue; } Bool_t IsValid() const; Double_t GetAsDouble() const; diff --git a/interpreter/cling/Module.mk b/interpreter/cling/Module.mk index eb61d771be9..a04c9ffaf22 100644 --- a/interpreter/cling/Module.mk +++ b/interpreter/cling/Module.mk @@ -20,7 +20,7 @@ CLINGDEP := $(CLINGO:.o=.d) CLINGETC_CLING := DynamicExprInfo.h DynamicLookupRuntimeUniverse.h \ DynamicLookupLifetimeHandler.h Interpreter.h InvocationOptions.h \ - RuntimeUniverse.h StoredValueRef.h Value.h \ + RuntimeUniverse.h Value.h \ ValuePrinter.h ValuePrinterInfo.h RuntimeException.h CLINGETC_LLVM := llvm/ADT/IntrusiveRefCntPtr.h \ diff --git a/interpreter/cling/include/cling/Interpreter/DynamicLookupRuntimeUniverse.h b/interpreter/cling/include/cling/Interpreter/DynamicLookupRuntimeUniverse.h index e132ebdf5c2..f75db9538ec 100644 --- a/interpreter/cling/include/cling/Interpreter/DynamicLookupRuntimeUniverse.h +++ b/interpreter/cling/include/cling/Interpreter/DynamicLookupRuntimeUniverse.h @@ -16,7 +16,7 @@ #include "cling/Interpreter/Interpreter.h" #include "cling/Interpreter/DynamicExprInfo.h" #include "cling/Interpreter/DynamicLookupLifetimeHandler.h" -#include "cling/Interpreter/StoredValueRef.h" +#include "cling/Interpreter/Value.h" namespace cling { @@ -45,7 +45,7 @@ namespace runtime { /// evaluated at runtime. template<typename T> T EvaluateT(DynamicExprInfo* ExprInfo, clang::DeclContext* DC ) { - StoredValueRef result( + Value result( cling::runtime::gCling->Evaluate(ExprInfo->getExpr(), DC, ExprInfo->isValuePrinterRequested()) ); @@ -53,7 +53,7 @@ namespace runtime { // Check whether the expected return type and the actual return type are // compatible with Sema::CheckAssingmentConstraints or // ASTContext::typesAreCompatible. - return result.get().getAs<T>(); + return result.simplisticCastAs<T>(); return T(); } diff --git a/interpreter/cling/include/cling/Interpreter/RuntimeUniverse.h b/interpreter/cling/include/cling/Interpreter/RuntimeUniverse.h index ce1c586663f..01816b3550b 100644 --- a/interpreter/cling/include/cling/Interpreter/RuntimeUniverse.h +++ b/interpreter/cling/include/cling/Interpreter/RuntimeUniverse.h @@ -56,69 +56,69 @@ namespace cling { ///\brief Set the value of the GenericValue for the expression /// evaluated at the prompt. - ///\param [in] vpI - The cling::Interpreter for StoredValueRef. + ///\param [in] vpI - The cling::Interpreter for Value. ///\param [in] vpQT - The opaque ptr for the clang::QualType of value. ///\param [in] value - The float value of the assignment to be stored /// in GenericValue. - ///\param [out] vpSVR - The StoredValueRef that is created. + ///\param [out] vpSVR - The Value that is created. /// - void setValueNoAlloc(void* vpI, void* vpSVR, void* vpQT, float value); + void setValueNoAlloc(void* vpI, void* vpV, void* vpQT, float value); ///\brief Set the value of the GenericValue for the expression /// evaluated at the prompt. - ///\param [in] vpI - The cling::Interpreter for StoredValueRef. + ///\param [in] vpI - The cling::Interpreter for Value. ///\param [in] vpQT - The opaque ptr for the clang::QualType of value. ///\param [in] value - The double value of the assignment to be stored /// in GenericValue. - ///\param [out] vpSVR - The StoredValueRef that is created. + ///\param [out] vpSVR - The Value that is created. /// - void setValueNoAlloc(void* vpI, void* vpSVR, void* vpQT, double value); + void setValueNoAlloc(void* vpI, void* vpV, void* vpQT, double value); ///\brief Set the value of the GenericValue for the expression /// evaluated at the prompt. Extract through /// APFloat(ASTContext::getFloatTypeSemantics(QT), const APInt &) - ///\param [in] vpI - The cling::Interpreter for StoredValueRef. + ///\param [in] vpI - The cling::Interpreter for Value. ///\param [in] vpQT - The opaque ptr for the clang::QualType of value. ///\param [in] value - The value of the assignment to be stored /// in GenericValue. - ///\param [out] vpSVR - The StoredValueRef that is created. + ///\param [out] vpSVR - The Value that is created. /// - void setValueNoAlloc(void* vpI, void* vpSVR, void* vpQT, + void setValueNoAlloc(void* vpI, void* vpV, void* vpQT, long double value); ///\brief Set the value of the GenericValue for the expression /// evaluated at the prompt. /// We are using unsigned long long instead of uint64, because we don't /// want to #include the header. - ///\param [in] vpI - The cling::Interpreter for StoredValueRef. + ///\param [in] vpI - The cling::Interpreter for Value. ///\param [in] vpQT - The opaque ptr for the clang::QualType of value. ///\param [in] value - The uint64_t value of the assignment to be stored /// in GenericValue. - ///\param [out] vpSVR - The StoredValueRef that is created. + ///\param [out] vpSVR - The Value that is created. /// - void setValueNoAlloc(void* vpI, void* vpSVR, void* vpQT, + void setValueNoAlloc(void* vpI, void* vpV, void* vpQT, unsigned long long value); ///\brief Set the value of the GenericValue for the expression /// evaluated at the prompt. - ///\param [in] vpI - The cling::Interpreter for StoredValueRef. + ///\param [in] vpI - The cling::Interpreter for Value. ///\param [in] vpQT - The opaque ptr for the clang::QualType of value. ///\param [in] value - The void* value of the assignment to be stored /// in GenericValue. - ///\param [out] vpSVR - The StoredValueRef that is created. + ///\param [out] vpV - The Value that is created. /// - void setValueNoAlloc(void* vpI, void* vpSVR, void* vpQT, + void setValueNoAlloc(void* vpI, void* vpV, void* vpQT, const void* value); ///\brief Set the value of the Generic value and return the address /// for the allocated storage space. - ///\param [in] vpI - The cling::Interpreter for StoredValueRef. + ///\param [in] vpI - The cling::Interpreter for Value. ///\param [in] vpQT - The opaque ptr for the clang::QualType of value. - ///\param [out] vpSVR - The StoredValueRef that is created. + ///\param [out] vpV - The Value that is created. /// ///\returns the address where the value should be put. /// - void* setValueWithAlloc(void* vpI, void* vpSVR, void* vpQT); + void* setValueWithAlloc(void* vpI, void* vpV, void* vpQT); ///\brief Placement new doesn't work for arrays. It needs to be called on /// each element. For non-PODs we also need to call the *structors. This diff --git a/interpreter/cling/include/cling/Interpreter/Value.h b/interpreter/cling/include/cling/Interpreter/Value.h index 61b83c9f56c..0c514544e36 100644 --- a/interpreter/cling/include/cling/Interpreter/Value.h +++ b/interpreter/cling/include/cling/Interpreter/Value.h @@ -61,10 +61,6 @@ namespace cling { /// \brief Retrieve the underlying, canonical, desugared, unqualified type. EStorageType getStorageType() const; - /// \brief Whether this type needs managed heap, i.e. the storage provided - /// by Storage is insufficient. - bool needsManagedAllocation() const; - /// \brief Allocate storage as needed by the type. void ManagedAllocate(Interpreter* interp); @@ -79,7 +75,7 @@ namespace cling { public: /// \brief Default constructor, creates a value that IsInvalid(). - Value() {} + Value(): m_Type(0) {} /// \brief Copy a value. Value(const Value& other); /// \brief Construct a valid but ininitialized Value. After this call the @@ -93,6 +89,11 @@ namespace cling { clang::QualType getType() const; + /// \brief Whether this type needs managed heap, i.e. the storage provided + /// by the m_Storage member is insufficient, or a non-trivial destructor + /// must be called. + bool needsManagedAllocation() const; + /// \brief Determine whether the Value has been set. // /// Determine whether the Value has been set by checking @@ -100,14 +101,14 @@ namespace cling { bool isValid() const; /// \brief Determine whether the Value is set but void. - bool isVoid(const clang::ASTContext& ASTContext) const; + bool isVoid(const clang::ASTContext& Ctx) const; /// \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. - bool hasValue(const clang::ASTContext& ASTContext) const { - return isValid() && !isVoid(ASTContext); } + bool hasValue(const clang::ASTContext& Ctx) const { + return isValid() && !isVoid(Ctx); } /// \brief Get a reference to the value without type checking. /// T *must* correspond to type. Else use simplisticCastAs()! @@ -120,7 +121,7 @@ namespace cling { T getAs() const { return const_cast<Value*>(this)->getAs<T>(); } template <typename T> - T* getAs(T**) const { return (T*)getAs((void**)0); } + T*& getAs(T**) const { return (T*&)getAs((void**)0); } void*& getAs(void**) { return m_Storage.m_Ptr; } double& getAs(double*) { return m_Storage.m_Double; } long double& getAs(long double*) { return m_Storage.m_LongDouble; } @@ -128,7 +129,21 @@ namespace cling { long long& getAs(long long*) { return m_Storage.m_LL; } unsigned long long& getAs(unsigned long long*) { return m_Storage.m_ULL; } - /// \brief Get the value. + void*& getPtr() { return m_Storage.m_Ptr; } + double& getDouble() { return m_Storage.m_Double; } + long double& getLongDouble() { return m_Storage.m_LongDouble; } + float& getFloat() { return m_Storage.m_Float; } + long long& getLL() { return m_Storage.m_LL; } + unsigned long long& getULL() { return m_Storage.m_ULL; } + + void* getPtr() const { return m_Storage.m_Ptr; } + double getDouble() const { return m_Storage.m_Double; } + long double getLongDouble() const { return m_Storage.m_LongDouble; } + float getFloat() const { return m_Storage.m_Float; } + long long getLL() const { return m_Storage.m_LL; } + unsigned long long getULL() const { return m_Storage.m_ULL; } + + /// \brief Get the value with cast. // /// Get the value cast to T. This is similar to reinterpret_cast<T>(value), /// casting the value of builtins (except void), enums and pointers. diff --git a/interpreter/cling/lib/Interpreter/CMakeLists.txt b/interpreter/cling/lib/Interpreter/CMakeLists.txt index 471e40953ea..ce547b7082d 100644 --- a/interpreter/cling/lib/Interpreter/CMakeLists.txt +++ b/interpreter/cling/lib/Interpreter/CMakeLists.txt @@ -37,7 +37,6 @@ add_cling_library(clingInterpreter RequiredSymbols.cpp ValueExtractionSynthesizer.cpp RuntimeException.cpp - StoredValueRef.cpp Transaction.cpp TransactionTransformer.cpp TransactionUnloader.cpp diff --git a/interpreter/cling/lib/Interpreter/Interpreter.cpp b/interpreter/cling/lib/Interpreter/Interpreter.cpp index e439d1831d6..892287137ab 100644 --- a/interpreter/cling/lib/Interpreter/Interpreter.cpp +++ b/interpreter/cling/lib/Interpreter/Interpreter.cpp @@ -957,10 +957,6 @@ namespace cling { m_Executor->installLazyFunctionCreator(fp); } - void Interpreter::suppressLazyFunctionCreatorDiags(bool suppressed/*=true*/) { - m_Executor->suppressLazyFunctionCreatorDiags(suppressed); - } - Value Interpreter::Evaluate(const char* expr, DeclContext* DC, bool ValuePrinterReq) { Sema& TheSema = getCI()->getSema(); diff --git a/interpreter/cling/lib/Interpreter/Value.cpp b/interpreter/cling/lib/Interpreter/Value.cpp index dd777d90a86..22b0f2d1df9 100644 --- a/interpreter/cling/lib/Interpreter/Value.cpp +++ b/interpreter/cling/lib/Interpreter/Value.cpp @@ -74,7 +74,8 @@ namespace { namespace cling { -Value::Value(const Value& other) : m_Type(other.m_Type) { +Value::Value(const Value& other): + m_Type(other.m_Type), m_Storage(other.m_Storage) { if (needsManagedAllocation()) AllocatedValue::getFromPayload(m_Storage.m_Ptr)->Retain(); } @@ -86,7 +87,13 @@ Value::Value(clang::QualType clangTy, Interpreter* Interp): } Value& Value::operator =(const Value& other) { + // Release old value. + if (needsManagedAllocation()) + AllocatedValue::getFromPayload(m_Storage.m_Ptr)->Release(); + + // Retain new one. m_Type = other.m_Type; + m_Storage = other.m_Storage; if (needsManagedAllocation()) AllocatedValue::getFromPayload(m_Storage.m_Ptr)->Retain(); return *this; @@ -103,8 +110,8 @@ clang::QualType Value::getType() const { bool Value::isValid() const { return !getType().isNull(); } -bool Value::isVoid(const clang::ASTContext& ASTContext) const { - return isValid() && ASTContext.hasSameType(getType(), ASTContext.VoidTy); +bool Value::isVoid(const clang::ASTContext& Ctx) const { + return isValid() && Ctx.hasSameType(getType(), Ctx.VoidTy); } Value::EStorageType Value::getStorageType() const { @@ -130,14 +137,16 @@ Value::EStorageType Value::getStorageType() const { } bool Value::needsManagedAllocation() const { - return !getType()->getUnqualifiedDesugaredType()->isBuiltinType(); + if (!isValid()) return false; + const clang::Type* UnqDes = getType()->getUnqualifiedDesugaredType(); + return UnqDes->isRecordType() || UnqDes->isArrayType() + || UnqDes->isMemberPointerType(); } void Value::ManagedAllocate(Interpreter* interp) { assert(interp && "This type requires the interpreter for value allocation"); void* dtorFunc = 0; - if (const clang::RecordType* RTy - = clang::dyn_cast<clang::RecordType>(getType())) + if (const clang::RecordType* RTy = getType()->getAs<clang::RecordType>()) dtorFunc = GetDtorWrapperPtr(RTy->getDecl(), *interp); const clang::ASTContext& ctx = interp->getCI()->getASTContext(); diff --git a/interpreter/cling/lib/Interpreter/ValueExtractionSynthesizer.h b/interpreter/cling/lib/Interpreter/ValueExtractionSynthesizer.h index 9caed0218ed..330ae582b2e 100644 --- a/interpreter/cling/lib/Interpreter/ValueExtractionSynthesizer.h +++ b/interpreter/cling/lib/Interpreter/ValueExtractionSynthesizer.h @@ -73,7 +73,7 @@ public: /// call to cling::runtime::internal::copyArray(...) /// /// We need to synthesize later: - /// Wrapper has signature: void w(cling::StoredValueRef SVR) + /// Wrapper has signature: void w(cling::Value V) /// case 1): /// setValueNoAlloc(gCling, &SVR, lastExprTy, lastExpr()) /// case 2): diff --git a/interpreter/cling/test/Interfaces/evaluate.C b/interpreter/cling/test/Interfaces/evaluate.C index 99e2653828e..db330d30161 100644 --- a/interpreter/cling/test/Interfaces/evaluate.C +++ b/interpreter/cling/test/Interfaces/evaluate.C @@ -9,44 +9,44 @@ // RUN: cat %s | %cling -Xclang -verify | FileCheck %s #include "cling/Interpreter/Interpreter.h" -#include "cling/Interpreter/StoredValueRef.h" +#include "cling/Interpreter/Value.h" -cling::StoredValueRef V; -V // CHECK: (cling::StoredValueRef) <<<invalid>>> @0x{{.*}} +cling::Value V; +V // CHECK: (cling::Value) <<<invalid>>> @0x{{.*}} gCling->evaluate("return 1;", V); -V // CHECK: (cling::StoredValueRef) boxes [(int) 1] +V // CHECK: (cling::Value) boxes [(int) 1] -// Returns must put the result in the StoredValueRef. +// Returns must put the result in the Value. bool cond = true; gCling->evaluate("if (cond) return \"true\"; else return 0;", V); -V // CHECK: (cling::StoredValueRef) boxes [(const char [5]) "true"] +V // CHECK: (cling::Value) boxes [(const char [5]) "true"] gCling->evaluate("cond = false; if (cond) return \"true\"; else return 0;", V); -V // CHECK: (cling::StoredValueRef) boxes [(int) 0] +V // CHECK: (cling::Value) boxes [(int) 0] gCling->evaluate("auto a = 12.3; a;", V); -V // CHECK: (cling::StoredValueRef) boxes [(double) 1.230000e+01] +V // CHECK: (cling::Value) boxes [(double) 1.230000e+01] long LongV = 17; gCling->evaluate("LongV;", V); -V // CHECK: (cling::StoredValueRef) boxes [(long) 17] +V // CHECK: (cling::Value) boxes [(long) 17] int* IntP = (int*)0x12; gCling->evaluate("IntP;", V); -V // CHECK: (cling::StoredValueRef) boxes [(int *) 0x12] +V // CHECK: (cling::Value) boxes [(int *) 0x12] -cling::StoredValueRef Result; +cling::Value Result; gCling->evaluate("V", Result); -// Here we check what happens for record type like cling::StoredValueRef; they are returned by reference. -Result // CHECK: (cling::StoredValueRef) boxes [(cling::StoredValueRef &) boxes [(int *) 0x12]] -V // CHECK: (cling::StoredValueRef) boxes [(int *) 0x12] +// Here we check what happens for record type like cling::Value; they are returned by reference. +Result // CHECK: (cling::Value) boxes [(cling::Value &) boxes [(int *) 0x12]] +V // CHECK: (cling::Value) boxes [(int *) 0x12] // Savannah #96277 gCling->evaluate("gCling->declare(\"double sin(double);\"); double one = sin(3.141/2);", V); -V // CHECK: (cling::StoredValueRef) boxes [(double) 1.000000e+00] +V // CHECK: (cling::Value) boxes [(double) 1.000000e+00] gCling->process("double one = sin(3.141/2);", &V); -V // CHECK: (cling::StoredValueRef) boxes [(double) 1.000000e+00] +V // CHECK: (cling::Value) boxes [(double) 1.000000e+00] one // CHECK: (double) 1.000 int one; // expected-error {{redefinition of 'one' with a different type: 'int' vs 'double'}} expected-note {{previous definition is here}} @@ -59,7 +59,7 @@ gCling->evaluate("f", V); V.isValid() //CHECK: {{\([_]B|b}}ool) true // end PR#98434 -// Check lifetime of objects in StoredValue +// Check lifetime of objects in Value .rawInput 1 struct WithDtor { static int fgCount; @@ -73,25 +73,24 @@ WithDtor getWithDtor() { return WithDtor(); } std::vector<WithDtor> getWithDtorVec() { std::vector<WithDtor> ret; ret.resize(7); return ret; } .rawInput 0 -cling::StoredValueRef* VOnHeap = new cling::StoredValueRef(); +cling::Value* VOnHeap = new cling::Value(); gCling->evaluate("getWithDtor()", *VOnHeap); -*VOnHeap //CHECK: (cling::StoredValueRef) boxes [(WithDtor) @0x{{.*}}] +*VOnHeap //CHECK: (cling::Value) boxes [(WithDtor) @0x{{.*}}] WithDtor::fgCount //CHECK: (int) 1 delete VOnHeap; WithDtor::fgCount //CHECK: (int) 0 // Check destructor call for templates -VOnHeap = new cling::StoredValueRef(); +VOnHeap = new cling::Value(); gCling->evaluate("getWithDtorVec()", *VOnHeap); -*VOnHeap //CHECK: (cling::StoredValueRef) boxes [(std::vector<WithDtor>) @0x{{.*}}] +*VOnHeap //CHECK: (cling::Value) boxes [(std::vector<WithDtor>) @0x{{.*}}] WithDtor::fgCount //CHECK: (int) 7 delete VOnHeap; WithDtor::fgCount //CHECK: (int) 0 // long doubles (tricky for the JIT). gCling->evaluate("17.42L", V); -V // CHECK: (cling::StoredValueRef) boxes [(long double) 17.4200000{{[0-9]*}}L] - +V // CHECK: (cling::Value) boxes [(long double) 17.42{{[0-9]*}}L] // Test references, temporaries .rawInput 1 @@ -121,19 +120,19 @@ namespace cling { return p->asStr(); } } -void dumpTracerSVR(cling::StoredValueRef& svr) { - ((Tracer*)svr.get().getAs<void*>())->dump("dump"); +void dumpTracerSVR(cling::Value& svr) { + ((Tracer*)svr.getAs<void*>())->dump("dump"); } .rawInput 0 // Creating the static in constructs one object. It gets returned by // reference; it should only be destructed by ~JIT, definitely not by -// ~StoredValueRef (which should only store a Tracer&) +// ~Value (which should only store a Tracer&) gCling->evaluate("RefMaker()", V); // This is the local static: // CHECK: REF{1}:ctor printf("RefMaker() done\n"); // CHECK-NEXT: RefMaker() done -V // CHECK-NEXT: (cling::StoredValueRef) boxes [(Tracer &) @{{.*}}] +V // CHECK-NEXT: (cling::Value) boxes [(Tracer &) @{{.*}}] dumpTracerSVR(V); // CHECK-NEXT: REF{1}:dump // Setting a new value should destruct the old - BUT it's a ref thus no @@ -146,7 +145,7 @@ gCling->evaluate("ObjMaker()", V); // The temporary gets created: // CHECK-NEXT:MADE{2}:ctor printf("ObjMaker() done\n"); //CHECK-NEXT: ObjMaker() done -V // CHECK-NEXT: (cling::StoredValueRef) boxes [(Tracer) @{{.*}}] +V // CHECK-NEXT: (cling::Value) boxes [(Tracer) @{{.*}}] dumpTracerSVR(V); // CHECK-NEXT: MADE{2}:dump // Creating a variable: @@ -160,17 +159,17 @@ Tracer RT("VAR"); // CHECK-NEXT: VAR{3}:ctor // CHECK-NEXT: MADE{2}:dtor gCling->evaluate("RT", V); // should not call any ctor! printf("RT done\n"); //CHECK-NEXT: RT done -V // CHECK-NEXT: (cling::StoredValueRef) boxes [(Tracer &) @{{.*}}] +V // CHECK-NEXT: (cling::Value) boxes [(Tracer &) @{{.*}}] dumpTracerSVR(V); // CHECK-NEXT: VAR{2}:dump // The following creates a copy, explicitly. This temporary object is then put -// into the StoredValueRef. +// into the Value. // gCling->evaluate("(Tracer)RT", V); // Copies RT: //CHECK-NEXT: VAR+{3}:copy printf("(Tracer)RT done\n"); //CHECK-NEXT: RT done -V // CHECK-NEXT: (cling::StoredValueRef) boxes [(Tracer) @{{.*}}] +V // CHECK-NEXT: (cling::Value) boxes [(Tracer) @{{.*}}] dumpTracerSVR(V); // CHECK-NEXT: VAR+{3}:dump // Destruct the variables with static storage: diff --git a/interpreter/cling/test/Prompt/Regression.C b/interpreter/cling/test/Prompt/Regression.C index 93419872bc5..c608a259e64 100644 --- a/interpreter/cling/test/Prompt/Regression.C +++ b/interpreter/cling/test/Prompt/Regression.C @@ -13,10 +13,10 @@ // PR #96277 #include "cling/Interpreter/Interpreter.h" -#include "cling/Interpreter/StoredValueRef.h" +#include "cling/Interpreter/Value.h" #include <stdio.h> gCling->declare("int print() { printf(\"print is run.\\n\"); return 1; }"); -cling::StoredValueRef V; +cling::Value V; gCling->process("int a = print();",&V); //CHECK: print is run. gCling->process("a", &V); @@ -28,7 +28,7 @@ gCling->process("a;", &V); gCling->process("\"Root\"", &V); // CHECK: (const char [5]) "Root" V -// CHECK: (cling::StoredValueRef) boxes [(const char *) "Root"] +// CHECK: (cling::Value) boxes [(const char *) "Root"] // End PR #98146 typedef enum {k1,k2} enumName; enumName var -- GitLab