Simplify; adapt to new Value.
This commit is contained in:
parent
93970e8c35
commit
d00d9e8d54
@ -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 \
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -37,7 +37,6 @@ add_cling_library(clingInterpreter
|
||||
RequiredSymbols.cpp
|
||||
ValueExtractionSynthesizer.cpp
|
||||
RuntimeException.cpp
|
||||
StoredValueRef.cpp
|
||||
Transaction.cpp
|
||||
TransactionTransformer.cpp
|
||||
TransactionUnloader.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();
|
||||
|
@ -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();
|
||||
|
@ -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):
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user