From 38059e6f97ae62aab9d3ca2f386eca1a1186a930 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 20 Sep 2017 23:16:44 -0400 Subject: [PATCH 1/2] parse-c: fix anonymous enums --- src/parsec.cpp | 14 +++++++++++--- test/parsec.zig | 10 ++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/parsec.cpp b/src/parsec.cpp index d2f5731e22a79c2f4054703c97b65e8225e0c69d..2895ccdb1b7b0de01780d5f50988ceda80b1f3f6 100644 --- a/src/parsec.cpp +++ b/src/parsec.cpp @@ -137,6 +137,9 @@ static AstNode *trans_create_node_fn_call_1(Context *c, AstNode *fn_ref_expr, As static AstNode *trans_create_node_field_access(Context *c, AstNode *container, Buf *field_name) { AstNode *node = trans_create_node(c, NodeTypeFieldAccessExpr); + if (container->type == NodeTypeSymbol) { + assert(container->data.symbol_expr.symbol != nullptr); + } node->data.field_access_expr.struct_expr = container; node->data.field_access_expr.field_name = field_name; return node; @@ -2527,9 +2530,14 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) { // in C each enum value is in the global namespace. so we put them there too. // at this point we can rely on the enum emitting successfully - AstNode *field_access_node = trans_create_node_field_access(c, - trans_create_node_symbol(c, full_type_name), field_name); - add_global_var(c, enum_val_name, field_access_node); + if (is_anonymous) { + AstNode *lit_node = trans_create_node_unsigned(c, i); + add_global_var(c, enum_val_name, lit_node); + } else { + AstNode *field_access_node = trans_create_node_field_access(c, + trans_create_node_symbol(c, full_type_name), field_name); + add_global_var(c, enum_val_name, field_access_node); + } } if (is_anonymous) { diff --git a/test/parsec.zig b/test/parsec.zig index f408066d2486d353de3101a775ef1e19cc441ac0..0952d2debf3a6103b945d5dc6b258a2c9ad0a059 100644 --- a/test/parsec.zig +++ b/test/parsec.zig @@ -353,4 +353,14 @@ pub fn addCases(cases: &tests.ParseCContext) { \\ return i; \\} ); + + cases.add("anonymous enum", + \\enum { + \\ One, + \\ Two, + \\}; + , + \\pub const One = 0; + \\pub const Two = 1; + ); } -- 2.54.0 From f68d724647b33028310471b5e7a32dd5898ac961 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 21 Sep 2017 00:02:18 -0400 Subject: [PATCH 2/2] parse-c: support function calls --- src/parsec.cpp | 35 ++++++++++++++++++++++++++++------- test/parsec.zig | 10 ++++++++++ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/parsec.cpp b/src/parsec.cpp index 2895ccdb1b7b0de01780d5f50988ceda80b1f3f6..8cc0945e4807f443ea541f6869dab2bcfd45f09b 100644 --- a/src/parsec.cpp +++ b/src/parsec.cpp @@ -1178,6 +1178,13 @@ static AstNode *trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCas return nullptr; return trans_c_cast(c, stmt->getExprLoc(), stmt->getType(), target_node); } + case CK_FunctionToPointerDecay: + { + AstNode *target_node = trans_expr(c, true, block, stmt->getSubExpr(), TransRValue); + if (target_node == nullptr) + return nullptr; + return target_node; + } case CK_Dependent: emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_Dependent"); return nullptr; @@ -1208,9 +1215,6 @@ static AstNode *trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCas case CK_ArrayToPointerDecay: emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_ArrayToPointerDecay"); return nullptr; - case CK_FunctionToPointerDecay: - emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_FunctionToPointerDecay"); - return nullptr; case CK_NullToPointer: emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_NullToPointer"); return nullptr; @@ -1719,6 +1723,25 @@ static AstNode *trans_while_loop(Context *c, AstNode *block, WhileStmt *stmt) { return while_node; } +static AstNode *trans_call_expr(Context *c, bool result_used, AstNode *block, CallExpr *stmt) { + AstNode *node = trans_create_node(c, NodeTypeFnCallExpr); + node->data.fn_call_expr.fn_ref_expr = trans_expr(c, true, block, stmt->getCallee(), TransRValue); + if (node->data.fn_call_expr.fn_ref_expr == nullptr) + return nullptr; + + unsigned num_args = stmt->getNumArgs(); + Expr **args = stmt->getArgs(); + for (unsigned i = 0; i < num_args; i += 1) { + AstNode *arg_node = trans_expr(c, true, block, args[i], TransRValue); + if (arg_node == nullptr) + return nullptr; + + node->data.fn_call_expr.params.append(arg_node); + } + + return node; +} + static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *stmt, TransLRValue lrvalue) { Stmt::StmtClass sc = stmt->getStmtClass(); switch (sc) { @@ -1744,6 +1767,8 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s return trans_local_declaration(c, block, (DeclStmt *)stmt); case Stmt::WhileStmtClass: return trans_while_loop(c, block, (WhileStmt *)stmt); + case Stmt::CallExprClass: + return trans_call_expr(c, result_used, block, (CallExpr *)stmt); case Stmt::CaseStmtClass: emit_warning(c, stmt->getLocStart(), "TODO handle C CaseStmtClass"); return nullptr; @@ -1882,10 +1907,6 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s case Stmt::CXXUuidofExprClass: emit_warning(c, stmt->getLocStart(), "TODO handle C CXXUuidofExprClass"); return nullptr; - case Stmt::CallExprClass: - (void)result_used; - emit_warning(c, stmt->getLocStart(), "TODO handle C CallExprClass"); - return nullptr; case Stmt::CUDAKernelCallExprClass: emit_warning(c, stmt->getLocStart(), "TODO handle C CUDAKernelCallExprClass"); return nullptr; diff --git a/test/parsec.zig b/test/parsec.zig index 0952d2debf3a6103b945d5dc6b258a2c9ad0a059..5df16aabacdbf053237b17f0347144b37892198f 100644 --- a/test/parsec.zig +++ b/test/parsec.zig @@ -363,4 +363,14 @@ pub fn addCases(cases: &tests.ParseCContext) { \\pub const One = 0; \\pub const Two = 1; ); + + cases.add("function call", + \\static void bar(void) { } + \\void foo(void) { bar(); } + , + \\pub fn bar() {} + \\export fn foo() { + \\ bar(); + \\} + ); } -- 2.54.0