diff options
Diffstat (limited to 'src/parseh.cpp')
| -rw-r--r-- | src/parseh.cpp | 401 |
1 files changed, 371 insertions, 30 deletions
diff --git a/src/parseh.cpp b/src/parseh.cpp index 0d8bfd9dfe..48a23a90b6 100644 --- a/src/parseh.cpp +++ b/src/parseh.cpp @@ -276,18 +276,22 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const return get_c_int_type(c->codegen, CIntTypeLong); case BuiltinType::LongLong: return get_c_int_type(c->codegen, CIntTypeLongLong); + case BuiltinType::UInt128: + return c->codegen->builtin_types.entry_u128; + case BuiltinType::Int128: + return c->codegen->builtin_types.entry_i128; case BuiltinType::Float: return c->codegen->builtin_types.entry_f32; case BuiltinType::Double: return c->codegen->builtin_types.entry_f64; + case BuiltinType::Float128: + return c->codegen->builtin_types.entry_f128; case BuiltinType::LongDouble: return c->codegen->builtin_types.entry_c_longdouble; case BuiltinType::WChar_U: case BuiltinType::Char16: case BuiltinType::Char32: - case BuiltinType::UInt128: case BuiltinType::WChar_S: - case BuiltinType::Int128: case BuiltinType::Half: case BuiltinType::NullPtr: case BuiltinType::ObjCId: @@ -338,7 +342,6 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const case BuiltinType::OCLImage2dMSAADepthRW: case BuiltinType::OCLImage2dArrayMSAADepthRW: case BuiltinType::OCLImage3dRW: - case BuiltinType::Float128: case BuiltinType::OCLSampler: case BuiltinType::OCLEvent: case BuiltinType::OCLClkEvent: @@ -606,13 +609,70 @@ static TypeTableEntry *resolve_qual_type(Context *c, QualType qt, const Decl *de #include "ast_render.hpp" -static AstNode * ast_trans_stmt(Context *c, Stmt *stmt); +static bool c_is_signed_integer(Context *c, QualType qt) { + const Type *c_type = qt.getTypePtr(); + if (c_type->getTypeClass() != Type::Builtin) + return false; + const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(c_type); + switch (builtin_ty->getKind()) { + case BuiltinType::SChar: + case BuiltinType::Short: + case BuiltinType::Int: + case BuiltinType::Long: + case BuiltinType::LongLong: + case BuiltinType::Int128: + case BuiltinType::WChar_S: + return true; + default: + return false; + } +} + +static bool c_is_unsigned_integer(Context *c, QualType qt) { + const Type *c_type = qt.getTypePtr(); + if (c_type->getTypeClass() != Type::Builtin) + return false; + const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(c_type); + switch (builtin_ty->getKind()) { + case BuiltinType::Char_U: + case BuiltinType::UChar: + case BuiltinType::Char_S: + case BuiltinType::UShort: + case BuiltinType::UInt: + case BuiltinType::ULong: + case BuiltinType::ULongLong: + case BuiltinType::UInt128: + case BuiltinType::WChar_U: + return true; + default: + return false; + } +} -static AstNode * ast_trans_expr(Context *c, Expr *expr) { - return ast_trans_stmt(c, expr); +static bool c_is_float(Context *c, QualType qt) { + const Type *c_type = qt.getTypePtr(); + if (c_type->getTypeClass() != Type::Builtin) + return false; + const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(c_type); + switch (builtin_ty->getKind()) { + case BuiltinType::Half: + case BuiltinType::Float: + case BuiltinType::Double: + case BuiltinType::Float128: + case BuiltinType::LongDouble: + return true; + default: + return false; + } } -static AstNode * ast_create_node(Context *c, const SourceRange &range, NodeType id) { +static AstNode * trans_stmt(Context *c, Stmt *stmt); + +static AstNode * trans_expr(Context *c, Expr *expr) { + return trans_stmt(c, expr); +} + +static AstNode * trans_create_node(Context *c, Stmt *stmt, NodeType id) { AstNode *node = allocate<AstNode>(1); node->type = id; node->owner = c->import; @@ -620,22 +680,22 @@ static AstNode * ast_create_node(Context *c, const SourceRange &range, NodeType return node; } -static AstNode * ast_trans_compound_stmt(Context *c, CompoundStmt *stmt) { - AstNode *block_node = ast_create_node(c, stmt->getSourceRange(), NodeTypeBlock); +static AstNode * trans_compound_stmt(Context *c, CompoundStmt *stmt) { + AstNode *block_node = trans_create_node(c, stmt, NodeTypeBlock); for (CompoundStmt::body_iterator it = stmt->body_begin(), end_it = stmt->body_end(); it != end_it; ++it) { - AstNode *child_node = ast_trans_stmt(c, *it); + AstNode *child_node = trans_stmt(c, *it); block_node->data.block.statements.append(child_node); } return block_node; } -static AstNode *ast_trans_return_stmt(Context *c, ReturnStmt *stmt) { +static AstNode *trans_return_stmt(Context *c, ReturnStmt *stmt) { Expr *value_expr = stmt->getRetValue(); if (value_expr == nullptr) { zig_panic("TODO handle C return void"); } else { - AstNode *return_node = ast_create_node(c, stmt->getSourceRange(), NodeTypeReturnExpr); - return_node->data.return_expr.expr = ast_trans_expr(c, value_expr); + AstNode *return_node = trans_create_node(c, stmt, NodeTypeReturnExpr); + return_node->data.return_expr.expr = trans_expr(c, value_expr); return return_node; } } @@ -656,8 +716,9 @@ static void aps_int_to_bigint(Context *c, const llvm::APSInt &aps_int, BigInt *b } } } -static AstNode * ast_trans_integer_literal(Context *c, IntegerLiteral *stmt) { - AstNode *node = ast_create_node(c, stmt->getSourceRange(), NodeTypeIntLiteral); + +static AstNode * trans_integer_literal(Context *c, IntegerLiteral *stmt) { + AstNode *node = trans_create_node(c, stmt, NodeTypeIntLiteral); llvm::APSInt result; if (!stmt->EvaluateAsInt(result, *c->ctx)) { fprintf(stderr, "TODO unable to convert integer literal to zig\n"); @@ -667,15 +728,305 @@ static AstNode * ast_trans_integer_literal(Context *c, IntegerLiteral *stmt) { return node; } -static AstNode *ast_trans_stmt(Context *c, Stmt *stmt) { +static AstNode * trans_conditional_operator(Context *c, ConditionalOperator *stmt) { + AstNode *node = trans_create_node(c, stmt, NodeTypeIfBoolExpr); + + Expr *cond_expr = stmt->getCond(); + Expr *true_expr = stmt->getTrueExpr(); + Expr *false_expr = stmt->getFalseExpr(); + + node->data.if_bool_expr.condition = trans_expr(c, cond_expr); + node->data.if_bool_expr.then_block = trans_expr(c, true_expr); + node->data.if_bool_expr.else_node = trans_expr(c, false_expr); + + return node; +} + +static AstNode * trans_binary_operator(Context *c, BinaryOperator *stmt) { + switch (stmt->getOpcode()) { + case BO_PtrMemD: + zig_panic("TODO handle more C binary operators: BO_PtrMemD"); + case BO_PtrMemI: + zig_panic("TODO handle more C binary operators: BO_PtrMemI"); + case BO_Mul: + zig_panic("TODO handle more C binary operators: BO_Mul"); + case BO_Div: + zig_panic("TODO handle more C binary operators: BO_Div"); + case BO_Rem: + zig_panic("TODO handle more C binary operators: BO_Rem"); + case BO_Add: + zig_panic("TODO handle more C binary operators: BO_Add"); + case BO_Sub: + zig_panic("TODO handle more C binary operators: BO_Sub"); + case BO_Shl: + zig_panic("TODO handle more C binary operators: BO_Shl"); + case BO_Shr: + zig_panic("TODO handle more C binary operators: BO_Shr"); + case BO_LT: + { + AstNode *node = trans_create_node(c, stmt, NodeTypeBinOpExpr); + node->data.bin_op_expr.bin_op = BinOpTypeCmpLessThan; + node->data.bin_op_expr.op1 = trans_expr(c, stmt->getLHS()); + node->data.bin_op_expr.op2 = trans_expr(c, stmt->getRHS()); + return node; + } + case BO_GT: + zig_panic("TODO handle more C binary operators: BO_GT"); + case BO_LE: + zig_panic("TODO handle more C binary operators: BO_LE"); + case BO_GE: + zig_panic("TODO handle more C binary operators: BO_GE"); + case BO_EQ: + zig_panic("TODO handle more C binary operators: BO_EQ"); + case BO_NE: + zig_panic("TODO handle more C binary operators: BO_NE"); + case BO_And: + zig_panic("TODO handle more C binary operators: BO_And"); + case BO_Xor: + zig_panic("TODO handle more C binary operators: BO_Xor"); + case BO_Or: + zig_panic("TODO handle more C binary operators: BO_Or"); + case BO_LAnd: + zig_panic("TODO handle more C binary operators: BO_LAnd"); + case BO_LOr: + zig_panic("TODO handle more C binary operators: BO_LOr"); + case BO_Assign: + zig_panic("TODO handle more C binary operators: BO_Assign"); + case BO_MulAssign: + zig_panic("TODO handle more C binary operators: BO_MulAssign"); + case BO_DivAssign: + zig_panic("TODO handle more C binary operators: BO_DivAssign"); + case BO_RemAssign: + zig_panic("TODO handle more C binary operators: BO_RemAssign"); + case BO_AddAssign: + zig_panic("TODO handle more C binary operators: BO_AddAssign"); + case BO_SubAssign: + zig_panic("TODO handle more C binary operators: BO_SubAssign"); + case BO_ShlAssign: + zig_panic("TODO handle more C binary operators: BO_ShlAssign"); + case BO_ShrAssign: + zig_panic("TODO handle more C binary operators: BO_ShrAssign"); + case BO_AndAssign: + zig_panic("TODO handle more C binary operators: BO_AndAssign"); + case BO_XorAssign: + zig_panic("TODO handle more C binary operators: BO_XorAssign"); + case BO_OrAssign: + zig_panic("TODO handle more C binary operators: BO_OrAssign"); + case BO_Comma: + zig_panic("TODO handle more C binary operators: BO_Comma"); + } + + zig_unreachable(); +} + +static AstNode * trans_implicit_cast_expr(Context *c, ImplicitCastExpr *stmt) { + switch (stmt->getCastKind()) { + case CK_LValueToRValue: + return trans_expr(c, stmt->getSubExpr()); + case CK_Dependent: + zig_panic("TODO handle C translation cast CK_Dependent"); + case CK_BitCast: + zig_panic("TODO handle C translation cast CK_BitCast"); + case CK_LValueBitCast: + zig_panic("TODO handle C translation cast CK_LValueBitCast"); + case CK_NoOp: + zig_panic("TODO handle C translation cast CK_NoOp"); + case CK_BaseToDerived: + zig_panic("TODO handle C translation cast CK_BaseToDerived"); + case CK_DerivedToBase: + zig_panic("TODO handle C translation cast CK_DerivedToBase"); + case CK_UncheckedDerivedToBase: + zig_panic("TODO handle C translation cast CK_UncheckedDerivedToBase"); + case CK_Dynamic: + zig_panic("TODO handle C translation cast CK_Dynamic"); + case CK_ToUnion: + zig_panic("TODO handle C translation cast CK_ToUnion"); + case CK_ArrayToPointerDecay: + zig_panic("TODO handle C translation cast CK_ArrayToPointerDecay"); + case CK_FunctionToPointerDecay: + zig_panic("TODO handle C translation cast CK_FunctionToPointerDecay"); + case CK_NullToPointer: + zig_panic("TODO handle C translation cast CK_NullToPointer"); + case CK_NullToMemberPointer: + zig_panic("TODO handle C translation cast CK_NullToMemberPointer"); + case CK_BaseToDerivedMemberPointer: + zig_panic("TODO handle C translation cast CK_BaseToDerivedMemberPointer"); + case CK_DerivedToBaseMemberPointer: + zig_panic("TODO handle C translation cast CK_DerivedToBaseMemberPointer"); + case CK_MemberPointerToBoolean: + zig_panic("TODO handle C translation cast CK_MemberPointerToBoolean"); + case CK_ReinterpretMemberPointer: + zig_panic("TODO handle C translation cast CK_ReinterpretMemberPointer"); + case CK_UserDefinedConversion: + zig_panic("TODO handle C translation cast CK_UserDefinedConversion"); + case CK_ConstructorConversion: + zig_panic("TODO handle C translation cast CK_ConstructorConversion"); + case CK_IntegralToPointer: + zig_panic("TODO handle C translation cast CK_IntegralToPointer"); + case CK_PointerToIntegral: + zig_panic("TODO handle C translation cast CK_PointerToIntegral"); + case CK_PointerToBoolean: + zig_panic("TODO handle C translation cast CK_PointerToBoolean"); + case CK_ToVoid: + zig_panic("TODO handle C translation cast CK_ToVoid"); + case CK_VectorSplat: + zig_panic("TODO handle C translation cast CK_VectorSplat"); + case CK_IntegralCast: + zig_panic("TODO handle C translation cast CK_IntegralCast"); + case CK_IntegralToBoolean: + zig_panic("TODO handle C translation cast CK_IntegralToBoolean"); + case CK_IntegralToFloating: + zig_panic("TODO handle C translation cast CK_IntegralToFloating"); + case CK_FloatingToIntegral: + zig_panic("TODO handle C translation cast CK_FloatingToIntegral"); + case CK_FloatingToBoolean: + zig_panic("TODO handle C translation cast CK_FloatingToBoolean"); + case CK_BooleanToSignedIntegral: + zig_panic("TODO handle C translation cast CK_BooleanToSignedIntegral"); + case CK_FloatingCast: + zig_panic("TODO handle C translation cast CK_FloatingCast"); + case CK_CPointerToObjCPointerCast: + zig_panic("TODO handle C translation cast CK_CPointerToObjCPointerCast"); + case CK_BlockPointerToObjCPointerCast: + zig_panic("TODO handle C translation cast CK_BlockPointerToObjCPointerCast"); + case CK_AnyPointerToBlockPointerCast: + zig_panic("TODO handle C translation cast CK_AnyPointerToBlockPointerCast"); + case CK_ObjCObjectLValueCast: + zig_panic("TODO handle C translation cast CK_ObjCObjectLValueCast"); + case CK_FloatingRealToComplex: + zig_panic("TODO handle C translation cast CK_FloatingRealToComplex"); + case CK_FloatingComplexToReal: + zig_panic("TODO handle C translation cast CK_FloatingComplexToReal"); + case CK_FloatingComplexToBoolean: + zig_panic("TODO handle C translation cast CK_FloatingComplexToBoolean"); + case CK_FloatingComplexCast: + zig_panic("TODO handle C translation cast CK_FloatingComplexCast"); + case CK_FloatingComplexToIntegralComplex: + zig_panic("TODO handle C translation cast CK_FloatingComplexToIntegralComplex"); + case CK_IntegralRealToComplex: + zig_panic("TODO handle C translation cast CK_IntegralRealToComplex"); + case CK_IntegralComplexToReal: + zig_panic("TODO handle C translation cast CK_IntegralComplexToReal"); + case CK_IntegralComplexToBoolean: + zig_panic("TODO handle C translation cast CK_IntegralComplexToBoolean"); + case CK_IntegralComplexCast: + zig_panic("TODO handle C translation cast CK_IntegralComplexCast"); + case CK_IntegralComplexToFloatingComplex: + zig_panic("TODO handle C translation cast CK_IntegralComplexToFloatingComplex"); + case CK_ARCProduceObject: + zig_panic("TODO handle C translation cast CK_ARCProduceObject"); + case CK_ARCConsumeObject: + zig_panic("TODO handle C translation cast CK_ARCConsumeObject"); + case CK_ARCReclaimReturnedObject: + zig_panic("TODO handle C translation cast CK_ARCReclaimReturnedObject"); + case CK_ARCExtendBlockObject: + zig_panic("TODO handle C translation cast CK_ARCExtendBlockObject"); + case CK_AtomicToNonAtomic: + zig_panic("TODO handle C translation cast CK_AtomicToNonAtomic"); + case CK_NonAtomicToAtomic: + zig_panic("TODO handle C translation cast CK_NonAtomicToAtomic"); + case CK_CopyAndAutoreleaseBlockObject: + zig_panic("TODO handle C translation cast CK_CopyAndAutoreleaseBlockObject"); + case CK_BuiltinFnToFnPtr: + zig_panic("TODO handle C translation cast CK_BuiltinFnToFnPtr"); + case CK_ZeroToOCLEvent: + zig_panic("TODO handle C translation cast CK_ZeroToOCLEvent"); + case CK_ZeroToOCLQueue: + zig_panic("TODO handle C translation cast CK_ZeroToOCLQueue"); + case CK_AddressSpaceConversion: + zig_panic("TODO handle C translation cast CK_AddressSpaceConversion"); + case CK_IntToOCLSampler: + zig_panic("TODO handle C translation cast CK_IntToOCLSampler"); + } + zig_unreachable(); +} + +static AstNode * trans_decl_ref_expr(Context *c, DeclRefExpr *stmt) { + ValueDecl *value_decl = stmt->getDecl(); + const char *name = decl_name(value_decl); + + AstNode *node = trans_create_node(c, stmt, NodeTypeSymbol); + node->data.symbol_expr.symbol = buf_create_from_str(name); + return node; +} + +static AstNode * trans_create_num_lit_node_unsigned(Context *c, Stmt *stmt, uint64_t x) { + AstNode *node = trans_create_node(c, stmt, NodeTypeIntLiteral); + node->data.int_literal.bigint = allocate<BigInt>(1); + bigint_init_unsigned(node->data.int_literal.bigint, x); + return node; +} + +static AstNode * trans_unary_operator(Context *c, UnaryOperator *stmt) { + switch (stmt->getOpcode()) { + case UO_PostInc: + zig_panic("TODO handle C translation UO_PostInc"); + case UO_PostDec: + zig_panic("TODO handle C translation UO_PostDec"); + case UO_PreInc: + zig_panic("TODO handle C translation UO_PreInc"); + case UO_PreDec: + zig_panic("TODO handle C translation UO_PreDec"); + case UO_AddrOf: + zig_panic("TODO handle C translation UO_AddrOf"); + case UO_Deref: + zig_panic("TODO handle C translation UO_Deref"); + case UO_Plus: + zig_panic("TODO handle C translation UO_Plus"); + case UO_Minus: + { + Expr *op_expr = stmt->getSubExpr(); + if (c_is_signed_integer(c, op_expr->getType()) || c_is_float(c, op_expr->getType())) { + AstNode *node = trans_create_node(c, stmt, NodeTypePrefixOpExpr); + node->data.prefix_op_expr.prefix_op = PrefixOpNegation; + node->data.prefix_op_expr.primary_expr = trans_expr(c, op_expr); + return node; + } else if (c_is_unsigned_integer(c, op_expr->getType())) { + // we gotta emit 0 -% x + AstNode *node = trans_create_node(c, stmt, NodeTypeBinOpExpr); + node->data.bin_op_expr.op1 = trans_create_num_lit_node_unsigned(c, stmt, 0); + node->data.bin_op_expr.op2 = trans_expr(c, op_expr); + node->data.bin_op_expr.bin_op = BinOpTypeSubWrap; + return node; + } else { + zig_panic("TODO translate C negation with non float non integer"); + } + } + case UO_Not: + zig_panic("TODO handle C translation UO_Not"); + case UO_LNot: + zig_panic("TODO handle C translation UO_LNot"); + case UO_Real: + zig_panic("TODO handle C translation UO_Real"); + case UO_Imag: + zig_panic("TODO handle C translation UO_Imag"); + case UO_Extension: + zig_panic("TODO handle C translation UO_Extension"); + case UO_Coawait: + zig_panic("TODO handle C translation UO_Coawait"); + } + zig_unreachable(); +} + +static AstNode *trans_stmt(Context *c, Stmt *stmt) { Stmt::StmtClass sc = stmt->getStmtClass(); switch (sc) { case Stmt::ReturnStmtClass: - return ast_trans_return_stmt(c, (ReturnStmt *)stmt); + return trans_return_stmt(c, (ReturnStmt *)stmt); case Stmt::CompoundStmtClass: - return ast_trans_compound_stmt(c, (CompoundStmt *)stmt); + return trans_compound_stmt(c, (CompoundStmt *)stmt); case Stmt::IntegerLiteralClass: - return ast_trans_integer_literal(c, (IntegerLiteral *)stmt); + return trans_integer_literal(c, (IntegerLiteral *)stmt); + case Stmt::ConditionalOperatorClass: + return trans_conditional_operator(c, (ConditionalOperator *)stmt); + case Stmt::BinaryOperatorClass: + return trans_binary_operator(c, (BinaryOperator *)stmt); + case Stmt::ImplicitCastExprClass: + return trans_implicit_cast_expr(c, (ImplicitCastExpr *)stmt); + case Stmt::DeclRefExprClass: + return trans_decl_ref_expr(c, (DeclRefExpr *)stmt); + case Stmt::UnaryOperatorClass: + return trans_unary_operator(c, (UnaryOperator *)stmt); case Stmt::CaseStmtClass: zig_panic("TODO handle C CaseStmtClass"); case Stmt::DefaultStmtClass: @@ -714,8 +1065,6 @@ static AstNode *ast_trans_stmt(Context *c, Stmt *stmt) { zig_panic("TODO handle C DoStmtClass"); case Stmt::BinaryConditionalOperatorClass: zig_panic("TODO handle C BinaryConditionalOperatorClass"); - case Stmt::ConditionalOperatorClass: - zig_panic("TODO handle C ConditionalOperatorClass"); case Stmt::AddrLabelExprClass: zig_panic("TODO handle C AddrLabelExprClass"); case Stmt::ArrayInitIndexExprClass: @@ -730,8 +1079,6 @@ static AstNode *ast_trans_stmt(Context *c, Stmt *stmt) { zig_panic("TODO handle C AsTypeExprClass"); case Stmt::AtomicExprClass: zig_panic("TODO handle C AtomicExprClass"); - case Stmt::BinaryOperatorClass: - zig_panic("TODO handle C BinaryOperatorClass"); case Stmt::CompoundAssignOperatorClass: zig_panic("TODO handle C CompoundAssignOperatorClass"); case Stmt::BlockExprClass: @@ -802,8 +1149,6 @@ static AstNode *ast_trans_stmt(Context *c, Stmt *stmt) { zig_panic("TODO handle C CXXStaticCastExprClass"); case Stmt::ObjCBridgedCastExprClass: zig_panic("TODO handle C ObjCBridgedCastExprClass"); - case Stmt::ImplicitCastExprClass: - zig_panic("TODO handle C ImplicitCastExprClass"); case Stmt::CharacterLiteralClass: zig_panic("TODO handle C CharacterLiteralClass"); case Stmt::ChooseExprClass: @@ -816,8 +1161,6 @@ static AstNode *ast_trans_stmt(Context *c, Stmt *stmt) { zig_panic("TODO handle C CoawaitExprClass"); case Stmt::CoyieldExprClass: zig_panic("TODO handle C CoyieldExprClass"); - case Stmt::DeclRefExprClass: - zig_panic("TODO handle C DeclRefExprClass"); case Stmt::DependentCoawaitExprClass: zig_panic("TODO handle C DependentCoawaitExprClass"); case Stmt::DependentScopeDeclRefExprClass: @@ -926,8 +1269,6 @@ static AstNode *ast_trans_stmt(Context *c, Stmt *stmt) { zig_panic("TODO handle C TypoExprClass"); case Stmt::UnaryExprOrTypeTraitExprClass: zig_panic("TODO handle C UnaryExprOrTypeTraitExprClass"); - case Stmt::UnaryOperatorClass: - zig_panic("TODO handle C UnaryOperatorClass"); case Stmt::VAArgExprClass: zig_panic("TODO handle C VAArgExprClass"); case Stmt::ForStmtClass: @@ -1070,7 +1411,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { if (fn_decl->hasBody()) { fprintf(stderr, "fn %s\n", buf_ptr(fn_name)); Stmt *body = fn_decl->getBody(); - AstNode *body_node = ast_trans_stmt(c, body); + AstNode *body_node = trans_stmt(c, body); ast_render(c->codegen, stderr, body_node, 4); fprintf(stderr, "\n"); } |
