From adef192de9ee2b931cbee11624a0eaa719f899f7 Mon Sep 17 00:00:00 2001
From: Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
Date: Mon, 15 Oct 2012 13:42:09 +0000
Subject: [PATCH] Prepare cling for fixing bug #98146. In principle the bug
 could be fixed in 10 seconds, but I don't like where EvaluateInternal is
 going. At first place it shouldn't do any smart guessing what the
 transformers would do. Second it shouldn't try to attach expression
 evaluation (storing the result in cling::Value) while preparing for value
 printing.

To sum up:
* Simplify the old craft in EvaluateInternal
  - Move the value printing logic into the value printer transformer.
  - Move the expression evaluation login (mainly coming through the
Interpreter::evaluate interface) into separate transformer.
* Attach the new transformer to the list of transformers (the size of it was
increased as well.)
* Add new compilation option switch that the new transformer will react on.
* Turn on the switch where necessary.
* Simplify value printer logic. Now everything is at one place, which makes it
simpler and easier to debug.
* Make IncrementalParser::Parse to take compilation options' reference instead of
constructing it's own.
* As consequence of the new implementation - two bugs in the testsuite were
uncovered. Propose a fix for them.
* Improve documentation.
* TODO: There is some code duplication, which will be factored out soon.


git-svn-id: http://root.cern.ch/svn/root/trunk@46549 27541ba8-7e3a-0410-8455-c3a389f83636
---
 .../cling/Interpreter/CompilationOptions.h    |  5 +
 .../lib/Interpreter/IncrementalParser.cpp     |  7 +-
 .../cling/lib/Interpreter/IncrementalParser.h | 11 ++-
 .../cling/lib/Interpreter/Interpreter.cpp     | 71 ++++----------
 .../lib/Interpreter/ReturnSynthesizer.cpp     | 80 ++++++++++++++++
 .../cling/lib/Interpreter/ReturnSynthesizer.h | 47 +++++++++
 .../Interpreter/ValuePrinterSynthesizer.cpp   | 95 +++++++++++++------
 .../lib/Interpreter/ValuePrinterSynthesizer.h | 11 ++-
 interpreter/cling/test/Interfaces/evaluate.C  |  7 +-
 interpreter/cling/test/Prompt/Regression.C    |  2 +-
 10 files changed, 247 insertions(+), 89 deletions(-)
 create mode 100644 interpreter/cling/lib/Interpreter/ReturnSynthesizer.cpp
 create mode 100644 interpreter/cling/lib/Interpreter/ReturnSynthesizer.h

