Types.cpp revision 226633
1117610Sdes//===--- Types.cpp - Driver input & temporary type information ------------===//
2117610Sdes//
3141098Sdes//                     The LLVM Compiler Infrastructure
4255376Sdes//
5141098Sdes// This file is distributed under the University of Illinois Open Source
6141098Sdes// License. See LICENSE.TXT for details.
7141098Sdes//
8141098Sdes//===----------------------------------------------------------------------===//
9117610Sdes
10141098Sdes#include "clang/Driver/Types.h"
11117610Sdes
12141098Sdes#include "llvm/ADT/StringSwitch.h"
13141098Sdes#include <string.h>
14141098Sdes#include <cassert>
15141098Sdes
16141098Sdesusing namespace clang::driver;
17141098Sdesusing namespace clang::driver::types;
18117610Sdes
19141098Sdesstruct TypeInfo {
20141098Sdes  const char *Name;
21141098Sdes  const char *Flags;
22141098Sdes  const char *TempSuffix;
23141098Sdes  ID PreprocessedType;
24141098Sdes};
25141098Sdes
26141098Sdesstatic const TypeInfo TypeInfos[] = {
27141098Sdes#define TYPE(NAME, ID, PP_TYPE, TEMP_SUFFIX, FLAGS) \
28141098Sdes  { NAME, FLAGS, TEMP_SUFFIX, TY_##PP_TYPE, },
29141098Sdes#include "clang/Driver/Types.def"
30141098Sdes#undef TYPE
31141098Sdes};
32141098Sdesstatic const unsigned numTypes = sizeof(TypeInfos) / sizeof(TypeInfos[0]);
33141098Sdes
34141098Sdesstatic const TypeInfo &getInfo(unsigned id) {
35141098Sdes  assert(id > 0 && id - 1 < numTypes && "Invalid Type ID.");
36141098Sdes  return TypeInfos[id - 1];
37117610Sdes}
38255376Sdes
39117610Sdesconst char *types::getTypeName(ID Id) {
40117610Sdes  return getInfo(Id).Name;
41117610Sdes}
42228692Sdes
43117610Sdestypes::ID types::getPreprocessedType(ID Id) {
44228692Sdes  return getInfo(Id).PreprocessedType;
45228692Sdes}
46228692Sdes
47228692Sdesconst char *types::getTypeTempSuffix(ID Id) {
48117610Sdes  return getInfo(Id).TempSuffix;
49117610Sdes}
50117610Sdes
51228692Sdesbool types::onlyAssembleType(ID Id) {
52228692Sdes  return strchr(getInfo(Id).Flags, 'a');
53228692Sdes}
54228692Sdes
55228692Sdesbool types::onlyPrecompileType(ID Id) {
56228692Sdes  return strchr(getInfo(Id).Flags, 'p');
57117610Sdes}
58228692Sdes
59228692Sdesbool types::canTypeBeUserSpecified(ID Id) {
60117610Sdes  return strchr(getInfo(Id).Flags, 'u');
61228692Sdes}
62228692Sdes
63228692Sdesbool types::appendSuffixForType(ID Id) {
64228692Sdes  return strchr(getInfo(Id).Flags, 'A');
65228692Sdes}
66228692Sdes
67228692Sdesbool types::canLipoType(ID Id) {
68228692Sdes  return (Id == TY_Nothing ||
69228692Sdes          Id == TY_Image ||
70117610Sdes          Id == TY_Object);
71228692Sdes}
72228692Sdes
73228692Sdesbool types::isAcceptedByClang(ID Id) {
74228692Sdes  switch (Id) {
75228692Sdes  default:
76228692Sdes    return false;
77228692Sdes
78228692Sdes  case TY_Asm:
79228692Sdes  case TY_C: case TY_PP_C:
80228692Sdes  case TY_CL:
81228692Sdes  case TY_CUDA:
82228692Sdes  case TY_ObjC: case TY_PP_ObjC: case TY_PP_ObjC_Alias:
83228692Sdes  case TY_CXX: case TY_PP_CXX:
84228692Sdes  case TY_ObjCXX: case TY_PP_ObjCXX: case TY_PP_ObjCXX_Alias:
85228692Sdes  case TY_CHeader: case TY_PP_CHeader:
86228692Sdes  case TY_CLHeader:
87228692Sdes  case TY_ObjCHeader: case TY_PP_ObjCHeader:
88228692Sdes  case TY_CXXHeader: case TY_PP_CXXHeader:
89141098Sdes  case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
90228692Sdes  case TY_AST:
91228692Sdes  case TY_LLVM_IR: case TY_LLVM_BC:
92141098Sdes    return true;
93228692Sdes  }
94141098Sdes}
95141098Sdes
96141098Sdesbool types::isOnlyAcceptedByClang(ID Id) {
97228692Sdes  switch (Id) {
98228692Sdes  default:
99228692Sdes    return false;
100174832Sdes
101117610Sdes  case TY_AST:
102228692Sdes  case TY_LLVM_IR:
103228692Sdes  case TY_LLVM_BC:
104141098Sdes  case TY_RewrittenObjC:
105174832Sdes    return true;
106174832Sdes  }
107117610Sdes}
108174832Sdes
109174832Sdesbool types::isObjC(ID Id) {
110174832Sdes  switch (Id) {
111117610Sdes  default:
112141098Sdes    return false;
113228692Sdes
114228692Sdes  case TY_ObjC: case TY_PP_ObjC: case TY_PP_ObjC_Alias:
115117610Sdes  case TY_ObjCXX: case TY_PP_ObjCXX:
116228692Sdes  case TY_ObjCHeader: case TY_PP_ObjCHeader:
117228692Sdes  case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader: case TY_PP_ObjCXX_Alias:
118228692Sdes    return true;
119228692Sdes  }
120228692Sdes}
121228692Sdes
122228692Sdesbool types::isCXX(ID Id) {
123228692Sdes  switch (Id) {
124228692Sdes  default:
125228692Sdes    return false;
126141098Sdes
127228692Sdes  case TY_CXX: case TY_PP_CXX:
128228692Sdes  case TY_ObjCXX: case TY_PP_ObjCXX:
129141098Sdes  case TY_CXXHeader: case TY_PP_CXXHeader:
130117610Sdes  case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
131228692Sdes    return true;
132141098Sdes  }
133228692Sdes}
134117610Sdes
135228692Sdestypes::ID types::lookupTypeForExtension(const char *Ext) {
136117610Sdes  return llvm::StringSwitch<types::ID>(Ext)
137228692Sdes           .Case("c", TY_C)
138228692Sdes           .Case("i", TY_PP_C)
139141098Sdes           .Case("m", TY_ObjC)
140228692Sdes           .Case("M", TY_ObjCXX)
141117610Sdes           .Case("h", TY_CHeader)
142174832Sdes           .Case("C", TY_CXX)
143117610Sdes           .Case("H", TY_CXXHeader)
144228692Sdes           .Case("f", TY_PP_Fortran)
145228692Sdes           .Case("F", TY_Fortran)
146228692Sdes           .Case("s", TY_PP_Asm)
147228692Sdes           .Case("S", TY_Asm)
148228692Sdes           .Case("o", TY_Object)
149228692Sdes           .Case("ii", TY_PP_CXX)
150228692Sdes           .Case("mi", TY_PP_ObjC)
151228692Sdes           .Case("mm", TY_ObjCXX)
152117610Sdes           .Case("bc", TY_LLVM_BC)
153141098Sdes           .Case("cc", TY_CXX)
154228692Sdes           .Case("CC", TY_CXX)
155117610Sdes           .Case("cl", TY_CL)
156228692Sdes           .Case("cp", TY_CXX)
157117610Sdes           .Case("cu", TY_CUDA)
158228692Sdes           .Case("hh", TY_CXXHeader)
159255376Sdes           .Case("ll", TY_LLVM_IR)
160255376Sdes           .Case("hpp", TY_CXXHeader)
161255376Sdes           .Case("ads", TY_Ada)
162255376Sdes           .Case("adb", TY_Ada)
163228692Sdes           .Case("ast", TY_AST)
164117610Sdes           .Case("c++", TY_CXX)
165228692Sdes           .Case("C++", TY_CXX)
166117610Sdes           .Case("cxx", TY_CXX)
167174832Sdes           .Case("cpp", TY_CXX)
168174832Sdes           .Case("CPP", TY_CXX)
169228692Sdes           .Case("CXX", TY_CXX)
170141098Sdes           .Case("for", TY_PP_Fortran)
171228692Sdes           .Case("FOR", TY_PP_Fortran)
172228692Sdes           .Case("fpp", TY_Fortran)
173228692Sdes           .Case("FPP", TY_Fortran)
174228692Sdes           .Case("f90", TY_PP_Fortran)
175228692Sdes           .Case("f95", TY_PP_Fortran)
176141098Sdes           .Case("F90", TY_Fortran)
177228692Sdes           .Case("F95", TY_Fortran)
178141098Sdes           .Case("mii", TY_PP_ObjCXX)
179141098Sdes           .Default(TY_INVALID);
180228692Sdes}
181228692Sdes
182228692Sdestypes::ID types::lookupTypeForTypeSpecifier(const char *Name) {
183228692Sdes  unsigned N = strlen(Name);
184228692Sdes
185228692Sdes  for (unsigned i=0; i<numTypes; ++i) {
186228692Sdes    types::ID Id = (types::ID) (i + 1);
187228692Sdes    if (canTypeBeUserSpecified(Id) &&
188228692Sdes        memcmp(Name, getInfo(Id).Name, N + 1) == 0)
189228692Sdes      return Id;
190228692Sdes  }
191228692Sdes
192228692Sdes  return TY_INVALID;
193255376Sdes}
194255376Sdes
195255376Sdes// FIXME: Why don't we just put this list in the defs file, eh.
196255376Sdes
197228692Sdesunsigned types::getNumCompilationPhases(ID Id) {
198228692Sdes  if (Id == TY_Object)
199228692Sdes    return 1;
200228692Sdes
201141098Sdes  unsigned N = 0;
202141098Sdes  if (getPreprocessedType(Id) != TY_INVALID)
203141098Sdes    N += 1;
204141098Sdes
205255376Sdes  if (onlyAssembleType(Id))
206141098Sdes    return N + 2; // assemble, link
207141098Sdes  if (onlyPrecompileType(Id))
208117610Sdes    return N + 1; // precompile
209117610Sdes
210228692Sdes  return N + 3; // compile, assemble, link
211255376Sdes}
212255376Sdes
213255376Sdesphases::ID types::getCompilationPhase(ID Id, unsigned N) {
214255376Sdes  assert(N < getNumCompilationPhases(Id) && "Invalid index.");
215255376Sdes
216228692Sdes  if (Id == TY_Object)
217228692Sdes    return phases::Link;
218228692Sdes
219228692Sdes  if (getPreprocessedType(Id) != TY_INVALID) {
220228692Sdes    if (N == 0)
221228692Sdes      return phases::Preprocess;
222228692Sdes    --N;
223228692Sdes  }
224228692Sdes
225228692Sdes  if (onlyAssembleType(Id))
226228692Sdes    return N == 0 ? phases::Assemble : phases::Link;
227228692Sdes
228228692Sdes  if (onlyPrecompileType(Id))
229228692Sdes    return phases::Precompile;
230228692Sdes
231228692Sdes  if (N == 0)
232228692Sdes    return phases::Compile;
233228692Sdes  if (N == 1)
234228692Sdes    return phases::Assemble;
235228692Sdes
236228692Sdes  return phases::Link;
237228692Sdes}
238228692Sdes
239228692SdesID types::lookupCXXTypeForCType(ID Id) {
240228692Sdes  switch (Id) {
241141098Sdes  default:
242141098Sdes    return Id;
243255376Sdes
244141098Sdes  case types::TY_C:
245255376Sdes    return types::TY_CXX;
246141098Sdes  case types::TY_PP_C:
247117610Sdes    return types::TY_PP_CXX;
248141098Sdes  case types::TY_CHeader:
249141098Sdes    return types::TY_CXXHeader;
250228692Sdes  case types::TY_PP_CHeader:
251228692Sdes    return types::TY_PP_CXXHeader;
252228692Sdes  }
253228692Sdes}
254117610Sdes