<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  <NAME> <<EMAIL>>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "ValuePrinterSynthesizer.h"

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/Transaction.h"
#include "cling/Utils/AST.h"

#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclGroup.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/ExprCXX.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/Sema.h"

#include "llvm/Support/raw_os_ostream.h"

#include <iostream>

using namespace clang;

namespace cling {

  ValuePrinterSynthesizer::ValuePrinterSynthesizer(clang::Sema* S, 
                                                   llvm::raw_ostream* Stream)
    : TransactionTransformer(S), m_Context(&S->getASTContext()) {
    if (Stream)
      m_ValuePrinterStream.reset(Stream);
    else 
      m_ValuePrinterStream.reset(new llvm::raw_os_ostream(std::cout));
  }


  // pin the vtable here.
  ValuePrinterSynthesizer::~ValuePrinterSynthesizer()
  { }

  void ValuePrinterSynthesizer::Transform() {
    if (getTransaction()->getCompilationOpts().ValuePrinting 
        == CompilationOptions::VPDisabled)
      return;

    if (!tryAttachVP(getTransaction()->getWrapperFD()))
      return setTransaction(0); // On error set to NULL.
  }

  bool ValuePrinterSynthesizer::tryAttachVP(FunctionDecl* FD) {
    // 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.
    // 1: Expression printing enabled - print no matter what.
    // 2: Expression printing auto - analyze - rely on the omitted ';' to
    //    not produce the suppress marker.
    int indexOfLastExpr = -1;
    Expr* To = utils::Analyze::GetOrCreateLastExpr(FD, &indexOfLastExpr, 
                                                   /*omitDS*/false,
                                                   m_Sema);
    if (To) {
      // Update the CompoundStmt body, avoiding alloc/dealloc of all the el.
      CompoundStmt* CS = cast<CompoundStmt>(FD->getBody());
      assert(CS && "Missing body?");

      const CompilationOptions& CO(getTransaction()->getCompilationOpts());
      switch (CO.ValuePrinting) {
      case CompilationOptions::VPDisabled:
        assert(0 && "Don't wait that long. Exit early!");
        break;
      case CompilationOptions::VPEnabled:
        break;
      case CompilationOptions::VPAuto:
        if ((int)CS->size() > indexOfLastExpr+1 
            && (*(CS->body_begin() + indexOfLastExpr + 1))
            && isa<NullStmt>(*(CS->body_begin() + indexOfLastExpr + 1))) {
          // If next is NullStmt disable VP is disabled - exit. Signal this in
          // the CO of the transaction.
          Transaction* T = getTransaction();
          T->getCompilationOpts().ValuePrinting = CompilationOptions::VPDisabled;
          return true;
        }
        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 = SynthesizeVP(To);

        if (Result)
          *(CS->body_begin()+indexOfLastExpr) = Result;
      }
      // 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);
        if (S)
          S->RemoveDecl(FD);
        DC->removeDecl(FD);
      }
    }

    return true;
  }

  // We need to artificially create:
  // cling_PrintValue(void* (ASTContext)C, void* (Expr)E, const void* (&i)
  Expr* ValuePrinterSynthesizer::SynthesizeVP(Expr* E) {
    QualType QT = E->getType();
    // For now we skip void and function pointer types.
    if (!QT.isNull() && (QT->isVoidType() || QT->isFunctionType()))
      return 0;<commit_msg>Expand 'properly' VPAuto into whatever the value printer synthesizer desided to do.<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  <NAME> <<EMAIL>>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "ValuePrinterSynthesizer.h"

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/Transaction.h"
#include "cling/Utils/AST.h"

#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclGroup.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/ExprCXX.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/Sema.h"

#include "llvm/Support/raw_os_ostream.h"

#include <iostream>

using namespace clang;

namespace cling {

  ValuePrinterSynthesizer::ValuePrinterSynthesizer(clang::Sema* S, 
                                                   llvm::raw_ostream* Stream)
    : TransactionTransformer(S), m_Context(&S->getASTContext()) {
    if (Stream)
      m_ValuePrinterStream.reset(Stream);
    else 
      m_ValuePrinterStream.reset(new llvm::raw_os_ostream(std::cout));
  }


  // pin the vtable here.
  ValuePrinterSynthesizer::~ValuePrinterSynthesizer()
  { }

  void ValuePrinterSynthesizer::Transform() {
    if (getTransaction()->getCompilationOpts().ValuePrinting 
        == CompilationOptions::VPDisabled)
      return;

    if (!tryAttachVP(getTransaction()->getWrapperFD()))
      return setTransaction(0); // On error set to NULL.
  }

  bool ValuePrinterSynthesizer::tryAttachVP(FunctionDecl* FD) {
    // 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.
    // 1: Expression printing enabled - print no matter what.
    // 2: Expression printing auto - analyze - rely on the omitted ';' to
    //    not produce the suppress marker.
    int indexOfLastExpr = -1;
    Expr* To = utils::Analyze::GetOrCreateLastExpr(FD, &indexOfLastExpr, 
                                                   /*omitDS*/false,
                                                   m_Sema);
    if (To) {
      // Update the CompoundStmt body, avoiding alloc/dealloc of all the el.
      CompoundStmt* CS = cast<CompoundStmt>(FD->getBody());
      assert(CS && "Missing body?");

      const CompilationOptions& CO(getTransaction()->getCompilationOpts());
      switch (CO.ValuePrinting) {
      case CompilationOptions::VPDisabled:
        assert(0 && "Don't wait that long. Exit early!");
        break;
      case CompilationOptions::VPEnabled:
        break;
      case CompilationOptions::VPAuto: {
        CompilationOptions& CO = getTransaction()->getCompilationOpts();
        // FIXME: Propagate the flag to the nested transactions also, they
        // must have the same CO as their parents.
        CO.ValuePrinting = CompilationOptions::VPEnabled;
        if ((int)CS->size() > indexOfLastExpr+1
            && (*(CS->body_begin() + indexOfLastExpr + 1))
            && isa<NullStmt>(*(CS->body_begin() + indexOfLastExpr + 1))) {
          // If next is NullStmt disable VP is disabled - exit. Signal this in
          // the CO of the transaction.
          CO.ValuePrinting = CompilationOptions::VPDisabled;
        }
        if (CO.ValuePrinting == CompilationOptions::VPDisabled)
          return true;
      }
        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 = SynthesizeVP(To);

        if (Result)
          *(CS->body_begin()+indexOfLastExpr) = Result;
      }
      // 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);
        if (S)
          S->RemoveDecl(FD);
        DC->removeDecl(FD);
      }
    }
    else // if nothing to attach to set the CO's ValuePrinting to disabled.
      getTransaction()->getCompilationOpts().ValuePrinting
        = CompilationOptions::VPDisabled;
    return true;
  }

  // We need to artificially create:
  // cling_PrintValue(void* (ASTContext)C, void* (Expr)E, const void* (&i)
  Expr* ValuePrinterSynthesizer::SynthesizeVP(Expr* E) {
    QualType QT = E->getType();
    // For now we skip void and function pointer types.
    if (!QT.isNull() && (QT->isVoidType() || QT->isFunctionType()))
      return 0;
{'fraction_non_alphanumeric': 0.15179690764730464, 'fraction_numerical': 0.002298370246552445, 'mean_word_length': 2.2761806981519506, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 58, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5889785', 'n_tokens_mistral': 2864, 'n_tokens_neox': 2810, 'n_words': 719}