<commit_before>//--------------------------------------------------------------------*- C++ -*-
// 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 "IncrementalExecutor.h"
#include "IncrementalJIT.h"
#include "Threading.h"

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

#include "clang/Basic/Diagnostic.h"

#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/PassManager.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Target/TargetMachine.h"

#ifdef LLVM_ON_WIN32
extern "C"
char *__unDName(char *demangled, const char *mangled, int out_len,
                void * (* pAlloc )(size_t), void (* pFree )(void *),
                unsigned short int flags);
#else
#include <cxxabi.h>
#endif

using namespace llvm;

namespace cling {

IncrementalExecutor::IncrementalExecutor(clang::DiagnosticsEngine& diags):
  m_CurrentAtExitModule(0)
#if 0
  : m_Diags(diags)
#endif
{

  // MSVC doesn't support m_AtExitFuncsSpinLock=ATOMIC_FLAG_INIT; in the class definition
  std::atomic_flag_clear( &m_AtExitFuncsSpinLock );

  // No need to protect this access of m_AtExitFuncs, since nobody
  // can use this object yet.
  m_AtExitFuncs.reserve(256);

  m_JIT.reset(new IncrementalJIT(*this, std::move(CreateHostTargetMachine())));
}

// Keep in source: ~unique_ptr<ClingJIT> needs ClingJIT
IncrementalExecutor::~IncrementalExecutor() {}

std::unique_ptr<TargetMachine>
  IncrementalExecutor::CreateHostTargetMachine() const {
  // TODO: make this configurable.
  Triple TheTriple(sys::getProcessTriple());
#ifdef _WIN32
  /*
	* MCJIT works on Windows, but currently only through ELF object format.
	*/
  TheTriple.setObjectFormat(llvm::Triple::ELF);
#endif
  std::string Error;
  const Target *TheTarget
    = TargetRegistry::lookupTarget(TheTriple.getTriple(), Error);
  if (!TheTarget) {
    llvm::errs() << "cling::IncrementalExecutor: unable to find target:\n"
                 << Error;
  }

  std::string MCPU;
  std::string FeaturesStr;

  TargetOptions Options = TargetOptions();
  Options.NoFramePointerElim = 1;
  Options.JITEmitDebugInfo = 1;
  Reloc::Model RelocModel = Reloc::Default;
  CodeModel::Model CMModel = CodeModel::JITDefault;
  CodeGenOpt::Level OptLevel = CodeGenOpt::Less;

  std::unique_ptr<TargetMachine> TM;
  TM.reset(TheTarget->createTargetMachine(TheTriple.getTriple(),
                                          MCPU, FeaturesStr,
                                          Options,
                                          RelocModel, CMModel,
                                          OptLevel));
  return std::move(TM);
}

void IncrementalExecutor::shuttingDown() {
  // No need to protect this access, since hopefully there is no concurrent
  // shutdown request.
  for (size_t I = 0, N = m_AtExitFuncs.size(); I < N; ++I) {
    const CXAAtExitElement& AEE = m_AtExitFuncs[N - I - 1];
    (*AEE.m_Func)(AEE.m_Arg);
  }
}

void IncrementalExecutor::AddAtExitFunc(void (*func) (void*), void* arg) {
  // Register a CXAAtExit function
  cling::internal::SpinLockGuard slg(m_AtExitFuncsSpinLock);
  m_AtExitFuncs.push_back(CXAAtExitElement(func, arg, m_CurrentAtExitModule));
}

void unresolvedSymbol()
{
  // throw exception?
  llvm::errs() << "IncrementalExecutor: calling unresolved symbol, "
    "see previous error message!\n";
}

void* IncrementalExecutor::HandleMissingFunction(const std::string& mangled_name)
{
  // Not found in the map, add the symbol in the list of unresolved symbols
  if (m_unresolvedSymbols.insert(mangled_name).second) {
    //llvm::errs() << "IncrementalExecutor: use of undefined symbol '"
    //             << mangled_name << "'!\n";
  }

  // Avoid "ISO C++ forbids casting between pointer-to-function and
  // pointer-to-object":
  return (void*)reinterpret_cast<size_t>(unresolvedSymbol);
}

void*
IncrementalExecutor::NotifyLazyFunctionCreators(const std::string& mangled_name)
{
  for (std::vector<LazyFunctionCreatorFunc_t>::iterator it
         = m_lazyFuncCreator.begin(), et = m_lazyFuncCreator.end();<commit_msg>Silence *calling* unresolved symbols. Handing it out already complains.<commit_after>//--------------------------------------------------------------------*- C++ -*-
// 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 "IncrementalExecutor.h"
#include "IncrementalJIT.h"
#include "Threading.h"

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

#include "clang/Basic/Diagnostic.h"

#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/PassManager.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Target/TargetMachine.h"

#ifdef LLVM_ON_WIN32
extern "C"
char *__unDName(char *demangled, const char *mangled, int out_len,
                void * (* pAlloc )(size_t), void (* pFree )(void *),
                unsigned short int flags);
#else
#include <cxxabi.h>
#endif

using namespace llvm;

namespace cling {

IncrementalExecutor::IncrementalExecutor(clang::DiagnosticsEngine& diags):
  m_CurrentAtExitModule(0)
#if 0
  : m_Diags(diags)
#endif
{

  // MSVC doesn't support m_AtExitFuncsSpinLock=ATOMIC_FLAG_INIT; in the class definition
  std::atomic_flag_clear( &m_AtExitFuncsSpinLock );

  // No need to protect this access of m_AtExitFuncs, since nobody
  // can use this object yet.
  m_AtExitFuncs.reserve(256);

  m_JIT.reset(new IncrementalJIT(*this, std::move(CreateHostTargetMachine())));
}

// Keep in source: ~unique_ptr<ClingJIT> needs ClingJIT
IncrementalExecutor::~IncrementalExecutor() {}

std::unique_ptr<TargetMachine>
  IncrementalExecutor::CreateHostTargetMachine() const {
  // TODO: make this configurable.
  Triple TheTriple(sys::getProcessTriple());
#ifdef _WIN32
  /*
	* MCJIT works on Windows, but currently only through ELF object format.
	*/
  TheTriple.setObjectFormat(llvm::Triple::ELF);
#endif
  std::string Error;
  const Target *TheTarget
    = TargetRegistry::lookupTarget(TheTriple.getTriple(), Error);
  if (!TheTarget) {
    llvm::errs() << "cling::IncrementalExecutor: unable to find target:\n"
                 << Error;
  }

  std::string MCPU;
  std::string FeaturesStr;

  TargetOptions Options = TargetOptions();
  Options.NoFramePointerElim = 1;
  Options.JITEmitDebugInfo = 1;
  Reloc::Model RelocModel = Reloc::Default;
  CodeModel::Model CMModel = CodeModel::JITDefault;
  CodeGenOpt::Level OptLevel = CodeGenOpt::Less;

  std::unique_ptr<TargetMachine> TM;
  TM.reset(TheTarget->createTargetMachine(TheTriple.getTriple(),
                                          MCPU, FeaturesStr,
                                          Options,
                                          RelocModel, CMModel,
                                          OptLevel));
  return std::move(TM);
}

void IncrementalExecutor::shuttingDown() {
  // No need to protect this access, since hopefully there is no concurrent
  // shutdown request.
  for (size_t I = 0, N = m_AtExitFuncs.size(); I < N; ++I) {
    const CXAAtExitElement& AEE = m_AtExitFuncs[N - I - 1];
    (*AEE.m_Func)(AEE.m_Arg);
  }
}

void IncrementalExecutor::AddAtExitFunc(void (*func) (void*), void* arg) {
  // Register a CXAAtExit function
  cling::internal::SpinLockGuard slg(m_AtExitFuncsSpinLock);
  m_AtExitFuncs.push_back(CXAAtExitElement(func, arg, m_CurrentAtExitModule));
}

void unresolvedSymbol()
{
  // This might get called recursively, or a billion of times. Do not generate
  // useless output; unresolvedSymbol() is always handed out with an error
  // message - that's enough.
  //llvm::errs() << "IncrementalExecutor: calling unresolved symbol, "
  //  "see previous error message!\n";

  // throw exception instead?
}

void* IncrementalExecutor::HandleMissingFunction(const std::string& mangled_name)
{
  // Not found in the map, add the symbol in the list of unresolved symbols
  if (m_unresolvedSymbols.insert(mangled_name).second) {
    //llvm::errs() << "IncrementalExecutor: use of undefined symbol '"
    //             << mangled_name << "'!\n";
  }

  // Avoid "ISO C++ forbids casting between pointer-to-function and
  // pointer-to-object":
  return (void*)reinterpret_cast<size_t>(unresolvedSymbol);
}

void*
IncrementalExecutor::NotifyLazyFunctionCreators(const std::string& mangled_name)
{
  for (std::vector<LazyFunctionCreatorFunc_t>::iterator it
         = m_lazyFuncCreator.begin(), et = m_lazyFuncCreator.end();
{'fraction_non_alphanumeric': 0.15327929255711129, 'fraction_numerical': 0.00273713022423413, 'mean_word_length': 3.326047358834244, 'pattern_counts': {'":': 2, '<': 47, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7317937', 'n_tokens_mistral': 3034, 'n_tokens_neox': 2928, 'n_words': 696}