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