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