<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 "cling/Interpreter/Interpreter.h"

#include "cling-compiledata.h"
#include "DynamicLookup.h"
#include "IncrementalExecutor.h"
#include "IncrementalParser.h"

#include "cling/Interpreter/CIFactory.h"
#include "cling/Interpreter/ClangInternalState.h"
#include "cling/Interpreter/CompilationOptions.h"
#include "cling/Interpreter/DynamicLibraryManager.h"
#include "cling/Interpreter/InterpreterCallbacks.h"
#include "cling/Interpreter/LookupHelper.h"
#include "cling/Interpreter/Transaction.h"
#include "cling/Interpreter/Value.h"
#include "cling/Utils/AST.h"

#include "clang/AST/ASTContext.h"
#include "clang/AST/GlobalDecl.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/SourceManager.h"
#include "clang/CodeGen/ModuleBuilder.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/Utils.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/Parser.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaDiagnostic.h"

#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"

#include <sstream>
#include <string>
#include <vector>

using namespace clang;

namespace {

  static cling::Interpreter::ExecutionResult
  ConvertExecutionResult(cling::IncrementalExecutor::ExecutionResult ExeRes) {
    switch (ExeRes) {
    case cling::IncrementalExecutor::kExeSuccess:
      return cling::Interpreter::kExeSuccess;
    case cling::IncrementalExecutor::kExeFunctionNotCompiled:
      return cling::Interpreter::kExeFunctionNotCompiled;
    case cling::IncrementalExecutor::kExeUnresolvedSymbols:
      return cling::Interpreter::kExeUnresolvedSymbols;
    default: break;
    }
    return cling::Interpreter::kExeSuccess;
  }
} // unnamed namespace

namespace cling {
  namespace runtime {
    namespace internal {
      // "Declared" to the JIT in RuntimeUniverse.h
      void local_cxa_atexit(void (*func) (void*), void* arg, void* interp) {
        Interpreter* cling = (cling::Interpreter*)interp;
        cling->AddAtExitFunc(func, arg);
      }
    } // end namespace internal
  } // end namespace runtime

  // FIXME: workaround until JIT supports exceptions
  jmp_buf* Interpreter::m_JumpBuf;

  Interpreter::PushTransactionRAII::PushTransactionRAII(const Interpreter* i)
    : m_Interpreter(i) {
    CompilationOptions CO;
    CO.DeclarationExtraction = 0;
    CO.ValuePrinting = 0;
    CO.ResultEvaluation = 0;
    CO.DynamicScoping = 0;
    CO.Debug = 0;
    CO.CodeGeneration = 1;
    CO.CodeGenerationForModule = 0;

    m_Transaction = m_Interpreter->m_IncrParser->beginTransaction(CO);
  }

  Interpreter::PushTransactionRAII::~PushTransactionRAII() {
    pop();
  }

  void Interpreter::PushTransactionRAII::pop() const {
    if (Transaction* T 
        = m_Interpreter->m_IncrParser->endTransaction(m_Transaction)) {
      assert(T == m_Transaction && "Ended different transaction?");
      m_Interpreter->m_IncrParser->commitTransaction(T);
    }
  }

  Interpreter::StateDebuggerRAII::StateDebuggerRAII(const Interpreter* i)
    : m_Interpreter(i) {
    if (!i->isPrintingDebug())
      return;
    const CompilerInstance& CI = *m_Interpreter->getCI();
    CodeGenerator* CG = i->m_IncrParser->getCodeGenerator();

    // The ClangInternalState can provoke deserialization, we need a transaction.
    PushTransactionRAII pushedT(i);

    m_State.reset(new ClangInternalState(CI.getASTContext(),
                                         CI.getPreprocessor(),
                                         CG ? CG->GetModule() : 0,
                                         CG,
                                         "aName"));
  }

  Interpreter::StateDebuggerRAII::~StateDebuggerRAII() {
    pop();
  }

  void Interpreter::StateDebuggerRAII::pop() const {
    if (!m_Interpreter->isPrintingDebug())
      return;
    m_State->compare("aName");
  }

  // This function isn't referenced outside its translation unit, but it
  // can't use the "static" keyword because its address is used for
  // GetMainExecutable (since some platforms don't support taking the
  // address of main, and some platforms can't implement GetMainExecutable
  // without being given the address of a function in the main executable).
  std::string GetExecutablePath(const char *Argv0) {
    // This just needs to be some symbol in the binary; C++ doesn't
    // allow taking the address of ::main however.
    void *MainAddr = (void*) (intptr_t) GetExecutablePath;
    return llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
  }

