1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | #include "clang/Driver/Types.h" |
10 | #include "llvm/ADT/STLExtras.h" |
11 | #include "llvm/ADT/StringSwitch.h" |
12 | #include <cassert> |
13 | #include <string.h> |
14 | |
15 | using namespace clang::driver; |
16 | using namespace clang::driver::types; |
17 | |
18 | struct TypeInfo { |
19 | const char *Name; |
20 | const char *Flags; |
21 | const char *TempSuffix; |
22 | ID PreprocessedType; |
23 | }; |
24 | |
25 | static const TypeInfo TypeInfos[] = { |
26 | #define TYPE(NAME, ID, PP_TYPE, TEMP_SUFFIX, FLAGS) \ |
27 | { NAME, FLAGS, TEMP_SUFFIX, TY_##PP_TYPE, }, |
28 | #include "clang/Driver/Types.def" |
29 | #undef TYPE |
30 | }; |
31 | static const unsigned numTypes = llvm::array_lengthof(TypeInfos); |
32 | |
33 | static const TypeInfo &getInfo(unsigned id) { |
34 | (0) . __assert_fail ("id > 0 && id - 1 < numTypes && \"Invalid Type ID.\"", "/home/seafit/code_projects/clang_source/clang/lib/Driver/Types.cpp", 34, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(id > 0 && id - 1 < numTypes && "Invalid Type ID."); |
35 | return TypeInfos[id - 1]; |
36 | } |
37 | |
38 | const char *types::getTypeName(ID Id) { |
39 | return getInfo(Id).Name; |
40 | } |
41 | |
42 | types::ID types::getPreprocessedType(ID Id) { |
43 | return getInfo(Id).PreprocessedType; |
44 | } |
45 | |
46 | types::ID types::getPrecompiledType(ID Id) { |
47 | if (strchr(getInfo(Id).Flags, 'm')) |
48 | return TY_ModuleFile; |
49 | if (onlyPrecompileType(Id)) |
50 | return TY_PCH; |
51 | return TY_INVALID; |
52 | } |
53 | |
54 | const char *types::getTypeTempSuffix(ID Id, bool CLMode) { |
55 | if (CLMode) { |
56 | switch (Id) { |
57 | case TY_Object: |
58 | case TY_LTO_BC: |
59 | return "obj"; |
60 | case TY_Image: |
61 | return "exe"; |
62 | case TY_PP_Asm: |
63 | return "asm"; |
64 | default: |
65 | break; |
66 | } |
67 | } |
68 | return getInfo(Id).TempSuffix; |
69 | } |
70 | |
71 | bool types::onlyAssembleType(ID Id) { |
72 | return strchr(getInfo(Id).Flags, 'a'); |
73 | } |
74 | |
75 | bool types::onlyPrecompileType(ID Id) { |
76 | return strchr(getInfo(Id).Flags, 'p'); |
77 | } |
78 | |
79 | bool types::canTypeBeUserSpecified(ID Id) { |
80 | return strchr(getInfo(Id).Flags, 'u'); |
81 | } |
82 | |
83 | bool types::appendSuffixForType(ID Id) { |
84 | return strchr(getInfo(Id).Flags, 'A'); |
85 | } |
86 | |
87 | bool types::canLipoType(ID Id) { |
88 | return (Id == TY_Nothing || |
89 | Id == TY_Image || |
90 | Id == TY_Object || |
91 | Id == TY_LTO_BC); |
92 | } |
93 | |
94 | bool types::isAcceptedByClang(ID Id) { |
95 | switch (Id) { |
96 | default: |
97 | return false; |
98 | |
99 | case TY_Asm: |
100 | case TY_C: case TY_PP_C: |
101 | case TY_CL: |
102 | case TY_CUDA: case TY_PP_CUDA: |
103 | case TY_CUDA_DEVICE: |
104 | case TY_HIP: |
105 | case TY_PP_HIP: |
106 | case TY_HIP_DEVICE: |
107 | case TY_ObjC: case TY_PP_ObjC: case TY_PP_ObjC_Alias: |
108 | case TY_CXX: case TY_PP_CXX: |
109 | case TY_ObjCXX: case TY_PP_ObjCXX: case TY_PP_ObjCXX_Alias: |
110 | case TY_CHeader: case TY_PP_CHeader: |
111 | case TY_CLHeader: |
112 | case TY_ObjCHeader: case TY_PP_ObjCHeader: |
113 | case TY_CXXHeader: case TY_PP_CXXHeader: |
114 | case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader: |
115 | case TY_CXXModule: case TY_PP_CXXModule: |
116 | case TY_AST: case TY_ModuleFile: |
117 | case TY_LLVM_IR: case TY_LLVM_BC: |
118 | return true; |
119 | } |
120 | } |
121 | |
122 | bool types::isObjC(ID Id) { |
123 | switch (Id) { |
124 | default: |
125 | return false; |
126 | |
127 | case TY_ObjC: case TY_PP_ObjC: case TY_PP_ObjC_Alias: |
128 | case TY_ObjCXX: case TY_PP_ObjCXX: |
129 | case TY_ObjCHeader: case TY_PP_ObjCHeader: |
130 | case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader: case TY_PP_ObjCXX_Alias: |
131 | return true; |
132 | } |
133 | } |
134 | |
135 | bool types::isCXX(ID Id) { |
136 | switch (Id) { |
137 | default: |
138 | return false; |
139 | |
140 | case TY_CXX: case TY_PP_CXX: |
141 | case TY_ObjCXX: case TY_PP_ObjCXX: case TY_PP_ObjCXX_Alias: |
142 | case TY_CXXHeader: case TY_PP_CXXHeader: |
143 | case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader: |
144 | case TY_CXXModule: case TY_PP_CXXModule: |
145 | case TY_CUDA: case TY_PP_CUDA: case TY_CUDA_DEVICE: |
146 | case TY_HIP: |
147 | case TY_PP_HIP: |
148 | case TY_HIP_DEVICE: |
149 | return true; |
150 | } |
151 | } |
152 | |
153 | bool types::isLLVMIR(ID Id) { |
154 | switch (Id) { |
155 | default: |
156 | return false; |
157 | |
158 | case TY_LLVM_IR: |
159 | case TY_LLVM_BC: |
160 | case TY_LTO_IR: |
161 | case TY_LTO_BC: |
162 | return true; |
163 | } |
164 | } |
165 | |
166 | bool types::isCuda(ID Id) { |
167 | switch (Id) { |
168 | default: |
169 | return false; |
170 | |
171 | case TY_CUDA: |
172 | case TY_PP_CUDA: |
173 | case TY_CUDA_DEVICE: |
174 | return true; |
175 | } |
176 | } |
177 | |
178 | bool types::isHIP(ID Id) { |
179 | switch (Id) { |
180 | default: |
181 | return false; |
182 | |
183 | case TY_HIP: |
184 | case TY_PP_HIP: |
185 | case TY_HIP_DEVICE: |
186 | return true; |
187 | } |
188 | } |
189 | |
190 | bool types::isSrcFile(ID Id) { |
191 | return Id != TY_Object && getPreprocessedType(Id) != TY_INVALID; |
192 | } |
193 | |
194 | types::ID types::lookupTypeForExtension(llvm::StringRef Ext) { |
195 | return llvm::StringSwitch<types::ID>(Ext) |
196 | .Case("c", TY_C) |
197 | .Case("C", TY_CXX) |
198 | .Case("F", TY_Fortran) |
199 | .Case("f", TY_PP_Fortran) |
200 | .Case("h", TY_CHeader) |
201 | .Case("H", TY_CXXHeader) |
202 | .Case("i", TY_PP_C) |
203 | .Case("m", TY_ObjC) |
204 | .Case("M", TY_ObjCXX) |
205 | .Case("o", TY_Object) |
206 | .Case("S", TY_Asm) |
207 | .Case("s", TY_PP_Asm) |
208 | .Case("bc", TY_LLVM_BC) |
209 | .Case("cc", TY_CXX) |
210 | .Case("CC", TY_CXX) |
211 | .Case("cl", TY_CL) |
212 | .Case("cp", TY_CXX) |
213 | .Case("cu", TY_CUDA) |
214 | .Case("hh", TY_CXXHeader) |
215 | .Case("ii", TY_PP_CXX) |
216 | .Case("ll", TY_LLVM_IR) |
217 | .Case("mi", TY_PP_ObjC) |
218 | .Case("mm", TY_ObjCXX) |
219 | .Case("rs", TY_RenderScript) |
220 | .Case("adb", TY_Ada) |
221 | .Case("ads", TY_Ada) |
222 | .Case("asm", TY_PP_Asm) |
223 | .Case("ast", TY_AST) |
224 | .Case("ccm", TY_CXXModule) |
225 | .Case("cpp", TY_CXX) |
226 | .Case("CPP", TY_CXX) |
227 | .Case("c++", TY_CXX) |
228 | .Case("C++", TY_CXX) |
229 | .Case("cui", TY_PP_CUDA) |
230 | .Case("cxx", TY_CXX) |
231 | .Case("CXX", TY_CXX) |
232 | .Case("F90", TY_Fortran) |
233 | .Case("f90", TY_PP_Fortran) |
234 | .Case("F95", TY_Fortran) |
235 | .Case("f95", TY_PP_Fortran) |
236 | .Case("for", TY_PP_Fortran) |
237 | .Case("FOR", TY_PP_Fortran) |
238 | .Case("fpp", TY_Fortran) |
239 | .Case("FPP", TY_Fortran) |
240 | .Case("gch", TY_PCH) |
241 | .Case("hip", TY_HIP) |
242 | .Case("hpp", TY_CXXHeader) |
243 | .Case("iim", TY_PP_CXXModule) |
244 | .Case("lib", TY_Object) |
245 | .Case("mii", TY_PP_ObjCXX) |
246 | .Case("obj", TY_Object) |
247 | .Case("pch", TY_PCH) |
248 | .Case("pcm", TY_ModuleFile) |
249 | .Case("c++m", TY_CXXModule) |
250 | .Case("cppm", TY_CXXModule) |
251 | .Case("cxxm", TY_CXXModule) |
252 | .Default(TY_INVALID); |
253 | } |
254 | |
255 | types::ID types::lookupTypeForTypeSpecifier(const char *Name) { |
256 | for (unsigned i=0; i<numTypes; ++i) { |
257 | types::ID Id = (types::ID) (i + 1); |
258 | if (canTypeBeUserSpecified(Id) && |
259 | strcmp(Name, getInfo(Id).Name) == 0) |
260 | return Id; |
261 | } |
262 | |
263 | return TY_INVALID; |
264 | } |
265 | |
266 | |
267 | void types::getCompilationPhases(ID Id, llvm::SmallVectorImpl<phases::ID> &P) { |
268 | if (Id != TY_Object) { |
269 | if (getPreprocessedType(Id) != TY_INVALID) { |
270 | P.push_back(phases::Preprocess); |
271 | } |
272 | |
273 | if (getPrecompiledType(Id) != TY_INVALID) { |
274 | P.push_back(phases::Precompile); |
275 | } |
276 | |
277 | if (!onlyPrecompileType(Id)) { |
278 | if (!onlyAssembleType(Id)) { |
279 | P.push_back(phases::Compile); |
280 | P.push_back(phases::Backend); |
281 | } |
282 | P.push_back(phases::Assemble); |
283 | } |
284 | } |
285 | |
286 | if (!onlyPrecompileType(Id)) { |
287 | P.push_back(phases::Link); |
288 | } |
289 | (0) . __assert_fail ("0 < P.size() && \"Not enough phases in list\"", "/home/seafit/code_projects/clang_source/clang/lib/Driver/Types.cpp", 289, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(0 < P.size() && "Not enough phases in list"); |
290 | (0) . __assert_fail ("P.size() <= phases..MaxNumberOfPhases && \"Too many phases in list\"", "/home/seafit/code_projects/clang_source/clang/lib/Driver/Types.cpp", 290, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(P.size() <= phases::MaxNumberOfPhases && "Too many phases in list"); |
291 | } |
292 | |
293 | ID types::lookupCXXTypeForCType(ID Id) { |
294 | switch (Id) { |
295 | default: |
296 | return Id; |
297 | |
298 | case types::TY_C: |
299 | return types::TY_CXX; |
300 | case types::TY_PP_C: |
301 | return types::TY_PP_CXX; |
302 | case types::TY_CHeader: |
303 | return types::TY_CXXHeader; |
304 | case types::TY_PP_CHeader: |
305 | return types::TY_PP_CXXHeader; |
306 | } |
307 | } |
308 | |
309 | ID types::(ID Id) { |
310 | switch (Id) { |
311 | default: |
312 | return Id; |
313 | |
314 | |
315 | case types::TY_C: |
316 | return types::TY_CHeader; |
317 | case types::TY_CXX: |
318 | case types::TY_CXXModule: |
319 | return types::TY_CXXHeader; |
320 | case types::TY_ObjC: |
321 | return types::TY_ObjCHeader; |
322 | case types::TY_ObjCXX: |
323 | return types::TY_ObjCXXHeader; |
324 | case types::TY_CL: |
325 | return types::TY_CLHeader; |
326 | } |
327 | } |
328 | |