Types.cpp revision 3fdcc6fb12d7cf38d2a3111736f80f0dd55447b4
1//===--- Types.cpp - Driver input & temporary type information ------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "clang/Driver/Types.h"
11
12#include "llvm/ADT/StringSwitch.h"
13#include <string.h>
14#include <cassert>
15
16using namespace clang::driver;
17using namespace clang::driver::types;
18
19struct TypeInfo {
20  const char *Name;
21  const char *Flags;
22  const char *TempSuffix;
23  ID PreprocessedType;
24};
25
26static const TypeInfo TypeInfos[] = {
27#define TYPE(NAME, ID, PP_TYPE, TEMP_SUFFIX, FLAGS) \
28  { NAME, FLAGS, TEMP_SUFFIX, TY_##PP_TYPE, },
29#include "clang/Driver/Types.def"
30#undef TYPE
31};
32static const unsigned numTypes = sizeof(TypeInfos) / sizeof(TypeInfos[0]);
33
34static const TypeInfo &getInfo(unsigned id) {
35  assert(id > 0 && id - 1 < numTypes && "Invalid Type ID.");
36  return TypeInfos[id - 1];
37}
38
39const char *types::getTypeName(ID Id) {
40  return getInfo(Id).Name;
41}
42
43types::ID types::getPreprocessedType(ID Id) {
44  return getInfo(Id).PreprocessedType;
45}
46
47const char *types::getTypeTempSuffix(ID Id) {
48  return getInfo(Id).TempSuffix;
49}
50
51bool types::onlyAssembleType(ID Id) {
52  return strchr(getInfo(Id).Flags, 'a');
53}
54
55bool types::onlyPrecompileType(ID Id) {
56  return strchr(getInfo(Id).Flags, 'p');
57}
58
59bool types::canTypeBeUserSpecified(ID Id) {
60  return strchr(getInfo(Id).Flags, 'u');
61}
62
63bool types::appendSuffixForType(ID Id) {
64  return strchr(getInfo(Id).Flags, 'A');
65}
66
67bool types::canLipoType(ID Id) {
68  return (Id == TY_Nothing ||
69          Id == TY_Image ||
70          Id == TY_Object);
71}
72
73bool types::isAcceptedByClang(ID Id) {
74  switch (Id) {
75  default:
76    return false;
77
78  case TY_Asm:
79  case TY_C: case TY_PP_C:
80  case TY_CL:
81  case TY_CUDA:
82  case TY_ObjC: case TY_PP_ObjC:
83  case TY_CXX: case TY_PP_CXX:
84  case TY_ObjCXX: case TY_PP_ObjCXX:
85  case TY_CHeader: case TY_PP_CHeader:
86  case TY_ObjCHeader: case TY_PP_ObjCHeader:
87  case TY_CXXHeader: case TY_PP_CXXHeader:
88  case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
89  case TY_AST:
90  case TY_LLVM_IR: case TY_LLVM_BC:
91    return true;
92  }
93}
94
95bool types::isOnlyAcceptedByClang(ID Id) {
96  switch (Id) {
97  default:
98    return false;
99
100  case TY_AST:
101  case TY_LLVM_IR:
102  case TY_LLVM_BC:
103  case TY_RewrittenObjC:
104    return true;
105  }
106}
107
108bool types::isObjC(ID Id) {
109  switch (Id) {
110  default:
111    return false;
112
113  case TY_ObjC: case TY_PP_ObjC:
114  case TY_ObjCXX: case TY_PP_ObjCXX:
115  case TY_ObjCHeader: case TY_PP_ObjCHeader:
116  case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
117    return true;
118  }
119}
120
121bool types::isCXX(ID Id) {
122  switch (Id) {
123  default:
124    return false;
125
126  case TY_CXX: case TY_PP_CXX:
127  case TY_ObjCXX: case TY_PP_ObjCXX:
128  case TY_CXXHeader: case TY_PP_CXXHeader:
129  case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
130    return true;
131  }
132}
133
134types::ID types::lookupTypeForExtension(const char *Ext) {
135  return llvm::StringSwitch<types::ID>(Ext)
136           .Case("c", TY_C)
137           .Case("i", TY_PP_C)
138           .Case("m", TY_ObjC)
139           .Case("M", TY_ObjCXX)
140           .Case("h", TY_CHeader)
141           .Case("C", TY_CXX)
142           .Case("H", TY_CXXHeader)
143           .Case("f", TY_PP_Fortran)
144           .Case("F", TY_Fortran)
145           .Case("s", TY_PP_Asm)
146           .Case("S", TY_Asm)
147           .Case("ii", TY_PP_CXX)
148           .Case("mi", TY_PP_ObjC)
149           .Case("mm", TY_ObjCXX)
150           .Case("bc", TY_LLVM_BC)
151           .Case("cc", TY_CXX)
152           .Case("CC", TY_CXX)
153           .Case("cl", TY_CL)
154           .Case("cp", TY_CXX)
155           .Case("cu", TY_CUDA)
156           .Case("hh", TY_CXXHeader)
157           .Case("ll", TY_LLVM_IR)
158           .Case("hpp", TY_CXXHeader)
159           .Case("ads", TY_Ada)
160           .Case("adb", TY_Ada)
161           .Case("ast", TY_AST)
162           .Case("c++", TY_CXX)
163           .Case("C++", TY_CXX)
164           .Case("cxx", TY_CXX)
165           .Case("cpp", TY_CXX)
166           .Case("CPP", TY_CXX)
167           .Case("CXX", TY_CXX)
168           .Case("for", TY_PP_Fortran)
169           .Case("FOR", TY_PP_Fortran)
170           .Case("fpp", TY_Fortran)
171           .Case("FPP", TY_Fortran)
172           .Case("f90", TY_PP_Fortran)
173           .Case("f95", TY_PP_Fortran)
174           .Case("F90", TY_Fortran)
175           .Case("F95", TY_Fortran)
176           .Case("mii", TY_PP_ObjCXX)
177           .Default(TY_INVALID);
178}
179
180types::ID types::lookupTypeForTypeSpecifier(const char *Name) {
181  unsigned N = strlen(Name);
182
183  for (unsigned i=0; i<numTypes; ++i) {
184    types::ID Id = (types::ID) (i + 1);
185    if (canTypeBeUserSpecified(Id) &&
186        memcmp(Name, getInfo(Id).Name, N + 1) == 0)
187      return Id;
188  }
189
190  return TY_INVALID;
191}
192
193// FIXME: Why don't we just put this list in the defs file, eh.
194
195unsigned types::getNumCompilationPhases(ID Id) {
196  if (Id == TY_Object)
197    return 1;
198
199  unsigned N = 0;
200  if (getPreprocessedType(Id) != TY_INVALID)
201    N += 1;
202
203  if (onlyAssembleType(Id))
204    return N + 2; // assemble, link
205  if (onlyPrecompileType(Id))
206    return N + 1; // precompile
207
208  return N + 3; // compile, assemble, link
209}
210
211phases::ID types::getCompilationPhase(ID Id, unsigned N) {
212  assert(N < getNumCompilationPhases(Id) && "Invalid index.");
213
214  if (Id == TY_Object)
215    return phases::Link;
216
217  if (getPreprocessedType(Id) != TY_INVALID) {
218    if (N == 0)
219      return phases::Preprocess;
220    --N;
221  }
222
223  if (onlyAssembleType(Id))
224    return N == 0 ? phases::Assemble : phases::Link;
225
226  if (onlyPrecompileType(Id))
227    return phases::Precompile;
228
229  if (N == 0)
230    return phases::Compile;
231  if (N == 1)
232    return phases::Assemble;
233
234  return phases::Link;
235}
236
237ID types::lookupCXXTypeForCType(ID Id) {
238  switch (Id) {
239  default:
240    return Id;
241
242  case types::TY_C:
243    return types::TY_CXX;
244  case types::TY_PP_C:
245    return types::TY_PP_CXX;
246  case types::TY_CHeader:
247    return types::TY_CXXHeader;
248  case types::TY_PP_CHeader:
249    return types::TY_PP_CXXHeader;
250  }
251}
252