/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/Driver/Types.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- Types.cpp - Driver input & temporary type information ------------===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | |
9 | | #include "clang/Driver/Types.h" |
10 | | #include "llvm/ADT/STLExtras.h" |
11 | | #include "llvm/ADT/StringSwitch.h" |
12 | | #include "llvm/ADT/SmallVector.h" |
13 | | #include <cassert> |
14 | | #include <cstring> |
15 | | |
16 | | using namespace clang::driver; |
17 | | using namespace clang::driver::types; |
18 | | |
19 | | struct TypeInfo { |
20 | | const char *Name; |
21 | | const char *Flags; |
22 | | const char *TempSuffix; |
23 | | ID PreprocessedType; |
24 | | const llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> Phases; |
25 | | }; |
26 | | |
27 | | static const TypeInfo TypeInfos[] = { |
28 | | #define TYPE(NAME, ID, PP_TYPE, TEMP_SUFFIX, FLAGS, ...) \ |
29 | | { NAME, FLAGS, TEMP_SUFFIX, TY_##PP_TYPE, { __VA_ARGS__ }, }, |
30 | | #include "clang/Driver/Types.def" |
31 | | #undef TYPE |
32 | | }; |
33 | | static const unsigned numTypes = llvm::array_lengthof(TypeInfos); |
34 | | |
35 | 341k | static const TypeInfo &getInfo(unsigned id) { |
36 | 341k | assert(id > 0 && id - 1 < numTypes && "Invalid Type ID."); |
37 | 341k | return TypeInfos[id - 1]; |
38 | 341k | } |
39 | | |
40 | 30.3k | const char *types::getTypeName(ID Id) { |
41 | 30.3k | return getInfo(Id).Name; |
42 | 30.3k | } |
43 | | |
44 | 81.7k | types::ID types::getPreprocessedType(ID Id) { |
45 | 81.7k | return getInfo(Id).PreprocessedType; |
46 | 81.7k | } |
47 | | |
48 | 28.1k | types::ID types::getPrecompiledType(ID Id) { |
49 | 28.1k | if (strchr(getInfo(Id).Flags, 'm')) |
50 | 12 | return TY_ModuleFile; |
51 | 28.1k | if (onlyPrecompileType(Id)) |
52 | 135 | return TY_PCH; |
53 | 27.9k | return TY_INVALID; |
54 | 27.9k | } |
55 | | |
56 | 11.2k | const char *types::getTypeTempSuffix(ID Id, bool CLMode) { |
57 | 11.2k | if (CLMode) { |
58 | 751 | switch (Id) { |
59 | 751 | case TY_Object: |
60 | 443 | case TY_LTO_BC: |
61 | 443 | return "obj"; |
62 | 443 | case TY_Image: |
63 | 283 | return "exe"; |
64 | 443 | case TY_PP_Asm: |
65 | 16 | return "asm"; |
66 | 443 | default: |
67 | 9 | break; |
68 | 10.4k | } |
69 | 10.4k | } |
70 | 10.4k | return getInfo(Id).TempSuffix; |
71 | 10.4k | } |
72 | | |
73 | 28.0k | bool types::onlyAssembleType(ID Id) { |
74 | 28.0k | return strchr(getInfo(Id).Flags, 'a'); |
75 | 28.0k | } |
76 | | |
77 | 99.0k | bool types::onlyPrecompileType(ID Id) { |
78 | 99.0k | return strchr(getInfo(Id).Flags, 'p'); |
79 | 99.0k | } |
80 | | |
81 | 9.40k | bool types::canTypeBeUserSpecified(ID Id) { |
82 | 9.40k | return strchr(getInfo(Id).Flags, 'u'); |
83 | 9.40k | } |
84 | | |
85 | 3.57k | bool types::appendSuffixForType(ID Id) { |
86 | 3.57k | return strchr(getInfo(Id).Flags, 'A'); |
87 | 3.57k | } |
88 | | |
89 | 862 | bool types::canLipoType(ID Id) { |
90 | 862 | return (Id == TY_Nothing || |
91 | 862 | Id == TY_Image || |
92 | 862 | Id == TY_Object837 || |
93 | 862 | Id == TY_LTO_BC0 ); |
94 | 862 | } |
95 | | |
96 | 34.5k | bool types::isAcceptedByClang(ID Id) { |
97 | 34.5k | switch (Id) { |
98 | 34.5k | default: |
99 | 4.90k | return false; |
100 | 34.5k | |
101 | 34.5k | case TY_Asm: |
102 | 29.6k | case TY_C: case TY_PP_C: |
103 | 29.6k | case TY_CL: |
104 | 29.6k | case TY_CUDA: case TY_PP_CUDA: |
105 | 29.6k | case TY_CUDA_DEVICE: |
106 | 29.6k | case TY_HIP: |
107 | 29.6k | case TY_PP_HIP: |
108 | 29.6k | case TY_HIP_DEVICE: |
109 | 29.6k | case TY_ObjC: case TY_PP_ObjC: case TY_PP_ObjC_Alias: |
110 | 29.6k | case TY_CXX: case TY_PP_CXX: |
111 | 29.6k | case TY_ObjCXX: case TY_PP_ObjCXX: case TY_PP_ObjCXX_Alias: |
112 | 29.6k | case TY_CHeader: case TY_PP_CHeader: |
113 | 29.6k | case TY_CLHeader: |
114 | 29.6k | case TY_ObjCHeader: case TY_PP_ObjCHeader: |
115 | 29.6k | case TY_CXXHeader: case TY_PP_CXXHeader: |
116 | 29.6k | case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader: |
117 | 29.6k | case TY_CXXModule: case TY_PP_CXXModule: |
118 | 29.6k | case TY_AST: case TY_ModuleFile: |
119 | 29.6k | case TY_LLVM_IR: case TY_LLVM_BC: |
120 | 29.6k | return true; |
121 | 34.5k | } |
122 | 34.5k | } |
123 | | |
124 | 87.4k | bool types::isObjC(ID Id) { |
125 | 87.4k | switch (Id) { |
126 | 87.4k | default: |
127 | 85.2k | return false; |
128 | 87.4k | |
129 | 87.4k | case TY_ObjC: 2.15k case TY_PP_ObjC: 2.15k case TY_PP_ObjC_Alias: |
130 | 2.15k | case TY_ObjCXX: case TY_PP_ObjCXX: |
131 | 2.15k | case TY_ObjCHeader: case TY_PP_ObjCHeader: |
132 | 2.15k | case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader: case TY_PP_ObjCXX_Alias: |
133 | 2.15k | return true; |
134 | 87.4k | } |
135 | 87.4k | } |
136 | | |
137 | 193k | bool types::isCXX(ID Id) { |
138 | 193k | switch (Id) { |
139 | 193k | default: |
140 | 120k | return false; |
141 | 193k | |
142 | 193k | case TY_CXX: 72.6k case TY_PP_CXX: |
143 | 72.6k | case TY_ObjCXX: case TY_PP_ObjCXX: case TY_PP_ObjCXX_Alias: |
144 | 72.6k | case TY_CXXHeader: case TY_PP_CXXHeader: |
145 | 72.6k | case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader: |
146 | 72.6k | case TY_CXXModule: case TY_PP_CXXModule: |
147 | 72.6k | case TY_CUDA: case TY_PP_CUDA: case TY_CUDA_DEVICE: |
148 | 72.6k | case TY_HIP: |
149 | 72.6k | case TY_PP_HIP: |
150 | 72.6k | case TY_HIP_DEVICE: |
151 | 72.6k | return true; |
152 | 193k | } |
153 | 193k | } |
154 | | |
155 | 735 | bool types::isLLVMIR(ID Id) { |
156 | 735 | switch (Id) { |
157 | 735 | default: |
158 | 717 | return false; |
159 | 735 | |
160 | 735 | case TY_LLVM_IR: |
161 | 18 | case TY_LLVM_BC: |
162 | 18 | case TY_LTO_IR: |
163 | 18 | case TY_LTO_BC: |
164 | 18 | return true; |
165 | 735 | } |
166 | 735 | } |
167 | | |
168 | 42.8k | bool types::isCuda(ID Id) { |
169 | 42.8k | switch (Id) { |
170 | 42.8k | default: |
171 | 42.5k | return false; |
172 | 42.8k | |
173 | 42.8k | case TY_CUDA: |
174 | 264 | case TY_PP_CUDA: |
175 | 264 | case TY_CUDA_DEVICE: |
176 | 264 | return true; |
177 | 42.8k | } |
178 | 42.8k | } |
179 | | |
180 | 42.8k | bool types::isHIP(ID Id) { |
181 | 42.8k | switch (Id) { |
182 | 42.8k | default: |
183 | 42.7k | return false; |
184 | 42.8k | |
185 | 42.8k | case TY_HIP: |
186 | 28 | case TY_PP_HIP: |
187 | 28 | case TY_HIP_DEVICE: |
188 | 28 | return true; |
189 | 42.8k | } |
190 | 42.8k | } |
191 | | |
192 | 123 | bool types::isSrcFile(ID Id) { |
193 | 123 | return Id != TY_Object && getPreprocessedType(Id) != TY_INVALID110 ; |
194 | 123 | } |
195 | | |
196 | 49.4k | types::ID types::lookupTypeForExtension(llvm::StringRef Ext) { |
197 | 49.4k | return llvm::StringSwitch<types::ID>(Ext) |
198 | 49.4k | .Case("c", TY_C) |
199 | 49.4k | .Case("C", TY_CXX) |
200 | 49.4k | .Case("F", TY_Fortran) |
201 | 49.4k | .Case("f", TY_PP_Fortran) |
202 | 49.4k | .Case("h", TY_CHeader) |
203 | 49.4k | .Case("H", TY_CXXHeader) |
204 | 49.4k | .Case("i", TY_PP_C) |
205 | 49.4k | .Case("m", TY_ObjC) |
206 | 49.4k | .Case("M", TY_ObjCXX) |
207 | 49.4k | .Case("o", TY_Object) |
208 | 49.4k | .Case("S", TY_Asm) |
209 | 49.4k | .Case("s", TY_PP_Asm) |
210 | 49.4k | .Case("bc", TY_LLVM_BC) |
211 | 49.4k | .Case("cc", TY_CXX) |
212 | 49.4k | .Case("CC", TY_CXX) |
213 | 49.4k | .Case("cl", TY_CL) |
214 | 49.4k | .Case("cp", TY_CXX) |
215 | 49.4k | .Case("cu", TY_CUDA) |
216 | 49.4k | .Case("hh", TY_CXXHeader) |
217 | 49.4k | .Case("ii", TY_PP_CXX) |
218 | 49.4k | .Case("ll", TY_LLVM_IR) |
219 | 49.4k | .Case("mi", TY_PP_ObjC) |
220 | 49.4k | .Case("mm", TY_ObjCXX) |
221 | 49.4k | .Case("rs", TY_RenderScript) |
222 | 49.4k | .Case("adb", TY_Ada) |
223 | 49.4k | .Case("ads", TY_Ada) |
224 | 49.4k | .Case("asm", TY_PP_Asm) |
225 | 49.4k | .Case("ast", TY_AST) |
226 | 49.4k | .Case("ccm", TY_CXXModule) |
227 | 49.4k | .Case("cpp", TY_CXX) |
228 | 49.4k | .Case("CPP", TY_CXX) |
229 | 49.4k | .Case("c++", TY_CXX) |
230 | 49.4k | .Case("C++", TY_CXX) |
231 | 49.4k | .Case("cui", TY_PP_CUDA) |
232 | 49.4k | .Case("cxx", TY_CXX) |
233 | 49.4k | .Case("CXX", TY_CXX) |
234 | 49.4k | .Case("F90", TY_Fortran) |
235 | 49.4k | .Case("f90", TY_PP_Fortran) |
236 | 49.4k | .Case("F95", TY_Fortran) |
237 | 49.4k | .Case("f95", TY_PP_Fortran) |
238 | 49.4k | .Case("for", TY_PP_Fortran) |
239 | 49.4k | .Case("FOR", TY_PP_Fortran) |
240 | 49.4k | .Case("fpp", TY_Fortran) |
241 | 49.4k | .Case("FPP", TY_Fortran) |
242 | 49.4k | .Case("gch", TY_PCH) |
243 | 49.4k | .Case("hip", TY_HIP) |
244 | 49.4k | .Case("hpp", TY_CXXHeader) |
245 | 49.4k | .Case("iim", TY_PP_CXXModule) |
246 | 49.4k | .Case("lib", TY_Object) |
247 | 49.4k | .Case("mii", TY_PP_ObjCXX) |
248 | 49.4k | .Case("obj", TY_Object) |
249 | 49.4k | .Case("pch", TY_PCH) |
250 | 49.4k | .Case("pcm", TY_ModuleFile) |
251 | 49.4k | .Case("c++m", TY_CXXModule) |
252 | 49.4k | .Case("cppm", TY_CXXModule) |
253 | 49.4k | .Case("cxxm", TY_CXXModule) |
254 | 49.4k | .Default(TY_INVALID); |
255 | 49.4k | } |
256 | | |
257 | 1.25k | types::ID types::lookupTypeForTypeSpecifier(const char *Name) { |
258 | 9.14k | for (unsigned i=0; i<numTypes; ++i7.88k ) { |
259 | 9.14k | types::ID Id = (types::ID) (i + 1); |
260 | 9.14k | if (canTypeBeUserSpecified(Id) && |
261 | 9.14k | strcmp(Name, getInfo(Id).Name) == 07.88k ) |
262 | 1.25k | return Id; |
263 | 9.14k | } |
264 | 1.25k | |
265 | 1.25k | return TY_INVALID0 ; |
266 | 1.25k | } |
267 | | |
268 | | // FIXME: Why don't we just put this list in the defs file, eh. |
269 | | // FIXME: The list is now in Types.def but for now this function will verify |
270 | | // the old behavior and a subsequent change will delete most of the body. |
271 | 42.8k | void types::getCompilationPhases(ID Id, llvm::SmallVectorImpl<phases::ID> &P) { |
272 | 42.8k | if (Id != TY_Object) { |
273 | 28.0k | if (getPreprocessedType(Id) != TY_INVALID) { |
274 | 23.6k | P.push_back(phases::Preprocess); |
275 | 23.6k | } |
276 | 28.0k | |
277 | 28.0k | if (getPrecompiledType(Id) != TY_INVALID) { |
278 | 71 | P.push_back(phases::Precompile); |
279 | 71 | } |
280 | 28.0k | |
281 | 28.0k | if (!onlyPrecompileType(Id)) { |
282 | 27.9k | if (!onlyAssembleType(Id)) { |
283 | 27.0k | P.push_back(phases::Compile); |
284 | 27.0k | P.push_back(phases::Backend); |
285 | 27.0k | } |
286 | 27.9k | P.push_back(phases::Assemble); |
287 | 27.9k | } |
288 | 28.0k | } |
289 | 42.8k | |
290 | 42.8k | if (!onlyPrecompileType(Id)) { |
291 | 42.7k | P.push_back(phases::Link); |
292 | 42.7k | } |
293 | 42.8k | |
294 | 42.8k | // Check that the static Phase list matches. |
295 | 42.8k | // TODO: These will be deleted. |
296 | 42.8k | const llvm::SmallVectorImpl<phases::ID> &Phases = getInfo(Id).Phases; |
297 | 42.8k | assert(Phases.size() == P.size() && |
298 | 42.8k | std::equal(Phases.begin(), Phases.end(), P.begin()) && |
299 | 42.8k | "Invalid phase or size"); |
300 | 42.8k | |
301 | 42.8k | // TODO: This function is still being used to assert that the phase list in |
302 | 42.8k | // Types.def is correct. Everything above this comment will be removed |
303 | 42.8k | // in a subsequent NFC commit. |
304 | 42.8k | P = Phases; |
305 | 42.8k | assert(0 < P.size() && "Not enough phases in list"); |
306 | 42.8k | assert(P.size() <= phases::MaxNumberOfPhases && "Too many phases in list"); |
307 | 42.8k | } |
308 | | |
309 | 13.7k | ID types::lookupCXXTypeForCType(ID Id) { |
310 | 13.7k | switch (Id) { |
311 | 13.7k | default: |
312 | 13.6k | return Id; |
313 | 13.7k | |
314 | 13.7k | case types::TY_C: |
315 | 56 | return types::TY_CXX; |
316 | 13.7k | case types::TY_PP_C: |
317 | 0 | return types::TY_PP_CXX; |
318 | 13.7k | case types::TY_CHeader: |
319 | 0 | return types::TY_CXXHeader; |
320 | 13.7k | case types::TY_PP_CHeader: |
321 | 0 | return types::TY_PP_CXXHeader; |
322 | 13.7k | } |
323 | 13.7k | } |
324 | | |
325 | 25 | ID types::lookupHeaderTypeForSourceType(ID Id) { |
326 | 25 | switch (Id) { |
327 | 25 | default: |
328 | 0 | return Id; |
329 | 25 | |
330 | 25 | // FIXME: Handle preprocessed input types. |
331 | 25 | case types::TY_C: |
332 | 3 | return types::TY_CHeader; |
333 | 25 | case types::TY_CXX: |
334 | 22 | case types::TY_CXXModule: |
335 | 22 | return types::TY_CXXHeader; |
336 | 22 | case types::TY_ObjC: |
337 | 0 | return types::TY_ObjCHeader; |
338 | 22 | case types::TY_ObjCXX: |
339 | 0 | return types::TY_ObjCXXHeader; |
340 | 22 | case types::TY_CL: |
341 | 0 | return types::TY_CLHeader; |
342 | 25 | } |
343 | 25 | } |