static const llvm::Type *makeLLVMType(TypePtr t) { switch (t->typeKind) { case BOOL_TYPE : return llvmIntType(8); case INTEGER_TYPE : { IntegerType *x = (IntegerType *)t.ptr(); return llvmIntType(x->bits); } case FLOAT_TYPE : { FloatType *x = (FloatType *)t.ptr(); return llvmFloatType(x->bits); } case POINTER_TYPE : { PointerType *x = (PointerType *)t.ptr(); return llvmPointerType(x->pointeeType); } case CODE_POINTER_TYPE : { CodePointerType *x = (CodePointerType *)t.ptr(); vector<const llvm::Type *> llArgTypes; for (unsigned i = 0; i < x->argTypes.size(); ++i) llArgTypes.push_back(llvmPointerType(x->argTypes[i])); for (unsigned i = 0; i < x->returnTypes.size(); ++i) { TypePtr t = x->returnTypes[i]; if (x->returnIsRef[i]) llArgTypes.push_back(llvmPointerType(pointerType(t))); else llArgTypes.push_back(llvmPointerType(t)); } llvm::FunctionType *llFuncType = llvm::FunctionType::get(llvmIntType(32), llArgTypes, false); return llvm::PointerType::getUnqual(llFuncType); } case CCODE_POINTER_TYPE : { CCodePointerType *x = (CCodePointerType *)t.ptr(); vector<const llvm::Type *> llArgTypes; for (unsigned i = 0; i < x->argTypes.size(); ++i) llArgTypes.push_back(llvmType(x->argTypes[i])); const llvm::Type *llReturnType = x->returnType.ptr() ? llvmType(x->returnType) : llvmVoidType(); llvm::FunctionType *llFuncType = llvm::FunctionType::get(llReturnType, llArgTypes, x->hasVarArgs); return llvm::PointerType::getUnqual(llFuncType); } case ARRAY_TYPE : { ArrayType *x = (ArrayType *)t.ptr(); return llvmArrayType(x->elementType, x->size); } case VEC_TYPE : { VecType *x = (VecType *)t.ptr(); return llvm::VectorType::get(llvmType(x->elementType), x->size); } case TUPLE_TYPE : { TupleType *x = (TupleType *)t.ptr(); vector<const llvm::Type *> llTypes; vector<TypePtr>::iterator i, end; for (i = x->elementTypes.begin(), end = x->elementTypes.end(); i != end; ++i) llTypes.push_back(llvmType(*i)); if (x->elementTypes.empty()) llTypes.push_back(llvmIntType(8)); return llvm::StructType::get(llvm::getGlobalContext(), llTypes); } case UNION_TYPE : { UnionType *x = (UnionType *)t.ptr(); const llvm::Type *maxAlignType = NULL; size_t maxAlign = 0; size_t maxAlignSize = 0; size_t maxSize = 0; for (unsigned i = 0; i < x->memberTypes.size(); ++i) { const llvm::Type *llt = makeLLVMApproximateType(x->memberTypes[i]); size_t align = llvmTargetData->getABITypeAlignment(llt); size_t size = llvmTargetData->getTypeAllocSize(llt); if (align > maxAlign) { maxAlign = align; maxAlignType = llt; maxAlignSize = size; } if (size > maxSize) maxSize = size; } if (!maxAlignType) { maxAlignType = llvmIntType(8); maxAlign = 1; } vector<const llvm::Type *> llTypes; llTypes.push_back(maxAlignType); if (maxSize > maxAlignSize) { const llvm::Type *padding = llvm::ArrayType::get(llvmIntType(8), maxSize-maxAlignSize); llTypes.push_back(padding); } return llvm::StructType::get(llvm::getGlobalContext(), llTypes); } case RECORD_TYPE : { RecordType *x = (RecordType *)t.ptr(); const vector<TypePtr> &fieldTypes = recordFieldTypes(x); vector<const llvm::Type *> llTypes; vector<TypePtr>::const_iterator i, end; for (i = fieldTypes.begin(), end = fieldTypes.end(); i != end; ++i) llTypes.push_back(llvmType(*i)); if (fieldTypes.empty()) llTypes.push_back(llvmIntType(8)); return llvm::StructType::get(llvm::getGlobalContext(), llTypes); } case VARIANT_TYPE : { VariantType *x = (VariantType *)t.ptr(); return llvmType(variantReprType(x)); } case STATIC_TYPE : { vector<const llvm::Type *> llTypes; llTypes.push_back(llvmIntType(8)); return llvm::StructType::get(llvm::getGlobalContext(), llTypes); } case ENUM_TYPE : { return llvmType(cIntType); } default : assert(false); return NULL; } }
llvm::Constant *llvmFP(double val, unsigned bits) { return llvm::ConstantFP::get(llvmFloatType(), val); }