authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-09-05 22:55:03-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-09-05 22:55:03-04:00
log2c9bdad3462f356f4c2ed2442f2cd6de80b9805b
tree4bd725e4f8e4ef33121c91ff114057bbd9f277c6
parent48c44615a4f03c105a8053db552320d26482436a

rename parseh to parsec


15 files changed, 2752 insertions(+), 2757 deletions(-)

CMakeLists.txt+1-1
...@@ -193,7 +193,7 @@ set(ZIG_SOURCES...@@ -193,7 +193,7 @@ set(ZIG_SOURCES
193 "${CMAKE_SOURCE_DIR}/src/target.cpp"193 "${CMAKE_SOURCE_DIR}/src/target.cpp"
194 "${CMAKE_SOURCE_DIR}/src/tokenizer.cpp"194 "${CMAKE_SOURCE_DIR}/src/tokenizer.cpp"
195 "${CMAKE_SOURCE_DIR}/src/util.cpp"195 "${CMAKE_SOURCE_DIR}/src/util.cpp"
196 "${CMAKE_SOURCE_DIR}/src/parseh.cpp"196 "${CMAKE_SOURCE_DIR}/src/parsec.cpp"
197 "${CMAKE_SOURCE_DIR}/src/zig_llvm.cpp"197 "${CMAKE_SOURCE_DIR}/src/zig_llvm.cpp"
198)198)
199199
build.zig+1-1
...@@ -19,5 +19,5 @@ pub fn build(b: &Builder) {...@@ -19,5 +19,5 @@ pub fn build(b: &Builder) {
19 test_step.dependOn(tests.addCompileErrorTests(b, test_filter));19 test_step.dependOn(tests.addCompileErrorTests(b, test_filter));
20 test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filter));20 test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filter));
21 test_step.dependOn(tests.addDebugSafetyTests(b, test_filter));21 test_step.dependOn(tests.addDebugSafetyTests(b, test_filter));
22 test_step.dependOn(tests.addParseHTests(b, test_filter));22 test_step.dependOn(tests.addParseCTests(b, test_filter));
23}23}
ci/travis_linux_script+1-1
...@@ -15,4 +15,4 @@ make install...@@ -15,4 +15,4 @@ make install
15# we have to skip cross compiling OSX tests because apt.llvm.org has an old version15# we have to skip cross compiling OSX tests because apt.llvm.org has an old version
16# of llvm for the version of ubuntu that travis is running on.16# of llvm for the version of ubuntu that travis is running on.
17./zig build --build-file ../build.zig test-behavior test-std test-compiler-rt -Dtest-filter=linux17./zig build --build-file ../build.zig test-behavior test-std test-compiler-rt -Dtest-filter=linux
18./zig build --build-file ../build.zig test-compare-output test-build-examples test-compile-errors test-asm-link test-debug-safety test-parseh18./zig build --build-file ../build.zig test-compare-output test-build-examples test-compile-errors test-asm-link test-debug-safety test-parsec
src/analyze.cpp+2-7
...@@ -26,7 +26,7 @@ static void resolve_enum_zero_bits(CodeGen *g, TypeTableEntry *enum_type);...@@ -26,7 +26,7 @@ static void resolve_enum_zero_bits(CodeGen *g, TypeTableEntry *enum_type);
26static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type);26static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type);
2727
28ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) {28ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) {
29 // if this assert fails, then parseh generated code that29 // if this assert fails, then parsec generated code that
30 // failed semantic analysis, which isn't supposed to happen30 // failed semantic analysis, which isn't supposed to happen
31 assert(!node->owner->c_import_node);31 assert(!node->owner->c_import_node);
3232
...@@ -38,7 +38,7 @@ ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) {...@@ -38,7 +38,7 @@ ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) {
38}38}
3939
40ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *msg) {40ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *msg) {
41 // if this assert fails, then parseh generated code that41 // if this assert fails, then parsec generated code that
42 // failed semantic analysis, which isn't supposed to happen42 // failed semantic analysis, which isn't supposed to happen
43 assert(!node->owner->c_import_node);43 assert(!node->owner->c_import_node);
4444
...@@ -1265,7 +1265,6 @@ TypeTableEntry *create_enum_tag_type(CodeGen *g, TypeTableEntry *enum_type, Type...@@ -1265,7 +1265,6 @@ TypeTableEntry *create_enum_tag_type(CodeGen *g, TypeTableEntry *enum_type, Type
1265}1265}
12661266
1267static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {1267static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
1268 // if you change this logic you likely must also change similar logic in parseh.cpp
1269 assert(enum_type->id == TypeTableEntryIdEnum);1268 assert(enum_type->id == TypeTableEntryIdEnum);
12701269
1271 if (enum_type->data.enumeration.complete)1270 if (enum_type->data.enumeration.complete)
...@@ -1578,8 +1577,6 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f...@@ -1578,8 +1577,6 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
1578}1577}
15791578
1580static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) {1579static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) {
1581 // if you change the logic of this function likely you must make a similar change in
1582 // parseh.cpp
1583 assert(struct_type->id == TypeTableEntryIdStruct);1580 assert(struct_type->id == TypeTableEntryIdStruct);
15841581
1585 if (struct_type->data.structure.complete)1582 if (struct_type->data.structure.complete)
...@@ -3079,8 +3076,6 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *...@@ -3079,8 +3076,6 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *
3079 continue;3076 continue;
3080 }3077 }
30813078
3082 // Note: target_tld->name is not necessarily equal to entry->key because
3083 // of aliases that parseh uses.
3084 Buf *target_tld_name = entry->key;3079 Buf *target_tld_name = entry->key;
30853080
3086 auto existing_entry = dst_use_node->owner->decls_scope->decl_table.put_unique(target_tld_name, target_tld);3081 auto existing_entry = dst_use_node->owner->decls_scope->decl_table.put_unique(target_tld_name, target_tld);
src/codegen.cpp+2-2
...@@ -15,7 +15,7 @@...@@ -15,7 +15,7 @@
15#include "ir.hpp"15#include "ir.hpp"
16#include "link.hpp"16#include "link.hpp"
17#include "os.hpp"17#include "os.hpp"
18#include "parseh.hpp"18#include "parsec.hpp"
19#include "target.hpp"19#include "target.hpp"
20#include "zig_llvm.hpp"20#include "zig_llvm.hpp"
2121
...@@ -5001,7 +5001,7 @@ static void init(CodeGen *g) {...@@ -5001,7 +5001,7 @@ static void init(CodeGen *g) {
5001 define_builtin_compile_vars(g);5001 define_builtin_compile_vars(g);
5002}5002}
50035003
5004void codegen_parseh(CodeGen *g, Buf *full_path) {5004void codegen_parsec(CodeGen *g, Buf *full_path) {
5005 find_libc_include_path(g);5005 find_libc_include_path(g);
50065006
5007 Buf *src_basename = buf_alloc();5007 Buf *src_basename = buf_alloc();
src/codegen.hpp+1-1
...@@ -54,7 +54,7 @@ PackageTableEntry *codegen_create_package(CodeGen *g, const char *root_src_dir,...@@ -54,7 +54,7 @@ PackageTableEntry *codegen_create_package(CodeGen *g, const char *root_src_dir,
54void codegen_add_assembly(CodeGen *g, Buf *path);54void codegen_add_assembly(CodeGen *g, Buf *path);
55void codegen_add_object(CodeGen *g, Buf *object_path);55void codegen_add_object(CodeGen *g, Buf *object_path);
5656
57void codegen_parseh(CodeGen *g, Buf *path);57void codegen_parsec(CodeGen *g, Buf *path);
5858
5959
60#endif60#endif
src/ir.cpp+1-1
...@@ -11,7 +11,7 @@...@@ -11,7 +11,7 @@
11#include "ir.hpp"11#include "ir.hpp"
12#include "ir_print.hpp"12#include "ir_print.hpp"
13#include "os.hpp"13#include "os.hpp"
14#include "parseh.hpp"14#include "parsec.hpp"
15#include "quadmath.hpp"15#include "quadmath.hpp"
16#include "range_set.hpp"16#include "range_set.hpp"
1717
src/main.cpp+11-11
...@@ -23,7 +23,7 @@ static int usage(const char *arg0) {...@@ -23,7 +23,7 @@ static int usage(const char *arg0) {
23 " build_exe [source] create executable from source or object files\n"23 " build_exe [source] create executable from source or object files\n"
24 " build_lib [source] create library from source or object files\n"24 " build_lib [source] create library from source or object files\n"
25 " build_obj [source] create object from source or assembly\n"25 " build_obj [source] create object from source or assembly\n"
26 " parseh [source] convert a c header file to zig extern declarations\n"26 " parsec [source] convert c code to zig code\n"
27 " targets list available compilation targets\n"27 " targets list available compilation targets\n"
28 " test [source] create and run a test build\n"28 " test [source] create and run a test build\n"
29 " version print version number and exit\n"29 " version print version number and exit\n"
...@@ -132,7 +132,7 @@ enum Cmd {...@@ -132,7 +132,7 @@ enum Cmd {
132 CmdTest,132 CmdTest,
133 CmdVersion,133 CmdVersion,
134 CmdZen,134 CmdZen,
135 CmdParseH,135 CmdParseC,
136 CmdTargets,136 CmdTargets,
137};137};
138138
...@@ -470,8 +470,8 @@ int main(int argc, char **argv) {...@@ -470,8 +470,8 @@ int main(int argc, char **argv) {
470 cmd = CmdVersion;470 cmd = CmdVersion;
471 } else if (strcmp(arg, "zen") == 0) {471 } else if (strcmp(arg, "zen") == 0) {
472 cmd = CmdZen;472 cmd = CmdZen;
473 } else if (strcmp(arg, "parseh") == 0) {473 } else if (strcmp(arg, "parsec") == 0) {
474 cmd = CmdParseH;474 cmd = CmdParseC;
475 } else if (strcmp(arg, "test") == 0) {475 } else if (strcmp(arg, "test") == 0) {
476 cmd = CmdTest;476 cmd = CmdTest;
477 out_type = OutTypeExe;477 out_type = OutTypeExe;
...@@ -484,7 +484,7 @@ int main(int argc, char **argv) {...@@ -484,7 +484,7 @@ int main(int argc, char **argv) {
484 } else {484 } else {
485 switch (cmd) {485 switch (cmd) {
486 case CmdBuild:486 case CmdBuild:
487 case CmdParseH:487 case CmdParseC:
488 case CmdTest:488 case CmdTest:
489 if (!in_file) {489 if (!in_file) {
490 in_file = arg;490 in_file = arg;
...@@ -541,13 +541,13 @@ int main(int argc, char **argv) {...@@ -541,13 +541,13 @@ int main(int argc, char **argv) {
541541
542 switch (cmd) {542 switch (cmd) {
543 case CmdBuild:543 case CmdBuild:
544 case CmdParseH:544 case CmdParseC:
545 case CmdTest:545 case CmdTest:
546 {546 {
547 if (cmd == CmdBuild && !in_file && objects.length == 0 && asm_files.length == 0) {547 if (cmd == CmdBuild && !in_file && objects.length == 0 && asm_files.length == 0) {
548 fprintf(stderr, "Expected source file argument or at least one --object or --assembly argument.\n");548 fprintf(stderr, "Expected source file argument or at least one --object or --assembly argument.\n");
549 return usage(arg0);549 return usage(arg0);
550 } else if ((cmd == CmdParseH || cmd == CmdTest) && !in_file) {550 } else if ((cmd == CmdParseC || cmd == CmdTest) && !in_file) {
551 fprintf(stderr, "Expected source file argument.\n");551 fprintf(stderr, "Expected source file argument.\n");
552 return usage(arg0);552 return usage(arg0);
553 } else if (cmd == CmdBuild && out_type == OutTypeObj && objects.length != 0) {553 } else if (cmd == CmdBuild && out_type == OutTypeObj && objects.length != 0) {
...@@ -557,7 +557,7 @@ int main(int argc, char **argv) {...@@ -557,7 +557,7 @@ int main(int argc, char **argv) {
557557
558 assert(cmd != CmdBuild || out_type != OutTypeUnknown);558 assert(cmd != CmdBuild || out_type != OutTypeUnknown);
559559
560 bool need_name = (cmd == CmdBuild || cmd == CmdParseH);560 bool need_name = (cmd == CmdBuild || cmd == CmdParseC);
561561
562 Buf *in_file_buf = nullptr;562 Buf *in_file_buf = nullptr;
563563
...@@ -580,7 +580,7 @@ int main(int argc, char **argv) {...@@ -580,7 +580,7 @@ int main(int argc, char **argv) {
580 return usage(arg0);580 return usage(arg0);
581 }581 }
582582
583 Buf *zig_root_source_file = (cmd == CmdParseH) ? nullptr : in_file_buf;583 Buf *zig_root_source_file = (cmd == CmdParseC) ? nullptr : in_file_buf;
584584
585 Buf *full_cache_dir = buf_alloc();585 Buf *full_cache_dir = buf_alloc();
586 os_path_resolve(buf_create_from_str("."),586 os_path_resolve(buf_create_from_str("."),
...@@ -668,8 +668,8 @@ int main(int argc, char **argv) {...@@ -668,8 +668,8 @@ int main(int argc, char **argv) {
668 if (timing_info)668 if (timing_info)
669 codegen_print_timing_report(g, stdout);669 codegen_print_timing_report(g, stdout);
670 return EXIT_SUCCESS;670 return EXIT_SUCCESS;
671 } else if (cmd == CmdParseH) {671 } else if (cmd == CmdParseC) {
672 codegen_parseh(g, in_file_buf);672 codegen_parsec(g, in_file_buf);
673 ast_render(g, stdout, g->root_import->root, 4);673 ast_render(g, stdout, g->root_import->root, 4);
674 if (timing_info)674 if (timing_info)
675 codegen_print_timing_report(g, stdout);675 codegen_print_timing_report(g, stdout);
src/parsec.cpp created+2389
...@@ -0,0 +1,2389 @@
1/*
2 * Copyright (c) 2015 Andrew Kelley
3 *
4 * This file is part of zig, which is MIT licensed.
5 * See http://opensource.org/licenses/MIT
6 */
7
8#include "all_types.hpp"
9#include "analyze.hpp"
10#include "c_tokenizer.hpp"
11#include "config.h"
12#include "error.hpp"
13#include "ir.hpp"
14#include "os.hpp"
15#include "parsec.hpp"
16#include "parser.hpp"
17
18
19#include <clang/Frontend/ASTUnit.h>
20#include <clang/Frontend/CompilerInstance.h>
21#include <clang/AST/Expr.h>
22
23#include <string.h>
24
25using namespace clang;
26
27struct MacroSymbol {
28 Buf *name;
29 Buf *value;
30};
31
32struct Alias {
33 Buf *new_name;
34 Buf *canon_name;
35};
36
37struct Context {
38 ImportTableEntry *import;
39 ZigList<ErrorMsg *> *errors;
40 bool warnings_on;
41 VisibMod visib_mod;
42 AstNode *root;
43 HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table;
44 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table;
45 SourceManager *source_manager;
46 ZigList<Alias> aliases;
47 ZigList<MacroSymbol> macro_symbols;
48 AstNode *source_node;
49
50 CodeGen *codegen;
51 ASTContext *ctx;
52};
53
54static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl);
55static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl);
56static AstNode *resolve_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl);
57static AstNode *trans_qual_type_with_table(Context *c, QualType qt, const SourceLocation &source_loc);
58static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc);
59
60
61__attribute__ ((format (printf, 3, 4)))
62static void emit_warning(Context *c, const SourceLocation &sl, const char *format, ...) {
63 if (!c->warnings_on) {
64 return;
65 }
66
67 va_list ap;
68 va_start(ap, format);
69 Buf *msg = buf_vprintf(format, ap);
70 va_end(ap);
71
72 StringRef filename = c->source_manager->getFilename(sl);
73 const char *filename_bytes = (const char *)filename.bytes_begin();
74 Buf *path;
75 if (filename_bytes) {
76 path = buf_create_from_str(filename_bytes);
77 } else {
78 path = buf_sprintf("(no file)");
79 }
80 unsigned line = c->source_manager->getSpellingLineNumber(sl);
81 unsigned column = c->source_manager->getSpellingColumnNumber(sl);
82 fprintf(stderr, "%s:%u:%u: warning: %s\n", buf_ptr(path), line, column, buf_ptr(msg));
83}
84
85static void add_global_weak_alias(Context *c, Buf *new_name, Buf *canon_name) {
86 Alias *alias = c->aliases.add_one();
87 alias->new_name = new_name;
88 alias->canon_name = canon_name;
89}
90
91static AstNode * trans_create_node(Context *c, NodeType id) {
92 AstNode *node = allocate<AstNode>(1);
93 node->type = id;
94 node->owner = c->import;
95 // TODO line/column. mapping to C file??
96 return node;
97}
98
99static AstNode *trans_create_node_float_lit(Context *c, double value) {
100 AstNode *node = trans_create_node(c, NodeTypeFloatLiteral);
101 node->data.float_literal.bigfloat = allocate<BigFloat>(1);
102 bigfloat_init_64(node->data.float_literal.bigfloat, value);
103 return node;
104}
105
106static AstNode *trans_create_node_symbol(Context *c, Buf *name) {
107 AstNode *node = trans_create_node(c, NodeTypeSymbol);
108 node->data.symbol_expr.symbol = name;
109 return node;
110}
111
112static AstNode *trans_create_node_symbol_str(Context *c, const char *name) {
113 return trans_create_node_symbol(c, buf_create_from_str(name));
114}
115
116static AstNode *trans_create_node_builtin_fn_call(Context *c, Buf *name) {
117 AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
118 node->data.fn_call_expr.fn_ref_expr = trans_create_node_symbol(c, name);
119 node->data.fn_call_expr.is_builtin = true;
120 return node;
121}
122
123static AstNode *trans_create_node_builtin_fn_call_str(Context *c, const char *name) {
124 return trans_create_node_builtin_fn_call(c, buf_create_from_str(name));
125}
126
127static AstNode *trans_create_node_opaque(Context *c) {
128 return trans_create_node_builtin_fn_call_str(c, "OpaqueType");
129}
130
131static AstNode *trans_create_node_field_access(Context *c, AstNode *container, Buf *field_name) {
132 AstNode *node = trans_create_node(c, NodeTypeFieldAccessExpr);
133 node->data.field_access_expr.struct_expr = container;
134 node->data.field_access_expr.field_name = field_name;
135 return node;
136}
137
138static AstNode *trans_create_node_prefix_op(Context *c, PrefixOp op, AstNode *child_node) {
139 AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);
140 node->data.prefix_op_expr.prefix_op = op;
141 node->data.prefix_op_expr.primary_expr = child_node;
142 return node;
143}
144
145static AstNode *trans_create_node_addr_of(Context *c, bool is_const, bool is_volatile, AstNode *child_node) {
146 AstNode *node = trans_create_node(c, NodeTypeAddrOfExpr);
147 node->data.addr_of_expr.is_const = is_const;
148 node->data.addr_of_expr.is_volatile = is_volatile;
149 node->data.addr_of_expr.op_expr = child_node;
150 return node;
151}
152
153static AstNode *trans_create_node_str_lit_c(Context *c, Buf *buf) {
154 AstNode *node = trans_create_node(c, NodeTypeStringLiteral);
155 node->data.string_literal.buf = buf;
156 node->data.string_literal.c = true;
157 return node;
158}
159
160static AstNode *trans_create_node_unsigned_negative(Context *c, uint64_t x, bool is_negative) {
161 AstNode *node = trans_create_node(c, NodeTypeIntLiteral);
162 node->data.int_literal.bigint = allocate<BigInt>(1);
163 bigint_init_data(node->data.int_literal.bigint, &x, 1, is_negative);
164 return node;
165}
166
167static AstNode *trans_create_node_unsigned(Context *c, uint64_t x) {
168 return trans_create_node_unsigned_negative(c, x, false);
169}
170
171static AstNode *trans_create_node_cast(Context *c, AstNode *dest, AstNode *src) {
172 AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
173 node->data.fn_call_expr.fn_ref_expr = dest;
174 node->data.fn_call_expr.params.resize(1);
175 node->data.fn_call_expr.params.items[0] = src;
176 return node;
177}
178
179static AstNode *trans_create_node_unsigned_negative_type(Context *c, uint64_t x, bool is_negative,
180 const char *type_name)
181{
182 AstNode *lit_node = trans_create_node_unsigned_negative(c, x, is_negative);
183 return trans_create_node_cast(c, trans_create_node_symbol_str(c, type_name), lit_node);
184}
185
186static AstNode *trans_create_node_array_type(Context *c, AstNode *size_node, AstNode *child_type_node) {
187 AstNode *node = trans_create_node(c, NodeTypeArrayType);
188 node->data.array_type.size = size_node;
189 node->data.array_type.child_type = child_type_node;
190 return node;
191}
192
193static AstNode *trans_create_node_var_decl(Context *c, bool is_const, Buf *var_name, AstNode *type_node,
194 AstNode *init_node)
195{
196 AstNode *node = trans_create_node(c, NodeTypeVariableDeclaration);
197 node->data.variable_declaration.visib_mod = c->visib_mod;
198 node->data.variable_declaration.symbol = var_name;
199 node->data.variable_declaration.is_const = is_const;
200 node->data.variable_declaration.type = type_node;
201 node->data.variable_declaration.expr = init_node;
202 return node;
203}
204
205
206static AstNode *trans_create_node_inline_fn(Context *c, Buf *fn_name, Buf *var_name, AstNode *src_proto_node) {
207 AstNode *fn_def = trans_create_node(c, NodeTypeFnDef);
208 AstNode *fn_proto = trans_create_node(c, NodeTypeFnProto);
209 fn_proto->data.fn_proto.visib_mod = c->visib_mod;
210 fn_proto->data.fn_proto.name = fn_name;
211 fn_proto->data.fn_proto.is_inline = true;
212 fn_proto->data.fn_proto.return_type = src_proto_node->data.fn_proto.return_type; // TODO ok for these to alias?
213
214 fn_def->data.fn_def.fn_proto = fn_proto;
215 fn_proto->data.fn_proto.fn_def_node = fn_def;
216
217 AstNode *unwrap_node = trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, trans_create_node_symbol(c, var_name));
218 AstNode *fn_call_node = trans_create_node(c, NodeTypeFnCallExpr);
219 fn_call_node->data.fn_call_expr.fn_ref_expr = unwrap_node;
220
221 for (size_t i = 0; i < src_proto_node->data.fn_proto.params.length; i += 1) {
222 AstNode *src_param_node = src_proto_node->data.fn_proto.params.at(i);
223 Buf *param_name = src_param_node->data.param_decl.name;
224 if (!param_name) param_name = buf_sprintf("arg%" ZIG_PRI_usize "", i);
225
226 AstNode *dest_param_node = trans_create_node(c, NodeTypeParamDecl);
227 dest_param_node->data.param_decl.name = param_name;
228 dest_param_node->data.param_decl.type = src_param_node->data.param_decl.type;
229 dest_param_node->data.param_decl.is_noalias = src_param_node->data.param_decl.is_noalias;
230 fn_proto->data.fn_proto.params.append(dest_param_node);
231
232 fn_call_node->data.fn_call_expr.params.append(trans_create_node_symbol(c, param_name));
233
234 }
235
236 AstNode *block = trans_create_node(c, NodeTypeBlock);
237 block->data.block.statements.resize(1);
238 block->data.block.statements.items[0] = fn_call_node;
239 block->data.block.last_statement_is_result_expression = true;
240
241 fn_def->data.fn_def.body = block;
242 return fn_def;
243}
244
245static AstNode *get_global(Context *c, Buf *name) {
246 for (size_t i = 0; i < c->root->data.root.top_level_decls.length; i += 1) {
247 AstNode *decl_node = c->root->data.root.top_level_decls.items[i];
248 if (decl_node->type == NodeTypeVariableDeclaration) {
249 if (buf_eql_buf(decl_node->data.variable_declaration.symbol, name)) {
250 return decl_node;
251 }
252 } else if (decl_node->type == NodeTypeFnDef) {
253 if (buf_eql_buf(decl_node->data.fn_def.fn_proto->data.fn_proto.name, name)) {
254 return decl_node;
255 }
256 } else if (decl_node->type == NodeTypeFnProto) {
257 if (buf_eql_buf(decl_node->data.fn_proto.name, name)) {
258 return decl_node;
259 }
260 }
261 }
262 {
263 auto entry = c->macro_table.maybe_get(name);
264 if (entry)
265 return entry->value;
266 }
267 return nullptr;
268}
269
270static AstNode *add_global_var(Context *c, Buf *var_name, AstNode *value_node) {
271 bool is_const = true;
272 AstNode *type_node = nullptr;
273 AstNode *node = trans_create_node_var_decl(c, is_const, var_name, type_node, value_node);
274 c->root->data.root.top_level_decls.append(node);
275 return node;
276}
277
278static const char *decl_name(const Decl *decl) {
279 const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl);
280 return (const char *)named_decl->getName().bytes_begin();
281}
282
283static AstNode *trans_create_node_apint(Context *c, const llvm::APSInt &aps_int) {
284 AstNode *node = trans_create_node(c, NodeTypeIntLiteral);
285 node->data.int_literal.bigint = allocate<BigInt>(1);
286 bigint_init_data(node->data.int_literal.bigint, aps_int.getRawData(), aps_int.getNumWords(), aps_int.isNegative());
287 return node;
288
289}
290
291static bool is_c_void_type(AstNode *node) {
292 return (node->type == NodeTypeSymbol && buf_eql_str(node->data.symbol_expr.symbol, "c_void"));
293}
294
295static bool qual_type_child_is_fn_proto(const QualType &qt) {
296 if (qt.getTypePtr()->getTypeClass() == Type::Paren) {
297 const ParenType *paren_type = static_cast<const ParenType *>(qt.getTypePtr());
298 if (paren_type->getInnerType()->getTypeClass() == Type::FunctionProto) {
299 return true;
300 }
301 } else if (qt.getTypePtr()->getTypeClass() == Type::Attributed) {
302 const AttributedType *attr_type = static_cast<const AttributedType *>(qt.getTypePtr());
303 return qual_type_child_is_fn_proto(attr_type->getEquivalentType());
304 }
305 return false;
306}
307
308static bool c_is_signed_integer(Context *c, QualType qt) {
309 const Type *c_type = qt.getTypePtr();
310 if (c_type->getTypeClass() != Type::Builtin)
311 return false;
312 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(c_type);
313 switch (builtin_ty->getKind()) {
314 case BuiltinType::SChar:
315 case BuiltinType::Short:
316 case BuiltinType::Int:
317 case BuiltinType::Long:
318 case BuiltinType::LongLong:
319 case BuiltinType::Int128:
320 case BuiltinType::WChar_S:
321 return true;
322 default:
323 return false;
324 }
325}
326
327static bool c_is_unsigned_integer(Context *c, QualType qt) {
328 const Type *c_type = qt.getTypePtr();
329 if (c_type->getTypeClass() != Type::Builtin)
330 return false;
331 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(c_type);
332 switch (builtin_ty->getKind()) {
333 case BuiltinType::Char_U:
334 case BuiltinType::UChar:
335 case BuiltinType::Char_S:
336 case BuiltinType::UShort:
337 case BuiltinType::UInt:
338 case BuiltinType::ULong:
339 case BuiltinType::ULongLong:
340 case BuiltinType::UInt128:
341 case BuiltinType::WChar_U:
342 return true;
343 default:
344 return false;
345 }
346}
347
348static bool c_is_float(Context *c, QualType qt) {
349 const Type *c_type = qt.getTypePtr();
350 if (c_type->getTypeClass() != Type::Builtin)
351 return false;
352 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(c_type);
353 switch (builtin_ty->getKind()) {
354 case BuiltinType::Half:
355 case BuiltinType::Float:
356 case BuiltinType::Double:
357 case BuiltinType::Float128:
358 case BuiltinType::LongDouble:
359 return true;
360 default:
361 return false;
362 }
363}
364
365static AstNode * trans_stmt(Context *c, AstNode *block, Stmt *stmt);
366static AstNode * trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc);
367
368static AstNode * trans_expr(Context *c, AstNode *block, Expr *expr) {
369 return trans_stmt(c, block, expr);
370}
371
372static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLocation &source_loc) {
373 switch (ty->getTypeClass()) {
374 case Type::Builtin:
375 {
376 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty);
377 switch (builtin_ty->getKind()) {
378 case BuiltinType::Void:
379 return trans_create_node_symbol_str(c, "c_void");
380 case BuiltinType::Bool:
381 return trans_create_node_symbol_str(c, "bool");
382 case BuiltinType::Char_U:
383 case BuiltinType::UChar:
384 case BuiltinType::Char_S:
385 return trans_create_node_symbol_str(c, "u8");
386 case BuiltinType::SChar:
387 return trans_create_node_symbol_str(c, "i8");
388 case BuiltinType::UShort:
389 return trans_create_node_symbol_str(c, "c_ushort");
390 case BuiltinType::UInt:
391 return trans_create_node_symbol_str(c, "c_uint");
392 case BuiltinType::ULong:
393 return trans_create_node_symbol_str(c, "c_ulong");
394 case BuiltinType::ULongLong:
395 return trans_create_node_symbol_str(c, "c_ulonglong");
396 case BuiltinType::Short:
397 return trans_create_node_symbol_str(c, "c_short");
398 case BuiltinType::Int:
399 return trans_create_node_symbol_str(c, "c_int");
400 case BuiltinType::Long:
401 return trans_create_node_symbol_str(c, "c_long");
402 case BuiltinType::LongLong:
403 return trans_create_node_symbol_str(c, "c_longlong");
404 case BuiltinType::UInt128:
405 return trans_create_node_symbol_str(c, "u128");
406 case BuiltinType::Int128:
407 return trans_create_node_symbol_str(c, "i128");
408 case BuiltinType::Float:
409 return trans_create_node_symbol_str(c, "f32");
410 case BuiltinType::Double:
411 return trans_create_node_symbol_str(c, "f64");
412 case BuiltinType::Float128:
413 return trans_create_node_symbol_str(c, "f128");
414 case BuiltinType::LongDouble:
415 return trans_create_node_symbol_str(c, "c_longdouble");
416 case BuiltinType::WChar_U:
417 case BuiltinType::Char16:
418 case BuiltinType::Char32:
419 case BuiltinType::WChar_S:
420 case BuiltinType::Half:
421 case BuiltinType::NullPtr:
422 case BuiltinType::ObjCId:
423 case BuiltinType::ObjCClass:
424 case BuiltinType::ObjCSel:
425 case BuiltinType::OMPArraySection:
426 case BuiltinType::Dependent:
427 case BuiltinType::Overload:
428 case BuiltinType::BoundMember:
429 case BuiltinType::PseudoObject:
430 case BuiltinType::UnknownAny:
431 case BuiltinType::BuiltinFn:
432 case BuiltinType::ARCUnbridgedCast:
433
434 case BuiltinType::OCLImage1dRO:
435 case BuiltinType::OCLImage1dArrayRO:
436 case BuiltinType::OCLImage1dBufferRO:
437 case BuiltinType::OCLImage2dRO:
438 case BuiltinType::OCLImage2dArrayRO:
439 case BuiltinType::OCLImage2dDepthRO:
440 case BuiltinType::OCLImage2dArrayDepthRO:
441 case BuiltinType::OCLImage2dMSAARO:
442 case BuiltinType::OCLImage2dArrayMSAARO:
443 case BuiltinType::OCLImage2dMSAADepthRO:
444 case BuiltinType::OCLImage2dArrayMSAADepthRO:
445 case BuiltinType::OCLImage3dRO:
446 case BuiltinType::OCLImage1dWO:
447 case BuiltinType::OCLImage1dArrayWO:
448 case BuiltinType::OCLImage1dBufferWO:
449 case BuiltinType::OCLImage2dWO:
450 case BuiltinType::OCLImage2dArrayWO:
451 case BuiltinType::OCLImage2dDepthWO:
452 case BuiltinType::OCLImage2dArrayDepthWO:
453 case BuiltinType::OCLImage2dMSAAWO:
454 case BuiltinType::OCLImage2dArrayMSAAWO:
455 case BuiltinType::OCLImage2dMSAADepthWO:
456 case BuiltinType::OCLImage2dArrayMSAADepthWO:
457 case BuiltinType::OCLImage3dWO:
458 case BuiltinType::OCLImage1dRW:
459 case BuiltinType::OCLImage1dArrayRW:
460 case BuiltinType::OCLImage1dBufferRW:
461 case BuiltinType::OCLImage2dRW:
462 case BuiltinType::OCLImage2dArrayRW:
463 case BuiltinType::OCLImage2dDepthRW:
464 case BuiltinType::OCLImage2dArrayDepthRW:
465 case BuiltinType::OCLImage2dMSAARW:
466 case BuiltinType::OCLImage2dArrayMSAARW:
467 case BuiltinType::OCLImage2dMSAADepthRW:
468 case BuiltinType::OCLImage2dArrayMSAADepthRW:
469 case BuiltinType::OCLImage3dRW:
470 case BuiltinType::OCLSampler:
471 case BuiltinType::OCLEvent:
472 case BuiltinType::OCLClkEvent:
473 case BuiltinType::OCLQueue:
474 case BuiltinType::OCLReserveID:
475 emit_warning(c, source_loc, "unsupported builtin type");
476 return nullptr;
477 }
478 break;
479 }
480 case Type::Pointer:
481 {
482 const PointerType *pointer_ty = static_cast<const PointerType*>(ty);
483 QualType child_qt = pointer_ty->getPointeeType();
484 AstNode *child_node = trans_qual_type(c, child_qt, source_loc);
485 if (child_node == nullptr) {
486 emit_warning(c, source_loc, "pointer to unsupported type");
487 return nullptr;
488 }
489
490 if (qual_type_child_is_fn_proto(child_qt)) {
491 return trans_create_node_prefix_op(c, PrefixOpMaybe, child_node);
492 }
493
494 AstNode *pointer_node = trans_create_node_addr_of(c, child_qt.isConstQualified(),
495 child_qt.isVolatileQualified(), child_node);
496 return trans_create_node_prefix_op(c, PrefixOpMaybe, pointer_node);
497 }
498 case Type::Typedef:
499 {
500 const TypedefType *typedef_ty = static_cast<const TypedefType*>(ty);
501 const TypedefNameDecl *typedef_decl = typedef_ty->getDecl();
502 return resolve_typedef_decl(c, typedef_decl);
503 }
504 case Type::Elaborated:
505 {
506 const ElaboratedType *elaborated_ty = static_cast<const ElaboratedType*>(ty);
507 switch (elaborated_ty->getKeyword()) {
508 case ETK_Struct:
509 return trans_qual_type_with_table(c, elaborated_ty->getNamedType(), source_loc);
510 case ETK_Enum:
511 return trans_qual_type_with_table(c, elaborated_ty->getNamedType(), source_loc);
512 case ETK_Interface:
513 case ETK_Union:
514 case ETK_Class:
515 case ETK_Typename:
516 case ETK_None:
517 emit_warning(c, source_loc, "unsupported elaborated type");
518 return nullptr;
519 }
520 }
521 case Type::FunctionProto:
522 {
523 const FunctionProtoType *fn_proto_ty = static_cast<const FunctionProtoType*>(ty);
524
525 AstNode *proto_node = trans_create_node(c, NodeTypeFnProto);
526 switch (fn_proto_ty->getCallConv()) {
527 case CC_C: // __attribute__((cdecl))
528 proto_node->data.fn_proto.cc = CallingConventionC;
529 proto_node->data.fn_proto.is_extern = true;
530 break;
531 case CC_X86StdCall: // __attribute__((stdcall))
532 proto_node->data.fn_proto.cc = CallingConventionStdcall;
533 break;
534 case CC_X86FastCall: // __attribute__((fastcall))
535 emit_warning(c, source_loc, "unsupported calling convention: x86 fastcall");
536 return nullptr;
537 case CC_X86ThisCall: // __attribute__((thiscall))
538 emit_warning(c, source_loc, "unsupported calling convention: x86 thiscall");
539 return nullptr;
540 case CC_X86VectorCall: // __attribute__((vectorcall))
541 emit_warning(c, source_loc, "unsupported calling convention: x86 vectorcall");
542 return nullptr;
543 case CC_X86Pascal: // __attribute__((pascal))
544 emit_warning(c, source_loc, "unsupported calling convention: x86 pascal");
545 return nullptr;
546 case CC_Win64: // __attribute__((ms_abi))
547 emit_warning(c, source_loc, "unsupported calling convention: win64");
548 return nullptr;
549 case CC_X86_64SysV: // __attribute__((sysv_abi))
550 emit_warning(c, source_loc, "unsupported calling convention: x86 64sysv");
551 return nullptr;
552 case CC_X86RegCall:
553 emit_warning(c, source_loc, "unsupported calling convention: x86 reg");
554 return nullptr;
555 case CC_AAPCS: // __attribute__((pcs("aapcs")))
556 emit_warning(c, source_loc, "unsupported calling convention: aapcs");
557 return nullptr;
558 case CC_AAPCS_VFP: // __attribute__((pcs("aapcs-vfp")))
559 emit_warning(c, source_loc, "unsupported calling convention: aapcs-vfp");
560 return nullptr;
561 case CC_IntelOclBicc: // __attribute__((intel_ocl_bicc))
562 emit_warning(c, source_loc, "unsupported calling convention: intel_ocl_bicc");
563 return nullptr;
564 case CC_SpirFunction: // default for OpenCL functions on SPIR target
565 emit_warning(c, source_loc, "unsupported calling convention: SPIR function");
566 return nullptr;
567 case CC_OpenCLKernel:
568 emit_warning(c, source_loc, "unsupported calling convention: OpenCLKernel");
569 return nullptr;
570 case CC_Swift:
571 emit_warning(c, source_loc, "unsupported calling convention: Swift");
572 return nullptr;
573 case CC_PreserveMost:
574 emit_warning(c, source_loc, "unsupported calling convention: PreserveMost");
575 return nullptr;
576 case CC_PreserveAll:
577 emit_warning(c, source_loc, "unsupported calling convention: PreserveAll");
578 return nullptr;
579 }
580
581 proto_node->data.fn_proto.is_var_args = fn_proto_ty->isVariadic();
582 size_t param_count = fn_proto_ty->getNumParams();
583
584 if (fn_proto_ty->getNoReturnAttr()) {
585 proto_node->data.fn_proto.return_type = trans_create_node_symbol_str(c, "noreturn");
586 } else {
587 proto_node->data.fn_proto.return_type = trans_qual_type(c, fn_proto_ty->getReturnType(),
588 source_loc);
589 if (proto_node->data.fn_proto.return_type == nullptr) {
590 emit_warning(c, source_loc, "unsupported function proto return type");
591 return nullptr;
592 }
593 // convert c_void to actual void (only for return type)
594 if (is_c_void_type(proto_node->data.fn_proto.return_type)) {
595 proto_node->data.fn_proto.return_type = nullptr;
596 }
597 }
598
599 //emit_warning(c, source_loc, "TODO figure out fn prototype fn name");
600 const char *fn_name = nullptr;
601 if (fn_name != nullptr) {
602 proto_node->data.fn_proto.name = buf_create_from_str(fn_name);
603 }
604
605 for (size_t i = 0; i < param_count; i += 1) {
606 QualType qt = fn_proto_ty->getParamType(i);
607 AstNode *param_type_node = trans_qual_type(c, qt, source_loc);
608
609 if (param_type_node == nullptr) {
610 emit_warning(c, source_loc, "unresolved function proto parameter type");
611 return nullptr;
612 }
613
614 AstNode *param_node = trans_create_node(c, NodeTypeParamDecl);
615 //emit_warning(c, source_loc, "TODO figure out fn prototype param name");
616 const char *param_name = nullptr;
617 if (param_name != nullptr) {
618 param_node->data.param_decl.name = buf_create_from_str(param_name);
619 }
620 param_node->data.param_decl.is_noalias = qt.isRestrictQualified();
621 param_node->data.param_decl.type = param_type_node;
622 proto_node->data.fn_proto.params.append(param_node);
623 }
624 // TODO check for always_inline attribute
625 // TODO check for align attribute
626
627 return proto_node;
628 }
629 case Type::Record:
630 {
631 const RecordType *record_ty = static_cast<const RecordType*>(ty);
632 return resolve_record_decl(c, record_ty->getDecl());
633 }
634 case Type::Enum:
635 {
636 const EnumType *enum_ty = static_cast<const EnumType*>(ty);
637 return resolve_enum_decl(c, enum_ty->getDecl());
638 }
639 case Type::ConstantArray:
640 {
641 const ConstantArrayType *const_arr_ty = static_cast<const ConstantArrayType *>(ty);
642 AstNode *child_type_node = trans_qual_type(c, const_arr_ty->getElementType(), source_loc);
643 if (child_type_node == nullptr) {
644 emit_warning(c, source_loc, "unresolved array element type");
645 return nullptr;
646 }
647 uint64_t size = const_arr_ty->getSize().getLimitedValue();
648 AstNode *size_node = trans_create_node_unsigned(c, size);
649 return trans_create_node_array_type(c, size_node, child_type_node);
650 }
651 case Type::Paren:
652 {
653 const ParenType *paren_ty = static_cast<const ParenType *>(ty);
654 return trans_qual_type(c, paren_ty->getInnerType(), source_loc);
655 }
656 case Type::Decayed:
657 {
658 const DecayedType *decayed_ty = static_cast<const DecayedType *>(ty);
659 return trans_qual_type(c, decayed_ty->getDecayedType(), source_loc);
660 }
661 case Type::Attributed:
662 {
663 const AttributedType *attributed_ty = static_cast<const AttributedType *>(ty);
664 return trans_qual_type(c, attributed_ty->getEquivalentType(), source_loc);
665 }
666 case Type::BlockPointer:
667 case Type::LValueReference:
668 case Type::RValueReference:
669 case Type::MemberPointer:
670 case Type::IncompleteArray:
671 case Type::VariableArray:
672 case Type::DependentSizedArray:
673 case Type::DependentSizedExtVector:
674 case Type::Vector:
675 case Type::ExtVector:
676 case Type::FunctionNoProto:
677 case Type::UnresolvedUsing:
678 case Type::Adjusted:
679 case Type::TypeOfExpr:
680 case Type::TypeOf:
681 case Type::Decltype:
682 case Type::UnaryTransform:
683 case Type::TemplateTypeParm:
684 case Type::SubstTemplateTypeParm:
685 case Type::SubstTemplateTypeParmPack:
686 case Type::TemplateSpecialization:
687 case Type::Auto:
688 case Type::InjectedClassName:
689 case Type::DependentName:
690 case Type::DependentTemplateSpecialization:
691 case Type::PackExpansion:
692 case Type::ObjCObject:
693 case Type::ObjCInterface:
694 case Type::Complex:
695 case Type::ObjCObjectPointer:
696 case Type::Atomic:
697 case Type::Pipe:
698 case Type::ObjCTypeParam:
699 case Type::DeducedTemplateSpecialization:
700 emit_warning(c, source_loc, "unsupported type: '%s'", ty->getTypeClassName());
701 return nullptr;
702 }
703 zig_unreachable();
704}
705
706static AstNode * trans_qual_type_with_table(Context *c, QualType qt, const SourceLocation &source_loc) {
707 return trans_type_with_table(c, qt.getTypePtr(), source_loc);
708}
709
710static AstNode * trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc) {
711 return trans_qual_type_with_table(c, qt, source_loc);
712}
713
714static AstNode * trans_compound_stmt(Context *c, AstNode *parent, CompoundStmt *stmt) {
715 AstNode *child_block = trans_create_node(c, NodeTypeBlock);
716 for (CompoundStmt::body_iterator it = stmt->body_begin(), end_it = stmt->body_end(); it != end_it; ++it) {
717 AstNode *child_node = trans_stmt(c, child_block, *it);
718 if (child_node != nullptr)
719 child_block->data.block.statements.append(child_node);
720 }
721 return child_block;
722}
723
724static AstNode *trans_return_stmt(Context *c, AstNode *block, ReturnStmt *stmt) {
725 Expr *value_expr = stmt->getRetValue();
726 if (value_expr == nullptr) {
727 zig_panic("TODO handle C return void");
728 } else {
729 AstNode *return_node = trans_create_node(c, NodeTypeReturnExpr);
730 return_node->data.return_expr.expr = trans_expr(c, block, value_expr);
731 return return_node;
732 }
733}
734
735static AstNode *trans_integer_literal(Context *c, IntegerLiteral *stmt) {
736 llvm::APSInt result;
737 if (!stmt->EvaluateAsInt(result, *c->ctx)) {
738 zig_panic("TODO handle libclang unable to evaluate C integer literal");
739 }
740 return trans_create_node_apint(c, result);
741}
742
743static AstNode *trans_conditional_operator(Context *c, AstNode *block, ConditionalOperator *stmt) {
744 AstNode *node = trans_create_node(c, NodeTypeIfBoolExpr);
745
746 Expr *cond_expr = stmt->getCond();
747 Expr *true_expr = stmt->getTrueExpr();
748 Expr *false_expr = stmt->getFalseExpr();
749
750 node->data.if_bool_expr.condition = trans_expr(c, block, cond_expr);
751 node->data.if_bool_expr.then_block = trans_expr(c, block, true_expr);
752 node->data.if_bool_expr.else_node = trans_expr(c, block, false_expr);
753
754 return node;
755}
756
757static AstNode * trans_create_bin_op(Context *c, AstNode *block, Expr *lhs, BinOpType bin_op, Expr *rhs) {
758 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
759 node->data.bin_op_expr.bin_op = bin_op;
760 node->data.bin_op_expr.op1 = trans_expr(c, block, lhs);
761 node->data.bin_op_expr.op2 = trans_expr(c, block, rhs);
762 return node;
763}
764
765static AstNode * trans_binary_operator(Context *c, AstNode *block, BinaryOperator *stmt) {
766 switch (stmt->getOpcode()) {
767 case BO_PtrMemD:
768 zig_panic("TODO handle more C binary operators: BO_PtrMemD");
769 case BO_PtrMemI:
770 zig_panic("TODO handle more C binary operators: BO_PtrMemI");
771 case BO_Mul:
772 zig_panic("TODO handle more C binary operators: BO_Mul");
773 case BO_Div:
774 zig_panic("TODO handle more C binary operators: BO_Div");
775 case BO_Rem:
776 zig_panic("TODO handle more C binary operators: BO_Rem");
777 case BO_Add:
778 zig_panic("TODO handle more C binary operators: BO_Add");
779 case BO_Sub:
780 zig_panic("TODO handle more C binary operators: BO_Sub");
781 case BO_Shl:
782 zig_panic("TODO handle more C binary operators: BO_Shl");
783 case BO_Shr:
784 zig_panic("TODO handle more C binary operators: BO_Shr");
785 case BO_LT:
786 return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeCmpLessThan, stmt->getRHS());
787 case BO_GT:
788 return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeCmpGreaterThan, stmt->getRHS());
789 case BO_LE:
790 return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeCmpLessOrEq, stmt->getRHS());
791 case BO_GE:
792 return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeCmpGreaterOrEq, stmt->getRHS());
793 case BO_EQ:
794 zig_panic("TODO handle more C binary operators: BO_EQ");
795 case BO_NE:
796 zig_panic("TODO handle more C binary operators: BO_NE");
797 case BO_And:
798 zig_panic("TODO handle more C binary operators: BO_And");
799 case BO_Xor:
800 zig_panic("TODO handle more C binary operators: BO_Xor");
801 case BO_Or:
802 zig_panic("TODO handle more C binary operators: BO_Or");
803 case BO_LAnd:
804 zig_panic("TODO handle more C binary operators: BO_LAnd");
805 case BO_LOr:
806 zig_panic("TODO handle more C binary operators: BO_LOr");
807 case BO_Assign:
808 zig_panic("TODO handle more C binary operators: BO_Assign");
809 case BO_MulAssign:
810 zig_panic("TODO handle more C binary operators: BO_MulAssign");
811 case BO_DivAssign:
812 zig_panic("TODO handle more C binary operators: BO_DivAssign");
813 case BO_RemAssign:
814 zig_panic("TODO handle more C binary operators: BO_RemAssign");
815 case BO_AddAssign:
816 zig_panic("TODO handle more C binary operators: BO_AddAssign");
817 case BO_SubAssign:
818 zig_panic("TODO handle more C binary operators: BO_SubAssign");
819 case BO_ShlAssign:
820 zig_panic("TODO handle more C binary operators: BO_ShlAssign");
821 case BO_ShrAssign:
822 zig_panic("TODO handle more C binary operators: BO_ShrAssign");
823 case BO_AndAssign:
824 zig_panic("TODO handle more C binary operators: BO_AndAssign");
825 case BO_XorAssign:
826 zig_panic("TODO handle more C binary operators: BO_XorAssign");
827 case BO_OrAssign:
828 zig_panic("TODO handle more C binary operators: BO_OrAssign");
829 case BO_Comma:
830 zig_panic("TODO handle more C binary operators: BO_Comma");
831 }
832
833 zig_unreachable();
834}
835
836static AstNode * trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCastExpr *stmt) {
837 switch (stmt->getCastKind()) {
838 case CK_LValueToRValue:
839 return trans_expr(c, block, stmt->getSubExpr());
840 case CK_IntegralCast:
841 {
842 AstNode *node = trans_create_node_builtin_fn_call_str(c, "bitCast");
843 node->data.fn_call_expr.params.append(trans_qual_type(c, stmt->getType(), stmt->getExprLoc()));
844 node->data.fn_call_expr.params.append(trans_expr(c, block, stmt->getSubExpr()));
845 return node;
846 }
847 case CK_Dependent:
848 zig_panic("TODO handle C translation cast CK_Dependent");
849 case CK_BitCast:
850 zig_panic("TODO handle C translation cast CK_BitCast");
851 case CK_LValueBitCast:
852 zig_panic("TODO handle C translation cast CK_LValueBitCast");
853 case CK_NoOp:
854 zig_panic("TODO handle C translation cast CK_NoOp");
855 case CK_BaseToDerived:
856 zig_panic("TODO handle C translation cast CK_BaseToDerived");
857 case CK_DerivedToBase:
858 zig_panic("TODO handle C translation cast CK_DerivedToBase");
859 case CK_UncheckedDerivedToBase:
860 zig_panic("TODO handle C translation cast CK_UncheckedDerivedToBase");
861 case CK_Dynamic:
862 zig_panic("TODO handle C translation cast CK_Dynamic");
863 case CK_ToUnion:
864 zig_panic("TODO handle C translation cast CK_ToUnion");
865 case CK_ArrayToPointerDecay:
866 zig_panic("TODO handle C translation cast CK_ArrayToPointerDecay");
867 case CK_FunctionToPointerDecay:
868 zig_panic("TODO handle C translation cast CK_FunctionToPointerDecay");
869 case CK_NullToPointer:
870 zig_panic("TODO handle C translation cast CK_NullToPointer");
871 case CK_NullToMemberPointer:
872 zig_panic("TODO handle C translation cast CK_NullToMemberPointer");
873 case CK_BaseToDerivedMemberPointer:
874 zig_panic("TODO handle C translation cast CK_BaseToDerivedMemberPointer");
875 case CK_DerivedToBaseMemberPointer:
876 zig_panic("TODO handle C translation cast CK_DerivedToBaseMemberPointer");
877 case CK_MemberPointerToBoolean:
878 zig_panic("TODO handle C translation cast CK_MemberPointerToBoolean");
879 case CK_ReinterpretMemberPointer:
880 zig_panic("TODO handle C translation cast CK_ReinterpretMemberPointer");
881 case CK_UserDefinedConversion:
882 zig_panic("TODO handle C translation cast CK_UserDefinedConversion");
883 case CK_ConstructorConversion:
884 zig_panic("TODO handle C translation cast CK_ConstructorConversion");
885 case CK_IntegralToPointer:
886 zig_panic("TODO handle C translation cast CK_IntegralToPointer");
887 case CK_PointerToIntegral:
888 zig_panic("TODO handle C translation cast CK_PointerToIntegral");
889 case CK_PointerToBoolean:
890 zig_panic("TODO handle C translation cast CK_PointerToBoolean");
891 case CK_ToVoid:
892 zig_panic("TODO handle C translation cast CK_ToVoid");
893 case CK_VectorSplat:
894 zig_panic("TODO handle C translation cast CK_VectorSplat");
895 case CK_IntegralToBoolean:
896 zig_panic("TODO handle C translation cast CK_IntegralToBoolean");
897 case CK_IntegralToFloating:
898 zig_panic("TODO handle C translation cast CK_IntegralToFloating");
899 case CK_FloatingToIntegral:
900 zig_panic("TODO handle C translation cast CK_FloatingToIntegral");
901 case CK_FloatingToBoolean:
902 zig_panic("TODO handle C translation cast CK_FloatingToBoolean");
903 case CK_BooleanToSignedIntegral:
904 zig_panic("TODO handle C translation cast CK_BooleanToSignedIntegral");
905 case CK_FloatingCast:
906 zig_panic("TODO handle C translation cast CK_FloatingCast");
907 case CK_CPointerToObjCPointerCast:
908 zig_panic("TODO handle C translation cast CK_CPointerToObjCPointerCast");
909 case CK_BlockPointerToObjCPointerCast:
910 zig_panic("TODO handle C translation cast CK_BlockPointerToObjCPointerCast");
911 case CK_AnyPointerToBlockPointerCast:
912 zig_panic("TODO handle C translation cast CK_AnyPointerToBlockPointerCast");
913 case CK_ObjCObjectLValueCast:
914 zig_panic("TODO handle C translation cast CK_ObjCObjectLValueCast");
915 case CK_FloatingRealToComplex:
916 zig_panic("TODO handle C translation cast CK_FloatingRealToComplex");
917 case CK_FloatingComplexToReal:
918 zig_panic("TODO handle C translation cast CK_FloatingComplexToReal");
919 case CK_FloatingComplexToBoolean:
920 zig_panic("TODO handle C translation cast CK_FloatingComplexToBoolean");
921 case CK_FloatingComplexCast:
922 zig_panic("TODO handle C translation cast CK_FloatingComplexCast");
923 case CK_FloatingComplexToIntegralComplex:
924 zig_panic("TODO handle C translation cast CK_FloatingComplexToIntegralComplex");
925 case CK_IntegralRealToComplex:
926 zig_panic("TODO handle C translation cast CK_IntegralRealToComplex");
927 case CK_IntegralComplexToReal:
928 zig_panic("TODO handle C translation cast CK_IntegralComplexToReal");
929 case CK_IntegralComplexToBoolean:
930 zig_panic("TODO handle C translation cast CK_IntegralComplexToBoolean");
931 case CK_IntegralComplexCast:
932 zig_panic("TODO handle C translation cast CK_IntegralComplexCast");
933 case CK_IntegralComplexToFloatingComplex:
934 zig_panic("TODO handle C translation cast CK_IntegralComplexToFloatingComplex");
935 case CK_ARCProduceObject:
936 zig_panic("TODO handle C translation cast CK_ARCProduceObject");
937 case CK_ARCConsumeObject:
938 zig_panic("TODO handle C translation cast CK_ARCConsumeObject");
939 case CK_ARCReclaimReturnedObject:
940 zig_panic("TODO handle C translation cast CK_ARCReclaimReturnedObject");
941 case CK_ARCExtendBlockObject:
942 zig_panic("TODO handle C translation cast CK_ARCExtendBlockObject");
943 case CK_AtomicToNonAtomic:
944 zig_panic("TODO handle C translation cast CK_AtomicToNonAtomic");
945 case CK_NonAtomicToAtomic:
946 zig_panic("TODO handle C translation cast CK_NonAtomicToAtomic");
947 case CK_CopyAndAutoreleaseBlockObject:
948 zig_panic("TODO handle C translation cast CK_CopyAndAutoreleaseBlockObject");
949 case CK_BuiltinFnToFnPtr:
950 zig_panic("TODO handle C translation cast CK_BuiltinFnToFnPtr");
951 case CK_ZeroToOCLEvent:
952 zig_panic("TODO handle C translation cast CK_ZeroToOCLEvent");
953 case CK_ZeroToOCLQueue:
954 zig_panic("TODO handle C translation cast CK_ZeroToOCLQueue");
955 case CK_AddressSpaceConversion:
956 zig_panic("TODO handle C translation cast CK_AddressSpaceConversion");
957 case CK_IntToOCLSampler:
958 zig_panic("TODO handle C translation cast CK_IntToOCLSampler");
959 }
960 zig_unreachable();
961}
962
963static AstNode * trans_decl_ref_expr(Context *c, DeclRefExpr *stmt) {
964 ValueDecl *value_decl = stmt->getDecl();
965 const char *name = decl_name(value_decl);
966
967 AstNode *node = trans_create_node(c, NodeTypeSymbol);
968 node->data.symbol_expr.symbol = buf_create_from_str(name);
969 return node;
970}
971
972static AstNode * trans_unary_operator(Context *c, AstNode *block, UnaryOperator *stmt) {
973 switch (stmt->getOpcode()) {
974 case UO_PostInc:
975 zig_panic("TODO handle C translation UO_PostInc");
976 case UO_PostDec:
977 zig_panic("TODO handle C translation UO_PostDec");
978 case UO_PreInc:
979 zig_panic("TODO handle C translation UO_PreInc");
980 case UO_PreDec:
981 zig_panic("TODO handle C translation UO_PreDec");
982 case UO_AddrOf:
983 zig_panic("TODO handle C translation UO_AddrOf");
984 case UO_Deref:
985 zig_panic("TODO handle C translation UO_Deref");
986 case UO_Plus:
987 zig_panic("TODO handle C translation UO_Plus");
988 case UO_Minus:
989 {
990 Expr *op_expr = stmt->getSubExpr();
991 if (c_is_signed_integer(c, op_expr->getType()) || c_is_float(c, op_expr->getType())) {
992 AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);
993 node->data.prefix_op_expr.prefix_op = PrefixOpNegation;
994 node->data.prefix_op_expr.primary_expr = trans_expr(c, block, op_expr);
995 return node;
996 } else if (c_is_unsigned_integer(c, op_expr->getType())) {
997 // we gotta emit 0 -% x
998 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
999 node->data.bin_op_expr.op1 = trans_create_node_unsigned(c, 0);
1000 node->data.bin_op_expr.op2 = trans_expr(c, block, op_expr);
1001 node->data.bin_op_expr.bin_op = BinOpTypeSubWrap;
1002 return node;
1003 } else {
1004 zig_panic("TODO translate C negation with non float non integer");
1005 }
1006 }
1007 case UO_Not:
1008 zig_panic("TODO handle C translation UO_Not");
1009 case UO_LNot:
1010 zig_panic("TODO handle C translation UO_LNot");
1011 case UO_Real:
1012 zig_panic("TODO handle C translation UO_Real");
1013 case UO_Imag:
1014 zig_panic("TODO handle C translation UO_Imag");
1015 case UO_Extension:
1016 zig_panic("TODO handle C translation UO_Extension");
1017 case UO_Coawait:
1018 zig_panic("TODO handle C translation UO_Coawait");
1019 }
1020 zig_unreachable();
1021}
1022
1023static AstNode * trans_local_declaration(Context *c, AstNode *block, DeclStmt *stmt) {
1024 for (auto iter = stmt->decl_begin(); iter != stmt->decl_end(); iter++) {
1025 Decl *decl = *iter;
1026 switch (decl->getKind()) {
1027 case Decl::Var: {
1028 VarDecl *var_decl = (VarDecl *)decl;
1029 QualType qual_type = var_decl->getTypeSourceInfo()->getType();
1030 AstNode *init_node = var_decl->hasInit() ? trans_expr(c, block, var_decl->getInit()) : nullptr;
1031 AstNode *type_node = trans_qual_type(c, qual_type, stmt->getStartLoc());
1032 AstNode *node = trans_create_node_var_decl(c, qual_type.isConstQualified(),
1033 buf_create_from_str(decl_name(var_decl)), type_node, init_node);
1034 block->data.block.statements.append(node);
1035 continue;
1036 }
1037 case Decl::AccessSpec:
1038 zig_panic("TODO handle decl kind AccessSpec");
1039 case Decl::Block:
1040 zig_panic("TODO handle decl kind Block");
1041 case Decl::Captured:
1042 zig_panic("TODO handle decl kind Captured");
1043 case Decl::ClassScopeFunctionSpecialization:
1044 zig_panic("TODO handle decl kind ClassScopeFunctionSpecialization");
1045 case Decl::Empty:
1046 zig_panic("TODO handle decl kind Empty");
1047 case Decl::Export:
1048 zig_panic("TODO handle decl kind Export");
1049 case Decl::ExternCContext:
1050 zig_panic("TODO handle decl kind ExternCContext");
1051 case Decl::FileScopeAsm:
1052 zig_panic("TODO handle decl kind FileScopeAsm");
1053 case Decl::Friend:
1054 zig_panic("TODO handle decl kind Friend");
1055 case Decl::FriendTemplate:
1056 zig_panic("TODO handle decl kind FriendTemplate");
1057 case Decl::Import:
1058 zig_panic("TODO handle decl kind Import");
1059 case Decl::LinkageSpec:
1060 zig_panic("TODO handle decl kind LinkageSpec");
1061 case Decl::Label:
1062 zig_panic("TODO handle decl kind Label");
1063 case Decl::Namespace:
1064 zig_panic("TODO handle decl kind Namespace");
1065 case Decl::NamespaceAlias:
1066 zig_panic("TODO handle decl kind NamespaceAlias");
1067 case Decl::ObjCCompatibleAlias:
1068 zig_panic("TODO handle decl kind ObjCCompatibleAlias");
1069 case Decl::ObjCCategory:
1070 zig_panic("TODO handle decl kind ObjCCategory");
1071 case Decl::ObjCCategoryImpl:
1072 zig_panic("TODO handle decl kind ObjCCategoryImpl");
1073 case Decl::ObjCImplementation:
1074 zig_panic("TODO handle decl kind ObjCImplementation");
1075 case Decl::ObjCInterface:
1076 zig_panic("TODO handle decl kind ObjCInterface");
1077 case Decl::ObjCProtocol:
1078 zig_panic("TODO handle decl kind ObjCProtocol");
1079 case Decl::ObjCMethod:
1080 zig_panic("TODO handle decl kind ObjCMethod");
1081 case Decl::ObjCProperty:
1082 zig_panic("TODO handle decl kind ObjCProperty");
1083 case Decl::BuiltinTemplate:
1084 zig_panic("TODO handle decl kind BuiltinTemplate");
1085 case Decl::ClassTemplate:
1086 zig_panic("TODO handle decl kind ClassTemplate");
1087 case Decl::FunctionTemplate:
1088 zig_panic("TODO handle decl kind FunctionTemplate");
1089 case Decl::TypeAliasTemplate:
1090 zig_panic("TODO handle decl kind TypeAliasTemplate");
1091 case Decl::VarTemplate:
1092 zig_panic("TODO handle decl kind VarTemplate");
1093 case Decl::TemplateTemplateParm:
1094 zig_panic("TODO handle decl kind TemplateTemplateParm");
1095 case Decl::Enum:
1096 zig_panic("TODO handle decl kind Enum");
1097 case Decl::Record:
1098 zig_panic("TODO handle decl kind Record");
1099 case Decl::CXXRecord:
1100 zig_panic("TODO handle decl kind CXXRecord");
1101 case Decl::ClassTemplateSpecialization:
1102 zig_panic("TODO handle decl kind ClassTemplateSpecialization");
1103 case Decl::ClassTemplatePartialSpecialization:
1104 zig_panic("TODO handle decl kind ClassTemplatePartialSpecialization");
1105 case Decl::TemplateTypeParm:
1106 zig_panic("TODO handle decl kind TemplateTypeParm");
1107 case Decl::ObjCTypeParam:
1108 zig_panic("TODO handle decl kind ObjCTypeParam");
1109 case Decl::TypeAlias:
1110 zig_panic("TODO handle decl kind TypeAlias");
1111 case Decl::Typedef:
1112 zig_panic("TODO handle decl kind Typedef");
1113 case Decl::UnresolvedUsingTypename:
1114 zig_panic("TODO handle decl kind UnresolvedUsingTypename");
1115 case Decl::Using:
1116 zig_panic("TODO handle decl kind Using");
1117 case Decl::UsingDirective:
1118 zig_panic("TODO handle decl kind UsingDirective");
1119 case Decl::UsingPack:
1120 zig_panic("TODO handle decl kind UsingPack");
1121 case Decl::UsingShadow:
1122 zig_panic("TODO handle decl kind UsingShadow");
1123 case Decl::ConstructorUsingShadow:
1124 zig_panic("TODO handle decl kind ConstructorUsingShadow");
1125 case Decl::Binding:
1126 zig_panic("TODO handle decl kind Binding");
1127 case Decl::Field:
1128 zig_panic("TODO handle decl kind Field");
1129 case Decl::ObjCAtDefsField:
1130 zig_panic("TODO handle decl kind ObjCAtDefsField");
1131 case Decl::ObjCIvar:
1132 zig_panic("TODO handle decl kind ObjCIvar");
1133 case Decl::Function:
1134 zig_panic("TODO handle decl kind Function");
1135 case Decl::CXXDeductionGuide:
1136 zig_panic("TODO handle decl kind CXXDeductionGuide");
1137 case Decl::CXXMethod:
1138 zig_panic("TODO handle decl kind CXXMethod");
1139 case Decl::CXXConstructor:
1140 zig_panic("TODO handle decl kind CXXConstructor");
1141 case Decl::CXXConversion:
1142 zig_panic("TODO handle decl kind CXXConversion");
1143 case Decl::CXXDestructor:
1144 zig_panic("TODO handle decl kind CXXDestructor");
1145 case Decl::MSProperty:
1146 zig_panic("TODO handle decl kind MSProperty");
1147 case Decl::NonTypeTemplateParm:
1148 zig_panic("TODO handle decl kind NonTypeTemplateParm");
1149 case Decl::Decomposition:
1150 zig_panic("TODO handle decl kind Decomposition");
1151 case Decl::ImplicitParam:
1152 zig_panic("TODO handle decl kind ImplicitParam");
1153 case Decl::OMPCapturedExpr:
1154 zig_panic("TODO handle decl kind OMPCapturedExpr");
1155 case Decl::ParmVar:
1156 zig_panic("TODO handle decl kind ParmVar");
1157 case Decl::VarTemplateSpecialization:
1158 zig_panic("TODO handle decl kind VarTemplateSpecialization");
1159 case Decl::VarTemplatePartialSpecialization:
1160 zig_panic("TODO handle decl kind VarTemplatePartialSpecialization");
1161 case Decl::EnumConstant:
1162 zig_panic("TODO handle decl kind EnumConstant");
1163 case Decl::IndirectField:
1164 zig_panic("TODO handle decl kind IndirectField");
1165 case Decl::OMPDeclareReduction:
1166 zig_panic("TODO handle decl kind OMPDeclareReduction");
1167 case Decl::UnresolvedUsingValue:
1168 zig_panic("TODO handle decl kind UnresolvedUsingValue");
1169 case Decl::OMPThreadPrivate:
1170 zig_panic("TODO handle decl kind OMPThreadPrivate");
1171 case Decl::ObjCPropertyImpl:
1172 zig_panic("TODO handle decl kind ObjCPropertyImpl");
1173 case Decl::PragmaComment:
1174 zig_panic("TODO handle decl kind PragmaComment");
1175 case Decl::PragmaDetectMismatch:
1176 zig_panic("TODO handle decl kind PragmaDetectMismatch");
1177 case Decl::StaticAssert:
1178 zig_panic("TODO handle decl kind StaticAssert");
1179 case Decl::TranslationUnit:
1180 zig_panic("TODO handle decl kind TranslationUnit");
1181 }
1182 zig_unreachable();
1183 }
1184
1185 // declarations were already added
1186 return nullptr;
1187}
1188
1189static AstNode *trans_while_loop(Context *c, AstNode *block, WhileStmt *stmt) {
1190 AstNode *while_node = trans_create_node(c, NodeTypeWhileExpr);
1191 while_node->data.while_expr.condition = trans_expr(c, block, stmt->getCond());
1192 while_node->data.while_expr.body = trans_stmt(c, block, stmt->getBody());
1193 return while_node;
1194}
1195
1196static AstNode *trans_stmt(Context *c, AstNode *block, Stmt *stmt) {
1197 Stmt::StmtClass sc = stmt->getStmtClass();
1198 switch (sc) {
1199 case Stmt::ReturnStmtClass:
1200 return trans_return_stmt(c, block, (ReturnStmt *)stmt);
1201 case Stmt::CompoundStmtClass:
1202 return trans_compound_stmt(c, block, (CompoundStmt *)stmt);
1203 case Stmt::IntegerLiteralClass:
1204 return trans_integer_literal(c, (IntegerLiteral *)stmt);
1205 case Stmt::ConditionalOperatorClass:
1206 return trans_conditional_operator(c, block, (ConditionalOperator *)stmt);
1207 case Stmt::BinaryOperatorClass:
1208 return trans_binary_operator(c, block, (BinaryOperator *)stmt);
1209 case Stmt::ImplicitCastExprClass:
1210 return trans_implicit_cast_expr(c, block, (ImplicitCastExpr *)stmt);
1211 case Stmt::DeclRefExprClass:
1212 return trans_decl_ref_expr(c, (DeclRefExpr *)stmt);
1213 case Stmt::UnaryOperatorClass:
1214 return trans_unary_operator(c, block, (UnaryOperator *)stmt);
1215 case Stmt::DeclStmtClass:
1216 return trans_local_declaration(c, block, (DeclStmt *)stmt);
1217 case Stmt::WhileStmtClass:
1218 return trans_while_loop(c, block, (WhileStmt *)stmt);
1219 case Stmt::CaseStmtClass:
1220 zig_panic("TODO handle C CaseStmtClass");
1221 case Stmt::DefaultStmtClass:
1222 zig_panic("TODO handle C DefaultStmtClass");
1223 case Stmt::SwitchStmtClass:
1224 zig_panic("TODO handle C SwitchStmtClass");
1225 case Stmt::NoStmtClass:
1226 zig_panic("TODO handle C NoStmtClass");
1227 case Stmt::GCCAsmStmtClass:
1228 zig_panic("TODO handle C GCCAsmStmtClass");
1229 case Stmt::MSAsmStmtClass:
1230 zig_panic("TODO handle C MSAsmStmtClass");
1231 case Stmt::AttributedStmtClass:
1232 zig_panic("TODO handle C AttributedStmtClass");
1233 case Stmt::BreakStmtClass:
1234 zig_panic("TODO handle C BreakStmtClass");
1235 case Stmt::CXXCatchStmtClass:
1236 zig_panic("TODO handle C CXXCatchStmtClass");
1237 case Stmt::CXXForRangeStmtClass:
1238 zig_panic("TODO handle C CXXForRangeStmtClass");
1239 case Stmt::CXXTryStmtClass:
1240 zig_panic("TODO handle C CXXTryStmtClass");
1241 case Stmt::CapturedStmtClass:
1242 zig_panic("TODO handle C CapturedStmtClass");
1243 case Stmt::ContinueStmtClass:
1244 zig_panic("TODO handle C ContinueStmtClass");
1245 case Stmt::CoreturnStmtClass:
1246 zig_panic("TODO handle C CoreturnStmtClass");
1247 case Stmt::CoroutineBodyStmtClass:
1248 zig_panic("TODO handle C CoroutineBodyStmtClass");
1249 case Stmt::DoStmtClass:
1250 zig_panic("TODO handle C DoStmtClass");
1251 case Stmt::BinaryConditionalOperatorClass:
1252 zig_panic("TODO handle C BinaryConditionalOperatorClass");
1253 case Stmt::AddrLabelExprClass:
1254 zig_panic("TODO handle C AddrLabelExprClass");
1255 case Stmt::ArrayInitIndexExprClass:
1256 zig_panic("TODO handle C ArrayInitIndexExprClass");
1257 case Stmt::ArrayInitLoopExprClass:
1258 zig_panic("TODO handle C ArrayInitLoopExprClass");
1259 case Stmt::ArraySubscriptExprClass:
1260 zig_panic("TODO handle C ArraySubscriptExprClass");
1261 case Stmt::ArrayTypeTraitExprClass:
1262 zig_panic("TODO handle C ArrayTypeTraitExprClass");
1263 case Stmt::AsTypeExprClass:
1264 zig_panic("TODO handle C AsTypeExprClass");
1265 case Stmt::AtomicExprClass:
1266 zig_panic("TODO handle C AtomicExprClass");
1267 case Stmt::CompoundAssignOperatorClass:
1268 zig_panic("TODO handle C CompoundAssignOperatorClass");
1269 case Stmt::BlockExprClass:
1270 zig_panic("TODO handle C BlockExprClass");
1271 case Stmt::CXXBindTemporaryExprClass:
1272 zig_panic("TODO handle C CXXBindTemporaryExprClass");
1273 case Stmt::CXXBoolLiteralExprClass:
1274 zig_panic("TODO handle C CXXBoolLiteralExprClass");
1275 case Stmt::CXXConstructExprClass:
1276 zig_panic("TODO handle C CXXConstructExprClass");
1277 case Stmt::CXXTemporaryObjectExprClass:
1278 zig_panic("TODO handle C CXXTemporaryObjectExprClass");
1279 case Stmt::CXXDefaultArgExprClass:
1280 zig_panic("TODO handle C CXXDefaultArgExprClass");
1281 case Stmt::CXXDefaultInitExprClass:
1282 zig_panic("TODO handle C CXXDefaultInitExprClass");
1283 case Stmt::CXXDeleteExprClass:
1284 zig_panic("TODO handle C CXXDeleteExprClass");
1285 case Stmt::CXXDependentScopeMemberExprClass:
1286 zig_panic("TODO handle C CXXDependentScopeMemberExprClass");
1287 case Stmt::CXXFoldExprClass:
1288 zig_panic("TODO handle C CXXFoldExprClass");
1289 case Stmt::CXXInheritedCtorInitExprClass:
1290 zig_panic("TODO handle C CXXInheritedCtorInitExprClass");
1291 case Stmt::CXXNewExprClass:
1292 zig_panic("TODO handle C CXXNewExprClass");
1293 case Stmt::CXXNoexceptExprClass:
1294 zig_panic("TODO handle C CXXNoexceptExprClass");
1295 case Stmt::CXXNullPtrLiteralExprClass:
1296 zig_panic("TODO handle C CXXNullPtrLiteralExprClass");
1297 case Stmt::CXXPseudoDestructorExprClass:
1298 zig_panic("TODO handle C CXXPseudoDestructorExprClass");
1299 case Stmt::CXXScalarValueInitExprClass:
1300 zig_panic("TODO handle C CXXScalarValueInitExprClass");
1301 case Stmt::CXXStdInitializerListExprClass:
1302 zig_panic("TODO handle C CXXStdInitializerListExprClass");
1303 case Stmt::CXXThisExprClass:
1304 zig_panic("TODO handle C CXXThisExprClass");
1305 case Stmt::CXXThrowExprClass:
1306 zig_panic("TODO handle C CXXThrowExprClass");
1307 case Stmt::CXXTypeidExprClass:
1308 zig_panic("TODO handle C CXXTypeidExprClass");
1309 case Stmt::CXXUnresolvedConstructExprClass:
1310 zig_panic("TODO handle C CXXUnresolvedConstructExprClass");
1311 case Stmt::CXXUuidofExprClass:
1312 zig_panic("TODO handle C CXXUuidofExprClass");
1313 case Stmt::CallExprClass:
1314 zig_panic("TODO handle C CallExprClass");
1315 case Stmt::CUDAKernelCallExprClass:
1316 zig_panic("TODO handle C CUDAKernelCallExprClass");
1317 case Stmt::CXXMemberCallExprClass:
1318 zig_panic("TODO handle C CXXMemberCallExprClass");
1319 case Stmt::CXXOperatorCallExprClass:
1320 zig_panic("TODO handle C CXXOperatorCallExprClass");
1321 case Stmt::UserDefinedLiteralClass:
1322 zig_panic("TODO handle C UserDefinedLiteralClass");
1323 case Stmt::CStyleCastExprClass:
1324 zig_panic("TODO handle C CStyleCastExprClass");
1325 case Stmt::CXXFunctionalCastExprClass:
1326 zig_panic("TODO handle C CXXFunctionalCastExprClass");
1327 case Stmt::CXXConstCastExprClass:
1328 zig_panic("TODO handle C CXXConstCastExprClass");
1329 case Stmt::CXXDynamicCastExprClass:
1330 zig_panic("TODO handle C CXXDynamicCastExprClass");
1331 case Stmt::CXXReinterpretCastExprClass:
1332 zig_panic("TODO handle C CXXReinterpretCastExprClass");
1333 case Stmt::CXXStaticCastExprClass:
1334 zig_panic("TODO handle C CXXStaticCastExprClass");
1335 case Stmt::ObjCBridgedCastExprClass:
1336 zig_panic("TODO handle C ObjCBridgedCastExprClass");
1337 case Stmt::CharacterLiteralClass:
1338 zig_panic("TODO handle C CharacterLiteralClass");
1339 case Stmt::ChooseExprClass:
1340 zig_panic("TODO handle C ChooseExprClass");
1341 case Stmt::CompoundLiteralExprClass:
1342 zig_panic("TODO handle C CompoundLiteralExprClass");
1343 case Stmt::ConvertVectorExprClass:
1344 zig_panic("TODO handle C ConvertVectorExprClass");
1345 case Stmt::CoawaitExprClass:
1346 zig_panic("TODO handle C CoawaitExprClass");
1347 case Stmt::CoyieldExprClass:
1348 zig_panic("TODO handle C CoyieldExprClass");
1349 case Stmt::DependentCoawaitExprClass:
1350 zig_panic("TODO handle C DependentCoawaitExprClass");
1351 case Stmt::DependentScopeDeclRefExprClass:
1352 zig_panic("TODO handle C DependentScopeDeclRefExprClass");
1353 case Stmt::DesignatedInitExprClass:
1354 zig_panic("TODO handle C DesignatedInitExprClass");
1355 case Stmt::DesignatedInitUpdateExprClass:
1356 zig_panic("TODO handle C DesignatedInitUpdateExprClass");
1357 case Stmt::ExprWithCleanupsClass:
1358 zig_panic("TODO handle C ExprWithCleanupsClass");
1359 case Stmt::ExpressionTraitExprClass:
1360 zig_panic("TODO handle C ExpressionTraitExprClass");
1361 case Stmt::ExtVectorElementExprClass:
1362 zig_panic("TODO handle C ExtVectorElementExprClass");
1363 case Stmt::FloatingLiteralClass:
1364 zig_panic("TODO handle C FloatingLiteralClass");
1365 case Stmt::FunctionParmPackExprClass:
1366 zig_panic("TODO handle C FunctionParmPackExprClass");
1367 case Stmt::GNUNullExprClass:
1368 zig_panic("TODO handle C GNUNullExprClass");
1369 case Stmt::GenericSelectionExprClass:
1370 zig_panic("TODO handle C GenericSelectionExprClass");
1371 case Stmt::ImaginaryLiteralClass:
1372 zig_panic("TODO handle C ImaginaryLiteralClass");
1373 case Stmt::ImplicitValueInitExprClass:
1374 zig_panic("TODO handle C ImplicitValueInitExprClass");
1375 case Stmt::InitListExprClass:
1376 zig_panic("TODO handle C InitListExprClass");
1377 case Stmt::LambdaExprClass:
1378 zig_panic("TODO handle C LambdaExprClass");
1379 case Stmt::MSPropertyRefExprClass:
1380 zig_panic("TODO handle C MSPropertyRefExprClass");
1381 case Stmt::MSPropertySubscriptExprClass:
1382 zig_panic("TODO handle C MSPropertySubscriptExprClass");
1383 case Stmt::MaterializeTemporaryExprClass:
1384 zig_panic("TODO handle C MaterializeTemporaryExprClass");
1385 case Stmt::MemberExprClass:
1386 zig_panic("TODO handle C MemberExprClass");
1387 case Stmt::NoInitExprClass:
1388 zig_panic("TODO handle C NoInitExprClass");
1389 case Stmt::OMPArraySectionExprClass:
1390 zig_panic("TODO handle C OMPArraySectionExprClass");
1391 case Stmt::ObjCArrayLiteralClass:
1392 zig_panic("TODO handle C ObjCArrayLiteralClass");
1393 case Stmt::ObjCAvailabilityCheckExprClass:
1394 zig_panic("TODO handle C ObjCAvailabilityCheckExprClass");
1395 case Stmt::ObjCBoolLiteralExprClass:
1396 zig_panic("TODO handle C ObjCBoolLiteralExprClass");
1397 case Stmt::ObjCBoxedExprClass:
1398 zig_panic("TODO handle C ObjCBoxedExprClass");
1399 case Stmt::ObjCDictionaryLiteralClass:
1400 zig_panic("TODO handle C ObjCDictionaryLiteralClass");
1401 case Stmt::ObjCEncodeExprClass:
1402 zig_panic("TODO handle C ObjCEncodeExprClass");
1403 case Stmt::ObjCIndirectCopyRestoreExprClass:
1404 zig_panic("TODO handle C ObjCIndirectCopyRestoreExprClass");
1405 case Stmt::ObjCIsaExprClass:
1406 zig_panic("TODO handle C ObjCIsaExprClass");
1407 case Stmt::ObjCIvarRefExprClass:
1408 zig_panic("TODO handle C ObjCIvarRefExprClass");
1409 case Stmt::ObjCMessageExprClass:
1410 zig_panic("TODO handle C ObjCMessageExprClass");
1411 case Stmt::ObjCPropertyRefExprClass:
1412 zig_panic("TODO handle C ObjCPropertyRefExprClass");
1413 case Stmt::ObjCProtocolExprClass:
1414 zig_panic("TODO handle C ObjCProtocolExprClass");
1415 case Stmt::ObjCSelectorExprClass:
1416 zig_panic("TODO handle C ObjCSelectorExprClass");
1417 case Stmt::ObjCStringLiteralClass:
1418 zig_panic("TODO handle C ObjCStringLiteralClass");
1419 case Stmt::ObjCSubscriptRefExprClass:
1420 zig_panic("TODO handle C ObjCSubscriptRefExprClass");
1421 case Stmt::OffsetOfExprClass:
1422 zig_panic("TODO handle C OffsetOfExprClass");
1423 case Stmt::OpaqueValueExprClass:
1424 zig_panic("TODO handle C OpaqueValueExprClass");
1425 case Stmt::UnresolvedLookupExprClass:
1426 zig_panic("TODO handle C UnresolvedLookupExprClass");
1427 case Stmt::UnresolvedMemberExprClass:
1428 zig_panic("TODO handle C UnresolvedMemberExprClass");
1429 case Stmt::PackExpansionExprClass:
1430 zig_panic("TODO handle C PackExpansionExprClass");
1431 case Stmt::ParenExprClass:
1432 zig_panic("TODO handle C ParenExprClass");
1433 case Stmt::ParenListExprClass:
1434 zig_panic("TODO handle C ParenListExprClass");
1435 case Stmt::PredefinedExprClass:
1436 zig_panic("TODO handle C PredefinedExprClass");
1437 case Stmt::PseudoObjectExprClass:
1438 zig_panic("TODO handle C PseudoObjectExprClass");
1439 case Stmt::ShuffleVectorExprClass:
1440 zig_panic("TODO handle C ShuffleVectorExprClass");
1441 case Stmt::SizeOfPackExprClass:
1442 zig_panic("TODO handle C SizeOfPackExprClass");
1443 case Stmt::StmtExprClass:
1444 zig_panic("TODO handle C StmtExprClass");
1445 case Stmt::StringLiteralClass:
1446 zig_panic("TODO handle C StringLiteralClass");
1447 case Stmt::SubstNonTypeTemplateParmExprClass:
1448 zig_panic("TODO handle C SubstNonTypeTemplateParmExprClass");
1449 case Stmt::SubstNonTypeTemplateParmPackExprClass:
1450 zig_panic("TODO handle C SubstNonTypeTemplateParmPackExprClass");
1451 case Stmt::TypeTraitExprClass:
1452 zig_panic("TODO handle C TypeTraitExprClass");
1453 case Stmt::TypoExprClass:
1454 zig_panic("TODO handle C TypoExprClass");
1455 case Stmt::UnaryExprOrTypeTraitExprClass:
1456 zig_panic("TODO handle C UnaryExprOrTypeTraitExprClass");
1457 case Stmt::VAArgExprClass:
1458 zig_panic("TODO handle C VAArgExprClass");
1459 case Stmt::ForStmtClass:
1460 zig_panic("TODO handle C ForStmtClass");
1461 case Stmt::GotoStmtClass:
1462 zig_panic("TODO handle C GotoStmtClass");
1463 case Stmt::IfStmtClass:
1464 zig_panic("TODO handle C IfStmtClass");
1465 case Stmt::IndirectGotoStmtClass:
1466 zig_panic("TODO handle C IndirectGotoStmtClass");
1467 case Stmt::LabelStmtClass:
1468 zig_panic("TODO handle C LabelStmtClass");
1469 case Stmt::MSDependentExistsStmtClass:
1470 zig_panic("TODO handle C MSDependentExistsStmtClass");
1471 case Stmt::NullStmtClass:
1472 zig_panic("TODO handle C NullStmtClass");
1473 case Stmt::OMPAtomicDirectiveClass:
1474 zig_panic("TODO handle C OMPAtomicDirectiveClass");
1475 case Stmt::OMPBarrierDirectiveClass:
1476 zig_panic("TODO handle C OMPBarrierDirectiveClass");
1477 case Stmt::OMPCancelDirectiveClass:
1478 zig_panic("TODO handle C OMPCancelDirectiveClass");
1479 case Stmt::OMPCancellationPointDirectiveClass:
1480 zig_panic("TODO handle C OMPCancellationPointDirectiveClass");
1481 case Stmt::OMPCriticalDirectiveClass:
1482 zig_panic("TODO handle C OMPCriticalDirectiveClass");
1483 case Stmt::OMPFlushDirectiveClass:
1484 zig_panic("TODO handle C OMPFlushDirectiveClass");
1485 case Stmt::OMPDistributeDirectiveClass:
1486 zig_panic("TODO handle C OMPDistributeDirectiveClass");
1487 case Stmt::OMPDistributeParallelForDirectiveClass:
1488 zig_panic("TODO handle C OMPDistributeParallelForDirectiveClass");
1489 case Stmt::OMPDistributeParallelForSimdDirectiveClass:
1490 zig_panic("TODO handle C OMPDistributeParallelForSimdDirectiveClass");
1491 case Stmt::OMPDistributeSimdDirectiveClass:
1492 zig_panic("TODO handle C OMPDistributeSimdDirectiveClass");
1493 case Stmt::OMPForDirectiveClass:
1494 zig_panic("TODO handle C OMPForDirectiveClass");
1495 case Stmt::OMPForSimdDirectiveClass:
1496 zig_panic("TODO handle C OMPForSimdDirectiveClass");
1497 case Stmt::OMPParallelForDirectiveClass:
1498 zig_panic("TODO handle C OMPParallelForDirectiveClass");
1499 case Stmt::OMPParallelForSimdDirectiveClass:
1500 zig_panic("TODO handle C OMPParallelForSimdDirectiveClass");
1501 case Stmt::OMPSimdDirectiveClass:
1502 zig_panic("TODO handle C OMPSimdDirectiveClass");
1503 case Stmt::OMPTargetParallelForSimdDirectiveClass:
1504 zig_panic("TODO handle C OMPTargetParallelForSimdDirectiveClass");
1505 case Stmt::OMPTargetSimdDirectiveClass:
1506 zig_panic("TODO handle C OMPTargetSimdDirectiveClass");
1507 case Stmt::OMPTargetTeamsDistributeDirectiveClass:
1508 zig_panic("TODO handle C OMPTargetTeamsDistributeDirectiveClass");
1509 case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
1510 zig_panic("TODO handle C OMPTargetTeamsDistributeParallelForDirectiveClass");
1511 case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
1512 zig_panic("TODO handle C OMPTargetTeamsDistributeParallelForSimdDirectiveClass");
1513 case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
1514 zig_panic("TODO handle C OMPTargetTeamsDistributeSimdDirectiveClass");
1515 case Stmt::OMPTaskLoopDirectiveClass:
1516 zig_panic("TODO handle C OMPTaskLoopDirectiveClass");
1517 case Stmt::OMPTaskLoopSimdDirectiveClass:
1518 zig_panic("TODO handle C OMPTaskLoopSimdDirectiveClass");
1519 case Stmt::OMPTeamsDistributeDirectiveClass:
1520 zig_panic("TODO handle C OMPTeamsDistributeDirectiveClass");
1521 case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
1522 zig_panic("TODO handle C OMPTeamsDistributeParallelForDirectiveClass");
1523 case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
1524 zig_panic("TODO handle C OMPTeamsDistributeParallelForSimdDirectiveClass");
1525 case Stmt::OMPTeamsDistributeSimdDirectiveClass:
1526 zig_panic("TODO handle C OMPTeamsDistributeSimdDirectiveClass");
1527 case Stmt::OMPMasterDirectiveClass:
1528 zig_panic("TODO handle C OMPMasterDirectiveClass");
1529 case Stmt::OMPOrderedDirectiveClass:
1530 zig_panic("TODO handle C OMPOrderedDirectiveClass");
1531 case Stmt::OMPParallelDirectiveClass:
1532 zig_panic("TODO handle C OMPParallelDirectiveClass");
1533 case Stmt::OMPParallelSectionsDirectiveClass:
1534 zig_panic("TODO handle C OMPParallelSectionsDirectiveClass");
1535 case Stmt::OMPSectionDirectiveClass:
1536 zig_panic("TODO handle C OMPSectionDirectiveClass");
1537 case Stmt::OMPSectionsDirectiveClass:
1538 zig_panic("TODO handle C OMPSectionsDirectiveClass");
1539 case Stmt::OMPSingleDirectiveClass:
1540 zig_panic("TODO handle C OMPSingleDirectiveClass");
1541 case Stmt::OMPTargetDataDirectiveClass:
1542 zig_panic("TODO handle C OMPTargetDataDirectiveClass");
1543 case Stmt::OMPTargetDirectiveClass:
1544 zig_panic("TODO handle C OMPTargetDirectiveClass");
1545 case Stmt::OMPTargetEnterDataDirectiveClass:
1546 zig_panic("TODO handle C OMPTargetEnterDataDirectiveClass");
1547 case Stmt::OMPTargetExitDataDirectiveClass:
1548 zig_panic("TODO handle C OMPTargetExitDataDirectiveClass");
1549 case Stmt::OMPTargetParallelDirectiveClass:
1550 zig_panic("TODO handle C OMPTargetParallelDirectiveClass");
1551 case Stmt::OMPTargetParallelForDirectiveClass:
1552 zig_panic("TODO handle C OMPTargetParallelForDirectiveClass");
1553 case Stmt::OMPTargetTeamsDirectiveClass:
1554 zig_panic("TODO handle C OMPTargetTeamsDirectiveClass");
1555 case Stmt::OMPTargetUpdateDirectiveClass:
1556 zig_panic("TODO handle C OMPTargetUpdateDirectiveClass");
1557 case Stmt::OMPTaskDirectiveClass:
1558 zig_panic("TODO handle C OMPTaskDirectiveClass");
1559 case Stmt::OMPTaskgroupDirectiveClass:
1560 zig_panic("TODO handle C OMPTaskgroupDirectiveClass");
1561 case Stmt::OMPTaskwaitDirectiveClass:
1562 zig_panic("TODO handle C OMPTaskwaitDirectiveClass");
1563 case Stmt::OMPTaskyieldDirectiveClass:
1564 zig_panic("TODO handle C OMPTaskyieldDirectiveClass");
1565 case Stmt::OMPTeamsDirectiveClass:
1566 zig_panic("TODO handle C OMPTeamsDirectiveClass");
1567 case Stmt::ObjCAtCatchStmtClass:
1568 zig_panic("TODO handle C ObjCAtCatchStmtClass");
1569 case Stmt::ObjCAtFinallyStmtClass:
1570 zig_panic("TODO handle C ObjCAtFinallyStmtClass");
1571 case Stmt::ObjCAtSynchronizedStmtClass:
1572 zig_panic("TODO handle C ObjCAtSynchronizedStmtClass");
1573 case Stmt::ObjCAtThrowStmtClass:
1574 zig_panic("TODO handle C ObjCAtThrowStmtClass");
1575 case Stmt::ObjCAtTryStmtClass:
1576 zig_panic("TODO handle C ObjCAtTryStmtClass");
1577 case Stmt::ObjCAutoreleasePoolStmtClass:
1578 zig_panic("TODO handle C ObjCAutoreleasePoolStmtClass");
1579 case Stmt::ObjCForCollectionStmtClass:
1580 zig_panic("TODO handle C ObjCForCollectionStmtClass");
1581 case Stmt::SEHExceptStmtClass:
1582 zig_panic("TODO handle C SEHExceptStmtClass");
1583 case Stmt::SEHFinallyStmtClass:
1584 zig_panic("TODO handle C SEHFinallyStmtClass");
1585 case Stmt::SEHLeaveStmtClass:
1586 zig_panic("TODO handle C SEHLeaveStmtClass");
1587 case Stmt::SEHTryStmtClass:
1588 zig_panic("TODO handle C SEHTryStmtClass");
1589 }
1590 zig_unreachable();
1591}
1592
1593static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
1594 Buf *fn_name = buf_create_from_str(decl_name(fn_decl));
1595
1596 if (get_global(c, fn_name)) {
1597 // we already saw this function
1598 return;
1599 }
1600
1601 AstNode *proto_node = trans_qual_type(c, fn_decl->getType(), fn_decl->getLocation());
1602 if (proto_node == nullptr) {
1603 emit_warning(c, fn_decl->getLocation(), "unable to resolve prototype of function '%s'", buf_ptr(fn_name));
1604 return;
1605 }
1606
1607 proto_node->data.fn_proto.name = fn_name;
1608 proto_node->data.fn_proto.is_extern = !fn_decl->hasBody();
1609
1610 StorageClass sc = fn_decl->getStorageClass();
1611 if (sc == SC_None) {
1612 proto_node->data.fn_proto.visib_mod = fn_decl->hasBody() ? VisibModExport : c->visib_mod;
1613 } else if (sc == SC_Extern || sc == SC_Static) {
1614 proto_node->data.fn_proto.visib_mod = c->visib_mod;
1615 } else if (sc == SC_PrivateExtern) {
1616 emit_warning(c, fn_decl->getLocation(), "unsupported storage class: private extern");
1617 return;
1618 } else {
1619 emit_warning(c, fn_decl->getLocation(), "unsupported storage class: unknown");
1620 return;
1621 }
1622
1623 for (size_t i = 0; i < proto_node->data.fn_proto.params.length; i += 1) {
1624 AstNode *param_node = proto_node->data.fn_proto.params.at(i);
1625 const ParmVarDecl *param = fn_decl->getParamDecl(i);
1626 const char *name = decl_name(param);
1627 if (strlen(name) == 0) {
1628 Buf *proto_param_name = param_node->data.param_decl.name;
1629 if (proto_param_name == nullptr) {
1630 param_node->data.param_decl.name = buf_sprintf("arg%" ZIG_PRI_usize "", i);
1631 } else {
1632 param_node->data.param_decl.name = proto_param_name;
1633 }
1634 } else {
1635 param_node->data.param_decl.name = buf_create_from_str(name);
1636 }
1637 }
1638
1639 if (fn_decl->hasBody()) {
1640 Stmt *body = fn_decl->getBody();
1641
1642 AstNode *fn_def_node = trans_create_node(c, NodeTypeFnDef);
1643 fn_def_node->data.fn_def.fn_proto = proto_node;
1644 fn_def_node->data.fn_def.body = trans_stmt(c, nullptr, body);
1645
1646 proto_node->data.fn_proto.fn_def_node = fn_def_node;
1647 c->root->data.root.top_level_decls.append(fn_def_node);
1648 return;
1649 }
1650
1651 c->root->data.root.top_level_decls.append(proto_node);
1652}
1653
1654static AstNode *resolve_typdef_as_builtin(Context *c, const TypedefNameDecl *typedef_decl, const char *primitive_name) {
1655 AstNode *node = trans_create_node_symbol_str(c, primitive_name);
1656 c->decl_table.put(typedef_decl, node);
1657 return node;
1658}
1659
1660static AstNode *resolve_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) {
1661 auto existing_entry = c->decl_table.maybe_get((void*)typedef_decl);
1662 if (existing_entry) {
1663 return existing_entry->value;
1664 }
1665
1666 QualType child_qt = typedef_decl->getUnderlyingType();
1667 Buf *type_name = buf_create_from_str(decl_name(typedef_decl));
1668
1669 if (buf_eql_str(type_name, "uint8_t")) {
1670 return resolve_typdef_as_builtin(c, typedef_decl, "u8");
1671 } else if (buf_eql_str(type_name, "int8_t")) {
1672 return resolve_typdef_as_builtin(c, typedef_decl, "i8");
1673 } else if (buf_eql_str(type_name, "uint16_t")) {
1674 return resolve_typdef_as_builtin(c, typedef_decl, "u16");
1675 } else if (buf_eql_str(type_name, "int16_t")) {
1676 return resolve_typdef_as_builtin(c, typedef_decl, "i16");
1677 } else if (buf_eql_str(type_name, "uint32_t")) {
1678 return resolve_typdef_as_builtin(c, typedef_decl, "u32");
1679 } else if (buf_eql_str(type_name, "int32_t")) {
1680 return resolve_typdef_as_builtin(c, typedef_decl, "i32");
1681 } else if (buf_eql_str(type_name, "uint64_t")) {
1682 return resolve_typdef_as_builtin(c, typedef_decl, "u64");
1683 } else if (buf_eql_str(type_name, "int64_t")) {
1684 return resolve_typdef_as_builtin(c, typedef_decl, "i64");
1685 } else if (buf_eql_str(type_name, "intptr_t")) {
1686 return resolve_typdef_as_builtin(c, typedef_decl, "isize");
1687 } else if (buf_eql_str(type_name, "uintptr_t")) {
1688 return resolve_typdef_as_builtin(c, typedef_decl, "usize");
1689 } else if (buf_eql_str(type_name, "ssize_t")) {
1690 return resolve_typdef_as_builtin(c, typedef_decl, "isize");
1691 } else if (buf_eql_str(type_name, "size_t")) {
1692 return resolve_typdef_as_builtin(c, typedef_decl, "usize");
1693 }
1694
1695 // if the underlying type is anonymous, we can special case it to just
1696 // use the name of this typedef
1697 // TODO
1698
1699 AstNode *type_node = trans_qual_type(c, child_qt, typedef_decl->getLocation());
1700 if (type_node == nullptr) {
1701 emit_warning(c, typedef_decl->getLocation(), "typedef %s - unresolved child type", buf_ptr(type_name));
1702 c->decl_table.put(typedef_decl, nullptr);
1703 return nullptr;
1704 }
1705 add_global_var(c, type_name, type_node);
1706
1707 AstNode *symbol_node = trans_create_node_symbol(c, type_name);
1708 c->decl_table.put(typedef_decl, symbol_node);
1709 return symbol_node;
1710}
1711
1712struct AstNode *demote_enum_to_opaque(Context *c, const EnumDecl *enum_decl,
1713 Buf *full_type_name, Buf *bare_name)
1714{
1715 AstNode *opaque_node = trans_create_node_opaque(c);
1716 if (full_type_name == nullptr) {
1717 c->decl_table.put(enum_decl->getCanonicalDecl(), opaque_node);
1718 return opaque_node;
1719 }
1720 AstNode *symbol_node = trans_create_node_symbol(c, full_type_name);
1721 add_global_weak_alias(c, bare_name, full_type_name);
1722 add_global_var(c, full_type_name, opaque_node);
1723 c->decl_table.put(enum_decl->getCanonicalDecl(), symbol_node);
1724 return symbol_node;
1725}
1726
1727static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) {
1728 auto existing_entry = c->decl_table.maybe_get((void*)enum_decl->getCanonicalDecl());
1729 if (existing_entry) {
1730 return existing_entry->value;
1731 }
1732
1733 const char *raw_name = decl_name(enum_decl);
1734 bool is_anonymous = (raw_name[0] == 0);
1735 Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name);
1736 Buf *full_type_name = is_anonymous ? nullptr : buf_sprintf("enum_%s", buf_ptr(bare_name));
1737
1738 const EnumDecl *enum_def = enum_decl->getDefinition();
1739 if (!enum_def) {
1740 return demote_enum_to_opaque(c, enum_decl, full_type_name, bare_name);
1741 }
1742
1743 bool pure_enum = true;
1744 uint32_t field_count = 0;
1745 for (auto it = enum_def->enumerator_begin(),
1746 it_end = enum_def->enumerator_end();
1747 it != it_end; ++it, field_count += 1)
1748 {
1749 const EnumConstantDecl *enum_const = *it;
1750 if (enum_const->getInitExpr()) {
1751 pure_enum = false;
1752 }
1753 }
1754
1755 AstNode *tag_int_type = trans_qual_type(c, enum_decl->getIntegerType(), enum_decl->getLocation());
1756 assert(tag_int_type);
1757
1758 if (pure_enum) {
1759 AstNode *enum_node = trans_create_node(c, NodeTypeContainerDecl);
1760 enum_node->data.container_decl.kind = ContainerKindEnum;
1761 enum_node->data.container_decl.layout = ContainerLayoutExtern;
1762 enum_node->data.container_decl.init_arg_expr = tag_int_type;
1763
1764 enum_node->data.container_decl.fields.resize(field_count);
1765 uint32_t i = 0;
1766 for (auto it = enum_def->enumerator_begin(),
1767 it_end = enum_def->enumerator_end();
1768 it != it_end; ++it, i += 1)
1769 {
1770 const EnumConstantDecl *enum_const = *it;
1771
1772 Buf *enum_val_name = buf_create_from_str(decl_name(enum_const));
1773 Buf *field_name;
1774 if (bare_name != nullptr && buf_starts_with_buf(enum_val_name, bare_name)) {
1775 field_name = buf_slice(enum_val_name, buf_len(bare_name), buf_len(enum_val_name));
1776 } else {
1777 field_name = enum_val_name;
1778 }
1779
1780 AstNode *field_node = trans_create_node(c, NodeTypeStructField);
1781 field_node->data.struct_field.name = field_name;
1782 field_node->data.struct_field.type = nullptr;
1783 enum_node->data.container_decl.fields.items[i] = field_node;
1784
1785 // in C each enum value is in the global namespace. so we put them there too.
1786 // at this point we can rely on the enum emitting successfully
1787 AstNode *field_access_node = trans_create_node_field_access(c,
1788 trans_create_node_symbol(c, full_type_name), field_name);
1789 add_global_var(c, enum_val_name, field_access_node);
1790 }
1791
1792 if (is_anonymous) {
1793 c->decl_table.put(enum_decl->getCanonicalDecl(), enum_node);
1794 return enum_node;
1795 } else {
1796 AstNode *symbol_node = trans_create_node_symbol(c, full_type_name);
1797 add_global_weak_alias(c, bare_name, full_type_name);
1798 add_global_var(c, full_type_name, enum_node);
1799 c->decl_table.put(enum_decl->getCanonicalDecl(), symbol_node);
1800 return enum_node;
1801 }
1802 }
1803
1804 // TODO after issue #305 is solved, make this be an enum with tag_int_type
1805 // as the integer type and set the custom enum values
1806 AstNode *enum_node = tag_int_type;
1807
1808
1809 // add variables for all the values with enum_node
1810 for (auto it = enum_def->enumerator_begin(),
1811 it_end = enum_def->enumerator_end();
1812 it != it_end; ++it)
1813 {
1814 const EnumConstantDecl *enum_const = *it;
1815
1816 Buf *enum_val_name = buf_create_from_str(decl_name(enum_const));
1817 AstNode *int_node = trans_create_node_apint(c, enum_const->getInitVal());
1818 AstNode *var_node = add_global_var(c, enum_val_name, int_node);
1819 var_node->data.variable_declaration.type = tag_int_type;
1820 }
1821
1822 if (is_anonymous) {
1823 c->decl_table.put(enum_decl->getCanonicalDecl(), enum_node);
1824 return enum_node;
1825 } else {
1826 AstNode *symbol_node = trans_create_node_symbol(c, full_type_name);
1827 add_global_weak_alias(c, bare_name, full_type_name);
1828 add_global_var(c, full_type_name, enum_node);
1829 return symbol_node;
1830 }
1831}
1832
1833static AstNode *demote_struct_to_opaque(Context *c, const RecordDecl *record_decl,
1834 Buf *full_type_name, Buf *bare_name)
1835{
1836 AstNode *opaque_node = trans_create_node_opaque(c);
1837 if (full_type_name == nullptr) {
1838 c->decl_table.put(record_decl->getCanonicalDecl(), opaque_node);
1839 return opaque_node;
1840 }
1841 AstNode *symbol_node = trans_create_node_symbol(c, full_type_name);
1842 add_global_weak_alias(c, bare_name, full_type_name);
1843 add_global_var(c, full_type_name, opaque_node);
1844 c->decl_table.put(record_decl->getCanonicalDecl(), symbol_node);
1845 return symbol_node;
1846}
1847
1848static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {
1849 auto existing_entry = c->decl_table.maybe_get((void*)record_decl->getCanonicalDecl());
1850 if (existing_entry) {
1851 return existing_entry->value;
1852 }
1853
1854 const char *raw_name = decl_name(record_decl);
1855
1856 if (!record_decl->isStruct()) {
1857 emit_warning(c, record_decl->getLocation(), "skipping record %s, not a struct", raw_name);
1858 c->decl_table.put(record_decl->getCanonicalDecl(), nullptr);
1859 return nullptr;
1860 }
1861
1862 bool is_anonymous = record_decl->isAnonymousStructOrUnion() || raw_name[0] == 0;
1863 Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name);
1864 Buf *full_type_name = (bare_name == nullptr) ? nullptr : buf_sprintf("struct_%s", buf_ptr(bare_name));
1865
1866 RecordDecl *record_def = record_decl->getDefinition();
1867 if (record_def == nullptr) {
1868 return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);
1869 }
1870
1871 // count fields and validate
1872 uint32_t field_count = 0;
1873 for (auto it = record_def->field_begin(),
1874 it_end = record_def->field_end();
1875 it != it_end; ++it, field_count += 1)
1876 {
1877 const FieldDecl *field_decl = *it;
1878
1879 if (field_decl->isBitField()) {
1880 emit_warning(c, field_decl->getLocation(), "struct %s demoted to opaque type - has bitfield",
1881 is_anonymous ? "(anon)" : buf_ptr(bare_name));
1882 return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);
1883 }
1884 }
1885
1886 AstNode *struct_node = trans_create_node(c, NodeTypeContainerDecl);
1887 struct_node->data.container_decl.kind = ContainerKindStruct;
1888 struct_node->data.container_decl.layout = ContainerLayoutExtern;
1889
1890 // TODO handle attribute packed
1891
1892 struct_node->data.container_decl.fields.resize(field_count);
1893
1894 // must be before fields in case a circular reference happens
1895 if (is_anonymous) {
1896 c->decl_table.put(record_decl->getCanonicalDecl(), struct_node);
1897 } else {
1898 c->decl_table.put(record_decl->getCanonicalDecl(), trans_create_node_symbol(c, full_type_name));
1899 }
1900
1901 uint32_t i = 0;
1902 for (auto it = record_def->field_begin(),
1903 it_end = record_def->field_end();
1904 it != it_end; ++it, i += 1)
1905 {
1906 const FieldDecl *field_decl = *it;
1907
1908 AstNode *field_node = trans_create_node(c, NodeTypeStructField);
1909 field_node->data.struct_field.name = buf_create_from_str(decl_name(field_decl));
1910 field_node->data.struct_field.type = trans_qual_type(c, field_decl->getType(), field_decl->getLocation());
1911
1912 if (field_node->data.struct_field.type == nullptr) {
1913 emit_warning(c, field_decl->getLocation(),
1914 "struct %s demoted to opaque type - unresolved type",
1915 is_anonymous ? "(anon)" : buf_ptr(bare_name));
1916
1917 return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);
1918 }
1919
1920 struct_node->data.container_decl.fields.items[i] = field_node;
1921 }
1922
1923 if (is_anonymous) {
1924 return struct_node;
1925 } else {
1926 add_global_weak_alias(c, bare_name, full_type_name);
1927 add_global_var(c, full_type_name, struct_node);
1928 return trans_create_node_symbol(c, full_type_name);
1929 }
1930}
1931
1932static void visit_var_decl(Context *c, const VarDecl *var_decl) {
1933 Buf *name = buf_create_from_str(decl_name(var_decl));
1934
1935 switch (var_decl->getTLSKind()) {
1936 case VarDecl::TLS_None:
1937 break;
1938 case VarDecl::TLS_Static:
1939 emit_warning(c, var_decl->getLocation(),
1940 "ignoring variable '%s' - static thread local storage", buf_ptr(name));
1941 return;
1942 case VarDecl::TLS_Dynamic:
1943 emit_warning(c, var_decl->getLocation(),
1944 "ignoring variable '%s' - dynamic thread local storage", buf_ptr(name));
1945 return;
1946 }
1947
1948 QualType qt = var_decl->getType();
1949 AstNode *var_type = trans_qual_type(c, qt, var_decl->getLocation());
1950 if (var_type == nullptr) {
1951 emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - unresolved type", buf_ptr(name));
1952 return;
1953 }
1954
1955 bool is_extern = var_decl->hasExternalStorage();
1956 bool is_static = var_decl->isFileVarDecl();
1957 bool is_const = qt.isConstQualified();
1958
1959 if (is_static && !is_extern) {
1960 AstNode *init_node;
1961 if (var_decl->hasInit()) {
1962 APValue *ap_value = var_decl->evaluateValue();
1963 if (ap_value == nullptr) {
1964 emit_warning(c, var_decl->getLocation(),
1965 "ignoring variable '%s' - unable to evaluate initializer", buf_ptr(name));
1966 return;
1967 }
1968 switch (ap_value->getKind()) {
1969 case APValue::Int:
1970 init_node = trans_create_node_apint(c, ap_value->getInt());
1971 break;
1972 case APValue::Uninitialized:
1973 init_node = trans_create_node_symbol_str(c, "undefined");
1974 break;
1975 case APValue::Float:
1976 case APValue::ComplexInt:
1977 case APValue::ComplexFloat:
1978 case APValue::LValue:
1979 case APValue::Vector:
1980 case APValue::Array:
1981 case APValue::Struct:
1982 case APValue::Union:
1983 case APValue::MemberPointer:
1984 case APValue::AddrLabelDiff:
1985 emit_warning(c, var_decl->getLocation(),
1986 "ignoring variable '%s' - unrecognized initializer value kind", buf_ptr(name));
1987 return;
1988 }
1989 } else {
1990 init_node = trans_create_node_symbol_str(c, "undefined");
1991 }
1992
1993 AstNode *var_node = trans_create_node_var_decl(c, is_const, name, var_type, init_node);
1994 c->root->data.root.top_level_decls.append(var_node);
1995 return;
1996 }
1997
1998 if (is_extern) {
1999 AstNode *var_node = trans_create_node_var_decl(c, is_const, name, var_type, nullptr);
2000 var_node->data.variable_declaration.is_extern = true;
2001 c->root->data.root.top_level_decls.append(var_node);
2002 return;
2003 }
2004
2005 emit_warning(c, var_decl->getLocation(),
2006 "ignoring variable '%s' - non-extern, non-static variable", buf_ptr(name));
2007 return;
2008}
2009
2010static bool decl_visitor(void *context, const Decl *decl) {
2011 Context *c = (Context*)context;
2012
2013 switch (decl->getKind()) {
2014 case Decl::Function:
2015 visit_fn_decl(c, static_cast<const FunctionDecl*>(decl));
2016 break;
2017 case Decl::Typedef:
2018 resolve_typedef_decl(c, static_cast<const TypedefNameDecl *>(decl));
2019 break;
2020 case Decl::Enum:
2021 resolve_enum_decl(c, static_cast<const EnumDecl *>(decl));
2022 break;
2023 case Decl::Record:
2024 resolve_record_decl(c, static_cast<const RecordDecl *>(decl));
2025 break;
2026 case Decl::Var:
2027 visit_var_decl(c, static_cast<const VarDecl *>(decl));
2028 break;
2029 default:
2030 emit_warning(c, decl->getLocation(), "ignoring %s decl", decl->getDeclKindName());
2031 }
2032
2033 return true;
2034}
2035
2036static bool name_exists(Context *c, Buf *name) {
2037 return get_global(c, name) != nullptr;
2038}
2039
2040static void render_aliases(Context *c) {
2041 for (size_t i = 0; i < c->aliases.length; i += 1) {
2042 Alias *alias = &c->aliases.at(i);
2043 if (name_exists(c, alias->new_name))
2044 continue;
2045
2046 add_global_var(c, alias->new_name, trans_create_node_symbol(c, alias->canon_name));
2047 }
2048}
2049
2050static void render_macros(Context *c) {
2051 auto it = c->macro_table.entry_iterator();
2052 for (;;) {
2053 auto *entry = it.next();
2054 if (!entry)
2055 break;
2056
2057 AstNode *value_node = entry->value;
2058 if (value_node->type == NodeTypeFnDef) {
2059 c->root->data.root.top_level_decls.append(value_node);
2060 } else {
2061 add_global_var(c, entry->key, value_node);
2062 }
2063 }
2064}
2065
2066static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *char_ptr) {
2067 tokenize_c_macro(ctok, (const uint8_t *)char_ptr);
2068
2069 if (ctok->error) {
2070 return;
2071 }
2072
2073 bool negate = false;
2074 for (size_t i = 0; i < ctok->tokens.length; i += 1) {
2075 bool is_first = (i == 0);
2076 bool is_last = (i == ctok->tokens.length - 1);
2077 CTok *tok = &ctok->tokens.at(i);
2078 switch (tok->id) {
2079 case CTokIdCharLit:
2080 if (is_last && is_first) {
2081 AstNode *node = trans_create_node_unsigned(c, tok->data.char_lit);
2082 c->macro_table.put(name, node);
2083 }
2084 return;
2085 case CTokIdStrLit:
2086 if (is_last && is_first) {
2087 AstNode *node = trans_create_node_str_lit_c(c, buf_create_from_buf(&tok->data.str_lit));
2088 c->macro_table.put(name, node);
2089 }
2090 return;
2091 case CTokIdNumLitInt:
2092 if (is_last) {
2093 AstNode *node;
2094 switch (tok->data.num_lit_int.suffix) {
2095 case CNumLitSuffixNone:
2096 node = trans_create_node_unsigned_negative(c, tok->data.num_lit_int.x, negate);
2097 break;
2098 case CNumLitSuffixL:
2099 node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate,
2100 "c_long");
2101 break;
2102 case CNumLitSuffixU:
2103 node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate,
2104 "c_uint");
2105 break;
2106 case CNumLitSuffixLU:
2107 node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate,
2108 "c_ulong");
2109 break;
2110 case CNumLitSuffixLL:
2111 node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate,
2112 "c_longlong");
2113 break;
2114 case CNumLitSuffixLLU:
2115 node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate,
2116 "c_ulonglong");
2117 break;
2118 }
2119 c->macro_table.put(name, node);
2120 }
2121 return;
2122 case CTokIdNumLitFloat:
2123 if (is_last) {
2124 double value = negate ? -tok->data.num_lit_float : tok->data.num_lit_float;
2125 AstNode *node = trans_create_node_float_lit(c, value);
2126 c->macro_table.put(name, node);
2127 }
2128 return;
2129 case CTokIdSymbol:
2130 if (is_last && is_first) {
2131 // if it equals itself, ignore. for example, from stdio.h:
2132 // #define stdin stdin
2133 Buf *symbol_name = buf_create_from_buf(&tok->data.symbol);
2134 if (buf_eql_buf(name, symbol_name)) {
2135 return;
2136 }
2137 c->macro_symbols.append({name, symbol_name});
2138 return;
2139 }
2140 case CTokIdMinus:
2141 if (is_first) {
2142 negate = true;
2143 break;
2144 } else {
2145 return;
2146 }
2147 }
2148 }
2149}
2150
2151static void process_symbol_macros(Context *c) {
2152 for (size_t i = 0; i < c->macro_symbols.length; i += 1) {
2153 MacroSymbol ms = c->macro_symbols.at(i);
2154
2155 // Check if this macro aliases another top level declaration
2156 AstNode *existing_node = get_global(c, ms.value);
2157 if (!existing_node || name_exists(c, ms.name))
2158 continue;
2159
2160 // If a macro aliases a global variable which is a function pointer, we conclude that
2161 // the macro is intended to represent a function that assumes the function pointer
2162 // variable is non-null and calls it.
2163 if (existing_node->type == NodeTypeVariableDeclaration) {
2164 AstNode *var_type = existing_node->data.variable_declaration.type;
2165 if (var_type != nullptr && var_type->type == NodeTypePrefixOpExpr &&
2166 var_type->data.prefix_op_expr.prefix_op == PrefixOpMaybe)
2167 {
2168 AstNode *fn_proto_node = var_type->data.prefix_op_expr.primary_expr;
2169 if (fn_proto_node->type == NodeTypeFnProto) {
2170 AstNode *inline_fn_node = trans_create_node_inline_fn(c, ms.name, ms.value, fn_proto_node);
2171 c->macro_table.put(ms.name, inline_fn_node);
2172 continue;
2173 }
2174 }
2175 }
2176
2177 add_global_var(c, ms.name, trans_create_node_symbol(c, ms.value));
2178 }
2179}
2180
2181static void process_preprocessor_entities(Context *c, ASTUnit &unit) {
2182 CTokenize ctok = {{0}};
2183
2184 // TODO if we see #undef, delete it from the table
2185
2186 for (PreprocessedEntity *entity : unit.getLocalPreprocessingEntities()) {
2187 switch (entity->getKind()) {
2188 case PreprocessedEntity::InvalidKind:
2189 case PreprocessedEntity::InclusionDirectiveKind:
2190 case PreprocessedEntity::MacroExpansionKind:
2191 continue;
2192 case PreprocessedEntity::MacroDefinitionKind:
2193 {
2194 MacroDefinitionRecord *macro = static_cast<MacroDefinitionRecord *>(entity);
2195 const char *raw_name = macro->getName()->getNameStart();
2196 SourceRange range = macro->getSourceRange();
2197 SourceLocation begin_loc = range.getBegin();
2198 SourceLocation end_loc = range.getEnd();
2199
2200 if (begin_loc == end_loc) {
2201 // this means it is a macro without a value
2202 // we don't care about such things
2203 continue;
2204 }
2205 Buf *name = buf_create_from_str(raw_name);
2206 if (name_exists(c, name)) {
2207 continue;
2208 }
2209
2210 const char *end_c = c->source_manager->getCharacterData(end_loc);
2211 process_macro(c, &ctok, name, end_c);
2212 }
2213 }
2214 }
2215}
2216
2217int parse_h_buf(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, Buf *source,
2218 CodeGen *codegen, AstNode *source_node)
2219{
2220 int err;
2221 Buf tmp_file_path = BUF_INIT;
2222 if ((err = os_buf_to_tmp_file(source, buf_create_from_str(".h"), &tmp_file_path))) {
2223 return err;
2224 }
2225
2226 err = parse_h_file(import, errors, buf_ptr(&tmp_file_path), codegen, source_node);
2227
2228 os_delete_file(&tmp_file_path);
2229
2230 return err;
2231}
2232
2233int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const char *target_file,
2234 CodeGen *codegen, AstNode *source_node)
2235{
2236 Context context = {0};
2237 Context *c = &context;
2238 c->warnings_on = codegen->verbose;
2239 c->import = import;
2240 c->errors = errors;
2241 c->visib_mod = VisibModPub;
2242 c->decl_table.init(8);
2243 c->macro_table.init(8);
2244 c->codegen = codegen;
2245 c->source_node = source_node;
2246
2247 ZigList<const char *> clang_argv = {0};
2248
2249 clang_argv.append("-x");
2250 clang_argv.append("c");
2251
2252 if (c->codegen->is_native_target) {
2253 char *ZIG_PARSEC_CFLAGS = getenv("ZIG_NATIVE_PARSEC_CFLAGS");
2254 if (ZIG_PARSEC_CFLAGS) {
2255 Buf tmp_buf = BUF_INIT;
2256 char *start = ZIG_PARSEC_CFLAGS;
2257 char *space = strstr(start, " ");
2258 while (space) {
2259 if (space - start > 0) {
2260 buf_init_from_mem(&tmp_buf, start, space - start);
2261 clang_argv.append(buf_ptr(buf_create_from_buf(&tmp_buf)));
2262 }
2263 start = space + 1;
2264 space = strstr(start, " ");
2265 }
2266 buf_init_from_str(&tmp_buf, start);
2267 clang_argv.append(buf_ptr(buf_create_from_buf(&tmp_buf)));
2268 }
2269 }
2270
2271 clang_argv.append("-isystem");
2272 clang_argv.append(ZIG_HEADERS_DIR);
2273
2274 clang_argv.append("-isystem");
2275 clang_argv.append(buf_ptr(codegen->libc_include_dir));
2276
2277 for (size_t i = 0; i < codegen->clang_argv_len; i += 1) {
2278 clang_argv.append(codegen->clang_argv[i]);
2279 }
2280
2281 // we don't need spell checking and it slows things down
2282 clang_argv.append("-fno-spell-checking");
2283
2284 // this gives us access to preprocessing entities, presumably at
2285 // the cost of performance
2286 clang_argv.append("-Xclang");
2287 clang_argv.append("-detailed-preprocessing-record");
2288
2289 if (!c->codegen->is_native_target) {
2290 clang_argv.append("-target");
2291 clang_argv.append(buf_ptr(&c->codegen->triple_str));
2292 }
2293
2294 clang_argv.append(target_file);
2295
2296 // to make the [start...end] argument work
2297 clang_argv.append(nullptr);
2298
2299 IntrusiveRefCntPtr<DiagnosticsEngine> diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
2300
2301 std::shared_ptr<PCHContainerOperations> pch_container_ops = std::make_shared<PCHContainerOperations>();
2302
2303 bool skip_function_bodies = false;
2304 bool only_local_decls = true;
2305 bool capture_diagnostics = true;
2306 bool user_files_are_volatile = true;
2307 bool allow_pch_with_compiler_errors = false;
2308 bool single_file_parse = false;
2309 bool for_serialization = false;
2310 const char *resources_path = ZIG_HEADERS_DIR;
2311 std::unique_ptr<ASTUnit> err_unit;
2312 std::unique_ptr<ASTUnit> ast_unit(ASTUnit::LoadFromCommandLine(
2313 &clang_argv.at(0), &clang_argv.last(),
2314 pch_container_ops, diags, resources_path,
2315 only_local_decls, capture_diagnostics, None, true, 0, TU_Complete,
2316 false, false, allow_pch_with_compiler_errors, skip_function_bodies,
2317 single_file_parse, user_files_are_volatile, for_serialization, None, &err_unit,
2318 nullptr));
2319
2320 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
2321 if (!ast_unit && !err_unit) {
2322 return ErrorFileSystem;
2323 }
2324
2325 if (diags->getClient()->getNumErrors() > 0) {
2326 if (ast_unit) {
2327 err_unit = std::move(ast_unit);
2328 }
2329
2330 for (ASTUnit::stored_diag_iterator it = err_unit->stored_diag_begin(),
2331 it_end = err_unit->stored_diag_end();
2332 it != it_end; ++it)
2333 {
2334 switch (it->getLevel()) {
2335 case DiagnosticsEngine::Ignored:
2336 case DiagnosticsEngine::Note:
2337 case DiagnosticsEngine::Remark:
2338 case DiagnosticsEngine::Warning:
2339 continue;
2340 case DiagnosticsEngine::Error:
2341 case DiagnosticsEngine::Fatal:
2342 break;
2343 }
2344 StringRef msg_str_ref = it->getMessage();
2345 Buf *msg = buf_create_from_str((const char *)msg_str_ref.bytes_begin());
2346 FullSourceLoc fsl = it->getLocation();
2347 if (fsl.hasManager()) {
2348 FileID file_id = fsl.getFileID();
2349 StringRef filename = fsl.getManager().getFilename(fsl);
2350 unsigned line = fsl.getSpellingLineNumber() - 1;
2351 unsigned column = fsl.getSpellingColumnNumber() - 1;
2352 unsigned offset = fsl.getManager().getFileOffset(fsl);
2353 const char *source = (const char *)fsl.getManager().getBufferData(file_id).bytes_begin();
2354 Buf *path;
2355 if (filename.empty()) {
2356 path = buf_alloc();
2357 } else {
2358 path = buf_create_from_mem((const char *)filename.bytes_begin(), filename.size());
2359 }
2360
2361 ErrorMsg *err_msg = err_msg_create_with_offset(path, line, column, offset, source, msg);
2362
2363 c->errors->append(err_msg);
2364 } else {
2365 // NOTE the only known way this gets triggered right now is if you have a lot of errors
2366 // clang emits "too many errors emitted, stopping now"
2367 fprintf(stderr, "unexpected error from clang: %s\n", buf_ptr(msg));
2368 }
2369 }
2370
2371 return 0;
2372 }
2373
2374 c->ctx = &ast_unit->getASTContext();
2375 c->source_manager = &ast_unit->getSourceManager();
2376 c->root = trans_create_node(c, NodeTypeRoot);
2377
2378 ast_unit->visitLocalTopLevelDecls(c, decl_visitor);
2379
2380 process_preprocessor_entities(c, *ast_unit);
2381
2382 process_symbol_macros(c);
2383 render_macros(c);
2384 render_aliases(c);
2385
2386 import->root = c->root;
2387
2388 return 0;
2389}
src/parsec.hpp created+20
...@@ -0,0 +1,20 @@
1/*
2 * Copyright (c) 2015 Andrew Kelley
3 *
4 * This file is part of zig, which is MIT licensed.
5 * See http://opensource.org/licenses/MIT
6 */
7
8
9#ifndef ZIG_PARSEC_HPP
10#define ZIG_PARSEC_HPP
11
12#include "all_types.hpp"
13
14int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const char *target_file,
15 CodeGen *codegen, AstNode *source_node);
16
17int parse_h_buf(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, Buf *source,
18 CodeGen *codegen, AstNode *source_node);
19
20#endif
src/parseh.cpp deleted-2389
...@@ -1,2389 +0,0 @@
1/*
2 * Copyright (c) 2015 Andrew Kelley
3 *
4 * This file is part of zig, which is MIT licensed.
5 * See http://opensource.org/licenses/MIT
6 */
7
8#include "all_types.hpp"
9#include "analyze.hpp"
10#include "c_tokenizer.hpp"
11#include "config.h"
12#include "error.hpp"
13#include "ir.hpp"
14#include "os.hpp"
15#include "parseh.hpp"
16#include "parser.hpp"
17
18
19#include <clang/Frontend/ASTUnit.h>
20#include <clang/Frontend/CompilerInstance.h>
21#include <clang/AST/Expr.h>
22
23#include <string.h>
24
25using namespace clang;
26
27struct MacroSymbol {
28 Buf *name;
29 Buf *value;
30};
31
32struct Alias {
33 Buf *new_name;
34 Buf *canon_name;
35};
36
37struct Context {
38 ImportTableEntry *import;
39 ZigList<ErrorMsg *> *errors;
40 bool warnings_on;
41 VisibMod visib_mod;
42 AstNode *root;
43 HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table;
44 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table;
45 SourceManager *source_manager;
46 ZigList<Alias> aliases;
47 ZigList<MacroSymbol> macro_symbols;
48 AstNode *source_node;
49
50 CodeGen *codegen;
51 ASTContext *ctx;
52};
53
54static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl);
55static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl);
56static AstNode *resolve_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl);
57static AstNode *trans_qual_type_with_table(Context *c, QualType qt, const SourceLocation &source_loc);
58static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc);
59
60
61__attribute__ ((format (printf, 3, 4)))
62static void emit_warning(Context *c, const SourceLocation &sl, const char *format, ...) {
63 if (!c->warnings_on) {
64 return;
65 }
66
67 va_list ap;
68 va_start(ap, format);
69 Buf *msg = buf_vprintf(format, ap);
70 va_end(ap);
71
72 StringRef filename = c->source_manager->getFilename(sl);
73 const char *filename_bytes = (const char *)filename.bytes_begin();
74 Buf *path;
75 if (filename_bytes) {
76 path = buf_create_from_str(filename_bytes);
77 } else {
78 path = buf_sprintf("(no file)");
79 }
80 unsigned line = c->source_manager->getSpellingLineNumber(sl);
81 unsigned column = c->source_manager->getSpellingColumnNumber(sl);
82 fprintf(stderr, "%s:%u:%u: warning: %s\n", buf_ptr(path), line, column, buf_ptr(msg));
83}
84
85static void add_global_weak_alias(Context *c, Buf *new_name, Buf *canon_name) {
86 Alias *alias = c->aliases.add_one();
87 alias->new_name = new_name;
88 alias->canon_name = canon_name;
89}
90
91static AstNode * trans_create_node(Context *c, NodeType id) {
92 AstNode *node = allocate<AstNode>(1);
93 node->type = id;
94 node->owner = c->import;
95 // TODO line/column. mapping to C file??
96 return node;
97}
98
99static AstNode *trans_create_node_float_lit(Context *c, double value) {
100 AstNode *node = trans_create_node(c, NodeTypeFloatLiteral);
101 node->data.float_literal.bigfloat = allocate<BigFloat>(1);
102 bigfloat_init_64(node->data.float_literal.bigfloat, value);
103 return node;
104}
105
106static AstNode *trans_create_node_symbol(Context *c, Buf *name) {
107 AstNode *node = trans_create_node(c, NodeTypeSymbol);
108 node->data.symbol_expr.symbol = name;
109 return node;
110}
111
112static AstNode *trans_create_node_symbol_str(Context *c, const char *name) {
113 return trans_create_node_symbol(c, buf_create_from_str(name));
114}
115
116static AstNode *trans_create_node_builtin_fn_call(Context *c, Buf *name) {
117 AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
118 node->data.fn_call_expr.fn_ref_expr = trans_create_node_symbol(c, name);
119 node->data.fn_call_expr.is_builtin = true;
120 return node;
121}
122
123static AstNode *trans_create_node_builtin_fn_call_str(Context *c, const char *name) {
124 return trans_create_node_builtin_fn_call(c, buf_create_from_str(name));
125}
126
127static AstNode *trans_create_node_opaque(Context *c) {
128 return trans_create_node_builtin_fn_call_str(c, "OpaqueType");
129}
130
131static AstNode *trans_create_node_field_access(Context *c, AstNode *container, Buf *field_name) {
132 AstNode *node = trans_create_node(c, NodeTypeFieldAccessExpr);
133 node->data.field_access_expr.struct_expr = container;
134 node->data.field_access_expr.field_name = field_name;
135 return node;
136}
137
138static AstNode *trans_create_node_prefix_op(Context *c, PrefixOp op, AstNode *child_node) {
139 AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);
140 node->data.prefix_op_expr.prefix_op = op;
141 node->data.prefix_op_expr.primary_expr = child_node;
142 return node;
143}
144
145static AstNode *trans_create_node_addr_of(Context *c, bool is_const, bool is_volatile, AstNode *child_node) {
146 AstNode *node = trans_create_node(c, NodeTypeAddrOfExpr);
147 node->data.addr_of_expr.is_const = is_const;
148 node->data.addr_of_expr.is_volatile = is_volatile;
149 node->data.addr_of_expr.op_expr = child_node;
150 return node;
151}
152
153static AstNode *trans_create_node_str_lit_c(Context *c, Buf *buf) {
154 AstNode *node = trans_create_node(c, NodeTypeStringLiteral);
155 node->data.string_literal.buf = buf;
156 node->data.string_literal.c = true;
157 return node;
158}
159
160static AstNode *trans_create_node_unsigned_negative(Context *c, uint64_t x, bool is_negative) {
161 AstNode *node = trans_create_node(c, NodeTypeIntLiteral);
162 node->data.int_literal.bigint = allocate<BigInt>(1);
163 bigint_init_data(node->data.int_literal.bigint, &x, 1, is_negative);
164 return node;
165}
166
167static AstNode *trans_create_node_unsigned(Context *c, uint64_t x) {
168 return trans_create_node_unsigned_negative(c, x, false);
169}
170
171static AstNode *trans_create_node_cast(Context *c, AstNode *dest, AstNode *src) {
172 AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
173 node->data.fn_call_expr.fn_ref_expr = dest;
174 node->data.fn_call_expr.params.resize(1);
175 node->data.fn_call_expr.params.items[0] = src;
176 return node;
177}
178
179static AstNode *trans_create_node_unsigned_negative_type(Context *c, uint64_t x, bool is_negative,
180 const char *type_name)
181{
182 AstNode *lit_node = trans_create_node_unsigned_negative(c, x, is_negative);
183 return trans_create_node_cast(c, trans_create_node_symbol_str(c, type_name), lit_node);
184}
185
186static AstNode *trans_create_node_array_type(Context *c, AstNode *size_node, AstNode *child_type_node) {
187 AstNode *node = trans_create_node(c, NodeTypeArrayType);
188 node->data.array_type.size = size_node;
189 node->data.array_type.child_type = child_type_node;
190 return node;
191}
192
193static AstNode *trans_create_node_var_decl(Context *c, bool is_const, Buf *var_name, AstNode *type_node,
194 AstNode *init_node)
195{
196 AstNode *node = trans_create_node(c, NodeTypeVariableDeclaration);
197 node->data.variable_declaration.visib_mod = c->visib_mod;
198 node->data.variable_declaration.symbol = var_name;
199 node->data.variable_declaration.is_const = is_const;
200 node->data.variable_declaration.type = type_node;
201 node->data.variable_declaration.expr = init_node;
202 return node;
203}
204
205
206static AstNode *trans_create_node_inline_fn(Context *c, Buf *fn_name, Buf *var_name, AstNode *src_proto_node) {
207 AstNode *fn_def = trans_create_node(c, NodeTypeFnDef);
208 AstNode *fn_proto = trans_create_node(c, NodeTypeFnProto);
209 fn_proto->data.fn_proto.visib_mod = c->visib_mod;
210 fn_proto->data.fn_proto.name = fn_name;
211 fn_proto->data.fn_proto.is_inline = true;
212 fn_proto->data.fn_proto.return_type = src_proto_node->data.fn_proto.return_type; // TODO ok for these to alias?
213
214 fn_def->data.fn_def.fn_proto = fn_proto;
215 fn_proto->data.fn_proto.fn_def_node = fn_def;
216
217 AstNode *unwrap_node = trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, trans_create_node_symbol(c, var_name));
218 AstNode *fn_call_node = trans_create_node(c, NodeTypeFnCallExpr);
219 fn_call_node->data.fn_call_expr.fn_ref_expr = unwrap_node;
220
221 for (size_t i = 0; i < src_proto_node->data.fn_proto.params.length; i += 1) {
222 AstNode *src_param_node = src_proto_node->data.fn_proto.params.at(i);
223 Buf *param_name = src_param_node->data.param_decl.name;
224 if (!param_name) param_name = buf_sprintf("arg%" ZIG_PRI_usize "", i);
225
226 AstNode *dest_param_node = trans_create_node(c, NodeTypeParamDecl);
227 dest_param_node->data.param_decl.name = param_name;
228 dest_param_node->data.param_decl.type = src_param_node->data.param_decl.type;
229 dest_param_node->data.param_decl.is_noalias = src_param_node->data.param_decl.is_noalias;
230 fn_proto->data.fn_proto.params.append(dest_param_node);
231
232 fn_call_node->data.fn_call_expr.params.append(trans_create_node_symbol(c, param_name));
233
234 }
235
236 AstNode *block = trans_create_node(c, NodeTypeBlock);
237 block->data.block.statements.resize(1);
238 block->data.block.statements.items[0] = fn_call_node;
239 block->data.block.last_statement_is_result_expression = true;
240
241 fn_def->data.fn_def.body = block;
242 return fn_def;
243}
244
245static AstNode *get_global(Context *c, Buf *name) {
246 for (size_t i = 0; i < c->root->data.root.top_level_decls.length; i += 1) {
247 AstNode *decl_node = c->root->data.root.top_level_decls.items[i];
248 if (decl_node->type == NodeTypeVariableDeclaration) {
249 if (buf_eql_buf(decl_node->data.variable_declaration.symbol, name)) {
250 return decl_node;
251 }
252 } else if (decl_node->type == NodeTypeFnDef) {
253 if (buf_eql_buf(decl_node->data.fn_def.fn_proto->data.fn_proto.name, name)) {
254 return decl_node;
255 }
256 } else if (decl_node->type == NodeTypeFnProto) {
257 if (buf_eql_buf(decl_node->data.fn_proto.name, name)) {
258 return decl_node;
259 }
260 }
261 }
262 {
263 auto entry = c->macro_table.maybe_get(name);
264 if (entry)
265 return entry->value;
266 }
267 return nullptr;
268}
269
270static AstNode *add_global_var(Context *c, Buf *var_name, AstNode *value_node) {
271 bool is_const = true;
272 AstNode *type_node = nullptr;
273 AstNode *node = trans_create_node_var_decl(c, is_const, var_name, type_node, value_node);
274 c->root->data.root.top_level_decls.append(node);
275 return node;
276}
277
278static const char *decl_name(const Decl *decl) {
279 const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl);
280 return (const char *)named_decl->getName().bytes_begin();
281}
282
283static AstNode *trans_create_node_apint(Context *c, const llvm::APSInt &aps_int) {
284 AstNode *node = trans_create_node(c, NodeTypeIntLiteral);
285 node->data.int_literal.bigint = allocate<BigInt>(1);
286 bigint_init_data(node->data.int_literal.bigint, aps_int.getRawData(), aps_int.getNumWords(), aps_int.isNegative());
287 return node;
288
289}
290
291static bool is_c_void_type(AstNode *node) {
292 return (node->type == NodeTypeSymbol && buf_eql_str(node->data.symbol_expr.symbol, "c_void"));
293}
294
295static bool qual_type_child_is_fn_proto(const QualType &qt) {
296 if (qt.getTypePtr()->getTypeClass() == Type::Paren) {
297 const ParenType *paren_type = static_cast<const ParenType *>(qt.getTypePtr());
298 if (paren_type->getInnerType()->getTypeClass() == Type::FunctionProto) {
299 return true;
300 }
301 } else if (qt.getTypePtr()->getTypeClass() == Type::Attributed) {
302 const AttributedType *attr_type = static_cast<const AttributedType *>(qt.getTypePtr());
303 return qual_type_child_is_fn_proto(attr_type->getEquivalentType());
304 }
305 return false;
306}
307
308static bool c_is_signed_integer(Context *c, QualType qt) {
309 const Type *c_type = qt.getTypePtr();
310 if (c_type->getTypeClass() != Type::Builtin)
311 return false;
312 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(c_type);
313 switch (builtin_ty->getKind()) {
314 case BuiltinType::SChar:
315 case BuiltinType::Short:
316 case BuiltinType::Int:
317 case BuiltinType::Long:
318 case BuiltinType::LongLong:
319 case BuiltinType::Int128:
320 case BuiltinType::WChar_S:
321 return true;
322 default:
323 return false;
324 }
325}
326
327static bool c_is_unsigned_integer(Context *c, QualType qt) {
328 const Type *c_type = qt.getTypePtr();
329 if (c_type->getTypeClass() != Type::Builtin)
330 return false;
331 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(c_type);
332 switch (builtin_ty->getKind()) {
333 case BuiltinType::Char_U:
334 case BuiltinType::UChar:
335 case BuiltinType::Char_S:
336 case BuiltinType::UShort:
337 case BuiltinType::UInt:
338 case BuiltinType::ULong:
339 case BuiltinType::ULongLong:
340 case BuiltinType::UInt128:
341 case BuiltinType::WChar_U:
342 return true;
343 default:
344 return false;
345 }
346}
347
348static bool c_is_float(Context *c, QualType qt) {
349 const Type *c_type = qt.getTypePtr();
350 if (c_type->getTypeClass() != Type::Builtin)
351 return false;
352 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(c_type);
353 switch (builtin_ty->getKind()) {
354 case BuiltinType::Half:
355 case BuiltinType::Float:
356 case BuiltinType::Double:
357 case BuiltinType::Float128:
358 case BuiltinType::LongDouble:
359 return true;
360 default:
361 return false;
362 }
363}
364
365static AstNode * trans_stmt(Context *c, AstNode *block, Stmt *stmt);
366static AstNode * trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc);
367
368static AstNode * trans_expr(Context *c, AstNode *block, Expr *expr) {
369 return trans_stmt(c, block, expr);
370}
371
372static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLocation &source_loc) {
373 switch (ty->getTypeClass()) {
374 case Type::Builtin:
375 {
376 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty);
377 switch (builtin_ty->getKind()) {
378 case BuiltinType::Void:
379 return trans_create_node_symbol_str(c, "c_void");
380 case BuiltinType::Bool:
381 return trans_create_node_symbol_str(c, "bool");
382 case BuiltinType::Char_U:
383 case BuiltinType::UChar:
384 case BuiltinType::Char_S:
385 return trans_create_node_symbol_str(c, "u8");
386 case BuiltinType::SChar:
387 return trans_create_node_symbol_str(c, "i8");
388 case BuiltinType::UShort:
389 return trans_create_node_symbol_str(c, "c_ushort");
390 case BuiltinType::UInt:
391 return trans_create_node_symbol_str(c, "c_uint");
392 case BuiltinType::ULong:
393 return trans_create_node_symbol_str(c, "c_ulong");
394 case BuiltinType::ULongLong:
395 return trans_create_node_symbol_str(c, "c_ulonglong");
396 case BuiltinType::Short:
397 return trans_create_node_symbol_str(c, "c_short");
398 case BuiltinType::Int:
399 return trans_create_node_symbol_str(c, "c_int");
400 case BuiltinType::Long:
401 return trans_create_node_symbol_str(c, "c_long");
402 case BuiltinType::LongLong:
403 return trans_create_node_symbol_str(c, "c_longlong");
404 case BuiltinType::UInt128:
405 return trans_create_node_symbol_str(c, "u128");
406 case BuiltinType::Int128:
407 return trans_create_node_symbol_str(c, "i128");
408 case BuiltinType::Float:
409 return trans_create_node_symbol_str(c, "f32");
410 case BuiltinType::Double:
411 return trans_create_node_symbol_str(c, "f64");
412 case BuiltinType::Float128:
413 return trans_create_node_symbol_str(c, "f128");
414 case BuiltinType::LongDouble:
415 return trans_create_node_symbol_str(c, "c_longdouble");
416 case BuiltinType::WChar_U:
417 case BuiltinType::Char16:
418 case BuiltinType::Char32:
419 case BuiltinType::WChar_S:
420 case BuiltinType::Half:
421 case BuiltinType::NullPtr:
422 case BuiltinType::ObjCId:
423 case BuiltinType::ObjCClass:
424 case BuiltinType::ObjCSel:
425 case BuiltinType::OMPArraySection:
426 case BuiltinType::Dependent:
427 case BuiltinType::Overload:
428 case BuiltinType::BoundMember:
429 case BuiltinType::PseudoObject:
430 case BuiltinType::UnknownAny:
431 case BuiltinType::BuiltinFn:
432 case BuiltinType::ARCUnbridgedCast:
433
434 case BuiltinType::OCLImage1dRO:
435 case BuiltinType::OCLImage1dArrayRO:
436 case BuiltinType::OCLImage1dBufferRO:
437 case BuiltinType::OCLImage2dRO:
438 case BuiltinType::OCLImage2dArrayRO:
439 case BuiltinType::OCLImage2dDepthRO:
440 case BuiltinType::OCLImage2dArrayDepthRO:
441 case BuiltinType::OCLImage2dMSAARO:
442 case BuiltinType::OCLImage2dArrayMSAARO:
443 case BuiltinType::OCLImage2dMSAADepthRO:
444 case BuiltinType::OCLImage2dArrayMSAADepthRO:
445 case BuiltinType::OCLImage3dRO:
446 case BuiltinType::OCLImage1dWO:
447 case BuiltinType::OCLImage1dArrayWO:
448 case BuiltinType::OCLImage1dBufferWO:
449 case BuiltinType::OCLImage2dWO:
450 case BuiltinType::OCLImage2dArrayWO:
451 case BuiltinType::OCLImage2dDepthWO:
452 case BuiltinType::OCLImage2dArrayDepthWO:
453 case BuiltinType::OCLImage2dMSAAWO:
454 case BuiltinType::OCLImage2dArrayMSAAWO:
455 case BuiltinType::OCLImage2dMSAADepthWO:
456 case BuiltinType::OCLImage2dArrayMSAADepthWO:
457 case BuiltinType::OCLImage3dWO:
458 case BuiltinType::OCLImage1dRW:
459 case BuiltinType::OCLImage1dArrayRW:
460 case BuiltinType::OCLImage1dBufferRW:
461 case BuiltinType::OCLImage2dRW:
462 case BuiltinType::OCLImage2dArrayRW:
463 case BuiltinType::OCLImage2dDepthRW:
464 case BuiltinType::OCLImage2dArrayDepthRW:
465 case BuiltinType::OCLImage2dMSAARW:
466 case BuiltinType::OCLImage2dArrayMSAARW:
467 case BuiltinType::OCLImage2dMSAADepthRW:
468 case BuiltinType::OCLImage2dArrayMSAADepthRW:
469 case BuiltinType::OCLImage3dRW:
470 case BuiltinType::OCLSampler:
471 case BuiltinType::OCLEvent:
472 case BuiltinType::OCLClkEvent:
473 case BuiltinType::OCLQueue:
474 case BuiltinType::OCLReserveID:
475 emit_warning(c, source_loc, "unsupported builtin type");
476 return nullptr;
477 }
478 break;
479 }
480 case Type::Pointer:
481 {
482 const PointerType *pointer_ty = static_cast<const PointerType*>(ty);
483 QualType child_qt = pointer_ty->getPointeeType();
484 AstNode *child_node = trans_qual_type(c, child_qt, source_loc);
485 if (child_node == nullptr) {
486 emit_warning(c, source_loc, "pointer to unsupported type");
487 return nullptr;
488 }
489
490 if (qual_type_child_is_fn_proto(child_qt)) {
491 return trans_create_node_prefix_op(c, PrefixOpMaybe, child_node);
492 }
493
494 AstNode *pointer_node = trans_create_node_addr_of(c, child_qt.isConstQualified(),
495 child_qt.isVolatileQualified(), child_node);
496 return trans_create_node_prefix_op(c, PrefixOpMaybe, pointer_node);
497 }
498 case Type::Typedef:
499 {
500 const TypedefType *typedef_ty = static_cast<const TypedefType*>(ty);
501 const TypedefNameDecl *typedef_decl = typedef_ty->getDecl();
502 return resolve_typedef_decl(c, typedef_decl);
503 }
504 case Type::Elaborated:
505 {
506 const ElaboratedType *elaborated_ty = static_cast<const ElaboratedType*>(ty);
507 switch (elaborated_ty->getKeyword()) {
508 case ETK_Struct:
509 return trans_qual_type_with_table(c, elaborated_ty->getNamedType(), source_loc);
510 case ETK_Enum:
511 return trans_qual_type_with_table(c, elaborated_ty->getNamedType(), source_loc);
512 case ETK_Interface:
513 case ETK_Union:
514 case ETK_Class:
515 case ETK_Typename:
516 case ETK_None:
517 emit_warning(c, source_loc, "unsupported elaborated type");
518 return nullptr;
519 }
520 }
521 case Type::FunctionProto:
522 {
523 const FunctionProtoType *fn_proto_ty = static_cast<const FunctionProtoType*>(ty);
524
525 AstNode *proto_node = trans_create_node(c, NodeTypeFnProto);
526 switch (fn_proto_ty->getCallConv()) {
527 case CC_C: // __attribute__((cdecl))
528 proto_node->data.fn_proto.cc = CallingConventionC;
529 proto_node->data.fn_proto.is_extern = true;
530 break;
531 case CC_X86StdCall: // __attribute__((stdcall))
532 proto_node->data.fn_proto.cc = CallingConventionStdcall;
533 break;
534 case CC_X86FastCall: // __attribute__((fastcall))
535 emit_warning(c, source_loc, "unsupported calling convention: x86 fastcall");
536 return nullptr;
537 case CC_X86ThisCall: // __attribute__((thiscall))
538 emit_warning(c, source_loc, "unsupported calling convention: x86 thiscall");
539 return nullptr;
540 case CC_X86VectorCall: // __attribute__((vectorcall))
541 emit_warning(c, source_loc, "unsupported calling convention: x86 vectorcall");
542 return nullptr;
543 case CC_X86Pascal: // __attribute__((pascal))
544 emit_warning(c, source_loc, "unsupported calling convention: x86 pascal");
545 return nullptr;
546 case CC_Win64: // __attribute__((ms_abi))
547 emit_warning(c, source_loc, "unsupported calling convention: win64");
548 return nullptr;
549 case CC_X86_64SysV: // __attribute__((sysv_abi))
550 emit_warning(c, source_loc, "unsupported calling convention: x86 64sysv");
551 return nullptr;
552 case CC_X86RegCall:
553 emit_warning(c, source_loc, "unsupported calling convention: x86 reg");
554 return nullptr;
555 case CC_AAPCS: // __attribute__((pcs("aapcs")))
556 emit_warning(c, source_loc, "unsupported calling convention: aapcs");
557 return nullptr;
558 case CC_AAPCS_VFP: // __attribute__((pcs("aapcs-vfp")))
559 emit_warning(c, source_loc, "unsupported calling convention: aapcs-vfp");
560 return nullptr;
561 case CC_IntelOclBicc: // __attribute__((intel_ocl_bicc))
562 emit_warning(c, source_loc, "unsupported calling convention: intel_ocl_bicc");
563 return nullptr;
564 case CC_SpirFunction: // default for OpenCL functions on SPIR target
565 emit_warning(c, source_loc, "unsupported calling convention: SPIR function");
566 return nullptr;
567 case CC_OpenCLKernel:
568 emit_warning(c, source_loc, "unsupported calling convention: OpenCLKernel");
569 return nullptr;
570 case CC_Swift:
571 emit_warning(c, source_loc, "unsupported calling convention: Swift");
572 return nullptr;
573 case CC_PreserveMost:
574 emit_warning(c, source_loc, "unsupported calling convention: PreserveMost");
575 return nullptr;
576 case CC_PreserveAll:
577 emit_warning(c, source_loc, "unsupported calling convention: PreserveAll");
578 return nullptr;
579 }
580
581 proto_node->data.fn_proto.is_var_args = fn_proto_ty->isVariadic();
582 size_t param_count = fn_proto_ty->getNumParams();
583
584 if (fn_proto_ty->getNoReturnAttr()) {
585 proto_node->data.fn_proto.return_type = trans_create_node_symbol_str(c, "noreturn");
586 } else {
587 proto_node->data.fn_proto.return_type = trans_qual_type(c, fn_proto_ty->getReturnType(),
588 source_loc);
589 if (proto_node->data.fn_proto.return_type == nullptr) {
590 emit_warning(c, source_loc, "unsupported function proto return type");
591 return nullptr;
592 }
593 // convert c_void to actual void (only for return type)
594 if (is_c_void_type(proto_node->data.fn_proto.return_type)) {
595 proto_node->data.fn_proto.return_type = nullptr;
596 }
597 }
598
599 //emit_warning(c, source_loc, "TODO figure out fn prototype fn name");
600 const char *fn_name = nullptr;
601 if (fn_name != nullptr) {
602 proto_node->data.fn_proto.name = buf_create_from_str(fn_name);
603 }
604
605 for (size_t i = 0; i < param_count; i += 1) {
606 QualType qt = fn_proto_ty->getParamType(i);
607 AstNode *param_type_node = trans_qual_type(c, qt, source_loc);
608
609 if (param_type_node == nullptr) {
610 emit_warning(c, source_loc, "unresolved function proto parameter type");
611 return nullptr;
612 }
613
614 AstNode *param_node = trans_create_node(c, NodeTypeParamDecl);
615 //emit_warning(c, source_loc, "TODO figure out fn prototype param name");
616 const char *param_name = nullptr;
617 if (param_name != nullptr) {
618 param_node->data.param_decl.name = buf_create_from_str(param_name);
619 }
620 param_node->data.param_decl.is_noalias = qt.isRestrictQualified();
621 param_node->data.param_decl.type = param_type_node;
622 proto_node->data.fn_proto.params.append(param_node);
623 }
624 // TODO check for always_inline attribute
625 // TODO check for align attribute
626
627 return proto_node;
628 }
629 case Type::Record:
630 {
631 const RecordType *record_ty = static_cast<const RecordType*>(ty);
632 return resolve_record_decl(c, record_ty->getDecl());
633 }
634 case Type::Enum:
635 {
636 const EnumType *enum_ty = static_cast<const EnumType*>(ty);
637 return resolve_enum_decl(c, enum_ty->getDecl());
638 }
639 case Type::ConstantArray:
640 {
641 const ConstantArrayType *const_arr_ty = static_cast<const ConstantArrayType *>(ty);
642 AstNode *child_type_node = trans_qual_type(c, const_arr_ty->getElementType(), source_loc);
643 if (child_type_node == nullptr) {
644 emit_warning(c, source_loc, "unresolved array element type");
645 return nullptr;
646 }
647 uint64_t size = const_arr_ty->getSize().getLimitedValue();
648 AstNode *size_node = trans_create_node_unsigned(c, size);
649 return trans_create_node_array_type(c, size_node, child_type_node);
650 }
651 case Type::Paren:
652 {
653 const ParenType *paren_ty = static_cast<const ParenType *>(ty);
654 return trans_qual_type(c, paren_ty->getInnerType(), source_loc);
655 }
656 case Type::Decayed:
657 {
658 const DecayedType *decayed_ty = static_cast<const DecayedType *>(ty);
659 return trans_qual_type(c, decayed_ty->getDecayedType(), source_loc);
660 }
661 case Type::Attributed:
662 {
663 const AttributedType *attributed_ty = static_cast<const AttributedType *>(ty);
664 return trans_qual_type(c, attributed_ty->getEquivalentType(), source_loc);
665 }
666 case Type::BlockPointer:
667 case Type::LValueReference:
668 case Type::RValueReference:
669 case Type::MemberPointer:
670 case Type::IncompleteArray:
671 case Type::VariableArray:
672 case Type::DependentSizedArray:
673 case Type::DependentSizedExtVector:
674 case Type::Vector:
675 case Type::ExtVector:
676 case Type::FunctionNoProto:
677 case Type::UnresolvedUsing:
678 case Type::Adjusted:
679 case Type::TypeOfExpr:
680 case Type::TypeOf:
681 case Type::Decltype:
682 case Type::UnaryTransform:
683 case Type::TemplateTypeParm:
684 case Type::SubstTemplateTypeParm:
685 case Type::SubstTemplateTypeParmPack:
686 case Type::TemplateSpecialization:
687 case Type::Auto:
688 case Type::InjectedClassName:
689 case Type::DependentName:
690 case Type::DependentTemplateSpecialization:
691 case Type::PackExpansion:
692 case Type::ObjCObject:
693 case Type::ObjCInterface:
694 case Type::Complex:
695 case Type::ObjCObjectPointer:
696 case Type::Atomic:
697 case Type::Pipe:
698 case Type::ObjCTypeParam:
699 case Type::DeducedTemplateSpecialization:
700 emit_warning(c, source_loc, "unsupported type: '%s'", ty->getTypeClassName());
701 return nullptr;
702 }
703 zig_unreachable();
704}
705
706static AstNode * trans_qual_type_with_table(Context *c, QualType qt, const SourceLocation &source_loc) {
707 return trans_type_with_table(c, qt.getTypePtr(), source_loc);
708}
709
710static AstNode * trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc) {
711 return trans_qual_type_with_table(c, qt, source_loc);
712}
713
714static AstNode * trans_compound_stmt(Context *c, AstNode *parent, CompoundStmt *stmt) {
715 AstNode *child_block = trans_create_node(c, NodeTypeBlock);
716 for (CompoundStmt::body_iterator it = stmt->body_begin(), end_it = stmt->body_end(); it != end_it; ++it) {
717 AstNode *child_node = trans_stmt(c, child_block, *it);
718 if (child_node != nullptr)
719 child_block->data.block.statements.append(child_node);
720 }
721 return child_block;
722}
723
724static AstNode *trans_return_stmt(Context *c, AstNode *block, ReturnStmt *stmt) {
725 Expr *value_expr = stmt->getRetValue();
726 if (value_expr == nullptr) {
727 zig_panic("TODO handle C return void");
728 } else {
729 AstNode *return_node = trans_create_node(c, NodeTypeReturnExpr);
730 return_node->data.return_expr.expr = trans_expr(c, block, value_expr);
731 return return_node;
732 }
733}
734
735static AstNode *trans_integer_literal(Context *c, IntegerLiteral *stmt) {
736 llvm::APSInt result;
737 if (!stmt->EvaluateAsInt(result, *c->ctx)) {
738 zig_panic("TODO handle libclang unable to evaluate C integer literal");
739 }
740 return trans_create_node_apint(c, result);
741}
742
743static AstNode *trans_conditional_operator(Context *c, AstNode *block, ConditionalOperator *stmt) {
744 AstNode *node = trans_create_node(c, NodeTypeIfBoolExpr);
745
746 Expr *cond_expr = stmt->getCond();
747 Expr *true_expr = stmt->getTrueExpr();
748 Expr *false_expr = stmt->getFalseExpr();
749
750 node->data.if_bool_expr.condition = trans_expr(c, block, cond_expr);
751 node->data.if_bool_expr.then_block = trans_expr(c, block, true_expr);
752 node->data.if_bool_expr.else_node = trans_expr(c, block, false_expr);
753
754 return node;
755}
756
757static AstNode * trans_create_bin_op(Context *c, AstNode *block, Expr *lhs, BinOpType bin_op, Expr *rhs) {
758 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
759 node->data.bin_op_expr.bin_op = bin_op;
760 node->data.bin_op_expr.op1 = trans_expr(c, block, lhs);
761 node->data.bin_op_expr.op2 = trans_expr(c, block, rhs);
762 return node;
763}
764
765static AstNode * trans_binary_operator(Context *c, AstNode *block, BinaryOperator *stmt) {
766 switch (stmt->getOpcode()) {
767 case BO_PtrMemD:
768 zig_panic("TODO handle more C binary operators: BO_PtrMemD");
769 case BO_PtrMemI:
770 zig_panic("TODO handle more C binary operators: BO_PtrMemI");
771 case BO_Mul:
772 zig_panic("TODO handle more C binary operators: BO_Mul");
773 case BO_Div:
774 zig_panic("TODO handle more C binary operators: BO_Div");
775 case BO_Rem:
776 zig_panic("TODO handle more C binary operators: BO_Rem");
777 case BO_Add:
778 zig_panic("TODO handle more C binary operators: BO_Add");
779 case BO_Sub:
780 zig_panic("TODO handle more C binary operators: BO_Sub");
781 case BO_Shl:
782 zig_panic("TODO handle more C binary operators: BO_Shl");
783 case BO_Shr:
784 zig_panic("TODO handle more C binary operators: BO_Shr");
785 case BO_LT:
786 return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeCmpLessThan, stmt->getRHS());
787 case BO_GT:
788 return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeCmpGreaterThan, stmt->getRHS());
789 case BO_LE:
790 return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeCmpLessOrEq, stmt->getRHS());
791 case BO_GE:
792 return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeCmpGreaterOrEq, stmt->getRHS());
793 case BO_EQ:
794 zig_panic("TODO handle more C binary operators: BO_EQ");
795 case BO_NE:
796 zig_panic("TODO handle more C binary operators: BO_NE");
797 case BO_And:
798 zig_panic("TODO handle more C binary operators: BO_And");
799 case BO_Xor:
800 zig_panic("TODO handle more C binary operators: BO_Xor");
801 case BO_Or:
802 zig_panic("TODO handle more C binary operators: BO_Or");
803 case BO_LAnd:
804 zig_panic("TODO handle more C binary operators: BO_LAnd");
805 case BO_LOr:
806 zig_panic("TODO handle more C binary operators: BO_LOr");
807 case BO_Assign:
808 zig_panic("TODO handle more C binary operators: BO_Assign");
809 case BO_MulAssign:
810 zig_panic("TODO handle more C binary operators: BO_MulAssign");
811 case BO_DivAssign:
812 zig_panic("TODO handle more C binary operators: BO_DivAssign");
813 case BO_RemAssign:
814 zig_panic("TODO handle more C binary operators: BO_RemAssign");
815 case BO_AddAssign:
816 zig_panic("TODO handle more C binary operators: BO_AddAssign");
817 case BO_SubAssign:
818 zig_panic("TODO handle more C binary operators: BO_SubAssign");
819 case BO_ShlAssign:
820 zig_panic("TODO handle more C binary operators: BO_ShlAssign");
821 case BO_ShrAssign:
822 zig_panic("TODO handle more C binary operators: BO_ShrAssign");
823 case BO_AndAssign:
824 zig_panic("TODO handle more C binary operators: BO_AndAssign");
825 case BO_XorAssign:
826 zig_panic("TODO handle more C binary operators: BO_XorAssign");
827 case BO_OrAssign:
828 zig_panic("TODO handle more C binary operators: BO_OrAssign");
829 case BO_Comma:
830 zig_panic("TODO handle more C binary operators: BO_Comma");
831 }
832
833 zig_unreachable();
834}
835
836static AstNode * trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCastExpr *stmt) {
837 switch (stmt->getCastKind()) {
838 case CK_LValueToRValue:
839 return trans_expr(c, block, stmt->getSubExpr());
840 case CK_IntegralCast:
841 {
842 AstNode *node = trans_create_node_builtin_fn_call_str(c, "bitCast");
843 node->data.fn_call_expr.params.append(trans_qual_type(c, stmt->getType(), stmt->getExprLoc()));
844 node->data.fn_call_expr.params.append(trans_expr(c, block, stmt->getSubExpr()));
845 return node;
846 }
847 case CK_Dependent:
848 zig_panic("TODO handle C translation cast CK_Dependent");
849 case CK_BitCast:
850 zig_panic("TODO handle C translation cast CK_BitCast");
851 case CK_LValueBitCast:
852 zig_panic("TODO handle C translation cast CK_LValueBitCast");
853 case CK_NoOp:
854 zig_panic("TODO handle C translation cast CK_NoOp");
855 case CK_BaseToDerived:
856 zig_panic("TODO handle C translation cast CK_BaseToDerived");
857 case CK_DerivedToBase:
858 zig_panic("TODO handle C translation cast CK_DerivedToBase");
859 case CK_UncheckedDerivedToBase:
860 zig_panic("TODO handle C translation cast CK_UncheckedDerivedToBase");
861 case CK_Dynamic:
862 zig_panic("TODO handle C translation cast CK_Dynamic");
863 case CK_ToUnion:
864 zig_panic("TODO handle C translation cast CK_ToUnion");
865 case CK_ArrayToPointerDecay:
866 zig_panic("TODO handle C translation cast CK_ArrayToPointerDecay");
867 case CK_FunctionToPointerDecay:
868 zig_panic("TODO handle C translation cast CK_FunctionToPointerDecay");
869 case CK_NullToPointer:
870 zig_panic("TODO handle C translation cast CK_NullToPointer");
871 case CK_NullToMemberPointer:
872 zig_panic("TODO handle C translation cast CK_NullToMemberPointer");
873 case CK_BaseToDerivedMemberPointer:
874 zig_panic("TODO handle C translation cast CK_BaseToDerivedMemberPointer");
875 case CK_DerivedToBaseMemberPointer:
876 zig_panic("TODO handle C translation cast CK_DerivedToBaseMemberPointer");
877 case CK_MemberPointerToBoolean:
878 zig_panic("TODO handle C translation cast CK_MemberPointerToBoolean");
879 case CK_ReinterpretMemberPointer:
880 zig_panic("TODO handle C translation cast CK_ReinterpretMemberPointer");
881 case CK_UserDefinedConversion:
882 zig_panic("TODO handle C translation cast CK_UserDefinedConversion");
883 case CK_ConstructorConversion:
884 zig_panic("TODO handle C translation cast CK_ConstructorConversion");
885 case CK_IntegralToPointer:
886 zig_panic("TODO handle C translation cast CK_IntegralToPointer");
887 case CK_PointerToIntegral:
888 zig_panic("TODO handle C translation cast CK_PointerToIntegral");
889 case CK_PointerToBoolean:
890 zig_panic("TODO handle C translation cast CK_PointerToBoolean");
891 case CK_ToVoid:
892 zig_panic("TODO handle C translation cast CK_ToVoid");
893 case CK_VectorSplat:
894 zig_panic("TODO handle C translation cast CK_VectorSplat");
895 case CK_IntegralToBoolean:
896 zig_panic("TODO handle C translation cast CK_IntegralToBoolean");
897 case CK_IntegralToFloating:
898 zig_panic("TODO handle C translation cast CK_IntegralToFloating");
899 case CK_FloatingToIntegral:
900 zig_panic("TODO handle C translation cast CK_FloatingToIntegral");
901 case CK_FloatingToBoolean:
902 zig_panic("TODO handle C translation cast CK_FloatingToBoolean");
903 case CK_BooleanToSignedIntegral:
904 zig_panic("TODO handle C translation cast CK_BooleanToSignedIntegral");
905 case CK_FloatingCast:
906 zig_panic("TODO handle C translation cast CK_FloatingCast");
907 case CK_CPointerToObjCPointerCast:
908 zig_panic("TODO handle C translation cast CK_CPointerToObjCPointerCast");
909 case CK_BlockPointerToObjCPointerCast:
910 zig_panic("TODO handle C translation cast CK_BlockPointerToObjCPointerCast");
911 case CK_AnyPointerToBlockPointerCast:
912 zig_panic("TODO handle C translation cast CK_AnyPointerToBlockPointerCast");
913 case CK_ObjCObjectLValueCast:
914 zig_panic("TODO handle C translation cast CK_ObjCObjectLValueCast");
915 case CK_FloatingRealToComplex:
916 zig_panic("TODO handle C translation cast CK_FloatingRealToComplex");
917 case CK_FloatingComplexToReal:
918 zig_panic("TODO handle C translation cast CK_FloatingComplexToReal");
919 case CK_FloatingComplexToBoolean:
920 zig_panic("TODO handle C translation cast CK_FloatingComplexToBoolean");
921 case CK_FloatingComplexCast:
922 zig_panic("TODO handle C translation cast CK_FloatingComplexCast");
923 case CK_FloatingComplexToIntegralComplex:
924 zig_panic("TODO handle C translation cast CK_FloatingComplexToIntegralComplex");
925 case CK_IntegralRealToComplex:
926 zig_panic("TODO handle C translation cast CK_IntegralRealToComplex");
927 case CK_IntegralComplexToReal:
928 zig_panic("TODO handle C translation cast CK_IntegralComplexToReal");
929 case CK_IntegralComplexToBoolean:
930 zig_panic("TODO handle C translation cast CK_IntegralComplexToBoolean");
931 case CK_IntegralComplexCast:
932 zig_panic("TODO handle C translation cast CK_IntegralComplexCast");
933 case CK_IntegralComplexToFloatingComplex:
934 zig_panic("TODO handle C translation cast CK_IntegralComplexToFloatingComplex");
935 case CK_ARCProduceObject:
936 zig_panic("TODO handle C translation cast CK_ARCProduceObject");
937 case CK_ARCConsumeObject:
938 zig_panic("TODO handle C translation cast CK_ARCConsumeObject");
939 case CK_ARCReclaimReturnedObject:
940 zig_panic("TODO handle C translation cast CK_ARCReclaimReturnedObject");
941 case CK_ARCExtendBlockObject:
942 zig_panic("TODO handle C translation cast CK_ARCExtendBlockObject");
943 case CK_AtomicToNonAtomic:
944 zig_panic("TODO handle C translation cast CK_AtomicToNonAtomic");
945 case CK_NonAtomicToAtomic:
946 zig_panic("TODO handle C translation cast CK_NonAtomicToAtomic");
947 case CK_CopyAndAutoreleaseBlockObject:
948 zig_panic("TODO handle C translation cast CK_CopyAndAutoreleaseBlockObject");
949 case CK_BuiltinFnToFnPtr:
950 zig_panic("TODO handle C translation cast CK_BuiltinFnToFnPtr");
951 case CK_ZeroToOCLEvent:
952 zig_panic("TODO handle C translation cast CK_ZeroToOCLEvent");
953 case CK_ZeroToOCLQueue:
954 zig_panic("TODO handle C translation cast CK_ZeroToOCLQueue");
955 case CK_AddressSpaceConversion:
956 zig_panic("TODO handle C translation cast CK_AddressSpaceConversion");
957 case CK_IntToOCLSampler:
958 zig_panic("TODO handle C translation cast CK_IntToOCLSampler");
959 }
960 zig_unreachable();
961}
962
963static AstNode * trans_decl_ref_expr(Context *c, DeclRefExpr *stmt) {
964 ValueDecl *value_decl = stmt->getDecl();
965 const char *name = decl_name(value_decl);
966
967 AstNode *node = trans_create_node(c, NodeTypeSymbol);
968 node->data.symbol_expr.symbol = buf_create_from_str(name);
969 return node;
970}
971
972static AstNode * trans_unary_operator(Context *c, AstNode *block, UnaryOperator *stmt) {
973 switch (stmt->getOpcode()) {
974 case UO_PostInc:
975 zig_panic("TODO handle C translation UO_PostInc");
976 case UO_PostDec:
977 zig_panic("TODO handle C translation UO_PostDec");
978 case UO_PreInc:
979 zig_panic("TODO handle C translation UO_PreInc");
980 case UO_PreDec:
981 zig_panic("TODO handle C translation UO_PreDec");
982 case UO_AddrOf:
983 zig_panic("TODO handle C translation UO_AddrOf");
984 case UO_Deref:
985 zig_panic("TODO handle C translation UO_Deref");
986 case UO_Plus:
987 zig_panic("TODO handle C translation UO_Plus");
988 case UO_Minus:
989 {
990 Expr *op_expr = stmt->getSubExpr();
991 if (c_is_signed_integer(c, op_expr->getType()) || c_is_float(c, op_expr->getType())) {
992 AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);
993 node->data.prefix_op_expr.prefix_op = PrefixOpNegation;
994 node->data.prefix_op_expr.primary_expr = trans_expr(c, block, op_expr);
995 return node;
996 } else if (c_is_unsigned_integer(c, op_expr->getType())) {
997 // we gotta emit 0 -% x
998 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
999 node->data.bin_op_expr.op1 = trans_create_node_unsigned(c, 0);
1000 node->data.bin_op_expr.op2 = trans_expr(c, block, op_expr);
1001 node->data.bin_op_expr.bin_op = BinOpTypeSubWrap;
1002 return node;
1003 } else {
1004 zig_panic("TODO translate C negation with non float non integer");
1005 }
1006 }
1007 case UO_Not:
1008 zig_panic("TODO handle C translation UO_Not");
1009 case UO_LNot:
1010 zig_panic("TODO handle C translation UO_LNot");
1011 case UO_Real:
1012 zig_panic("TODO handle C translation UO_Real");
1013 case UO_Imag:
1014 zig_panic("TODO handle C translation UO_Imag");
1015 case UO_Extension:
1016 zig_panic("TODO handle C translation UO_Extension");
1017 case UO_Coawait:
1018 zig_panic("TODO handle C translation UO_Coawait");
1019 }
1020 zig_unreachable();
1021}
1022
1023static AstNode * trans_local_declaration(Context *c, AstNode *block, DeclStmt *stmt) {
1024 for (auto iter = stmt->decl_begin(); iter != stmt->decl_end(); iter++) {
1025 Decl *decl = *iter;
1026 switch (decl->getKind()) {
1027 case Decl::Var: {
1028 VarDecl *var_decl = (VarDecl *)decl;
1029 QualType qual_type = var_decl->getTypeSourceInfo()->getType();
1030 AstNode *init_node = var_decl->hasInit() ? trans_expr(c, block, var_decl->getInit()) : nullptr;
1031 AstNode *type_node = trans_qual_type(c, qual_type, stmt->getStartLoc());
1032 AstNode *node = trans_create_node_var_decl(c, qual_type.isConstQualified(),
1033 buf_create_from_str(decl_name(var_decl)), type_node, init_node);
1034 block->data.block.statements.append(node);
1035 continue;
1036 }
1037 case Decl::AccessSpec:
1038 zig_panic("TODO handle decl kind AccessSpec");
1039 case Decl::Block:
1040 zig_panic("TODO handle decl kind Block");
1041 case Decl::Captured:
1042 zig_panic("TODO handle decl kind Captured");
1043 case Decl::ClassScopeFunctionSpecialization:
1044 zig_panic("TODO handle decl kind ClassScopeFunctionSpecialization");
1045 case Decl::Empty:
1046 zig_panic("TODO handle decl kind Empty");
1047 case Decl::Export:
1048 zig_panic("TODO handle decl kind Export");
1049 case Decl::ExternCContext:
1050 zig_panic("TODO handle decl kind ExternCContext");
1051 case Decl::FileScopeAsm:
1052 zig_panic("TODO handle decl kind FileScopeAsm");
1053 case Decl::Friend:
1054 zig_panic("TODO handle decl kind Friend");
1055 case Decl::FriendTemplate:
1056 zig_panic("TODO handle decl kind FriendTemplate");
1057 case Decl::Import:
1058 zig_panic("TODO handle decl kind Import");
1059 case Decl::LinkageSpec:
1060 zig_panic("TODO handle decl kind LinkageSpec");
1061 case Decl::Label:
1062 zig_panic("TODO handle decl kind Label");
1063 case Decl::Namespace:
1064 zig_panic("TODO handle decl kind Namespace");
1065 case Decl::NamespaceAlias:
1066 zig_panic("TODO handle decl kind NamespaceAlias");
1067 case Decl::ObjCCompatibleAlias:
1068 zig_panic("TODO handle decl kind ObjCCompatibleAlias");
1069 case Decl::ObjCCategory:
1070 zig_panic("TODO handle decl kind ObjCCategory");
1071 case Decl::ObjCCategoryImpl:
1072 zig_panic("TODO handle decl kind ObjCCategoryImpl");
1073 case Decl::ObjCImplementation:
1074 zig_panic("TODO handle decl kind ObjCImplementation");
1075 case Decl::ObjCInterface:
1076 zig_panic("TODO handle decl kind ObjCInterface");
1077 case Decl::ObjCProtocol:
1078 zig_panic("TODO handle decl kind ObjCProtocol");
1079 case Decl::ObjCMethod:
1080 zig_panic("TODO handle decl kind ObjCMethod");
1081 case Decl::ObjCProperty:
1082 zig_panic("TODO handle decl kind ObjCProperty");
1083 case Decl::BuiltinTemplate:
1084 zig_panic("TODO handle decl kind BuiltinTemplate");
1085 case Decl::ClassTemplate:
1086 zig_panic("TODO handle decl kind ClassTemplate");
1087 case Decl::FunctionTemplate:
1088 zig_panic("TODO handle decl kind FunctionTemplate");
1089 case Decl::TypeAliasTemplate:
1090 zig_panic("TODO handle decl kind TypeAliasTemplate");
1091 case Decl::VarTemplate:
1092 zig_panic("TODO handle decl kind VarTemplate");
1093 case Decl::TemplateTemplateParm:
1094 zig_panic("TODO handle decl kind TemplateTemplateParm");
1095 case Decl::Enum:
1096 zig_panic("TODO handle decl kind Enum");
1097 case Decl::Record:
1098 zig_panic("TODO handle decl kind Record");
1099 case Decl::CXXRecord:
1100 zig_panic("TODO handle decl kind CXXRecord");
1101 case Decl::ClassTemplateSpecialization:
1102 zig_panic("TODO handle decl kind ClassTemplateSpecialization");
1103 case Decl::ClassTemplatePartialSpecialization:
1104 zig_panic("TODO handle decl kind ClassTemplatePartialSpecialization");
1105 case Decl::TemplateTypeParm:
1106 zig_panic("TODO handle decl kind TemplateTypeParm");
1107 case Decl::ObjCTypeParam:
1108 zig_panic("TODO handle decl kind ObjCTypeParam");
1109 case Decl::TypeAlias:
1110 zig_panic("TODO handle decl kind TypeAlias");
1111 case Decl::Typedef:
1112 zig_panic("TODO handle decl kind Typedef");
1113 case Decl::UnresolvedUsingTypename:
1114 zig_panic("TODO handle decl kind UnresolvedUsingTypename");
1115 case Decl::Using:
1116 zig_panic("TODO handle decl kind Using");
1117 case Decl::UsingDirective:
1118 zig_panic("TODO handle decl kind UsingDirective");
1119 case Decl::UsingPack:
1120 zig_panic("TODO handle decl kind UsingPack");
1121 case Decl::UsingShadow:
1122 zig_panic("TODO handle decl kind UsingShadow");
1123 case Decl::ConstructorUsingShadow:
1124 zig_panic("TODO handle decl kind ConstructorUsingShadow");
1125 case Decl::Binding:
1126 zig_panic("TODO handle decl kind Binding");
1127 case Decl::Field:
1128 zig_panic("TODO handle decl kind Field");
1129 case Decl::ObjCAtDefsField:
1130 zig_panic("TODO handle decl kind ObjCAtDefsField");
1131 case Decl::ObjCIvar:
1132 zig_panic("TODO handle decl kind ObjCIvar");
1133 case Decl::Function:
1134 zig_panic("TODO handle decl kind Function");
1135 case Decl::CXXDeductionGuide:
1136 zig_panic("TODO handle decl kind CXXDeductionGuide");
1137 case Decl::CXXMethod:
1138 zig_panic("TODO handle decl kind CXXMethod");
1139 case Decl::CXXConstructor:
1140 zig_panic("TODO handle decl kind CXXConstructor");
1141 case Decl::CXXConversion:
1142 zig_panic("TODO handle decl kind CXXConversion");
1143 case Decl::CXXDestructor:
1144 zig_panic("TODO handle decl kind CXXDestructor");
1145 case Decl::MSProperty:
1146 zig_panic("TODO handle decl kind MSProperty");
1147 case Decl::NonTypeTemplateParm:
1148 zig_panic("TODO handle decl kind NonTypeTemplateParm");
1149 case Decl::Decomposition:
1150 zig_panic("TODO handle decl kind Decomposition");
1151 case Decl::ImplicitParam:
1152 zig_panic("TODO handle decl kind ImplicitParam");
1153 case Decl::OMPCapturedExpr:
1154 zig_panic("TODO handle decl kind OMPCapturedExpr");
1155 case Decl::ParmVar:
1156 zig_panic("TODO handle decl kind ParmVar");
1157 case Decl::VarTemplateSpecialization:
1158 zig_panic("TODO handle decl kind VarTemplateSpecialization");
1159 case Decl::VarTemplatePartialSpecialization:
1160 zig_panic("TODO handle decl kind VarTemplatePartialSpecialization");
1161 case Decl::EnumConstant:
1162 zig_panic("TODO handle decl kind EnumConstant");
1163 case Decl::IndirectField:
1164 zig_panic("TODO handle decl kind IndirectField");
1165 case Decl::OMPDeclareReduction:
1166 zig_panic("TODO handle decl kind OMPDeclareReduction");
1167 case Decl::UnresolvedUsingValue:
1168 zig_panic("TODO handle decl kind UnresolvedUsingValue");
1169 case Decl::OMPThreadPrivate:
1170 zig_panic("TODO handle decl kind OMPThreadPrivate");
1171 case Decl::ObjCPropertyImpl:
1172 zig_panic("TODO handle decl kind ObjCPropertyImpl");
1173 case Decl::PragmaComment:
1174 zig_panic("TODO handle decl kind PragmaComment");
1175 case Decl::PragmaDetectMismatch:
1176 zig_panic("TODO handle decl kind PragmaDetectMismatch");
1177 case Decl::StaticAssert:
1178 zig_panic("TODO handle decl kind StaticAssert");
1179 case Decl::TranslationUnit:
1180 zig_panic("TODO handle decl kind TranslationUnit");
1181 }
1182 zig_unreachable();
1183 }
1184
1185 // declarations were already added
1186 return nullptr;
1187}
1188
1189static AstNode *trans_while_loop(Context *c, AstNode *block, WhileStmt *stmt) {
1190 AstNode *while_node = trans_create_node(c, NodeTypeWhileExpr);
1191 while_node->data.while_expr.condition = trans_expr(c, block, stmt->getCond());
1192 while_node->data.while_expr.body = trans_stmt(c, block, stmt->getBody());
1193 return while_node;
1194}
1195
1196static AstNode *trans_stmt(Context *c, AstNode *block, Stmt *stmt) {
1197 Stmt::StmtClass sc = stmt->getStmtClass();
1198 switch (sc) {
1199 case Stmt::ReturnStmtClass:
1200 return trans_return_stmt(c, block, (ReturnStmt *)stmt);
1201 case Stmt::CompoundStmtClass:
1202 return trans_compound_stmt(c, block, (CompoundStmt *)stmt);
1203 case Stmt::IntegerLiteralClass:
1204 return trans_integer_literal(c, (IntegerLiteral *)stmt);
1205 case Stmt::ConditionalOperatorClass:
1206 return trans_conditional_operator(c, block, (ConditionalOperator *)stmt);
1207 case Stmt::BinaryOperatorClass:
1208 return trans_binary_operator(c, block, (BinaryOperator *)stmt);
1209 case Stmt::ImplicitCastExprClass:
1210 return trans_implicit_cast_expr(c, block, (ImplicitCastExpr *)stmt);
1211 case Stmt::DeclRefExprClass:
1212 return trans_decl_ref_expr(c, (DeclRefExpr *)stmt);
1213 case Stmt::UnaryOperatorClass:
1214 return trans_unary_operator(c, block, (UnaryOperator *)stmt);
1215 case Stmt::DeclStmtClass:
1216 return trans_local_declaration(c, block, (DeclStmt *)stmt);
1217 case Stmt::WhileStmtClass:
1218 return trans_while_loop(c, block, (WhileStmt *)stmt);
1219 case Stmt::CaseStmtClass:
1220 zig_panic("TODO handle C CaseStmtClass");
1221 case Stmt::DefaultStmtClass:
1222 zig_panic("TODO handle C DefaultStmtClass");
1223 case Stmt::SwitchStmtClass:
1224 zig_panic("TODO handle C SwitchStmtClass");
1225 case Stmt::NoStmtClass:
1226 zig_panic("TODO handle C NoStmtClass");
1227 case Stmt::GCCAsmStmtClass:
1228 zig_panic("TODO handle C GCCAsmStmtClass");
1229 case Stmt::MSAsmStmtClass:
1230 zig_panic("TODO handle C MSAsmStmtClass");
1231 case Stmt::AttributedStmtClass:
1232 zig_panic("TODO handle C AttributedStmtClass");
1233 case Stmt::BreakStmtClass:
1234 zig_panic("TODO handle C BreakStmtClass");
1235 case Stmt::CXXCatchStmtClass:
1236 zig_panic("TODO handle C CXXCatchStmtClass");
1237 case Stmt::CXXForRangeStmtClass:
1238 zig_panic("TODO handle C CXXForRangeStmtClass");
1239 case Stmt::CXXTryStmtClass:
1240 zig_panic("TODO handle C CXXTryStmtClass");
1241 case Stmt::CapturedStmtClass:
1242 zig_panic("TODO handle C CapturedStmtClass");
1243 case Stmt::ContinueStmtClass:
1244 zig_panic("TODO handle C ContinueStmtClass");
1245 case Stmt::CoreturnStmtClass:
1246 zig_panic("TODO handle C CoreturnStmtClass");
1247 case Stmt::CoroutineBodyStmtClass:
1248 zig_panic("TODO handle C CoroutineBodyStmtClass");
1249 case Stmt::DoStmtClass:
1250 zig_panic("TODO handle C DoStmtClass");
1251 case Stmt::BinaryConditionalOperatorClass:
1252 zig_panic("TODO handle C BinaryConditionalOperatorClass");
1253 case Stmt::AddrLabelExprClass:
1254 zig_panic("TODO handle C AddrLabelExprClass");
1255 case Stmt::ArrayInitIndexExprClass:
1256 zig_panic("TODO handle C ArrayInitIndexExprClass");
1257 case Stmt::ArrayInitLoopExprClass:
1258 zig_panic("TODO handle C ArrayInitLoopExprClass");
1259 case Stmt::ArraySubscriptExprClass:
1260 zig_panic("TODO handle C ArraySubscriptExprClass");
1261 case Stmt::ArrayTypeTraitExprClass:
1262 zig_panic("TODO handle C ArrayTypeTraitExprClass");
1263 case Stmt::AsTypeExprClass:
1264 zig_panic("TODO handle C AsTypeExprClass");
1265 case Stmt::AtomicExprClass:
1266 zig_panic("TODO handle C AtomicExprClass");
1267 case Stmt::CompoundAssignOperatorClass:
1268 zig_panic("TODO handle C CompoundAssignOperatorClass");
1269 case Stmt::BlockExprClass:
1270 zig_panic("TODO handle C BlockExprClass");
1271 case Stmt::CXXBindTemporaryExprClass:
1272 zig_panic("TODO handle C CXXBindTemporaryExprClass");
1273 case Stmt::CXXBoolLiteralExprClass:
1274 zig_panic("TODO handle C CXXBoolLiteralExprClass");
1275 case Stmt::CXXConstructExprClass:
1276 zig_panic("TODO handle C CXXConstructExprClass");
1277 case Stmt::CXXTemporaryObjectExprClass:
1278 zig_panic("TODO handle C CXXTemporaryObjectExprClass");
1279 case Stmt::CXXDefaultArgExprClass:
1280 zig_panic("TODO handle C CXXDefaultArgExprClass");
1281 case Stmt::CXXDefaultInitExprClass:
1282 zig_panic("TODO handle C CXXDefaultInitExprClass");
1283 case Stmt::CXXDeleteExprClass:
1284 zig_panic("TODO handle C CXXDeleteExprClass");
1285 case Stmt::CXXDependentScopeMemberExprClass:
1286 zig_panic("TODO handle C CXXDependentScopeMemberExprClass");
1287 case Stmt::CXXFoldExprClass:
1288 zig_panic("TODO handle C CXXFoldExprClass");
1289 case Stmt::CXXInheritedCtorInitExprClass:
1290 zig_panic("TODO handle C CXXInheritedCtorInitExprClass");
1291 case Stmt::CXXNewExprClass:
1292 zig_panic("TODO handle C CXXNewExprClass");
1293 case Stmt::CXXNoexceptExprClass:
1294 zig_panic("TODO handle C CXXNoexceptExprClass");
1295 case Stmt::CXXNullPtrLiteralExprClass:
1296 zig_panic("TODO handle C CXXNullPtrLiteralExprClass");
1297 case Stmt::CXXPseudoDestructorExprClass:
1298 zig_panic("TODO handle C CXXPseudoDestructorExprClass");
1299 case Stmt::CXXScalarValueInitExprClass:
1300 zig_panic("TODO handle C CXXScalarValueInitExprClass");
1301 case Stmt::CXXStdInitializerListExprClass:
1302 zig_panic("TODO handle C CXXStdInitializerListExprClass");
1303 case Stmt::CXXThisExprClass:
1304 zig_panic("TODO handle C CXXThisExprClass");
1305 case Stmt::CXXThrowExprClass:
1306 zig_panic("TODO handle C CXXThrowExprClass");
1307 case Stmt::CXXTypeidExprClass:
1308 zig_panic("TODO handle C CXXTypeidExprClass");
1309 case Stmt::CXXUnresolvedConstructExprClass:
1310 zig_panic("TODO handle C CXXUnresolvedConstructExprClass");
1311 case Stmt::CXXUuidofExprClass:
1312 zig_panic("TODO handle C CXXUuidofExprClass");
1313 case Stmt::CallExprClass:
1314 zig_panic("TODO handle C CallExprClass");
1315 case Stmt::CUDAKernelCallExprClass:
1316 zig_panic("TODO handle C CUDAKernelCallExprClass");
1317 case Stmt::CXXMemberCallExprClass:
1318 zig_panic("TODO handle C CXXMemberCallExprClass");
1319 case Stmt::CXXOperatorCallExprClass:
1320 zig_panic("TODO handle C CXXOperatorCallExprClass");
1321 case Stmt::UserDefinedLiteralClass:
1322 zig_panic("TODO handle C UserDefinedLiteralClass");
1323 case Stmt::CStyleCastExprClass:
1324 zig_panic("TODO handle C CStyleCastExprClass");
1325 case Stmt::CXXFunctionalCastExprClass:
1326 zig_panic("TODO handle C CXXFunctionalCastExprClass");
1327 case Stmt::CXXConstCastExprClass:
1328 zig_panic("TODO handle C CXXConstCastExprClass");
1329 case Stmt::CXXDynamicCastExprClass:
1330 zig_panic("TODO handle C CXXDynamicCastExprClass");
1331 case Stmt::CXXReinterpretCastExprClass:
1332 zig_panic("TODO handle C CXXReinterpretCastExprClass");
1333 case Stmt::CXXStaticCastExprClass:
1334 zig_panic("TODO handle C CXXStaticCastExprClass");
1335 case Stmt::ObjCBridgedCastExprClass:
1336 zig_panic("TODO handle C ObjCBridgedCastExprClass");
1337 case Stmt::CharacterLiteralClass:
1338 zig_panic("TODO handle C CharacterLiteralClass");
1339 case Stmt::ChooseExprClass:
1340 zig_panic("TODO handle C ChooseExprClass");
1341 case Stmt::CompoundLiteralExprClass:
1342 zig_panic("TODO handle C CompoundLiteralExprClass");
1343 case Stmt::ConvertVectorExprClass:
1344 zig_panic("TODO handle C ConvertVectorExprClass");
1345 case Stmt::CoawaitExprClass:
1346 zig_panic("TODO handle C CoawaitExprClass");
1347 case Stmt::CoyieldExprClass:
1348 zig_panic("TODO handle C CoyieldExprClass");
1349 case Stmt::DependentCoawaitExprClass:
1350 zig_panic("TODO handle C DependentCoawaitExprClass");
1351 case Stmt::DependentScopeDeclRefExprClass:
1352 zig_panic("TODO handle C DependentScopeDeclRefExprClass");
1353 case Stmt::DesignatedInitExprClass:
1354 zig_panic("TODO handle C DesignatedInitExprClass");
1355 case Stmt::DesignatedInitUpdateExprClass:
1356 zig_panic("TODO handle C DesignatedInitUpdateExprClass");
1357 case Stmt::ExprWithCleanupsClass:
1358 zig_panic("TODO handle C ExprWithCleanupsClass");
1359 case Stmt::ExpressionTraitExprClass:
1360 zig_panic("TODO handle C ExpressionTraitExprClass");
1361 case Stmt::ExtVectorElementExprClass:
1362 zig_panic("TODO handle C ExtVectorElementExprClass");
1363 case Stmt::FloatingLiteralClass:
1364 zig_panic("TODO handle C FloatingLiteralClass");
1365 case Stmt::FunctionParmPackExprClass:
1366 zig_panic("TODO handle C FunctionParmPackExprClass");
1367 case Stmt::GNUNullExprClass:
1368 zig_panic("TODO handle C GNUNullExprClass");
1369 case Stmt::GenericSelectionExprClass:
1370 zig_panic("TODO handle C GenericSelectionExprClass");
1371 case Stmt::ImaginaryLiteralClass:
1372 zig_panic("TODO handle C ImaginaryLiteralClass");
1373 case Stmt::ImplicitValueInitExprClass:
1374 zig_panic("TODO handle C ImplicitValueInitExprClass");
1375 case Stmt::InitListExprClass:
1376 zig_panic("TODO handle C InitListExprClass");
1377 case Stmt::LambdaExprClass:
1378 zig_panic("TODO handle C LambdaExprClass");
1379 case Stmt::MSPropertyRefExprClass:
1380 zig_panic("TODO handle C MSPropertyRefExprClass");
1381 case Stmt::MSPropertySubscriptExprClass:
1382 zig_panic("TODO handle C MSPropertySubscriptExprClass");
1383 case Stmt::MaterializeTemporaryExprClass:
1384 zig_panic("TODO handle C MaterializeTemporaryExprClass");
1385 case Stmt::MemberExprClass:
1386 zig_panic("TODO handle C MemberExprClass");
1387 case Stmt::NoInitExprClass:
1388 zig_panic("TODO handle C NoInitExprClass");
1389 case Stmt::OMPArraySectionExprClass:
1390 zig_panic("TODO handle C OMPArraySectionExprClass");
1391 case Stmt::ObjCArrayLiteralClass:
1392 zig_panic("TODO handle C ObjCArrayLiteralClass");
1393 case Stmt::ObjCAvailabilityCheckExprClass:
1394 zig_panic("TODO handle C ObjCAvailabilityCheckExprClass");
1395 case Stmt::ObjCBoolLiteralExprClass:
1396 zig_panic("TODO handle C ObjCBoolLiteralExprClass");
1397 case Stmt::ObjCBoxedExprClass:
1398 zig_panic("TODO handle C ObjCBoxedExprClass");
1399 case Stmt::ObjCDictionaryLiteralClass:
1400 zig_panic("TODO handle C ObjCDictionaryLiteralClass");
1401 case Stmt::ObjCEncodeExprClass:
1402 zig_panic("TODO handle C ObjCEncodeExprClass");
1403 case Stmt::ObjCIndirectCopyRestoreExprClass:
1404 zig_panic("TODO handle C ObjCIndirectCopyRestoreExprClass");
1405 case Stmt::ObjCIsaExprClass:
1406 zig_panic("TODO handle C ObjCIsaExprClass");
1407 case Stmt::ObjCIvarRefExprClass:
1408 zig_panic("TODO handle C ObjCIvarRefExprClass");
1409 case Stmt::ObjCMessageExprClass:
1410 zig_panic("TODO handle C ObjCMessageExprClass");
1411 case Stmt::ObjCPropertyRefExprClass:
1412 zig_panic("TODO handle C ObjCPropertyRefExprClass");
1413 case Stmt::ObjCProtocolExprClass:
1414 zig_panic("TODO handle C ObjCProtocolExprClass");
1415 case Stmt::ObjCSelectorExprClass:
1416 zig_panic("TODO handle C ObjCSelectorExprClass");
1417 case Stmt::ObjCStringLiteralClass:
1418 zig_panic("TODO handle C ObjCStringLiteralClass");
1419 case Stmt::ObjCSubscriptRefExprClass:
1420 zig_panic("TODO handle C ObjCSubscriptRefExprClass");
1421 case Stmt::OffsetOfExprClass:
1422 zig_panic("TODO handle C OffsetOfExprClass");
1423 case Stmt::OpaqueValueExprClass:
1424 zig_panic("TODO handle C OpaqueValueExprClass");
1425 case Stmt::UnresolvedLookupExprClass:
1426 zig_panic("TODO handle C UnresolvedLookupExprClass");
1427 case Stmt::UnresolvedMemberExprClass:
1428 zig_panic("TODO handle C UnresolvedMemberExprClass");
1429 case Stmt::PackExpansionExprClass:
1430 zig_panic("TODO handle C PackExpansionExprClass");
1431 case Stmt::ParenExprClass:
1432 zig_panic("TODO handle C ParenExprClass");
1433 case Stmt::ParenListExprClass:
1434 zig_panic("TODO handle C ParenListExprClass");
1435 case Stmt::PredefinedExprClass:
1436 zig_panic("TODO handle C PredefinedExprClass");
1437 case Stmt::PseudoObjectExprClass:
1438 zig_panic("TODO handle C PseudoObjectExprClass");
1439 case Stmt::ShuffleVectorExprClass:
1440 zig_panic("TODO handle C ShuffleVectorExprClass");
1441 case Stmt::SizeOfPackExprClass:
1442 zig_panic("TODO handle C SizeOfPackExprClass");
1443 case Stmt::StmtExprClass:
1444 zig_panic("TODO handle C StmtExprClass");
1445 case Stmt::StringLiteralClass:
1446 zig_panic("TODO handle C StringLiteralClass");
1447 case Stmt::SubstNonTypeTemplateParmExprClass:
1448 zig_panic("TODO handle C SubstNonTypeTemplateParmExprClass");
1449 case Stmt::SubstNonTypeTemplateParmPackExprClass:
1450 zig_panic("TODO handle C SubstNonTypeTemplateParmPackExprClass");
1451 case Stmt::TypeTraitExprClass:
1452 zig_panic("TODO handle C TypeTraitExprClass");
1453 case Stmt::TypoExprClass:
1454 zig_panic("TODO handle C TypoExprClass");
1455 case Stmt::UnaryExprOrTypeTraitExprClass:
1456 zig_panic("TODO handle C UnaryExprOrTypeTraitExprClass");
1457 case Stmt::VAArgExprClass:
1458 zig_panic("TODO handle C VAArgExprClass");
1459 case Stmt::ForStmtClass:
1460 zig_panic("TODO handle C ForStmtClass");
1461 case Stmt::GotoStmtClass:
1462 zig_panic("TODO handle C GotoStmtClass");
1463 case Stmt::IfStmtClass:
1464 zig_panic("TODO handle C IfStmtClass");
1465 case Stmt::IndirectGotoStmtClass:
1466 zig_panic("TODO handle C IndirectGotoStmtClass");
1467 case Stmt::LabelStmtClass:
1468 zig_panic("TODO handle C LabelStmtClass");
1469 case Stmt::MSDependentExistsStmtClass:
1470 zig_panic("TODO handle C MSDependentExistsStmtClass");
1471 case Stmt::NullStmtClass:
1472 zig_panic("TODO handle C NullStmtClass");
1473 case Stmt::OMPAtomicDirectiveClass:
1474 zig_panic("TODO handle C OMPAtomicDirectiveClass");
1475 case Stmt::OMPBarrierDirectiveClass:
1476 zig_panic("TODO handle C OMPBarrierDirectiveClass");
1477 case Stmt::OMPCancelDirectiveClass:
1478 zig_panic("TODO handle C OMPCancelDirectiveClass");
1479 case Stmt::OMPCancellationPointDirectiveClass:
1480 zig_panic("TODO handle C OMPCancellationPointDirectiveClass");
1481 case Stmt::OMPCriticalDirectiveClass:
1482 zig_panic("TODO handle C OMPCriticalDirectiveClass");
1483 case Stmt::OMPFlushDirectiveClass:
1484 zig_panic("TODO handle C OMPFlushDirectiveClass");
1485 case Stmt::OMPDistributeDirectiveClass:
1486 zig_panic("TODO handle C OMPDistributeDirectiveClass");
1487 case Stmt::OMPDistributeParallelForDirectiveClass:
1488 zig_panic("TODO handle C OMPDistributeParallelForDirectiveClass");
1489 case Stmt::OMPDistributeParallelForSimdDirectiveClass:
1490 zig_panic("TODO handle C OMPDistributeParallelForSimdDirectiveClass");
1491 case Stmt::OMPDistributeSimdDirectiveClass:
1492 zig_panic("TODO handle C OMPDistributeSimdDirectiveClass");
1493 case Stmt::OMPForDirectiveClass:
1494 zig_panic("TODO handle C OMPForDirectiveClass");
1495 case Stmt::OMPForSimdDirectiveClass:
1496 zig_panic("TODO handle C OMPForSimdDirectiveClass");
1497 case Stmt::OMPParallelForDirectiveClass:
1498 zig_panic("TODO handle C OMPParallelForDirectiveClass");
1499 case Stmt::OMPParallelForSimdDirectiveClass:
1500 zig_panic("TODO handle C OMPParallelForSimdDirectiveClass");
1501 case Stmt::OMPSimdDirectiveClass:
1502 zig_panic("TODO handle C OMPSimdDirectiveClass");
1503 case Stmt::OMPTargetParallelForSimdDirectiveClass:
1504 zig_panic("TODO handle C OMPTargetParallelForSimdDirectiveClass");
1505 case Stmt::OMPTargetSimdDirectiveClass:
1506 zig_panic("TODO handle C OMPTargetSimdDirectiveClass");
1507 case Stmt::OMPTargetTeamsDistributeDirectiveClass:
1508 zig_panic("TODO handle C OMPTargetTeamsDistributeDirectiveClass");
1509 case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
1510 zig_panic("TODO handle C OMPTargetTeamsDistributeParallelForDirectiveClass");
1511 case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
1512 zig_panic("TODO handle C OMPTargetTeamsDistributeParallelForSimdDirectiveClass");
1513 case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
1514 zig_panic("TODO handle C OMPTargetTeamsDistributeSimdDirectiveClass");
1515 case Stmt::OMPTaskLoopDirectiveClass:
1516 zig_panic("TODO handle C OMPTaskLoopDirectiveClass");
1517 case Stmt::OMPTaskLoopSimdDirectiveClass:
1518 zig_panic("TODO handle C OMPTaskLoopSimdDirectiveClass");
1519 case Stmt::OMPTeamsDistributeDirectiveClass:
1520 zig_panic("TODO handle C OMPTeamsDistributeDirectiveClass");
1521 case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
1522 zig_panic("TODO handle C OMPTeamsDistributeParallelForDirectiveClass");
1523 case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
1524 zig_panic("TODO handle C OMPTeamsDistributeParallelForSimdDirectiveClass");
1525 case Stmt::OMPTeamsDistributeSimdDirectiveClass:
1526 zig_panic("TODO handle C OMPTeamsDistributeSimdDirectiveClass");
1527 case Stmt::OMPMasterDirectiveClass:
1528 zig_panic("TODO handle C OMPMasterDirectiveClass");
1529 case Stmt::OMPOrderedDirectiveClass:
1530 zig_panic("TODO handle C OMPOrderedDirectiveClass");
1531 case Stmt::OMPParallelDirectiveClass:
1532 zig_panic("TODO handle C OMPParallelDirectiveClass");
1533 case Stmt::OMPParallelSectionsDirectiveClass:
1534 zig_panic("TODO handle C OMPParallelSectionsDirectiveClass");
1535 case Stmt::OMPSectionDirectiveClass:
1536 zig_panic("TODO handle C OMPSectionDirectiveClass");
1537 case Stmt::OMPSectionsDirectiveClass:
1538 zig_panic("TODO handle C OMPSectionsDirectiveClass");
1539 case Stmt::OMPSingleDirectiveClass:
1540 zig_panic("TODO handle C OMPSingleDirectiveClass");
1541 case Stmt::OMPTargetDataDirectiveClass:
1542 zig_panic("TODO handle C OMPTargetDataDirectiveClass");
1543 case Stmt::OMPTargetDirectiveClass:
1544 zig_panic("TODO handle C OMPTargetDirectiveClass");
1545 case Stmt::OMPTargetEnterDataDirectiveClass:
1546 zig_panic("TODO handle C OMPTargetEnterDataDirectiveClass");
1547 case Stmt::OMPTargetExitDataDirectiveClass:
1548 zig_panic("TODO handle C OMPTargetExitDataDirectiveClass");
1549 case Stmt::OMPTargetParallelDirectiveClass:
1550 zig_panic("TODO handle C OMPTargetParallelDirectiveClass");
1551 case Stmt::OMPTargetParallelForDirectiveClass:
1552 zig_panic("TODO handle C OMPTargetParallelForDirectiveClass");
1553 case Stmt::OMPTargetTeamsDirectiveClass:
1554 zig_panic("TODO handle C OMPTargetTeamsDirectiveClass");
1555 case Stmt::OMPTargetUpdateDirectiveClass:
1556 zig_panic("TODO handle C OMPTargetUpdateDirectiveClass");
1557 case Stmt::OMPTaskDirectiveClass:
1558 zig_panic("TODO handle C OMPTaskDirectiveClass");
1559 case Stmt::OMPTaskgroupDirectiveClass:
1560 zig_panic("TODO handle C OMPTaskgroupDirectiveClass");
1561 case Stmt::OMPTaskwaitDirectiveClass:
1562 zig_panic("TODO handle C OMPTaskwaitDirectiveClass");
1563 case Stmt::OMPTaskyieldDirectiveClass:
1564 zig_panic("TODO handle C OMPTaskyieldDirectiveClass");
1565 case Stmt::OMPTeamsDirectiveClass:
1566 zig_panic("TODO handle C OMPTeamsDirectiveClass");
1567 case Stmt::ObjCAtCatchStmtClass:
1568 zig_panic("TODO handle C ObjCAtCatchStmtClass");
1569 case Stmt::ObjCAtFinallyStmtClass:
1570 zig_panic("TODO handle C ObjCAtFinallyStmtClass");
1571 case Stmt::ObjCAtSynchronizedStmtClass:
1572 zig_panic("TODO handle C ObjCAtSynchronizedStmtClass");
1573 case Stmt::ObjCAtThrowStmtClass:
1574 zig_panic("TODO handle C ObjCAtThrowStmtClass");
1575 case Stmt::ObjCAtTryStmtClass:
1576 zig_panic("TODO handle C ObjCAtTryStmtClass");
1577 case Stmt::ObjCAutoreleasePoolStmtClass:
1578 zig_panic("TODO handle C ObjCAutoreleasePoolStmtClass");
1579 case Stmt::ObjCForCollectionStmtClass:
1580 zig_panic("TODO handle C ObjCForCollectionStmtClass");
1581 case Stmt::SEHExceptStmtClass:
1582 zig_panic("TODO handle C SEHExceptStmtClass");
1583 case Stmt::SEHFinallyStmtClass:
1584 zig_panic("TODO handle C SEHFinallyStmtClass");
1585 case Stmt::SEHLeaveStmtClass:
1586 zig_panic("TODO handle C SEHLeaveStmtClass");
1587 case Stmt::SEHTryStmtClass:
1588 zig_panic("TODO handle C SEHTryStmtClass");
1589 }
1590 zig_unreachable();
1591}
1592
1593static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
1594 Buf *fn_name = buf_create_from_str(decl_name(fn_decl));
1595
1596 if (get_global(c, fn_name)) {
1597 // we already saw this function
1598 return;
1599 }
1600
1601 AstNode *proto_node = trans_qual_type(c, fn_decl->getType(), fn_decl->getLocation());
1602 if (proto_node == nullptr) {
1603 emit_warning(c, fn_decl->getLocation(), "unable to resolve prototype of function '%s'", buf_ptr(fn_name));
1604 return;
1605 }
1606
1607 proto_node->data.fn_proto.name = fn_name;
1608 proto_node->data.fn_proto.is_extern = !fn_decl->hasBody();
1609
1610 StorageClass sc = fn_decl->getStorageClass();
1611 if (sc == SC_None) {
1612 proto_node->data.fn_proto.visib_mod = fn_decl->hasBody() ? VisibModExport : c->visib_mod;
1613 } else if (sc == SC_Extern || sc == SC_Static) {
1614 proto_node->data.fn_proto.visib_mod = c->visib_mod;
1615 } else if (sc == SC_PrivateExtern) {
1616 emit_warning(c, fn_decl->getLocation(), "unsupported storage class: private extern");
1617 return;
1618 } else {
1619 emit_warning(c, fn_decl->getLocation(), "unsupported storage class: unknown");
1620 return;
1621 }
1622
1623 for (size_t i = 0; i < proto_node->data.fn_proto.params.length; i += 1) {
1624 AstNode *param_node = proto_node->data.fn_proto.params.at(i);
1625 const ParmVarDecl *param = fn_decl->getParamDecl(i);
1626 const char *name = decl_name(param);
1627 if (strlen(name) == 0) {
1628 Buf *proto_param_name = param_node->data.param_decl.name;
1629 if (proto_param_name == nullptr) {
1630 param_node->data.param_decl.name = buf_sprintf("arg%" ZIG_PRI_usize "", i);
1631 } else {
1632 param_node->data.param_decl.name = proto_param_name;
1633 }
1634 } else {
1635 param_node->data.param_decl.name = buf_create_from_str(name);
1636 }
1637 }
1638
1639 if (fn_decl->hasBody()) {
1640 Stmt *body = fn_decl->getBody();
1641
1642 AstNode *fn_def_node = trans_create_node(c, NodeTypeFnDef);
1643 fn_def_node->data.fn_def.fn_proto = proto_node;
1644 fn_def_node->data.fn_def.body = trans_stmt(c, nullptr, body);
1645
1646 proto_node->data.fn_proto.fn_def_node = fn_def_node;
1647 c->root->data.root.top_level_decls.append(fn_def_node);
1648 return;
1649 }
1650
1651 c->root->data.root.top_level_decls.append(proto_node);
1652}
1653
1654static AstNode *resolve_typdef_as_builtin(Context *c, const TypedefNameDecl *typedef_decl, const char *primitive_name) {
1655 AstNode *node = trans_create_node_symbol_str(c, primitive_name);
1656 c->decl_table.put(typedef_decl, node);
1657 return node;
1658}
1659
1660static AstNode *resolve_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) {
1661 auto existing_entry = c->decl_table.maybe_get((void*)typedef_decl);
1662 if (existing_entry) {
1663 return existing_entry->value;
1664 }
1665
1666 QualType child_qt = typedef_decl->getUnderlyingType();
1667 Buf *type_name = buf_create_from_str(decl_name(typedef_decl));
1668
1669 if (buf_eql_str(type_name, "uint8_t")) {
1670 return resolve_typdef_as_builtin(c, typedef_decl, "u8");
1671 } else if (buf_eql_str(type_name, "int8_t")) {
1672 return resolve_typdef_as_builtin(c, typedef_decl, "i8");
1673 } else if (buf_eql_str(type_name, "uint16_t")) {
1674 return resolve_typdef_as_builtin(c, typedef_decl, "u16");
1675 } else if (buf_eql_str(type_name, "int16_t")) {
1676 return resolve_typdef_as_builtin(c, typedef_decl, "i16");
1677 } else if (buf_eql_str(type_name, "uint32_t")) {
1678 return resolve_typdef_as_builtin(c, typedef_decl, "u32");
1679 } else if (buf_eql_str(type_name, "int32_t")) {
1680 return resolve_typdef_as_builtin(c, typedef_decl, "i32");
1681 } else if (buf_eql_str(type_name, "uint64_t")) {
1682 return resolve_typdef_as_builtin(c, typedef_decl, "u64");
1683 } else if (buf_eql_str(type_name, "int64_t")) {
1684 return resolve_typdef_as_builtin(c, typedef_decl, "i64");
1685 } else if (buf_eql_str(type_name, "intptr_t")) {
1686 return resolve_typdef_as_builtin(c, typedef_decl, "isize");
1687 } else if (buf_eql_str(type_name, "uintptr_t")) {
1688 return resolve_typdef_as_builtin(c, typedef_decl, "usize");
1689 } else if (buf_eql_str(type_name, "ssize_t")) {
1690 return resolve_typdef_as_builtin(c, typedef_decl, "isize");
1691 } else if (buf_eql_str(type_name, "size_t")) {
1692 return resolve_typdef_as_builtin(c, typedef_decl, "usize");
1693 }
1694
1695 // if the underlying type is anonymous, we can special case it to just
1696 // use the name of this typedef
1697 // TODO
1698
1699 AstNode *type_node = trans_qual_type(c, child_qt, typedef_decl->getLocation());
1700 if (type_node == nullptr) {
1701 emit_warning(c, typedef_decl->getLocation(), "typedef %s - unresolved child type", buf_ptr(type_name));
1702 c->decl_table.put(typedef_decl, nullptr);
1703 return nullptr;
1704 }
1705 add_global_var(c, type_name, type_node);
1706
1707 AstNode *symbol_node = trans_create_node_symbol(c, type_name);
1708 c->decl_table.put(typedef_decl, symbol_node);
1709 return symbol_node;
1710}
1711
1712struct AstNode *demote_enum_to_opaque(Context *c, const EnumDecl *enum_decl,
1713 Buf *full_type_name, Buf *bare_name)
1714{
1715 AstNode *opaque_node = trans_create_node_opaque(c);
1716 if (full_type_name == nullptr) {
1717 c->decl_table.put(enum_decl->getCanonicalDecl(), opaque_node);
1718 return opaque_node;
1719 }
1720 AstNode *symbol_node = trans_create_node_symbol(c, full_type_name);
1721 add_global_weak_alias(c, bare_name, full_type_name);
1722 add_global_var(c, full_type_name, opaque_node);
1723 c->decl_table.put(enum_decl->getCanonicalDecl(), symbol_node);
1724 return symbol_node;
1725}
1726
1727static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) {
1728 auto existing_entry = c->decl_table.maybe_get((void*)enum_decl->getCanonicalDecl());
1729 if (existing_entry) {
1730 return existing_entry->value;
1731 }
1732
1733 const char *raw_name = decl_name(enum_decl);
1734 bool is_anonymous = (raw_name[0] == 0);
1735 Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name);
1736 Buf *full_type_name = is_anonymous ? nullptr : buf_sprintf("enum_%s", buf_ptr(bare_name));
1737
1738 const EnumDecl *enum_def = enum_decl->getDefinition();
1739 if (!enum_def) {
1740 return demote_enum_to_opaque(c, enum_decl, full_type_name, bare_name);
1741 }
1742
1743 bool pure_enum = true;
1744 uint32_t field_count = 0;
1745 for (auto it = enum_def->enumerator_begin(),
1746 it_end = enum_def->enumerator_end();
1747 it != it_end; ++it, field_count += 1)
1748 {
1749 const EnumConstantDecl *enum_const = *it;
1750 if (enum_const->getInitExpr()) {
1751 pure_enum = false;
1752 }
1753 }
1754
1755 AstNode *tag_int_type = trans_qual_type(c, enum_decl->getIntegerType(), enum_decl->getLocation());
1756 assert(tag_int_type);
1757
1758 if (pure_enum) {
1759 AstNode *enum_node = trans_create_node(c, NodeTypeContainerDecl);
1760 enum_node->data.container_decl.kind = ContainerKindEnum;
1761 enum_node->data.container_decl.layout = ContainerLayoutExtern;
1762 enum_node->data.container_decl.init_arg_expr = tag_int_type;
1763
1764 enum_node->data.container_decl.fields.resize(field_count);
1765 uint32_t i = 0;
1766 for (auto it = enum_def->enumerator_begin(),
1767 it_end = enum_def->enumerator_end();
1768 it != it_end; ++it, i += 1)
1769 {
1770 const EnumConstantDecl *enum_const = *it;
1771
1772 Buf *enum_val_name = buf_create_from_str(decl_name(enum_const));
1773 Buf *field_name;
1774 if (bare_name != nullptr && buf_starts_with_buf(enum_val_name, bare_name)) {
1775 field_name = buf_slice(enum_val_name, buf_len(bare_name), buf_len(enum_val_name));
1776 } else {
1777 field_name = enum_val_name;
1778 }
1779
1780 AstNode *field_node = trans_create_node(c, NodeTypeStructField);
1781 field_node->data.struct_field.name = field_name;
1782 field_node->data.struct_field.type = nullptr;
1783 enum_node->data.container_decl.fields.items[i] = field_node;
1784
1785 // in C each enum value is in the global namespace. so we put them there too.
1786 // at this point we can rely on the enum emitting successfully
1787 AstNode *field_access_node = trans_create_node_field_access(c,
1788 trans_create_node_symbol(c, full_type_name), field_name);
1789 add_global_var(c, enum_val_name, field_access_node);
1790 }
1791
1792 if (is_anonymous) {
1793 c->decl_table.put(enum_decl->getCanonicalDecl(), enum_node);
1794 return enum_node;
1795 } else {
1796 AstNode *symbol_node = trans_create_node_symbol(c, full_type_name);
1797 add_global_weak_alias(c, bare_name, full_type_name);
1798 add_global_var(c, full_type_name, enum_node);
1799 c->decl_table.put(enum_decl->getCanonicalDecl(), symbol_node);
1800 return enum_node;
1801 }
1802 }
1803
1804 // TODO after issue #305 is solved, make this be an enum with tag_int_type
1805 // as the integer type and set the custom enum values
1806 AstNode *enum_node = tag_int_type;
1807
1808
1809 // add variables for all the values with enum_node
1810 for (auto it = enum_def->enumerator_begin(),
1811 it_end = enum_def->enumerator_end();
1812 it != it_end; ++it)
1813 {
1814 const EnumConstantDecl *enum_const = *it;
1815
1816 Buf *enum_val_name = buf_create_from_str(decl_name(enum_const));
1817 AstNode *int_node = trans_create_node_apint(c, enum_const->getInitVal());
1818 AstNode *var_node = add_global_var(c, enum_val_name, int_node);
1819 var_node->data.variable_declaration.type = tag_int_type;
1820 }
1821
1822 if (is_anonymous) {
1823 c->decl_table.put(enum_decl->getCanonicalDecl(), enum_node);
1824 return enum_node;
1825 } else {
1826 AstNode *symbol_node = trans_create_node_symbol(c, full_type_name);
1827 add_global_weak_alias(c, bare_name, full_type_name);
1828 add_global_var(c, full_type_name, enum_node);
1829 return symbol_node;
1830 }
1831}
1832
1833static AstNode *demote_struct_to_opaque(Context *c, const RecordDecl *record_decl,
1834 Buf *full_type_name, Buf *bare_name)
1835{
1836 AstNode *opaque_node = trans_create_node_opaque(c);
1837 if (full_type_name == nullptr) {
1838 c->decl_table.put(record_decl->getCanonicalDecl(), opaque_node);
1839 return opaque_node;
1840 }
1841 AstNode *symbol_node = trans_create_node_symbol(c, full_type_name);
1842 add_global_weak_alias(c, bare_name, full_type_name);
1843 add_global_var(c, full_type_name, opaque_node);
1844 c->decl_table.put(record_decl->getCanonicalDecl(), symbol_node);
1845 return symbol_node;
1846}
1847
1848static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {
1849 auto existing_entry = c->decl_table.maybe_get((void*)record_decl->getCanonicalDecl());
1850 if (existing_entry) {
1851 return existing_entry->value;
1852 }
1853
1854 const char *raw_name = decl_name(record_decl);
1855
1856 if (!record_decl->isStruct()) {
1857 emit_warning(c, record_decl->getLocation(), "skipping record %s, not a struct", raw_name);
1858 c->decl_table.put(record_decl->getCanonicalDecl(), nullptr);
1859 return nullptr;
1860 }
1861
1862 bool is_anonymous = record_decl->isAnonymousStructOrUnion() || raw_name[0] == 0;
1863 Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name);
1864 Buf *full_type_name = (bare_name == nullptr) ? nullptr : buf_sprintf("struct_%s", buf_ptr(bare_name));
1865
1866 RecordDecl *record_def = record_decl->getDefinition();
1867 if (record_def == nullptr) {
1868 return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);
1869 }
1870
1871 // count fields and validate
1872 uint32_t field_count = 0;
1873 for (auto it = record_def->field_begin(),
1874 it_end = record_def->field_end();
1875 it != it_end; ++it, field_count += 1)
1876 {
1877 const FieldDecl *field_decl = *it;
1878
1879 if (field_decl->isBitField()) {
1880 emit_warning(c, field_decl->getLocation(), "struct %s demoted to opaque type - has bitfield",
1881 is_anonymous ? "(anon)" : buf_ptr(bare_name));
1882 return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);
1883 }
1884 }
1885
1886 AstNode *struct_node = trans_create_node(c, NodeTypeContainerDecl);
1887 struct_node->data.container_decl.kind = ContainerKindStruct;
1888 struct_node->data.container_decl.layout = ContainerLayoutExtern;
1889
1890 // TODO handle attribute packed
1891
1892 struct_node->data.container_decl.fields.resize(field_count);
1893
1894 // must be before fields in case a circular reference happens
1895 if (is_anonymous) {
1896 c->decl_table.put(record_decl->getCanonicalDecl(), struct_node);
1897 } else {
1898 c->decl_table.put(record_decl->getCanonicalDecl(), trans_create_node_symbol(c, full_type_name));
1899 }
1900
1901 uint32_t i = 0;
1902 for (auto it = record_def->field_begin(),
1903 it_end = record_def->field_end();
1904 it != it_end; ++it, i += 1)
1905 {
1906 const FieldDecl *field_decl = *it;
1907
1908 AstNode *field_node = trans_create_node(c, NodeTypeStructField);
1909 field_node->data.struct_field.name = buf_create_from_str(decl_name(field_decl));
1910 field_node->data.struct_field.type = trans_qual_type(c, field_decl->getType(), field_decl->getLocation());
1911
1912 if (field_node->data.struct_field.type == nullptr) {
1913 emit_warning(c, field_decl->getLocation(),
1914 "struct %s demoted to opaque type - unresolved type",
1915 is_anonymous ? "(anon)" : buf_ptr(bare_name));
1916
1917 return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);
1918 }
1919
1920 struct_node->data.container_decl.fields.items[i] = field_node;
1921 }
1922
1923 if (is_anonymous) {
1924 return struct_node;
1925 } else {
1926 add_global_weak_alias(c, bare_name, full_type_name);
1927 add_global_var(c, full_type_name, struct_node);
1928 return trans_create_node_symbol(c, full_type_name);
1929 }
1930}
1931
1932static void visit_var_decl(Context *c, const VarDecl *var_decl) {
1933 Buf *name = buf_create_from_str(decl_name(var_decl));
1934
1935 switch (var_decl->getTLSKind()) {
1936 case VarDecl::TLS_None:
1937 break;
1938 case VarDecl::TLS_Static:
1939 emit_warning(c, var_decl->getLocation(),
1940 "ignoring variable '%s' - static thread local storage", buf_ptr(name));
1941 return;
1942 case VarDecl::TLS_Dynamic:
1943 emit_warning(c, var_decl->getLocation(),
1944 "ignoring variable '%s' - dynamic thread local storage", buf_ptr(name));
1945 return;
1946 }
1947
1948 QualType qt = var_decl->getType();
1949 AstNode *var_type = trans_qual_type(c, qt, var_decl->getLocation());
1950 if (var_type == nullptr) {
1951 emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - unresolved type", buf_ptr(name));
1952 return;
1953 }
1954
1955 bool is_extern = var_decl->hasExternalStorage();
1956 bool is_static = var_decl->isFileVarDecl();
1957 bool is_const = qt.isConstQualified();
1958
1959 if (is_static && !is_extern) {
1960 AstNode *init_node;
1961 if (var_decl->hasInit()) {
1962 APValue *ap_value = var_decl->evaluateValue();
1963 if (ap_value == nullptr) {
1964 emit_warning(c, var_decl->getLocation(),
1965 "ignoring variable '%s' - unable to evaluate initializer", buf_ptr(name));
1966 return;
1967 }
1968 switch (ap_value->getKind()) {
1969 case APValue::Int:
1970 init_node = trans_create_node_apint(c, ap_value->getInt());
1971 break;
1972 case APValue::Uninitialized:
1973 init_node = trans_create_node_symbol_str(c, "undefined");
1974 break;
1975 case APValue::Float:
1976 case APValue::ComplexInt:
1977 case APValue::ComplexFloat:
1978 case APValue::LValue:
1979 case APValue::Vector:
1980 case APValue::Array:
1981 case APValue::Struct:
1982 case APValue::Union:
1983 case APValue::MemberPointer:
1984 case APValue::AddrLabelDiff:
1985 emit_warning(c, var_decl->getLocation(),
1986 "ignoring variable '%s' - unrecognized initializer value kind", buf_ptr(name));
1987 return;
1988 }
1989 } else {
1990 init_node = trans_create_node_symbol_str(c, "undefined");
1991 }
1992
1993 AstNode *var_node = trans_create_node_var_decl(c, is_const, name, var_type, init_node);
1994 c->root->data.root.top_level_decls.append(var_node);
1995 return;
1996 }
1997
1998 if (is_extern) {
1999 AstNode *var_node = trans_create_node_var_decl(c, is_const, name, var_type, nullptr);
2000 var_node->data.variable_declaration.is_extern = true;
2001 c->root->data.root.top_level_decls.append(var_node);
2002 return;
2003 }
2004
2005 emit_warning(c, var_decl->getLocation(),
2006 "ignoring variable '%s' - non-extern, non-static variable", buf_ptr(name));
2007 return;
2008}
2009
2010static bool decl_visitor(void *context, const Decl *decl) {
2011 Context *c = (Context*)context;
2012
2013 switch (decl->getKind()) {
2014 case Decl::Function:
2015 visit_fn_decl(c, static_cast<const FunctionDecl*>(decl));
2016 break;
2017 case Decl::Typedef:
2018 resolve_typedef_decl(c, static_cast<const TypedefNameDecl *>(decl));
2019 break;
2020 case Decl::Enum:
2021 resolve_enum_decl(c, static_cast<const EnumDecl *>(decl));
2022 break;
2023 case Decl::Record:
2024 resolve_record_decl(c, static_cast<const RecordDecl *>(decl));
2025 break;
2026 case Decl::Var:
2027 visit_var_decl(c, static_cast<const VarDecl *>(decl));
2028 break;
2029 default:
2030 emit_warning(c, decl->getLocation(), "ignoring %s decl", decl->getDeclKindName());
2031 }
2032
2033 return true;
2034}
2035
2036static bool name_exists(Context *c, Buf *name) {
2037 return get_global(c, name) != nullptr;
2038}
2039
2040static void render_aliases(Context *c) {
2041 for (size_t i = 0; i < c->aliases.length; i += 1) {
2042 Alias *alias = &c->aliases.at(i);
2043 if (name_exists(c, alias->new_name))
2044 continue;
2045
2046 add_global_var(c, alias->new_name, trans_create_node_symbol(c, alias->canon_name));
2047 }
2048}
2049
2050static void render_macros(Context *c) {
2051 auto it = c->macro_table.entry_iterator();
2052 for (;;) {
2053 auto *entry = it.next();
2054 if (!entry)
2055 break;
2056
2057 AstNode *value_node = entry->value;
2058 if (value_node->type == NodeTypeFnDef) {
2059 c->root->data.root.top_level_decls.append(value_node);
2060 } else {
2061 add_global_var(c, entry->key, value_node);
2062 }
2063 }
2064}
2065
2066static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *char_ptr) {
2067 tokenize_c_macro(ctok, (const uint8_t *)char_ptr);
2068
2069 if (ctok->error) {
2070 return;
2071 }
2072
2073 bool negate = false;
2074 for (size_t i = 0; i < ctok->tokens.length; i += 1) {
2075 bool is_first = (i == 0);
2076 bool is_last = (i == ctok->tokens.length - 1);
2077 CTok *tok = &ctok->tokens.at(i);
2078 switch (tok->id) {
2079 case CTokIdCharLit:
2080 if (is_last && is_first) {
2081 AstNode *node = trans_create_node_unsigned(c, tok->data.char_lit);
2082 c->macro_table.put(name, node);
2083 }
2084 return;
2085 case CTokIdStrLit:
2086 if (is_last && is_first) {
2087 AstNode *node = trans_create_node_str_lit_c(c, buf_create_from_buf(&tok->data.str_lit));
2088 c->macro_table.put(name, node);
2089 }
2090 return;
2091 case CTokIdNumLitInt:
2092 if (is_last) {
2093 AstNode *node;
2094 switch (tok->data.num_lit_int.suffix) {
2095 case CNumLitSuffixNone:
2096 node = trans_create_node_unsigned_negative(c, tok->data.num_lit_int.x, negate);
2097 break;
2098 case CNumLitSuffixL:
2099 node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate,
2100 "c_long");
2101 break;
2102 case CNumLitSuffixU:
2103 node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate,
2104 "c_uint");
2105 break;
2106 case CNumLitSuffixLU:
2107 node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate,
2108 "c_ulong");
2109 break;
2110 case CNumLitSuffixLL:
2111 node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate,
2112 "c_longlong");
2113 break;
2114 case CNumLitSuffixLLU:
2115 node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate,
2116 "c_ulonglong");
2117 break;
2118 }
2119 c->macro_table.put(name, node);
2120 }
2121 return;
2122 case CTokIdNumLitFloat:
2123 if (is_last) {
2124 double value = negate ? -tok->data.num_lit_float : tok->data.num_lit_float;
2125 AstNode *node = trans_create_node_float_lit(c, value);
2126 c->macro_table.put(name, node);
2127 }
2128 return;
2129 case CTokIdSymbol:
2130 if (is_last && is_first) {
2131 // if it equals itself, ignore. for example, from stdio.h:
2132 // #define stdin stdin
2133 Buf *symbol_name = buf_create_from_buf(&tok->data.symbol);
2134 if (buf_eql_buf(name, symbol_name)) {
2135 return;
2136 }
2137 c->macro_symbols.append({name, symbol_name});
2138 return;
2139 }
2140 case CTokIdMinus:
2141 if (is_first) {
2142 negate = true;
2143 break;
2144 } else {
2145 return;
2146 }
2147 }
2148 }
2149}
2150
2151static void process_symbol_macros(Context *c) {
2152 for (size_t i = 0; i < c->macro_symbols.length; i += 1) {
2153 MacroSymbol ms = c->macro_symbols.at(i);
2154
2155 // Check if this macro aliases another top level declaration
2156 AstNode *existing_node = get_global(c, ms.value);
2157 if (!existing_node || name_exists(c, ms.name))
2158 continue;
2159
2160 // If a macro aliases a global variable which is a function pointer, we conclude that
2161 // the macro is intended to represent a function that assumes the function pointer
2162 // variable is non-null and calls it.
2163 if (existing_node->type == NodeTypeVariableDeclaration) {
2164 AstNode *var_type = existing_node->data.variable_declaration.type;
2165 if (var_type != nullptr && var_type->type == NodeTypePrefixOpExpr &&
2166 var_type->data.prefix_op_expr.prefix_op == PrefixOpMaybe)
2167 {
2168 AstNode *fn_proto_node = var_type->data.prefix_op_expr.primary_expr;
2169 if (fn_proto_node->type == NodeTypeFnProto) {
2170 AstNode *inline_fn_node = trans_create_node_inline_fn(c, ms.name, ms.value, fn_proto_node);
2171 c->macro_table.put(ms.name, inline_fn_node);
2172 continue;
2173 }
2174 }
2175 }
2176
2177 add_global_var(c, ms.name, trans_create_node_symbol(c, ms.value));
2178 }
2179}
2180
2181static void process_preprocessor_entities(Context *c, ASTUnit &unit) {
2182 CTokenize ctok = {{0}};
2183
2184 // TODO if we see #undef, delete it from the table
2185
2186 for (PreprocessedEntity *entity : unit.getLocalPreprocessingEntities()) {
2187 switch (entity->getKind()) {
2188 case PreprocessedEntity::InvalidKind:
2189 case PreprocessedEntity::InclusionDirectiveKind:
2190 case PreprocessedEntity::MacroExpansionKind:
2191 continue;
2192 case PreprocessedEntity::MacroDefinitionKind:
2193 {
2194 MacroDefinitionRecord *macro = static_cast<MacroDefinitionRecord *>(entity);
2195 const char *raw_name = macro->getName()->getNameStart();
2196 SourceRange range = macro->getSourceRange();
2197 SourceLocation begin_loc = range.getBegin();
2198 SourceLocation end_loc = range.getEnd();
2199
2200 if (begin_loc == end_loc) {
2201 // this means it is a macro without a value
2202 // we don't care about such things
2203 continue;
2204 }
2205 Buf *name = buf_create_from_str(raw_name);
2206 if (name_exists(c, name)) {
2207 continue;
2208 }
2209
2210 const char *end_c = c->source_manager->getCharacterData(end_loc);
2211 process_macro(c, &ctok, name, end_c);
2212 }
2213 }
2214 }
2215}
2216
2217int parse_h_buf(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, Buf *source,
2218 CodeGen *codegen, AstNode *source_node)
2219{
2220 int err;
2221 Buf tmp_file_path = BUF_INIT;
2222 if ((err = os_buf_to_tmp_file(source, buf_create_from_str(".h"), &tmp_file_path))) {
2223 return err;
2224 }
2225
2226 err = parse_h_file(import, errors, buf_ptr(&tmp_file_path), codegen, source_node);
2227
2228 os_delete_file(&tmp_file_path);
2229
2230 return err;
2231}
2232
2233int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const char *target_file,
2234 CodeGen *codegen, AstNode *source_node)
2235{
2236 Context context = {0};
2237 Context *c = &context;
2238 c->warnings_on = codegen->verbose;
2239 c->import = import;
2240 c->errors = errors;
2241 c->visib_mod = VisibModPub;
2242 c->decl_table.init(8);
2243 c->macro_table.init(8);
2244 c->codegen = codegen;
2245 c->source_node = source_node;
2246
2247 ZigList<const char *> clang_argv = {0};
2248
2249 clang_argv.append("-x");
2250 clang_argv.append("c");
2251
2252 if (c->codegen->is_native_target) {
2253 char *ZIG_PARSEH_CFLAGS = getenv("ZIG_NATIVE_PARSEH_CFLAGS");
2254 if (ZIG_PARSEH_CFLAGS) {
2255 Buf tmp_buf = BUF_INIT;
2256 char *start = ZIG_PARSEH_CFLAGS;
2257 char *space = strstr(start, " ");
2258 while (space) {
2259 if (space - start > 0) {
2260 buf_init_from_mem(&tmp_buf, start, space - start);
2261 clang_argv.append(buf_ptr(buf_create_from_buf(&tmp_buf)));
2262 }
2263 start = space + 1;
2264 space = strstr(start, " ");
2265 }
2266 buf_init_from_str(&tmp_buf, start);
2267 clang_argv.append(buf_ptr(buf_create_from_buf(&tmp_buf)));
2268 }
2269 }
2270
2271 clang_argv.append("-isystem");
2272 clang_argv.append(ZIG_HEADERS_DIR);
2273
2274 clang_argv.append("-isystem");
2275 clang_argv.append(buf_ptr(codegen->libc_include_dir));
2276
2277 for (size_t i = 0; i < codegen->clang_argv_len; i += 1) {
2278 clang_argv.append(codegen->clang_argv[i]);
2279 }
2280
2281 // we don't need spell checking and it slows things down
2282 clang_argv.append("-fno-spell-checking");
2283
2284 // this gives us access to preprocessing entities, presumably at
2285 // the cost of performance
2286 clang_argv.append("-Xclang");
2287 clang_argv.append("-detailed-preprocessing-record");
2288
2289 if (!c->codegen->is_native_target) {
2290 clang_argv.append("-target");
2291 clang_argv.append(buf_ptr(&c->codegen->triple_str));
2292 }
2293
2294 clang_argv.append(target_file);
2295
2296 // to make the [start...end] argument work
2297 clang_argv.append(nullptr);
2298
2299 IntrusiveRefCntPtr<DiagnosticsEngine> diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
2300
2301 std::shared_ptr<PCHContainerOperations> pch_container_ops = std::make_shared<PCHContainerOperations>();
2302
2303 bool skip_function_bodies = false;
2304 bool only_local_decls = true;
2305 bool capture_diagnostics = true;
2306 bool user_files_are_volatile = true;
2307 bool allow_pch_with_compiler_errors = false;
2308 bool single_file_parse = false;
2309 bool for_serialization = false;
2310 const char *resources_path = ZIG_HEADERS_DIR;
2311 std::unique_ptr<ASTUnit> err_unit;
2312 std::unique_ptr<ASTUnit> ast_unit(ASTUnit::LoadFromCommandLine(
2313 &clang_argv.at(0), &clang_argv.last(),
2314 pch_container_ops, diags, resources_path,
2315 only_local_decls, capture_diagnostics, None, true, 0, TU_Complete,
2316 false, false, allow_pch_with_compiler_errors, skip_function_bodies,
2317 single_file_parse, user_files_are_volatile, for_serialization, None, &err_unit,
2318 nullptr));
2319
2320 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
2321 if (!ast_unit && !err_unit) {
2322 return ErrorFileSystem;
2323 }
2324
2325 if (diags->getClient()->getNumErrors() > 0) {
2326 if (ast_unit) {
2327 err_unit = std::move(ast_unit);
2328 }
2329
2330 for (ASTUnit::stored_diag_iterator it = err_unit->stored_diag_begin(),
2331 it_end = err_unit->stored_diag_end();
2332 it != it_end; ++it)
2333 {
2334 switch (it->getLevel()) {
2335 case DiagnosticsEngine::Ignored:
2336 case DiagnosticsEngine::Note:
2337 case DiagnosticsEngine::Remark:
2338 case DiagnosticsEngine::Warning:
2339 continue;
2340 case DiagnosticsEngine::Error:
2341 case DiagnosticsEngine::Fatal:
2342 break;
2343 }
2344 StringRef msg_str_ref = it->getMessage();
2345 Buf *msg = buf_create_from_str((const char *)msg_str_ref.bytes_begin());
2346 FullSourceLoc fsl = it->getLocation();
2347 if (fsl.hasManager()) {
2348 FileID file_id = fsl.getFileID();
2349 StringRef filename = fsl.getManager().getFilename(fsl);
2350 unsigned line = fsl.getSpellingLineNumber() - 1;
2351 unsigned column = fsl.getSpellingColumnNumber() - 1;
2352 unsigned offset = fsl.getManager().getFileOffset(fsl);
2353 const char *source = (const char *)fsl.getManager().getBufferData(file_id).bytes_begin();
2354 Buf *path;
2355 if (filename.empty()) {
2356 path = buf_alloc();
2357 } else {
2358 path = buf_create_from_mem((const char *)filename.bytes_begin(), filename.size());
2359 }
2360
2361 ErrorMsg *err_msg = err_msg_create_with_offset(path, line, column, offset, source, msg);
2362
2363 c->errors->append(err_msg);
2364 } else {
2365 // NOTE the only known way this gets triggered right now is if you have a lot of errors
2366 // clang emits "too many errors emitted, stopping now"
2367 fprintf(stderr, "unexpected error from clang: %s\n", buf_ptr(msg));
2368 }
2369 }
2370
2371 return 0;
2372 }
2373
2374 c->ctx = &ast_unit->getASTContext();
2375 c->source_manager = &ast_unit->getSourceManager();
2376 c->root = trans_create_node(c, NodeTypeRoot);
2377
2378 ast_unit->visitLocalTopLevelDecls(c, decl_visitor);
2379
2380 process_preprocessor_entities(c, *ast_unit);
2381
2382 process_symbol_macros(c);
2383 render_macros(c);
2384 render_aliases(c);
2385
2386 import->root = c->root;
2387
2388 return 0;
2389}
src/parseh.hpp deleted-20
...@@ -1,20 +0,0 @@
1/*
2 * Copyright (c) 2015 Andrew Kelley
3 *
4 * This file is part of zig, which is MIT licensed.
5 * See http://opensource.org/licenses/MIT
6 */
7
8
9#ifndef ZIG_PARSEH_HPP
10#define ZIG_PARSEH_HPP
11
12#include "all_types.hpp"
13
14int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const char *target_file,
15 CodeGen *codegen, AstNode *source_node);
16
17int parse_h_buf(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, Buf *source,
18 CodeGen *codegen, AstNode *source_node);
19
20#endif
test/parsec.zig created+299
...@@ -0,0 +1,299 @@
1const tests = @import("tests.zig");
2
3pub fn addCases(cases: &tests.ParseCContext) {
4 cases.addAllowWarnings("simple data types",
5 \\#include <stdint.h>
6 \\int foo(char a, unsigned char b, signed char c);
7 \\int foo(char a, unsigned char b, signed char c); // test a duplicate prototype
8 \\void bar(uint8_t a, uint16_t b, uint32_t c, uint64_t d);
9 \\void baz(int8_t a, int16_t b, int32_t c, int64_t d);
10 ,
11 \\pub extern fn foo(a: u8, b: u8, c: i8) -> c_int;
12 ,
13 \\pub extern fn bar(a: u8, b: u16, c: u32, d: u64);
14 ,
15 \\pub extern fn baz(a: i8, b: i16, c: i32, d: i64);
16 );
17
18 cases.add("noreturn attribute",
19 \\void foo(void) __attribute__((noreturn));
20 ,
21 \\pub extern fn foo() -> noreturn;
22 );
23
24 cases.add("simple function",
25 \\int abs(int a) {
26 \\ return a < 0 ? -a : a;
27 \\}
28 ,
29 \\export fn abs(a: c_int) -> c_int {
30 \\ return if (a < 0) -a else a;
31 \\}
32 );
33
34 cases.add("enums",
35 \\enum Foo {
36 \\ FooA,
37 \\ FooB,
38 \\ Foo1,
39 \\};
40 ,
41 \\pub const enum_Foo = extern enum {
42 \\ A,
43 \\ B,
44 \\ @"1",
45 \\};
46 ,
47 \\pub const FooA = enum_Foo.A;
48 ,
49 \\pub const FooB = enum_Foo.B;
50 ,
51 \\pub const Foo1 = enum_Foo.@"1";
52 ,
53 \\pub const Foo = enum_Foo;
54 );
55
56 cases.add("restrict -> noalias",
57 \\void foo(void *restrict bar, void *restrict);
58 ,
59 \\pub extern fn foo(noalias bar: ?&c_void, noalias arg1: ?&c_void);
60 );
61
62 cases.add("simple struct",
63 \\struct Foo {
64 \\ int x;
65 \\ char *y;
66 \\};
67 ,
68 \\const struct_Foo = extern struct {
69 \\ x: c_int,
70 \\ y: ?&u8,
71 \\};
72 ,
73 \\pub const Foo = struct_Foo;
74 );
75
76 cases.add("qualified struct and enum",
77 \\struct Foo {
78 \\ int x;
79 \\ int y;
80 \\};
81 \\enum Bar {
82 \\ BarA,
83 \\ BarB,
84 \\};
85 \\void func(struct Foo *a, enum Bar **b);
86 ,
87 \\pub const struct_Foo = extern struct {
88 \\ x: c_int,
89 \\ y: c_int,
90 \\};
91 ,
92 \\pub const enum_Bar = extern enum {
93 \\ A,
94 \\ B,
95 \\};
96 ,
97 \\pub const BarA = enum_Bar.A;
98 ,
99 \\pub const BarB = enum_Bar.B;
100 ,
101 \\pub extern fn func(a: ?&struct_Foo, b: ?&?&enum_Bar);
102 ,
103 \\pub const Foo = struct_Foo;
104 ,
105 \\pub const Bar = enum_Bar;
106 );
107
108 cases.add("constant size array",
109 \\void func(int array[20]);
110 ,
111 \\pub extern fn func(array: ?&c_int);
112 );
113
114 cases.add("self referential struct with function pointer",
115 \\struct Foo {
116 \\ void (*derp)(struct Foo *foo);
117 \\};
118 ,
119 \\pub const struct_Foo = extern struct {
120 \\ derp: ?extern fn(?&struct_Foo),
121 \\};
122 ,
123 \\pub const Foo = struct_Foo;
124 );
125
126 cases.add("struct prototype used in func",
127 \\struct Foo;
128 \\struct Foo *some_func(struct Foo *foo, int x);
129 ,
130 \\pub const struct_Foo = @OpaqueType();
131 ,
132 \\pub extern fn some_func(foo: ?&struct_Foo, x: c_int) -> ?&struct_Foo;
133 ,
134 \\pub const Foo = struct_Foo;
135 );
136
137 cases.add("#define a char literal",
138 \\#define A_CHAR 'a'
139 ,
140 \\pub const A_CHAR = 97;
141 );
142
143 cases.add("#define an unsigned integer literal",
144 \\#define CHANNEL_COUNT 24
145 ,
146 \\pub const CHANNEL_COUNT = 24;
147 );
148
149 cases.add("#define referencing another #define",
150 \\#define THING2 THING1
151 \\#define THING1 1234
152 ,
153 \\pub const THING1 = 1234;
154 ,
155 \\pub const THING2 = THING1;
156 );
157
158 cases.add("variables",
159 \\extern int extern_var;
160 \\static const int int_var = 13;
161 ,
162 \\pub extern var extern_var: c_int;
163 ,
164 \\pub const int_var: c_int = 13;
165 );
166
167 cases.add("circular struct definitions",
168 \\struct Bar;
169 \\
170 \\struct Foo {
171 \\ struct Bar *next;
172 \\};
173 \\
174 \\struct Bar {
175 \\ struct Foo *next;
176 \\};
177 ,
178 \\pub const struct_Bar = extern struct {
179 \\ next: ?&struct_Foo,
180 \\};
181 ,
182 \\pub const struct_Foo = extern struct {
183 \\ next: ?&struct_Bar,
184 \\};
185 );
186
187 cases.add("typedef void",
188 \\typedef void Foo;
189 \\Foo fun(Foo *a);
190 ,
191 \\pub const Foo = c_void;
192 ,
193 \\pub extern fn fun(a: ?&Foo) -> Foo;
194 );
195
196 cases.add("generate inline func for #define global extern fn",
197 \\extern void (*fn_ptr)(void);
198 \\#define foo fn_ptr
199 \\
200 \\extern char (*fn_ptr2)(int, float);
201 \\#define bar fn_ptr2
202 ,
203 \\pub extern var fn_ptr: ?extern fn();
204 ,
205 \\pub inline fn foo() {
206 \\ ??fn_ptr()
207 \\}
208 ,
209 \\pub extern var fn_ptr2: ?extern fn(c_int, f32) -> u8;
210 ,
211 \\pub inline fn bar(arg0: c_int, arg1: f32) -> u8 {
212 \\ ??fn_ptr2(arg0, arg1)
213 \\}
214 );
215
216 cases.add("#define string",
217 \\#define foo "a string"
218 ,
219 \\pub const foo = c"a string";
220 );
221
222 cases.add("__cdecl doesn't mess up function pointers",
223 \\void foo(void (__cdecl *fn_ptr)(void));
224 ,
225 \\pub extern fn foo(fn_ptr: ?extern fn());
226 );
227
228 cases.add("comment after integer literal",
229 \\#define SDL_INIT_VIDEO 0x00000020 /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
230 ,
231 \\pub const SDL_INIT_VIDEO = 32;
232 );
233
234 cases.add("u integer suffix after hex literal",
235 \\#define SDL_INIT_VIDEO 0x00000020u /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
236 ,
237 \\pub const SDL_INIT_VIDEO = c_uint(32);
238 );
239
240 cases.add("l integer suffix after hex literal",
241 \\#define SDL_INIT_VIDEO 0x00000020l /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
242 ,
243 \\pub const SDL_INIT_VIDEO = c_long(32);
244 );
245
246 cases.add("ul integer suffix after hex literal",
247 \\#define SDL_INIT_VIDEO 0x00000020ul /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
248 ,
249 \\pub const SDL_INIT_VIDEO = c_ulong(32);
250 );
251
252 cases.add("lu integer suffix after hex literal",
253 \\#define SDL_INIT_VIDEO 0x00000020lu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
254 ,
255 \\pub const SDL_INIT_VIDEO = c_ulong(32);
256 );
257
258 cases.add("ll integer suffix after hex literal",
259 \\#define SDL_INIT_VIDEO 0x00000020ll /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
260 ,
261 \\pub const SDL_INIT_VIDEO = c_longlong(32);
262 );
263
264 cases.add("ull integer suffix after hex literal",
265 \\#define SDL_INIT_VIDEO 0x00000020ull /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
266 ,
267 \\pub const SDL_INIT_VIDEO = c_ulonglong(32);
268 );
269
270 cases.add("llu integer suffix after hex literal",
271 \\#define SDL_INIT_VIDEO 0x00000020llu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
272 ,
273 \\pub const SDL_INIT_VIDEO = c_ulonglong(32);
274 );
275
276 cases.add("zig keywords in C code",
277 \\struct comptime {
278 \\ int defer;
279 \\};
280 ,
281 \\pub const struct_comptime = extern struct {
282 \\ @"defer": c_int,
283 \\};
284 ,
285 \\pub const @"comptime" = struct_comptime;
286 );
287
288 cases.add("macro defines string literal with octal",
289 \\#define FOO "aoeu\023 derp"
290 \\#define FOO2 "aoeu\0234 derp"
291 \\#define FOO_CHAR '\077'
292 ,
293 \\pub const FOO = c"aoeu\x13 derp";
294 ,
295 \\pub const FOO2 = c"aoeu\x134 derp";
296 ,
297 \\pub const FOO_CHAR = 63;
298 );
299}
test/parseh.zig deleted-299
...@@ -1,299 +0,0 @@
1const tests = @import("tests.zig");
2
3pub fn addCases(cases: &tests.ParseHContext) {
4 cases.addAllowWarnings("simple data types",
5 \\#include <stdint.h>
6 \\int foo(char a, unsigned char b, signed char c);
7 \\int foo(char a, unsigned char b, signed char c); // test a duplicate prototype
8 \\void bar(uint8_t a, uint16_t b, uint32_t c, uint64_t d);
9 \\void baz(int8_t a, int16_t b, int32_t c, int64_t d);
10 ,
11 \\pub extern fn foo(a: u8, b: u8, c: i8) -> c_int;
12 ,
13 \\pub extern fn bar(a: u8, b: u16, c: u32, d: u64);
14 ,
15 \\pub extern fn baz(a: i8, b: i16, c: i32, d: i64);
16 );
17
18 cases.add("noreturn attribute",
19 \\void foo(void) __attribute__((noreturn));
20 ,
21 \\pub extern fn foo() -> noreturn;
22 );
23
24 cases.add("simple function",
25 \\int abs(int a) {
26 \\ return a < 0 ? -a : a;
27 \\}
28 ,
29 \\export fn abs(a: c_int) -> c_int {
30 \\ return if (a < 0) -a else a;
31 \\}
32 );
33
34 cases.add("enums",
35 \\enum Foo {
36 \\ FooA,
37 \\ FooB,
38 \\ Foo1,
39 \\};
40 ,
41 \\pub const enum_Foo = extern enum {
42 \\ A,
43 \\ B,
44 \\ @"1",
45 \\};
46 ,
47 \\pub const FooA = enum_Foo.A;
48 ,
49 \\pub const FooB = enum_Foo.B;
50 ,
51 \\pub const Foo1 = enum_Foo.@"1";
52 ,
53 \\pub const Foo = enum_Foo;
54 );
55
56 cases.add("restrict -> noalias",
57 \\void foo(void *restrict bar, void *restrict);
58 ,
59 \\pub extern fn foo(noalias bar: ?&c_void, noalias arg1: ?&c_void);
60 );
61
62 cases.add("simple struct",
63 \\struct Foo {
64 \\ int x;
65 \\ char *y;
66 \\};
67 ,
68 \\const struct_Foo = extern struct {
69 \\ x: c_int,
70 \\ y: ?&u8,
71 \\};
72 ,
73 \\pub const Foo = struct_Foo;
74 );
75
76 cases.add("qualified struct and enum",
77 \\struct Foo {
78 \\ int x;
79 \\ int y;
80 \\};
81 \\enum Bar {
82 \\ BarA,
83 \\ BarB,
84 \\};
85 \\void func(struct Foo *a, enum Bar **b);
86 ,
87 \\pub const struct_Foo = extern struct {
88 \\ x: c_int,
89 \\ y: c_int,
90 \\};
91 ,
92 \\pub const enum_Bar = extern enum {
93 \\ A,
94 \\ B,
95 \\};
96 ,
97 \\pub const BarA = enum_Bar.A;
98 ,
99 \\pub const BarB = enum_Bar.B;
100 ,
101 \\pub extern fn func(a: ?&struct_Foo, b: ?&?&enum_Bar);
102 ,
103 \\pub const Foo = struct_Foo;
104 ,
105 \\pub const Bar = enum_Bar;
106 );
107
108 cases.add("constant size array",
109 \\void func(int array[20]);
110 ,
111 \\pub extern fn func(array: ?&c_int);
112 );
113
114 cases.add("self referential struct with function pointer",
115 \\struct Foo {
116 \\ void (*derp)(struct Foo *foo);
117 \\};
118 ,
119 \\pub const struct_Foo = extern struct {
120 \\ derp: ?extern fn(?&struct_Foo),
121 \\};
122 ,
123 \\pub const Foo = struct_Foo;
124 );
125
126 cases.add("struct prototype used in func",
127 \\struct Foo;
128 \\struct Foo *some_func(struct Foo *foo, int x);
129 ,
130 \\pub const struct_Foo = @OpaqueType();
131 ,
132 \\pub extern fn some_func(foo: ?&struct_Foo, x: c_int) -> ?&struct_Foo;
133 ,
134 \\pub const Foo = struct_Foo;
135 );
136
137 cases.add("#define a char literal",
138 \\#define A_CHAR 'a'
139 ,
140 \\pub const A_CHAR = 97;
141 );
142
143 cases.add("#define an unsigned integer literal",
144 \\#define CHANNEL_COUNT 24
145 ,
146 \\pub const CHANNEL_COUNT = 24;
147 );
148
149 cases.add("#define referencing another #define",
150 \\#define THING2 THING1
151 \\#define THING1 1234
152 ,
153 \\pub const THING1 = 1234;
154 ,
155 \\pub const THING2 = THING1;
156 );
157
158 cases.add("variables",
159 \\extern int extern_var;
160 \\static const int int_var = 13;
161 ,
162 \\pub extern var extern_var: c_int;
163 ,
164 \\pub const int_var: c_int = 13;
165 );
166
167 cases.add("circular struct definitions",
168 \\struct Bar;
169 \\
170 \\struct Foo {
171 \\ struct Bar *next;
172 \\};
173 \\
174 \\struct Bar {
175 \\ struct Foo *next;
176 \\};
177 ,
178 \\pub const struct_Bar = extern struct {
179 \\ next: ?&struct_Foo,
180 \\};
181 ,
182 \\pub const struct_Foo = extern struct {
183 \\ next: ?&struct_Bar,
184 \\};
185 );
186
187 cases.add("typedef void",
188 \\typedef void Foo;
189 \\Foo fun(Foo *a);
190 ,
191 \\pub const Foo = c_void;
192 ,
193 \\pub extern fn fun(a: ?&Foo) -> Foo;
194 );
195
196 cases.add("generate inline func for #define global extern fn",
197 \\extern void (*fn_ptr)(void);
198 \\#define foo fn_ptr
199 \\
200 \\extern char (*fn_ptr2)(int, float);
201 \\#define bar fn_ptr2
202 ,
203 \\pub extern var fn_ptr: ?extern fn();
204 ,
205 \\pub inline fn foo() {
206 \\ ??fn_ptr()
207 \\}
208 ,
209 \\pub extern var fn_ptr2: ?extern fn(c_int, f32) -> u8;
210 ,
211 \\pub inline fn bar(arg0: c_int, arg1: f32) -> u8 {
212 \\ ??fn_ptr2(arg0, arg1)
213 \\}
214 );
215
216 cases.add("#define string",
217 \\#define foo "a string"
218 ,
219 \\pub const foo = c"a string";
220 );
221
222 cases.add("__cdecl doesn't mess up function pointers",
223 \\void foo(void (__cdecl *fn_ptr)(void));
224 ,
225 \\pub extern fn foo(fn_ptr: ?extern fn());
226 );
227
228 cases.add("comment after integer literal",
229 \\#define SDL_INIT_VIDEO 0x00000020 /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
230 ,
231 \\pub const SDL_INIT_VIDEO = 32;
232 );
233
234 cases.add("u integer suffix after hex literal",
235 \\#define SDL_INIT_VIDEO 0x00000020u /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
236 ,
237 \\pub const SDL_INIT_VIDEO = c_uint(32);
238 );
239
240 cases.add("l integer suffix after hex literal",
241 \\#define SDL_INIT_VIDEO 0x00000020l /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
242 ,
243 \\pub const SDL_INIT_VIDEO = c_long(32);
244 );
245
246 cases.add("ul integer suffix after hex literal",
247 \\#define SDL_INIT_VIDEO 0x00000020ul /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
248 ,
249 \\pub const SDL_INIT_VIDEO = c_ulong(32);
250 );
251
252 cases.add("lu integer suffix after hex literal",
253 \\#define SDL_INIT_VIDEO 0x00000020lu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
254 ,
255 \\pub const SDL_INIT_VIDEO = c_ulong(32);
256 );
257
258 cases.add("ll integer suffix after hex literal",
259 \\#define SDL_INIT_VIDEO 0x00000020ll /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
260 ,
261 \\pub const SDL_INIT_VIDEO = c_longlong(32);
262 );
263
264 cases.add("ull integer suffix after hex literal",
265 \\#define SDL_INIT_VIDEO 0x00000020ull /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
266 ,
267 \\pub const SDL_INIT_VIDEO = c_ulonglong(32);
268 );
269
270 cases.add("llu integer suffix after hex literal",
271 \\#define SDL_INIT_VIDEO 0x00000020llu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
272 ,
273 \\pub const SDL_INIT_VIDEO = c_ulonglong(32);
274 );
275
276 cases.add("zig keywords in C code",
277 \\struct comptime {
278 \\ int defer;
279 \\};
280 ,
281 \\pub const struct_comptime = extern struct {
282 \\ @"defer": c_int,
283 \\};
284 ,
285 \\pub const @"comptime" = struct_comptime;
286 );
287
288 cases.add("macro defines string literal with octal",
289 \\#define FOO "aoeu\023 derp"
290 \\#define FOO2 "aoeu\0234 derp"
291 \\#define FOO_CHAR '\077'
292 ,
293 \\pub const FOO = c"aoeu\x13 derp";
294 ,
295 \\pub const FOO2 = c"aoeu\x134 derp";
296 ,
297 \\pub const FOO_CHAR = 63;
298 );
299}
test/tests.zig+24-24
...@@ -17,7 +17,7 @@ const build_examples = @import("build_examples.zig");...@@ -17,7 +17,7 @@ const build_examples = @import("build_examples.zig");
17const compile_errors = @import("compile_errors.zig");17const compile_errors = @import("compile_errors.zig");
18const assemble_and_link = @import("assemble_and_link.zig");18const assemble_and_link = @import("assemble_and_link.zig");
19const debug_safety = @import("debug_safety.zig");19const debug_safety = @import("debug_safety.zig");
20const parseh = @import("parseh.zig");20const parsec = @import("parsec.zig");
2121
22const TestTarget = struct {22const TestTarget = struct {
23 os: builtin.Os,23 os: builtin.Os,
...@@ -115,16 +115,16 @@ pub fn addAssembleAndLinkTests(b: &build.Builder, test_filter: ?[]const u8) -> &...@@ -115,16 +115,16 @@ pub fn addAssembleAndLinkTests(b: &build.Builder, test_filter: ?[]const u8) -> &
115 return cases.step;115 return cases.step;
116}116}
117117
118pub fn addParseHTests(b: &build.Builder, test_filter: ?[]const u8) -> &build.Step {118pub fn addParseCTests(b: &build.Builder, test_filter: ?[]const u8) -> &build.Step {
119 const cases = %%b.allocator.create(ParseHContext);119 const cases = %%b.allocator.create(ParseCContext);
120 *cases = ParseHContext {120 *cases = ParseCContext {
121 .b = b,121 .b = b,
122 .step = b.step("test-parseh", "Run the C header file parsing tests"),122 .step = b.step("test-parsec", "Run the C header file parsing tests"),
123 .test_index = 0,123 .test_index = 0,
124 .test_filter = test_filter,124 .test_filter = test_filter,
125 };125 };
126126
127 parseh.addCases(cases);127 parsec.addCases(cases);
128128
129 return cases.step;129 return cases.step;
130}130}
...@@ -752,7 +752,7 @@ pub const BuildExamplesContext = struct {...@@ -752,7 +752,7 @@ pub const BuildExamplesContext = struct {
752 }752 }
753};753};
754754
755pub const ParseHContext = struct {755pub const ParseCContext = struct {
756 b: &build.Builder,756 b: &build.Builder,
757 step: &build.Step,757 step: &build.Step,
758 test_index: usize,758 test_index: usize,
...@@ -781,18 +781,18 @@ pub const ParseHContext = struct {...@@ -781,18 +781,18 @@ pub const ParseHContext = struct {
781 }781 }
782 };782 };
783783
784 const ParseHCmpOutputStep = struct {784 const ParseCCmpOutputStep = struct {
785 step: build.Step,785 step: build.Step,
786 context: &ParseHContext,786 context: &ParseCContext,
787 name: []const u8,787 name: []const u8,
788 test_index: usize,788 test_index: usize,
789 case: &const TestCase,789 case: &const TestCase,
790790
791 pub fn create(context: &ParseHContext, name: []const u8, case: &const TestCase) -> &ParseHCmpOutputStep {791 pub fn create(context: &ParseCContext, name: []const u8, case: &const TestCase) -> &ParseCCmpOutputStep {
792 const allocator = context.b.allocator;792 const allocator = context.b.allocator;
793 const ptr = %%allocator.create(ParseHCmpOutputStep);793 const ptr = %%allocator.create(ParseCCmpOutputStep);
794 *ptr = ParseHCmpOutputStep {794 *ptr = ParseCCmpOutputStep {
795 .step = build.Step.init("ParseHCmpOutput", allocator, make),795 .step = build.Step.init("ParseCCmpOutput", allocator, make),
796 .context = context,796 .context = context,
797 .name = name,797 .name = name,
798 .test_index = context.test_index,798 .test_index = context.test_index,
...@@ -803,13 +803,13 @@ pub const ParseHContext = struct {...@@ -803,13 +803,13 @@ pub const ParseHContext = struct {
803 }803 }
804804
805 fn make(step: &build.Step) -> %void {805 fn make(step: &build.Step) -> %void {
806 const self = @fieldParentPtr(ParseHCmpOutputStep, "step", step);806 const self = @fieldParentPtr(ParseCCmpOutputStep, "step", step);
807 const b = self.context.b;807 const b = self.context.b;
808808
809 const root_src = %%os.path.join(b.allocator, b.cache_root, self.case.sources.items[0].filename);809 const root_src = %%os.path.join(b.allocator, b.cache_root, self.case.sources.items[0].filename);
810810
811 var zig_args = ArrayList([]const u8).init(b.allocator);811 var zig_args = ArrayList([]const u8).init(b.allocator);
812 %%zig_args.append("parseh");812 %%zig_args.append("parsec");
813 %%zig_args.append(b.pathFromRoot(root_src));813 %%zig_args.append(b.pathFromRoot(root_src));
814814
815 %%io.stderr.printf("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name);815 %%io.stderr.printf("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name);
...@@ -855,7 +855,7 @@ pub const ParseHContext = struct {...@@ -855,7 +855,7 @@ pub const ParseHContext = struct {
855855
856 if (stderr.len != 0 and !self.case.allow_warnings) {856 if (stderr.len != 0 and !self.case.allow_warnings) {
857 %%io.stderr.printf(857 %%io.stderr.printf(
858 \\====== parseh emitted warnings: ============858 \\====== parsec emitted warnings: ============
859 \\{}859 \\{}
860 \\============================================860 \\============================================
861 \\861 \\
...@@ -888,7 +888,7 @@ pub const ParseHContext = struct {...@@ -888,7 +888,7 @@ pub const ParseHContext = struct {
888 %%io.stderr.printf("\n");888 %%io.stderr.printf("\n");
889 }889 }
890890
891 pub fn create(self: &ParseHContext, allow_warnings: bool, name: []const u8,891 pub fn create(self: &ParseCContext, allow_warnings: bool, name: []const u8,
892 source: []const u8, expected_lines: ...) -> &TestCase892 source: []const u8, expected_lines: ...) -> &TestCase
893 {893 {
894 const tc = %%self.b.allocator.create(TestCase);894 const tc = %%self.b.allocator.create(TestCase);
...@@ -906,32 +906,32 @@ pub const ParseHContext = struct {...@@ -906,32 +906,32 @@ pub const ParseHContext = struct {
906 return tc;906 return tc;
907 }907 }
908908
909 pub fn add(self: &ParseHContext, name: []const u8, source: []const u8, expected_lines: ...) {909 pub fn add(self: &ParseCContext, name: []const u8, source: []const u8, expected_lines: ...) {
910 const tc = self.create(false, name, source, expected_lines);910 const tc = self.create(false, name, source, expected_lines);
911 self.addCase(tc);911 self.addCase(tc);
912 }912 }
913913
914 pub fn addAllowWarnings(self: &ParseHContext, name: []const u8, source: []const u8, expected_lines: ...) {914 pub fn addAllowWarnings(self: &ParseCContext, name: []const u8, source: []const u8, expected_lines: ...) {
915 const tc = self.create(true, name, source, expected_lines);915 const tc = self.create(true, name, source, expected_lines);
916 self.addCase(tc);916 self.addCase(tc);
917 }917 }
918918
919 pub fn addCase(self: &ParseHContext, case: &const TestCase) {919 pub fn addCase(self: &ParseCContext, case: &const TestCase) {
920 const b = self.b;920 const b = self.b;
921921
922 const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "parseh {}", case.name);922 const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "parsec {}", case.name);
923 if (self.test_filter) |filter| {923 if (self.test_filter) |filter| {
924 if (mem.indexOf(u8, annotated_case_name, filter) == null)924 if (mem.indexOf(u8, annotated_case_name, filter) == null)
925 return;925 return;
926 }926 }
927927
928 const parseh_and_cmp = ParseHCmpOutputStep.create(self, annotated_case_name, case);928 const parsec_and_cmp = ParseCCmpOutputStep.create(self, annotated_case_name, case);
929 self.step.dependOn(&parseh_and_cmp.step);929 self.step.dependOn(&parsec_and_cmp.step);
930930
931 for (case.sources.toSliceConst()) |src_file| {931 for (case.sources.toSliceConst()) |src_file| {
932 const expanded_src_path = %%os.path.join(b.allocator, b.cache_root, src_file.filename);932 const expanded_src_path = %%os.path.join(b.allocator, b.cache_root, src_file.filename);
933 const write_src = b.addWriteFile(expanded_src_path, src_file.source);933 const write_src = b.addWriteFile(expanded_src_path, src_file.source);
934 parseh_and_cmp.step.dependOn(&write_src.step);934 parsec_and_cmp.step.dependOn(&write_src.step);
935 }935 }
936 }936 }
937};937};