Types.cpp revision ec4380002e5ed2527ae3f21c7841a4391f6319e3
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 15using namespace clang::driver; 16using namespace clang::driver::types; 17 18struct Info { 19 const char *Name; 20 const char *Flags; 21 const char *TempSuffix; 22 ID PreprocessedType; 23}; 24 25static 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}; 31static const unsigned numTypes = sizeof(TypeInfos) / sizeof(TypeInfos[0]); 32 33static Info &getInfo(unsigned id) { 34 assert(id > 0 && id - 1 < numTypes && "Invalid Type ID."); 35 return TypeInfos[id - 1]; 36} 37 38const char *types::getTypeName(ID Id) { 39 return getInfo(Id).Name; 40} 41 42types::ID types::getPreprocessedType(ID Id) { 43 return getInfo(Id).PreprocessedType; 44} 45 46const char *types::getTypeTempSuffix(ID Id) { 47 return getInfo(Id).TempSuffix; 48} 49 50bool types::onlyAssembleType(ID Id) { 51 return strchr(getInfo(Id).Flags, 'a'); 52} 53 54bool types::onlyPrecompileType(ID Id) { 55 return strchr(getInfo(Id).Flags, 'p'); 56} 57 58bool types::canTypeBeUserSpecified(ID Id) { 59 return strchr(getInfo(Id).Flags, 'u'); 60} 61 62bool types::appendSuffixForType(ID Id) { 63 return strchr(getInfo(Id).Flags, 'A'); 64} 65 66bool types::canLipoType(ID Id) { 67 return (Id == TY_Nothing || 68 Id == TY_Image || 69 Id == TY_Object); 70} 71 72bool 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 91bool 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 104types::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 152types::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 167unsigned 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 183phases::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