Types.cpp revision 199990
133965Sjdp//===--- Types.cpp - Driver input & temporary type information ----------*-===// 233965Sjdp// 333965Sjdp// The LLVM Compiler Infrastructure 433965Sjdp// 533965Sjdp// This file is distributed under the University of Illinois Open Source 633965Sjdp// License. See LICENSE.TXT for details. 733965Sjdp// 833965Sjdp//===----------------------------------------------------------------------===// 933965Sjdp 1033965Sjdp#include "clang/Driver/Types.h" 1133965Sjdp 1233965Sjdp#include "llvm/ADT/StringSwitch.h" 1333965Sjdp#include <string.h> 1433965Sjdp#include <cassert> 1533965Sjdp 1633965Sjdpusing namespace clang::driver; 1733965Sjdpusing namespace clang::driver::types; 1833965Sjdp 1933965Sjdpstruct TypeInfo { 2033965Sjdp const char *Name; 2133965Sjdp const char *Flags; 2233965Sjdp const char *TempSuffix; 2333965Sjdp ID PreprocessedType; 2433965Sjdp}; 2533965Sjdp 2633965Sjdpstatic TypeInfo TypeInfos[] = { 2733965Sjdp#define TYPE(NAME, ID, PP_TYPE, TEMP_SUFFIX, FLAGS) \ 2833965Sjdp { NAME, FLAGS, TEMP_SUFFIX, TY_##PP_TYPE, }, 2933965Sjdp#include "clang/Driver/Types.def" 3033965Sjdp#undef TYPE 3133965Sjdp}; 3233965Sjdpstatic const unsigned numTypes = sizeof(TypeInfos) / sizeof(TypeInfos[0]); 3333965Sjdp 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