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