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