authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-27 16:30:52-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-27 16:30:52-07:00
logd1ac1abd34318273b746763a1ce5f3055bba541c
tree4762113b020c8921d16e2a73fd817076636fa80f
parent75cab48c1e88b32c0fea5905761bf0adf7a87101

parseh correctly handles C's void type


3 files changed, 57 insertions(+), 13 deletions(-)

src/all_types.hpp+1
...@@ -242,6 +242,7 @@ struct AstNodeReturnExpr {...@@ -242,6 +242,7 @@ struct AstNodeReturnExpr {
242struct AstNodeVariableDeclaration {242struct AstNodeVariableDeclaration {
243 Buf symbol;243 Buf symbol;
244 bool is_const;244 bool is_const;
245 bool is_extern;
245 VisibMod visib_mod;246 VisibMod visib_mod;
246 // one or both of type and expr will be non null247 // one or both of type and expr will be non null
247 AstNode *type;248 AstNode *type;
src/main.cpp+29-10
...@@ -170,12 +170,12 @@ static void print_indent(ParseHPrint *p) {...@@ -170,12 +170,12 @@ static void print_indent(ParseHPrint *p) {
170 }170 }
171}171}
172172
173static Buf *type_node_to_name(AstNode *type_node) {173static Buf *node_to_buf(AstNode *node) {
174 if (type_node->type == NodeTypeSymbol) {174 if (node->type == NodeTypeSymbol) {
175 return &type_node->data.symbol_expr.symbol;175 return &node->data.symbol_expr.symbol;
176 } else if (type_node->type == NodeTypePrefixOpExpr) {176 } else if (node->type == NodeTypePrefixOpExpr) {
177 PrefixOp op = type_node->data.prefix_op_expr.prefix_op;177 PrefixOp op = node->data.prefix_op_expr.prefix_op;
178 const char *child_type_str = buf_ptr(type_node_to_name(type_node->data.prefix_op_expr.primary_expr));178 const char *child_type_str = buf_ptr(node_to_buf(node->data.prefix_op_expr.primary_expr));
179 if (op == PrefixOpAddressOf) {179 if (op == PrefixOpAddressOf) {
180 return buf_sprintf("&%s", child_type_str);180 return buf_sprintf("&%s", child_type_str);
181 } else if (op == PrefixOpConstAddressOf) {181 } else if (op == PrefixOpConstAddressOf) {
...@@ -242,6 +242,24 @@ static int parseh(const char *arg0, int argc, char **argv) {...@@ -242,6 +242,24 @@ static int parseh(const char *arg0, int argc, char **argv) {
242 return EXIT_FAILURE;242 return EXIT_FAILURE;
243 }243 }
244244
245 for (int var_i = 0; var_i < p->parse_h.var_list.length; var_i += 1) {
246 AstNode *var_decl = p->parse_h.var_list.at(var_i);
247 assert(var_decl->type == NodeTypeVariableDeclaration);
248 const char *pub_str = (var_decl->data.variable_declaration.visib_mod == VisibModPub) ? "pub " : "";
249 const char *extern_str = var_decl->data.variable_declaration.is_extern ? "extern " : "";
250 const char *var_name = buf_ptr(&var_decl->data.variable_declaration.symbol);
251 const char *const_or_var = var_decl->data.variable_declaration.is_const ? "const" : "var";
252 print_indent(p);
253 fprintf(p->f, "%s%s%s %s", pub_str, extern_str, const_or_var, var_name);
254 if (var_decl->data.variable_declaration.type) {
255 fprintf(p->f, ": %s", buf_ptr(node_to_buf(var_decl->data.variable_declaration.type)));
256 }
257 if (var_decl->data.variable_declaration.expr) {
258 fprintf(p->f, " = %s", buf_ptr(node_to_buf(var_decl->data.variable_declaration.expr)));
259 }
260 fprintf(p->f, ";\n");
261 }
262
245 for (int struct_i = 0; struct_i < p->parse_h.struct_list.length; struct_i += 1) {263 for (int struct_i = 0; struct_i < p->parse_h.struct_list.length; struct_i += 1) {
246 AstNode *struct_decl = p->parse_h.struct_list.at(struct_i);264 AstNode *struct_decl = p->parse_h.struct_list.at(struct_i);
247 assert(struct_decl->type == NodeTypeStructDecl);265 assert(struct_decl->type == NodeTypeStructDecl);
...@@ -253,7 +271,7 @@ static int parseh(const char *arg0, int argc, char **argv) {...@@ -253,7 +271,7 @@ static int parseh(const char *arg0, int argc, char **argv) {
253 AstNode *field_node = struct_decl->data.struct_decl.fields.at(field_i);271 AstNode *field_node = struct_decl->data.struct_decl.fields.at(field_i);
254 assert(field_node->type == NodeTypeStructField);272 assert(field_node->type == NodeTypeStructField);
255 const char *field_name = buf_ptr(&field_node->data.struct_field.name);273 const char *field_name = buf_ptr(&field_node->data.struct_field.name);
256 Buf *type_name = type_node_to_name(field_node->data.struct_field.type);274 Buf *type_name = node_to_buf(field_node->data.struct_field.type);
257 print_indent(p);275 print_indent(p);
258 fprintf(p->f, "%s: %s,\n", field_name, buf_ptr(type_name));276 fprintf(p->f, "%s: %s,\n", field_name, buf_ptr(type_name));
259 }277 }
...@@ -268,14 +286,15 @@ static int parseh(const char *arg0, int argc, char **argv) {...@@ -268,14 +286,15 @@ static int parseh(const char *arg0, int argc, char **argv) {
268 print_indent(p);286 print_indent(p);
269 const char *fn_name = buf_ptr(&fn_proto->data.fn_proto.name);287 const char *fn_name = buf_ptr(&fn_proto->data.fn_proto.name);
270 const char *pub_str = (fn_proto->data.fn_proto.visib_mod == VisibModPub) ? "pub " : "";288 const char *pub_str = (fn_proto->data.fn_proto.visib_mod == VisibModPub) ? "pub " : "";
271 fprintf(p->f, "%sextern fn %s(", pub_str, fn_name);289 const char *extern_str = fn_proto->data.fn_proto.is_extern ? "extern " : "";
290 fprintf(p->f, "%s%sfn %s(", pub_str, extern_str, fn_name);
272 int arg_count = fn_proto->data.fn_proto.params.length;291 int arg_count = fn_proto->data.fn_proto.params.length;
273 bool is_var_args = fn_proto->data.fn_proto.is_var_args;292 bool is_var_args = fn_proto->data.fn_proto.is_var_args;
274 for (int arg_i = 0; arg_i < arg_count; arg_i += 1) {293 for (int arg_i = 0; arg_i < arg_count; arg_i += 1) {
275 AstNode *param_decl = fn_proto->data.fn_proto.params.at(arg_i);294 AstNode *param_decl = fn_proto->data.fn_proto.params.at(arg_i);
276 assert(param_decl->type == NodeTypeParamDecl);295 assert(param_decl->type == NodeTypeParamDecl);
277 const char *arg_name = buf_ptr(&param_decl->data.param_decl.name);296 const char *arg_name = buf_ptr(&param_decl->data.param_decl.name);
278 Buf *arg_type = type_node_to_name(param_decl->data.param_decl.type);297 Buf *arg_type = node_to_buf(param_decl->data.param_decl.type);
279 const char *noalias_str = param_decl->data.param_decl.is_noalias ? "noalias " : "";298 const char *noalias_str = param_decl->data.param_decl.is_noalias ? "noalias " : "";
280 fprintf(p->f, "%s%s: %s", noalias_str, arg_name, buf_ptr(arg_type));299 fprintf(p->f, "%s%s: %s", noalias_str, arg_name, buf_ptr(arg_type));
281 if (arg_i + 1 < arg_count || is_var_args) {300 if (arg_i + 1 < arg_count || is_var_args) {
...@@ -286,7 +305,7 @@ static int parseh(const char *arg0, int argc, char **argv) {...@@ -286,7 +305,7 @@ static int parseh(const char *arg0, int argc, char **argv) {
286 fprintf(p->f, "...");305 fprintf(p->f, "...");
287 }306 }
288 fprintf(p->f, ")");307 fprintf(p->f, ")");
289 Buf *return_type_name = type_node_to_name(fn_proto->data.fn_proto.return_type);308 Buf *return_type_name = node_to_buf(fn_proto->data.fn_proto.return_type);
290 if (!buf_eql_str(return_type_name, "void")) {309 if (!buf_eql_str(return_type_name, "void")) {
291 fprintf(p->f, " -> %s", buf_ptr(return_type_name));310 fprintf(p->f, " -> %s", buf_ptr(return_type_name));
292 }311 }
src/parseh.cpp+27-3
...@@ -20,7 +20,8 @@ using namespace clang;...@@ -20,7 +20,8 @@ using namespace clang;
20struct Context {20struct Context {
21 ParseH *parse_h;21 ParseH *parse_h;
22 bool warnings_on;22 bool warnings_on;
23 bool pub;23 VisibMod visib_mod;
24 AstNode *c_void_decl_node;
24};25};
2526
26static AstNode *type_node_from_qual_type(Context *c, QualType qt);27static AstNode *type_node_from_qual_type(Context *c, QualType qt);
...@@ -42,10 +43,33 @@ static const char *decl_name(const Decl *decl) {...@@ -42,10 +43,33 @@ static const char *decl_name(const Decl *decl) {
42 return (const char *)named_decl->getName().bytes_begin();43 return (const char *)named_decl->getName().bytes_begin();
43}44}
4445
46static AstNode *create_typedef_node(Context *c, const char *new_name, const char *target_name) {
47 AstNode *node = create_node(c, NodeTypeVariableDeclaration);
48 buf_init_from_str(&node->data.variable_declaration.symbol, new_name);
49 node->data.variable_declaration.is_const = true;
50 node->data.variable_declaration.visib_mod = c->visib_mod;
51 node->data.variable_declaration.expr = simple_type_node(c, target_name);
52 return node;
53}
54
55static AstNode *convert_to_c_void(Context *c, AstNode *type_node) {
56 if (type_node->type == NodeTypeSymbol &&
57 buf_eql_str(&type_node->data.symbol_expr.symbol, "void"))
58 {
59 if (!c->c_void_decl_node) {
60 c->c_void_decl_node = create_typedef_node(c, "c_void", "u8");
61 c->parse_h->var_list.append(c->c_void_decl_node);
62 }
63 return simple_type_node(c, "c_void");
64 } else {
65 return type_node;
66 }
67}
68
45static AstNode *pointer_to_type(Context *c, AstNode *type_node, bool is_const) {69static AstNode *pointer_to_type(Context *c, AstNode *type_node, bool is_const) {
46 AstNode *node = create_node(c, NodeTypePrefixOpExpr);70 AstNode *node = create_node(c, NodeTypePrefixOpExpr);
47 node->data.prefix_op_expr.prefix_op = is_const ? PrefixOpConstAddressOf : PrefixOpAddressOf;71 node->data.prefix_op_expr.prefix_op = is_const ? PrefixOpConstAddressOf : PrefixOpAddressOf;
48 node->data.prefix_op_expr.primary_expr = type_node;72 node->data.prefix_op_expr.primary_expr = convert_to_c_void(c, type_node);
49 return node;73 return node;
50}74}
5175
...@@ -187,7 +211,7 @@ static bool decl_visitor(void *context, const Decl *decl) {...@@ -187,7 +211,7 @@ static bool decl_visitor(void *context, const Decl *decl) {
187 const FunctionDecl *fn_decl = static_cast<const FunctionDecl*>(decl);211 const FunctionDecl *fn_decl = static_cast<const FunctionDecl*>(decl);
188 AstNode *node = create_node(c, NodeTypeFnProto);212 AstNode *node = create_node(c, NodeTypeFnProto);
189 node->data.fn_proto.is_extern = true;213 node->data.fn_proto.is_extern = true;
190 node->data.fn_proto.visib_mod = c->pub ? VisibModPub : VisibModPrivate;214 node->data.fn_proto.visib_mod = c->visib_mod;
191 node->data.fn_proto.is_var_args = fn_decl->isVariadic();215 node->data.fn_proto.is_var_args = fn_decl->isVariadic();
192 buf_init_from_str(&node->data.fn_proto.name, decl_name(decl));216 buf_init_from_str(&node->data.fn_proto.name, decl_name(decl));
193217