<commit_before>/// \file GraphModule.cpp

#include "chi/GraphModule.hpp"
#include "chi/Context.hpp"
#include "chi/FunctionCompiler.hpp"
#include "chi/GraphFunction.hpp"
#include "chi/GraphStruct.hpp"
#include "chi/JsonDeserializer.hpp"
#include "chi/JsonSerializer.hpp"
#include "chi/NameMangler.hpp"
#include "chi/NodeInstance.hpp"
#include "chi/NodeType.hpp"
#include "chi/Result.hpp"
#include "chi/LLVMVersion.hpp"

#include <llvm/IR/DIBuilder.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/Module.h>
#include <llvm/Linker/Linker.h>
#include <llvm/Support/FileSystem.h>
#include <llvm/Transforms/Utils/Cloning.h>

#if LLVM_VERSION_LESS_EQUAL(3, 9)
#include <llvm/Bitcode/ReaderWriter.h>
#else
#include <llvm/Bitcode/BitcodeReader.h>
#endif

#include <boost/filesystem.hpp>
#include <boost/range.hpp>

#include <boost/uuid/uuid_io.hpp>

#include <libexecstream/exec-stream.h>

namespace fs = boost::filesystem;

namespace chi {

namespace {

// Compile C code to a llvm::Module
std::unique_ptr<llvm::Module> compileCCode(const char* execPath, boost::string_view code,
                                           const std::vector<std::string>& args,
                                           llvm::LLVMContext& ctx, Result& res) {
	std::vector<const char*> cArgs;
	for (const auto& arg : args) { cArgs.push_back(arg.c_str()); }
	cArgs.push_back("-nostdlib");

	std::string errors;

	// call chi-ctollvm
	std::unique_ptr<llvm::Module> mod;
	{
		std::vector<const char*> argsToChiCtoLLVM;
		for (auto arg : cArgs) {
			argsToChiCtoLLVM.push_back("-c");
			argsToChiCtoLLVM.push_back(arg);
		}
		
		exec_stream_t ctollvmExe;
		ctollvmExe.set_wait_timeout(exec_stream_t::s_out, 100000);
		auto exeLoc = fs::path(execPath).parent_path() / "chi-ctollvm"
#if WIN32
			".exe"
#endif
			;
		assert(fs::is_regular_file(exeLoc));
		ctollvmExe.start(exeLoc.string().c_str(), argsToChiCtoLLVM.begin(), argsToChiCtoLLVM.end());
		
		ctollvmExe.in() << code;
		ctollvmExe.close_in();
		
		auto generatedbc = std::string{std::istreambuf_iterator<char>(ctollvmExe.out()),
								std::istreambuf_iterator<char>()};
		auto errs = std::string{std::istreambuf_iterator<char>(ctollvmExe.err()),
		                         std::istreambuf_iterator<char>()};
								 
		ctollvmExe.close();
		auto errCode = ctollvmExe.exit_code();
		
		if (errCode != 0) {
			res.addEntry("EUKN", "Failed to Generate IR with clang", {{"Error", errs}});
			return nullptr;
		}
		if (!errs.empty()) {
			res.addEntry("WUKN", "Failed to generate IR with clang", {{"Warning", errs}});
		}
		
		
		auto errorOrMod = llvm::parseBitcodeFile(llvm::MemoryBufferRef(generatedbc, "generated.bc"), ctx);
		if (!errorOrMod) {
			res.addEntry("EUKN", "Failed to parse generated bitcode.", {});
			return nullptr;
		}
		mod = 
#if LLVM_VERSION_LESS_EQUAL(3, 6)
			std::unique_ptr<llvm::Module>
#else
			std::move
#endif
				(errorOrMod.get());
	}
	
	if (mod == nullptr) {
		res.addEntry("EUKN", "Failed to generate IR with clang", {{"Error", errors}});
	} else if (!errors.empty()) {
		res.addEntry("WUKN", "Warnings encountered while generating IR with clang",
		             {{"Error", errors}});
	}

	return mod;
}

/// The NodeType for calling C functions<commit_msg>Fix LLVM 3.5 call<commit_after>/// \file GraphModule.cpp

#include "chi/GraphModule.hpp"
#include "chi/Context.hpp"
#include "chi/FunctionCompiler.hpp"
#include "chi/GraphFunction.hpp"
#include "chi/GraphStruct.hpp"
#include "chi/JsonDeserializer.hpp"
#include "chi/JsonSerializer.hpp"
#include "chi/NameMangler.hpp"
#include "chi/NodeInstance.hpp"
#include "chi/NodeType.hpp"
#include "chi/Result.hpp"
#include "chi/LLVMVersion.hpp"

#include <llvm/IR/DIBuilder.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/Module.h>
#include <llvm/Linker/Linker.h>
#include <llvm/Support/FileSystem.h>
#include <llvm/Transforms/Utils/Cloning.h>

#if LLVM_VERSION_LESS_EQUAL(3, 9)
#include <llvm/Bitcode/ReaderWriter.h>
#else
#include <llvm/Bitcode/BitcodeReader.h>
#endif

#include <boost/filesystem.hpp>
#include <boost/range.hpp>

#include <boost/uuid/uuid_io.hpp>

#include <libexecstream/exec-stream.h>

namespace fs = boost::filesystem;

namespace chi {

namespace {

// Compile C code to a llvm::Module
std::unique_ptr<llvm::Module> compileCCode(const char* execPath, boost::string_view code,
                                           const std::vector<std::string>& args,
                                           llvm::LLVMContext& ctx, Result& res) {
	std::vector<const char*> cArgs;
	for (const auto& arg : args) { cArgs.push_back(arg.c_str()); }
	cArgs.push_back("-nostdlib");

	std::string errors;

	// call chi-ctollvm
	std::unique_ptr<llvm::Module> mod;
	{
		std::vector<const char*> argsToChiCtoLLVM;
		for (auto arg : cArgs) {
			argsToChiCtoLLVM.push_back("-c");
			argsToChiCtoLLVM.push_back(arg);
		}
		
		exec_stream_t ctollvmExe;
		ctollvmExe.set_wait_timeout(exec_stream_t::s_out, 100000);
		auto exeLoc = fs::path(execPath).parent_path() / "chi-ctollvm"
#if WIN32
			".exe"
#endif
			;
		assert(fs::is_regular_file(exeLoc));
		ctollvmExe.start(exeLoc.string().c_str(), argsToChiCtoLLVM.begin(), argsToChiCtoLLVM.end());
		
		ctollvmExe.in() << code;
		ctollvmExe.close_in();
		
		auto generatedbc = std::string{std::istreambuf_iterator<char>(ctollvmExe.out()),
								std::istreambuf_iterator<char>()};
		auto errs = std::string{std::istreambuf_iterator<char>(ctollvmExe.err()),
		                         std::istreambuf_iterator<char>()};
								 
		ctollvmExe.close();
		auto errCode = ctollvmExe.exit_code();
		
		if (errCode != 0) {
			res.addEntry("EUKN", "Failed to Generate IR with clang", {{"Error", errs}});
			return nullptr;
		}
		if (!errs.empty()) {
			res.addEntry("WUKN", "Failed to generate IR with clang", {{"Warning", errs}});
		}
		
		
		auto errorOrMod = llvm::parseBitcodeFile(
#if LLVM_VERSION_LESS_EQUAL(3, 5)
			llvm::MemoryBuffer::getMemBufferCopy
#else
			llvm::MemoryBufferRef
#endif
				(generatedbc, "generated.bc"), ctx);
		if (!errorOrMod) {
			res.addEntry("EUKN", "Failed to parse generated bitcode.", {});
			return nullptr;
		}
		mod = 
#if LLVM_VERSION_LESS_EQUAL(3, 6)
			std::unique_ptr<llvm::Module>
#else
			std::move
#endif
				(errorOrMod.get());
	}
	
	if (mod == nullptr) {
		res.addEntry("EUKN", "Failed to generate IR with clang", {{"Error", errors}});
	} else if (!errors.empty()) {
		res.addEntry("WUKN", "Warnings encountered while generating IR with clang",
		             {{"Error", errors}});
	}

	return mod;
}

/// The NodeType for calling C functions
{'fraction_non_alphanumeric': 0.1592852779474649, 'fraction_numerical': 0.004581551618814905, 'mean_word_length': 4.033820138355112, 'pattern_counts': {'":': 0, '<': 51, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5301427', 'n_tokens_mistral': 2576, 'n_tokens_neox': 2366, 'n_words': 448}