#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 HAVE_LLVM >= 0x0400
+#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>
-#else
-#include <llvm/PassManager.h>
-#include <llvm/Target/TargetLibraryInfo.h>
-#include <llvm/Target/TargetSubtargetInfo.h>
-#include <llvm/Support/FormattedStream.h>
-#endif
#include <clang/Basic/TargetInfo.h>
-#include <clang/Frontend/CodeGenOptions.h>
#include <clang/Frontend/CompilerInstance.h>
+#if LLVM_VERSION_MAJOR >= 8
+#include <clang/Basic/CodeGenOptions.h>
+#else
+#include <clang/Frontend/CodeGenOptions.h>
+#endif
+
+#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
+ const auto CGFT_ObjectFile = ::llvm::TargetMachine::CGFT_ObjectFile;
+ const auto CGFT_AssemblyFile =
+ ::llvm::TargetMachine::CGFT_AssemblyFile;
+ typedef ::llvm::TargetMachine::CodeGenFileType CodeGenFileType;
+#endif
+
+ 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
- typedef ::llvm::TargetLibraryInfo target_library_info;
+ return map[lang_as - clang::LangAS::Offset];
#endif
+ }
-#if HAVE_LLVM >= 0x0500
- const auto lang_as_offset = 0;
+#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
- const auto lang_as_offset = clang::LangAS::Offset;
const clang::InputKind ik_opencl = clang::IK_OpenCL;
#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);
+#if LLVM_VERSION_MAJOR >= 5
+ const clang::LangStandard::Kind lang_opencl10 = clang::LangStandard::lang_opencl10;
#else
- inv.setLangDefaults(lopts, ik, std);
+ const clang::LangStandard::Kind lang_opencl10 = clang::LangStandard::lang_opencl;
#endif
- }
inline void
add_link_bitcode_file(clang::CodeGenOptions &opts,
const std::string &path) {
-#if HAVE_LLVM >= 0x0500
+#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);
-#elif HAVE_LLVM >= 0x0308
- opts.LinkBitcodeFiles.emplace_back(::llvm::Linker::Flags::None, path);
#else
- opts.LinkBitcodeFile = path;
+ opts.LinkBitcodeFiles.emplace_back(::llvm::Linker::Flags::None, path);
#endif
}
-#if HAVE_LLVM >= 0x0307
- typedef ::llvm::legacy::PassManager pass_manager;
+#if LLVM_VERSION_MAJOR >= 6
+ const auto default_code_model = ::llvm::None;
#else
- typedef ::llvm::PassManager pass_manager;
-#endif
-
- inline void
- add_data_layout_pass(pass_manager &pm) {
-#if HAVE_LLVM < 0x0307
- pm.add(new ::llvm::DataLayoutPass());
-#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))));
+ const auto default_code_model = ::llvm::CodeModel::Default;
#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 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
- return std::unique_ptr< ::llvm::Linker>(new ::llvm::Linker(&mod));
+ if (!mod)
+ f(mod.getError().message());
#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));
+ 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 linker.linkInModule(mod.get());
+ ctx.setDiagnosticHandler(diagnostic_handler, data);
#endif
}
-#if HAVE_LLVM >= 0x0307
- typedef ::llvm::raw_svector_ostream &raw_ostream_to_emit_file;
-#else
- typedef ::llvm::formatted_raw_ostream raw_ostream_to_emit_file;
-#endif
-
-#if HAVE_LLVM >= 0x0307
- typedef ::llvm::DataLayout data_layout;
+ inline std::unique_ptr< ::llvm::Module>
+ clone_module(const ::llvm::Module &mod)
+ {
+#if LLVM_VERSION_MAJOR >= 7
+ return ::llvm::CloneModule(mod);
#else
- typedef const ::llvm::DataLayout *data_layout;
+ return ::llvm::CloneModule(&mod);
#endif
+ }
- inline data_layout
- get_data_layout(::llvm::TargetMachine &tm) {
-#if HAVE_LLVM >= 0x0307
- return tm.createDataLayout();
+ template<typename T> void
+ write_bitcode_to_file(const ::llvm::Module &mod, T &os)
+ {
+#if LLVM_VERSION_MAJOR >= 7
+ ::llvm::WriteBitcodeToFile(mod, os);
#else
- return tm.getSubtargetImpl()->getDataLayout();
+ ::llvm::WriteBitcodeToFile(&mod, os);
#endif
}
-#if HAVE_LLVM >= 0x0600
- const auto default_code_model = ::llvm::None;
+ 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
- const auto default_code_model = ::llvm::CodeModel::Default;
+ return tm.addPassesToEmitFile(pm, os, ft);
#endif
+ }
-#if HAVE_LLVM >= 0x0309
- const auto default_reloc_model = ::llvm::None;
+ 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
- const auto default_reloc_model = ::llvm::Reloc::Default;
+ return clang::CompilerInvocation::CreateFromArgs(
+ cinv, copts.data(), copts.data() + copts.size(), diag);
#endif
+ }
- template<typename M, typename F> void
- handle_module_error(M &mod, const F &f) {
-#if HAVE_LLVM >= 0x0400
- if (::llvm::Error err = mod.takeError())
- ::llvm::handleAllErrors(std::move(err), [&](::llvm::ErrorInfoBase &eib) {
- f(eib.message());
- });
+ 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
- if (!mod)
- f(mod.getError().message());
+ ::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
}
}