Clang Project

clang_source_code/lib/Driver/Types.cpp
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 <cassert>
13#include <string.h>
14
15using namespace clang::driver;
16using namespace clang::driver::types;
17
18struct TypeInfo {
19  const char *Name;
20  const char *Flags;
21  const char *TempSuffix;
22  ID PreprocessedType;
23};
24
25static 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};
31static const unsigned numTypes = llvm::array_lengthof(TypeInfos);
32
33static 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
38const char *types::getTypeName(ID Id) {
39  return getInfo(Id).Name;
40}
41
42types::ID types::getPreprocessedType(ID Id) {
43  return getInfo(Id).PreprocessedType;
44}
45
46types::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
54const char *types::getTypeTempSuffix(ID Idbool 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
71bool types::onlyAssembleType(ID Id) {
72  return strchr(getInfo(Id).Flags'a');
73}
74
75bool types::onlyPrecompileType(ID Id) {
76  return strchr(getInfo(Id).Flags'p');
77}
78
79bool types::canTypeBeUserSpecified(ID Id) {
80  return strchr(getInfo(Id).Flags'u');
81}
82
83bool types::appendSuffixForType(ID Id) {
84  return strchr(getInfo(Id).Flags'A');
85}
86
87bool types::canLipoType(ID Id) {
88  return (Id == TY_Nothing ||
89          Id == TY_Image ||
90          Id == TY_Object ||
91          Id == TY_LTO_BC);
92}
93
94bool types::isAcceptedByClang(ID Id) {
95  switch (Id) {
96  default:
97    return false;
98
99  case TY_Asm:
100  case TY_Ccase TY_PP_C:
101  case TY_CL:
102  case TY_CUDAcase 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_ObjCcase TY_PP_ObjCcase TY_PP_ObjC_Alias:
108  case TY_CXXcase TY_PP_CXX:
109  case TY_ObjCXXcase TY_PP_ObjCXXcase TY_PP_ObjCXX_Alias:
110  case TY_CHeadercase TY_PP_CHeader:
111  case TY_CLHeader:
112  case TY_ObjCHeadercase TY_PP_ObjCHeader:
113  case TY_CXXHeadercase TY_PP_CXXHeader:
114  case TY_ObjCXXHeadercase TY_PP_ObjCXXHeader:
115  case TY_CXXModulecase TY_PP_CXXModule:
116  case TY_ASTcase TY_ModuleFile:
117  case TY_LLVM_IRcase TY_LLVM_BC:
118    return true;
119  }
120}
121
122bool types::isObjC(ID Id) {
123  switch (Id) {
124  default:
125    return false;
126
127  case TY_ObjCcase TY_PP_ObjCcase TY_PP_ObjC_Alias:
128  case TY_ObjCXXcase TY_PP_ObjCXX:
129  case TY_ObjCHeadercase TY_PP_ObjCHeader:
130  case TY_ObjCXXHeadercase TY_PP_ObjCXXHeadercase TY_PP_ObjCXX_Alias:
131    return true;
132  }
133}
134
135bool types::isCXX(ID Id) {
136  switch (Id) {
137  default:
138    return false;
139
140  case TY_CXXcase TY_PP_CXX:
141  case TY_ObjCXXcase TY_PP_ObjCXXcase TY_PP_ObjCXX_Alias:
142  case TY_CXXHeadercase TY_PP_CXXHeader:
143  case TY_ObjCXXHeadercase TY_PP_ObjCXXHeader:
144  case TY_CXXModulecase TY_PP_CXXModule:
145  case TY_CUDAcase TY_PP_CUDAcase TY_CUDA_DEVICE:
146  case TY_HIP:
147  case TY_PP_HIP:
148  case TY_HIP_DEVICE:
149    return true;
150  }
151}
152
153bool 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
166bool 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
178bool 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
190bool types::isSrcFile(ID Id) {
191  return Id != TY_Object && getPreprocessedType(Id) != TY_INVALID;
192}
193
194types::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
255types::ID types::lookupTypeForTypeSpecifier(const char *Name) {
256  for (unsigned i=0i<numTypes; ++i) {
257    types::ID Id = (types::ID) (i + 1);
258    if (canTypeBeUserSpecified(Id) &&
259        strcmp(NamegetInfo(Id).Name) == 0)
260      return Id;
261  }
262
263  return TY_INVALID;
264}
265
266// FIXME: Why don't we just put this list in the defs file, eh.
267void 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
293ID 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
309ID types::lookupHeaderTypeForSourceType(ID Id) {
310  switch (Id) {
311  default:
312    return Id;
313
314  // FIXME: Handle preprocessed input types.
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