commit bf6d32f8cbaf6fd120962853089123b1ee800b99 (tree)
parent 46fef543f945bb2ddce32073c16b93a153a47754
Author: Josh Wolfe <thejoshwolfe@gmail.com>
Date: Wed, 20 Sep 2017 21:17:41 -0700
Merge remote-tracking branch 'origin/c-to-zig' into c-to-zig
Diffstat:
2 files changed, 59 insertions(+), 10 deletions(-)
diff --git 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;
@@ -1175,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;
@@ -1205,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;
@@ -1740,6 +1747,25 @@ static AstNode *trans_if_statement(Context *c, AstNode *block, IfStmt *stmt) {
return if_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) {
@@ -1767,6 +1793,8 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s
return trans_while_loop(c, block, (WhileStmt *)stmt);
case Stmt::IfStmtClass:
return trans_if_statement(c, block, (IfStmt *)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");
@@ -1906,10 +1934,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;
@@ -2551,9 +2575,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
@@ -353,4 +353,24 @@ pub fn addCases(cases: &tests.ParseCContext) {
\\ return i;
\\}
);
+
+ cases.add("anonymous enum",
+ \\enum {
+ \\ One,
+ \\ Two,
+ \\};
+ ,
+ \\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();
+ \\}
+ );
}