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#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 = sizeof(TypeInfos) / sizeof(TypeInfos[0]);
32
33static const TypeInfo &getInfo(unsigned id) {
34  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
46const char *types::getTypeTempSuffix(ID Id) {
47  return getInfo(Id).TempSuffix;
48}
49
50bool types::onlyAssembleType(ID Id) {
51  return strchr(getInfo(Id).Flags, 'a');
52}
53
54bool types::onlyPrecompileType(ID Id) {
55  return strchr(getInfo(Id).Flags, 'p');
56}
57
58bool types::canTypeBeUserSpecified(ID Id) {
59  return strchr(getInfo(Id).Flags, 'u');
60}
61
62bool types::appendSuffixForType(ID Id) {
63  return strchr(getInfo(Id).Flags, 'A');
64}
65
66bool types::canLipoType(ID Id) {
67  return (Id == TY_Nothing ||
68          Id == TY_Image ||
69          Id == TY_Object ||
70          Id == TY_LTO_BC);
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: case TY_PP_ObjC_Alias:
83  case TY_CXX: case TY_PP_CXX:
84  case TY_ObjCXX: case TY_PP_ObjCXX: case TY_PP_ObjCXX_Alias:
85  case TY_CHeader: case TY_PP_CHeader:
86  case TY_CLHeader:
87  case TY_ObjCHeader: case TY_PP_ObjCHeader:
88  case TY_CXXHeader: case TY_PP_CXXHeader:
89  case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
90  case TY_AST:
91  case TY_LLVM_IR: case TY_LLVM_BC:
92    return true;
93  }
94}
95
96bool types::isObjC(ID Id) {
97  switch (Id) {
98  default:
99    return false;
100
101  case TY_ObjC: case TY_PP_ObjC: case TY_PP_ObjC_Alias:
102  case TY_ObjCXX: case TY_PP_ObjCXX:
103  case TY_ObjCHeader: case TY_PP_ObjCHeader:
104  case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader: case TY_PP_ObjCXX_Alias:
105    return true;
106  }
107}
108
109bool types::isCXX(ID Id) {
110  switch (Id) {
111  default:
112    return false;
113
114  case TY_CXX: case TY_PP_CXX:
115  case TY_ObjCXX: case TY_PP_ObjCXX: case TY_PP_ObjCXX_Alias:
116  case TY_CXXHeader: case TY_PP_CXXHeader:
117  case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
118  case TY_CUDA:
119    return true;
120  }
121}
122
123types::ID types::lookupTypeForExtension(const char *Ext) {
124  return llvm::StringSwitch<types::ID>(Ext)
125           .Case("c", TY_C)
126           .Case("i", TY_PP_C)
127           .Case("m", TY_ObjC)
128           .Case("M", TY_ObjCXX)
129           .Case("h", TY_CHeader)
130           .Case("C", TY_CXX)
131           .Case("H", TY_CXXHeader)
132           .Case("f", TY_PP_Fortran)
133           .Case("F", TY_Fortran)
134           .Case("s", TY_PP_Asm)
135           .Case("S", TY_Asm)
136           .Case("o", TY_Object)
137           .Case("ii", TY_PP_CXX)
138           .Case("mi", TY_PP_ObjC)
139           .Case("mm", TY_ObjCXX)
140           .Case("bc", TY_LLVM_BC)
141           .Case("cc", TY_CXX)
142           .Case("CC", TY_CXX)
143           .Case("cl", TY_CL)
144           .Case("cp", TY_CXX)
145           .Case("cu", TY_CUDA)
146           .Case("hh", TY_CXXHeader)
147           .Case("ll", TY_LLVM_IR)
148           .Case("hpp", TY_CXXHeader)
149           .Case("ads", TY_Ada)
150           .Case("adb", TY_Ada)
151           .Case("ast", TY_AST)
152           .Case("c++", TY_CXX)
153           .Case("C++", TY_CXX)
154           .Case("cxx", TY_CXX)
155           .Case("cpp", TY_CXX)
156           .Case("CPP", TY_CXX)
157           .Case("CXX", TY_CXX)
158           .Case("for", TY_PP_Fortran)
159           .Case("FOR", TY_PP_Fortran)
160           .Case("fpp", TY_Fortran)
161           .Case("FPP", TY_Fortran)
162           .Case("f90", TY_PP_Fortran)
163           .Case("f95", TY_PP_Fortran)
164           .Case("F90", TY_Fortran)
165           .Case("F95", TY_Fortran)
166           .Case("mii", TY_PP_ObjCXX)
167           .Default(TY_INVALID);
168}
169
170types::ID types::lookupTypeForTypeSpecifier(const char *Name) {
171  for (unsigned i=0; i<numTypes; ++i) {
172    types::ID Id = (types::ID) (i + 1);
173    if (canTypeBeUserSpecified(Id) &&
174        strcmp(Name, getInfo(Id).Name) == 0)
175      return Id;
176  }
177
178  return TY_INVALID;
179}
180
181// FIXME: Why don't we just put this list in the defs file, eh.
182void types::getCompilationPhases(
183  ID Id,
184  llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> &P) {
185  if (Id != TY_Object) {
186    if (getPreprocessedType(Id) != TY_INVALID) {
187      P.push_back(phases::Preprocess);
188    }
189
190    if (onlyPrecompileType(Id)) {
191      P.push_back(phases::Precompile);
192    } else {
193      if (!onlyAssembleType(Id)) {
194        P.push_back(phases::Compile);
195      }
196      P.push_back(phases::Assemble);
197    }
198  }
199  if (!onlyPrecompileType(Id)) {
200    P.push_back(phases::Link);
201  }
202  assert(0 < P.size() && "Not enough phases in list");
203  assert(P.size() <= phases::MaxNumberOfPhases && "Too many phases in list");
204  return;
205}
206
207ID types::lookupCXXTypeForCType(ID Id) {
208  switch (Id) {
209  default:
210    return Id;
211
212  case types::TY_C:
213    return types::TY_CXX;
214  case types::TY_PP_C:
215    return types::TY_PP_CXX;
216  case types::TY_CHeader:
217    return types::TY_CXXHeader;
218  case types::TY_PP_CHeader:
219    return types::TY_PP_CXXHeader;
220  }
221}
222