CodeGenTypes.cpp revision 4e533287e6a9adac78c9ac370612581aad9b8c5e
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- CodeGenTypes.cpp - Type translation for LLVM CodeGen -------------===//
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
55f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This file was developed by Chris Lattner and is distributed under
65f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// the University of Illinois Open Source License. See LICENSE.TXT for details.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This is the code that handles AST -> LLVM type lowering.
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "CodeGenTypes.h"
155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/TargetInfo.h"
165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/AST/AST.h"
175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/DerivedTypes.h"
184e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlsson#include "llvm/Module.h"
195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang;
215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace CodeGen;
225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
234e533287e6a9adac78c9ac370612581aad9b8c5eAnders CarlssonCodeGenTypes::CodeGenTypes(ASTContext &Ctx, llvm::Module& M)
244e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlsson  : Context(Ctx), Target(Ctx.Target), TheModule(M) {
25d2d2a11a91d7ddf468bfb70f66362d24806ed601Chris Lattner}
265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ConvertType - Convert the specified type to its LLVM form.
285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerconst llvm::Type *CodeGenTypes::ConvertType(QualType T) {
295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // FIXME: Cache these, move the CodeGenModule, expand, etc.
305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const clang::Type &Ty = *T.getCanonicalType();
315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  switch (Ty.getTypeClass()) {
33d14faaa7ecbdf1dae6fa4b005b2993ba3ce30770Chris Lattner  case Type::TypeName:        // typedef isn't canonical.
34d14faaa7ecbdf1dae6fa4b005b2993ba3ce30770Chris Lattner  case Type::TypeOfExp:       // typeof isn't canonical.
35d14faaa7ecbdf1dae6fa4b005b2993ba3ce30770Chris Lattner  case Type::TypeOfTyp:       // typeof isn't canonical.
36d14faaa7ecbdf1dae6fa4b005b2993ba3ce30770Chris Lattner    assert(0 && "Non-canonical type, shouldn't happen");
375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Type::Builtin: {
385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    switch (cast<BuiltinType>(Ty).getKind()) {
395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case BuiltinType::Void:
405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      // LLVM void type can only be used as the result of a function call.  Just
415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      // map to the same as char.
42d2d2a11a91d7ddf468bfb70f66362d24806ed601Chris Lattner      return llvm::IntegerType::get(8);
435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case BuiltinType::Bool:
455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      // FIXME: This is very strange.  We want scalars to be i1, but in memory
465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      // they can be i1 or i32.  Should the codegen handle this issue?
475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return llvm::Type::Int1Ty;
485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
49d2d2a11a91d7ddf468bfb70f66362d24806ed601Chris Lattner    case BuiltinType::Char_S:
50d2d2a11a91d7ddf468bfb70f66362d24806ed601Chris Lattner    case BuiltinType::Char_U:
51d2d2a11a91d7ddf468bfb70f66362d24806ed601Chris Lattner    case BuiltinType::SChar:
52d2d2a11a91d7ddf468bfb70f66362d24806ed601Chris Lattner    case BuiltinType::UChar:
535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case BuiltinType::Short:
545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case BuiltinType::UShort:
555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case BuiltinType::Int:
565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case BuiltinType::UInt:
575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case BuiltinType::Long:
585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case BuiltinType::ULong:
595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case BuiltinType::LongLong:
605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case BuiltinType::ULongLong:
61d2d2a11a91d7ddf468bfb70f66362d24806ed601Chris Lattner      return llvm::IntegerType::get(Context.getTypeSize(T, SourceLocation()));
625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case BuiltinType::Float:      return llvm::Type::FloatTy;
645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case BuiltinType::Double:     return llvm::Type::DoubleTy;
655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case BuiltinType::LongDouble:
665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      // FIXME: mapping long double onto double.
675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return llvm::Type::DoubleTy;
685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Type::Complex: {
725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    std::vector<const llvm::Type*> Elts;
735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Elts.push_back(ConvertType(cast<ComplexType>(Ty).getElementType()));
745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Elts.push_back(Elts[0]);
755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return llvm::StructType::get(Elts);
765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Type::Pointer: {
785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    const PointerType &P = cast<PointerType>(Ty);
795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return llvm::PointerType::get(ConvertType(P.getPointeeType()));
805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Type::Reference: {
825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    const ReferenceType &R = cast<ReferenceType>(Ty);
835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return llvm::PointerType::get(ConvertType(R.getReferenceeType()));
845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Type::Array: {
875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    const ArrayType &A = cast<ArrayType>(Ty);
885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(A.getSizeModifier() == ArrayType::Normal &&
895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           A.getIndexTypeQualifier() == 0 &&
905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           "FIXME: We only handle trivial array types so far!");
915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    llvm::APSInt Size(32);
93590b6646ef747d2f7b42e5f40487ff07642d7b6fChris Lattner    if (A.getSizeExpr() &&
94590b6646ef747d2f7b42e5f40487ff07642d7b6fChris Lattner        A.getSizeExpr()->isIntegerConstantExpr(Size, Context)) {
955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      const llvm::Type *EltTy = ConvertType(A.getElementType());
965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return llvm::ArrayType::get(EltTy, Size.getZExtValue());
975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    } else {
985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      assert(0 && "FIXME: VLAs not implemented yet!");
995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
1005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
101a87b63b492553f1d47c418ad8849383aa3fd1ed1Chris Lattner  case Type::OCUVector:
1025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Type::Vector: {
1035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    const VectorType &VT = cast<VectorType>(Ty);
1045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return llvm::VectorType::get(ConvertType(VT.getElementType()),
1055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                 VT.getNumElements());
1065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Type::FunctionNoProto:
1085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Type::FunctionProto: {
1095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    const FunctionType &FP = cast<FunctionType>(Ty);
1105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    const llvm::Type *ResultType;
1115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (FP.getResultType()->isVoidType())
1135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      ResultType = llvm::Type::VoidTy;    // Result of function uses llvm void.
1145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    else
1155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      ResultType = ConvertType(FP.getResultType());
1165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // FIXME: Convert argument types.
1185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    bool isVarArg;
1195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    std::vector<const llvm::Type*> ArgTys;
1205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Struct return passes the struct byref.
1225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (!ResultType->isFirstClassType() && ResultType != llvm::Type::VoidTy) {
1235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      ArgTys.push_back(llvm::PointerType::get(ResultType));
1245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      ResultType = llvm::Type::VoidTy;
1255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
1265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(&FP)) {
1285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      DecodeArgumentTypes(*FTP, ArgTys);
1295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      isVarArg = FTP->isVariadic();
1305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    } else {
1315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      isVarArg = true;
1325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
1335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return llvm::FunctionType::get(ResultType, ArgTys, isVarArg, 0);
1355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case Type::Tagged:
1374e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlsson    const TagType &TT = cast<TagType>(Ty);
1384e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlsson    const TagDecl *TD = TT.getDecl();
1394e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlsson    llvm::Type *ResultType;
1404e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlsson
1414e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlsson    if (!TD->isDefinition()) {
1424e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlsson      ResultType = llvm::OpaqueType::get();
1434e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlsson    } else {
1444e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlsson      if (TD->getKind() == Decl::Struct) {
1454e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlsson        const RecordDecl *RD = cast<const RecordDecl>(TD);
1464e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlsson        std::vector<const llvm::Type*> Fields;
1474e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlsson        for (unsigned i = 0, e = RD->getNumMembers(); i != e; ++i)
1484e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlsson          Fields.push_back(ConvertType(RD->getMember(i)->getType()));
1494e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlsson        ResultType = llvm::StructType::get(Fields);
1504e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlsson      } else
1514e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlsson        assert(0 && "FIXME: Implement tag decl kind!");
1524e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlsson    }
1534e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlsson
1544e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlsson    std::string TypeName(TD->getKindName());
1554e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlsson    TypeName += '.';
1564e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlsson    TypeName += TD->getName();
1574e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlsson
1584e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlsson    TheModule.addTypeName(TypeName, ResultType);
1594e533287e6a9adac78c9ac370612581aad9b8c5eAnders Carlsson    return ResultType;
1605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // FIXME: implement.
1635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return llvm::OpaqueType::get();
1645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenTypes::DecodeArgumentTypes(const FunctionTypeProto &FTP,
1675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                       std::vector<const llvm::Type*> &ArgTys) {
1685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  for (unsigned i = 0, e = FTP.getNumArgs(); i != e; ++i) {
1695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    const llvm::Type *Ty = ConvertType(FTP.getArgType(i));
1705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (Ty->isFirstClassType())
1715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      ArgTys.push_back(Ty);
1725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    else
1735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      ArgTys.push_back(llvm::PointerType::get(Ty));
1745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
177