123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- //===--- CodeGenTypes.cpp - Type translation for LLVM CodeGen -------------===//
- //
- // The LLVM Compiler Infrastructure
- //
- // This file was developed by Chris Lattner and is distributed under
- // the University of Illinois Open Source License. See LICENSE.TXT for details.
- //
- //===----------------------------------------------------------------------===//
- //
- // This is the code that handles AST -> LLVM type lowering.
- //
- //===----------------------------------------------------------------------===//
- #include "CodeGenTypes.h"
- #include "clang/Basic/TargetInfo.h"
- #include "clang/AST/AST.h"
- #include "llvm/DerivedTypes.h"
- using namespace clang;
- using namespace CodeGen;
- /// ConvertType - Convert the specified type to its LLVM form.
- const llvm::Type *CodeGenTypes::ConvertType(QualType T) {
- // FIXME: Cache these, move the CodeGenModule, expand, etc.
- const clang::Type &Ty = *T.getCanonicalType();
-
- switch (Ty.getTypeClass()) {
- case Type::Builtin: {
- switch (cast<BuiltinType>(Ty).getKind()) {
- case BuiltinType::Void:
- // LLVM void type can only be used as the result of a function call. Just
- // map to the same as char.
- case BuiltinType::Char_S:
- case BuiltinType::Char_U:
- case BuiltinType::SChar:
- case BuiltinType::UChar:
- return llvm::IntegerType::get(Target.getCharWidth(SourceLocation()));
- case BuiltinType::Bool:
- // FIXME: This is very strange. We want scalars to be i1, but in memory
- // they can be i1 or i32. Should the codegen handle this issue?
- return llvm::Type::Int1Ty;
-
- case BuiltinType::Short:
- case BuiltinType::UShort:
- return llvm::IntegerType::get(Target.getShortWidth(SourceLocation()));
-
- case BuiltinType::Int:
- case BuiltinType::UInt:
- return llvm::IntegerType::get(Target.getIntWidth(SourceLocation()));
- case BuiltinType::Long:
- case BuiltinType::ULong:
- return llvm::IntegerType::get(Target.getLongWidth(SourceLocation()));
- case BuiltinType::LongLong:
- case BuiltinType::ULongLong:
- return llvm::IntegerType::get(Target.getLongLongWidth(SourceLocation()));
-
- case BuiltinType::Float: return llvm::Type::FloatTy;
- case BuiltinType::Double: return llvm::Type::DoubleTy;
- case BuiltinType::LongDouble:
- // FIXME: mapping long double onto double.
- return llvm::Type::DoubleTy;
- }
- break;
- }
- case Type::Complex: {
- std::vector<const llvm::Type*> Elts;
- Elts.push_back(ConvertType(cast<ComplexType>(Ty).getElementType()));
- Elts.push_back(Elts[0]);
- return llvm::StructType::get(Elts);
- }
- case Type::Pointer: {
- const PointerType &P = cast<PointerType>(Ty);
- return llvm::PointerType::get(ConvertType(P.getPointeeType()));
- }
- case Type::Reference: {
- const ReferenceType &R = cast<ReferenceType>(Ty);
- return llvm::PointerType::get(ConvertType(R.getReferenceeType()));
- }
-
- case Type::Array: {
- const ArrayType &A = cast<ArrayType>(Ty);
- assert(A.getSizeModifier() == ArrayType::Normal &&
- A.getIndexTypeQualifier() == 0 &&
- "FIXME: We only handle trivial array types so far!");
-
- llvm::APSInt Size(32);
- if (A.getSize() && A.getSize()->isIntegerConstantExpr(Size)) {
- const llvm::Type *EltTy = ConvertType(A.getElementType());
- return llvm::ArrayType::get(EltTy, Size.getZExtValue());
- } else {
- assert(0 && "FIXME: VLAs not implemented yet!");
- }
- }
- case Type::Vector: {
- const VectorType &VT = cast<VectorType>(Ty);
- return llvm::VectorType::get(ConvertType(VT.getElementType()),
- VT.getNumElements());
- }
- case Type::FunctionNoProto:
- case Type::FunctionProto: {
- const FunctionType &FP = cast<FunctionType>(Ty);
- const llvm::Type *ResultType;
-
- if (FP.getResultType()->isVoidType())
- ResultType = llvm::Type::VoidTy; // Result of function uses llvm void.
- else
- ResultType = ConvertType(FP.getResultType());
-
- // FIXME: Convert argument types.
- bool isVarArg;
- std::vector<const llvm::Type*> ArgTys;
-
- // Struct return passes the struct byref.
- if (!ResultType->isFirstClassType() && ResultType != llvm::Type::VoidTy) {
- ArgTys.push_back(llvm::PointerType::get(ResultType));
- ResultType = llvm::Type::VoidTy;
- }
-
- if (const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(&FP)) {
- DecodeArgumentTypes(*FTP, ArgTys);
- isVarArg = FTP->isVariadic();
- } else {
- isVarArg = true;
- }
-
- return llvm::FunctionType::get(ResultType, ArgTys, isVarArg, 0);
- }
- case Type::TypeName:
- case Type::Tagged:
- break;
- }
-
- // FIXME: implement.
- return llvm::OpaqueType::get();
- }
- void CodeGenTypes::DecodeArgumentTypes(const FunctionTypeProto &FTP,
- std::vector<const llvm::Type*> &ArgTys) {
- for (unsigned i = 0, e = FTP.getNumArgs(); i != e; ++i) {
- const llvm::Type *Ty = ConvertType(FTP.getArgType(i));
- if (Ty->isFirstClassType())
- ArgTys.push_back(Ty);
- else
- ArgTys.push_back(llvm::PointerType::get(Ty));
- }
- }
|