1218893Sdim//===--- Types.cpp - Driver input & temporary type information ------------===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed
10193326Sed#include "clang/Driver/Types.h"
11198893Srdivacky#include "llvm/ADT/StringSwitch.h"
12249423Sdim#include <cassert>
13193326Sed#include <string.h>
14193326Sed
15193326Sedusing namespace clang::driver;
16193326Sedusing namespace clang::driver::types;
17193326Sed
18199512Srdivackystruct TypeInfo {
19193326Sed  const char *Name;
20193326Sed  const char *Flags;
21193326Sed  const char *TempSuffix;
22193326Sed  ID PreprocessedType;
23193326Sed};
24193326Sed
25200583Srdivackystatic const TypeInfo TypeInfos[] = {
26193326Sed#define TYPE(NAME, ID, PP_TYPE, TEMP_SUFFIX, FLAGS) \
27193326Sed  { NAME, FLAGS, TEMP_SUFFIX, TY_##PP_TYPE, },
28193326Sed#include "clang/Driver/Types.def"
29193326Sed#undef TYPE
30193326Sed};
31193326Sedstatic const unsigned numTypes = sizeof(TypeInfos) / sizeof(TypeInfos[0]);
32193326Sed
33200583Srdivackystatic const TypeInfo &getInfo(unsigned id) {
34193326Sed  assert(id > 0 && id - 1 < numTypes && "Invalid Type ID.");
35193326Sed  return TypeInfos[id - 1];
36193326Sed}
37193326Sed
38198092Srdivackyconst char *types::getTypeName(ID Id) {
39198092Srdivacky  return getInfo(Id).Name;
40193326Sed}
41193326Sed
42198092Srdivackytypes::ID types::getPreprocessedType(ID Id) {
43198092Srdivacky  return getInfo(Id).PreprocessedType;
44193326Sed}
45193326Sed
46198092Srdivackyconst char *types::getTypeTempSuffix(ID Id) {
47198092Srdivacky  return getInfo(Id).TempSuffix;
48193326Sed}
49193326Sed
50198092Srdivackybool types::onlyAssembleType(ID Id) {
51198092Srdivacky  return strchr(getInfo(Id).Flags, 'a');
52193326Sed}
53193326Sed
54198092Srdivackybool types::onlyPrecompileType(ID Id) {
55198092Srdivacky  return strchr(getInfo(Id).Flags, 'p');
56193326Sed}
57193326Sed
58198092Srdivackybool types::canTypeBeUserSpecified(ID Id) {
59198092Srdivacky  return strchr(getInfo(Id).Flags, 'u');
60193326Sed}
61193326Sed
62198092Srdivackybool types::appendSuffixForType(ID Id) {
63198092Srdivacky  return strchr(getInfo(Id).Flags, 'A');
64193326Sed}
65193326Sed
66198092Srdivackybool types::canLipoType(ID Id) {
67193326Sed  return (Id == TY_Nothing ||
68193326Sed          Id == TY_Image ||
69239462Sdim          Id == TY_Object ||
70239462Sdim          Id == TY_LTO_BC);
71193326Sed}
72193326Sed
73193326Sedbool types::isAcceptedByClang(ID Id) {
74193326Sed  switch (Id) {
75193326Sed  default:
76193326Sed    return false;
77193326Sed
78193326Sed  case TY_Asm:
79193326Sed  case TY_C: case TY_PP_C:
80202379Srdivacky  case TY_CL:
81218893Sdim  case TY_CUDA:
82226633Sdim  case TY_ObjC: case TY_PP_ObjC: case TY_PP_ObjC_Alias:
83193326Sed  case TY_CXX: case TY_PP_CXX:
84226633Sdim  case TY_ObjCXX: case TY_PP_ObjCXX: case TY_PP_ObjCXX_Alias:
85193326Sed  case TY_CHeader: case TY_PP_CHeader:
86226633Sdim  case TY_CLHeader:
87193326Sed  case TY_ObjCHeader: case TY_PP_ObjCHeader:
88193326Sed  case TY_CXXHeader: case TY_PP_CXXHeader:
89193326Sed  case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
90249423Sdim  case TY_AST: case TY_ModuleFile:
91210299Sed  case TY_LLVM_IR: case TY_LLVM_BC:
92193326Sed    return true;
93193326Sed  }
94193326Sed}
95193326Sed
96199482Srdivackybool types::isObjC(ID Id) {
97199482Srdivacky  switch (Id) {
98199482Srdivacky  default:
99199482Srdivacky    return false;
100199482Srdivacky
101226633Sdim  case TY_ObjC: case TY_PP_ObjC: case TY_PP_ObjC_Alias:
102199482Srdivacky  case TY_ObjCXX: case TY_PP_ObjCXX:
103199482Srdivacky  case TY_ObjCHeader: case TY_PP_ObjCHeader:
104226633Sdim  case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader: case TY_PP_ObjCXX_Alias:
105199482Srdivacky    return true;
106199482Srdivacky  }
107199482Srdivacky}
108199482Srdivacky
109193326Sedbool types::isCXX(ID Id) {
110193326Sed  switch (Id) {
111193326Sed  default:
112193326Sed    return false;
113193326Sed
114193326Sed  case TY_CXX: case TY_PP_CXX:
115249423Sdim  case TY_ObjCXX: case TY_PP_ObjCXX: case TY_PP_ObjCXX_Alias:
116193326Sed  case TY_CXXHeader: case TY_PP_CXXHeader:
117193326Sed  case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
118239462Sdim  case TY_CUDA:
119193326Sed    return true;
120193326Sed  }
121193326Sed}
122193326Sed
123193326Sedtypes::ID types::lookupTypeForExtension(const char *Ext) {
124198893Srdivacky  return llvm::StringSwitch<types::ID>(Ext)
125198893Srdivacky           .Case("c", TY_C)
126198893Srdivacky           .Case("i", TY_PP_C)
127198893Srdivacky           .Case("m", TY_ObjC)
128198893Srdivacky           .Case("M", TY_ObjCXX)
129198893Srdivacky           .Case("h", TY_CHeader)
130198893Srdivacky           .Case("C", TY_CXX)
131198893Srdivacky           .Case("H", TY_CXXHeader)
132198893Srdivacky           .Case("f", TY_PP_Fortran)
133198893Srdivacky           .Case("F", TY_Fortran)
134198893Srdivacky           .Case("s", TY_PP_Asm)
135198893Srdivacky           .Case("S", TY_Asm)
136226633Sdim           .Case("o", TY_Object)
137198893Srdivacky           .Case("ii", TY_PP_CXX)
138198893Srdivacky           .Case("mi", TY_PP_ObjC)
139198893Srdivacky           .Case("mm", TY_ObjCXX)
140210299Sed           .Case("bc", TY_LLVM_BC)
141198893Srdivacky           .Case("cc", TY_CXX)
142198893Srdivacky           .Case("CC", TY_CXX)
143202379Srdivacky           .Case("cl", TY_CL)
144198893Srdivacky           .Case("cp", TY_CXX)
145218893Sdim           .Case("cu", TY_CUDA)
146198893Srdivacky           .Case("hh", TY_CXXHeader)
147210299Sed           .Case("ll", TY_LLVM_IR)
148199990Srdivacky           .Case("hpp", TY_CXXHeader)
149198893Srdivacky           .Case("ads", TY_Ada)
150198893Srdivacky           .Case("adb", TY_Ada)
151198893Srdivacky           .Case("ast", TY_AST)
152210299Sed           .Case("c++", TY_CXX)
153210299Sed           .Case("C++", TY_CXX)
154198893Srdivacky           .Case("cxx", TY_CXX)
155198893Srdivacky           .Case("cpp", TY_CXX)
156198893Srdivacky           .Case("CPP", TY_CXX)
157198893Srdivacky           .Case("CXX", TY_CXX)
158198893Srdivacky           .Case("for", TY_PP_Fortran)
159198893Srdivacky           .Case("FOR", TY_PP_Fortran)
160198893Srdivacky           .Case("fpp", TY_Fortran)
161198893Srdivacky           .Case("FPP", TY_Fortran)
162198893Srdivacky           .Case("f90", TY_PP_Fortran)
163198893Srdivacky           .Case("f95", TY_PP_Fortran)
164198893Srdivacky           .Case("F90", TY_Fortran)
165198893Srdivacky           .Case("F95", TY_Fortran)
166198893Srdivacky           .Case("mii", TY_PP_ObjCXX)
167249423Sdim           .Case("pcm", TY_ModuleFile)
168198893Srdivacky           .Default(TY_INVALID);
169193326Sed}
170193326Sed
171193326Sedtypes::ID types::lookupTypeForTypeSpecifier(const char *Name) {
172193326Sed  for (unsigned i=0; i<numTypes; ++i) {
173193326Sed    types::ID Id = (types::ID) (i + 1);
174198092Srdivacky    if (canTypeBeUserSpecified(Id) &&
175249423Sdim        strcmp(Name, getInfo(Id).Name) == 0)
176193326Sed      return Id;
177193326Sed  }
178193326Sed
179193326Sed  return TY_INVALID;
180193326Sed}
181193326Sed
182193326Sed// FIXME: Why don't we just put this list in the defs file, eh.
183249423Sdimvoid types::getCompilationPhases(
184249423Sdim  ID Id,
185249423Sdim  llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> &P) {
186249423Sdim  if (Id != TY_Object) {
187249423Sdim    if (getPreprocessedType(Id) != TY_INVALID) {
188249423Sdim      P.push_back(phases::Preprocess);
189249423Sdim    }
190193326Sed
191249423Sdim    if (onlyPrecompileType(Id)) {
192249423Sdim      P.push_back(phases::Precompile);
193249423Sdim    } else {
194249423Sdim      if (!onlyAssembleType(Id)) {
195249423Sdim        P.push_back(phases::Compile);
196249423Sdim      }
197249423Sdim      P.push_back(phases::Assemble);
198249423Sdim    }
199193326Sed  }
200249423Sdim  if (!onlyPrecompileType(Id)) {
201249423Sdim    P.push_back(phases::Link);
202249423Sdim  }
203249423Sdim  assert(0 < P.size() && "Not enough phases in list");
204249423Sdim  assert(P.size() <= phases::MaxNumberOfPhases && "Too many phases in list");
205249423Sdim  return;
206193326Sed}
207204643Srdivacky
208204643SrdivackyID types::lookupCXXTypeForCType(ID Id) {
209204643Srdivacky  switch (Id) {
210204643Srdivacky  default:
211204643Srdivacky    return Id;
212249423Sdim
213204643Srdivacky  case types::TY_C:
214204643Srdivacky    return types::TY_CXX;
215204643Srdivacky  case types::TY_PP_C:
216204643Srdivacky    return types::TY_PP_CXX;
217204643Srdivacky  case types::TY_CHeader:
218204643Srdivacky    return types::TY_CXXHeader;
219204643Srdivacky  case types::TY_PP_CHeader:
220204643Srdivacky    return types::TY_PP_CXXHeader;
221204643Srdivacky  }
222204643Srdivacky}
223