#include "util/algorithm.hpp"
+#include <llvm/Config/llvm-config.h>
+#if LLVM_VERSION_MAJOR < 4
+#include <llvm/Bitcode/ReaderWriter.h>
+#else
+#include <llvm/Bitcode/BitcodeReader.h>
+#include <llvm/Bitcode/BitcodeWriter.h>
+#endif
+
+#include <llvm/IR/LLVMContext.h>
#include <llvm/Linker/Linker.h>
#include <llvm/Transforms/IPO.h>
+#include <llvm/Transforms/Utils/Cloning.h>
#include <llvm/Target/TargetMachine.h>
+#if LLVM_VERSION_MAJOR >= 4
+#include <llvm/Support/Error.h>
+#else
+#include <llvm/Support/ErrorOr.h>
+#endif
-#if HAVE_LLVM >= 0x0307
#include <llvm/IR/LegacyPassManager.h>
#include <llvm/Analysis/TargetLibraryInfo.h>
+
+#include <clang/Basic/TargetInfo.h>
+#include <clang/Frontend/CompilerInstance.h>
+
+#if LLVM_VERSION_MAJOR >= 8
+#include <clang/Basic/CodeGenOptions.h>
#else
-#include <llvm/PassManager.h>
-#include <llvm/Target/TargetLibraryInfo.h>
-#include <llvm/Target/TargetSubtargetInfo.h>
-#include <llvm/Support/FormattedStream.h>
+#include <clang/Frontend/CodeGenOptions.h>
#endif
-#include <clang/Frontend/CodeGenOptions.h>
-#include <clang/Frontend/CompilerInstance.h>
+#if LLVM_VERSION_MAJOR >= 10
+#include <llvm/Support/CodeGen.h>
+#endif
namespace clover {
namespace llvm {
namespace compat {
-#if HAVE_LLVM >= 0x0307
- typedef ::llvm::TargetLibraryInfoImpl target_library_info;
+
+#if LLVM_VERSION_MAJOR >= 10
+ const auto CGFT_ObjectFile = ::llvm::CGFT_ObjectFile;
+ const auto CGFT_AssemblyFile = ::llvm::CGFT_AssemblyFile;
+ typedef ::llvm::CodeGenFileType CodeGenFileType;
#else
- typedef ::llvm::TargetLibraryInfo target_library_info;
+ const auto CGFT_ObjectFile = ::llvm::TargetMachine::CGFT_ObjectFile;
+ const auto CGFT_AssemblyFile =
+ ::llvm::TargetMachine::CGFT_AssemblyFile;
+ typedef ::llvm::TargetMachine::CodeGenFileType CodeGenFileType;
#endif
- inline void
- set_lang_defaults(clang::CompilerInvocation &inv,
- clang::LangOptions &lopts, clang::InputKind ik,
- const ::llvm::Triple &t,
- clang::PreprocessorOptions &ppopts,
- clang::LangStandard::Kind std) {
-#if HAVE_LLVM >= 0x0309
- inv.setLangDefaults(lopts, ik, t, ppopts, std);
+ template<typename T, typename AS>
+ unsigned target_address_space(const T &target, const AS lang_as) {
+ const auto &map = target.getAddressSpaceMap();
+#if LLVM_VERSION_MAJOR >= 5
+ return map[static_cast<unsigned>(lang_as)];
#else
- inv.setLangDefaults(lopts, ik, std);
+ return map[lang_as - clang::LangAS::Offset];
#endif
}
- inline void
- add_link_bitcode_file(clang::CodeGenOptions &opts,
- const std::string &path) {
-#if HAVE_LLVM >= 0x0308
- opts.LinkBitcodeFiles.emplace_back(::llvm::Linker::Flags::None, path);
+#if LLVM_VERSION_MAJOR >= 10
+ const clang::InputKind ik_opencl = clang::Language::OpenCL;
+#elif LLVM_VERSION_MAJOR >= 5
+ const clang::InputKind ik_opencl = clang::InputKind::OpenCL;
#else
- opts.LinkBitcodeFile = path;
+ const clang::InputKind ik_opencl = clang::IK_OpenCL;
#endif
- }
-#if HAVE_LLVM >= 0x0307
- typedef ::llvm::legacy::PassManager pass_manager;
+#if LLVM_VERSION_MAJOR >= 5
+ const clang::LangStandard::Kind lang_opencl10 = clang::LangStandard::lang_opencl10;
#else
- typedef ::llvm::PassManager pass_manager;
+ const clang::LangStandard::Kind lang_opencl10 = clang::LangStandard::lang_opencl;
#endif
inline void
- add_data_layout_pass(pass_manager &pm) {
-#if HAVE_LLVM < 0x0307
- pm.add(new ::llvm::DataLayoutPass());
+ add_link_bitcode_file(clang::CodeGenOptions &opts,
+ const std::string &path) {
+#if LLVM_VERSION_MAJOR >= 5
+ clang::CodeGenOptions::BitcodeFileToLink F;
+
+ F.Filename = path;
+ F.PropagateAttrs = true;
+ F.LinkFlags = ::llvm::Linker::Flags::None;
+ opts.LinkBitcodeFiles.emplace_back(F);
+#else
+ opts.LinkBitcodeFiles.emplace_back(::llvm::Linker::Flags::None, path);
#endif
}
- inline void
- add_internalize_pass(pass_manager &pm,
- const std::vector<std::string> &names) {
-#if HAVE_LLVM >= 0x0309
- pm.add(::llvm::createInternalizePass(
- [=](const ::llvm::GlobalValue &gv) {
- return std::find(names.begin(), names.end(),
- gv.getName()) != names.end();
- }));
-#else
- pm.add(::llvm::createInternalizePass(std::vector<const char *>(
- map(std::mem_fn(&std::string::data), names))));
+#if LLVM_VERSION_MAJOR >= 6
+ const auto default_code_model = ::llvm::None;
+#else
+ const auto default_code_model = ::llvm::CodeModel::Default;
+#endif
+
+ template<typename M, typename F> void
+ handle_module_error(M &mod, const F &f) {
+#if LLVM_VERSION_MAJOR >= 4
+ if (::llvm::Error err = mod.takeError())
+ ::llvm::handleAllErrors(std::move(err), [&](::llvm::ErrorInfoBase &eib) {
+ f(eib.message());
+ });
+#else
+ if (!mod)
+ f(mod.getError().message());
#endif
}
- inline std::unique_ptr<::llvm::Linker>
- create_linker(::llvm::Module &mod) {
-#if HAVE_LLVM >= 0x0308
- return std::unique_ptr<::llvm::Linker>(new ::llvm::Linker(mod));
+ template<typename T> void
+ set_diagnostic_handler(::llvm::LLVMContext &ctx,
+ T *diagnostic_handler, void *data) {
+#if LLVM_VERSION_MAJOR >= 6
+ ctx.setDiagnosticHandlerCallBack(diagnostic_handler, data);
#else
- return std::unique_ptr<::llvm::Linker>(new ::llvm::Linker(&mod));
+ ctx.setDiagnosticHandler(diagnostic_handler, data);
#endif
}
- inline bool
- link_in_module(::llvm::Linker &linker,
- std::unique_ptr<::llvm::Module> mod) {
-#if HAVE_LLVM >= 0x0308
- return linker.linkInModule(std::move(mod));
+ inline std::unique_ptr< ::llvm::Module>
+ clone_module(const ::llvm::Module &mod)
+ {
+#if LLVM_VERSION_MAJOR >= 7
+ return ::llvm::CloneModule(mod);
#else
- return linker.linkInModule(mod.get());
+ return ::llvm::CloneModule(&mod);
#endif
}
-#if HAVE_LLVM >= 0x0307
- typedef ::llvm::raw_svector_ostream &raw_ostream_to_emit_file;
+ template<typename T> void
+ write_bitcode_to_file(const ::llvm::Module &mod, T &os)
+ {
+#if LLVM_VERSION_MAJOR >= 7
+ ::llvm::WriteBitcodeToFile(mod, os);
#else
- typedef ::llvm::formatted_raw_ostream raw_ostream_to_emit_file;
+ ::llvm::WriteBitcodeToFile(&mod, os);
#endif
+ }
-#if HAVE_LLVM >= 0x0307
- typedef ::llvm::DataLayout data_layout;
+ template<typename TM, typename PM, typename OS, typename FT>
+ bool add_passes_to_emit_file(TM &tm, PM &pm, OS &os, FT &ft)
+ {
+#if LLVM_VERSION_MAJOR >= 7
+ return tm.addPassesToEmitFile(pm, os, nullptr, ft);
#else
- typedef const ::llvm::DataLayout *data_layout;
+ return tm.addPassesToEmitFile(pm, os, ft);
#endif
+ }
- inline data_layout
- get_data_layout(::llvm::TargetMachine &tm) {
-#if HAVE_LLVM >= 0x0307
- return tm.createDataLayout();
+ template<typename T> inline bool
+ create_compiler_invocation_from_args(clang::CompilerInvocation &cinv,
+ T copts,
+ clang::DiagnosticsEngine &diag)
+ {
+#if LLVM_VERSION_MAJOR >= 10
+ return clang::CompilerInvocation::CreateFromArgs(
+ cinv, copts, diag);
#else
- return tm.getSubtargetImpl()->getDataLayout();
+ return clang::CompilerInvocation::CreateFromArgs(
+ cinv, copts.data(), copts.data() + copts.size(), diag);
#endif
}
-#if HAVE_LLVM >= 0x0309
- const auto default_reloc_model = ::llvm::None;
+ template<typename T, typename M>
+ T get_abi_type(const T &arg_type, const M &mod) {
+#if LLVM_VERSION_MAJOR >= 7
+ return arg_type;
#else
- const auto default_reloc_model = ::llvm::Reloc::Default;
+ ::llvm::DataLayout dl(&mod);
+ const unsigned arg_store_size = dl.getTypeStoreSize(arg_type);
+ return !arg_type->isIntegerTy() ? arg_type :
+ dl.getSmallestLegalIntType(mod.getContext(), arg_store_size * 8);
#endif
+ }
}
}
}