  const Parser& Interpreter::getParser() const {
    return *m_IncrParser->getParser();<commit_msg>Add missing transaction in Interpreter::StateDebuggerRAII::~StateDebuggerRAII<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 "cling/Interpreter/Interpreter.h"

#include "cling-compiledata.h"
#include "DynamicLookup.h"
#include "IncrementalExecutor.h"
#include "IncrementalParser.h"

#include "cling/Interpreter/CIFactory.h"
#include "cling/Interpreter/ClangInternalState.h"
#include "cling/Interpreter/CompilationOptions.h"
#include "cling/Interpreter/DynamicLibraryManager.h"
#include "cling/Interpreter/InterpreterCallbacks.h"
#include "cling/Interpreter/LookupHelper.h"
#include "cling/Interpreter/Transaction.h"
#include "cling/Interpreter/Value.h"
#include "cling/Utils/AST.h"

#include "clang/AST/ASTContext.h"
#include "clang/AST/GlobalDecl.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/SourceManager.h"
#include "clang/CodeGen/ModuleBuilder.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/Utils.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/Parser.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaDiagnostic.h"

#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"

#include <sstream>
#include <string>
#include <vector>

using namespace clang;

namespace {

  static cling::Interpreter::ExecutionResult
  ConvertExecutionResult(cling::IncrementalExecutor::ExecutionResult ExeRes) {
    switch (ExeRes) {
    case cling::IncrementalExecutor::kExeSuccess:
      return cling::Interpreter::kExeSuccess;
    case cling::IncrementalExecutor::kExeFunctionNotCompiled:
      return cling::Interpreter::kExeFunctionNotCompiled;
    case cling::IncrementalExecutor::kExeUnresolvedSymbols:
      return cling::Interpreter::kExeUnresolvedSymbols;
    default: break;
    }
    return cling::Interpreter::kExeSuccess;
  }
} // unnamed namespace

namespace cling {
  namespace runtime {
    namespace internal {
      // "Declared" to the JIT in RuntimeUniverse.h
      void local_cxa_atexit(void (*func) (void*), void* arg, void* interp) {
        Interpreter* cling = (cling::Interpreter*)interp;
        cling->AddAtExitFunc(func, arg);
      }
    } // end namespace internal
  } // end namespace runtime

  // FIXME: workaround until JIT supports exceptions
  jmp_buf* Interpreter::m_JumpBuf;

  Interpreter::PushTransactionRAII::PushTransactionRAII(const Interpreter* i)
    : m_Interpreter(i) {
    CompilationOptions CO;
    CO.DeclarationExtraction = 0;
    CO.ValuePrinting = 0;
    CO.ResultEvaluation = 0;
    CO.DynamicScoping = 0;
    CO.Debug = 0;
    CO.CodeGeneration = 1;
    CO.CodeGenerationForModule = 0;

    m_Transaction = m_Interpreter->m_IncrParser->beginTransaction(CO);
  }

  Interpreter::PushTransactionRAII::~PushTransactionRAII() {
    pop();
  }

  void Interpreter::PushTransactionRAII::pop() const {
    if (Transaction* T 
        = m_Interpreter->m_IncrParser->endTransaction(m_Transaction)) {
      assert(T == m_Transaction && "Ended different transaction?");
      m_Interpreter->m_IncrParser->commitTransaction(T);
    }
  }

  Interpreter::StateDebuggerRAII::StateDebuggerRAII(const Interpreter* i)
    : m_Interpreter(i) {
    if (!i->isPrintingDebug())
      return;
    const CompilerInstance& CI = *m_Interpreter->getCI();
    CodeGenerator* CG = i->m_IncrParser->getCodeGenerator();

    // The ClangInternalState constructor can provoke deserialization,
    // we need a transaction.
    PushTransactionRAII pushedT(i);

    m_State.reset(new ClangInternalState(CI.getASTContext(),
                                         CI.getPreprocessor(),
                                         CG ? CG->GetModule() : 0,
                                         CG,
                                         "aName"));
  }

  Interpreter::StateDebuggerRAII::~StateDebuggerRAII() {
    // The ClangInternalState destructor can provoke deserialization,
    // we need a transaction.
    PushTransactionRAII pushedT(m_Interpreter);

    pop();
  }

  void Interpreter::StateDebuggerRAII::pop() const {
    if (!m_Interpreter->isPrintingDebug())
      return;
    m_State->compare("aName");
  }

  // This function isn't referenced outside its translation unit, but it
  // can't use the "static" keyword because its address is used for
  // GetMainExecutable (since some platforms don't support taking the
  // address of main, and some platforms can't implement GetMainExecutable
  // without being given the address of a function in the main executable).
  std::string GetExecutablePath(const char *Argv0) {
    // This just needs to be some symbol in the binary; C++ doesn't
    // allow taking the address of ::main however.
    void *MainAddr = (void*) (intptr_t) GetExecutablePath;
    return llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
  }

  const Parser& Interpreter::getParser() const {
    return *m_IncrParser->getParser();
{'fraction_non_alphanumeric': 0.14357101672112244, 'fraction_numerical': 0.0019219680953296175, 'mean_word_length': 3.2844792095512556, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2361335', 'n_tokens_mistral': 3175, 'n_tokens_neox': 3120, 'n_words': 686}