CodeGenTypes.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. //===--- CodeGenTypes.cpp - Type translation for LLVM CodeGen -------------===//
  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 is the code that handles AST -> LLVM type lowering.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "CodeGenTypes.h"
  14. #include "clang/Basic/TargetInfo.h"
  15. #include "clang/AST/AST.h"
  16. #include "llvm/DerivedTypes.h"
  17. using namespace clang;
  18. using namespace CodeGen;
  19. /// ConvertType - Convert the specified type to its LLVM form.
  20. const llvm::Type *CodeGenTypes::ConvertType(QualType T) {
  21. // FIXME: Cache these, move the CodeGenModule, expand, etc.
  22. const clang::Type &Ty = *T.getCanonicalType();
  23. switch (Ty.getTypeClass()) {
  24. case Type::Builtin: {
  25. switch (cast<BuiltinType>(Ty).getKind()) {
  26. case BuiltinType::Void:
  27. // LLVM void type can only be used as the result of a function call. Just
  28. // map to the same as char.
  29. case BuiltinType::Char_S:
  30. case BuiltinType::Char_U:
  31. case BuiltinType::SChar:
  32. case BuiltinType::UChar:
  33. return llvm::IntegerType::get(Target.getCharWidth(SourceLocation()));
  34. case BuiltinType::Bool:
  35. // FIXME: This is very strange. We want scalars to be i1, but in memory
  36. // they can be i1 or i32. Should the codegen handle this issue?
  37. return llvm::Type::Int1Ty;
  38. case BuiltinType::Short:
  39. case BuiltinType::UShort:
  40. return llvm::IntegerType::get(Target.getShortWidth(SourceLocation()));
  41. case BuiltinType::Int:
  42. case BuiltinType::UInt:
  43. return llvm::IntegerType::get(Target.getIntWidth(SourceLocation()));
  44. case BuiltinType::Long:
  45. case BuiltinType::ULong:
  46. return llvm::IntegerType::get(Target.getLongWidth(SourceLocation()));
  47. case BuiltinType::LongLong:
  48. case BuiltinType::ULongLong:
  49. return llvm::IntegerType::get(Target.getLongLongWidth(SourceLocation()));
  50. case BuiltinType::Float: return llvm::Type::FloatTy;
  51. case BuiltinType::Double: return llvm::Type::DoubleTy;
  52. case BuiltinType::LongDouble:
  53. // FIXME: mapping long double onto double.
  54. return llvm::Type::DoubleTy;
  55. }
  56. break;
  57. }
  58. case Type::Complex: {
  59. std::vector<const llvm::Type*> Elts;
  60. Elts.push_back(ConvertType(cast<ComplexType>(Ty).getElementType()));
  61. Elts.push_back(Elts[0]);
  62. return llvm::StructType::get(Elts);
  63. }
  64. case Type::Pointer: {
  65. const PointerType &P = cast<PointerType>(Ty);
  66. return llvm::PointerType::get(ConvertType(P.getPointeeType()));
  67. }
  68. case Type::Reference: {
  69. const ReferenceType &R = cast<ReferenceType>(Ty);
  70. return llvm::PointerType::get(ConvertType(R.getReferenceeType()));
  71. }
  72. case Type::Array: {
  73. const ArrayType &A = cast<ArrayType>(Ty);
  74. assert(A.getSizeModifier() == ArrayType::Normal &&
  75. A.getIndexTypeQualifier() == 0 &&
  76. "FIXME: We only handle trivial array types so far!");
  77. llvm::APSInt Size(32);
  78. if (A.getSize() && A.getSize()->isIntegerConstantExpr(Size)) {
  79. const llvm::Type *EltTy = ConvertType(A.getElementType());
  80. return llvm::ArrayType::get(EltTy, Size.getZExtValue());
  81. } else {
  82. assert(0 && "FIXME: VLAs not implemented yet!");
  83. }
  84. }
  85. case Type::Vector: {
  86. const VectorType &VT = cast<VectorType>(Ty);
  87. return llvm::VectorType::get(ConvertType(VT.getElementType()),
  88. VT.getNumElements());
  89. }
  90. case Type::FunctionNoProto:
  91. case Type::FunctionProto: {
  92. const FunctionType &FP = cast<FunctionType>(Ty);
  93. const llvm::Type *ResultType;
  94. if (FP.getResultType()->isVoidType())
  95. ResultType = llvm::Type::VoidTy; // Result of function uses llvm void.
  96. else
  97. ResultType = ConvertType(FP.getResultType());
  98. // FIXME: Convert argument types.
  99. bool isVarArg;
  100. std::vector<const llvm::Type*> ArgTys;
  101. // Struct return passes the struct byref.
  102. if (!ResultType->isFirstClassType() && ResultType != llvm::Type::VoidTy) {
  103. ArgTys.push_back(llvm::PointerType::get(ResultType));
  104. ResultType = llvm::Type::VoidTy;
  105. }
  106. if (const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(&FP)) {
  107. DecodeArgumentTypes(*FTP, ArgTys);
  108. isVarArg = FTP->isVariadic();
  109. } else {
  110. isVarArg = true;
  111. }
  112. return llvm::FunctionType::get(ResultType, ArgTys, isVarArg, 0);
  113. }
  114. case Type::TypeName:
  115. case Type::Tagged:
  116. break;
  117. }
  118. // FIXME: implement.
  119. return llvm::OpaqueType::get();
  120. }
  121. void CodeGenTypes::DecodeArgumentTypes(const FunctionTypeProto &FTP,
  122. std::vector<const llvm::Type*> &ArgTys) {
  123. for (unsigned i = 0, e = FTP.getNumArgs(); i != e; ++i) {
  124. const llvm::Type *Ty = ConvertType(FTP.getArgType(i));
  125. if (Ty->isFirstClassType())
  126. ArgTys.push_back(Ty);
  127. else
  128. ArgTys.push_back(llvm::PointerType::get(Ty));
  129. }
  130. }