Types.cpp 5.9 KB

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