<commit_before>// @(#)root/core/meta:$Id$
// Author: <NAME>   30/07/2012

/*************************************************************************
 * Copyright (C) 1995-2000, <NAME> and <NAME>.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TClingCallFunc                                                       //
//                                                                      //
// Emulation of the CINT CallFunc class.                                //
//                                                                      //
// The CINT C++ interpreter provides an interface for calling           //
// functions through the generated wrappers in dictionaries with        //
// the CallFunc class. This class provides the same functionality,      //
// using an interface as close as possible to CallFunc but the          //
// function metadata and calling service comes from the Cling           //
// C++ interpreter and the Clang C++ compiler, not CINT.                //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TClingCallFunc.h"

#include "TClingClassInfo.h"
#include "TClingMethodInfo.h"

#include "TError.h"

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/LookupHelper.h"
#include "cling/Interpreter/StoredValueRef.h"

#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/Mangle.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/RecordLayout.h"
#include "clang/AST/Type.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/Preprocessor.h"

#include "llvm/ADT/APInt.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/LLVMContext.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/Type.h"

#include <string>
#include <vector>

// This ought to be declared by the implementer .. oh well...
extern void unresolvedSymbol();

void TClingCallFunc::Exec(void *address) const
{
   if (!IsValid()) {
      return;
   }
   const clang::Decl *D = fMethod->GetMethodDecl();
   const clang::CXXMethodDecl *MD = llvm::dyn_cast<clang::CXXMethodDecl>(D);
   const clang::DeclContext *DC = D->getDeclContext();
   if (DC->isTranslationUnit() || DC->isNamespace() || (MD && MD->isStatic())) {
      // Free function or static member function.
      Invoke(fArgs);
   }
   else {
      // Member function.
      if (const clang::CXXConstructorDecl *CD =
               llvm::dyn_cast<clang::CXXConstructorDecl>(D)) {
         clang::ASTContext &Context = CD->getASTContext();
         const clang::RecordDecl *RD = llvm::cast<clang::RecordDecl>(DC);
         if (!RD->getDefinition()) {
            // Forward-declared class, we do not know what the size is.
            return;
         }
         const clang::ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
         int64_t size = Layout.getSize().getQuantity();
         address = malloc(size);
      }
      else {
         if (!address) {
            Error("TClingCallFunc::Exec",
                  "calling member function with no object pointer!\n");
         }
      }
      std::vector<llvm::GenericValue> args;
      llvm::GenericValue this_ptr;
      this_ptr.IntVal = llvm::APInt(sizeof(unsigned long) * CHAR_BIT,
                                    reinterpret_cast<unsigned long>(address));
      args.push_back(this_ptr);
      args.insert(args.end(), fArgs.begin(), fArgs.end());
      Invoke(args);
   }
}

long TClingCallFunc::ExecInt(void *address) const
{
   // Yes, the function name has Int in it, but it
   // returns a long.  This is a matter of CINT history.
   if (!IsValid()) {
      return 0L;
   }
   llvm::GenericValue val;
   const clang::Decl *D = fMethod->GetMethodDecl();
   const clang::CXXMethodDecl *MD = llvm::dyn_cast<clang::CXXMethodDecl>(D);
   const clang::DeclContext *DC = D->getDeclContext();
   if (DC->isTranslationUnit() || DC->isNamespace() || (MD && MD->isStatic())) {
      // Free function or static member function.
      val = Invoke(fArgs);
   }
   else {
      // Member function.
      if (const clang::CXXConstructorDecl *CD =
               llvm::dyn_cast<clang::CXXConstructorDecl>(D)) {
         clang::ASTContext &Context = CD->getASTContext();
         const clang::RecordDecl *RD = llvm::cast<clang::RecordDecl>(DC);
         if (!RD->getDefinition()) {
            // Forward-declared class, we do not know what the size is.
            return 0L;
         }
         const clang::ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
         int64_t size = Layout.getSize().getQuantity();
         address = malloc(size);
      }
      else {
         if (!address) {
            fprintf(stderr, "TClingCallFunc::Exec: error: "
                    "calling member function with no object pointer!\n");
         }
      }
      std::vector<llvm::GenericValue> args;
      llvm::GenericValue this_ptr;
      this_ptr.IntVal = llvm::APInt(sizeof(unsigned long) * CHAR_BIT,
                                    reinterpret_cast<unsigned long>(address));
      args.push_back(this_ptr);
      args.insert(args.end(), fArgs.begin(), fArgs.end());
      val  = Invoke(args);<commit_msg>Have the call to constructor (humm ... well, I mean a call to operator new), return the allocated address<commit_after>// @(#)root/core/meta:$Id$
// Author: <NAME>   30/07/2012

/*************************************************************************
 * Copyright (C) 1995-2000, <NAME> and <NAME>ers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TClingCallFunc                                                       //
//                                                                      //
// Emulation of the CINT CallFunc class.                                //
//                                                                      //
// The CINT C++ interpreter provides an interface for calling           //
// functions through the generated wrappers in dictionaries with        //
// the CallFunc class. This class provides the same functionality,      //
// using an interface as close as possible to CallFunc but the          //
// function metadata and calling service comes from the Cling           //
// C++ interpreter and the Clang C++ compiler, not CINT.                //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TClingCallFunc.h"

#include "TClingClassInfo.h"
#include "TClingMethodInfo.h"

#include "TError.h"

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/LookupHelper.h"
#include "cling/Interpreter/StoredValueRef.h"

#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/Mangle.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/RecordLayout.h"
#include "clang/AST/Type.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/Preprocessor.h"

#include "llvm/ADT/APInt.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/LLVMContext.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/Type.h"

#include <string>
#include <vector>

// This ought to be declared by the implementer .. oh well...
extern void unresolvedSymbol();

void TClingCallFunc::Exec(void *address) const
{
   if (!IsValid()) {
      return;
   }
   const clang::Decl *D = fMethod->GetMethodDecl();
   const clang::CXXMethodDecl *MD = llvm::dyn_cast<clang::CXXMethodDecl>(D);
   const clang::DeclContext *DC = D->getDeclContext();
   if (DC->isTranslationUnit() || DC->isNamespace() || (MD && MD->isStatic())) {
      // Free function or static member function.
      Invoke(fArgs);
   }
   else {
      // Member function.
      if (const clang::CXXConstructorDecl *CD =
               llvm::dyn_cast<clang::CXXConstructorDecl>(D)) {
         clang::ASTContext &Context = CD->getASTContext();
         const clang::RecordDecl *RD = llvm::cast<clang::RecordDecl>(DC);
         if (!RD->getDefinition()) {
            // Forward-declared class, we do not know what the size is.
            return;
         }
         const clang::ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
         int64_t size = Layout.getSize().getQuantity();
         address = malloc(size);
      }
      else {
         if (!address) {
            Error("TClingCallFunc::Exec",
                  "calling member function with no object pointer!\n");
         }
      }
      std::vector<llvm::GenericValue> args;
      llvm::GenericValue this_ptr;
      this_ptr.IntVal = llvm::APInt(sizeof(unsigned long) * CHAR_BIT,
                                    reinterpret_cast<unsigned long>(address));
      args.push_back(this_ptr);
      args.insert(args.end(), fArgs.begin(), fArgs.end());
      Invoke(args);
   }
}

long TClingCallFunc::ExecInt(void *address) const
{
   // Yes, the function name has Int in it, but it
   // returns a long.  This is a matter of CINT history.
   if (!IsValid()) {
      return 0L;
   }
   llvm::GenericValue val;
   const clang::Decl *D = fMethod->GetMethodDecl();
   const clang::CXXMethodDecl *MD = llvm::dyn_cast<clang::CXXMethodDecl>(D);
   const clang::DeclContext *DC = D->getDeclContext();
   if (DC->isTranslationUnit() || DC->isNamespace() || (MD && MD->isStatic())) {
      // Free function or static member function.
      val = Invoke(fArgs);
   }
   else {
      // Member function.
      if (const clang::CXXConstructorDecl *CD =
               llvm::dyn_cast<clang::CXXConstructorDecl>(D)) {
         clang::ASTContext &Context = CD->getASTContext();
         const clang::RecordDecl *RD = llvm::cast<clang::RecordDecl>(DC);
         if (!RD->getDefinition()) {
            // Forward-declared class, we do not know what the size is.
            return 0L;
         }
         const clang::ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
         int64_t size = Layout.getSize().getQuantity();
         address = malloc(size); // this is bad, we really need to call the class' own operator new but oh well

         std::vector<llvm::GenericValue> args;
         llvm::GenericValue this_ptr;
         this_ptr.IntVal = llvm::APInt(sizeof(unsigned long) * CHAR_BIT,
                                       reinterpret_cast<unsigned long>(address));
         args.push_back(this_ptr);
         args.insert(args.end(), fArgs.begin(), fArgs.end());
         val  = Invoke(args);
         
         // We don't really mean to call the constructor and return its (lack of)
         // return value, we meant to execute and return 'new TypeOf(...)' and
         // return the allocated address, so here you go:
         return (long)(address);
      }
      else {
         if (!address) {
            fprintf(stderr, "TClingCallFunc::Exec: error: "
                    "calling member function with no object pointer!\n");
         }
      }
      std::vector<llvm::GenericValue> args;
      llvm::GenericValue this_ptr;
      this_ptr.IntVal = llvm::APInt(sizeof(unsigned long) * CHAR_BIT,
                                    reinterpret_cast<unsigned long>(address));
      args.push_back(this_ptr);
      args.insert(args.end(), fArgs.begin(), fArgs.end());
      val  = Invoke(args);
{'fraction_non_alphanumeric': 0.16682532127558306, 'fraction_numerical': 0.0034904013961605585, 'mean_word_length': 1.9122199122199122, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 63, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 43, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7368968', 'n_tokens_mistral': 3465, 'n_tokens_neox': 3339, 'n_words': 826}