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