clang API Documentation
00001 //===--- Types.cpp - Driver input & temporary type information ------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "clang/Driver/Types.h" 00011 00012 #include "llvm/ADT/StringSwitch.h" 00013 #include <string.h> 00014 #include <cassert> 00015 00016 using namespace clang::driver; 00017 using namespace clang::driver::types; 00018 00019 struct TypeInfo { 00020 const char *Name; 00021 const char *Flags; 00022 const char *TempSuffix; 00023 ID PreprocessedType; 00024 }; 00025 00026 static const TypeInfo TypeInfos[] = { 00027 #define TYPE(NAME, ID, PP_TYPE, TEMP_SUFFIX, FLAGS) \ 00028 { NAME, FLAGS, TEMP_SUFFIX, TY_##PP_TYPE, }, 00029 #include "clang/Driver/Types.def" 00030 #undef TYPE 00031 }; 00032 static const unsigned numTypes = sizeof(TypeInfos) / sizeof(TypeInfos[0]); 00033 00034 static const TypeInfo &getInfo(unsigned id) { 00035 assert(id > 0 && id - 1 < numTypes && "Invalid Type ID."); 00036 return TypeInfos[id - 1]; 00037 } 00038 00039 const char *types::getTypeName(ID Id) { 00040 return getInfo(Id).Name; 00041 } 00042 00043 types::ID types::getPreprocessedType(ID Id) { 00044 return getInfo(Id).PreprocessedType; 00045 } 00046 00047 const char *types::getTypeTempSuffix(ID Id) { 00048 return getInfo(Id).TempSuffix; 00049 } 00050 00051 bool types::onlyAssembleType(ID Id) { 00052 return strchr(getInfo(Id).Flags, 'a'); 00053 } 00054 00055 bool types::onlyPrecompileType(ID Id) { 00056 return strchr(getInfo(Id).Flags, 'p'); 00057 } 00058 00059 bool types::canTypeBeUserSpecified(ID Id) { 00060 return strchr(getInfo(Id).Flags, 'u'); 00061 } 00062 00063 bool types::appendSuffixForType(ID Id) { 00064 return strchr(getInfo(Id).Flags, 'A'); 00065 } 00066 00067 bool types::canLipoType(ID Id) { 00068 return (Id == TY_Nothing || 00069 Id == TY_Image || 00070 Id == TY_Object); 00071 } 00072 00073 bool types::isAcceptedByClang(ID Id) { 00074 switch (Id) { 00075 default: 00076 return false; 00077 00078 case TY_Asm: 00079 case TY_C: case TY_PP_C: 00080 case TY_CL: 00081 case TY_CUDA: 00082 case TY_ObjC: case TY_PP_ObjC: case TY_PP_ObjC_Alias: 00083 case TY_CXX: case TY_PP_CXX: 00084 case TY_ObjCXX: case TY_PP_ObjCXX: case TY_PP_ObjCXX_Alias: 00085 case TY_CHeader: case TY_PP_CHeader: 00086 case TY_CLHeader: 00087 case TY_ObjCHeader: case TY_PP_ObjCHeader: 00088 case TY_CXXHeader: case TY_PP_CXXHeader: 00089 case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader: 00090 case TY_AST: 00091 case TY_LLVM_IR: case TY_LLVM_BC: 00092 return true; 00093 } 00094 } 00095 00096 bool types::isOnlyAcceptedByClang(ID Id) { 00097 switch (Id) { 00098 default: 00099 return false; 00100 00101 case TY_AST: 00102 case TY_LLVM_IR: 00103 case TY_LLVM_BC: 00104 case TY_RewrittenObjC: 00105 case TY_RewrittenLegacyObjC: 00106 return true; 00107 } 00108 } 00109 00110 bool types::isObjC(ID Id) { 00111 switch (Id) { 00112 default: 00113 return false; 00114 00115 case TY_ObjC: case TY_PP_ObjC: case TY_PP_ObjC_Alias: 00116 case TY_ObjCXX: case TY_PP_ObjCXX: 00117 case TY_ObjCHeader: case TY_PP_ObjCHeader: 00118 case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader: case TY_PP_ObjCXX_Alias: 00119 return true; 00120 } 00121 } 00122 00123 bool types::isCXX(ID Id) { 00124 switch (Id) { 00125 default: 00126 return false; 00127 00128 case TY_CXX: case TY_PP_CXX: 00129 case TY_ObjCXX: case TY_PP_ObjCXX: 00130 case TY_CXXHeader: case TY_PP_CXXHeader: 00131 case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader: 00132 case TY_CUDA: 00133 return true; 00134 } 00135 } 00136 00137 types::ID types::lookupTypeForExtension(const char *Ext) { 00138 return llvm::StringSwitch<types::ID>(Ext) 00139 .Case("c", TY_C) 00140 .Case("i", TY_PP_C) 00141 .Case("m", TY_ObjC) 00142 .Case("M", TY_ObjCXX) 00143 .Case("h", TY_CHeader) 00144 .Case("C", TY_CXX) 00145 .Case("H", TY_CXXHeader) 00146 .Case("f", TY_PP_Fortran) 00147 .Case("F", TY_Fortran) 00148 .Case("s", TY_PP_Asm) 00149 .Case("S", TY_Asm) 00150 .Case("o", TY_Object) 00151 .Case("ii", TY_PP_CXX) 00152 .Case("mi", TY_PP_ObjC) 00153 .Case("mm", TY_ObjCXX) 00154 .Case("bc", TY_LLVM_BC) 00155 .Case("cc", TY_CXX) 00156 .Case("CC", TY_CXX) 00157 .Case("cl", TY_CL) 00158 .Case("cp", TY_CXX) 00159 .Case("cu", TY_CUDA) 00160 .Case("hh", TY_CXXHeader) 00161 .Case("ll", TY_LLVM_IR) 00162 .Case("hpp", TY_CXXHeader) 00163 .Case("ads", TY_Ada) 00164 .Case("adb", TY_Ada) 00165 .Case("ast", TY_AST) 00166 .Case("c++", TY_CXX) 00167 .Case("C++", TY_CXX) 00168 .Case("cxx", TY_CXX) 00169 .Case("cpp", TY_CXX) 00170 .Case("CPP", TY_CXX) 00171 .Case("CXX", TY_CXX) 00172 .Case("for", TY_PP_Fortran) 00173 .Case("FOR", TY_PP_Fortran) 00174 .Case("fpp", TY_Fortran) 00175 .Case("FPP", TY_Fortran) 00176 .Case("f90", TY_PP_Fortran) 00177 .Case("f95", TY_PP_Fortran) 00178 .Case("F90", TY_Fortran) 00179 .Case("F95", TY_Fortran) 00180 .Case("mii", TY_PP_ObjCXX) 00181 .Default(TY_INVALID); 00182 } 00183 00184 types::ID types::lookupTypeForTypeSpecifier(const char *Name) { 00185 unsigned N = strlen(Name); 00186 00187 for (unsigned i=0; i<numTypes; ++i) { 00188 types::ID Id = (types::ID) (i + 1); 00189 if (canTypeBeUserSpecified(Id) && 00190 memcmp(Name, getInfo(Id).Name, N + 1) == 0) 00191 return Id; 00192 } 00193 00194 return TY_INVALID; 00195 } 00196 00197 // FIXME: Why don't we just put this list in the defs file, eh. 00198 00199 unsigned types::getNumCompilationPhases(ID Id) { 00200 if (Id == TY_Object) 00201 return 1; 00202 00203 unsigned N = 0; 00204 if (getPreprocessedType(Id) != TY_INVALID) 00205 N += 1; 00206 00207 if (onlyAssembleType(Id)) 00208 return N + 2; // assemble, link 00209 if (onlyPrecompileType(Id)) 00210 return N + 1; // precompile 00211 00212 return N + 3; // compile, assemble, link 00213 } 00214 00215 phases::ID types::getCompilationPhase(ID Id, unsigned N) { 00216 assert(N < getNumCompilationPhases(Id) && "Invalid index."); 00217 00218 if (Id == TY_Object) 00219 return phases::Link; 00220 00221 if (getPreprocessedType(Id) != TY_INVALID) { 00222 if (N == 0) 00223 return phases::Preprocess; 00224 --N; 00225 } 00226 00227 if (onlyAssembleType(Id)) 00228 return N == 0 ? phases::Assemble : phases::Link; 00229 00230 if (onlyPrecompileType(Id)) 00231 return phases::Precompile; 00232 00233 if (N == 0) 00234 return phases::Compile; 00235 if (N == 1) 00236 return phases::Assemble; 00237 00238 return phases::Link; 00239 } 00240 00241 ID types::lookupCXXTypeForCType(ID Id) { 00242 switch (Id) { 00243 default: 00244 return Id; 00245 00246 case types::TY_C: 00247 return types::TY_CXX; 00248 case types::TY_PP_C: 00249 return types::TY_PP_CXX; 00250 case types::TY_CHeader: 00251 return types::TY_CXXHeader; 00252 case types::TY_PP_CHeader: 00253 return types::TY_PP_CXXHeader; 00254 } 00255 }