1 //
2 // Copyright 2016 Francisco Jerez
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a
5 // copy of this software and associated documentation files (the "Software"),
6 // to deal in the Software without restriction, including without limitation
7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 // and/or sell copies of the Software, and to permit persons to whom the
9 // Software is furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 // OTHER DEALINGS IN THE SOFTWARE.
21 //
22 
23 ///
24 /// \file
25 /// Some thin wrappers around the Clang/LLVM API used to preserve
26 /// compatibility with older API versions while keeping the ifdef clutter low
27 /// in the rest of the clover::llvm subtree.  In case of an API break please
28 /// consider whether it's possible to preserve backwards compatibility by
29 /// introducing a new one-liner inline function or typedef here under the
30 /// compat namespace in order to keep the running code free from preprocessor
31 /// conditionals.
32 ///
33 
34 #ifndef CLOVER_LLVM_COMPAT_HPP
35 #define CLOVER_LLVM_COMPAT_HPP
36 
37 #include "util/algorithm.hpp"
38 
39 #include <llvm/Config/llvm-config.h>
40 
41 #include <llvm/ADT/Triple.h>
42 #include <llvm/Analysis/TargetLibraryInfo.h>
43 #include <llvm/IR/LegacyPassManager.h>
44 #include <llvm/IR/LLVMContext.h>
45 #include <llvm/IR/Type.h>
46 #include <llvm/Linker/Linker.h>
47 #include <llvm/Target/TargetMachine.h>
48 #include <llvm/Transforms/IPO.h>
49 #include <llvm/Transforms/Utils/Cloning.h>
50 
51 #include <clang/Basic/TargetInfo.h>
52 #include <clang/Frontend/CompilerInstance.h>
53 #include <clang/Lex/PreprocessorOptions.h>
54 
55 #if LLVM_VERSION_MAJOR >= 10
56 #include <llvm/Support/CodeGen.h>
57 #endif
58 
59 #if LLVM_VERSION_MAJOR >= 14
60 #include <llvm/MC/TargetRegistry.h>
61 #else
62 #include <llvm/Support/TargetRegistry.h>
63 #endif
64 
65 namespace clover {
66    namespace llvm {
67       namespace compat {
68 
69 #if LLVM_VERSION_MAJOR >= 10
70          const auto CGFT_ObjectFile = ::llvm::CGFT_ObjectFile;
71          const auto CGFT_AssemblyFile = ::llvm::CGFT_AssemblyFile;
72          typedef ::llvm::CodeGenFileType CodeGenFileType;
73 #else
74          const auto CGFT_ObjectFile = ::llvm::TargetMachine::CGFT_ObjectFile;
75          const auto CGFT_AssemblyFile =
76             ::llvm::TargetMachine::CGFT_AssemblyFile;
77          typedef ::llvm::TargetMachine::CodeGenFileType CodeGenFileType;
78 #endif
79 
80 #if LLVM_VERSION_MAJOR >= 10
81          const clang::InputKind ik_opencl = clang::Language::OpenCL;
82 #else
83          const clang::InputKind ik_opencl = clang::InputKind::OpenCL;
84 #endif
85 
86          template<typename T> inline bool
create_compiler_invocation_from_args(clang::CompilerInvocation & cinv,T copts,clang::DiagnosticsEngine & diag)87          create_compiler_invocation_from_args(clang::CompilerInvocation &cinv,
88                                               T copts,
89                                               clang::DiagnosticsEngine &diag)
90          {
91 #if LLVM_VERSION_MAJOR >= 10
92             return clang::CompilerInvocation::CreateFromArgs(
93                cinv, copts, diag);
94 #else
95             return clang::CompilerInvocation::CreateFromArgs(
96                cinv, copts.data(), copts.data() + copts.size(), diag);
97 #endif
98          }
99 
100          static inline void
compiler_set_lang_defaults(std::unique_ptr<clang::CompilerInstance> & c,clang::InputKind ik,const::llvm::Triple & triple,clang::LangStandard::Kind d)101          compiler_set_lang_defaults(std::unique_ptr<clang::CompilerInstance> &c,
102                                     clang::InputKind ik, const ::llvm::Triple& triple,
103                                     clang::LangStandard::Kind d)
104          {
105             c->getInvocation().setLangDefaults(c->getLangOpts(), ik, triple,
106 #if LLVM_VERSION_MAJOR >= 12
107                                                c->getPreprocessorOpts().Includes,
108 #else
109                                                c->getPreprocessorOpts(),
110 #endif
111                                                d);
112          }
113 
114          static inline bool
is_scalable_vector(const::llvm::Type * type)115          is_scalable_vector(const ::llvm::Type *type)
116          {
117 #if LLVM_VERSION_MAJOR >= 11
118             return ::llvm::isa<::llvm::ScalableVectorType>(type);
119 #else
120             return false;
121 #endif
122          }
123 
124          static inline bool
is_fixed_vector(const::llvm::Type * type)125          is_fixed_vector(const ::llvm::Type *type)
126          {
127 #if LLVM_VERSION_MAJOR >= 11
128             return ::llvm::isa<::llvm::FixedVectorType>(type);
129 #else
130             return type->isVectorTy();
131 #endif
132          }
133 
134          static inline unsigned
get_fixed_vector_elements(const::llvm::Type * type)135          get_fixed_vector_elements(const ::llvm::Type *type)
136          {
137 #if LLVM_VERSION_MAJOR >= 11
138             return ::llvm::cast<::llvm::FixedVectorType>(type)->getNumElements();
139 #else
140             return ((::llvm::VectorType*)type)->getNumElements();
141 #endif
142          }
143       }
144    }
145 }
146 
147 #endif
148