blob: cab6dcc32723d23f9e2756d22b1edc6c916018dd [file] [log] [blame]
Nick Lewycky3fdcc6f2010-12-31 17:31:54 +00001//===--- Types.cpp - Driver input & temporary type information ------------===//
Daniel Dunbare9fba572009-03-12 07:40:41 +00002//
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"
Douglas Gregor55d3f7a2009-10-29 00:41:01 +000011#include "llvm/ADT/StringSwitch.h"
Daniel Dunbare9fba572009-03-12 07:40:41 +000012#include <cassert>
Chandler Carruth55fc8732012-12-04 09:13:33 +000013#include <string.h>
Daniel Dunbare9fba572009-03-12 07:40:41 +000014
Daniel Dunbare9fba572009-03-12 07:40:41 +000015using namespace clang::driver;
16using namespace clang::driver::types;
17
Daniel Dunbard8e0e452009-11-18 20:19:26 +000018struct TypeInfo {
Daniel Dunbare9fba572009-03-12 07:40:41 +000019 const char *Name;
20 const char *Flags;
21 const char *TempSuffix;
22 ID PreprocessedType;
23};
24
Nuno Lopes68f7a242009-12-10 00:07:02 +000025static const TypeInfo TypeInfos[] = {
Daniel Dunbare9fba572009-03-12 07:40:41 +000026#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
Nuno Lopes68f7a242009-12-10 00:07:02 +000033static const TypeInfo &getInfo(unsigned id) {
Daniel Dunbare9fba572009-03-12 07:40:41 +000034 assert(id > 0 && id - 1 < numTypes && "Invalid Type ID.");
35 return TypeInfos[id - 1];
36}
37
Mike Stump1eb44332009-09-09 15:08:12 +000038const char *types::getTypeName(ID Id) {
39 return getInfo(Id).Name;
Daniel Dunbare9fba572009-03-12 07:40:41 +000040}
41
Mike Stump1eb44332009-09-09 15:08:12 +000042types::ID types::getPreprocessedType(ID Id) {
43 return getInfo(Id).PreprocessedType;
Daniel Dunbare9fba572009-03-12 07:40:41 +000044}
45
Mike Stump1eb44332009-09-09 15:08:12 +000046const char *types::getTypeTempSuffix(ID Id) {
47 return getInfo(Id).TempSuffix;
Daniel Dunbare9fba572009-03-12 07:40:41 +000048}
49
Mike Stump1eb44332009-09-09 15:08:12 +000050bool types::onlyAssembleType(ID Id) {
51 return strchr(getInfo(Id).Flags, 'a');
Daniel Dunbare9fba572009-03-12 07:40:41 +000052}
53
Mike Stump1eb44332009-09-09 15:08:12 +000054bool types::onlyPrecompileType(ID Id) {
55 return strchr(getInfo(Id).Flags, 'p');
Daniel Dunbare9fba572009-03-12 07:40:41 +000056}
57
Mike Stump1eb44332009-09-09 15:08:12 +000058bool types::canTypeBeUserSpecified(ID Id) {
59 return strchr(getInfo(Id).Flags, 'u');
Daniel Dunbare9fba572009-03-12 07:40:41 +000060}
61
Mike Stump1eb44332009-09-09 15:08:12 +000062bool types::appendSuffixForType(ID Id) {
63 return strchr(getInfo(Id).Flags, 'A');
Daniel Dunbare9fba572009-03-12 07:40:41 +000064}
65
Mike Stump1eb44332009-09-09 15:08:12 +000066bool types::canLipoType(ID Id) {
Daniel Dunbar9f5ef942009-03-12 18:21:41 +000067 return (Id == TY_Nothing ||
68 Id == TY_Image ||
Chad Rosierd6261a92012-08-02 21:39:47 +000069 Id == TY_Object ||
70 Id == TY_LTO_BC);
Daniel Dunbar9f5ef942009-03-12 18:21:41 +000071}
72
Nick Lewycky5bab9ae2012-11-15 05:36:36 +000073bool 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
Daniel Dunbar77544fd2009-11-17 08:07:16 +000096bool types::isObjC(ID Id) {
97 switch (Id) {
98 default:
99 return false;
100
Nico Webercc52a062011-08-13 23:13:37 +0000101 case TY_ObjC: case TY_PP_ObjC: case TY_PP_ObjC_Alias:
Daniel Dunbar77544fd2009-11-17 08:07:16 +0000102 case TY_ObjCXX: case TY_PP_ObjCXX:
103 case TY_ObjCHeader: case TY_PP_ObjCHeader:
Nico Webercc52a062011-08-13 23:13:37 +0000104 case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader: case TY_PP_ObjCXX_Alias:
Daniel Dunbar77544fd2009-11-17 08:07:16 +0000105 return true;
106 }
107}
108
Daniel Dunbar4db938c2009-03-13 23:46:19 +0000109bool types::isCXX(ID Id) {
110 switch (Id) {
111 default:
112 return false;
113
114 case TY_CXX: case TY_PP_CXX:
Chad Rosierecf16262012-11-16 22:31:39 +0000115 case TY_ObjCXX: case TY_PP_ObjCXX: case TY_PP_ObjCXX_Alias:
Daniel Dunbar4db938c2009-03-13 23:46:19 +0000116 case TY_CXXHeader: case TY_PP_CXXHeader:
117 case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
Peter Collingbourned26db2f2012-05-20 23:28:36 +0000118 case TY_CUDA:
Daniel Dunbar4db938c2009-03-13 23:46:19 +0000119 return true;
120 }
121}
122
Daniel Dunbare9fba572009-03-12 07:40:41 +0000123types::ID types::lookupTypeForExtension(const char *Ext) {
Douglas Gregor55d3f7a2009-10-29 00:41:01 +0000124 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)
Chad Rosier20fd8672011-08-12 23:16:53 +0000136 .Case("o", TY_Object)
Douglas Gregor55d3f7a2009-10-29 00:41:01 +0000137 .Case("ii", TY_PP_CXX)
138 .Case("mi", TY_PP_ObjC)
139 .Case("mm", TY_ObjCXX)
Daniel Dunbar6c6424b2010-06-07 23:28:45 +0000140 .Case("bc", TY_LLVM_BC)
Douglas Gregor55d3f7a2009-10-29 00:41:01 +0000141 .Case("cc", TY_CXX)
142 .Case("CC", TY_CXX)
Nate Begemanedcfc412010-01-05 06:00:15 +0000143 .Case("cl", TY_CL)
Douglas Gregor55d3f7a2009-10-29 00:41:01 +0000144 .Case("cp", TY_CXX)
Peter Collingbourne895fcca2010-12-01 03:15:20 +0000145 .Case("cu", TY_CUDA)
Douglas Gregor55d3f7a2009-10-29 00:41:01 +0000146 .Case("hh", TY_CXXHeader)
Daniel Dunbar6c6424b2010-06-07 23:28:45 +0000147 .Case("ll", TY_LLVM_IR)
Daniel Dunbar90cb9202009-11-22 22:08:27 +0000148 .Case("hpp", TY_CXXHeader)
Douglas Gregor55d3f7a2009-10-29 00:41:01 +0000149 .Case("ads", TY_Ada)
150 .Case("adb", TY_Ada)
151 .Case("ast", TY_AST)
Douglas Gregor169b7532010-06-22 23:43:22 +0000152 .Case("c++", TY_CXX)
153 .Case("C++", TY_CXX)
Douglas Gregor55d3f7a2009-10-29 00:41:01 +0000154 .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);
Daniel Dunbare9fba572009-03-12 07:40:41 +0000168}
169
170types::ID types::lookupTypeForTypeSpecifier(const char *Name) {
171 unsigned N = strlen(Name);
172
173 for (unsigned i=0; i<numTypes; ++i) {
174 types::ID Id = (types::ID) (i + 1);
Mike Stump1eb44332009-09-09 15:08:12 +0000175 if (canTypeBeUserSpecified(Id) &&
Daniel Dunbar3dbd6c52009-03-13 17:46:02 +0000176 memcmp(Name, getInfo(Id).Name, N + 1) == 0)
Daniel Dunbare9fba572009-03-12 07:40:41 +0000177 return Id;
178 }
179
180 return TY_INVALID;
181}
Daniel Dunbarc1b5fa82009-03-13 11:28:30 +0000182
183// FIXME: Why don't we just put this list in the defs file, eh.
184
Mike Stump1eb44332009-09-09 15:08:12 +0000185unsigned types::getNumCompilationPhases(ID Id) {
Daniel Dunbarc1b5fa82009-03-13 11:28:30 +0000186 if (Id == TY_Object)
187 return 1;
Mike Stump1eb44332009-09-09 15:08:12 +0000188
Daniel Dunbarc1b5fa82009-03-13 11:28:30 +0000189 unsigned N = 0;
190 if (getPreprocessedType(Id) != TY_INVALID)
191 N += 1;
Mike Stump1eb44332009-09-09 15:08:12 +0000192
Daniel Dunbarc1b5fa82009-03-13 11:28:30 +0000193 if (onlyAssembleType(Id))
194 return N + 2; // assemble, link
195 if (onlyPrecompileType(Id))
196 return N + 1; // precompile
Mike Stump1eb44332009-09-09 15:08:12 +0000197
Daniel Dunbarc1b5fa82009-03-13 11:28:30 +0000198 return N + 3; // compile, assemble, link
199}
200
201phases::ID types::getCompilationPhase(ID Id, unsigned N) {
202 assert(N < getNumCompilationPhases(Id) && "Invalid index.");
Mike Stump1eb44332009-09-09 15:08:12 +0000203
Daniel Dunbarc1b5fa82009-03-13 11:28:30 +0000204 if (Id == TY_Object)
205 return phases::Link;
206
207 if (getPreprocessedType(Id) != TY_INVALID) {
208 if (N == 0)
209 return phases::Preprocess;
210 --N;
211 }
212
213 if (onlyAssembleType(Id))
214 return N == 0 ? phases::Assemble : phases::Link;
215
216 if (onlyPrecompileType(Id))
217 return phases::Precompile;
218
219 if (N == 0)
220 return phases::Compile;
221 if (N == 1)
222 return phases::Assemble;
Mike Stump1eb44332009-09-09 15:08:12 +0000223
Daniel Dunbarc1b5fa82009-03-13 11:28:30 +0000224 return phases::Link;
225}
Daniel Dunbar51679c52010-02-17 20:32:58 +0000226
227ID types::lookupCXXTypeForCType(ID Id) {
228 switch (Id) {
229 default:
230 return Id;
Joey Gouly21261f42012-11-21 16:54:35 +0000231
Daniel Dunbar51679c52010-02-17 20:32:58 +0000232 case types::TY_C:
233 return types::TY_CXX;
234 case types::TY_PP_C:
235 return types::TY_PP_CXX;
236 case types::TY_CHeader:
237 return types::TY_CXXHeader;
238 case types::TY_PP_CHeader:
239 return types::TY_PP_CXXHeader;
240 }
241}