diff --git a/interpreter/cling/include/cling/Interpreter/CompilationOptions.h b/interpreter/cling/include/cling/Interpreter/CompilationOptions.h
index 76a111b215c..ecbcfbdc7ec 100644
--- a/interpreter/cling/include/cling/Interpreter/CompilationOptions.h
+++ b/interpreter/cling/include/cling/Interpreter/CompilationOptions.h
@@ -26,6 +26,10 @@ namespace cling {
     unsigned ValuePrinting : 2;
     enum ValuePrinting { VPDisabled, VPEnabled, VPAuto };
 
+    ///\brief Whether or not to return result from an execution.
+    ///
+    unsigned ResultEvaluation: 1;
+
     ///\brief Whether or not to extend the static scope with new information
     /// about the names available only at runtime
     ///
@@ -43,6 +47,7 @@ namespace cling {
     CompilationOptions() {
       DeclarationExtraction = 1;
       ValuePrinting = VPAuto;
+      ResultEvaluation = 0;
       DynamicScoping = 0;
       Debug = 0;
       CodeGeneration = 1;
diff --git a/interpreter/cling/lib/Interpreter/IncrementalParser.cpp b/interpreter/cling/lib/Interpreter/IncrementalParser.cpp
index 325dfde50b1..7a7a2434a0e 100644
--- a/interpreter/cling/lib/Interpreter/IncrementalParser.cpp
+++ b/interpreter/cling/lib/Interpreter/IncrementalParser.cpp
@@ -10,6 +10,7 @@
 #include "DeclCollector.h"
 #include "DeclExtractor.h"
 #include "DynamicLookup.h"
+#include "ReturnSynthesizer.h"
 #include "ValuePrinterSynthesizer.h"
 #include "cling/Interpreter/CIFactory.h"
 #include "cling/Interpreter/Interpreter.h"
@@ -69,6 +70,7 @@ namespace cling {
 
     m_TTransformers.push_back(new DeclExtractor(&getCI()->getSema()));
     m_TTransformers.push_back(new ValuePrinterSynthesizer(&CI->getSema(), 0));
+    m_TTransformers.push_back(new ReturnSynthesizer(&CI->getSema()));
     m_TTransformers.push_back(new ASTDumper());
 
     m_Parser.reset(new Parser(CI->getPreprocessor(), CI->getSema(),
@@ -247,8 +249,9 @@ namespace cling {
     return Result;
   }
 
-  Transaction* IncrementalParser::Parse(llvm::StringRef input) {
-    beginTransaction(CompilationOptions());
+  Transaction* IncrementalParser::Parse(llvm::StringRef input,
+                                        const CompilationOptions& Opts) {
+    beginTransaction(Opts);
     ParseInternal(input);
     endTransaction();
 
diff --git a/interpreter/cling/lib/Interpreter/IncrementalParser.h b/interpreter/cling/lib/Interpreter/IncrementalParser.h
index 90cfa68e7ef..13880fb54ea 100644
--- a/interpreter/cling/lib/Interpreter/IncrementalParser.h
+++ b/interpreter/cling/lib/Interpreter/IncrementalParser.h
@@ -81,7 +81,7 @@ namespace cling {
 
     ///\brief Contains the transaction transformers.
     ///
-    llvm::SmallVector<TransactionTransformer*, 4> m_TTransformers;
+    llvm::SmallVector<TransactionTransformer*, 6> m_TTransformers;
 
   public:
     enum EParseResult {
@@ -140,6 +140,10 @@ namespace cling {
 
     ///\brief Compiles the given input with the given compilation options.
     ///
+    ///\param[in] input - The code to compile.
+    ///\param[in] Opts - The compilation options to use.
+    ///\returns whether the operation was successful.
+    ///
     EParseResult Compile(llvm::StringRef input, const CompilationOptions& Opts);
 
     ///\brief Parses the given input without calling the custom consumers and 
@@ -149,9 +153,10 @@ namespace cling {
     /// different executable code.
     ///
     ///\param[in] input - The code to parse.
-    ///\returns The transaction coresponding to the input.
+    ///\param[in] Opts - The compilation options to use.
+    ///\returns The transaction corresponding to the input.
     ///
-    Transaction* Parse(llvm::StringRef input);
+    Transaction* Parse(llvm::StringRef input, const CompilationOptions& Opts);
 
     void unloadTransaction(Transaction* T);
 
diff --git a/interpreter/cling/lib/Interpreter/Interpreter.cpp b/interpreter/cling/lib/Interpreter/Interpreter.cpp
index 73ffe1f12be..4bfd8bbca0a 100644
--- a/interpreter/cling/lib/Interpreter/Interpreter.cpp
+++ b/interpreter/cling/lib/Interpreter/Interpreter.cpp
@@ -376,6 +376,7 @@ namespace cling {
     CompilationOptions CO;
     CO.DeclarationExtraction = 1;
     CO.ValuePrinting = CompilationOptions::VPAuto;
+    CO.ResultEvaluation = (bool)V;
     CO.DynamicScoping = isDynamicLookupEnabled();
     CO.Debug = isPrintingAST();
 
@@ -400,6 +401,7 @@ namespace cling {
     CO.CodeGeneration = 0;
     CO.DeclarationExtraction = 0;
     CO.ValuePrinting = 0;
+    CO.ResultEvaluation = 0;
     CO.DynamicScoping = isDynamicLookupEnabled();
     CO.Debug = isPrintingAST();
 
@@ -411,6 +413,7 @@ namespace cling {
     CompilationOptions CO;
     CO.DeclarationExtraction = 0;
     CO.ValuePrinting = 0;
+    CO.ResultEvaluation = 0;
     CO.DynamicScoping = isDynamicLookupEnabled();
     CO.Debug = isPrintingAST();
 
@@ -426,6 +429,7 @@ namespace cling {
     CompilationOptions CO;
     CO.DeclarationExtraction = 0;
     CO.ValuePrinting = 0;
+    CO.ResultEvaluation = (bool)V;
 
     return EvaluateInternal(input, CO, V);
   }
@@ -435,6 +439,7 @@ namespace cling {
     CompilationOptions CO;
     CO.DeclarationExtraction = 0;
     CO.ValuePrinting = CompilationOptions::VPEnabled;
+    CO.ResultEvaluation = 0;
 
     return EvaluateInternal(input, CO, V);
   }
@@ -512,8 +517,6 @@ namespace cling {
                                 const CompilationOptions& CO,
                                 StoredValueRef* V /* = 0 */) {
 
-    Sema& TheSema = getCI()->getSema();
-
     DiagnosticsEngine& Diag = getCI()->getDiagnostics();
     // Disable warnings which doesn't make sense when using the prompt
     // This gets reset with the clang::Diagnostics().Reset()
@@ -531,7 +534,7 @@ namespace cling {
     QualType RetTy = getCI()->getASTContext().VoidTy;
 
     if (V) {
-      const Transaction* CurT = m_IncrParser->Parse(Wrapper);
+      const Transaction* CurT = m_IncrParser->Parse(Wrapper, CO);
       assert(CurT->size() && "No decls created by Parse!");
 
       // Find the wrapper function declaration.
@@ -540,67 +543,30 @@ namespace cling {
       //       instantiation happened.  Our wrapper function should be the
       //       last decl in the set.
       //
-      FunctionDecl* TopLevelFD 
+      FunctionDecl* FD 
         = dyn_cast<FunctionDecl>(CurT->getLastDecl().getSingleDecl());
-      assert(TopLevelFD && "No Decls Parsed?");
-      DeclContext* CurContext = TheSema.CurContext;
-      TheSema.CurContext = TopLevelFD;
-      ASTContext& Context(getCI()->getASTContext());
-      // We have to be able to mark the expression for printout. There are three
-      // scenarios:
-      // 0: Expression printing disabled - don't do anything just disable the
-      //    consumer
-      //    is our marker, even if there wasn't missing ';'.
-      // 1: Expression printing enabled - make sure we don't have NullStmt,
-      //    which is used as a marker to suppress the print out.
-      // 2: Expression printing auto - do nothing - rely on the omitted ';' to
-      //    not produce the suppress marker.
-      if (CompoundStmt* CS = dyn_cast<CompoundStmt>(TopLevelFD->getBody())) {
+      assert(FD && "No Decls Parsed?");
+      if (CompoundStmt* CS = dyn_cast<CompoundStmt>(FD->getBody())) {
         // Collect all Stmts, contained in the CompoundStmt
         llvm::SmallVector<Stmt *, 4> Stmts;
         for (CompoundStmt::body_iterator iStmt = CS->body_begin(),
                eStmt = CS->body_end(); iStmt != eStmt; ++iStmt)
           Stmts.push_back(*iStmt);
-
-        size_t indexOfLastExpr = Stmts.size();
+          
+        int indexOfLastExpr = Stmts.size();
         while(indexOfLastExpr--) {
           // find the trailing expression statement (skip e.g. null statements)
-          if (Expr* E = dyn_cast_or_null<Expr>(Stmts[indexOfLastExpr])) {
-            RetTy = E->getType();
-            if (!RetTy->isVoidType()) {
-              // Change the void function's return type
-              FunctionProtoType::ExtProtoInfo EPI;
-              QualType FuncTy = Context.getFunctionType(RetTy,/* ArgArray = */0,
-                                                        /* NumArgs = */0, EPI);
-              TopLevelFD->setType(FuncTy);
-              // Strip the parenthesis if any
-              if (ParenExpr* PE = dyn_cast<ParenExpr>(E))
-                E = PE->getSubExpr();
-
-              // Change it with return stmt
-              Stmts[indexOfLastExpr]
-                = TheSema.ActOnReturnStmt(SourceLocation(), E).take();
-            }
+          if (isa<Expr>(Stmts[indexOfLastExpr])) {
             // even if void: we found an expression
             break;
           }
         }
-
-        // case 1:
-        if (CO.ValuePrinting == CompilationOptions::VPEnabled)
-          if (indexOfLastExpr < Stmts.size() - 1 &&
-              isa<NullStmt>(Stmts[indexOfLastExpr + 1]))
-            Stmts.erase(Stmts.begin() + indexOfLastExpr);
-        // Stmts.insert(Stmts.begin() + indexOfLastExpr + 1,
-        //              TheSema.ActOnNullStmt(SourceLocation()).take());
-
-        // Update the CompoundStmt body
-        CS->setStmts(TheSema.getASTContext(), Stmts.data(), Stmts.size());
-
+        if (indexOfLastExpr >= 0) {
+          Expr* lastExpr = dyn_cast<Expr>(Stmts[indexOfLastExpr]);
+          assert(lastExpr && "Last expr not found.");
+          RetTy = lastExpr->getType();
+        }
       }
-
-      TheSema.CurContext = CurContext;
-
       m_IncrParser->commitCurrentTransaction();
     }
     else
@@ -611,7 +577,8 @@ namespace cling {
        if (RunFunction(WrapperName, RetTy)) {
         return Interpreter::kSuccess;
       }
-    } else if (RunFunction(WrapperName, RetTy, V)) {
+    } else if (RunFunction(WrapperName, RetTy, V)) { // Why we have to pass-in
+      // the type again?
       return Interpreter::kSuccess;
     } else {
        *V = StoredValueRef::invalidValue();
diff --git a/interpreter/cling/lib/Interpreter/ReturnSynthesizer.cpp b/interpreter/cling/lib/Interpreter/ReturnSynthesizer.cpp
new file mode 100644
index 00000000000..ef369d03c65
--- /dev/null
+++ b/interpreter/cling/lib/Interpreter/ReturnSynthesizer.cpp
@@ -0,0 +1,80 @@
+//------------------------------------------------------------------------------
+// CLING - the C++ LLVM-based InterpreterG :)
+// version: $Id$
+// author:  Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
+//------------------------------------------------------------------------------
+
+#include "ReturnSynthesizer.h"
+
+#include "cling/Interpreter/Transaction.h"
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclGroup.h"
+#include "clang/Sema/Sema.h"
+
+using namespace clang;
+
+namespace cling {
+  ReturnSynthesizer::ReturnSynthesizer(clang::Sema* S)
+    : TransactionTransformer(S), m_Context(&S->getASTContext()) {
+  }
+
+  // pin the vtable here.
+  ReturnSynthesizer::~ReturnSynthesizer() 
+  { }
+
+  void ReturnSynthesizer::Transform() {
+    if (!getTransaction()->getCompilationOpts().ResultEvaluation)
+      return;
+
+    for (Transaction::const_iterator iDGR = getTransaction()->decls_begin(), 
+           eDGR = getTransaction()->decls_end(); iDGR != eDGR; ++iDGR)
+      for (DeclGroupRef::const_iterator I = (*iDGR).begin(), E = (*iDGR).end();
+           I != E; ++I)
+        if (FunctionDecl* FD = dyn_cast<FunctionDecl>(*I)) {
+          if (FD->getNameAsString().find("__cling_Un1Qu3"))
+            return;
+          if (CompoundStmt* CS = dyn_cast<CompoundStmt>(FD->getBody())) {
+            // Collect all Stmts, contained in the CompoundStmt
+            llvm::SmallVector<Stmt *, 4> Stmts;
+            for (CompoundStmt::body_iterator iStmt = CS->body_begin(),
+                   eStmt = CS->body_end(); iStmt != eStmt; ++iStmt)
+              Stmts.push_back(*iStmt);
+
+            int indexOfLastExpr = Stmts.size();
+            while(indexOfLastExpr--) {
+              // find the trailing expression statement (skip e.g. null statements)
+              if (isa<Expr>(Stmts[indexOfLastExpr])) {
+                // even if void: we found an expression
+                break;
+              }
+            }
+            
+            // If no expressions found quit early.
+            if (indexOfLastExpr < 0)
+              return; 
+            // We can't PushDeclContext, because we don't have scope.
+            Sema::ContextRAII pushedDC(*m_Sema, FD);
+            Expr* lastExpr = cast<Expr>(Stmts[indexOfLastExpr]); // It is an expr
+            if (lastExpr) {
+              QualType RetTy = lastExpr->getType();
+              if (!RetTy->isVoidType()) {
+                // Change the void function's return type
+                FunctionProtoType::ExtProtoInfo EPI;
+                QualType FnTy = m_Context->getFunctionType(RetTy,
+                                                           /* ArgArray = */0,
+                                                           /* NumArgs = */0, 
+                                                           EPI);
+                FD->setType(FnTy);
+                
+                // Change it with return stmt
+                Stmts[indexOfLastExpr]
+                  = m_Sema->ActOnReturnStmt(lastExpr->getExprLoc(), 
+                                            lastExpr).take();
+              }
+              CS->setStmts(*m_Context, Stmts.data(), Stmts.size());
+            }
+          }
+        }
+  }
+} // end namespace cling
diff --git a/interpreter/cling/lib/Interpreter/ReturnSynthesizer.h b/interpreter/cling/lib/Interpreter/ReturnSynthesizer.h
new file mode 100644
index 00000000000..be13d54f32f
--- /dev/null
+++ b/interpreter/cling/lib/Interpreter/ReturnSynthesizer.h
@@ -0,0 +1,47 @@
+//------------------------------------------------------------------------------
+// CLING - the C++ LLVM-based InterpreterG :)
+// version: $Id$
+// author:  Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
+//------------------------------------------------------------------------------
+
+#ifndef CLING_RETURN_SYNTHESIZER_H
+#define CLING_RETURN_SYNTHESIZER_H
+
+#include "TransactionTransformer.h"
+
+namespace clang {
+  class ASTContext;
+  class CompoundStmt;
+  class DeclGroupRef;
+  class Expr;
+  class Sema;
+}
+
+namespace llvm {
+  class raw_ostream;
+}
+
+namespace cling {
+
+  class ReturnSynthesizer : public TransactionTransformer {
+
+  private:
+    ///\brief Needed for the AST transformations, owned by Sema.
+    ///
+    clang::ASTContext* m_Context;
+
+public:
+    ///\ brief Constructs the return synthesizer.
+    ///
+    ///\param[in] S - The semantic analysis object.
+    ///
+    ReturnSynthesizer(clang::Sema* S);
+    
+    virtual ~ReturnSynthesizer();
+
+    virtual void Transform();
+  };
+
+} // namespace cling
+
+#endif // CLING_RETURN_SYNTHESIZER_H
diff --git a/interpreter/cling/lib/Interpreter/ValuePrinterSynthesizer.cpp b/interpreter/cling/lib/Interpreter/ValuePrinterSynthesizer.cpp
index 7b5451ae7a2..029d7851240 100644
--- a/interpreter/cling/lib/Interpreter/ValuePrinterSynthesizer.cpp
+++ b/interpreter/cling/lib/Interpreter/ValuePrinterSynthesizer.cpp
@@ -42,13 +42,14 @@ namespace cling {
   { }
 
   void ValuePrinterSynthesizer::Transform() {
-    if (!getTransaction()->getCompilationOpts().ValuePrinting)
+    if (getTransaction()->getCompilationOpts().ValuePrinting 
+        == CompilationOptions::VPDisabled)
       return;
 
     for (Transaction::const_iterator I = getTransaction()->decls_begin(), 
            E = getTransaction()->decls_end(); I != E; ++I)
       if(!tryAttachVP(*I))
-        return setTransaction(0); // On error set the to NULL.
+        return setTransaction(0); // On error set to NULL.
   }
 
   bool ValuePrinterSynthesizer::tryAttachVP(DeclGroupRef DGR) {
@@ -56,36 +57,75 @@ namespace cling {
       if (FunctionDecl* FD = dyn_cast<FunctionDecl>(*I)) {
         if (FD->getNameAsString().find("__cling_Un1Qu3"))
           return true;
-
+        const CompilationOptions& CO(getTransaction()->getCompilationOpts());
+        if (CO.ValuePrinting == CompilationOptions::VPDisabled)
+          return true; // Nothing to do.
+
+        // We have to be able to mark the expression for printout. There are
+        // three scenarios:
+        // 0: Expression printing disabled - don't do anything just exit
+        //    even if there wasn't missing ';'.
+        // 1: Expression printing enabled - print no matter what.
+        // 2: Expression printing auto - analyze - rely on the omitted ';' to
+        //    not produce the suppress marker.
         if (CompoundStmt* CS = dyn_cast<CompoundStmt>(FD->getBody())) {
-          for (CompoundStmt::body_iterator
-                 J = CS->body_begin(), E = CS->body_end(); J != E; ++J) {
-            if (J+1 ==  E || !isa<NullStmt>(*(J+1))) {
-              Expr* To = 0;
-              ReturnStmt* RS = dyn_cast<ReturnStmt>(*J);
-              if (RS)
-                To = RS->getRetValue();
-              else
-                To = dyn_cast<Expr>(*J);
-
-              if (To) {
-                Expr* Result = 0;
-                if (m_Sema->getLangOpts().CPlusPlus)
-                  Result = SynthesizeCppVP(To);
-                else
-                  Result = SynthesizeVP(To);
-
-                if (Result) {
-                  if (RS)
-                    RS->setRetValue(Result);
-                  else
-                    *J = Result;
-                }
-              }
+          // Collect all Stmts, contained in the CompoundStmt
+          llvm::SmallVector<Stmt *, 4> Stmts;
+          for (CompoundStmt::body_iterator iStmt = CS->body_begin(),
+                 eStmt = CS->body_end(); iStmt != eStmt; ++iStmt)
+            Stmts.push_back(*iStmt);
+
+          int indexOfLastExpr = Stmts.size();
+          while(indexOfLastExpr--) {
+            // find the trailing expression statement (skip e.g. null statements)
+            if (isa<Expr>(Stmts[indexOfLastExpr])) {
+              // even if void: we found an expression
+              break;
             }
           }
+
+          // If no expressions found quit early.
+          if (indexOfLastExpr < 0)
+            return true; 
+
+          // Update the CompoundStmt body
+          Expr* To = cast<Expr>(Stmts[indexOfLastExpr]);// We know it is an expr
+          switch (CO.ValuePrinting) {
+          case CompilationOptions::VPDisabled:
+            assert("Don't wait that long. Exit early!");
+            break;
+          case CompilationOptions::VPEnabled:
+            break;
+          case CompilationOptions::VPAuto:
+            if ((int)Stmts.size() > indexOfLastExpr+1 
+                && Stmts[indexOfLastExpr+1] 
+                && isa<NullStmt>(Stmts[indexOfLastExpr+1]))
+              return true; // If prev is NullStmt disable VP is disabled - exit.
+            break;
+          }
+
+          // We can't PushDeclContext, because we don't have scope.
+          Sema::ContextRAII pushedDC(*m_Sema, FD);
+
+          if (To) {
+            // Strip the parenthesis if any
+            if (ParenExpr* PE = dyn_cast<ParenExpr>(To))
+              To = PE->getSubExpr();
+            
+            Expr* Result = 0;
+            if (m_Sema->getLangOpts().CPlusPlus)
+              Result = SynthesizeCppVP(To);
+            else
+              Result = SynthesizeVP(To);
+
+            if (Result)
+              Stmts[indexOfLastExpr] = Result;
+
+            CS->setStmts(*m_Context, Stmts.data(), Stmts.size());
+          }
           // Clear the artificial NullStmt-s
           if (!ClearNullStmts(CS)) {
+            // FIXME: Why it is here? Shouldn't it be in DeclExtractor?
             // if no body remove the wrapper
             DeclContext* DC = FD->getDeclContext();
             Scope* S = m_Sema->getScopeForContext(DC);
@@ -95,6 +135,7 @@ namespace cling {
           }
         }
       }
+
     return true;
   }
 
diff --git a/interpreter/cling/lib/Interpreter/ValuePrinterSynthesizer.h b/interpreter/cling/lib/Interpreter/ValuePrinterSynthesizer.h
index a60a4cb0464..28acfe1f8cb 100644
--- a/interpreter/cling/lib/Interpreter/ValuePrinterSynthesizer.h
+++ b/interpreter/cling/lib/Interpreter/ValuePrinterSynthesizer.h
@@ -37,7 +37,7 @@ namespace cling {
     llvm::OwningPtr<llvm::raw_ostream> m_ValuePrinterStream;
 
 public:
-    ///\ brief Construct the value printer synthesizer.
+    ///\ brief Constructs the value printer synthesizer.
     ///
     ///\param[in] S - The semantic analysis object
     ///\param[in] Stream - The output stream where the value printer will write
@@ -49,6 +49,15 @@ public:
     virtual void Transform();
 
   private:
+    ///\brief Tries to attach a value printing mechanism to the given decl group
+    /// ref.
+    ///
+    ///\param[in] DGR - A decl group ref the value printer is being attached to.
+    ///
+    ///\returns true if the attachment was considered as success. I.e. even if
+    /// even if the value printer wasn't attached because of the compilation 
+    /// options disallowint it - it will return still true. Returns false on
+    /// critical error.
     bool tryAttachVP(clang::DeclGroupRef DGR);
     clang::Expr* SynthesizeCppVP(clang::Expr* E);
     clang::Expr* SynthesizeVP(clang::Expr* E);
diff --git a/interpreter/cling/test/Interfaces/evaluate.C b/interpreter/cling/test/Interfaces/evaluate.C
index fac17c4a58d..6ddc9ec451a 100644
--- a/interpreter/cling/test/Interfaces/evaluate.C
+++ b/interpreter/cling/test/Interfaces/evaluate.C
@@ -1,4 +1,4 @@
-// RUN: cat %s | %cling | FileCheck %s
+// RUN: cat %s | %cling -Xclang -verify | FileCheck %s
 
 #include "cling/Interpreter/Interpreter.h"
 #include "cling/Interpreter/StoredValueRef.h"
@@ -19,9 +19,10 @@ V // CHECK: (cling::StoredValueRef) boxes [(int *) 0x12]
 
 cling::StoredValueRef Result;
 gCling->evaluate("V", &Result);
-Result // CHECK: (cling::StoredValueRef) boxes [(cling::StoredValueRef) ]
+Result // CHECK: (cling::StoredValueRef) boxes [(cling::StoredValueRef)]
 V // CHECK: (cling::StoredValueRef) boxes [(int *) 0x12]
 
 // Savannah #96277
 gCling->evaluate("double sin(double); double one = sin(3.141/2);", &V);
-one // CHECK: (double) 1.000000e+00
+V // CHECK: (cling::StoredValueRef) boxes [(void)]
+one // expected-error {{use of undeclared identifier 'one'}}  
diff --git a/interpreter/cling/test/Prompt/Regression.C b/interpreter/cling/test/Prompt/Regression.C
index a0cfe4e0ad7..5fff2fc4f38 100644
--- a/interpreter/cling/test/Prompt/Regression.C
+++ b/interpreter/cling/test/Prompt/Regression.C
@@ -12,7 +12,7 @@ cling::StoredValueRef V;
 gCling->process("int a = print();",&V);
 //CHECK: print is run.
 gCling->process("a", &V);
-//CHECK: (int const) 1
+//CHECK: (int) 1
 gCling->process("a;", &V);
 //CHECK-NOT: print is run.
 // End PR #96277
-- 
GitLab