Builtins.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. //===--- Builtins.cpp - Builtin function implementation -------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file was developed by Chris Lattner and is distributed under
  6. // the University of Illinois Open Source License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file implements various things for builtin functions.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "clang/AST/Builtins.h"
  14. #include "clang/AST/ASTContext.h"
  15. #include "clang/Lex/IdentifierTable.h"
  16. #include "clang/Basic/TargetInfo.h"
  17. using namespace clang;
  18. static const Builtin::Info BuiltinInfo[] = {
  19. { "not a builtin function", 0, 0 },
  20. #define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
  21. #include "clang/AST/Builtins.def"
  22. };
  23. const Builtin::Info &Builtin::Context::GetRecord(unsigned ID) const {
  24. if (ID < Builtin::FirstTSBuiltin)
  25. return BuiltinInfo[ID];
  26. assert(ID - Builtin::FirstTSBuiltin < NumTSRecords && "Invalid builtin ID!");
  27. return TSRecords[ID - Builtin::FirstTSBuiltin];
  28. }
  29. /// InitializeBuiltins - Mark the identifiers for all the builtins with their
  30. /// appropriate builtin ID # and mark any non-portable builtin identifiers as
  31. /// such.
  32. void Builtin::Context::InitializeBuiltins(IdentifierTable &Table,
  33. const TargetInfo &Target) {
  34. // Step #1: mark all target-independent builtins with their ID's.
  35. for (unsigned i = Builtin::NotBuiltin+1; i != Builtin::FirstTSBuiltin; ++i)
  36. Table.get(BuiltinInfo[i].Name).setBuiltinID(i);
  37. // Step #2: handle target builtins.
  38. std::vector<const char *> NonPortableBuiltins;
  39. Target.getTargetBuiltins(TSRecords, NumTSRecords, NonPortableBuiltins);
  40. // Step #2a: Register target-specific builtins.
  41. for (unsigned i = 0, e = NumTSRecords; i != e; ++i)
  42. Table.get(TSRecords[i].Name).setBuiltinID(i+Builtin::FirstTSBuiltin);
  43. // Step #2b: Mark non-portable builtins as such.
  44. for (unsigned i = 0, e = NonPortableBuiltins.size(); i != e; ++i)
  45. Table.get(NonPortableBuiltins[i]).setNonPortableBuiltin(true);
  46. }
  47. /// DecodeTypeFromStr - This decodes one type descriptor from Str, advancing the
  48. /// pointer over the consumed characters. This returns the resultant type.
  49. static QualType DecodeTypeFromStr(const char *&Str, ASTContext &Context) {
  50. // Modifiers.
  51. bool Long = false, LongLong = false, Signed = false, Unsigned = false;
  52. // Read the modifiers first.
  53. bool Done = false;
  54. while (!Done) {
  55. switch (*Str++) {
  56. default: Done = true; --Str; break;
  57. case 'S':
  58. assert(!Unsigned && "Can't use both 'S' and 'U' modifiers!");
  59. assert(!Signed && "Can't use 'S' modifier multiple times!");
  60. Signed = true;
  61. break;
  62. case 'U':
  63. assert(!Signed && "Can't use both 'S' and 'U' modifiers!");
  64. assert(!Unsigned && "Can't use 'S' modifier multiple times!");
  65. Unsigned = true;
  66. break;
  67. case 'L':
  68. assert(!LongLong && "Can't have LLL modifier");
  69. if (Long)
  70. LongLong = true;
  71. else
  72. Long = true;
  73. break;
  74. }
  75. }
  76. // Read the base type.
  77. switch (*Str++) {
  78. default: assert(0 && "Unknown builtin type letter!");
  79. case 'v':
  80. assert(!Long && !Signed && !Unsigned && "Bad modifiers used with 'f'!");
  81. return Context.VoidTy;
  82. case 'f':
  83. assert(!Long && !Signed && !Unsigned && "Bad modifiers used with 'f'!");
  84. return Context.FloatTy;
  85. case 'd':
  86. assert(!LongLong && !Signed && !Unsigned && "Bad modifiers used with 'd'!");
  87. if (Long)
  88. return Context.LongDoubleTy;
  89. return Context.DoubleTy;
  90. case 's':
  91. assert(!LongLong && "Bad modifiers used with 's'!");
  92. if (Unsigned)
  93. return Context.UnsignedShortTy;
  94. return Context.ShortTy;
  95. //case 'i':
  96. }
  97. }
  98. /// GetBuiltinType - Return the type for the specified builtin.
  99. QualType Builtin::Context::GetBuiltinType(unsigned id, ASTContext &Context)const{
  100. const char *TypeStr = GetRecord(id).Type;
  101. llvm::SmallVector<QualType, 8> ArgTypes;
  102. QualType ResType = DecodeTypeFromStr(TypeStr, Context);
  103. while (TypeStr[0] && TypeStr[0] != '.')
  104. ArgTypes.push_back(DecodeTypeFromStr(TypeStr, Context));
  105. assert((TypeStr[0] != '.' || TypeStr[1] == 0) &&
  106. "'.' should only occur at end of builtin type list!");
  107. return Context.getFunctionType(ResType, &ArgTypes[0], ArgTypes.size(),
  108. TypeStr[0] == '.');
  109. }