#include "casting.h" #include namespace types { std::vector create_casts() { std::vector casts{}; auto int_ty = std::shared_ptr{ new FundamentalType{ FundamentalTypeKind::Int } }; auto char_ty = std::shared_ptr{ new FundamentalType{ FundamentalTypeKind::Char } }; auto bool_ty = std::shared_ptr{ new FundamentalType{ FundamentalTypeKind::Bool } }; auto numerical_types = { int_ty, char_ty, bool_ty }; for (auto& source_ty : numerical_types) { for (auto& target_ty : numerical_types) { if (types::types_equal(source_ty, target_ty)) { casts.push_back(CastDefinition{ source_ty, target_ty, true, [](codegen::Builder&, std::shared_ptr, llvm::Value* value) { return value; } }); continue; } bool allow_implicit = false; if (target_ty->size() >= source_ty->size()) allow_implicit = true; if (target_ty->is_signed()) { casts.push_back(CastDefinition{ source_ty, target_ty, allow_implicit, [](codegen::Builder& builder, std::shared_ptr target, llvm::Value* value) { return builder.builder->CreateSExtOrTrunc(value, target->codegen(builder), "cast"); } }); } else { casts.push_back(CastDefinition{ source_ty, target_ty, allow_implicit, [](codegen::Builder& builder, std::shared_ptr target, llvm::Value* value) { return builder.builder->CreateZExtOrTrunc(value, target->codegen(builder), "cast"); } }); } } } return casts; } std::optional find_cast( std::vector& casts, std::shared_ptr casted_ty, std::shared_ptr target_ty) { if (casted_ty->m_kind == types::TypeKind::Array && target_ty->m_kind == types::TypeKind::Pointer) { auto array_ty = dynamic_cast(casted_ty.get()); auto ptr_ty = dynamic_cast(target_ty.get()); if (!types_equal(array_ty->m_inner, ptr_ty->m_inner)) return {}; return CastDefinition{ casted_ty, target_ty, true, [](codegen::Builder&, std::shared_ptr, llvm::Value* value) { // auto ptr_ty = dynamic_cast(target.get()); // std::vector indices {}; // indices.push_back(llvm::ConstantInt::get( // builder.builder->getInt32Ty(), // 0 // )); // return builder.builder->CreateGEP(ptr_ty->m_inner->codegen(builder), value, indices, "arraydecay"); return value; } }; } for (auto& cast : casts) { if (types_equal(cast.casted_ty, casted_ty) && types_equal(cast.target_ty, target_ty)) { return cast; } } return {}; } }