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 <string.h> 13 #include <cassert> 14 15 using namespace clang::driver; 16 using namespace clang::driver::types; 17 18 struct Info { 19 const char *Name; 20 const char *Flags; 21 const char *TempSuffix; 22 ID PreprocessedType; 23 }; 24 25 static Info TypeInfos[] = { 26 #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 }; 31 static const unsigned numTypes = sizeof(TypeInfos) / sizeof(TypeInfos[0]); 32 33 static Info &getInfo(unsigned id) { 34 assert(id > 0 && id - 1 < numTypes && "Invalid Type ID."); 35 return TypeInfos[id - 1]; 36 } 37 38 const char *types::getTypeName(ID Id) { 39 return getInfo(Id).Name; 40 } 41 42 types::ID types::getPreprocessedType(ID Id) { 43 return getInfo(Id).PreprocessedType; 44 } 45 46 const char *types::getTypeTempSuffix(ID Id) { 47 return getInfo(Id).TempSuffix; 48 } 49 50 bool types::onlyAssembleType(ID Id) { 51 return strchr(getInfo(Id).Flags, 'a'); 52 } 53 54 bool types::onlyPrecompileType(ID Id) { 55 return strchr(getInfo(Id).Flags, 'p'); 56 } 57 58 bool types::canTypeBeUserSpecified(ID Id) { 59 return strchr(getInfo(Id).Flags, 'u'); 60 } 61 62 bool types::appendSuffixForType(ID Id) { 63 return strchr(getInfo(Id).Flags, 'A'); 64 } 65 66 bool types::canLipoType(ID Id) { 67 return (Id == TY_Nothing || 68 Id == TY_Image || 69 Id == TY_Object); 70 } 71 72 bool types::isAcceptedByClang(ID Id) { 73 switch (Id) { 74 default: 75 return false; 76 77 case TY_Asm: 78 case TY_C: case TY_PP_C: 79 case TY_ObjC: case TY_PP_ObjC: 80 case TY_CXX: case TY_PP_CXX: 81 case TY_ObjCXX: case TY_PP_ObjCXX: 82 case TY_CHeader: case TY_PP_CHeader: 83 case TY_ObjCHeader: case TY_PP_ObjCHeader: 84 case TY_CXXHeader: case TY_PP_CXXHeader: 85 case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader: 86 case TY_AST: 87 return true; 88 } 89 } 90 91 bool types::isCXX(ID Id) { 92 switch (Id) { 93 default: 94 return false; 95 96 case TY_CXX: case TY_PP_CXX: 97 case TY_ObjCXX: case TY_PP_ObjCXX: 98 case TY_CXXHeader: case TY_PP_CXXHeader: 99 case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader: 100 return true; 101 } 102 } 103 104 types::ID types::lookupTypeForExtension(const char *Ext) { 105 unsigned N = strlen(Ext); 106 107 switch (N) { 108 case 1: 109 if (memcmp(Ext, "c", 1) == 0) return TY_C; 110 if (memcmp(Ext, "i", 1) == 0) return TY_PP_C; 111 if (memcmp(Ext, "m", 1) == 0) return TY_ObjC; 112 if (memcmp(Ext, "M", 1) == 0) return TY_ObjCXX; 113 if (memcmp(Ext, "h", 1) == 0) return TY_CHeader; 114 if (memcmp(Ext, "C", 1) == 0) return TY_CXX; 115 if (memcmp(Ext, "H", 1) == 0) return TY_CXXHeader; 116 if (memcmp(Ext, "f", 1) == 0) return TY_PP_Fortran; 117 if (memcmp(Ext, "F", 1) == 0) return TY_Fortran; 118 if (memcmp(Ext, "s", 1) == 0) return TY_PP_Asm; 119 if (memcmp(Ext, "S", 1) == 0) return TY_Asm; 120 case 2: 121 if (memcmp(Ext, "ii", 2) == 0) return TY_PP_CXX; 122 if (memcmp(Ext, "mi", 2) == 0) return TY_PP_ObjC; 123 if (memcmp(Ext, "mm", 2) == 0) return TY_ObjCXX; 124 if (memcmp(Ext, "cc", 2) == 0) return TY_CXX; 125 if (memcmp(Ext, "cc", 2) == 0) return TY_CXX; 126 if (memcmp(Ext, "cp", 2) == 0) return TY_CXX; 127 if (memcmp(Ext, "hh", 2) == 0) return TY_CXXHeader; 128 break; 129 case 3: 130 if (memcmp(Ext, "ads", 3) == 0) return TY_Ada; 131 if (memcmp(Ext, "adb", 3) == 0) return TY_Ada; 132 if (memcmp(Ext, "ast", 3) == 0) return TY_AST; 133 if (memcmp(Ext, "cxx", 3) == 0) return TY_CXX; 134 if (memcmp(Ext, "cpp", 3) == 0) return TY_CXX; 135 if (memcmp(Ext, "CPP", 3) == 0) return TY_CXX; 136 if (memcmp(Ext, "cXX", 3) == 0) return TY_CXX; 137 if (memcmp(Ext, "for", 3) == 0) return TY_PP_Fortran; 138 if (memcmp(Ext, "FOR", 3) == 0) return TY_PP_Fortran; 139 if (memcmp(Ext, "fpp", 3) == 0) return TY_Fortran; 140 if (memcmp(Ext, "FPP", 3) == 0) return TY_Fortran; 141 if (memcmp(Ext, "f90", 3) == 0) return TY_PP_Fortran; 142 if (memcmp(Ext, "f95", 3) == 0) return TY_PP_Fortran; 143 if (memcmp(Ext, "F90", 3) == 0) return TY_Fortran; 144 if (memcmp(Ext, "F95", 3) == 0) return TY_Fortran; 145 if (memcmp(Ext, "mii", 3) == 0) return TY_PP_ObjCXX; 146 break; 147 } 148 149 return TY_INVALID; 150 } 151 152 types::ID types::lookupTypeForTypeSpecifier(const char *Name) { 153 unsigned N = strlen(Name); 154 155 for (unsigned i=0; i<numTypes; ++i) { 156 types::ID Id = (types::ID) (i + 1); 157 if (canTypeBeUserSpecified(Id) && 158 memcmp(Name, getInfo(Id).Name, N + 1) == 0) 159 return Id; 160 } 161 162 return TY_INVALID; 163 } 164 165 // FIXME: Why don't we just put this list in the defs file, eh. 166 167 unsigned types::getNumCompilationPhases(ID Id) { 168 if (Id == TY_Object) 169 return 1; 170 171 unsigned N = 0; 172 if (getPreprocessedType(Id) != TY_INVALID) 173 N += 1; 174 175 if (onlyAssembleType(Id)) 176 return N + 2; // assemble, link 177 if (onlyPrecompileType(Id)) 178 return N + 1; // precompile 179 180 return N + 3; // compile, assemble, link 181 } 182 183 phases::ID types::getCompilationPhase(ID Id, unsigned N) { 184 assert(N < getNumCompilationPhases(Id) && "Invalid index."); 185 186 if (Id == TY_Object) 187 return phases::Link; 188 189 if (getPreprocessedType(Id) != TY_INVALID) { 190 if (N == 0) 191 return phases::Preprocess; 192 --N; 193 } 194 195 if (onlyAssembleType(Id)) 196 return N == 0 ? phases::Assemble : phases::Link; 197 198 if (onlyPrecompileType(Id)) 199 return phases::Precompile; 200 201 if (N == 0) 202 return phases::Compile; 203 if (N == 1) 204 return phases::Assemble; 205 206 return phases::Link; 207 } 208