Branch data Line data Source code
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 : : #include "all_types.hpp"
8 : : #include "analyze.hpp"
9 : : #include "c_tokenizer.hpp"
10 : : #include "error.hpp"
11 : : #include "ir.hpp"
12 : : #include "os.hpp"
13 : : #include "translate_c.hpp"
14 : : #include "parser.hpp"
15 : : #include "zig_clang.h"
16 : :
17 : : #if __GNUC__ >= 8
18 : : #pragma GCC diagnostic push
19 : : #pragma GCC diagnostic ignored "-Wclass-memaccess"
20 : : #endif
21 : :
22 : : #include <clang/Frontend/ASTUnit.h>
23 : : #include <clang/Frontend/CompilerInstance.h>
24 : : #include <clang/AST/Expr.h>
25 : :
26 : : #if __GNUC__ >= 8
27 : : #pragma GCC diagnostic pop
28 : : #endif
29 : :
30 : : #include <string.h>
31 : :
32 : : struct Alias {
33 : : Buf *new_name;
34 : : Buf *canon_name;
35 : : };
36 : :
37 : : enum TransScopeId {
38 : : TransScopeIdSwitch,
39 : : TransScopeIdVar,
40 : : TransScopeIdBlock,
41 : : TransScopeIdRoot,
42 : : TransScopeIdWhile,
43 : : };
44 : :
45 : : struct TransScope {
46 : : TransScopeId id;
47 : : TransScope *parent;
48 : : };
49 : :
50 : : struct TransScopeSwitch {
51 : : TransScope base;
52 : : AstNode *switch_node;
53 : : uint32_t case_index;
54 : : bool found_default;
55 : : Buf *end_label_name;
56 : : };
57 : :
58 : : struct TransScopeVar {
59 : : TransScope base;
60 : : Buf *c_name;
61 : : Buf *zig_name;
62 : : };
63 : :
64 : : struct TransScopeBlock {
65 : : TransScope base;
66 : : AstNode *node;
67 : : };
68 : :
69 : : struct TransScopeRoot {
70 : : TransScope base;
71 : : };
72 : :
73 : : struct TransScopeWhile {
74 : : TransScope base;
75 : : AstNode *node;
76 : : };
77 : :
78 : : struct Context {
79 : : AstNode *root;
80 : : VisibMod visib_mod;
81 : : bool want_export;
82 : : HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table;
83 : : HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table;
84 : : HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> global_table;
85 : : ZigClangSourceManager *source_manager;
86 : : ZigList<Alias> aliases;
87 : : bool warnings_on;
88 : :
89 : : CodeGen *codegen;
90 : : ZigClangASTContext *ctx;
91 : :
92 : : TransScopeRoot *global_scope;
93 : : HashMap<Buf *, bool, buf_hash, buf_eql_buf> ptr_params;
94 : : };
95 : :
96 : : enum ResultUsed {
97 : : ResultUsedNo,
98 : : ResultUsedYes,
99 : : };
100 : :
101 : : enum TransLRValue {
102 : : TransLValue,
103 : : TransRValue,
104 : : };
105 : :
106 : : static TransScopeRoot *trans_scope_root_create(Context *c);
107 : : static TransScopeWhile *trans_scope_while_create(Context *c, TransScope *parent_scope);
108 : : static TransScopeBlock *trans_scope_block_create(Context *c, TransScope *parent_scope);
109 : : static TransScopeVar *trans_scope_var_create(Context *c, TransScope *parent_scope, Buf *wanted_name);
110 : : static TransScopeSwitch *trans_scope_switch_create(Context *c, TransScope *parent_scope);
111 : :
112 : : static TransScopeBlock *trans_scope_block_find(TransScope *scope);
113 : :
114 : : static AstNode *resolve_record_decl(Context *c, const ZigClangRecordDecl *record_decl);
115 : : static AstNode *resolve_enum_decl(Context *c, const ZigClangEnumDecl *enum_decl);
116 : : static AstNode *resolve_typedef_decl(Context *c, const ZigClangTypedefNameDecl *typedef_decl);
117 : :
118 : : static int trans_stmt_extra(Context *c, TransScope *scope, const ZigClangStmt *stmt,
119 : : ResultUsed result_used, TransLRValue lrval,
120 : : AstNode **out_node, TransScope **out_child_scope,
121 : : TransScope **out_node_scope);
122 : : static TransScope *trans_stmt(Context *c, TransScope *scope, const ZigClangStmt *stmt, AstNode **out_node);
123 : : static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const ZigClangExpr *expr, TransLRValue lrval);
124 : : static AstNode *trans_type(Context *c, const ZigClangType *ty, ZigClangSourceLocation source_loc);
125 : : static AstNode *trans_qual_type(Context *c, ZigClangQualType qt, ZigClangSourceLocation source_loc);
126 : : static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *scope,
127 : : const ZigClangExpr *expr, TransLRValue lrval);
128 : : static AstNode *trans_ap_value(Context *c, const ZigClangAPValue *ap_value, ZigClangQualType qt,
129 : : ZigClangSourceLocation source_loc);
130 : : static bool c_is_unsigned_integer(Context *c, ZigClangQualType qt);
131 : :
132 : 0 : static const ZigClangAPSInt *bitcast(const llvm::APSInt *src) {
133 : 0 : return reinterpret_cast<const ZigClangAPSInt *>(src);
134 : : }
135 : :
136 : 0 : static const ZigClangAPValue *bitcast(const clang::APValue *src) {
137 : 0 : return reinterpret_cast<const ZigClangAPValue *>(src);
138 : : }
139 : :
140 : 0 : static const ZigClangStmt *bitcast(const clang::Stmt *src) {
141 : 0 : return reinterpret_cast<const ZigClangStmt *>(src);
142 : : }
143 : :
144 : 0 : static const ZigClangExpr *bitcast(const clang::Expr *src) {
145 : 0 : return reinterpret_cast<const ZigClangExpr *>(src);
146 : : }
147 : :
148 : 0 : static ZigClangSourceLocation bitcast(clang::SourceLocation src) {
149 : : ZigClangSourceLocation dest;
150 : 0 : memcpy(&dest, static_cast<void *>(&src), sizeof(ZigClangSourceLocation));
151 : 0 : return dest;
152 : : }
153 : 0 : static ZigClangQualType bitcast(clang::QualType src) {
154 : : ZigClangQualType dest;
155 : 0 : memcpy(&dest, static_cast<void *>(&src), sizeof(ZigClangQualType));
156 : 0 : return dest;
157 : : }
158 : : //static clang::QualType bitcast(ZigClangQualType src) {
159 : : // clang::QualType dest;
160 : : // memcpy(&dest, static_cast<void *>(&src), sizeof(ZigClangQualType));
161 : : // return dest;
162 : : //}
163 : :
164 : : ATTRIBUTE_PRINTF(3, 4)
165 : 0 : static void emit_warning(Context *c, ZigClangSourceLocation sl, const char *format, ...) {
166 [ # # ]: 0 : if (!c->warnings_on) {
167 : 0 : return;
168 : : }
169 : :
170 : : va_list ap;
171 : 0 : va_start(ap, format);
172 : 0 : Buf *msg = buf_vprintf(format, ap);
173 : 0 : va_end(ap);
174 : :
175 : 0 : const char *filename_bytes = ZigClangSourceManager_getFilename(c->source_manager,
176 : 0 : ZigClangSourceManager_getSpellingLoc(c->source_manager, sl));
177 : : Buf *path;
178 [ # # ]: 0 : if (filename_bytes) {
179 : 0 : path = buf_create_from_str(filename_bytes);
180 : : } else {
181 : 0 : path = buf_sprintf("(no file)");
182 : : }
183 : 0 : unsigned line = ZigClangSourceManager_getSpellingLineNumber(c->source_manager, sl);
184 : 0 : unsigned column = ZigClangSourceManager_getSpellingColumnNumber(c->source_manager, sl);
185 : 0 : fprintf(stderr, "%s:%u:%u: warning: %s\n", buf_ptr(path), line, column, buf_ptr(msg));
186 : : }
187 : :
188 : 0 : static void add_global_weak_alias(Context *c, Buf *new_name, Buf *canon_name) {
189 : 0 : Alias *alias = c->aliases.add_one();
190 : 0 : alias->new_name = new_name;
191 : 0 : alias->canon_name = canon_name;
192 : 0 : }
193 : :
194 : 0 : static Buf *trans_lookup_zig_symbol(Context *c, TransScope *scope, Buf *c_symbol_name) {
195 [ # # ]: 0 : while (scope != nullptr) {
196 [ # # ]: 0 : if (scope->id == TransScopeIdVar) {
197 : 0 : TransScopeVar *var_scope = (TransScopeVar *)scope;
198 [ # # ]: 0 : if (buf_eql_buf(var_scope->c_name, c_symbol_name)) {
199 : 0 : return var_scope->zig_name;
200 : : }
201 : : }
202 : 0 : scope = scope->parent;
203 : : }
204 : 0 : return c_symbol_name;
205 : : }
206 : :
207 : 0 : static AstNode * trans_create_node(Context *c, NodeType id) {
208 : 0 : AstNode *node = allocate<AstNode>(1);
209 : 0 : node->type = id;
210 : : // TODO line/column. mapping to C file??
211 : 0 : return node;
212 : : }
213 : :
214 : 0 : static AstNode *trans_create_node_break(Context *c, Buf *label_name, AstNode *value_node) {
215 : 0 : AstNode *node = trans_create_node(c, NodeTypeBreak);
216 : 0 : node->data.break_expr.name = label_name;
217 : 0 : node->data.break_expr.expr = value_node;
218 : 0 : return node;
219 : : }
220 : :
221 : 0 : static AstNode *trans_create_node_return(Context *c, AstNode *value_node) {
222 : 0 : AstNode *node = trans_create_node(c, NodeTypeReturnExpr);
223 : 0 : node->data.return_expr.kind = ReturnKindUnconditional;
224 : 0 : node->data.return_expr.expr = value_node;
225 : 0 : return node;
226 : : }
227 : :
228 : 0 : static AstNode *trans_create_node_if(Context *c, AstNode *cond_node, AstNode *then_node, AstNode *else_node) {
229 : 0 : AstNode *node = trans_create_node(c, NodeTypeIfBoolExpr);
230 : 0 : node->data.if_bool_expr.condition = cond_node;
231 : 0 : node->data.if_bool_expr.then_block = then_node;
232 : 0 : node->data.if_bool_expr.else_node = else_node;
233 : 0 : return node;
234 : : }
235 : :
236 : 0 : static AstNode *trans_create_node_float_lit(Context *c, double value) {
237 : 0 : AstNode *node = trans_create_node(c, NodeTypeFloatLiteral);
238 : 0 : node->data.float_literal.bigfloat = allocate<BigFloat>(1);
239 : 0 : bigfloat_init_64(node->data.float_literal.bigfloat, value);
240 : 0 : return node;
241 : : }
242 : :
243 : 0 : static AstNode *trans_create_node_symbol(Context *c, Buf *name) {
244 : 0 : AstNode *node = trans_create_node(c, NodeTypeSymbol);
245 : 0 : node->data.symbol_expr.symbol = name;
246 : 0 : return node;
247 : : }
248 : :
249 : 0 : static AstNode *trans_create_node_symbol_str(Context *c, const char *name) {
250 : 0 : return trans_create_node_symbol(c, buf_create_from_str(name));
251 : : }
252 : :
253 : 0 : static AstNode *trans_create_node_builtin_fn_call(Context *c, Buf *name) {
254 : 0 : AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
255 : 0 : node->data.fn_call_expr.fn_ref_expr = trans_create_node_symbol(c, name);
256 : 0 : node->data.fn_call_expr.is_builtin = true;
257 : 0 : return node;
258 : : }
259 : :
260 : 0 : static AstNode *trans_create_node_builtin_fn_call_str(Context *c, const char *name) {
261 : 0 : return trans_create_node_builtin_fn_call(c, buf_create_from_str(name));
262 : : }
263 : :
264 : 0 : static AstNode *trans_create_node_opaque(Context *c) {
265 : 0 : return trans_create_node_builtin_fn_call_str(c, "OpaqueType");
266 : : }
267 : :
268 : 0 : static AstNode *trans_create_node_fn_call_1(Context *c, AstNode *fn_ref_expr, AstNode *arg1) {
269 : 0 : AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
270 : 0 : node->data.fn_call_expr.fn_ref_expr = fn_ref_expr;
271 : 0 : node->data.fn_call_expr.params.append(arg1);
272 : 0 : return node;
273 : : }
274 : :
275 : 0 : static AstNode *trans_create_node_field_access(Context *c, AstNode *container, Buf *field_name) {
276 : 0 : AstNode *node = trans_create_node(c, NodeTypeFieldAccessExpr);
277 [ # # ]: 0 : if (container->type == NodeTypeSymbol) {
278 [ # # ]: 0 : assert(container->data.symbol_expr.symbol != nullptr);
279 : : }
280 : 0 : node->data.field_access_expr.struct_expr = container;
281 : 0 : node->data.field_access_expr.field_name = field_name;
282 : 0 : return node;
283 : : }
284 : :
285 : 0 : static AstNode *trans_create_node_field_access_str(Context *c, AstNode *container, const char *field_name) {
286 : 0 : return trans_create_node_field_access(c, container, buf_create_from_str(field_name));
287 : : }
288 : :
289 : 0 : static AstNode *trans_create_node_ptr_deref(Context *c, AstNode *child_node) {
290 : 0 : AstNode *node = trans_create_node(c, NodeTypePtrDeref);
291 : 0 : node->data.ptr_deref_expr.target = child_node;
292 : 0 : return node;
293 : : }
294 : :
295 : 0 : static AstNode *trans_create_node_prefix_op(Context *c, PrefixOp op, AstNode *child_node) {
296 : 0 : AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);
297 : 0 : node->data.prefix_op_expr.prefix_op = op;
298 : 0 : node->data.prefix_op_expr.primary_expr = child_node;
299 : 0 : return node;
300 : : }
301 : :
302 : 0 : static AstNode *trans_create_node_unwrap_null(Context *c, AstNode *child_node) {
303 : 0 : AstNode *node = trans_create_node(c, NodeTypeUnwrapOptional);
304 : 0 : node->data.unwrap_optional.expr = child_node;
305 : 0 : return node;
306 : : }
307 : :
308 : 0 : static AstNode *trans_create_node_bin_op(Context *c, AstNode *lhs_node, BinOpType op, AstNode *rhs_node) {
309 : 0 : AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
310 : 0 : node->data.bin_op_expr.op1 = lhs_node;
311 : 0 : node->data.bin_op_expr.bin_op = op;
312 : 0 : node->data.bin_op_expr.op2 = rhs_node;
313 : 0 : return node;
314 : : }
315 : :
316 : 0 : static AstNode *maybe_suppress_result(Context *c, ResultUsed result_used, AstNode *node) {
317 [ # # ]: 0 : if (result_used == ResultUsedYes) return node;
318 : 0 : return trans_create_node_bin_op(c,
319 : : trans_create_node_symbol_str(c, "_"),
320 : : BinOpTypeAssign,
321 : 0 : node);
322 : : }
323 : :
324 : 0 : static TokenId ptr_len_to_token_id(PtrLen ptr_len) {
325 [ # # # # ]: 0 : switch (ptr_len) {
326 : 0 : case PtrLenSingle:
327 : 0 : return TokenIdStar;
328 : 0 : case PtrLenUnknown:
329 : 0 : return TokenIdBracketStarBracket;
330 : 0 : case PtrLenC:
331 : 0 : return TokenIdBracketStarCBracket;
332 : : }
333 : 0 : zig_unreachable();
334 : : }
335 : :
336 : 0 : static AstNode *trans_create_node_ptr_type(Context *c, bool is_const, bool is_volatile, AstNode *child_node, PtrLen ptr_len) {
337 : 0 : AstNode *node = trans_create_node(c, NodeTypePointerType);
338 : 0 : node->data.pointer_type.star_token = allocate<ZigToken>(1);
339 : 0 : node->data.pointer_type.star_token->id = ptr_len_to_token_id(ptr_len);
340 : 0 : node->data.pointer_type.is_const = is_const;
341 : 0 : node->data.pointer_type.is_volatile = is_volatile;
342 : 0 : node->data.pointer_type.op_expr = child_node;
343 : 0 : return node;
344 : : }
345 : :
346 : 0 : static AstNode *trans_create_node_addr_of(Context *c, AstNode *child_node) {
347 : 0 : AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);
348 : 0 : node->data.prefix_op_expr.prefix_op = PrefixOpAddrOf;
349 : 0 : node->data.prefix_op_expr.primary_expr = child_node;
350 : 0 : return node;
351 : : }
352 : :
353 : 0 : static AstNode *trans_create_node_bool(Context *c, bool value) {
354 : 0 : AstNode *bool_node = trans_create_node(c, NodeTypeBoolLiteral);
355 : 0 : bool_node->data.bool_literal.value = value;
356 : 0 : return bool_node;
357 : : }
358 : :
359 : 0 : static AstNode *trans_create_node_str_lit_c(Context *c, Buf *buf) {
360 : 0 : AstNode *node = trans_create_node(c, NodeTypeStringLiteral);
361 : 0 : node->data.string_literal.buf = buf;
362 : 0 : node->data.string_literal.c = true;
363 : 0 : return node;
364 : : }
365 : :
366 : 0 : static AstNode *trans_create_node_str_lit_non_c(Context *c, Buf *buf) {
367 : 0 : AstNode *node = trans_create_node(c, NodeTypeStringLiteral);
368 : 0 : node->data.string_literal.buf = buf;
369 : 0 : node->data.string_literal.c = false;
370 : 0 : return node;
371 : : }
372 : :
373 : 0 : static AstNode *trans_create_node_unsigned_negative(Context *c, uint64_t x, bool is_negative) {
374 : 0 : AstNode *node = trans_create_node(c, NodeTypeIntLiteral);
375 : 0 : node->data.int_literal.bigint = allocate<BigInt>(1);
376 : 0 : bigint_init_data(node->data.int_literal.bigint, &x, 1, is_negative);
377 : 0 : return node;
378 : : }
379 : :
380 : 0 : static AstNode *trans_create_node_unsigned(Context *c, uint64_t x) {
381 : 0 : return trans_create_node_unsigned_negative(c, x, false);
382 : : }
383 : :
384 : 0 : static AstNode *trans_create_node_cast(Context *c, AstNode *dest, AstNode *src) {
385 : 0 : AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
386 : 0 : node->data.fn_call_expr.fn_ref_expr = dest;
387 : 0 : node->data.fn_call_expr.params.resize(1);
388 : 0 : node->data.fn_call_expr.params.items[0] = src;
389 : 0 : return node;
390 : : }
391 : :
392 : 0 : static AstNode *trans_create_node_unsigned_negative_type(Context *c, uint64_t x, bool is_negative,
393 : : const char *type_name)
394 : : {
395 : 0 : AstNode *lit_node = trans_create_node_unsigned_negative(c, x, is_negative);
396 : 0 : return trans_create_node_cast(c, trans_create_node_symbol_str(c, type_name), lit_node);
397 : : }
398 : :
399 : 0 : static AstNode *trans_create_node_array_type(Context *c, AstNode *size_node, AstNode *child_type_node) {
400 : 0 : AstNode *node = trans_create_node(c, NodeTypeArrayType);
401 : 0 : node->data.array_type.size = size_node;
402 : 0 : node->data.array_type.child_type = child_type_node;
403 : 0 : return node;
404 : : }
405 : :
406 : 0 : static AstNode *trans_create_node_var_decl(Context *c, VisibMod visib_mod, bool is_const, Buf *var_name,
407 : : AstNode *type_node, AstNode *init_node)
408 : : {
409 : 0 : AstNode *node = trans_create_node(c, NodeTypeVariableDeclaration);
410 : 0 : node->data.variable_declaration.visib_mod = visib_mod;
411 : 0 : node->data.variable_declaration.symbol = var_name;
412 : 0 : node->data.variable_declaration.is_const = is_const;
413 : 0 : node->data.variable_declaration.type = type_node;
414 : 0 : node->data.variable_declaration.expr = init_node;
415 : 0 : return node;
416 : : }
417 : :
418 : 0 : static AstNode *trans_create_node_var_decl_global(Context *c, bool is_const, Buf *var_name, AstNode *type_node,
419 : : AstNode *init_node)
420 : : {
421 : 0 : return trans_create_node_var_decl(c, c->visib_mod, is_const, var_name, type_node, init_node);
422 : : }
423 : :
424 : 0 : static AstNode *trans_create_node_var_decl_local(Context *c, bool is_const, Buf *var_name, AstNode *type_node,
425 : : AstNode *init_node)
426 : : {
427 : 0 : return trans_create_node_var_decl(c, VisibModPrivate, is_const, var_name, type_node, init_node);
428 : : }
429 : :
430 : 0 : static AstNode *trans_create_node_inline_fn(Context *c, Buf *fn_name, AstNode *ref_node, AstNode *src_proto_node) {
431 : 0 : AstNode *fn_def = trans_create_node(c, NodeTypeFnDef);
432 : 0 : AstNode *fn_proto = trans_create_node(c, NodeTypeFnProto);
433 : 0 : fn_proto->data.fn_proto.visib_mod = c->visib_mod;
434 : 0 : fn_proto->data.fn_proto.name = fn_name;
435 : 0 : fn_proto->data.fn_proto.fn_inline = FnInlineAlways;
436 : 0 : fn_proto->data.fn_proto.return_type = src_proto_node->data.fn_proto.return_type; // TODO ok for these to alias?
437 : :
438 : 0 : fn_def->data.fn_def.fn_proto = fn_proto;
439 : 0 : fn_proto->data.fn_proto.fn_def_node = fn_def;
440 : :
441 : 0 : AstNode *unwrap_node = trans_create_node_unwrap_null(c, ref_node);
442 : 0 : AstNode *fn_call_node = trans_create_node(c, NodeTypeFnCallExpr);
443 : 0 : fn_call_node->data.fn_call_expr.fn_ref_expr = unwrap_node;
444 : :
445 [ # # ]: 0 : for (size_t i = 0; i < src_proto_node->data.fn_proto.params.length; i += 1) {
446 : 0 : AstNode *src_param_node = src_proto_node->data.fn_proto.params.at(i);
447 : 0 : Buf *param_name = src_param_node->data.param_decl.name;
448 [ # # ]: 0 : if (!param_name) param_name = buf_sprintf("arg%" ZIG_PRI_usize "", i);
449 : :
450 : 0 : AstNode *dest_param_node = trans_create_node(c, NodeTypeParamDecl);
451 : 0 : dest_param_node->data.param_decl.name = param_name;
452 : 0 : dest_param_node->data.param_decl.type = src_param_node->data.param_decl.type;
453 : 0 : dest_param_node->data.param_decl.is_noalias = src_param_node->data.param_decl.is_noalias;
454 : 0 : fn_proto->data.fn_proto.params.append(dest_param_node);
455 : :
456 : 0 : fn_call_node->data.fn_call_expr.params.append(trans_create_node_symbol(c, param_name));
457 : :
458 : : }
459 : :
460 : 0 : AstNode *block = trans_create_node(c, NodeTypeBlock);
461 : 0 : block->data.block.statements.resize(1);
462 : 0 : block->data.block.statements.items[0] = trans_create_node_return(c, fn_call_node);
463 : :
464 : 0 : fn_def->data.fn_def.body = block;
465 : 0 : return fn_def;
466 : : }
467 : :
468 : 0 : static AstNode *trans_create_node_grouped_expr(Context *c, AstNode *child) {
469 : 0 : AstNode *node = trans_create_node(c, NodeTypeGroupedExpr);
470 : 0 : node->data.grouped_expr = child;
471 : 0 : return node;
472 : : }
473 : :
474 : 0 : static AstNode *get_global(Context *c, Buf *name) {
475 : : {
476 : 0 : auto entry = c->global_table.maybe_get(name);
477 [ # # ]: 0 : if (entry) {
478 : 0 : return entry->value;
479 : : }
480 : : }
481 : : {
482 : 0 : auto entry = c->macro_table.maybe_get(name);
483 [ # # ]: 0 : if (entry)
484 : 0 : return entry->value;
485 : : }
486 : : ZigType *type;
487 [ # # ]: 0 : if (get_primitive_type(c->codegen, name, &type) != ErrorPrimitiveTypeNotFound) {
488 : 0 : return trans_create_node_symbol(c, name);
489 : : }
490 : 0 : return nullptr;
491 : : }
492 : :
493 : 0 : static void add_top_level_decl(Context *c, Buf *name, AstNode *node) {
494 : 0 : c->global_table.put(name, node);
495 : 0 : c->root->data.container_decl.decls.append(node);
496 : 0 : }
497 : :
498 : 0 : static AstNode *add_global_var(Context *c, Buf *var_name, AstNode *value_node) {
499 : 0 : bool is_const = true;
500 : 0 : AstNode *type_node = nullptr;
501 : 0 : AstNode *node = trans_create_node_var_decl_global(c, is_const, var_name, type_node, value_node);
502 : 0 : add_top_level_decl(c, var_name, node);
503 : 0 : return node;
504 : : }
505 : :
506 : 0 : static AstNode *trans_create_node_apint(Context *c, const ZigClangAPSInt *aps_int) {
507 : 0 : AstNode *node = trans_create_node(c, NodeTypeIntLiteral);
508 : 0 : node->data.int_literal.bigint = allocate<BigInt>(1);
509 [ # # ][ # # ]: 0 : bool is_negative = ZigClangAPSInt_isSigned(aps_int) && ZigClangAPSInt_isNegative(aps_int);
510 [ # # ]: 0 : if (!is_negative) {
511 : 0 : bigint_init_data(node->data.int_literal.bigint,
512 : : ZigClangAPSInt_getRawData(aps_int),
513 : 0 : ZigClangAPSInt_getNumWords(aps_int),
514 : : false);
515 : 0 : return node;
516 : : }
517 : 0 : const ZigClangAPSInt *negated = ZigClangAPSInt_negate(aps_int);
518 : 0 : bigint_init_data(node->data.int_literal.bigint, ZigClangAPSInt_getRawData(negated),
519 : 0 : ZigClangAPSInt_getNumWords(negated), true);
520 : 0 : ZigClangAPSInt_free(negated);
521 : 0 : return node;
522 : : }
523 : :
524 : 0 : static AstNode *trans_create_node_apfloat(Context *c, const llvm::APFloat &ap_float) {
525 : : uint8_t buf[128];
526 : 0 : size_t written = ap_float.convertToHexString((char *)buf, 0, false,
527 : 0 : llvm::APFloat::rmNearestTiesToEven);
528 : 0 : AstNode *node = trans_create_node(c, NodeTypeFloatLiteral);
529 : 0 : node->data.float_literal.bigfloat = allocate<BigFloat>(1);
530 [ # # ]: 0 : if (bigfloat_init_buf(node->data.float_literal.bigfloat, buf, written)) {
531 : 0 : node->data.float_literal.overflow = true;
532 : : }
533 : 0 : return node;
534 : : }
535 : :
536 : 0 : static const ZigClangType *qual_type_canon(ZigClangQualType qt) {
537 : 0 : ZigClangQualType canon = ZigClangQualType_getCanonicalType(qt);
538 : 0 : return ZigClangQualType_getTypePtr(canon);
539 : : }
540 : :
541 : 0 : static ZigClangQualType get_expr_qual_type(Context *c, const ZigClangExpr *expr) {
542 : : // String literals in C are `char *` but they should really be `const char *`.
543 [ # # ]: 0 : if (ZigClangExpr_getStmtClass(expr) == ZigClangStmt_ImplicitCastExprClass) {
544 : 0 : const clang::ImplicitCastExpr *cast_expr = reinterpret_cast<const clang::ImplicitCastExpr *>(expr);
545 [ # # ]: 0 : if ((ZigClangCK)cast_expr->getCastKind() == ZigClangCK_ArrayToPointerDecay) {
546 : 0 : const ZigClangExpr *sub_expr = bitcast(cast_expr->getSubExpr());
547 [ # # ]: 0 : if (ZigClangExpr_getStmtClass(sub_expr) == ZigClangStmt_StringLiteralClass) {
548 : 0 : ZigClangQualType array_qt = ZigClangExpr_getType(sub_expr);
549 : : const clang::ArrayType *array_type = reinterpret_cast<const clang::ArrayType *>(
550 : 0 : ZigClangQualType_getTypePtr(array_qt));
551 : 0 : ZigClangQualType pointee_qt = bitcast(array_type->getElementType());
552 : 0 : ZigClangQualType_addConst(&pointee_qt);
553 : 0 : return ZigClangASTContext_getPointerType(c->ctx, pointee_qt);
554 : : }
555 : : }
556 : : }
557 : 0 : return ZigClangExpr_getType(expr);
558 : : }
559 : :
560 : 0 : static ZigClangQualType get_expr_qual_type_before_implicit_cast(Context *c, const ZigClangExpr *expr) {
561 [ # # ]: 0 : if (ZigClangExpr_getStmtClass(expr) == ZigClangStmt_ImplicitCastExprClass) {
562 : 0 : const clang::ImplicitCastExpr *cast_expr = reinterpret_cast<const clang::ImplicitCastExpr *>(expr);
563 : 0 : return get_expr_qual_type(c, bitcast(cast_expr->getSubExpr()));
564 : : }
565 : 0 : return ZigClangExpr_getType(expr);
566 : : }
567 : :
568 : 0 : static AstNode *get_expr_type(Context *c, const ZigClangExpr *expr) {
569 : 0 : return trans_qual_type(c, get_expr_qual_type(c, expr), ZigClangExpr_getBeginLoc(expr));
570 : : }
571 : :
572 : 0 : static bool is_c_void_type(AstNode *node) {
573 [ # # ][ # # ]: 0 : return (node->type == NodeTypeSymbol && buf_eql_str(node->data.symbol_expr.symbol, "c_void"));
574 : : }
575 : :
576 : 0 : static bool qual_type_is_ptr(ZigClangQualType qt) {
577 : 0 : const ZigClangType *ty = qual_type_canon(qt);
578 : 0 : return ZigClangType_getTypeClass(ty) == ZigClangType_Pointer;
579 : : }
580 : :
581 : 0 : static const clang::FunctionProtoType *qual_type_get_fn_proto(ZigClangQualType qt, bool *is_ptr) {
582 : 0 : const ZigClangType *ty = qual_type_canon(qt);
583 : 0 : *is_ptr = false;
584 : :
585 [ # # ]: 0 : if (ZigClangType_getTypeClass(ty) == ZigClangType_Pointer) {
586 : 0 : *is_ptr = true;
587 : 0 : ZigClangQualType child_qt = ZigClangType_getPointeeType(ty);
588 : 0 : ty = ZigClangQualType_getTypePtr(child_qt);
589 : : }
590 : :
591 [ # # ]: 0 : if (ZigClangType_getTypeClass(ty) == ZigClangType_FunctionProto) {
592 : 0 : return reinterpret_cast<const clang::FunctionProtoType*>(ty);
593 : : }
594 : :
595 : 0 : return nullptr;
596 : : }
597 : :
598 : 0 : static bool qual_type_is_fn_ptr(ZigClangQualType qt) {
599 : : bool is_ptr;
600 [ # # ]: 0 : if (qual_type_get_fn_proto(qt, &is_ptr)) {
601 : 0 : return is_ptr;
602 : : }
603 : :
604 : 0 : return false;
605 : : }
606 : :
607 : 0 : static uint32_t qual_type_int_bit_width(Context *c, const ZigClangQualType qt, ZigClangSourceLocation source_loc) {
608 : 0 : const ZigClangType *ty = ZigClangQualType_getTypePtr(qt);
609 [ # # # ]: 0 : switch (ZigClangType_getTypeClass(ty)) {
610 : 0 : case ZigClangType_Builtin:
611 : : {
612 : 0 : const ZigClangBuiltinType *builtin_ty = reinterpret_cast<const ZigClangBuiltinType*>(ty);
613 [ # # # ]: 0 : switch (ZigClangBuiltinType_getKind(builtin_ty)) {
614 : 0 : case ZigClangBuiltinTypeChar_U:
615 : : case ZigClangBuiltinTypeUChar:
616 : : case ZigClangBuiltinTypeChar_S:
617 : : case ZigClangBuiltinTypeSChar:
618 : 0 : return 8;
619 : 0 : case ZigClangBuiltinTypeUInt128:
620 : : case ZigClangBuiltinTypeInt128:
621 : 0 : return 128;
622 : 0 : default:
623 : 0 : return 0;
624 : : }
625 : : zig_unreachable();
626 : : }
627 : 0 : case ZigClangType_Typedef:
628 : : {
629 : 0 : const ZigClangTypedefType *typedef_ty = reinterpret_cast<const ZigClangTypedefType*>(ty);
630 : 0 : const ZigClangTypedefNameDecl *typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
631 : 0 : const char *type_name = ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)typedef_decl);
632 [ # # ][ # # ]: 0 : if (strcmp(type_name, "uint8_t") == 0 || strcmp(type_name, "int8_t") == 0) {
633 : 0 : return 8;
634 [ # # ][ # # ]: 0 : } else if (strcmp(type_name, "uint16_t") == 0 || strcmp(type_name, "int16_t") == 0) {
635 : 0 : return 16;
636 [ # # ][ # # ]: 0 : } else if (strcmp(type_name, "uint32_t") == 0 || strcmp(type_name, "int32_t") == 0) {
637 : 0 : return 32;
638 [ # # ][ # # ]: 0 : } else if (strcmp(type_name, "uint64_t") == 0 || strcmp(type_name, "int64_t") == 0) {
639 : 0 : return 64;
640 : : } else {
641 : 0 : return 0;
642 : : }
643 : : }
644 : 0 : default:
645 : 0 : return 0;
646 : : }
647 : : zig_unreachable();
648 : : }
649 : :
650 : :
651 : 0 : static AstNode *qual_type_to_log2_int_ref(Context *c, const ZigClangQualType qt,
652 : : ZigClangSourceLocation source_loc)
653 : : {
654 : 0 : uint32_t int_bit_width = qual_type_int_bit_width(c, qt, source_loc);
655 [ # # ]: 0 : if (int_bit_width != 0) {
656 : : // we can perform the log2 now.
657 : 0 : uint64_t cast_bit_width = log2_u64(int_bit_width);
658 : 0 : return trans_create_node_symbol(c, buf_sprintf("u%" ZIG_PRI_u64, cast_bit_width));
659 : : }
660 : :
661 : 0 : AstNode *zig_type_node = trans_qual_type(c, qt, source_loc);
662 : :
663 : : // @import("std").math.Log2Int(c_long);
664 : : //
665 : : // FnCall
666 : : // FieldAccess
667 : : // FieldAccess
668 : : // FnCall (.builtin = true)
669 : : // Symbol "import"
670 : : // ZigClangStringLiteral "std"
671 : : // Symbol "math"
672 : : // Symbol "Log2Int"
673 : : // zig_type_node
674 : :
675 : 0 : AstNode *import_fn_call = trans_create_node_builtin_fn_call_str(c, "import");
676 : 0 : import_fn_call->data.fn_call_expr.params.append(trans_create_node_str_lit_non_c(c, buf_create_from_str("std")));
677 : 0 : AstNode *inner_field_access = trans_create_node_field_access_str(c, import_fn_call, "math");
678 : 0 : AstNode *outer_field_access = trans_create_node_field_access_str(c, inner_field_access, "Log2Int");
679 : 0 : AstNode *log2int_fn_call = trans_create_node_fn_call_1(c, outer_field_access, zig_type_node);
680 : :
681 : 0 : return log2int_fn_call;
682 : : }
683 : :
684 : 0 : static bool qual_type_child_is_fn_proto(ZigClangQualType qt) {
685 : 0 : const ZigClangType *ty = ZigClangQualType_getTypePtr(qt);
686 [ # # ]: 0 : if (ZigClangType_getTypeClass(ty) == ZigClangType_Paren) {
687 : 0 : const clang::ParenType *paren_type = reinterpret_cast<const clang::ParenType *>(ty);
688 [ # # ]: 0 : if (paren_type->getInnerType()->getTypeClass() == clang::Type::FunctionProto) {
689 : 0 : return true;
690 : : }
691 [ # # ]: 0 : } else if (ZigClangType_getTypeClass(ty) == ZigClangType_Attributed) {
692 : 0 : const clang::AttributedType *attr_type = reinterpret_cast<const clang::AttributedType *>(ty);
693 : 0 : return qual_type_child_is_fn_proto(bitcast(attr_type->getEquivalentType()));
694 : : }
695 : 0 : return false;
696 : : }
697 : :
698 : 0 : static AstNode* trans_c_ptr_cast(Context *c, ZigClangSourceLocation source_location, ZigClangQualType dest_type,
699 : : ZigClangQualType src_type, AstNode *expr)
700 : : {
701 : 0 : const ZigClangType *ty = ZigClangQualType_getTypePtr(dest_type);
702 : 0 : const ZigClangQualType child_type = ZigClangType_getPointeeType(ty);
703 : :
704 : 0 : AstNode *dest_type_node = trans_type(c, ty, source_location);
705 : 0 : AstNode *child_type_node = trans_qual_type(c, child_type, source_location);
706 : :
707 : : // Implicit downcasting from higher to lower alignment values is forbidden,
708 : : // use @alignCast to side-step this problem
709 : 0 : AstNode *ptrcast_node = trans_create_node_builtin_fn_call_str(c, "ptrCast");
710 : 0 : ptrcast_node->data.fn_call_expr.params.append(dest_type_node);
711 : :
712 [ # # ]: 0 : if (ZigClangType_isVoidType(qual_type_canon(child_type))) {
713 : : // void has 1-byte alignment
714 : 0 : ptrcast_node->data.fn_call_expr.params.append(expr);
715 : : } else {
716 : 0 : AstNode *alignof_node = trans_create_node_builtin_fn_call_str(c, "alignOf");
717 : 0 : alignof_node->data.fn_call_expr.params.append(child_type_node);
718 : 0 : AstNode *aligncast_node = trans_create_node_builtin_fn_call_str(c, "alignCast");
719 : 0 : aligncast_node->data.fn_call_expr.params.append(alignof_node);
720 : 0 : aligncast_node->data.fn_call_expr.params.append(expr);
721 : :
722 : 0 : ptrcast_node->data.fn_call_expr.params.append(aligncast_node);
723 : : }
724 : :
725 : 0 : return ptrcast_node;
726 : : }
727 : :
728 : 0 : static AstNode* trans_c_cast(Context *c, ZigClangSourceLocation source_location, ZigClangQualType dest_type,
729 : : ZigClangQualType src_type, AstNode *expr)
730 : : {
731 : : // The only way void pointer casts are valid C code, is if
732 : : // the value of the expression is ignored. We therefore just
733 : : // return the expr, and let the system that ignores values
734 : : // translate this correctly.
735 [ # # ]: 0 : if (ZigClangType_isVoidType(qual_type_canon(dest_type))) {
736 : 0 : return expr;
737 : : }
738 [ # # ]: 0 : if (ZigClangQualType_eq(dest_type, src_type)) {
739 : 0 : return expr;
740 : : }
741 [ # # ][ # # ]: 0 : if (qual_type_is_ptr(dest_type) && qual_type_is_ptr(src_type)) {
[ # # ]
742 : 0 : return trans_c_ptr_cast(c, source_location, dest_type, src_type, expr);
743 : : }
744 [ # # ][ # # ]: 0 : if (c_is_unsigned_integer(c, dest_type) && qual_type_is_ptr(src_type)) {
[ # # ]
745 : 0 : AstNode *addr_node = trans_create_node_builtin_fn_call_str(c, "ptrToInt");
746 : 0 : addr_node->data.fn_call_expr.params.append(expr);
747 : 0 : return trans_create_node_fn_call_1(c, trans_qual_type(c, dest_type, source_location), addr_node);
748 : : }
749 [ # # ][ # # ]: 0 : if (c_is_unsigned_integer(c, src_type) && qual_type_is_ptr(dest_type)) {
[ # # ]
750 : 0 : AstNode *ptr_node = trans_create_node_builtin_fn_call_str(c, "intToPtr");
751 : 0 : ptr_node->data.fn_call_expr.params.append(trans_qual_type(c, dest_type, source_location));
752 : 0 : ptr_node->data.fn_call_expr.params.append(expr);
753 : 0 : return ptr_node;
754 : : }
755 : : // TODO: maybe widen to increase size
756 : : // TODO: maybe bitcast to change sign
757 : : // TODO: maybe truncate to reduce size
758 : 0 : return trans_create_node_fn_call_1(c, trans_qual_type(c, dest_type, source_location), expr);
759 : : }
760 : :
761 : 0 : static bool c_is_signed_integer(Context *c, ZigClangQualType qt) {
762 : 0 : const ZigClangType *c_type = qual_type_canon(qt);
763 [ # # ]: 0 : if (ZigClangType_getTypeClass(c_type) != ZigClangType_Builtin)
764 : 0 : return false;
765 : 0 : const ZigClangBuiltinType *builtin_ty = reinterpret_cast<const ZigClangBuiltinType*>(c_type);
766 [ # # ]: 0 : switch (ZigClangBuiltinType_getKind(builtin_ty)) {
767 : 0 : case ZigClangBuiltinTypeSChar:
768 : : case ZigClangBuiltinTypeShort:
769 : : case ZigClangBuiltinTypeInt:
770 : : case ZigClangBuiltinTypeLong:
771 : : case ZigClangBuiltinTypeLongLong:
772 : : case ZigClangBuiltinTypeInt128:
773 : : case ZigClangBuiltinTypeWChar_S:
774 : 0 : return true;
775 : 0 : default:
776 : 0 : return false;
777 : : }
778 : : }
779 : :
780 : 0 : static bool c_is_unsigned_integer(Context *c, ZigClangQualType qt) {
781 : 0 : const ZigClangType *c_type = qual_type_canon(qt);
782 [ # # ]: 0 : if (ZigClangType_getTypeClass(c_type) != ZigClangType_Builtin)
783 : 0 : return false;
784 : 0 : const ZigClangBuiltinType *builtin_ty = reinterpret_cast<const ZigClangBuiltinType*>(c_type);
785 [ # # ]: 0 : switch (ZigClangBuiltinType_getKind(builtin_ty)) {
786 : 0 : case ZigClangBuiltinTypeChar_U:
787 : : case ZigClangBuiltinTypeUChar:
788 : : case ZigClangBuiltinTypeChar_S:
789 : : case ZigClangBuiltinTypeUShort:
790 : : case ZigClangBuiltinTypeUInt:
791 : : case ZigClangBuiltinTypeULong:
792 : : case ZigClangBuiltinTypeULongLong:
793 : : case ZigClangBuiltinTypeUInt128:
794 : : case ZigClangBuiltinTypeWChar_U:
795 : 0 : return true;
796 : 0 : default:
797 : 0 : return false;
798 : : }
799 : : }
800 : :
801 : 0 : static bool c_is_builtin_type(Context *c, ZigClangQualType qt, ZigClangBuiltinTypeKind kind) {
802 : 0 : const ZigClangType *c_type = qual_type_canon(qt);
803 [ # # ]: 0 : if (ZigClangType_getTypeClass(c_type) != ZigClangType_Builtin)
804 : 0 : return false;
805 : 0 : const ZigClangBuiltinType *builtin_ty = reinterpret_cast<const ZigClangBuiltinType*>(c_type);
806 : 0 : return ZigClangBuiltinType_getKind(builtin_ty) == kind;
807 : : }
808 : :
809 : 0 : static bool c_is_float(Context *c, ZigClangQualType qt) {
810 : 0 : const ZigClangType *c_type = ZigClangQualType_getTypePtr(qt);
811 [ # # ]: 0 : if (ZigClangType_getTypeClass(c_type) != ZigClangType_Builtin)
812 : 0 : return false;
813 : 0 : const ZigClangBuiltinType *builtin_ty = reinterpret_cast<const ZigClangBuiltinType*>(c_type);
814 [ # # ]: 0 : switch (ZigClangBuiltinType_getKind(builtin_ty)) {
815 : 0 : case ZigClangBuiltinTypeHalf:
816 : : case ZigClangBuiltinTypeFloat:
817 : : case ZigClangBuiltinTypeDouble:
818 : : case ZigClangBuiltinTypeFloat128:
819 : : case ZigClangBuiltinTypeLongDouble:
820 : 0 : return true;
821 : 0 : default:
822 : 0 : return false;
823 : : }
824 : : }
825 : :
826 : 0 : static bool qual_type_has_wrapping_overflow(Context *c, ZigClangQualType qt) {
827 [ # # ][ # # ]: 0 : if (c_is_signed_integer(c, qt) || c_is_float(c, qt)) {
[ # # ]
828 : : // float and signed integer overflow is undefined behavior.
829 : 0 : return false;
830 : : } else {
831 : : // unsigned integer overflow wraps around.
832 : 0 : return true;
833 : : }
834 : : }
835 : :
836 : 0 : static bool type_is_function(Context *c, const ZigClangType *ty, ZigClangSourceLocation source_loc) {
837 [ # # # # ]: 0 : switch (ZigClangType_getTypeClass(ty)) {
838 : 0 : case ZigClangType_FunctionProto:
839 : : case ZigClangType_FunctionNoProto:
840 : 0 : return true;
841 : 0 : case ZigClangType_Elaborated: {
842 : 0 : const clang::ElaboratedType *elaborated_ty = reinterpret_cast<const clang::ElaboratedType*>(ty);
843 : 0 : ZigClangQualType qt = bitcast(elaborated_ty->getNamedType());
844 : 0 : return type_is_function(c, ZigClangQualType_getTypePtr(qt), source_loc);
845 : : }
846 : 0 : case ZigClangType_Typedef: {
847 : 0 : const ZigClangTypedefType *typedef_ty = reinterpret_cast<const ZigClangTypedefType*>(ty);
848 : 0 : const ZigClangTypedefNameDecl *typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
849 : 0 : ZigClangQualType underlying_type = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);
850 : 0 : return type_is_function(c, ZigClangQualType_getTypePtr(underlying_type), source_loc);
851 : : }
852 : 0 : default:
853 : 0 : return false;
854 : : }
855 : : }
856 : :
857 : 0 : static bool type_is_opaque(Context *c, const ZigClangType *ty, ZigClangSourceLocation source_loc) {
858 [ # # # # : 0 : switch (ZigClangType_getTypeClass(ty)) {
# ]
859 : 0 : case ZigClangType_Builtin: {
860 : 0 : const ZigClangBuiltinType *builtin_ty = reinterpret_cast<const ZigClangBuiltinType*>(ty);
861 : 0 : return ZigClangBuiltinType_getKind(builtin_ty) == ZigClangBuiltinTypeVoid;
862 : : }
863 : 0 : case ZigClangType_Record: {
864 : 0 : const ZigClangRecordType *record_ty = reinterpret_cast<const ZigClangRecordType*>(ty);
865 : 0 : const ZigClangRecordDecl *record_decl = ZigClangRecordType_getDecl(record_ty);
866 : 0 : const ZigClangRecordDecl *record_def = ZigClangRecordDecl_getDefinition(record_decl);
867 [ # # ]: 0 : if (record_def == nullptr) {
868 : 0 : return true;
869 : : }
870 : 0 : for (auto it = reinterpret_cast<const clang::RecordDecl *>(record_def)->field_begin(),
871 : 0 : it_end = reinterpret_cast<const clang::RecordDecl *>(record_def)->field_end();
872 [ # # ]: 0 : it != it_end; ++it)
873 : : {
874 : 0 : const clang::FieldDecl *field_decl = *it;
875 : :
876 [ # # ]: 0 : if (field_decl->isBitField()) {
877 : 0 : return true;
878 : : }
879 : : }
880 : 0 : return false;
881 : : }
882 : 0 : case ZigClangType_Elaborated: {
883 : 0 : const clang::ElaboratedType *elaborated_ty = reinterpret_cast<const clang::ElaboratedType*>(ty);
884 : 0 : ZigClangQualType qt = bitcast(elaborated_ty->getNamedType());
885 : 0 : return type_is_opaque(c, ZigClangQualType_getTypePtr(qt), source_loc);
886 : : }
887 : 0 : case ZigClangType_Typedef: {
888 : 0 : const ZigClangTypedefType *typedef_ty = reinterpret_cast<const ZigClangTypedefType*>(ty);
889 : 0 : const ZigClangTypedefNameDecl *typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
890 : 0 : ZigClangQualType underlying_type = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);
891 : 0 : return type_is_opaque(c, ZigClangQualType_getTypePtr(underlying_type), source_loc);
892 : : }
893 : 0 : default:
894 : 0 : return false;
895 : : }
896 : : }
897 : :
898 : 0 : static AstNode *trans_type(Context *c, const ZigClangType *ty, ZigClangSourceLocation source_loc) {
899 [ # # # # : 0 : switch (ZigClangType_getTypeClass(ty)) {
# # # # #
# # # #
# ]
900 : 0 : case ZigClangType_Builtin:
901 : : {
902 : 0 : const ZigClangBuiltinType *builtin_ty = reinterpret_cast<const ZigClangBuiltinType *>(ty);
903 [ # # # # : 0 : switch (ZigClangBuiltinType_getKind(builtin_ty)) {
# # # # #
# # # # #
# # # # #
# # ]
904 : 0 : case ZigClangBuiltinTypeVoid:
905 : 0 : return trans_create_node_symbol_str(c, "c_void");
906 : 0 : case ZigClangBuiltinTypeBool:
907 : 0 : return trans_create_node_symbol_str(c, "bool");
908 : 0 : case ZigClangBuiltinTypeChar_U:
909 : : case ZigClangBuiltinTypeUChar:
910 : : case ZigClangBuiltinTypeChar_S:
911 : : case ZigClangBuiltinTypeChar8:
912 : 0 : return trans_create_node_symbol_str(c, "u8");
913 : 0 : case ZigClangBuiltinTypeSChar:
914 : 0 : return trans_create_node_symbol_str(c, "i8");
915 : 0 : case ZigClangBuiltinTypeUShort:
916 : 0 : return trans_create_node_symbol_str(c, "c_ushort");
917 : 0 : case ZigClangBuiltinTypeUInt:
918 : 0 : return trans_create_node_symbol_str(c, "c_uint");
919 : 0 : case ZigClangBuiltinTypeULong:
920 : 0 : return trans_create_node_symbol_str(c, "c_ulong");
921 : 0 : case ZigClangBuiltinTypeULongLong:
922 : 0 : return trans_create_node_symbol_str(c, "c_ulonglong");
923 : 0 : case ZigClangBuiltinTypeShort:
924 : 0 : return trans_create_node_symbol_str(c, "c_short");
925 : 0 : case ZigClangBuiltinTypeInt:
926 : 0 : return trans_create_node_symbol_str(c, "c_int");
927 : 0 : case ZigClangBuiltinTypeLong:
928 : 0 : return trans_create_node_symbol_str(c, "c_long");
929 : 0 : case ZigClangBuiltinTypeLongLong:
930 : 0 : return trans_create_node_symbol_str(c, "c_longlong");
931 : 0 : case ZigClangBuiltinTypeUInt128:
932 : 0 : return trans_create_node_symbol_str(c, "u128");
933 : 0 : case ZigClangBuiltinTypeInt128:
934 : 0 : return trans_create_node_symbol_str(c, "i128");
935 : 0 : case ZigClangBuiltinTypeFloat:
936 : 0 : return trans_create_node_symbol_str(c, "f32");
937 : 0 : case ZigClangBuiltinTypeDouble:
938 : 0 : return trans_create_node_symbol_str(c, "f64");
939 : 0 : case ZigClangBuiltinTypeFloat128:
940 : 0 : return trans_create_node_symbol_str(c, "f128");
941 : 0 : case ZigClangBuiltinTypeFloat16:
942 : 0 : return trans_create_node_symbol_str(c, "f16");
943 : 0 : case ZigClangBuiltinTypeLongDouble:
944 : 0 : return trans_create_node_symbol_str(c, "c_longdouble");
945 : 0 : case ZigClangBuiltinTypeWChar_U:
946 : : case ZigClangBuiltinTypeChar16:
947 : : case ZigClangBuiltinTypeChar32:
948 : : case ZigClangBuiltinTypeWChar_S:
949 : : case ZigClangBuiltinTypeHalf:
950 : : case ZigClangBuiltinTypeNullPtr:
951 : : case ZigClangBuiltinTypeObjCId:
952 : : case ZigClangBuiltinTypeObjCClass:
953 : : case ZigClangBuiltinTypeObjCSel:
954 : : case ZigClangBuiltinTypeOMPArraySection:
955 : : case ZigClangBuiltinTypeDependent:
956 : : case ZigClangBuiltinTypeOverload:
957 : : case ZigClangBuiltinTypeBoundMember:
958 : : case ZigClangBuiltinTypePseudoObject:
959 : : case ZigClangBuiltinTypeUnknownAny:
960 : : case ZigClangBuiltinTypeBuiltinFn:
961 : : case ZigClangBuiltinTypeARCUnbridgedCast:
962 : : case ZigClangBuiltinTypeShortAccum:
963 : : case ZigClangBuiltinTypeAccum:
964 : : case ZigClangBuiltinTypeLongAccum:
965 : : case ZigClangBuiltinTypeUShortAccum:
966 : : case ZigClangBuiltinTypeUAccum:
967 : : case ZigClangBuiltinTypeULongAccum:
968 : :
969 : : case ZigClangBuiltinTypeOCLImage1dRO:
970 : : case ZigClangBuiltinTypeOCLImage1dArrayRO:
971 : : case ZigClangBuiltinTypeOCLImage1dBufferRO:
972 : : case ZigClangBuiltinTypeOCLImage2dRO:
973 : : case ZigClangBuiltinTypeOCLImage2dArrayRO:
974 : : case ZigClangBuiltinTypeOCLImage2dDepthRO:
975 : : case ZigClangBuiltinTypeOCLImage2dArrayDepthRO:
976 : : case ZigClangBuiltinTypeOCLImage2dMSAARO:
977 : : case ZigClangBuiltinTypeOCLImage2dArrayMSAARO:
978 : : case ZigClangBuiltinTypeOCLImage2dMSAADepthRO:
979 : : case ZigClangBuiltinTypeOCLImage2dArrayMSAADepthRO:
980 : : case ZigClangBuiltinTypeOCLImage3dRO:
981 : : case ZigClangBuiltinTypeOCLImage1dWO:
982 : : case ZigClangBuiltinTypeOCLImage1dArrayWO:
983 : : case ZigClangBuiltinTypeOCLImage1dBufferWO:
984 : : case ZigClangBuiltinTypeOCLImage2dWO:
985 : : case ZigClangBuiltinTypeOCLImage2dArrayWO:
986 : : case ZigClangBuiltinTypeOCLImage2dDepthWO:
987 : : case ZigClangBuiltinTypeOCLImage2dArrayDepthWO:
988 : : case ZigClangBuiltinTypeOCLImage2dMSAAWO:
989 : : case ZigClangBuiltinTypeOCLImage2dArrayMSAAWO:
990 : : case ZigClangBuiltinTypeOCLImage2dMSAADepthWO:
991 : : case ZigClangBuiltinTypeOCLImage2dArrayMSAADepthWO:
992 : : case ZigClangBuiltinTypeOCLImage3dWO:
993 : : case ZigClangBuiltinTypeOCLImage1dRW:
994 : : case ZigClangBuiltinTypeOCLImage1dArrayRW:
995 : : case ZigClangBuiltinTypeOCLImage1dBufferRW:
996 : : case ZigClangBuiltinTypeOCLImage2dRW:
997 : : case ZigClangBuiltinTypeOCLImage2dArrayRW:
998 : : case ZigClangBuiltinTypeOCLImage2dDepthRW:
999 : : case ZigClangBuiltinTypeOCLImage2dArrayDepthRW:
1000 : : case ZigClangBuiltinTypeOCLImage2dMSAARW:
1001 : : case ZigClangBuiltinTypeOCLImage2dArrayMSAARW:
1002 : : case ZigClangBuiltinTypeOCLImage2dMSAADepthRW:
1003 : : case ZigClangBuiltinTypeOCLImage2dArrayMSAADepthRW:
1004 : : case ZigClangBuiltinTypeOCLImage3dRW:
1005 : : case ZigClangBuiltinTypeOCLSampler:
1006 : : case ZigClangBuiltinTypeOCLEvent:
1007 : : case ZigClangBuiltinTypeOCLClkEvent:
1008 : : case ZigClangBuiltinTypeOCLQueue:
1009 : : case ZigClangBuiltinTypeOCLReserveID:
1010 : : case ZigClangBuiltinTypeShortFract:
1011 : : case ZigClangBuiltinTypeFract:
1012 : : case ZigClangBuiltinTypeLongFract:
1013 : : case ZigClangBuiltinTypeUShortFract:
1014 : : case ZigClangBuiltinTypeUFract:
1015 : : case ZigClangBuiltinTypeULongFract:
1016 : : case ZigClangBuiltinTypeSatShortAccum:
1017 : : case ZigClangBuiltinTypeSatAccum:
1018 : : case ZigClangBuiltinTypeSatLongAccum:
1019 : : case ZigClangBuiltinTypeSatUShortAccum:
1020 : : case ZigClangBuiltinTypeSatUAccum:
1021 : : case ZigClangBuiltinTypeSatULongAccum:
1022 : : case ZigClangBuiltinTypeSatShortFract:
1023 : : case ZigClangBuiltinTypeSatFract:
1024 : : case ZigClangBuiltinTypeSatLongFract:
1025 : : case ZigClangBuiltinTypeSatUShortFract:
1026 : : case ZigClangBuiltinTypeSatUFract:
1027 : : case ZigClangBuiltinTypeSatULongFract:
1028 : : case ZigClangBuiltinTypeOCLIntelSubgroupAVCMcePayload:
1029 : : case ZigClangBuiltinTypeOCLIntelSubgroupAVCImePayload:
1030 : : case ZigClangBuiltinTypeOCLIntelSubgroupAVCRefPayload:
1031 : : case ZigClangBuiltinTypeOCLIntelSubgroupAVCSicPayload:
1032 : : case ZigClangBuiltinTypeOCLIntelSubgroupAVCMceResult:
1033 : : case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResult:
1034 : : case ZigClangBuiltinTypeOCLIntelSubgroupAVCRefResult:
1035 : : case ZigClangBuiltinTypeOCLIntelSubgroupAVCSicResult:
1036 : : case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResultSingleRefStreamout:
1037 : : case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResultDualRefStreamout:
1038 : : case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeSingleRefStreamin:
1039 : : case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeDualRefStreamin:
1040 : 0 : emit_warning(c, source_loc, "unsupported builtin type");
1041 : 0 : return nullptr;
1042 : : }
1043 : 0 : break;
1044 : : }
1045 : 0 : case ZigClangType_Pointer:
1046 : : {
1047 : 0 : ZigClangQualType child_qt = ZigClangType_getPointeeType(ty);
1048 : 0 : AstNode *child_node = trans_qual_type(c, child_qt, source_loc);
1049 [ # # ]: 0 : if (child_node == nullptr) {
1050 : 0 : emit_warning(c, source_loc, "pointer to unsupported type");
1051 : 0 : return nullptr;
1052 : : }
1053 : :
1054 [ # # ]: 0 : if (qual_type_child_is_fn_proto(child_qt)) {
1055 : 0 : return trans_create_node_prefix_op(c, PrefixOpOptional, child_node);
1056 : : }
1057 : :
1058 [ # # ]: 0 : if (type_is_function(c, ZigClangQualType_getTypePtr(child_qt), source_loc)) {
1059 : 0 : return trans_create_node_prefix_op(c, PrefixOpOptional, child_node);
1060 [ # # ]: 0 : } else if (type_is_opaque(c, ZigClangQualType_getTypePtr(child_qt), source_loc)) {
1061 : 0 : AstNode *pointer_node = trans_create_node_ptr_type(c,
1062 : 0 : ZigClangQualType_isConstQualified(child_qt),
1063 : 0 : ZigClangQualType_isVolatileQualified(child_qt),
1064 : 0 : child_node, PtrLenSingle);
1065 : 0 : return trans_create_node_prefix_op(c, PrefixOpOptional, pointer_node);
1066 : : } else {
1067 : 0 : return trans_create_node_ptr_type(c,
1068 : 0 : ZigClangQualType_isConstQualified(child_qt),
1069 : 0 : ZigClangQualType_isVolatileQualified(child_qt),
1070 : 0 : child_node, PtrLenC);
1071 : : }
1072 : : }
1073 : 0 : case ZigClangType_Typedef:
1074 : : {
1075 : 0 : const ZigClangTypedefType *typedef_ty = reinterpret_cast<const ZigClangTypedefType*>(ty);
1076 : 0 : const ZigClangTypedefNameDecl *typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
1077 : 0 : return resolve_typedef_decl(c, typedef_decl);
1078 : : }
1079 : 0 : case ZigClangType_Elaborated:
1080 : : {
1081 : 0 : const clang::ElaboratedType *elaborated_ty = reinterpret_cast<const clang::ElaboratedType*>(ty);
1082 [ # # # ]: 0 : switch (elaborated_ty->getKeyword()) {
1083 : 0 : case clang::ETK_Struct:
1084 : : case clang::ETK_Enum:
1085 : : case clang::ETK_Union:
1086 : 0 : return trans_qual_type(c, bitcast(elaborated_ty->getNamedType()), source_loc);
1087 : 0 : case clang::ETK_Interface:
1088 : : case clang::ETK_Class:
1089 : : case clang::ETK_Typename:
1090 : : case clang::ETK_None:
1091 : 0 : emit_warning(c, source_loc, "unsupported elaborated type");
1092 : 0 : return nullptr;
1093 : : }
1094 : : }
1095 : : case ZigClangType_FunctionProto:
1096 : : case ZigClangType_FunctionNoProto:
1097 : : {
1098 : 0 : const ZigClangFunctionType *fn_ty = reinterpret_cast<const ZigClangFunctionType*>(ty);
1099 : :
1100 : 0 : AstNode *proto_node = trans_create_node(c, NodeTypeFnProto);
1101 [ # # # # : 0 : switch (ZigClangFunctionType_getCallConv(fn_ty)) {
# # # # #
# # # # #
# # # #
# ]
1102 : 0 : case ZigClangCallingConv_C: // __attribute__((cdecl))
1103 : 0 : proto_node->data.fn_proto.cc = CallingConventionC;
1104 : 0 : proto_node->data.fn_proto.is_extern = true;
1105 : 0 : break;
1106 : 0 : case ZigClangCallingConv_X86StdCall: // __attribute__((stdcall))
1107 : 0 : proto_node->data.fn_proto.cc = CallingConventionStdcall;
1108 : 0 : break;
1109 : 0 : case ZigClangCallingConv_X86FastCall: // __attribute__((fastcall))
1110 : 0 : emit_warning(c, source_loc, "unsupported calling convention: x86 fastcall");
1111 : 0 : return nullptr;
1112 : 0 : case ZigClangCallingConv_X86ThisCall: // __attribute__((thiscall))
1113 : 0 : emit_warning(c, source_loc, "unsupported calling convention: x86 thiscall");
1114 : 0 : return nullptr;
1115 : 0 : case ZigClangCallingConv_X86VectorCall: // __attribute__((vectorcall))
1116 : 0 : emit_warning(c, source_loc, "unsupported calling convention: x86 vectorcall");
1117 : 0 : return nullptr;
1118 : 0 : case ZigClangCallingConv_X86Pascal: // __attribute__((pascal))
1119 : 0 : emit_warning(c, source_loc, "unsupported calling convention: x86 pascal");
1120 : 0 : return nullptr;
1121 : 0 : case ZigClangCallingConv_Win64: // __attribute__((ms_abi))
1122 : 0 : emit_warning(c, source_loc, "unsupported calling convention: win64");
1123 : 0 : return nullptr;
1124 : 0 : case ZigClangCallingConv_X86_64SysV: // __attribute__((sysv_abi))
1125 : 0 : emit_warning(c, source_loc, "unsupported calling convention: x86 64sysv");
1126 : 0 : return nullptr;
1127 : 0 : case ZigClangCallingConv_X86RegCall:
1128 : 0 : emit_warning(c, source_loc, "unsupported calling convention: x86 reg");
1129 : 0 : return nullptr;
1130 : 0 : case ZigClangCallingConv_AAPCS: // __attribute__((pcs("aapcs")))
1131 : 0 : emit_warning(c, source_loc, "unsupported calling convention: aapcs");
1132 : 0 : return nullptr;
1133 : 0 : case ZigClangCallingConv_AAPCS_VFP: // __attribute__((pcs("aapcs-vfp")))
1134 : 0 : emit_warning(c, source_loc, "unsupported calling convention: aapcs-vfp");
1135 : 0 : return nullptr;
1136 : 0 : case ZigClangCallingConv_IntelOclBicc: // __attribute__((intel_ocl_bicc))
1137 : 0 : emit_warning(c, source_loc, "unsupported calling convention: intel_ocl_bicc");
1138 : 0 : return nullptr;
1139 : 0 : case ZigClangCallingConv_SpirFunction: // default for OpenCL functions on SPIR target
1140 : 0 : emit_warning(c, source_loc, "unsupported calling convention: SPIR function");
1141 : 0 : return nullptr;
1142 : 0 : case ZigClangCallingConv_OpenCLKernel:
1143 : 0 : emit_warning(c, source_loc, "unsupported calling convention: OpenCLKernel");
1144 : 0 : return nullptr;
1145 : 0 : case ZigClangCallingConv_Swift:
1146 : 0 : emit_warning(c, source_loc, "unsupported calling convention: Swift");
1147 : 0 : return nullptr;
1148 : 0 : case ZigClangCallingConv_PreserveMost:
1149 : 0 : emit_warning(c, source_loc, "unsupported calling convention: PreserveMost");
1150 : 0 : return nullptr;
1151 : 0 : case ZigClangCallingConv_PreserveAll:
1152 : 0 : emit_warning(c, source_loc, "unsupported calling convention: PreserveAll");
1153 : 0 : return nullptr;
1154 : 0 : case ZigClangCallingConv_AArch64VectorCall:
1155 : 0 : emit_warning(c, source_loc, "unsupported calling convention: AArch64VectorCall");
1156 : 0 : return nullptr;
1157 : : }
1158 : :
1159 [ # # ]: 0 : if (ZigClangFunctionType_getNoReturnAttr(fn_ty)) {
1160 : 0 : proto_node->data.fn_proto.return_type = trans_create_node_symbol_str(c, "noreturn");
1161 : : } else {
1162 : 0 : proto_node->data.fn_proto.return_type = trans_qual_type(c,
1163 : : ZigClangFunctionType_getReturnType(fn_ty), source_loc);
1164 [ # # ]: 0 : if (proto_node->data.fn_proto.return_type == nullptr) {
1165 : 0 : emit_warning(c, source_loc, "unsupported function proto return type");
1166 : 0 : return nullptr;
1167 : : }
1168 : : // convert c_void to actual void (only for return type)
1169 : : // we do want to look at the AstNode instead of ZigClangQualType, because
1170 : : // if they do something like:
1171 : : // typedef Foo void;
1172 : : // void foo(void) -> Foo;
1173 : : // we want to keep the return type AST node.
1174 [ # # ]: 0 : if (is_c_void_type(proto_node->data.fn_proto.return_type)) {
1175 : 0 : proto_node->data.fn_proto.return_type = trans_create_node_symbol_str(c, "void");
1176 : : }
1177 : : }
1178 : :
1179 : : //emit_warning(c, source_loc, "TODO figure out fn prototype fn name");
1180 : 0 : const char *fn_name = nullptr;
1181 [ # # ]: 0 : if (fn_name != nullptr) {
1182 : 0 : proto_node->data.fn_proto.name = buf_create_from_str(fn_name);
1183 : : }
1184 : :
1185 [ # # ]: 0 : if (ZigClangType_getTypeClass(ty) == ZigClangType_FunctionNoProto) {
1186 : 0 : return proto_node;
1187 : : }
1188 : :
1189 : 0 : const ZigClangFunctionProtoType *fn_proto_ty = reinterpret_cast<const ZigClangFunctionProtoType*>(ty);
1190 : :
1191 : 0 : proto_node->data.fn_proto.is_var_args = ZigClangFunctionProtoType_isVariadic(fn_proto_ty);
1192 : 0 : size_t param_count = ZigClangFunctionProtoType_getNumParams(fn_proto_ty);
1193 : :
1194 [ # # ]: 0 : for (size_t i = 0; i < param_count; i += 1) {
1195 : 0 : ZigClangQualType qt = ZigClangFunctionProtoType_getParamType(fn_proto_ty, i);
1196 : 0 : AstNode *param_type_node = trans_qual_type(c, qt, source_loc);
1197 : :
1198 [ # # ]: 0 : if (param_type_node == nullptr) {
1199 : 0 : emit_warning(c, source_loc, "unresolved function proto parameter type");
1200 : 0 : return nullptr;
1201 : : }
1202 : :
1203 : 0 : AstNode *param_node = trans_create_node(c, NodeTypeParamDecl);
1204 : : //emit_warning(c, source_loc, "TODO figure out fn prototype param name");
1205 : 0 : const char *param_name = nullptr;
1206 [ # # ]: 0 : if (param_name != nullptr) {
1207 : 0 : param_node->data.param_decl.name = buf_create_from_str(param_name);
1208 : : }
1209 : 0 : param_node->data.param_decl.is_noalias = ZigClangQualType_isRestrictQualified(qt);
1210 : 0 : param_node->data.param_decl.type = param_type_node;
1211 : 0 : proto_node->data.fn_proto.params.append(param_node);
1212 : : }
1213 : : // TODO check for always_inline attribute
1214 : : // TODO check for align attribute
1215 : :
1216 : 0 : return proto_node;
1217 : : }
1218 : 0 : case ZigClangType_Record:
1219 : : {
1220 : 0 : const ZigClangRecordType *record_ty = reinterpret_cast<const ZigClangRecordType*>(ty);
1221 : 0 : return resolve_record_decl(c, ZigClangRecordType_getDecl(record_ty));
1222 : : }
1223 : 0 : case ZigClangType_Enum:
1224 : : {
1225 : 0 : const ZigClangEnumType *enum_ty = reinterpret_cast<const ZigClangEnumType*>(ty);
1226 : 0 : return resolve_enum_decl(c, ZigClangEnumType_getDecl(enum_ty));
1227 : : }
1228 : 0 : case ZigClangType_ConstantArray:
1229 : : {
1230 : 0 : const clang::ConstantArrayType *const_arr_ty = reinterpret_cast<const clang::ConstantArrayType *>(ty);
1231 : 0 : AstNode *child_type_node = trans_qual_type(c, bitcast(const_arr_ty->getElementType()), source_loc);
1232 [ # # ]: 0 : if (child_type_node == nullptr) {
1233 : 0 : emit_warning(c, source_loc, "unresolved array element type");
1234 : 0 : return nullptr;
1235 : : }
1236 : 0 : uint64_t size = const_arr_ty->getSize().getLimitedValue();
1237 : 0 : AstNode *size_node = trans_create_node_unsigned(c, size);
1238 : 0 : return trans_create_node_array_type(c, size_node, child_type_node);
1239 : : }
1240 : 0 : case ZigClangType_Paren:
1241 : : {
1242 : 0 : const clang::ParenType *paren_ty = reinterpret_cast<const clang::ParenType *>(ty);
1243 : 0 : return trans_qual_type(c, bitcast(paren_ty->getInnerType()), source_loc);
1244 : : }
1245 : 0 : case ZigClangType_Decayed:
1246 : : {
1247 : 0 : const clang::DecayedType *decayed_ty = reinterpret_cast<const clang::DecayedType *>(ty);
1248 : 0 : return trans_qual_type(c, bitcast(decayed_ty->getDecayedType()), source_loc);
1249 : : }
1250 : 0 : case ZigClangType_Attributed:
1251 : : {
1252 : 0 : const clang::AttributedType *attributed_ty = reinterpret_cast<const clang::AttributedType *>(ty);
1253 : 0 : return trans_qual_type(c, bitcast(attributed_ty->getEquivalentType()), source_loc);
1254 : : }
1255 : 0 : case ZigClangType_IncompleteArray:
1256 : : {
1257 : 0 : const clang::IncompleteArrayType *incomplete_array_ty = reinterpret_cast<const clang::IncompleteArrayType *>(ty);
1258 : 0 : ZigClangQualType child_qt = bitcast(incomplete_array_ty->getElementType());
1259 : 0 : AstNode *child_type_node = trans_qual_type(c, child_qt, source_loc);
1260 [ # # ]: 0 : if (child_type_node == nullptr) {
1261 : 0 : emit_warning(c, source_loc, "unresolved array element type");
1262 : 0 : return nullptr;
1263 : : }
1264 : 0 : AstNode *pointer_node = trans_create_node_ptr_type(c,
1265 : 0 : ZigClangQualType_isConstQualified(child_qt),
1266 : 0 : ZigClangQualType_isVolatileQualified(child_qt),
1267 : 0 : child_type_node, PtrLenC);
1268 : 0 : return pointer_node;
1269 : : }
1270 : 0 : case ZigClangType_BlockPointer:
1271 : : case ZigClangType_LValueReference:
1272 : : case ZigClangType_RValueReference:
1273 : : case ZigClangType_MemberPointer:
1274 : : case ZigClangType_VariableArray:
1275 : : case ZigClangType_DependentSizedArray:
1276 : : case ZigClangType_DependentSizedExtVector:
1277 : : case ZigClangType_Vector:
1278 : : case ZigClangType_ExtVector:
1279 : : case ZigClangType_UnresolvedUsing:
1280 : : case ZigClangType_Adjusted:
1281 : : case ZigClangType_TypeOfExpr:
1282 : : case ZigClangType_TypeOf:
1283 : : case ZigClangType_Decltype:
1284 : : case ZigClangType_UnaryTransform:
1285 : : case ZigClangType_TemplateTypeParm:
1286 : : case ZigClangType_SubstTemplateTypeParm:
1287 : : case ZigClangType_SubstTemplateTypeParmPack:
1288 : : case ZigClangType_TemplateSpecialization:
1289 : : case ZigClangType_Auto:
1290 : : case ZigClangType_InjectedClassName:
1291 : : case ZigClangType_DependentName:
1292 : : case ZigClangType_DependentTemplateSpecialization:
1293 : : case ZigClangType_PackExpansion:
1294 : : case ZigClangType_ObjCObject:
1295 : : case ZigClangType_ObjCInterface:
1296 : : case ZigClangType_Complex:
1297 : : case ZigClangType_ObjCObjectPointer:
1298 : : case ZigClangType_Atomic:
1299 : : case ZigClangType_Pipe:
1300 : : case ZigClangType_ObjCTypeParam:
1301 : : case ZigClangType_DeducedTemplateSpecialization:
1302 : : case ZigClangType_DependentAddressSpace:
1303 : : case ZigClangType_DependentVector:
1304 : 0 : emit_warning(c, source_loc, "unsupported type: '%s'", ZigClangType_getTypeClassName(ty));
1305 : 0 : return nullptr;
1306 : : }
1307 : 0 : zig_unreachable();
1308 : : }
1309 : :
1310 : 0 : static AstNode *trans_qual_type(Context *c, ZigClangQualType qt, ZigClangSourceLocation source_loc) {
1311 : 0 : return trans_type(c, ZigClangQualType_getTypePtr(qt), source_loc);
1312 : : }
1313 : :
1314 : 0 : static int trans_compound_stmt_inline(Context *c, TransScope *scope, const ZigClangCompoundStmt *stmt,
1315 : : AstNode *block_node, TransScope **out_node_scope)
1316 : : {
1317 [ # # ]: 0 : assert(block_node->type == NodeTypeBlock);
1318 : 0 : for (ZigClangCompoundStmt_const_body_iterator it = ZigClangCompoundStmt_body_begin(stmt),
1319 [ # # ]: 0 : end_it = ZigClangCompoundStmt_body_end(stmt); it != end_it; ++it)
1320 : : {
1321 : : AstNode *child_node;
1322 : 0 : scope = trans_stmt(c, scope, *it, &child_node);
1323 [ # # ]: 0 : if (scope == nullptr)
1324 : 0 : return ErrorUnexpected;
1325 [ # # ]: 0 : if (child_node != nullptr)
1326 : 0 : block_node->data.block.statements.append(child_node);
1327 : : }
1328 [ # # ]: 0 : if (out_node_scope != nullptr) {
1329 : 0 : *out_node_scope = scope;
1330 : : }
1331 : 0 : return ErrorNone;
1332 : : }
1333 : :
1334 : 0 : static AstNode *trans_compound_stmt(Context *c, TransScope *scope, const ZigClangCompoundStmt *stmt,
1335 : : TransScope **out_node_scope)
1336 : : {
1337 : 0 : TransScopeBlock *child_scope_block = trans_scope_block_create(c, scope);
1338 [ # # ]: 0 : if (trans_compound_stmt_inline(c, &child_scope_block->base, stmt, child_scope_block->node, out_node_scope))
1339 : 0 : return nullptr;
1340 : 0 : return child_scope_block->node;
1341 : : }
1342 : :
1343 : 0 : static AstNode *trans_stmt_expr(Context *c, ResultUsed result_used, TransScope *scope,
1344 : : const clang::StmtExpr *stmt, TransScope **out_node_scope)
1345 : : {
1346 : 0 : AstNode *block = trans_compound_stmt(c, scope, (const ZigClangCompoundStmt *)stmt->getSubStmt(), out_node_scope);
1347 [ # # ]: 0 : if (block == nullptr)
1348 : 0 : return block;
1349 [ # # ]: 0 : assert(block->type == NodeTypeBlock);
1350 [ # # ]: 0 : if (block->data.block.statements.length == 0)
1351 : 0 : return block;
1352 : :
1353 : 0 : Buf *label = buf_create_from_str("x");
1354 : 0 : block->data.block.name = label;
1355 : 0 : AstNode *return_expr = block->data.block.statements.pop();
1356 [ # # ][ # # ]: 0 : if (return_expr->type == NodeTypeBinOpExpr &&
1357 [ # # ]: 0 : return_expr->data.bin_op_expr.bin_op == BinOpTypeAssign &&
1358 : 0 : return_expr->data.bin_op_expr.op1->type == NodeTypeSymbol)
1359 : : {
1360 : 0 : Buf *symbol_buf = return_expr->data.bin_op_expr.op1->data.symbol_expr.symbol;
1361 [ # # ]: 0 : if (strcmp("_", buf_ptr(symbol_buf)) == 0)
1362 : 0 : return_expr = return_expr->data.bin_op_expr.op2;
1363 : : }
1364 : 0 : block->data.block.statements.append(trans_create_node_break(c, label, return_expr));
1365 : 0 : return maybe_suppress_result(c, result_used, block);
1366 : : }
1367 : :
1368 : 0 : static AstNode *trans_return_stmt(Context *c, TransScope *scope, const clang::ReturnStmt *stmt) {
1369 : 0 : const ZigClangExpr *value_expr = bitcast(stmt->getRetValue());
1370 [ # # ]: 0 : if (value_expr == nullptr) {
1371 : 0 : return trans_create_node(c, NodeTypeReturnExpr);
1372 : : } else {
1373 : 0 : AstNode *return_node = trans_create_node(c, NodeTypeReturnExpr);
1374 : 0 : return_node->data.return_expr.expr = trans_expr(c, ResultUsedYes, scope, value_expr, TransRValue);
1375 [ # # ]: 0 : if (return_node->data.return_expr.expr == nullptr)
1376 : 0 : return nullptr;
1377 : 0 : return return_node;
1378 : : }
1379 : : }
1380 : :
1381 : 0 : static AstNode *trans_integer_literal(Context *c, ResultUsed result_used, const clang::IntegerLiteral *stmt) {
1382 : 0 : clang::Expr::EvalResult result;
1383 [ # # ]: 0 : if (!stmt->EvaluateAsInt(result, *reinterpret_cast<clang::ASTContext *>(c->ctx))) {
1384 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "invalid integer literal");
1385 : 0 : return nullptr;
1386 : : }
1387 : 0 : AstNode *node = trans_create_node_apint(c, bitcast(&result.Val.getInt()));
1388 : 0 : return maybe_suppress_result(c, result_used, node);
1389 : : }
1390 : :
1391 : 0 : static AstNode *trans_floating_literal(Context *c, ResultUsed result_used, const clang::FloatingLiteral *stmt) {
1392 : 0 : llvm::APFloat result{0.0f};
1393 [ # # ]: 0 : if (!stmt->EvaluateAsFloat(result, *reinterpret_cast<clang::ASTContext *>(c->ctx))) {
1394 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "invalid floating literal");
1395 : 0 : return nullptr;
1396 : : }
1397 : 0 : AstNode *node = trans_create_node_apfloat(c, result);
1398 : 0 : return maybe_suppress_result(c, result_used, node);
1399 : : }
1400 : :
1401 : 0 : static AstNode *trans_character_literal(Context *c, ResultUsed result_used, const clang::CharacterLiteral *stmt) {
1402 [ # # # # : 0 : switch (stmt->getKind()) {
# # ]
1403 : 0 : case clang::CharacterLiteral::CharacterKind::Ascii:
1404 : : {
1405 : 0 : unsigned val = stmt->getValue();
1406 : : // C has a somewhat obscure feature called multi-character character
1407 : : // constant
1408 [ # # ]: 0 : if (val > 255)
1409 : 0 : return trans_create_node_unsigned(c, val);
1410 : : }
1411 : : // fallthrough
1412 : : case clang::CharacterLiteral::CharacterKind::UTF8:
1413 : : {
1414 : 0 : AstNode *node = trans_create_node(c, NodeTypeCharLiteral);
1415 : 0 : node->data.char_literal.value = stmt->getValue();
1416 : 0 : return maybe_suppress_result(c, result_used, node);
1417 : : }
1418 : 0 : case clang::CharacterLiteral::CharacterKind::UTF16:
1419 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO support UTF16 character literals");
1420 : 0 : return nullptr;
1421 : 0 : case clang::CharacterLiteral::CharacterKind::UTF32:
1422 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO support UTF32 character literals");
1423 : 0 : return nullptr;
1424 : 0 : case clang::CharacterLiteral::CharacterKind::Wide:
1425 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO support wide character literals");
1426 : 0 : return nullptr;
1427 : : }
1428 : 0 : zig_unreachable();
1429 : : }
1430 : :
1431 : 0 : static AstNode *trans_constant_expr(Context *c, ResultUsed result_used, const clang::ConstantExpr *expr) {
1432 : 0 : clang::Expr::EvalResult result;
1433 [ # # ]: 0 : if (!expr->EvaluateAsConstantExpr(result, clang::Expr::EvaluateForCodeGen,
1434 : 0 : *reinterpret_cast<clang::ASTContext *>(c->ctx)))
1435 : : {
1436 : 0 : emit_warning(c, bitcast(expr->getBeginLoc()), "invalid constant expression");
1437 : 0 : return nullptr;
1438 : : }
1439 : 0 : AstNode *node = trans_ap_value(c, bitcast(&result.Val), bitcast(expr->getType()), bitcast(expr->getBeginLoc()));
1440 : 0 : return maybe_suppress_result(c, result_used, node);
1441 : : }
1442 : :
1443 : 0 : static AstNode *trans_conditional_operator(Context *c, ResultUsed result_used, TransScope *scope,
1444 : : const clang::ConditionalOperator *stmt)
1445 : : {
1446 : 0 : AstNode *node = trans_create_node(c, NodeTypeIfBoolExpr);
1447 : :
1448 : 0 : const ZigClangExpr *cond_expr = bitcast(stmt->getCond());
1449 : 0 : const ZigClangExpr *true_expr = bitcast(stmt->getTrueExpr());
1450 : 0 : const ZigClangExpr *false_expr = bitcast(stmt->getFalseExpr());
1451 : :
1452 : 0 : node->data.if_bool_expr.condition = trans_expr(c, ResultUsedYes, scope, cond_expr, TransRValue);
1453 [ # # ]: 0 : if (node->data.if_bool_expr.condition == nullptr)
1454 : 0 : return nullptr;
1455 : :
1456 : 0 : node->data.if_bool_expr.then_block = trans_expr(c, result_used, scope, true_expr, TransRValue);
1457 [ # # ]: 0 : if (node->data.if_bool_expr.then_block == nullptr)
1458 : 0 : return nullptr;
1459 : :
1460 : 0 : node->data.if_bool_expr.else_node = trans_expr(c, result_used, scope, false_expr, TransRValue);
1461 [ # # ]: 0 : if (node->data.if_bool_expr.else_node == nullptr)
1462 : 0 : return nullptr;
1463 : :
1464 : 0 : return maybe_suppress_result(c, result_used, node);
1465 : : }
1466 : :
1467 : 0 : static AstNode *trans_create_bin_op(Context *c, TransScope *scope, const ZigClangExpr *lhs,
1468 : : BinOpType bin_op, const ZigClangExpr *rhs)
1469 : : {
1470 : 0 : AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
1471 : 0 : node->data.bin_op_expr.bin_op = bin_op;
1472 : :
1473 : 0 : node->data.bin_op_expr.op1 = trans_expr(c, ResultUsedYes, scope, lhs, TransRValue);
1474 [ # # ]: 0 : if (node->data.bin_op_expr.op1 == nullptr)
1475 : 0 : return nullptr;
1476 : :
1477 : 0 : node->data.bin_op_expr.op2 = trans_expr(c, ResultUsedYes, scope, rhs, TransRValue);
1478 [ # # ]: 0 : if (node->data.bin_op_expr.op2 == nullptr)
1479 : 0 : return nullptr;
1480 : :
1481 : 0 : return node;
1482 : : }
1483 : :
1484 : 0 : static AstNode *trans_create_bool_bin_op(Context *c, TransScope *scope, const ZigClangExpr *lhs,
1485 : : BinOpType bin_op, const ZigClangExpr *rhs)
1486 : : {
1487 [ # # ][ # # ]: 0 : assert(bin_op == BinOpTypeBoolAnd || bin_op == BinOpTypeBoolOr);
1488 : 0 : AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
1489 : 0 : node->data.bin_op_expr.bin_op = bin_op;
1490 : :
1491 : 0 : node->data.bin_op_expr.op1 = trans_bool_expr(c, ResultUsedYes, scope, lhs, TransRValue);
1492 [ # # ]: 0 : if (node->data.bin_op_expr.op1 == nullptr)
1493 : 0 : return nullptr;
1494 : :
1495 : 0 : node->data.bin_op_expr.op2 = trans_bool_expr(c, ResultUsedYes, scope, rhs, TransRValue);
1496 [ # # ]: 0 : if (node->data.bin_op_expr.op2 == nullptr)
1497 : 0 : return nullptr;
1498 : :
1499 : 0 : return node;
1500 : : }
1501 : :
1502 : 0 : static AstNode *trans_create_assign(Context *c, ResultUsed result_used, TransScope *scope,
1503 : : const ZigClangExpr *lhs, const ZigClangExpr *rhs)
1504 : : {
1505 [ # # ]: 0 : if (result_used == ResultUsedNo) {
1506 : : // common case
1507 : 0 : AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
1508 : 0 : node->data.bin_op_expr.bin_op = BinOpTypeAssign;
1509 : :
1510 : 0 : node->data.bin_op_expr.op1 = trans_expr(c, ResultUsedYes, scope, lhs, TransLValue);
1511 [ # # ]: 0 : if (node->data.bin_op_expr.op1 == nullptr)
1512 : 0 : return nullptr;
1513 : :
1514 : 0 : node->data.bin_op_expr.op2 = trans_expr(c, ResultUsedYes, scope, rhs, TransRValue);
1515 [ # # ]: 0 : if (node->data.bin_op_expr.op2 == nullptr)
1516 : 0 : return nullptr;
1517 : :
1518 : 0 : return node;
1519 : : } else {
1520 : : // worst case
1521 : : // c: lhs = rhs
1522 : : // zig: (x: {
1523 : : // zig: const _tmp = rhs;
1524 : : // zig: lhs = _tmp;
1525 : : // zig: break :x _tmp
1526 : : // zig: })
1527 : :
1528 : 0 : TransScopeBlock *child_scope = trans_scope_block_create(c, scope);
1529 : 0 : Buf *label_name = buf_create_from_str("x");
1530 : 0 : child_scope->node->data.block.name = label_name;
1531 : :
1532 : : // const _tmp = rhs;
1533 : 0 : AstNode *rhs_node = trans_expr(c, ResultUsedYes, &child_scope->base, rhs, TransRValue);
1534 [ # # ]: 0 : if (rhs_node == nullptr) return nullptr;
1535 : : // TODO: avoid name collisions with generated variable names
1536 : 0 : Buf* tmp_var_name = buf_create_from_str("_tmp");
1537 : 0 : AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr, rhs_node);
1538 : 0 : child_scope->node->data.block.statements.append(tmp_var_decl);
1539 : :
1540 : : // lhs = _tmp;
1541 : 0 : AstNode *lhs_node = trans_expr(c, ResultUsedYes, &child_scope->base, lhs, TransLValue);
1542 [ # # ]: 0 : if (lhs_node == nullptr) return nullptr;
1543 : 0 : child_scope->node->data.block.statements.append(
1544 : : trans_create_node_bin_op(c, lhs_node, BinOpTypeAssign,
1545 : : trans_create_node_symbol(c, tmp_var_name)));
1546 : :
1547 : : // break :x _tmp
1548 : 0 : AstNode *tmp_symbol_node = trans_create_node_symbol(c, tmp_var_name);
1549 : 0 : child_scope->node->data.block.statements.append(trans_create_node_break(c, label_name, tmp_symbol_node));
1550 : :
1551 : 0 : return trans_create_node_grouped_expr(c, child_scope->node);
1552 : : }
1553 : : }
1554 : :
1555 : 0 : static AstNode *trans_create_shift_op(Context *c, TransScope *scope, ZigClangQualType result_type,
1556 : : const ZigClangExpr *lhs_expr, BinOpType bin_op, const ZigClangExpr *rhs_expr)
1557 : : {
1558 : 0 : ZigClangSourceLocation rhs_location = ZigClangExpr_getBeginLoc(rhs_expr);
1559 : 0 : AstNode *rhs_type = qual_type_to_log2_int_ref(c, result_type, rhs_location);
1560 : : // lhs >> u5(rh)
1561 : :
1562 : 0 : AstNode *lhs = trans_expr(c, ResultUsedYes, scope, lhs_expr, TransLValue);
1563 [ # # ]: 0 : if (lhs == nullptr) return nullptr;
1564 : :
1565 : 0 : AstNode *rhs = trans_expr(c, ResultUsedYes, scope, rhs_expr, TransRValue);
1566 [ # # ]: 0 : if (rhs == nullptr) return nullptr;
1567 : 0 : AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs);
1568 : :
1569 : 0 : return trans_create_node_bin_op(c, lhs, bin_op, coerced_rhs);
1570 : : }
1571 : :
1572 : 0 : static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransScope *scope, const clang::BinaryOperator *stmt) {
1573 [ # # # # : 0 : switch (stmt->getOpcode()) {
# # # # #
# # # # #
# # # # #
# # # # #
# ]
1574 : 0 : case clang::BO_PtrMemD:
1575 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle more C binary operators: BO_PtrMemD");
1576 : 0 : return nullptr;
1577 : 0 : case clang::BO_PtrMemI:
1578 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle more C binary operators: BO_PtrMemI");
1579 : 0 : return nullptr;
1580 : 0 : case clang::BO_Cmp:
1581 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle more C binary operators: BO_Cmp");
1582 : 0 : return nullptr;
1583 : 0 : case clang::BO_Mul: {
1584 [ # # ]: 0 : AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()),
1585 : 0 : qual_type_has_wrapping_overflow(c, bitcast(stmt->getType())) ? BinOpTypeMultWrap : BinOpTypeMult,
1586 : 0 : bitcast(stmt->getRHS()));
1587 : 0 : return maybe_suppress_result(c, result_used, node);
1588 : : }
1589 : 0 : case clang::BO_Div:
1590 [ # # ]: 0 : if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType()))) {
1591 : : // unsigned/float division uses the operator
1592 : 0 : AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeDiv, bitcast(stmt->getRHS()));
1593 : 0 : return maybe_suppress_result(c, result_used, node);
1594 : : } else {
1595 : : // signed integer division uses @divTrunc
1596 : 0 : AstNode *fn_call = trans_create_node_builtin_fn_call_str(c, "divTrunc");
1597 : 0 : AstNode *lhs = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getLHS()), TransLValue);
1598 [ # # ]: 0 : if (lhs == nullptr) return nullptr;
1599 : 0 : fn_call->data.fn_call_expr.params.append(lhs);
1600 : 0 : AstNode *rhs = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getRHS()), TransLValue);
1601 [ # # ]: 0 : if (rhs == nullptr) return nullptr;
1602 : 0 : fn_call->data.fn_call_expr.params.append(rhs);
1603 : 0 : return maybe_suppress_result(c, result_used, fn_call);
1604 : : }
1605 : 0 : case clang::BO_Rem:
1606 [ # # ]: 0 : if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType()))) {
1607 : : // unsigned/float division uses the operator
1608 : 0 : AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeMod, bitcast(stmt->getRHS()));
1609 : 0 : return maybe_suppress_result(c, result_used, node);
1610 : : } else {
1611 : : // signed integer division uses @rem
1612 : 0 : AstNode *fn_call = trans_create_node_builtin_fn_call_str(c, "rem");
1613 : 0 : AstNode *lhs = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getLHS()), TransLValue);
1614 [ # # ]: 0 : if (lhs == nullptr) return nullptr;
1615 : 0 : fn_call->data.fn_call_expr.params.append(lhs);
1616 : 0 : AstNode *rhs = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getRHS()), TransLValue);
1617 [ # # ]: 0 : if (rhs == nullptr) return nullptr;
1618 : 0 : fn_call->data.fn_call_expr.params.append(rhs);
1619 : 0 : return maybe_suppress_result(c, result_used, fn_call);
1620 : : }
1621 : 0 : case clang::BO_Add: {
1622 [ # # ]: 0 : AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()),
1623 : 0 : qual_type_has_wrapping_overflow(c, bitcast(stmt->getType())) ? BinOpTypeAddWrap : BinOpTypeAdd,
1624 : 0 : bitcast(stmt->getRHS()));
1625 : 0 : return maybe_suppress_result(c, result_used, node);
1626 : : }
1627 : 0 : case clang::BO_Sub: {
1628 [ # # ]: 0 : AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()),
1629 : 0 : qual_type_has_wrapping_overflow(c, bitcast(stmt->getType())) ? BinOpTypeSubWrap : BinOpTypeSub,
1630 : 0 : bitcast(stmt->getRHS()));
1631 : 0 : return maybe_suppress_result(c, result_used, node);
1632 : : }
1633 : 0 : case clang::BO_Shl: {
1634 : 0 : AstNode *node = trans_create_shift_op(c, scope, bitcast(stmt->getType()), bitcast(stmt->getLHS()), BinOpTypeBitShiftLeft, bitcast(stmt->getRHS()));
1635 : 0 : return maybe_suppress_result(c, result_used, node);
1636 : : }
1637 : 0 : case clang::BO_Shr: {
1638 : 0 : AstNode *node = trans_create_shift_op(c, scope, bitcast(stmt->getType()), bitcast(stmt->getLHS()), BinOpTypeBitShiftRight, bitcast(stmt->getRHS()));
1639 : 0 : return maybe_suppress_result(c, result_used, node);
1640 : : }
1641 : 0 : case clang::BO_LT: {
1642 : 0 : AstNode *node =trans_create_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeCmpLessThan, bitcast(stmt->getRHS()));
1643 : 0 : return maybe_suppress_result(c, result_used, node);
1644 : : }
1645 : 0 : case clang::BO_GT: {
1646 : 0 : AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeCmpGreaterThan, bitcast(stmt->getRHS()));
1647 : 0 : return maybe_suppress_result(c, result_used, node);
1648 : : }
1649 : 0 : case clang::BO_LE: {
1650 : 0 : AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeCmpLessOrEq, bitcast(stmt->getRHS()));
1651 : 0 : return maybe_suppress_result(c, result_used, node);
1652 : : }
1653 : 0 : case clang::BO_GE: {
1654 : 0 : AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeCmpGreaterOrEq, bitcast(stmt->getRHS()));
1655 : 0 : return maybe_suppress_result(c, result_used, node);
1656 : : }
1657 : 0 : case clang::BO_EQ: {
1658 : 0 : AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeCmpEq, bitcast(stmt->getRHS()));
1659 : 0 : return maybe_suppress_result(c, result_used, node);
1660 : : }
1661 : 0 : case clang::BO_NE: {
1662 : 0 : AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeCmpNotEq, bitcast(stmt->getRHS()));
1663 : 0 : return maybe_suppress_result(c, result_used, node);
1664 : : }
1665 : 0 : case clang::BO_And: {
1666 : 0 : AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeBinAnd, bitcast(stmt->getRHS()));
1667 : 0 : return maybe_suppress_result(c, result_used, node);
1668 : : }
1669 : 0 : case clang::BO_Xor: {
1670 : 0 : AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeBinXor, bitcast(stmt->getRHS()));
1671 : 0 : return maybe_suppress_result(c, result_used, node);
1672 : : }
1673 : 0 : case clang::BO_Or: {
1674 : 0 : AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeBinOr, bitcast(stmt->getRHS()));
1675 : 0 : return maybe_suppress_result(c, result_used, node);
1676 : : }
1677 : 0 : case clang::BO_LAnd: {
1678 : 0 : AstNode *node = trans_create_bool_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeBoolAnd, bitcast(stmt->getRHS()));
1679 : 0 : return maybe_suppress_result(c, result_used, node);
1680 : : }
1681 : 0 : case clang::BO_LOr: {
1682 : 0 : AstNode *node = trans_create_bool_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeBoolOr, bitcast(stmt->getRHS()));
1683 : 0 : return maybe_suppress_result(c, result_used, node);
1684 : : }
1685 : 0 : case clang::BO_Assign:
1686 : 0 : return trans_create_assign(c, result_used, scope, bitcast(stmt->getLHS()), bitcast(stmt->getRHS()));
1687 : 0 : case clang::BO_Comma:
1688 : : {
1689 : 0 : TransScopeBlock *scope_block = trans_scope_block_create(c, scope);
1690 : 0 : Buf *label_name = buf_create_from_str("x");
1691 : 0 : scope_block->node->data.block.name = label_name;
1692 : :
1693 : 0 : AstNode *lhs = trans_expr(c, ResultUsedNo, &scope_block->base, bitcast(stmt->getLHS()), TransRValue);
1694 [ # # ]: 0 : if (lhs == nullptr)
1695 : 0 : return nullptr;
1696 : 0 : scope_block->node->data.block.statements.append(lhs);
1697 : :
1698 : 0 : AstNode *rhs = trans_expr(c, ResultUsedYes, &scope_block->base, bitcast(stmt->getRHS()), TransRValue);
1699 [ # # ]: 0 : if (rhs == nullptr)
1700 : 0 : return nullptr;
1701 : :
1702 : 0 : rhs = trans_create_node_break(c, label_name, rhs);
1703 : 0 : scope_block->node->data.block.statements.append(rhs);
1704 : 0 : return maybe_suppress_result(c, result_used, scope_block->node);
1705 : : }
1706 : 0 : case clang::BO_MulAssign:
1707 : : case clang::BO_DivAssign:
1708 : : case clang::BO_RemAssign:
1709 : : case clang::BO_AddAssign:
1710 : : case clang::BO_SubAssign:
1711 : : case clang::BO_ShlAssign:
1712 : : case clang::BO_ShrAssign:
1713 : : case clang::BO_AndAssign:
1714 : : case clang::BO_XorAssign:
1715 : : case clang::BO_OrAssign:
1716 : 0 : zig_unreachable();
1717 : : }
1718 : :
1719 : 0 : zig_unreachable();
1720 : : }
1721 : :
1722 : 0 : static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result_used, TransScope *scope,
1723 : : const clang::CompoundAssignOperator *stmt, BinOpType assign_op, BinOpType bin_op)
1724 : : {
1725 : 0 : ZigClangSourceLocation rhs_location = bitcast(stmt->getRHS()->getBeginLoc());
1726 : 0 : AstNode *rhs_type = qual_type_to_log2_int_ref(c, bitcast(stmt->getComputationLHSType()), rhs_location);
1727 : :
1728 : 0 : bool use_intermediate_casts = stmt->getComputationLHSType().getTypePtr() != stmt->getComputationResultType().getTypePtr();
1729 [ # # ][ # # ]: 0 : if (!use_intermediate_casts && result_used == ResultUsedNo) {
1730 : : // simple common case, where the C and Zig are identical:
1731 : : // lhs >>= rhs
1732 : 0 : AstNode *lhs = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getLHS()), TransLValue);
1733 [ # # ]: 0 : if (lhs == nullptr) return nullptr;
1734 : :
1735 : 0 : AstNode *rhs = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getRHS()), TransRValue);
1736 [ # # ]: 0 : if (rhs == nullptr) return nullptr;
1737 : 0 : AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs);
1738 : :
1739 : 0 : return trans_create_node_bin_op(c, lhs, assign_op, coerced_rhs);
1740 : : } else {
1741 : : // need more complexity. worst case, this looks like this:
1742 : : // c: lhs >>= rhs
1743 : : // zig: (x: {
1744 : : // zig: const _ref = &lhs;
1745 : : // zig: *_ref = result_type(operation_type(*_ref) >> u5(rhs));
1746 : : // zig: break :x *_ref
1747 : : // zig: })
1748 : : // where u5 is the appropriate type
1749 : :
1750 : 0 : TransScopeBlock *child_scope = trans_scope_block_create(c, scope);
1751 : 0 : Buf *label_name = buf_create_from_str("x");
1752 : 0 : child_scope->node->data.block.name = label_name;
1753 : :
1754 : : // const _ref = &lhs;
1755 : 0 : AstNode *lhs = trans_expr(c, ResultUsedYes, &child_scope->base, bitcast(stmt->getLHS()), TransLValue);
1756 [ # # ]: 0 : if (lhs == nullptr) return nullptr;
1757 : 0 : AstNode *addr_of_lhs = trans_create_node_addr_of(c, lhs);
1758 : : // TODO: avoid name collisions with generated variable names
1759 : 0 : Buf* tmp_var_name = buf_create_from_str("_ref");
1760 : 0 : AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr, addr_of_lhs);
1761 : 0 : child_scope->node->data.block.statements.append(tmp_var_decl);
1762 : :
1763 : : // *_ref = result_type(operation_type(*_ref) >> u5(rhs));
1764 : :
1765 : 0 : AstNode *rhs = trans_expr(c, ResultUsedYes, &child_scope->base, bitcast(stmt->getRHS()), TransRValue);
1766 [ # # ]: 0 : if (rhs == nullptr) return nullptr;
1767 : 0 : AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs);
1768 : :
1769 : : // operation_type(*_ref)
1770 : 0 : AstNode *operation_type_cast = trans_c_cast(c, rhs_location,
1771 : : bitcast(stmt->getComputationLHSType()),
1772 : : bitcast(stmt->getLHS()->getType()),
1773 : 0 : trans_create_node_ptr_deref(c, trans_create_node_symbol(c, tmp_var_name)));
1774 : :
1775 : : // result_type(... >> u5(rhs))
1776 : 0 : AstNode *result_type_cast = trans_c_cast(c, rhs_location,
1777 : : bitcast(stmt->getComputationResultType()),
1778 : : bitcast(stmt->getComputationLHSType()),
1779 : : trans_create_node_bin_op(c,
1780 : : operation_type_cast,
1781 : : bin_op,
1782 : 0 : coerced_rhs));
1783 : :
1784 : : // *_ref = ...
1785 : 0 : AstNode *assign_statement = trans_create_node_bin_op(c,
1786 : : trans_create_node_ptr_deref(c,
1787 : : trans_create_node_symbol(c, tmp_var_name)),
1788 : 0 : BinOpTypeAssign, result_type_cast);
1789 : :
1790 : 0 : child_scope->node->data.block.statements.append(assign_statement);
1791 : :
1792 [ # # ]: 0 : if (result_used == ResultUsedYes) {
1793 : : // break :x *_ref
1794 : 0 : child_scope->node->data.block.statements.append(
1795 : : trans_create_node_break(c, label_name,
1796 : : trans_create_node_ptr_deref(c,
1797 : : trans_create_node_symbol(c, tmp_var_name))));
1798 : : }
1799 : :
1800 : 0 : return trans_create_node_grouped_expr(c, child_scope->node);
1801 : : }
1802 : : }
1803 : :
1804 : 0 : static AstNode *trans_create_compound_assign(Context *c, ResultUsed result_used, TransScope *scope,
1805 : : const clang::CompoundAssignOperator *stmt, BinOpType assign_op, BinOpType bin_op)
1806 : : {
1807 [ # # ]: 0 : if (result_used == ResultUsedNo) {
1808 : : // simple common case, where the C and Zig are identical:
1809 : : // lhs += rhs
1810 : 0 : AstNode *lhs = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getLHS()), TransLValue);
1811 [ # # ]: 0 : if (lhs == nullptr) return nullptr;
1812 : 0 : AstNode *rhs = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getRHS()), TransRValue);
1813 [ # # ]: 0 : if (rhs == nullptr) return nullptr;
1814 : 0 : return trans_create_node_bin_op(c, lhs, assign_op, rhs);
1815 : : } else {
1816 : : // need more complexity. worst case, this looks like this:
1817 : : // c: lhs += rhs
1818 : : // zig: (x: {
1819 : : // zig: const _ref = &lhs;
1820 : : // zig: *_ref = *_ref + rhs;
1821 : : // zig: break :x *_ref
1822 : : // zig: })
1823 : :
1824 : 0 : TransScopeBlock *child_scope = trans_scope_block_create(c, scope);
1825 : 0 : Buf *label_name = buf_create_from_str("x");
1826 : 0 : child_scope->node->data.block.name = label_name;
1827 : :
1828 : : // const _ref = &lhs;
1829 : 0 : AstNode *lhs = trans_expr(c, ResultUsedYes, &child_scope->base, bitcast(stmt->getLHS()), TransLValue);
1830 [ # # ]: 0 : if (lhs == nullptr) return nullptr;
1831 : 0 : AstNode *addr_of_lhs = trans_create_node_addr_of(c, lhs);
1832 : : // TODO: avoid name collisions with generated variable names
1833 : 0 : Buf* tmp_var_name = buf_create_from_str("_ref");
1834 : 0 : AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr, addr_of_lhs);
1835 : 0 : child_scope->node->data.block.statements.append(tmp_var_decl);
1836 : :
1837 : : // *_ref = *_ref + rhs;
1838 : :
1839 : 0 : AstNode *rhs = trans_expr(c, ResultUsedYes, &child_scope->base, bitcast(stmt->getRHS()), TransRValue);
1840 [ # # ]: 0 : if (rhs == nullptr) return nullptr;
1841 : :
1842 : 0 : AstNode *assign_statement = trans_create_node_bin_op(c,
1843 : : trans_create_node_ptr_deref(c,
1844 : : trans_create_node_symbol(c, tmp_var_name)),
1845 : : BinOpTypeAssign,
1846 : : trans_create_node_bin_op(c,
1847 : : trans_create_node_ptr_deref(c,
1848 : : trans_create_node_symbol(c, tmp_var_name)),
1849 : : bin_op,
1850 : 0 : rhs));
1851 : 0 : child_scope->node->data.block.statements.append(assign_statement);
1852 : :
1853 : : // break :x *_ref
1854 : 0 : child_scope->node->data.block.statements.append(
1855 : : trans_create_node_break(c, label_name,
1856 : : trans_create_node_ptr_deref(c,
1857 : : trans_create_node_symbol(c, tmp_var_name))));
1858 : :
1859 : 0 : return trans_create_node_grouped_expr(c, child_scope->node);
1860 : : }
1861 : : }
1862 : :
1863 : :
1864 : 0 : static AstNode *trans_compound_assign_operator(Context *c, ResultUsed result_used, TransScope *scope,
1865 : : const clang::CompoundAssignOperator *stmt)
1866 : : {
1867 [ # # # # : 0 : switch (stmt->getOpcode()) {
# # # # #
# # # # ]
1868 : 0 : case clang::BO_MulAssign:
1869 [ # # ]: 0 : if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType())))
1870 : 0 : return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignTimesWrap, BinOpTypeMultWrap);
1871 : : else
1872 : 0 : return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignTimes, BinOpTypeMult);
1873 : 0 : case clang::BO_DivAssign:
1874 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle more C compound assign operators: BO_DivAssign");
1875 : 0 : return nullptr;
1876 : 0 : case clang::BO_RemAssign:
1877 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle more C compound assign operators: BO_RemAssign");
1878 : 0 : return nullptr;
1879 : 0 : case clang::BO_Cmp:
1880 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle more C compound assign operators: BO_Cmp");
1881 : 0 : return nullptr;
1882 : 0 : case clang::BO_AddAssign:
1883 [ # # ]: 0 : if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType())))
1884 : 0 : return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignPlusWrap, BinOpTypeAddWrap);
1885 : : else
1886 : 0 : return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignPlus, BinOpTypeAdd);
1887 : 0 : case clang::BO_SubAssign:
1888 [ # # ]: 0 : if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType())))
1889 : 0 : return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignMinusWrap, BinOpTypeSubWrap);
1890 : : else
1891 : 0 : return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignMinus, BinOpTypeSub);
1892 : 0 : case clang::BO_ShlAssign:
1893 : 0 : return trans_create_compound_assign_shift(c, result_used, scope, stmt, BinOpTypeAssignBitShiftLeft, BinOpTypeBitShiftLeft);
1894 : 0 : case clang::BO_ShrAssign:
1895 : 0 : return trans_create_compound_assign_shift(c, result_used, scope, stmt, BinOpTypeAssignBitShiftRight, BinOpTypeBitShiftRight);
1896 : 0 : case clang::BO_AndAssign:
1897 : 0 : return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignBitAnd, BinOpTypeBinAnd);
1898 : 0 : case clang::BO_XorAssign:
1899 : 0 : return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignBitXor, BinOpTypeBinXor);
1900 : 0 : case clang::BO_OrAssign:
1901 : 0 : return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignBitOr, BinOpTypeBinOr);
1902 : 0 : case clang::BO_PtrMemD:
1903 : : case clang::BO_PtrMemI:
1904 : : case clang::BO_Assign:
1905 : : case clang::BO_Mul:
1906 : : case clang::BO_Div:
1907 : : case clang::BO_Rem:
1908 : : case clang::BO_Add:
1909 : : case clang::BO_Sub:
1910 : : case clang::BO_Shl:
1911 : : case clang::BO_Shr:
1912 : : case clang::BO_LT:
1913 : : case clang::BO_GT:
1914 : : case clang::BO_LE:
1915 : : case clang::BO_GE:
1916 : : case clang::BO_EQ:
1917 : : case clang::BO_NE:
1918 : : case clang::BO_And:
1919 : : case clang::BO_Xor:
1920 : : case clang::BO_Or:
1921 : : case clang::BO_LAnd:
1922 : : case clang::BO_LOr:
1923 : : case clang::BO_Comma:
1924 : 0 : zig_unreachable();
1925 : : }
1926 : :
1927 : 0 : zig_unreachable();
1928 : : }
1929 : :
1930 : 0 : static AstNode *trans_implicit_cast_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::ImplicitCastExpr *stmt) {
1931 [ # # # # : 0 : switch ((ZigClangCK)stmt->getCastKind()) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
1932 : 0 : case ZigClangCK_LValueToRValue:
1933 : 0 : return trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getSubExpr()), TransRValue);
1934 : 0 : case ZigClangCK_IntegralCast:
1935 : : {
1936 : 0 : AstNode *target_node = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getSubExpr()), TransRValue);
1937 [ # # ]: 0 : if (target_node == nullptr)
1938 : 0 : return nullptr;
1939 : 0 : AstNode *node = trans_c_cast(c, bitcast(stmt->getExprLoc()), bitcast(stmt->getType()),
1940 : 0 : bitcast(stmt->getSubExpr()->getType()), target_node);
1941 : 0 : return maybe_suppress_result(c, result_used, node);
1942 : : }
1943 : 0 : case ZigClangCK_FunctionToPointerDecay:
1944 : : case ZigClangCK_ArrayToPointerDecay:
1945 : : {
1946 : 0 : AstNode *target_node = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getSubExpr()), TransRValue);
1947 [ # # ]: 0 : if (target_node == nullptr)
1948 : 0 : return nullptr;
1949 : 0 : return maybe_suppress_result(c, result_used, target_node);
1950 : : }
1951 : 0 : case ZigClangCK_BitCast:
1952 : : {
1953 : 0 : AstNode *target_node = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getSubExpr()), TransRValue);
1954 [ # # ]: 0 : if (target_node == nullptr)
1955 : 0 : return nullptr;
1956 : :
1957 : 0 : const ZigClangQualType dest_type = get_expr_qual_type(c, bitcast(stmt));
1958 : 0 : const ZigClangQualType src_type = get_expr_qual_type(c, bitcast(stmt->getSubExpr()));
1959 : :
1960 : 0 : return trans_c_cast(c, bitcast(stmt->getBeginLoc()), dest_type, src_type, target_node);
1961 : : }
1962 : 0 : case ZigClangCK_NullToPointer:
1963 : 0 : return trans_create_node(c, NodeTypeNullLiteral);
1964 : 0 : case ZigClangCK_NoOp:
1965 : 0 : return trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getSubExpr()), TransRValue);
1966 : 0 : case ZigClangCK_Dependent:
1967 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_Dependent");
1968 : 0 : return nullptr;
1969 : 0 : case ZigClangCK_LValueBitCast:
1970 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_LValueBitCast");
1971 : 0 : return nullptr;
1972 : 0 : case ZigClangCK_BaseToDerived:
1973 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_BaseToDerived");
1974 : 0 : return nullptr;
1975 : 0 : case ZigClangCK_DerivedToBase:
1976 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_DerivedToBase");
1977 : 0 : return nullptr;
1978 : 0 : case ZigClangCK_UncheckedDerivedToBase:
1979 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_UncheckedDerivedToBase");
1980 : 0 : return nullptr;
1981 : 0 : case ZigClangCK_Dynamic:
1982 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_Dynamic");
1983 : 0 : return nullptr;
1984 : 0 : case ZigClangCK_ToUnion:
1985 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_ToUnion");
1986 : 0 : return nullptr;
1987 : 0 : case ZigClangCK_NullToMemberPointer:
1988 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_NullToMemberPointer");
1989 : 0 : return nullptr;
1990 : 0 : case ZigClangCK_BaseToDerivedMemberPointer:
1991 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_BaseToDerivedMemberPointer");
1992 : 0 : return nullptr;
1993 : 0 : case ZigClangCK_DerivedToBaseMemberPointer:
1994 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_DerivedToBaseMemberPointer");
1995 : 0 : return nullptr;
1996 : 0 : case ZigClangCK_MemberPointerToBoolean:
1997 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_MemberPointerToBoolean");
1998 : 0 : return nullptr;
1999 : 0 : case ZigClangCK_ReinterpretMemberPointer:
2000 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_ReinterpretMemberPointer");
2001 : 0 : return nullptr;
2002 : 0 : case ZigClangCK_UserDefinedConversion:
2003 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_UserDefinedConversion");
2004 : 0 : return nullptr;
2005 : 0 : case ZigClangCK_ConstructorConversion:
2006 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ConstructorConversion");
2007 : 0 : return nullptr;
2008 : 0 : case ZigClangCK_PointerToBoolean:
2009 : : {
2010 : 0 : const clang::Expr *expr = stmt->getSubExpr();
2011 : 0 : AstNode *val = trans_expr(c, ResultUsedYes, scope, bitcast(expr), TransRValue);
2012 [ # # ]: 0 : if (val == nullptr)
2013 : 0 : return nullptr;
2014 : :
2015 : 0 : AstNode *val_ptr = trans_create_node_builtin_fn_call_str(c, "ptrToInt");
2016 : 0 : val_ptr->data.fn_call_expr.params.append(val);
2017 : :
2018 : 0 : AstNode *zero = trans_create_node_unsigned(c, 0);
2019 : :
2020 : : // Translate as @ptrToInt((&val) != 0)
2021 : 0 : return trans_create_node_bin_op(c, val_ptr, BinOpTypeCmpNotEq, zero);
2022 : : }
2023 : 0 : case ZigClangCK_ToVoid:
2024 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ToVoid");
2025 : 0 : return nullptr;
2026 : 0 : case ZigClangCK_VectorSplat:
2027 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_VectorSplat");
2028 : 0 : return nullptr;
2029 : 0 : case ZigClangCK_IntegralToBoolean:
2030 : : {
2031 : 0 : const clang::Expr *expr = stmt->getSubExpr();
2032 : :
2033 : : bool expr_val;
2034 [ # # ]: 0 : if (expr->EvaluateAsBooleanCondition(expr_val, *reinterpret_cast<clang::ASTContext *>(c->ctx))) {
2035 : 0 : return trans_create_node_bool(c, expr_val);
2036 : : }
2037 : :
2038 : 0 : AstNode *val = trans_expr(c, ResultUsedYes, scope, bitcast(expr), TransRValue);
2039 [ # # ]: 0 : if (val == nullptr)
2040 : 0 : return nullptr;
2041 : :
2042 : 0 : AstNode *zero = trans_create_node_unsigned(c, 0);
2043 : :
2044 : : // Translate as val != 0
2045 : 0 : return trans_create_node_bin_op(c, val, BinOpTypeCmpNotEq, zero);
2046 : : }
2047 : 0 : case ZigClangCK_PointerToIntegral:
2048 : : {
2049 : 0 : AstNode *target_node = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getSubExpr()), TransRValue);
2050 [ # # ]: 0 : if (target_node == nullptr)
2051 : 0 : return nullptr;
2052 : :
2053 : 0 : AstNode *dest_type_node = get_expr_type(c, (const ZigClangExpr *)stmt);
2054 [ # # ]: 0 : if (dest_type_node == nullptr)
2055 : 0 : return nullptr;
2056 : :
2057 : 0 : AstNode *val_node = trans_create_node_builtin_fn_call_str(c, "ptrToInt");
2058 : 0 : val_node->data.fn_call_expr.params.append(target_node);
2059 : : // @ptrToInt always returns a usize
2060 : 0 : AstNode *node = trans_create_node_builtin_fn_call_str(c, "intCast");
2061 : 0 : node->data.fn_call_expr.params.append(dest_type_node);
2062 : 0 : node->data.fn_call_expr.params.append(val_node);
2063 : :
2064 : 0 : return maybe_suppress_result(c, result_used, node);
2065 : : }
2066 : 0 : case ZigClangCK_IntegralToPointer:
2067 : : {
2068 : 0 : AstNode *target_node = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getSubExpr()), TransRValue);
2069 [ # # ]: 0 : if (target_node == nullptr)
2070 : 0 : return nullptr;
2071 : :
2072 : 0 : AstNode *dest_type_node = get_expr_type(c, (const ZigClangExpr *)stmt);
2073 [ # # ]: 0 : if (dest_type_node == nullptr)
2074 : 0 : return nullptr;
2075 : :
2076 : 0 : AstNode *node = trans_create_node_builtin_fn_call_str(c, "intToPtr");
2077 : 0 : node->data.fn_call_expr.params.append(dest_type_node);
2078 : 0 : node->data.fn_call_expr.params.append(target_node);
2079 : :
2080 : 0 : return maybe_suppress_result(c, result_used, node);
2081 : : }
2082 : 0 : case ZigClangCK_IntegralToFloating:
2083 : : case ZigClangCK_FloatingToIntegral:
2084 : : {
2085 : 0 : AstNode *target_node = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getSubExpr()), TransRValue);
2086 [ # # ]: 0 : if (target_node == nullptr)
2087 : 0 : return nullptr;
2088 : :
2089 : 0 : AstNode *dest_type_node = get_expr_type(c, (const ZigClangExpr *)stmt);
2090 [ # # ]: 0 : if (dest_type_node == nullptr)
2091 : 0 : return nullptr;
2092 : :
2093 : 0 : char const *fn = (ZigClangCK)stmt->getCastKind() == ZigClangCK_IntegralToFloating ?
2094 [ # # ]: 0 : "intToFloat" : "floatToInt";
2095 : 0 : AstNode *node = trans_create_node_builtin_fn_call_str(c, fn);
2096 : 0 : node->data.fn_call_expr.params.append(dest_type_node);
2097 : 0 : node->data.fn_call_expr.params.append(target_node);
2098 : :
2099 : 0 : return maybe_suppress_result(c, result_used, node);
2100 : : }
2101 : 0 : case ZigClangCK_FixedPointCast:
2102 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FixedPointCast");
2103 : 0 : return nullptr;
2104 : 0 : case ZigClangCK_FixedPointToBoolean:
2105 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FixedPointToBoolean");
2106 : 0 : return nullptr;
2107 : 0 : case ZigClangCK_FloatingToBoolean:
2108 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingToBoolean");
2109 : 0 : return nullptr;
2110 : 0 : case ZigClangCK_BooleanToSignedIntegral:
2111 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_BooleanToSignedIntegral");
2112 : 0 : return nullptr;
2113 : 0 : case ZigClangCK_FloatingCast:
2114 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingCast");
2115 : 0 : return nullptr;
2116 : 0 : case ZigClangCK_CPointerToObjCPointerCast:
2117 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_CPointerToObjCPointerCast");
2118 : 0 : return nullptr;
2119 : 0 : case ZigClangCK_BlockPointerToObjCPointerCast:
2120 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_BlockPointerToObjCPointerCast");
2121 : 0 : return nullptr;
2122 : 0 : case ZigClangCK_AnyPointerToBlockPointerCast:
2123 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_AnyPointerToBlockPointerCast");
2124 : 0 : return nullptr;
2125 : 0 : case ZigClangCK_ObjCObjectLValueCast:
2126 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ObjCObjectLValueCast");
2127 : 0 : return nullptr;
2128 : 0 : case ZigClangCK_FloatingRealToComplex:
2129 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingRealToComplex");
2130 : 0 : return nullptr;
2131 : 0 : case ZigClangCK_FloatingComplexToReal:
2132 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingComplexToReal");
2133 : 0 : return nullptr;
2134 : 0 : case ZigClangCK_FloatingComplexToBoolean:
2135 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingComplexToBoolean");
2136 : 0 : return nullptr;
2137 : 0 : case ZigClangCK_FloatingComplexCast:
2138 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingComplexCast");
2139 : 0 : return nullptr;
2140 : 0 : case ZigClangCK_FloatingComplexToIntegralComplex:
2141 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingComplexToIntegralComplex");
2142 : 0 : return nullptr;
2143 : 0 : case ZigClangCK_IntegralRealToComplex:
2144 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralRealToComplex");
2145 : 0 : return nullptr;
2146 : 0 : case ZigClangCK_IntegralComplexToReal:
2147 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralComplexToReal");
2148 : 0 : return nullptr;
2149 : 0 : case ZigClangCK_IntegralComplexToBoolean:
2150 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralComplexToBoolean");
2151 : 0 : return nullptr;
2152 : 0 : case ZigClangCK_IntegralComplexCast:
2153 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralComplexCast");
2154 : 0 : return nullptr;
2155 : 0 : case ZigClangCK_IntegralComplexToFloatingComplex:
2156 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralComplexToFloatingComplex");
2157 : 0 : return nullptr;
2158 : 0 : case ZigClangCK_ARCProduceObject:
2159 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ARCProduceObject");
2160 : 0 : return nullptr;
2161 : 0 : case ZigClangCK_ARCConsumeObject:
2162 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ARCConsumeObject");
2163 : 0 : return nullptr;
2164 : 0 : case ZigClangCK_ARCReclaimReturnedObject:
2165 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ARCReclaimReturnedObject");
2166 : 0 : return nullptr;
2167 : 0 : case ZigClangCK_ARCExtendBlockObject:
2168 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ARCExtendBlockObject");
2169 : 0 : return nullptr;
2170 : 0 : case ZigClangCK_AtomicToNonAtomic:
2171 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_AtomicToNonAtomic");
2172 : 0 : return nullptr;
2173 : 0 : case ZigClangCK_NonAtomicToAtomic:
2174 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_NonAtomicToAtomic");
2175 : 0 : return nullptr;
2176 : 0 : case ZigClangCK_CopyAndAutoreleaseBlockObject:
2177 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_CopyAndAutoreleaseBlockObject");
2178 : 0 : return nullptr;
2179 : 0 : case ZigClangCK_BuiltinFnToFnPtr:
2180 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_BuiltinFnToFnPtr");
2181 : 0 : return nullptr;
2182 : 0 : case ZigClangCK_ZeroToOCLOpaqueType:
2183 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ZeroToOCLOpaqueType");
2184 : 0 : return nullptr;
2185 : 0 : case ZigClangCK_AddressSpaceConversion:
2186 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_AddressSpaceConversion");
2187 : 0 : return nullptr;
2188 : 0 : case ZigClangCK_IntToOCLSampler:
2189 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntToOCLSampler");
2190 : 0 : return nullptr;
2191 : : }
2192 : 0 : zig_unreachable();
2193 : : }
2194 : :
2195 : 0 : static AstNode *trans_decl_ref_expr(Context *c, TransScope *scope, const clang::DeclRefExpr *stmt, TransLRValue lrval) {
2196 : 0 : const clang::ValueDecl *value_decl = stmt->getDecl();
2197 : 0 : Buf *c_symbol_name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)value_decl));
2198 : 0 : Buf *zig_symbol_name = trans_lookup_zig_symbol(c, scope, c_symbol_name);
2199 [ # # ]: 0 : if (lrval == TransLValue) {
2200 : 0 : c->ptr_params.put(zig_symbol_name, true);
2201 : : }
2202 : 0 : return trans_create_node_symbol(c, zig_symbol_name);
2203 : : }
2204 : :
2205 : 0 : static AstNode *trans_create_post_crement(Context *c, ResultUsed result_used, TransScope *scope,
2206 : : const clang::UnaryOperator *stmt, BinOpType assign_op)
2207 : : {
2208 : 0 : const ZigClangExpr *op_expr = bitcast(stmt->getSubExpr());
2209 : :
2210 [ # # ]: 0 : if (result_used == ResultUsedNo) {
2211 : : // common case
2212 : : // c: expr++
2213 : : // zig: expr += 1
2214 : 0 : return trans_create_node_bin_op(c,
2215 : : trans_expr(c, ResultUsedYes, scope, op_expr, TransLValue),
2216 : : assign_op,
2217 : 0 : trans_create_node_unsigned(c, 1));
2218 : : }
2219 : : // worst case
2220 : : // c: expr++
2221 : : // zig: (x: {
2222 : : // zig: const _ref = &expr;
2223 : : // zig: const _tmp = *_ref;
2224 : : // zig: *_ref += 1;
2225 : : // zig: break :x _tmp
2226 : : // zig: })
2227 : 0 : TransScopeBlock *child_scope = trans_scope_block_create(c, scope);
2228 : 0 : Buf *label_name = buf_create_from_str("x");
2229 : 0 : child_scope->node->data.block.name = label_name;
2230 : :
2231 : : // const _ref = &expr;
2232 : 0 : AstNode *expr = trans_expr(c, ResultUsedYes, &child_scope->base, op_expr, TransLValue);
2233 [ # # ]: 0 : if (expr == nullptr) return nullptr;
2234 : 0 : AstNode *addr_of_expr = trans_create_node_addr_of(c, expr);
2235 : : // TODO: avoid name collisions with generated variable names
2236 : 0 : Buf* ref_var_name = buf_create_from_str("_ref");
2237 : 0 : AstNode *ref_var_decl = trans_create_node_var_decl_local(c, true, ref_var_name, nullptr, addr_of_expr);
2238 : 0 : child_scope->node->data.block.statements.append(ref_var_decl);
2239 : :
2240 : : // const _tmp = *_ref;
2241 : 0 : Buf* tmp_var_name = buf_create_from_str("_tmp");
2242 : 0 : AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr,
2243 : : trans_create_node_ptr_deref(c,
2244 : 0 : trans_create_node_symbol(c, ref_var_name)));
2245 : 0 : child_scope->node->data.block.statements.append(tmp_var_decl);
2246 : :
2247 : : // *_ref += 1;
2248 : 0 : AstNode *assign_statement = trans_create_node_bin_op(c,
2249 : : trans_create_node_ptr_deref(c,
2250 : : trans_create_node_symbol(c, ref_var_name)),
2251 : : assign_op,
2252 : 0 : trans_create_node_unsigned(c, 1));
2253 : 0 : child_scope->node->data.block.statements.append(assign_statement);
2254 : :
2255 : : // break :x _tmp
2256 : 0 : child_scope->node->data.block.statements.append(trans_create_node_break(c, label_name, trans_create_node_symbol(c, tmp_var_name)));
2257 : :
2258 : 0 : return trans_create_node_grouped_expr(c, child_scope->node);
2259 : : }
2260 : :
2261 : 0 : static AstNode *trans_create_pre_crement(Context *c, ResultUsed result_used, TransScope *scope,
2262 : : const clang::UnaryOperator *stmt, BinOpType assign_op)
2263 : : {
2264 : 0 : const ZigClangExpr *op_expr = bitcast(stmt->getSubExpr());
2265 : :
2266 [ # # ]: 0 : if (result_used == ResultUsedNo) {
2267 : : // common case
2268 : : // c: ++expr
2269 : : // zig: expr += 1
2270 : 0 : return trans_create_node_bin_op(c,
2271 : : trans_expr(c, ResultUsedYes, scope, op_expr, TransLValue),
2272 : : assign_op,
2273 : 0 : trans_create_node_unsigned(c, 1));
2274 : : }
2275 : : // worst case
2276 : : // c: ++expr
2277 : : // zig: (x: {
2278 : : // zig: const _ref = &expr;
2279 : : // zig: *_ref += 1;
2280 : : // zig: break :x *_ref
2281 : : // zig: })
2282 : 0 : TransScopeBlock *child_scope = trans_scope_block_create(c, scope);
2283 : 0 : Buf *label_name = buf_create_from_str("x");
2284 : 0 : child_scope->node->data.block.name = label_name;
2285 : :
2286 : : // const _ref = &expr;
2287 : 0 : AstNode *expr = trans_expr(c, ResultUsedYes, &child_scope->base, op_expr, TransLValue);
2288 [ # # ]: 0 : if (expr == nullptr) return nullptr;
2289 : 0 : AstNode *addr_of_expr = trans_create_node_addr_of(c, expr);
2290 : : // TODO: avoid name collisions with generated variable names
2291 : 0 : Buf* ref_var_name = buf_create_from_str("_ref");
2292 : 0 : AstNode *ref_var_decl = trans_create_node_var_decl_local(c, true, ref_var_name, nullptr, addr_of_expr);
2293 : 0 : child_scope->node->data.block.statements.append(ref_var_decl);
2294 : :
2295 : : // *_ref += 1;
2296 : 0 : AstNode *assign_statement = trans_create_node_bin_op(c,
2297 : : trans_create_node_ptr_deref(c,
2298 : : trans_create_node_symbol(c, ref_var_name)),
2299 : : assign_op,
2300 : 0 : trans_create_node_unsigned(c, 1));
2301 : 0 : child_scope->node->data.block.statements.append(assign_statement);
2302 : :
2303 : : // break :x *_ref
2304 : 0 : AstNode *deref_expr = trans_create_node_ptr_deref(c,
2305 : 0 : trans_create_node_symbol(c, ref_var_name));
2306 : 0 : child_scope->node->data.block.statements.append(trans_create_node_break(c, label_name, deref_expr));
2307 : :
2308 : 0 : return trans_create_node_grouped_expr(c, child_scope->node);
2309 : : }
2310 : :
2311 : 0 : static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransScope *scope, const clang::UnaryOperator *stmt) {
2312 [ # # # # : 0 : switch (stmt->getOpcode()) {
# # # # #
# # # # #
# ]
2313 : 0 : case clang::UO_PostInc:
2314 [ # # ]: 0 : if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType())))
2315 : 0 : return trans_create_post_crement(c, result_used, scope, stmt, BinOpTypeAssignPlusWrap);
2316 : : else
2317 : 0 : return trans_create_post_crement(c, result_used, scope, stmt, BinOpTypeAssignPlus);
2318 : 0 : case clang::UO_PostDec:
2319 [ # # ]: 0 : if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType())))
2320 : 0 : return trans_create_post_crement(c, result_used, scope, stmt, BinOpTypeAssignMinusWrap);
2321 : : else
2322 : 0 : return trans_create_post_crement(c, result_used, scope, stmt, BinOpTypeAssignMinus);
2323 : 0 : case clang::UO_PreInc:
2324 [ # # ]: 0 : if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType())))
2325 : 0 : return trans_create_pre_crement(c, result_used, scope, stmt, BinOpTypeAssignPlusWrap);
2326 : : else
2327 : 0 : return trans_create_pre_crement(c, result_used, scope, stmt, BinOpTypeAssignPlus);
2328 : 0 : case clang::UO_PreDec:
2329 [ # # ]: 0 : if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType())))
2330 : 0 : return trans_create_pre_crement(c, result_used, scope, stmt, BinOpTypeAssignMinusWrap);
2331 : : else
2332 : 0 : return trans_create_pre_crement(c, result_used, scope, stmt, BinOpTypeAssignMinus);
2333 : 0 : case clang::UO_AddrOf:
2334 : : {
2335 : 0 : AstNode *value_node = trans_expr(c, result_used, scope, bitcast(stmt->getSubExpr()), TransLValue);
2336 [ # # ]: 0 : if (value_node == nullptr)
2337 : 0 : return value_node;
2338 : 0 : return trans_create_node_addr_of(c, value_node);
2339 : : }
2340 : 0 : case clang::UO_Deref:
2341 : : {
2342 : 0 : AstNode *value_node = trans_expr(c, result_used, scope, bitcast(stmt->getSubExpr()), TransRValue);
2343 [ # # ]: 0 : if (value_node == nullptr)
2344 : 0 : return nullptr;
2345 : 0 : bool is_fn_ptr = qual_type_is_fn_ptr(bitcast(stmt->getSubExpr()->getType()));
2346 [ # # ]: 0 : if (is_fn_ptr)
2347 : 0 : return value_node;
2348 : 0 : AstNode *unwrapped = trans_create_node_unwrap_null(c, value_node);
2349 : 0 : return trans_create_node_ptr_deref(c, unwrapped);
2350 : : }
2351 : 0 : case clang::UO_Plus:
2352 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation UO_Plus");
2353 : 0 : return nullptr;
2354 : 0 : case clang::UO_Minus:
2355 : : {
2356 : 0 : const ZigClangExpr *op_expr = bitcast(stmt->getSubExpr());
2357 [ # # ]: 0 : if (!qual_type_has_wrapping_overflow(c, ZigClangExpr_getType(op_expr))) {
2358 : 0 : AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);
2359 : 0 : node->data.prefix_op_expr.prefix_op = PrefixOpNegation;
2360 : :
2361 : 0 : node->data.prefix_op_expr.primary_expr = trans_expr(c, ResultUsedYes, scope, op_expr, TransRValue);
2362 [ # # ]: 0 : if (node->data.prefix_op_expr.primary_expr == nullptr)
2363 : 0 : return nullptr;
2364 : :
2365 : 0 : return node;
2366 [ # # ]: 0 : } else if (c_is_unsigned_integer(c, ZigClangExpr_getType(op_expr))) {
2367 : : // we gotta emit 0 -% x
2368 : 0 : AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
2369 : 0 : node->data.bin_op_expr.op1 = trans_create_node_unsigned(c, 0);
2370 : :
2371 : 0 : node->data.bin_op_expr.op2 = trans_expr(c, ResultUsedYes, scope, op_expr, TransRValue);
2372 [ # # ]: 0 : if (node->data.bin_op_expr.op2 == nullptr)
2373 : 0 : return nullptr;
2374 : :
2375 : 0 : node->data.bin_op_expr.bin_op = BinOpTypeSubWrap;
2376 : 0 : return node;
2377 : : } else {
2378 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "C negation with non float non integer");
2379 : 0 : return nullptr;
2380 : : }
2381 : : }
2382 : 0 : case clang::UO_Not:
2383 : : {
2384 : 0 : const ZigClangExpr *op_expr = bitcast(stmt->getSubExpr());
2385 : 0 : AstNode *sub_node = trans_expr(c, ResultUsedYes, scope, op_expr, TransRValue);
2386 [ # # ]: 0 : if (sub_node == nullptr)
2387 : 0 : return nullptr;
2388 : :
2389 : 0 : return trans_create_node_prefix_op(c, PrefixOpBinNot, sub_node);
2390 : : }
2391 : 0 : case clang::UO_LNot:
2392 : : {
2393 : 0 : const ZigClangExpr *op_expr = bitcast(stmt->getSubExpr());
2394 : 0 : AstNode *sub_node = trans_bool_expr(c, ResultUsedYes, scope, op_expr, TransRValue);
2395 [ # # ]: 0 : if (sub_node == nullptr)
2396 : 0 : return nullptr;
2397 : :
2398 : 0 : return trans_create_node_prefix_op(c, PrefixOpBoolNot, sub_node);
2399 : : }
2400 : 0 : case clang::UO_Real:
2401 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation UO_Real");
2402 : 0 : return nullptr;
2403 : 0 : case clang::UO_Imag:
2404 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation UO_Imag");
2405 : 0 : return nullptr;
2406 : 0 : case clang::UO_Extension:
2407 : 0 : return trans_expr(c, result_used, scope, bitcast(stmt->getSubExpr()), TransLValue);
2408 : 0 : case clang::UO_Coawait:
2409 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation UO_Coawait");
2410 : 0 : return nullptr;
2411 : : }
2412 : 0 : zig_unreachable();
2413 : : }
2414 : :
2415 : 0 : static int trans_local_declaration(Context *c, TransScope *scope, const clang::DeclStmt *stmt,
2416 : : AstNode **out_node, TransScope **out_scope)
2417 : : {
2418 : : // declarations are added via the scope
2419 : 0 : *out_node = nullptr;
2420 : :
2421 : 0 : TransScopeBlock *scope_block = trans_scope_block_find(scope);
2422 [ # # ]: 0 : assert(scope_block != nullptr);
2423 : :
2424 [ # # ]: 0 : for (auto iter = stmt->decl_begin(); iter != stmt->decl_end(); iter++) {
2425 : 0 : clang::Decl *decl = *iter;
2426 [ # # # # : 0 : switch (decl->getKind()) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
2427 : 0 : case clang::Decl::Var: {
2428 : 0 : clang::VarDecl *var_decl = (clang::VarDecl *)decl;
2429 : 0 : ZigClangQualType qual_type = bitcast(var_decl->getTypeSourceInfo()->getType());
2430 : 0 : AstNode *init_node = nullptr;
2431 [ # # ]: 0 : if (var_decl->hasInit()) {
2432 : 0 : init_node = trans_expr(c, ResultUsedYes, scope, bitcast(var_decl->getInit()), TransRValue);
2433 [ # # ]: 0 : if (init_node == nullptr)
2434 : 0 : return ErrorUnexpected;
2435 : :
2436 : : } else {
2437 : 0 : init_node = trans_create_node(c, NodeTypeUndefinedLiteral);
2438 : : }
2439 : 0 : AstNode *type_node = trans_qual_type(c, qual_type, bitcast(stmt->getBeginLoc()));
2440 [ # # ]: 0 : if (type_node == nullptr)
2441 : 0 : return ErrorUnexpected;
2442 : :
2443 : 0 : Buf *c_symbol_name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)var_decl));
2444 : :
2445 : 0 : TransScopeVar *var_scope = trans_scope_var_create(c, scope, c_symbol_name);
2446 : 0 : scope = &var_scope->base;
2447 : :
2448 : 0 : AstNode *node = trans_create_node_var_decl_local(c,
2449 : 0 : ZigClangQualType_isConstQualified(qual_type),
2450 : 0 : var_scope->zig_name, type_node, init_node);
2451 : :
2452 : 0 : scope_block->node->data.block.statements.append(node);
2453 : 0 : continue;
2454 : : }
2455 : 0 : case clang::Decl::AccessSpec:
2456 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle decl kind AccessSpec");
2457 : 0 : return ErrorUnexpected;
2458 : 0 : case clang::Decl::Block:
2459 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Block");
2460 : 0 : return ErrorUnexpected;
2461 : 0 : case clang::Decl::Captured:
2462 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Captured");
2463 : 0 : return ErrorUnexpected;
2464 : 0 : case clang::Decl::ClassScopeFunctionSpecialization:
2465 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ClassScopeFunctionSpecialization");
2466 : 0 : return ErrorUnexpected;
2467 : 0 : case clang::Decl::Empty:
2468 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Empty");
2469 : 0 : return ErrorUnexpected;
2470 : 0 : case clang::Decl::Export:
2471 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Export");
2472 : 0 : return ErrorUnexpected;
2473 : 0 : case clang::Decl::ExternCContext:
2474 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ExternCContext");
2475 : 0 : return ErrorUnexpected;
2476 : 0 : case clang::Decl::FileScopeAsm:
2477 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C FileScopeAsm");
2478 : 0 : return ErrorUnexpected;
2479 : 0 : case clang::Decl::Friend:
2480 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Friend");
2481 : 0 : return ErrorUnexpected;
2482 : 0 : case clang::Decl::FriendTemplate:
2483 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C FriendTemplate");
2484 : 0 : return ErrorUnexpected;
2485 : 0 : case clang::Decl::Import:
2486 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Import");
2487 : 0 : return ErrorUnexpected;
2488 : 0 : case clang::Decl::LinkageSpec:
2489 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C LinkageSpec");
2490 : 0 : return ErrorUnexpected;
2491 : 0 : case clang::Decl::Label:
2492 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Label");
2493 : 0 : return ErrorUnexpected;
2494 : 0 : case clang::Decl::Namespace:
2495 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Namespace");
2496 : 0 : return ErrorUnexpected;
2497 : 0 : case clang::Decl::NamespaceAlias:
2498 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C NamespaceAlias");
2499 : 0 : return ErrorUnexpected;
2500 : 0 : case clang::Decl::ObjCCompatibleAlias:
2501 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCCompatibleAlias");
2502 : 0 : return ErrorUnexpected;
2503 : 0 : case clang::Decl::ObjCCategory:
2504 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCCategory");
2505 : 0 : return ErrorUnexpected;
2506 : 0 : case clang::Decl::ObjCCategoryImpl:
2507 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCCategoryImpl");
2508 : 0 : return ErrorUnexpected;
2509 : 0 : case clang::Decl::ObjCImplementation:
2510 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCImplementation");
2511 : 0 : return ErrorUnexpected;
2512 : 0 : case clang::Decl::ObjCInterface:
2513 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCInterface");
2514 : 0 : return ErrorUnexpected;
2515 : 0 : case clang::Decl::ObjCProtocol:
2516 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCProtocol");
2517 : 0 : return ErrorUnexpected;
2518 : 0 : case clang::Decl::ObjCMethod:
2519 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCMethod");
2520 : 0 : return ErrorUnexpected;
2521 : 0 : case clang::Decl::ObjCProperty:
2522 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCProperty");
2523 : 0 : return ErrorUnexpected;
2524 : 0 : case clang::Decl::BuiltinTemplate:
2525 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C BuiltinTemplate");
2526 : 0 : return ErrorUnexpected;
2527 : 0 : case clang::Decl::ClassTemplate:
2528 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ClassTemplate");
2529 : 0 : return ErrorUnexpected;
2530 : 0 : case clang::Decl::FunctionTemplate:
2531 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C FunctionTemplate");
2532 : 0 : return ErrorUnexpected;
2533 : 0 : case clang::Decl::TypeAliasTemplate:
2534 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TypeAliasTemplate");
2535 : 0 : return ErrorUnexpected;
2536 : 0 : case clang::Decl::VarTemplate:
2537 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C VarTemplate");
2538 : 0 : return ErrorUnexpected;
2539 : 0 : case clang::Decl::TemplateTemplateParm:
2540 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TemplateTemplateParm");
2541 : 0 : return ErrorUnexpected;
2542 : 0 : case clang::Decl::Enum:
2543 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Enum");
2544 : 0 : return ErrorUnexpected;
2545 : 0 : case clang::Decl::Record:
2546 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Record");
2547 : 0 : return ErrorUnexpected;
2548 : 0 : case clang::Decl::CXXRecord:
2549 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXRecord");
2550 : 0 : return ErrorUnexpected;
2551 : 0 : case clang::Decl::ClassTemplateSpecialization:
2552 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ClassTemplateSpecialization");
2553 : 0 : return ErrorUnexpected;
2554 : 0 : case clang::Decl::ClassTemplatePartialSpecialization:
2555 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ClassTemplatePartialSpecialization");
2556 : 0 : return ErrorUnexpected;
2557 : 0 : case clang::Decl::TemplateTypeParm:
2558 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TemplateTypeParm");
2559 : 0 : return ErrorUnexpected;
2560 : 0 : case clang::Decl::ObjCTypeParam:
2561 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCTypeParam");
2562 : 0 : return ErrorUnexpected;
2563 : 0 : case clang::Decl::TypeAlias:
2564 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TypeAlias");
2565 : 0 : return ErrorUnexpected;
2566 : 0 : case clang::Decl::Typedef:
2567 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Typedef");
2568 : 0 : return ErrorUnexpected;
2569 : 0 : case clang::Decl::UnresolvedUsingTypename:
2570 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UnresolvedUsingTypename");
2571 : 0 : return ErrorUnexpected;
2572 : 0 : case clang::Decl::Using:
2573 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Using");
2574 : 0 : return ErrorUnexpected;
2575 : 0 : case clang::Decl::UsingDirective:
2576 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UsingDirective");
2577 : 0 : return ErrorUnexpected;
2578 : 0 : case clang::Decl::UsingPack:
2579 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UsingPack");
2580 : 0 : return ErrorUnexpected;
2581 : 0 : case clang::Decl::UsingShadow:
2582 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UsingShadow");
2583 : 0 : return ErrorUnexpected;
2584 : 0 : case clang::Decl::ConstructorUsingShadow:
2585 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ConstructorUsingShadow");
2586 : 0 : return ErrorUnexpected;
2587 : 0 : case clang::Decl::Binding:
2588 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Binding");
2589 : 0 : return ErrorUnexpected;
2590 : 0 : case clang::Decl::Field:
2591 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Field");
2592 : 0 : return ErrorUnexpected;
2593 : 0 : case clang::Decl::ObjCAtDefsField:
2594 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAtDefsField");
2595 : 0 : return ErrorUnexpected;
2596 : 0 : case clang::Decl::ObjCIvar:
2597 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCIvar");
2598 : 0 : return ErrorUnexpected;
2599 : 0 : case clang::Decl::Function:
2600 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Function");
2601 : 0 : return ErrorUnexpected;
2602 : 0 : case clang::Decl::CXXDeductionGuide:
2603 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDeductionGuide");
2604 : 0 : return ErrorUnexpected;
2605 : 0 : case clang::Decl::CXXMethod:
2606 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXMethod");
2607 : 0 : return ErrorUnexpected;
2608 : 0 : case clang::Decl::CXXConstructor:
2609 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXConstructor");
2610 : 0 : return ErrorUnexpected;
2611 : 0 : case clang::Decl::CXXConversion:
2612 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXConversion");
2613 : 0 : return ErrorUnexpected;
2614 : 0 : case clang::Decl::CXXDestructor:
2615 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDestructor");
2616 : 0 : return ErrorUnexpected;
2617 : 0 : case clang::Decl::MSProperty:
2618 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C MSProperty");
2619 : 0 : return ErrorUnexpected;
2620 : 0 : case clang::Decl::NonTypeTemplateParm:
2621 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C NonTypeTemplateParm");
2622 : 0 : return ErrorUnexpected;
2623 : 0 : case clang::Decl::Decomposition:
2624 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Decomposition");
2625 : 0 : return ErrorUnexpected;
2626 : 0 : case clang::Decl::ImplicitParam:
2627 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ImplicitParam");
2628 : 0 : return ErrorUnexpected;
2629 : 0 : case clang::Decl::OMPCapturedExpr:
2630 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPCapturedExpr");
2631 : 0 : return ErrorUnexpected;
2632 : 0 : case clang::Decl::ParmVar:
2633 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ParmVar");
2634 : 0 : return ErrorUnexpected;
2635 : 0 : case clang::Decl::VarTemplateSpecialization:
2636 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C VarTemplateSpecialization");
2637 : 0 : return ErrorUnexpected;
2638 : 0 : case clang::Decl::VarTemplatePartialSpecialization:
2639 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C VarTemplatePartialSpecialization");
2640 : 0 : return ErrorUnexpected;
2641 : 0 : case clang::Decl::EnumConstant:
2642 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C EnumConstant");
2643 : 0 : return ErrorUnexpected;
2644 : 0 : case clang::Decl::IndirectField:
2645 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C IndirectField");
2646 : 0 : return ErrorUnexpected;
2647 : 0 : case clang::Decl::OMPDeclareReduction:
2648 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPDeclareReduction");
2649 : 0 : return ErrorUnexpected;
2650 : 0 : case clang::Decl::UnresolvedUsingValue:
2651 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UnresolvedUsingValue");
2652 : 0 : return ErrorUnexpected;
2653 : 0 : case clang::Decl::OMPRequires:
2654 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPRequires");
2655 : 0 : return ErrorUnexpected;
2656 : 0 : case clang::Decl::OMPThreadPrivate:
2657 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPThreadPrivate");
2658 : 0 : return ErrorUnexpected;
2659 : 0 : case clang::Decl::ObjCPropertyImpl:
2660 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCPropertyImpl");
2661 : 0 : return ErrorUnexpected;
2662 : 0 : case clang::Decl::PragmaComment:
2663 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C PragmaComment");
2664 : 0 : return ErrorUnexpected;
2665 : 0 : case clang::Decl::PragmaDetectMismatch:
2666 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C PragmaDetectMismatch");
2667 : 0 : return ErrorUnexpected;
2668 : 0 : case clang::Decl::StaticAssert:
2669 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C StaticAssert");
2670 : 0 : return ErrorUnexpected;
2671 : 0 : case clang::Decl::TranslationUnit:
2672 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TranslationUnit");
2673 : 0 : return ErrorUnexpected;
2674 : : }
2675 : 0 : zig_unreachable();
2676 : : }
2677 : :
2678 : 0 : *out_scope = scope;
2679 : 0 : return ErrorNone;
2680 : : }
2681 : :
2682 : 0 : static AstNode *to_enum_zero_cmp(Context *c, AstNode *expr, AstNode *enum_type) {
2683 : 0 : AstNode *tag_type = trans_create_node_builtin_fn_call_str(c, "TagType");
2684 : 0 : tag_type->data.fn_call_expr.params.append(enum_type);
2685 : :
2686 : : // @TagType(Enum)(0)
2687 : 0 : AstNode *zero = trans_create_node_unsigned_negative(c, 0, false);
2688 : 0 : AstNode *casted_zero = trans_create_node_fn_call_1(c, tag_type, zero);
2689 : :
2690 : : // @bitCast(Enum, @TagType(Enum)(0))
2691 : 0 : AstNode *bitcast = trans_create_node_builtin_fn_call_str(c, "bitCast");
2692 : 0 : bitcast->data.fn_call_expr.params.append(enum_type);
2693 : 0 : bitcast->data.fn_call_expr.params.append(casted_zero);
2694 : :
2695 : 0 : return trans_create_node_bin_op(c, expr, BinOpTypeCmpNotEq, bitcast);
2696 : : }
2697 : :
2698 : 0 : static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *scope, const ZigClangExpr *expr, TransLRValue lrval) {
2699 : 0 : AstNode *res = trans_expr(c, result_used, scope, expr, lrval);
2700 [ # # ]: 0 : if (res == nullptr)
2701 : 0 : return nullptr;
2702 : :
2703 [ # # # # ]: 0 : switch (res->type) {
2704 : 0 : case NodeTypeBinOpExpr:
2705 [ # # ]: 0 : switch (res->data.bin_op_expr.bin_op) {
2706 : 0 : case BinOpTypeBoolOr:
2707 : : case BinOpTypeBoolAnd:
2708 : : case BinOpTypeCmpEq:
2709 : : case BinOpTypeCmpNotEq:
2710 : : case BinOpTypeCmpLessThan:
2711 : : case BinOpTypeCmpGreaterThan:
2712 : : case BinOpTypeCmpLessOrEq:
2713 : : case BinOpTypeCmpGreaterOrEq:
2714 : 0 : return res;
2715 : 0 : default:
2716 : 0 : break;
2717 : : }
2718 : :
2719 : : case NodeTypePrefixOpExpr:
2720 [ # # ]: 0 : switch (res->data.prefix_op_expr.prefix_op) {
2721 : 0 : case PrefixOpBoolNot:
2722 : 0 : return res;
2723 : 0 : default:
2724 : 0 : break;
2725 : : }
2726 : :
2727 : : case NodeTypeBoolLiteral:
2728 : 0 : return res;
2729 : :
2730 : 0 : default:
2731 : 0 : break;
2732 : : }
2733 : :
2734 : :
2735 : 0 : const ZigClangType *ty = ZigClangQualType_getTypePtr(get_expr_qual_type_before_implicit_cast(c, expr));
2736 : 0 : auto classs = ZigClangType_getTypeClass(ty);
2737 [ # # # # : 0 : switch (classs) {
# # # ]
2738 : 0 : case ZigClangType_Builtin:
2739 : : {
2740 : 0 : const ZigClangBuiltinType *builtin_ty = reinterpret_cast<const ZigClangBuiltinType*>(ty);
2741 [ # # # # ]: 0 : switch (ZigClangBuiltinType_getKind(builtin_ty)) {
2742 : 0 : case ZigClangBuiltinTypeBool:
2743 : : case ZigClangBuiltinTypeChar_U:
2744 : : case ZigClangBuiltinTypeUChar:
2745 : : case ZigClangBuiltinTypeChar_S:
2746 : : case ZigClangBuiltinTypeSChar:
2747 : : case ZigClangBuiltinTypeUShort:
2748 : : case ZigClangBuiltinTypeUInt:
2749 : : case ZigClangBuiltinTypeULong:
2750 : : case ZigClangBuiltinTypeULongLong:
2751 : : case ZigClangBuiltinTypeShort:
2752 : : case ZigClangBuiltinTypeInt:
2753 : : case ZigClangBuiltinTypeLong:
2754 : : case ZigClangBuiltinTypeLongLong:
2755 : : case ZigClangBuiltinTypeUInt128:
2756 : : case ZigClangBuiltinTypeInt128:
2757 : : case ZigClangBuiltinTypeFloat:
2758 : : case ZigClangBuiltinTypeDouble:
2759 : : case ZigClangBuiltinTypeFloat128:
2760 : : case ZigClangBuiltinTypeLongDouble:
2761 : : case ZigClangBuiltinTypeWChar_U:
2762 : : case ZigClangBuiltinTypeChar8:
2763 : : case ZigClangBuiltinTypeChar16:
2764 : : case ZigClangBuiltinTypeChar32:
2765 : : case ZigClangBuiltinTypeWChar_S:
2766 : : case ZigClangBuiltinTypeFloat16:
2767 : 0 : return trans_create_node_bin_op(c, res, BinOpTypeCmpNotEq, trans_create_node_unsigned_negative(c, 0, false));
2768 : 0 : case ZigClangBuiltinTypeNullPtr:
2769 : 0 : return trans_create_node_bin_op(c, res, BinOpTypeCmpNotEq,
2770 : 0 : trans_create_node(c, NodeTypeNullLiteral));
2771 : :
2772 : 0 : case ZigClangBuiltinTypeVoid:
2773 : : case ZigClangBuiltinTypeHalf:
2774 : : case ZigClangBuiltinTypeObjCId:
2775 : : case ZigClangBuiltinTypeObjCClass:
2776 : : case ZigClangBuiltinTypeObjCSel:
2777 : : case ZigClangBuiltinTypeOMPArraySection:
2778 : : case ZigClangBuiltinTypeDependent:
2779 : : case ZigClangBuiltinTypeOverload:
2780 : : case ZigClangBuiltinTypeBoundMember:
2781 : : case ZigClangBuiltinTypePseudoObject:
2782 : : case ZigClangBuiltinTypeUnknownAny:
2783 : : case ZigClangBuiltinTypeBuiltinFn:
2784 : : case ZigClangBuiltinTypeARCUnbridgedCast:
2785 : : case ZigClangBuiltinTypeOCLImage1dRO:
2786 : : case ZigClangBuiltinTypeOCLImage1dArrayRO:
2787 : : case ZigClangBuiltinTypeOCLImage1dBufferRO:
2788 : : case ZigClangBuiltinTypeOCLImage2dRO:
2789 : : case ZigClangBuiltinTypeOCLImage2dArrayRO:
2790 : : case ZigClangBuiltinTypeOCLImage2dDepthRO:
2791 : : case ZigClangBuiltinTypeOCLImage2dArrayDepthRO:
2792 : : case ZigClangBuiltinTypeOCLImage2dMSAARO:
2793 : : case ZigClangBuiltinTypeOCLImage2dArrayMSAARO:
2794 : : case ZigClangBuiltinTypeOCLImage2dMSAADepthRO:
2795 : : case ZigClangBuiltinTypeOCLImage2dArrayMSAADepthRO:
2796 : : case ZigClangBuiltinTypeOCLImage3dRO:
2797 : : case ZigClangBuiltinTypeOCLImage1dWO:
2798 : : case ZigClangBuiltinTypeOCLImage1dArrayWO:
2799 : : case ZigClangBuiltinTypeOCLImage1dBufferWO:
2800 : : case ZigClangBuiltinTypeOCLImage2dWO:
2801 : : case ZigClangBuiltinTypeOCLImage2dArrayWO:
2802 : : case ZigClangBuiltinTypeOCLImage2dDepthWO:
2803 : : case ZigClangBuiltinTypeOCLImage2dArrayDepthWO:
2804 : : case ZigClangBuiltinTypeOCLImage2dMSAAWO:
2805 : : case ZigClangBuiltinTypeOCLImage2dArrayMSAAWO:
2806 : : case ZigClangBuiltinTypeOCLImage2dMSAADepthWO:
2807 : : case ZigClangBuiltinTypeOCLImage2dArrayMSAADepthWO:
2808 : : case ZigClangBuiltinTypeOCLImage3dWO:
2809 : : case ZigClangBuiltinTypeOCLImage1dRW:
2810 : : case ZigClangBuiltinTypeOCLImage1dArrayRW:
2811 : : case ZigClangBuiltinTypeOCLImage1dBufferRW:
2812 : : case ZigClangBuiltinTypeOCLImage2dRW:
2813 : : case ZigClangBuiltinTypeOCLImage2dArrayRW:
2814 : : case ZigClangBuiltinTypeOCLImage2dDepthRW:
2815 : : case ZigClangBuiltinTypeOCLImage2dArrayDepthRW:
2816 : : case ZigClangBuiltinTypeOCLImage2dMSAARW:
2817 : : case ZigClangBuiltinTypeOCLImage2dArrayMSAARW:
2818 : : case ZigClangBuiltinTypeOCLImage2dMSAADepthRW:
2819 : : case ZigClangBuiltinTypeOCLImage2dArrayMSAADepthRW:
2820 : : case ZigClangBuiltinTypeOCLImage3dRW:
2821 : : case ZigClangBuiltinTypeOCLSampler:
2822 : : case ZigClangBuiltinTypeOCLEvent:
2823 : : case ZigClangBuiltinTypeOCLClkEvent:
2824 : : case ZigClangBuiltinTypeOCLQueue:
2825 : : case ZigClangBuiltinTypeOCLReserveID:
2826 : : case ZigClangBuiltinTypeShortAccum:
2827 : : case ZigClangBuiltinTypeAccum:
2828 : : case ZigClangBuiltinTypeLongAccum:
2829 : : case ZigClangBuiltinTypeUShortAccum:
2830 : : case ZigClangBuiltinTypeUAccum:
2831 : : case ZigClangBuiltinTypeULongAccum:
2832 : : case ZigClangBuiltinTypeShortFract:
2833 : : case ZigClangBuiltinTypeFract:
2834 : : case ZigClangBuiltinTypeLongFract:
2835 : : case ZigClangBuiltinTypeUShortFract:
2836 : : case ZigClangBuiltinTypeUFract:
2837 : : case ZigClangBuiltinTypeULongFract:
2838 : : case ZigClangBuiltinTypeSatShortAccum:
2839 : : case ZigClangBuiltinTypeSatAccum:
2840 : : case ZigClangBuiltinTypeSatLongAccum:
2841 : : case ZigClangBuiltinTypeSatUShortAccum:
2842 : : case ZigClangBuiltinTypeSatUAccum:
2843 : : case ZigClangBuiltinTypeSatULongAccum:
2844 : : case ZigClangBuiltinTypeSatShortFract:
2845 : : case ZigClangBuiltinTypeSatFract:
2846 : : case ZigClangBuiltinTypeSatLongFract:
2847 : : case ZigClangBuiltinTypeSatUShortFract:
2848 : : case ZigClangBuiltinTypeSatUFract:
2849 : : case ZigClangBuiltinTypeSatULongFract:
2850 : : case ZigClangBuiltinTypeOCLIntelSubgroupAVCMcePayload:
2851 : : case ZigClangBuiltinTypeOCLIntelSubgroupAVCImePayload:
2852 : : case ZigClangBuiltinTypeOCLIntelSubgroupAVCRefPayload:
2853 : : case ZigClangBuiltinTypeOCLIntelSubgroupAVCSicPayload:
2854 : : case ZigClangBuiltinTypeOCLIntelSubgroupAVCMceResult:
2855 : : case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResult:
2856 : : case ZigClangBuiltinTypeOCLIntelSubgroupAVCRefResult:
2857 : : case ZigClangBuiltinTypeOCLIntelSubgroupAVCSicResult:
2858 : : case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResultSingleRefStreamout:
2859 : : case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResultDualRefStreamout:
2860 : : case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeSingleRefStreamin:
2861 : : case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeDualRefStreamin:
2862 : 0 : return res;
2863 : : }
2864 : 0 : break;
2865 : : }
2866 : 0 : case ZigClangType_Pointer:
2867 : 0 : return trans_create_node_bin_op(c, res, BinOpTypeCmpNotEq, trans_create_node(c, NodeTypeNullLiteral));
2868 : :
2869 : 0 : case ZigClangType_Typedef:
2870 : : {
2871 : 0 : const ZigClangTypedefType *typedef_ty = reinterpret_cast<const ZigClangTypedefType*>(ty);
2872 : 0 : const ZigClangTypedefNameDecl *typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
2873 : 0 : auto existing_entry = c->decl_table.maybe_get((void*)ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl));
2874 [ # # ]: 0 : if (existing_entry) {
2875 : 0 : return existing_entry->value;
2876 : : }
2877 : :
2878 : 0 : return res;
2879 : : }
2880 : :
2881 : 0 : case ZigClangType_Enum:
2882 : : {
2883 : 0 : const ZigClangEnumType *enum_ty = reinterpret_cast<const ZigClangEnumType *>(ty);
2884 : 0 : AstNode *enum_type = resolve_enum_decl(c, ZigClangEnumType_getDecl(enum_ty));
2885 : 0 : return to_enum_zero_cmp(c, res, enum_type);
2886 : : }
2887 : :
2888 : 0 : case ZigClangType_Elaborated:
2889 : : {
2890 : 0 : const clang::ElaboratedType *elaborated_ty = reinterpret_cast<const clang::ElaboratedType*>(ty);
2891 [ # # # ]: 0 : switch (elaborated_ty->getKeyword()) {
2892 : 0 : case clang::ETK_Enum: {
2893 : 0 : AstNode *enum_type = trans_qual_type(c, bitcast(elaborated_ty->getNamedType()),
2894 : 0 : ZigClangExpr_getBeginLoc(expr));
2895 : 0 : return to_enum_zero_cmp(c, res, enum_type);
2896 : : }
2897 : 0 : case clang::ETK_Struct:
2898 : : case clang::ETK_Union:
2899 : : case clang::ETK_Interface:
2900 : : case clang::ETK_Class:
2901 : : case clang::ETK_Typename:
2902 : : case clang::ETK_None:
2903 : 0 : return res;
2904 : : }
2905 : : }
2906 : :
2907 : : case ZigClangType_FunctionProto:
2908 : : case ZigClangType_Record:
2909 : : case ZigClangType_ConstantArray:
2910 : : case ZigClangType_Paren:
2911 : : case ZigClangType_Decayed:
2912 : : case ZigClangType_Attributed:
2913 : : case ZigClangType_IncompleteArray:
2914 : : case ZigClangType_BlockPointer:
2915 : : case ZigClangType_LValueReference:
2916 : : case ZigClangType_RValueReference:
2917 : : case ZigClangType_MemberPointer:
2918 : : case ZigClangType_VariableArray:
2919 : : case ZigClangType_DependentSizedArray:
2920 : : case ZigClangType_DependentSizedExtVector:
2921 : : case ZigClangType_Vector:
2922 : : case ZigClangType_ExtVector:
2923 : : case ZigClangType_FunctionNoProto:
2924 : : case ZigClangType_UnresolvedUsing:
2925 : : case ZigClangType_Adjusted:
2926 : : case ZigClangType_TypeOfExpr:
2927 : : case ZigClangType_TypeOf:
2928 : : case ZigClangType_Decltype:
2929 : : case ZigClangType_UnaryTransform:
2930 : : case ZigClangType_TemplateTypeParm:
2931 : : case ZigClangType_SubstTemplateTypeParm:
2932 : : case ZigClangType_SubstTemplateTypeParmPack:
2933 : : case ZigClangType_TemplateSpecialization:
2934 : : case ZigClangType_Auto:
2935 : : case ZigClangType_InjectedClassName:
2936 : : case ZigClangType_DependentName:
2937 : : case ZigClangType_DependentTemplateSpecialization:
2938 : : case ZigClangType_PackExpansion:
2939 : : case ZigClangType_ObjCObject:
2940 : : case ZigClangType_ObjCInterface:
2941 : : case ZigClangType_Complex:
2942 : : case ZigClangType_ObjCObjectPointer:
2943 : : case ZigClangType_Atomic:
2944 : : case ZigClangType_Pipe:
2945 : : case ZigClangType_ObjCTypeParam:
2946 : : case ZigClangType_DeducedTemplateSpecialization:
2947 : : case ZigClangType_DependentAddressSpace:
2948 : : case ZigClangType_DependentVector:
2949 : 0 : return res;
2950 : : }
2951 : 0 : zig_unreachable();
2952 : : }
2953 : :
2954 : 0 : static AstNode *trans_while_loop(Context *c, TransScope *scope, const clang::WhileStmt *stmt) {
2955 : 0 : TransScopeWhile *while_scope = trans_scope_while_create(c, scope);
2956 : :
2957 : 0 : while_scope->node->data.while_expr.condition = trans_bool_expr(c, ResultUsedYes, scope,
2958 : : bitcast(stmt->getCond()), TransRValue);
2959 [ # # ]: 0 : if (while_scope->node->data.while_expr.condition == nullptr)
2960 : 0 : return nullptr;
2961 : :
2962 : 0 : TransScope *body_scope = trans_stmt(c, &while_scope->base, bitcast(stmt->getBody()),
2963 : 0 : &while_scope->node->data.while_expr.body);
2964 [ # # ]: 0 : if (body_scope == nullptr)
2965 : 0 : return nullptr;
2966 : :
2967 : 0 : return while_scope->node;
2968 : : }
2969 : :
2970 : 0 : static AstNode *trans_if_statement(Context *c, TransScope *scope, const clang::IfStmt *stmt) {
2971 : : // if (c) t
2972 : : // if (c) t else e
2973 : 0 : AstNode *if_node = trans_create_node(c, NodeTypeIfBoolExpr);
2974 : :
2975 : 0 : TransScope *then_scope = trans_stmt(c, scope, bitcast(stmt->getThen()), &if_node->data.if_bool_expr.then_block);
2976 [ # # ]: 0 : if (then_scope == nullptr)
2977 : 0 : return nullptr;
2978 : :
2979 [ # # ]: 0 : if (stmt->getElse() != nullptr) {
2980 : 0 : TransScope *else_scope = trans_stmt(c, scope, bitcast(stmt->getElse()), &if_node->data.if_bool_expr.else_node);
2981 [ # # ]: 0 : if (else_scope == nullptr)
2982 : 0 : return nullptr;
2983 : : }
2984 : :
2985 : 0 : if_node->data.if_bool_expr.condition = trans_bool_expr(c, ResultUsedYes, scope, bitcast(stmt->getCond()),
2986 : : TransRValue);
2987 [ # # ]: 0 : if (if_node->data.if_bool_expr.condition == nullptr)
2988 : 0 : return nullptr;
2989 : :
2990 : 0 : return if_node;
2991 : : }
2992 : :
2993 : 0 : static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::CallExpr *stmt) {
2994 : 0 : AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
2995 : :
2996 : 0 : AstNode *callee_raw_node = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getCallee()), TransRValue);
2997 [ # # ]: 0 : if (callee_raw_node == nullptr)
2998 : 0 : return nullptr;
2999 : :
3000 : 0 : bool is_ptr = false;
3001 : 0 : const clang::FunctionProtoType *fn_ty = qual_type_get_fn_proto(bitcast(stmt->getCallee()->getType()), &is_ptr);
3002 : 0 : AstNode *callee_node = nullptr;
3003 [ # # ][ # # ]: 0 : if (is_ptr && fn_ty) {
3004 [ # # ]: 0 : if ((ZigClangStmtClass)stmt->getCallee()->getStmtClass() == ZigClangStmt_ImplicitCastExprClass) {
3005 : 0 : const clang::ImplicitCastExpr *implicit_cast = static_cast<const clang::ImplicitCastExpr *>(stmt->getCallee());
3006 [ # # ]: 0 : if ((ZigClangCK)implicit_cast->getCastKind() == ZigClangCK_FunctionToPointerDecay) {
3007 [ # # ]: 0 : if ((ZigClangStmtClass)implicit_cast->getSubExpr()->getStmtClass() == ZigClangStmt_DeclRefExprClass) {
3008 : 0 : const clang::DeclRefExpr *decl_ref = static_cast<const clang::DeclRefExpr *>(implicit_cast->getSubExpr());
3009 : 0 : const clang::Decl *decl = decl_ref->getFoundDecl();
3010 [ # # ]: 0 : if (decl->getKind() == clang::Decl::Function) {
3011 : 0 : callee_node = callee_raw_node;
3012 : : }
3013 : : }
3014 : : }
3015 : : }
3016 [ # # ]: 0 : if (callee_node == nullptr) {
3017 : 0 : callee_node = trans_create_node_unwrap_null(c, callee_raw_node);
3018 : 0 : }
3019 : : } else {
3020 : 0 : callee_node = callee_raw_node;
3021 : : }
3022 : :
3023 : 0 : node->data.fn_call_expr.fn_ref_expr = callee_node;
3024 : :
3025 : 0 : unsigned num_args = stmt->getNumArgs();
3026 : 0 : const ZigClangExpr * const* args = reinterpret_cast<const ZigClangExpr * const*>(stmt->getArgs());
3027 [ # # ]: 0 : for (unsigned i = 0; i < num_args; i += 1) {
3028 : 0 : AstNode *arg_node = trans_expr(c, ResultUsedYes, scope, args[i], TransRValue);
3029 [ # # ]: 0 : if (arg_node == nullptr)
3030 : 0 : return nullptr;
3031 : :
3032 : 0 : node->data.fn_call_expr.params.append(arg_node);
3033 : : }
3034 : :
3035 [ # # ]: 0 : if (result_used == ResultUsedNo && fn_ty &&
[ # # # # ]
[ # # ]
3036 : 0 : !ZigClangType_isVoidType(qual_type_canon(bitcast(fn_ty->getReturnType()))))
3037 : : {
3038 : 0 : node = trans_create_node_bin_op(c, trans_create_node_symbol_str(c, "_"), BinOpTypeAssign, node);
3039 : : }
3040 : :
3041 : 0 : return node;
3042 : : }
3043 : :
3044 : 0 : static AstNode *trans_member_expr(Context *c, ResultUsed result_used, TransScope *scope,
3045 : : const clang::MemberExpr *stmt)
3046 : : {
3047 : 0 : AstNode *container_node = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getBase()), TransRValue);
3048 [ # # ]: 0 : if (container_node == nullptr)
3049 : 0 : return nullptr;
3050 : :
3051 [ # # ]: 0 : if (stmt->isArrow()) {
3052 : 0 : container_node = trans_create_node_unwrap_null(c, container_node);
3053 : : }
3054 : :
3055 : 0 : const char *name = ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)stmt->getMemberDecl());
3056 : :
3057 : 0 : AstNode *node = trans_create_node_field_access_str(c, container_node, name);
3058 : 0 : return maybe_suppress_result(c, result_used, node);
3059 : : }
3060 : :
3061 : 0 : static AstNode *trans_array_subscript_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::ArraySubscriptExpr *stmt) {
3062 : 0 : AstNode *container_node = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getBase()), TransRValue);
3063 [ # # ]: 0 : if (container_node == nullptr)
3064 : 0 : return nullptr;
3065 : :
3066 : 0 : AstNode *idx_node = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getIdx()), TransRValue);
3067 [ # # ]: 0 : if (idx_node == nullptr)
3068 : 0 : return nullptr;
3069 : :
3070 : :
3071 : 0 : AstNode *node = trans_create_node(c, NodeTypeArrayAccessExpr);
3072 : 0 : node->data.array_access_expr.array_ref_expr = container_node;
3073 : 0 : node->data.array_access_expr.subscript = idx_node;
3074 : 0 : return maybe_suppress_result(c, result_used, node);
3075 : : }
3076 : :
3077 : 0 : static AstNode *trans_c_style_cast_expr(Context *c, ResultUsed result_used, TransScope *scope,
3078 : : const clang::CStyleCastExpr *stmt, TransLRValue lrvalue)
3079 : : {
3080 : 0 : AstNode *sub_expr_node = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getSubExpr()), lrvalue);
3081 [ # # ]: 0 : if (sub_expr_node == nullptr)
3082 : 0 : return nullptr;
3083 : :
3084 : 0 : AstNode *cast = trans_c_cast(c, bitcast(stmt->getBeginLoc()), bitcast(stmt->getType()),
3085 : 0 : bitcast(stmt->getSubExpr()->getType()), sub_expr_node);
3086 [ # # ]: 0 : if (cast == nullptr)
3087 : 0 : return nullptr;
3088 : :
3089 : 0 : return maybe_suppress_result(c, result_used, cast);
3090 : : }
3091 : :
3092 : 0 : static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, ResultUsed result_used,
3093 : : TransScope *scope, const clang::UnaryExprOrTypeTraitExpr *stmt)
3094 : : {
3095 : 0 : AstNode *type_node = trans_qual_type(c, bitcast(stmt->getTypeOfArgument()), bitcast(stmt->getBeginLoc()));
3096 [ # # ]: 0 : if (type_node == nullptr)
3097 : 0 : return nullptr;
3098 : :
3099 : 0 : AstNode *node = trans_create_node_builtin_fn_call_str(c, "sizeOf");
3100 : 0 : node->data.fn_call_expr.params.append(type_node);
3101 : 0 : return maybe_suppress_result(c, result_used, node);
3102 : : }
3103 : :
3104 : 0 : static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const clang::DoStmt *stmt) {
3105 : 0 : TransScopeWhile *while_scope = trans_scope_while_create(c, parent_scope);
3106 : :
3107 : 0 : while_scope->node->data.while_expr.condition = trans_create_node_bool(c, true);
3108 : :
3109 : : AstNode *body_node;
3110 : : TransScope *child_scope;
3111 [ # # ]: 0 : if ((ZigClangStmtClass)stmt->getBody()->getStmtClass() == ZigClangStmt_CompoundStmtClass) {
3112 : : // there's already a block in C, so we'll append our condition to it.
3113 : : // c: do {
3114 : : // c: a;
3115 : : // c: b;
3116 : : // c: } while(c);
3117 : : // zig: while (true) {
3118 : : // zig: a;
3119 : : // zig: b;
3120 : : // zig: if (!cond) break;
3121 : : // zig: }
3122 : :
3123 : : // We call the low level function so that we can set child_scope to the scope of the generated block.
3124 [ # # ]: 0 : if (trans_stmt_extra(c, &while_scope->base, bitcast(stmt->getBody()), ResultUsedNo, TransRValue, &body_node,
3125 : 0 : nullptr, &child_scope))
3126 : : {
3127 : 0 : return nullptr;
3128 : : }
3129 [ # # ]: 0 : assert(body_node->type == NodeTypeBlock);
3130 : : } else {
3131 : : // the C statement is without a block, so we need to create a block to contain it.
3132 : : // c: do
3133 : : // c: a;
3134 : : // c: while(c);
3135 : : // zig: while (true) {
3136 : : // zig: a;
3137 : : // zig: if (!cond) break;
3138 : : // zig: }
3139 : 0 : TransScopeBlock *child_block_scope = trans_scope_block_create(c, &while_scope->base);
3140 : 0 : body_node = child_block_scope->node;
3141 : : AstNode *child_statement;
3142 : 0 : child_scope = trans_stmt(c, &child_block_scope->base, bitcast(stmt->getBody()), &child_statement);
3143 [ # # ]: 0 : if (child_scope == nullptr) return nullptr;
3144 [ # # ]: 0 : if (child_statement != nullptr) {
3145 : 0 : body_node->data.block.statements.append(child_statement);
3146 : : }
3147 : : }
3148 : :
3149 : : // if (!cond) break;
3150 : 0 : AstNode *condition_node = trans_expr(c, ResultUsedYes, child_scope, bitcast(stmt->getCond()), TransRValue);
3151 [ # # ]: 0 : if (condition_node == nullptr) return nullptr;
3152 : 0 : AstNode *terminator_node = trans_create_node(c, NodeTypeIfBoolExpr);
3153 : 0 : terminator_node->data.if_bool_expr.condition = trans_create_node_prefix_op(c, PrefixOpBoolNot, condition_node);
3154 : 0 : terminator_node->data.if_bool_expr.then_block = trans_create_node(c, NodeTypeBreak);
3155 : :
3156 [ # # ]: 0 : assert(terminator_node != nullptr);
3157 : 0 : body_node->data.block.statements.append(terminator_node);
3158 : :
3159 : 0 : while_scope->node->data.while_expr.body = body_node;
3160 : :
3161 : 0 : return while_scope->node;
3162 : : }
3163 : :
3164 : 0 : static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const clang::ForStmt *stmt) {
3165 : : AstNode *loop_block_node;
3166 : : TransScopeWhile *while_scope;
3167 : : TransScope *cond_scope;
3168 : 0 : const ZigClangStmt *init_stmt = bitcast(stmt->getInit());
3169 [ # # ]: 0 : if (init_stmt == nullptr) {
3170 : 0 : while_scope = trans_scope_while_create(c, parent_scope);
3171 : 0 : loop_block_node = while_scope->node;
3172 : 0 : cond_scope = parent_scope;
3173 : : } else {
3174 : 0 : TransScopeBlock *child_scope = trans_scope_block_create(c, parent_scope);
3175 : 0 : loop_block_node = child_scope->node;
3176 : :
3177 : : AstNode *vars_node;
3178 : 0 : cond_scope = trans_stmt(c, &child_scope->base, init_stmt, &vars_node);
3179 [ # # ]: 0 : if (cond_scope == nullptr)
3180 : 0 : return nullptr;
3181 [ # # ]: 0 : if (vars_node != nullptr)
3182 : 0 : child_scope->node->data.block.statements.append(vars_node);
3183 : :
3184 : 0 : while_scope = trans_scope_while_create(c, cond_scope);
3185 : :
3186 : 0 : child_scope->node->data.block.statements.append(while_scope->node);
3187 : : }
3188 : :
3189 : 0 : const ZigClangExpr *cond_expr = bitcast(stmt->getCond());
3190 [ # # ]: 0 : if (cond_expr == nullptr) {
3191 : 0 : while_scope->node->data.while_expr.condition = trans_create_node_bool(c, true);
3192 : : } else {
3193 : 0 : while_scope->node->data.while_expr.condition = trans_bool_expr(c, ResultUsedYes, cond_scope,
3194 : : cond_expr, TransRValue);
3195 : :
3196 [ # # ]: 0 : if (while_scope->node->data.while_expr.condition == nullptr)
3197 : 0 : return nullptr;
3198 : : }
3199 : :
3200 : 0 : const ZigClangExpr *inc_expr = bitcast(stmt->getInc());
3201 [ # # ]: 0 : if (inc_expr != nullptr) {
3202 : 0 : AstNode *inc_node = trans_expr(c, ResultUsedNo, cond_scope, inc_expr, TransRValue);
3203 [ # # ]: 0 : if (inc_node == nullptr)
3204 : 0 : return nullptr;
3205 : 0 : while_scope->node->data.while_expr.continue_expr = inc_node;
3206 : : }
3207 : :
3208 : : AstNode *body_statement;
3209 : 0 : TransScope *body_scope = trans_stmt(c, &while_scope->base, bitcast(stmt->getBody()), &body_statement);
3210 [ # # ]: 0 : if (body_scope == nullptr)
3211 : 0 : return nullptr;
3212 : :
3213 [ # # ]: 0 : if (body_statement == nullptr) {
3214 : 0 : while_scope->node->data.while_expr.body = trans_create_node(c, NodeTypeBlock);
3215 : : } else {
3216 : 0 : while_scope->node->data.while_expr.body = body_statement;
3217 : : }
3218 : :
3219 : 0 : return loop_block_node;
3220 : : }
3221 : :
3222 : 0 : static AstNode *trans_switch_stmt(Context *c, TransScope *parent_scope, const clang::SwitchStmt *stmt) {
3223 : 0 : TransScopeBlock *block_scope = trans_scope_block_create(c, parent_scope);
3224 : :
3225 : : TransScopeSwitch *switch_scope;
3226 : :
3227 : 0 : const clang::DeclStmt *var_decl_stmt = stmt->getConditionVariableDeclStmt();
3228 [ # # ]: 0 : if (var_decl_stmt == nullptr) {
3229 : 0 : switch_scope = trans_scope_switch_create(c, &block_scope->base);
3230 : : } else {
3231 : : AstNode *vars_node;
3232 : 0 : TransScope *var_scope = trans_stmt(c, &block_scope->base, (const ZigClangStmt *)var_decl_stmt, &vars_node);
3233 [ # # ]: 0 : if (var_scope == nullptr)
3234 : 0 : return nullptr;
3235 [ # # ]: 0 : if (vars_node != nullptr)
3236 : 0 : block_scope->node->data.block.statements.append(vars_node);
3237 : 0 : switch_scope = trans_scope_switch_create(c, var_scope);
3238 : : }
3239 : 0 : block_scope->node->data.block.statements.append(switch_scope->switch_node);
3240 : :
3241 : : // TODO avoid name collisions
3242 : 0 : Buf *end_label_name = buf_create_from_str("__switch");
3243 : 0 : switch_scope->end_label_name = end_label_name;
3244 : 0 : block_scope->node->data.block.name = end_label_name;
3245 : :
3246 : 0 : const ZigClangExpr *cond_expr = bitcast(stmt->getCond());
3247 [ # # ]: 0 : assert(cond_expr != nullptr);
3248 : :
3249 : 0 : AstNode *expr_node = trans_expr(c, ResultUsedYes, &block_scope->base, cond_expr, TransRValue);
3250 [ # # ]: 0 : if (expr_node == nullptr)
3251 : 0 : return nullptr;
3252 : 0 : switch_scope->switch_node->data.switch_expr.expr = expr_node;
3253 : :
3254 : : AstNode *body_node;
3255 : 0 : const ZigClangStmt *body_stmt = bitcast(stmt->getBody());
3256 [ # # ]: 0 : if (ZigClangStmt_getStmtClass(body_stmt) == ZigClangStmt_CompoundStmtClass) {
3257 [ # # ]: 0 : if (trans_compound_stmt_inline(c, &switch_scope->base, (const ZigClangCompoundStmt *)body_stmt,
3258 : 0 : block_scope->node, nullptr))
3259 : : {
3260 : 0 : return nullptr;
3261 : : }
3262 : : } else {
3263 : 0 : TransScope *body_scope = trans_stmt(c, &switch_scope->base, body_stmt, &body_node);
3264 [ # # ]: 0 : if (body_scope == nullptr)
3265 : 0 : return nullptr;
3266 [ # # ]: 0 : if (body_node != nullptr)
3267 : 0 : block_scope->node->data.block.statements.append(body_node);
3268 : : }
3269 : :
3270 [ # # ][ # # ]: 0 : if (!switch_scope->found_default && !stmt->isAllEnumCasesCovered()) {
[ # # ]
3271 : 0 : AstNode *prong_node = trans_create_node(c, NodeTypeSwitchProng);
3272 : 0 : prong_node->data.switch_prong.expr = trans_create_node_break(c, end_label_name, nullptr);
3273 : 0 : switch_scope->switch_node->data.switch_expr.prongs.append(prong_node);
3274 : : }
3275 : :
3276 : 0 : return block_scope->node;
3277 : : }
3278 : :
3279 : 0 : static TransScopeSwitch *trans_scope_switch_find(TransScope *scope) {
3280 [ # # ]: 0 : while (scope != nullptr) {
3281 [ # # ]: 0 : if (scope->id == TransScopeIdSwitch) {
3282 : 0 : return (TransScopeSwitch *)scope;
3283 : : }
3284 : 0 : scope = scope->parent;
3285 : : }
3286 : 0 : return nullptr;
3287 : : }
3288 : :
3289 : 0 : static int trans_switch_case(Context *c, TransScope *parent_scope, const clang::CaseStmt *stmt, AstNode **out_node,
3290 : : TransScope **out_scope) {
3291 : 0 : *out_node = nullptr;
3292 : :
3293 [ # # ]: 0 : if (stmt->getRHS() != nullptr) {
3294 : 0 : emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO support GNU switch case a ... b extension");
3295 : 0 : return ErrorUnexpected;
3296 : : }
3297 : :
3298 : 0 : TransScopeSwitch *switch_scope = trans_scope_switch_find(parent_scope);
3299 [ # # ]: 0 : assert(switch_scope != nullptr);
3300 : :
3301 : 0 : Buf *label_name = buf_sprintf("__case_%" PRIu32, switch_scope->case_index);
3302 : 0 : switch_scope->case_index += 1;
3303 : :
3304 : : {
3305 : : // Add the prong
3306 : 0 : AstNode *prong_node = trans_create_node(c, NodeTypeSwitchProng);
3307 : 0 : AstNode *item_node = trans_expr(c, ResultUsedYes, &switch_scope->base, bitcast(stmt->getLHS()), TransRValue);
3308 [ # # ]: 0 : if (item_node == nullptr)
3309 : 0 : return ErrorUnexpected;
3310 : 0 : prong_node->data.switch_prong.items.append(item_node);
3311 : 0 : prong_node->data.switch_prong.expr = trans_create_node_break(c, label_name, nullptr);
3312 : 0 : switch_scope->switch_node->data.switch_expr.prongs.append(prong_node);
3313 : : }
3314 : :
3315 : 0 : TransScopeBlock *scope_block = trans_scope_block_find(parent_scope);
3316 : :
3317 : 0 : AstNode *case_block = trans_create_node(c, NodeTypeBlock);
3318 : 0 : case_block->data.block.name = label_name;
3319 : 0 : case_block->data.block.statements = scope_block->node->data.block.statements;
3320 : 0 : scope_block->node->data.block.statements = {0};
3321 : 0 : scope_block->node->data.block.statements.append(case_block);
3322 : :
3323 : : AstNode *sub_stmt_node;
3324 : 0 : TransScope *new_scope = trans_stmt(c, parent_scope, bitcast(stmt->getSubStmt()), &sub_stmt_node);
3325 [ # # ]: 0 : if (new_scope == nullptr)
3326 : 0 : return ErrorUnexpected;
3327 [ # # ]: 0 : if (sub_stmt_node != nullptr)
3328 : 0 : scope_block->node->data.block.statements.append(sub_stmt_node);
3329 : :
3330 : 0 : *out_scope = new_scope;
3331 : 0 : return ErrorNone;
3332 : : }
3333 : :
3334 : 0 : static int trans_switch_default(Context *c, TransScope *parent_scope, const clang::DefaultStmt *stmt, AstNode **out_node,
3335 : : TransScope **out_scope)
3336 : : {
3337 : 0 : *out_node = nullptr;
3338 : :
3339 : 0 : TransScopeSwitch *switch_scope = trans_scope_switch_find(parent_scope);
3340 [ # # ]: 0 : assert(switch_scope != nullptr);
3341 : :
3342 : 0 : Buf *label_name = buf_sprintf("__default");
3343 : :
3344 : : {
3345 : : // Add the prong
3346 : 0 : AstNode *prong_node = trans_create_node(c, NodeTypeSwitchProng);
3347 : 0 : prong_node->data.switch_prong.expr = trans_create_node_break(c, label_name, nullptr);
3348 : 0 : switch_scope->switch_node->data.switch_expr.prongs.append(prong_node);
3349 : 0 : switch_scope->found_default = true;
3350 : : }
3351 : :
3352 : 0 : TransScopeBlock *scope_block = trans_scope_block_find(parent_scope);
3353 : :
3354 : 0 : AstNode *case_block = trans_create_node(c, NodeTypeBlock);
3355 : 0 : case_block->data.block.name = label_name;
3356 : 0 : case_block->data.block.statements = scope_block->node->data.block.statements;
3357 : 0 : scope_block->node->data.block.statements = {0};
3358 : 0 : scope_block->node->data.block.statements.append(case_block);
3359 : :
3360 : : AstNode *sub_stmt_node;
3361 : 0 : TransScope *new_scope = trans_stmt(c, parent_scope, bitcast(stmt->getSubStmt()), &sub_stmt_node);
3362 [ # # ]: 0 : if (new_scope == nullptr)
3363 : 0 : return ErrorUnexpected;
3364 [ # # ]: 0 : if (sub_stmt_node != nullptr)
3365 : 0 : scope_block->node->data.block.statements.append(sub_stmt_node);
3366 : :
3367 : 0 : *out_scope = new_scope;
3368 : 0 : return ErrorNone;
3369 : : }
3370 : :
3371 : 0 : static AstNode *trans_string_literal(Context *c, ResultUsed result_used, TransScope *scope, const ZigClangStringLiteral *stmt) {
3372 [ # # # # : 0 : switch (ZigClangStringLiteral_getKind(stmt)) {
# ]
3373 : 0 : case ZigClangStringLiteral_StringKind_Ascii:
3374 : : case ZigClangStringLiteral_StringKind_UTF8: {
3375 : : size_t str_len;
3376 : 0 : const char *str_ptr = ZigClangStringLiteral_getString_bytes_begin_size(stmt, &str_len);
3377 : 0 : AstNode *node = trans_create_node_str_lit_c(c, buf_create_from_mem(str_ptr, str_len));
3378 : 0 : return maybe_suppress_result(c, result_used, node);
3379 : : }
3380 : 0 : case ZigClangStringLiteral_StringKind_UTF16:
3381 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc((const ZigClangStmt *)stmt), "TODO support UTF16 string literals");
3382 : 0 : return nullptr;
3383 : 0 : case ZigClangStringLiteral_StringKind_UTF32:
3384 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc((const ZigClangStmt *)stmt), "TODO support UTF32 string literals");
3385 : 0 : return nullptr;
3386 : 0 : case ZigClangStringLiteral_StringKind_Wide:
3387 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc((const ZigClangStmt *)stmt), "TODO support wide string literals");
3388 : 0 : return nullptr;
3389 : : }
3390 : 0 : zig_unreachable();
3391 : : }
3392 : :
3393 : 0 : static AstNode *trans_break_stmt(Context *c, TransScope *scope, const clang::BreakStmt *stmt) {
3394 : 0 : TransScope *cur_scope = scope;
3395 [ # # ]: 0 : while (cur_scope != nullptr) {
3396 [ # # ]: 0 : if (cur_scope->id == TransScopeIdWhile) {
3397 : 0 : return trans_create_node(c, NodeTypeBreak);
3398 [ # # ]: 0 : } else if (cur_scope->id == TransScopeIdSwitch) {
3399 : 0 : TransScopeSwitch *switch_scope = (TransScopeSwitch *)cur_scope;
3400 : 0 : return trans_create_node_break(c, switch_scope->end_label_name, nullptr);
3401 : : }
3402 : 0 : cur_scope = cur_scope->parent;
3403 : : }
3404 : 0 : zig_unreachable();
3405 : : }
3406 : :
3407 : 0 : static AstNode *trans_continue_stmt(Context *c, TransScope *scope, const ZigClangContinueStmt *stmt) {
3408 : 0 : return trans_create_node(c, NodeTypeContinue);
3409 : : }
3410 : :
3411 : 0 : static AstNode *trans_predefined_expr(Context *c, ResultUsed result_used, TransScope *scope,
3412 : : const ZigClangPredefinedExpr *expr)
3413 : : {
3414 : 0 : return trans_string_literal(c, result_used, scope, ZigClangPredefinedExpr_getFunctionName(expr));
3415 : : }
3416 : :
3417 : 0 : static int wrap_stmt(AstNode **out_node, TransScope **out_scope, TransScope *in_scope, AstNode *result_node) {
3418 [ # # ]: 0 : if (result_node == nullptr)
3419 : 0 : return ErrorUnexpected;
3420 : 0 : *out_node = result_node;
3421 [ # # ]: 0 : if (out_scope != nullptr)
3422 : 0 : *out_scope = in_scope;
3423 : 0 : return ErrorNone;
3424 : : }
3425 : :
3426 : 0 : static int trans_stmt_extra(Context *c, TransScope *scope, const ZigClangStmt *stmt,
3427 : : ResultUsed result_used, TransLRValue lrvalue,
3428 : : AstNode **out_node, TransScope **out_child_scope,
3429 : : TransScope **out_node_scope)
3430 : : {
3431 : 0 : ZigClangStmtClass sc = ZigClangStmt_getStmtClass(stmt);
3432 [ # # # # : 0 : switch (sc) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ]
3433 : 0 : case ZigClangStmt_ReturnStmtClass:
3434 : 0 : return wrap_stmt(out_node, out_child_scope, scope,
3435 : 0 : trans_return_stmt(c, scope, (const clang::ReturnStmt *)stmt));
3436 : 0 : case ZigClangStmt_CompoundStmtClass:
3437 : 0 : return wrap_stmt(out_node, out_child_scope, scope,
3438 : 0 : trans_compound_stmt(c, scope, (const ZigClangCompoundStmt *)stmt, out_node_scope));
3439 : 0 : case ZigClangStmt_IntegerLiteralClass:
3440 : 0 : return wrap_stmt(out_node, out_child_scope, scope,
3441 : 0 : trans_integer_literal(c, result_used, (const clang::IntegerLiteral *)stmt));
3442 : 0 : case ZigClangStmt_ConditionalOperatorClass:
3443 : 0 : return wrap_stmt(out_node, out_child_scope, scope,
3444 : 0 : trans_conditional_operator(c, result_used, scope, (const clang::ConditionalOperator *)stmt));
3445 : 0 : case ZigClangStmt_BinaryOperatorClass:
3446 : 0 : return wrap_stmt(out_node, out_child_scope, scope,
3447 : 0 : trans_binary_operator(c, result_used, scope, (const clang::BinaryOperator *)stmt));
3448 : 0 : case ZigClangStmt_CompoundAssignOperatorClass:
3449 : 0 : return wrap_stmt(out_node, out_child_scope, scope,
3450 : 0 : trans_compound_assign_operator(c, result_used, scope, (const clang::CompoundAssignOperator *)stmt));
3451 : 0 : case ZigClangStmt_ImplicitCastExprClass:
3452 : 0 : return wrap_stmt(out_node, out_child_scope, scope,
3453 : 0 : trans_implicit_cast_expr(c, result_used, scope, (const clang::ImplicitCastExpr *)stmt));
3454 : 0 : case ZigClangStmt_DeclRefExprClass:
3455 : 0 : return wrap_stmt(out_node, out_child_scope, scope,
3456 : 0 : trans_decl_ref_expr(c, scope, (const clang::DeclRefExpr *)stmt, lrvalue));
3457 : 0 : case ZigClangStmt_UnaryOperatorClass:
3458 : 0 : return wrap_stmt(out_node, out_child_scope, scope,
3459 : 0 : trans_unary_operator(c, result_used, scope, (const clang::UnaryOperator *)stmt));
3460 : 0 : case ZigClangStmt_DeclStmtClass:
3461 : 0 : return trans_local_declaration(c, scope, (const clang::DeclStmt *)stmt, out_node, out_child_scope);
3462 : 0 : case ZigClangStmt_DoStmtClass:
3463 : : case ZigClangStmt_WhileStmtClass: {
3464 : : AstNode *while_node = sc == ZigClangStmt_DoStmtClass
3465 [ # # ]: 0 : ? trans_do_loop(c, scope, (const clang::DoStmt *)stmt)
3466 : 0 : : trans_while_loop(c, scope, (const clang::WhileStmt *)stmt);
3467 : :
3468 [ # # ]: 0 : if (while_node == nullptr)
3469 : 0 : return ErrorUnexpected;
3470 : :
3471 [ # # ]: 0 : assert(while_node->type == NodeTypeWhileExpr);
3472 [ # # ]: 0 : if (while_node->data.while_expr.body == nullptr)
3473 : 0 : while_node->data.while_expr.body = trans_create_node(c, NodeTypeBlock);
3474 : :
3475 : 0 : return wrap_stmt(out_node, out_child_scope, scope, while_node);
3476 : : }
3477 : 0 : case ZigClangStmt_IfStmtClass:
3478 : 0 : return wrap_stmt(out_node, out_child_scope, scope,
3479 : 0 : trans_if_statement(c, scope, (const clang::IfStmt *)stmt));
3480 : 0 : case ZigClangStmt_CallExprClass:
3481 : 0 : return wrap_stmt(out_node, out_child_scope, scope,
3482 : 0 : trans_call_expr(c, result_used, scope, (const clang::CallExpr *)stmt));
3483 : 0 : case ZigClangStmt_NullStmtClass:
3484 : 0 : *out_node = trans_create_node(c, NodeTypeBlock);
3485 : 0 : *out_child_scope = scope;
3486 : 0 : return ErrorNone;
3487 : 0 : case ZigClangStmt_MemberExprClass:
3488 : 0 : return wrap_stmt(out_node, out_child_scope, scope,
3489 : 0 : trans_member_expr(c, result_used, scope, (const clang::MemberExpr *)stmt));
3490 : 0 : case ZigClangStmt_ArraySubscriptExprClass:
3491 : 0 : return wrap_stmt(out_node, out_child_scope, scope,
3492 : 0 : trans_array_subscript_expr(c, result_used, scope, (const clang::ArraySubscriptExpr *)stmt));
3493 : 0 : case ZigClangStmt_CStyleCastExprClass:
3494 : 0 : return wrap_stmt(out_node, out_child_scope, scope,
3495 : 0 : trans_c_style_cast_expr(c, result_used, scope, (const clang::CStyleCastExpr *)stmt, lrvalue));
3496 : 0 : case ZigClangStmt_UnaryExprOrTypeTraitExprClass:
3497 : 0 : return wrap_stmt(out_node, out_child_scope, scope,
3498 : 0 : trans_unary_expr_or_type_trait_expr(c, result_used, scope, (const clang::UnaryExprOrTypeTraitExpr *)stmt));
3499 : 0 : case ZigClangStmt_ForStmtClass: {
3500 : 0 : AstNode *node = trans_for_loop(c, scope, (const clang::ForStmt *)stmt);
3501 : 0 : return wrap_stmt(out_node, out_child_scope, scope, node);
3502 : : }
3503 : 0 : case ZigClangStmt_StringLiteralClass:
3504 : 0 : return wrap_stmt(out_node, out_child_scope, scope,
3505 : 0 : trans_string_literal(c, result_used, scope, (const ZigClangStringLiteral *)stmt));
3506 : 0 : case ZigClangStmt_BreakStmtClass:
3507 : 0 : return wrap_stmt(out_node, out_child_scope, scope,
3508 : 0 : trans_break_stmt(c, scope, (const clang::BreakStmt *)stmt));
3509 : 0 : case ZigClangStmt_ContinueStmtClass:
3510 : 0 : return wrap_stmt(out_node, out_child_scope, scope,
3511 : 0 : trans_continue_stmt(c, scope, (const ZigClangContinueStmt *)stmt));
3512 : 0 : case ZigClangStmt_ParenExprClass:
3513 : 0 : return wrap_stmt(out_node, out_child_scope, scope,
3514 : : trans_expr(c, result_used, scope,
3515 : 0 : bitcast(((const clang::ParenExpr*)stmt)->getSubExpr()), lrvalue));
3516 : 0 : case ZigClangStmt_SwitchStmtClass:
3517 : 0 : return wrap_stmt(out_node, out_child_scope, scope,
3518 : 0 : trans_switch_stmt(c, scope, (const clang::SwitchStmt *)stmt));
3519 : 0 : case ZigClangStmt_CaseStmtClass:
3520 : 0 : return trans_switch_case(c, scope, (const clang::CaseStmt *)stmt, out_node, out_child_scope);
3521 : 0 : case ZigClangStmt_DefaultStmtClass:
3522 : 0 : return trans_switch_default(c, scope, (const clang::DefaultStmt *)stmt, out_node, out_child_scope);
3523 : 0 : case ZigClangStmt_ConstantExprClass:
3524 : 0 : return wrap_stmt(out_node, out_child_scope, scope,
3525 : 0 : trans_constant_expr(c, result_used, (const clang::ConstantExpr *)stmt));
3526 : 0 : case ZigClangStmt_PredefinedExprClass:
3527 : 0 : return wrap_stmt(out_node, out_child_scope, scope,
3528 : 0 : trans_predefined_expr(c, result_used, scope, (const ZigClangPredefinedExpr *)stmt));
3529 : 0 : case ZigClangStmt_StmtExprClass:
3530 : 0 : return wrap_stmt(out_node, out_child_scope, scope,
3531 : 0 : trans_stmt_expr(c, result_used, scope, (const clang::StmtExpr *)stmt, out_node_scope));
3532 : 0 : case ZigClangStmt_NoStmtClass:
3533 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C NoStmtClass");
3534 : 0 : return ErrorUnexpected;
3535 : 0 : case ZigClangStmt_GCCAsmStmtClass:
3536 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C GCCAsmStmtClass");
3537 : 0 : return ErrorUnexpected;
3538 : 0 : case ZigClangStmt_MSAsmStmtClass:
3539 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C MSAsmStmtClass");
3540 : 0 : return ErrorUnexpected;
3541 : 0 : case ZigClangStmt_AttributedStmtClass:
3542 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C AttributedStmtClass");
3543 : 0 : return ErrorUnexpected;
3544 : 0 : case ZigClangStmt_CXXCatchStmtClass:
3545 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXCatchStmtClass");
3546 : 0 : return ErrorUnexpected;
3547 : 0 : case ZigClangStmt_CXXForRangeStmtClass:
3548 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXForRangeStmtClass");
3549 : 0 : return ErrorUnexpected;
3550 : 0 : case ZigClangStmt_CXXTryStmtClass:
3551 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXTryStmtClass");
3552 : 0 : return ErrorUnexpected;
3553 : 0 : case ZigClangStmt_CapturedStmtClass:
3554 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CapturedStmtClass");
3555 : 0 : return ErrorUnexpected;
3556 : 0 : case ZigClangStmt_CoreturnStmtClass:
3557 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CoreturnStmtClass");
3558 : 0 : return ErrorUnexpected;
3559 : 0 : case ZigClangStmt_CoroutineBodyStmtClass:
3560 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CoroutineBodyStmtClass");
3561 : 0 : return ErrorUnexpected;
3562 : 0 : case ZigClangStmt_BinaryConditionalOperatorClass:
3563 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C BinaryConditionalOperatorClass");
3564 : 0 : return ErrorUnexpected;
3565 : 0 : case ZigClangStmt_AddrLabelExprClass:
3566 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C AddrLabelExprClass");
3567 : 0 : return ErrorUnexpected;
3568 : 0 : case ZigClangStmt_ArrayInitIndexExprClass:
3569 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ArrayInitIndexExprClass");
3570 : 0 : return ErrorUnexpected;
3571 : 0 : case ZigClangStmt_ArrayInitLoopExprClass:
3572 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ArrayInitLoopExprClass");
3573 : 0 : return ErrorUnexpected;
3574 : 0 : case ZigClangStmt_ArrayTypeTraitExprClass:
3575 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ArrayTypeTraitExprClass");
3576 : 0 : return ErrorUnexpected;
3577 : 0 : case ZigClangStmt_AsTypeExprClass:
3578 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C AsTypeExprClass");
3579 : 0 : return ErrorUnexpected;
3580 : 0 : case ZigClangStmt_AtomicExprClass:
3581 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C AtomicExprClass");
3582 : 0 : return ErrorUnexpected;
3583 : 0 : case ZigClangStmt_BlockExprClass:
3584 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C BlockExprClass");
3585 : 0 : return ErrorUnexpected;
3586 : 0 : case ZigClangStmt_CXXBindTemporaryExprClass:
3587 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXBindTemporaryExprClass");
3588 : 0 : return ErrorUnexpected;
3589 : 0 : case ZigClangStmt_CXXBoolLiteralExprClass:
3590 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXBoolLiteralExprClass");
3591 : 0 : return ErrorUnexpected;
3592 : 0 : case ZigClangStmt_CXXConstructExprClass:
3593 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXConstructExprClass");
3594 : 0 : return ErrorUnexpected;
3595 : 0 : case ZigClangStmt_CXXTemporaryObjectExprClass:
3596 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXTemporaryObjectExprClass");
3597 : 0 : return ErrorUnexpected;
3598 : 0 : case ZigClangStmt_CXXDefaultArgExprClass:
3599 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXDefaultArgExprClass");
3600 : 0 : return ErrorUnexpected;
3601 : 0 : case ZigClangStmt_CXXDefaultInitExprClass:
3602 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXDefaultInitExprClass");
3603 : 0 : return ErrorUnexpected;
3604 : 0 : case ZigClangStmt_CXXDeleteExprClass:
3605 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXDeleteExprClass");
3606 : 0 : return ErrorUnexpected;
3607 : 0 : case ZigClangStmt_CXXDependentScopeMemberExprClass:
3608 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXDependentScopeMemberExprClass");
3609 : 0 : return ErrorUnexpected;
3610 : 0 : case ZigClangStmt_CXXFoldExprClass:
3611 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXFoldExprClass");
3612 : 0 : return ErrorUnexpected;
3613 : 0 : case ZigClangStmt_CXXInheritedCtorInitExprClass:
3614 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXInheritedCtorInitExprClass");
3615 : 0 : return ErrorUnexpected;
3616 : 0 : case ZigClangStmt_CXXNewExprClass:
3617 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXNewExprClass");
3618 : 0 : return ErrorUnexpected;
3619 : 0 : case ZigClangStmt_CXXNoexceptExprClass:
3620 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXNoexceptExprClass");
3621 : 0 : return ErrorUnexpected;
3622 : 0 : case ZigClangStmt_CXXNullPtrLiteralExprClass:
3623 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXNullPtrLiteralExprClass");
3624 : 0 : return ErrorUnexpected;
3625 : 0 : case ZigClangStmt_CXXPseudoDestructorExprClass:
3626 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXPseudoDestructorExprClass");
3627 : 0 : return ErrorUnexpected;
3628 : 0 : case ZigClangStmt_CXXScalarValueInitExprClass:
3629 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXScalarValueInitExprClass");
3630 : 0 : return ErrorUnexpected;
3631 : 0 : case ZigClangStmt_CXXStdInitializerListExprClass:
3632 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXStdInitializerListExprClass");
3633 : 0 : return ErrorUnexpected;
3634 : 0 : case ZigClangStmt_CXXThisExprClass:
3635 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXThisExprClass");
3636 : 0 : return ErrorUnexpected;
3637 : 0 : case ZigClangStmt_CXXThrowExprClass:
3638 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXThrowExprClass");
3639 : 0 : return ErrorUnexpected;
3640 : 0 : case ZigClangStmt_CXXTypeidExprClass:
3641 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXTypeidExprClass");
3642 : 0 : return ErrorUnexpected;
3643 : 0 : case ZigClangStmt_CXXUnresolvedConstructExprClass:
3644 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXUnresolvedConstructExprClass");
3645 : 0 : return ErrorUnexpected;
3646 : 0 : case ZigClangStmt_CXXUuidofExprClass:
3647 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXUuidofExprClass");
3648 : 0 : return ErrorUnexpected;
3649 : 0 : case ZigClangStmt_CUDAKernelCallExprClass:
3650 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CUDAKernelCallExprClass");
3651 : 0 : return ErrorUnexpected;
3652 : 0 : case ZigClangStmt_CXXMemberCallExprClass:
3653 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXMemberCallExprClass");
3654 : 0 : return ErrorUnexpected;
3655 : 0 : case ZigClangStmt_CXXOperatorCallExprClass:
3656 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXOperatorCallExprClass");
3657 : 0 : return ErrorUnexpected;
3658 : 0 : case ZigClangStmt_UserDefinedLiteralClass:
3659 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C UserDefinedLiteralClass");
3660 : 0 : return ErrorUnexpected;
3661 : 0 : case ZigClangStmt_CXXFunctionalCastExprClass:
3662 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXFunctionalCastExprClass");
3663 : 0 : return ErrorUnexpected;
3664 : 0 : case ZigClangStmt_CXXConstCastExprClass:
3665 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXConstCastExprClass");
3666 : 0 : return ErrorUnexpected;
3667 : 0 : case ZigClangStmt_CXXDynamicCastExprClass:
3668 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXDynamicCastExprClass");
3669 : 0 : return ErrorUnexpected;
3670 : 0 : case ZigClangStmt_CXXReinterpretCastExprClass:
3671 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXReinterpretCastExprClass");
3672 : 0 : return ErrorUnexpected;
3673 : 0 : case ZigClangStmt_CXXStaticCastExprClass:
3674 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXStaticCastExprClass");
3675 : 0 : return ErrorUnexpected;
3676 : 0 : case ZigClangStmt_ObjCBridgedCastExprClass:
3677 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCBridgedCastExprClass");
3678 : 0 : return ErrorUnexpected;
3679 : 0 : case ZigClangStmt_CharacterLiteralClass:
3680 : 0 : return wrap_stmt(out_node, out_child_scope, scope,
3681 : 0 : trans_character_literal(c, result_used, (const clang::CharacterLiteral *)stmt));
3682 : : return ErrorUnexpected;
3683 : 0 : case ZigClangStmt_ChooseExprClass:
3684 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ChooseExprClass");
3685 : 0 : return ErrorUnexpected;
3686 : 0 : case ZigClangStmt_CompoundLiteralExprClass:
3687 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CompoundLiteralExprClass");
3688 : 0 : return ErrorUnexpected;
3689 : 0 : case ZigClangStmt_ConvertVectorExprClass:
3690 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ConvertVectorExprClass");
3691 : 0 : return ErrorUnexpected;
3692 : 0 : case ZigClangStmt_CoawaitExprClass:
3693 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CoawaitExprClass");
3694 : 0 : return ErrorUnexpected;
3695 : 0 : case ZigClangStmt_CoyieldExprClass:
3696 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CoyieldExprClass");
3697 : 0 : return ErrorUnexpected;
3698 : 0 : case ZigClangStmt_DependentCoawaitExprClass:
3699 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C DependentCoawaitExprClass");
3700 : 0 : return ErrorUnexpected;
3701 : 0 : case ZigClangStmt_DependentScopeDeclRefExprClass:
3702 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C DependentScopeDeclRefExprClass");
3703 : 0 : return ErrorUnexpected;
3704 : 0 : case ZigClangStmt_DesignatedInitExprClass:
3705 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C DesignatedInitExprClass");
3706 : 0 : return ErrorUnexpected;
3707 : 0 : case ZigClangStmt_DesignatedInitUpdateExprClass:
3708 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C DesignatedInitUpdateExprClass");
3709 : 0 : return ErrorUnexpected;
3710 : 0 : case ZigClangStmt_ExpressionTraitExprClass:
3711 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ExpressionTraitExprClass");
3712 : 0 : return ErrorUnexpected;
3713 : 0 : case ZigClangStmt_ExtVectorElementExprClass:
3714 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ExtVectorElementExprClass");
3715 : 0 : return ErrorUnexpected;
3716 : 0 : case ZigClangStmt_FixedPointLiteralClass:
3717 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C FixedPointLiteralClass");
3718 : 0 : return ErrorUnexpected;
3719 : 0 : case ZigClangStmt_FloatingLiteralClass:
3720 : 0 : return wrap_stmt(out_node, out_child_scope, scope,
3721 : 0 : trans_floating_literal(c, result_used, (const clang::FloatingLiteral *)stmt));
3722 : 0 : case ZigClangStmt_ExprWithCleanupsClass:
3723 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ExprWithCleanupsClass");
3724 : 0 : return ErrorUnexpected;
3725 : 0 : case ZigClangStmt_FunctionParmPackExprClass:
3726 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C FunctionParmPackExprClass");
3727 : 0 : return ErrorUnexpected;
3728 : 0 : case ZigClangStmt_GNUNullExprClass:
3729 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C GNUNullExprClass");
3730 : 0 : return ErrorUnexpected;
3731 : 0 : case ZigClangStmt_GenericSelectionExprClass:
3732 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C GenericSelectionExprClass");
3733 : 0 : return ErrorUnexpected;
3734 : 0 : case ZigClangStmt_ImaginaryLiteralClass:
3735 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ImaginaryLiteralClass");
3736 : 0 : return ErrorUnexpected;
3737 : 0 : case ZigClangStmt_ImplicitValueInitExprClass:
3738 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ImplicitValueInitExprClass");
3739 : 0 : return ErrorUnexpected;
3740 : 0 : case ZigClangStmt_InitListExprClass:
3741 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C InitListExprClass");
3742 : 0 : return ErrorUnexpected;
3743 : 0 : case ZigClangStmt_LambdaExprClass:
3744 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C LambdaExprClass");
3745 : 0 : return ErrorUnexpected;
3746 : 0 : case ZigClangStmt_MSPropertyRefExprClass:
3747 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C MSPropertyRefExprClass");
3748 : 0 : return ErrorUnexpected;
3749 : 0 : case ZigClangStmt_MSPropertySubscriptExprClass:
3750 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C MSPropertySubscriptExprClass");
3751 : 0 : return ErrorUnexpected;
3752 : 0 : case ZigClangStmt_MaterializeTemporaryExprClass:
3753 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C MaterializeTemporaryExprClass");
3754 : 0 : return ErrorUnexpected;
3755 : 0 : case ZigClangStmt_NoInitExprClass:
3756 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C NoInitExprClass");
3757 : 0 : return ErrorUnexpected;
3758 : 0 : case ZigClangStmt_OMPArraySectionExprClass:
3759 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPArraySectionExprClass");
3760 : 0 : return ErrorUnexpected;
3761 : 0 : case ZigClangStmt_ObjCArrayLiteralClass:
3762 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCArrayLiteralClass");
3763 : 0 : return ErrorUnexpected;
3764 : 0 : case ZigClangStmt_ObjCAvailabilityCheckExprClass:
3765 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAvailabilityCheckExprClass");
3766 : 0 : return ErrorUnexpected;
3767 : 0 : case ZigClangStmt_ObjCBoolLiteralExprClass:
3768 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCBoolLiteralExprClass");
3769 : 0 : return ErrorUnexpected;
3770 : 0 : case ZigClangStmt_ObjCBoxedExprClass:
3771 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCBoxedExprClass");
3772 : 0 : return ErrorUnexpected;
3773 : 0 : case ZigClangStmt_ObjCDictionaryLiteralClass:
3774 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCDictionaryLiteralClass");
3775 : 0 : return ErrorUnexpected;
3776 : 0 : case ZigClangStmt_ObjCEncodeExprClass:
3777 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCEncodeExprClass");
3778 : 0 : return ErrorUnexpected;
3779 : 0 : case ZigClangStmt_ObjCIndirectCopyRestoreExprClass:
3780 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCIndirectCopyRestoreExprClass");
3781 : 0 : return ErrorUnexpected;
3782 : 0 : case ZigClangStmt_ObjCIsaExprClass:
3783 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCIsaExprClass");
3784 : 0 : return ErrorUnexpected;
3785 : 0 : case ZigClangStmt_ObjCIvarRefExprClass:
3786 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCIvarRefExprClass");
3787 : 0 : return ErrorUnexpected;
3788 : 0 : case ZigClangStmt_ObjCMessageExprClass:
3789 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCMessageExprClass");
3790 : 0 : return ErrorUnexpected;
3791 : 0 : case ZigClangStmt_ObjCPropertyRefExprClass:
3792 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCPropertyRefExprClass");
3793 : 0 : return ErrorUnexpected;
3794 : 0 : case ZigClangStmt_ObjCProtocolExprClass:
3795 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCProtocolExprClass");
3796 : 0 : return ErrorUnexpected;
3797 : 0 : case ZigClangStmt_ObjCSelectorExprClass:
3798 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCSelectorExprClass");
3799 : 0 : return ErrorUnexpected;
3800 : 0 : case ZigClangStmt_ObjCStringLiteralClass:
3801 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCStringLiteralClass");
3802 : 0 : return ErrorUnexpected;
3803 : 0 : case ZigClangStmt_ObjCSubscriptRefExprClass:
3804 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCSubscriptRefExprClass");
3805 : 0 : return ErrorUnexpected;
3806 : 0 : case ZigClangStmt_OffsetOfExprClass:
3807 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OffsetOfExprClass");
3808 : 0 : return ErrorUnexpected;
3809 : 0 : case ZigClangStmt_OpaqueValueExprClass:
3810 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OpaqueValueExprClass");
3811 : 0 : return ErrorUnexpected;
3812 : 0 : case ZigClangStmt_UnresolvedLookupExprClass:
3813 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C UnresolvedLookupExprClass");
3814 : 0 : return ErrorUnexpected;
3815 : 0 : case ZigClangStmt_UnresolvedMemberExprClass:
3816 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C UnresolvedMemberExprClass");
3817 : 0 : return ErrorUnexpected;
3818 : 0 : case ZigClangStmt_PackExpansionExprClass:
3819 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C PackExpansionExprClass");
3820 : 0 : return ErrorUnexpected;
3821 : 0 : case ZigClangStmt_ParenListExprClass:
3822 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ParenListExprClass");
3823 : 0 : return ErrorUnexpected;
3824 : 0 : case ZigClangStmt_PseudoObjectExprClass:
3825 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C PseudoObjectExprClass");
3826 : 0 : return ErrorUnexpected;
3827 : 0 : case ZigClangStmt_ShuffleVectorExprClass:
3828 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ShuffleVectorExprClass");
3829 : 0 : return ErrorUnexpected;
3830 : 0 : case ZigClangStmt_SizeOfPackExprClass:
3831 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SizeOfPackExprClass");
3832 : 0 : return ErrorUnexpected;
3833 : 0 : case ZigClangStmt_SubstNonTypeTemplateParmExprClass:
3834 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SubstNonTypeTemplateParmExprClass");
3835 : 0 : return ErrorUnexpected;
3836 : 0 : case ZigClangStmt_SubstNonTypeTemplateParmPackExprClass:
3837 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SubstNonTypeTemplateParmPackExprClass");
3838 : 0 : return ErrorUnexpected;
3839 : 0 : case ZigClangStmt_TypeTraitExprClass:
3840 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C TypeTraitExprClass");
3841 : 0 : return ErrorUnexpected;
3842 : 0 : case ZigClangStmt_TypoExprClass:
3843 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C TypoExprClass");
3844 : 0 : return ErrorUnexpected;
3845 : 0 : case ZigClangStmt_VAArgExprClass:
3846 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C VAArgExprClass");
3847 : 0 : return ErrorUnexpected;
3848 : 0 : case ZigClangStmt_GotoStmtClass:
3849 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C GotoStmtClass");
3850 : 0 : return ErrorUnexpected;
3851 : 0 : case ZigClangStmt_IndirectGotoStmtClass:
3852 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C IndirectGotoStmtClass");
3853 : 0 : return ErrorUnexpected;
3854 : 0 : case ZigClangStmt_LabelStmtClass:
3855 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C LabelStmtClass");
3856 : 0 : return ErrorUnexpected;
3857 : 0 : case ZigClangStmt_MSDependentExistsStmtClass:
3858 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C MSDependentExistsStmtClass");
3859 : 0 : return ErrorUnexpected;
3860 : 0 : case ZigClangStmt_OMPAtomicDirectiveClass:
3861 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPAtomicDirectiveClass");
3862 : 0 : return ErrorUnexpected;
3863 : 0 : case ZigClangStmt_OMPBarrierDirectiveClass:
3864 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPBarrierDirectiveClass");
3865 : 0 : return ErrorUnexpected;
3866 : 0 : case ZigClangStmt_OMPCancelDirectiveClass:
3867 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPCancelDirectiveClass");
3868 : 0 : return ErrorUnexpected;
3869 : 0 : case ZigClangStmt_OMPCancellationPointDirectiveClass:
3870 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPCancellationPointDirectiveClass");
3871 : 0 : return ErrorUnexpected;
3872 : 0 : case ZigClangStmt_OMPCriticalDirectiveClass:
3873 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPCriticalDirectiveClass");
3874 : 0 : return ErrorUnexpected;
3875 : 0 : case ZigClangStmt_OMPFlushDirectiveClass:
3876 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPFlushDirectiveClass");
3877 : 0 : return ErrorUnexpected;
3878 : 0 : case ZigClangStmt_OMPDistributeDirectiveClass:
3879 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPDistributeDirectiveClass");
3880 : 0 : return ErrorUnexpected;
3881 : 0 : case ZigClangStmt_OMPDistributeParallelForDirectiveClass:
3882 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPDistributeParallelForDirectiveClass");
3883 : 0 : return ErrorUnexpected;
3884 : 0 : case ZigClangStmt_OMPDistributeParallelForSimdDirectiveClass:
3885 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPDistributeParallelForSimdDirectiveClass");
3886 : 0 : return ErrorUnexpected;
3887 : 0 : case ZigClangStmt_OMPDistributeSimdDirectiveClass:
3888 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPDistributeSimdDirectiveClass");
3889 : 0 : return ErrorUnexpected;
3890 : 0 : case ZigClangStmt_OMPForDirectiveClass:
3891 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPForDirectiveClass");
3892 : 0 : return ErrorUnexpected;
3893 : 0 : case ZigClangStmt_OMPForSimdDirectiveClass:
3894 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPForSimdDirectiveClass");
3895 : 0 : return ErrorUnexpected;
3896 : 0 : case ZigClangStmt_OMPParallelForDirectiveClass:
3897 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPParallelForDirectiveClass");
3898 : 0 : return ErrorUnexpected;
3899 : 0 : case ZigClangStmt_OMPParallelForSimdDirectiveClass:
3900 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPParallelForSimdDirectiveClass");
3901 : 0 : return ErrorUnexpected;
3902 : 0 : case ZigClangStmt_OMPSimdDirectiveClass:
3903 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPSimdDirectiveClass");
3904 : 0 : return ErrorUnexpected;
3905 : 0 : case ZigClangStmt_OMPTargetParallelForSimdDirectiveClass:
3906 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetParallelForSimdDirectiveClass");
3907 : 0 : return ErrorUnexpected;
3908 : 0 : case ZigClangStmt_OMPTargetSimdDirectiveClass:
3909 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetSimdDirectiveClass");
3910 : 0 : return ErrorUnexpected;
3911 : 0 : case ZigClangStmt_OMPTargetTeamsDistributeDirectiveClass:
3912 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetTeamsDistributeDirectiveClass");
3913 : 0 : return ErrorUnexpected;
3914 : 0 : case ZigClangStmt_OMPTargetTeamsDistributeParallelForDirectiveClass:
3915 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetTeamsDistributeParallelForDirectiveClass");
3916 : 0 : return ErrorUnexpected;
3917 : 0 : case ZigClangStmt_OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
3918 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetTeamsDistributeParallelForSimdDirectiveClass");
3919 : 0 : return ErrorUnexpected;
3920 : 0 : case ZigClangStmt_OMPTargetTeamsDistributeSimdDirectiveClass:
3921 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetTeamsDistributeSimdDirectiveClass");
3922 : 0 : return ErrorUnexpected;
3923 : 0 : case ZigClangStmt_OMPTaskLoopDirectiveClass:
3924 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTaskLoopDirectiveClass");
3925 : 0 : return ErrorUnexpected;
3926 : 0 : case ZigClangStmt_OMPTaskLoopSimdDirectiveClass:
3927 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTaskLoopSimdDirectiveClass");
3928 : 0 : return ErrorUnexpected;
3929 : 0 : case ZigClangStmt_OMPTeamsDistributeDirectiveClass:
3930 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTeamsDistributeDirectiveClass");
3931 : 0 : return ErrorUnexpected;
3932 : 0 : case ZigClangStmt_OMPTeamsDistributeParallelForDirectiveClass:
3933 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTeamsDistributeParallelForDirectiveClass");
3934 : 0 : return ErrorUnexpected;
3935 : 0 : case ZigClangStmt_OMPTeamsDistributeParallelForSimdDirectiveClass:
3936 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTeamsDistributeParallelForSimdDirectiveClass");
3937 : 0 : return ErrorUnexpected;
3938 : 0 : case ZigClangStmt_OMPTeamsDistributeSimdDirectiveClass:
3939 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTeamsDistributeSimdDirectiveClass");
3940 : 0 : return ErrorUnexpected;
3941 : 0 : case ZigClangStmt_OMPMasterDirectiveClass:
3942 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPMasterDirectiveClass");
3943 : 0 : return ErrorUnexpected;
3944 : 0 : case ZigClangStmt_OMPOrderedDirectiveClass:
3945 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPOrderedDirectiveClass");
3946 : 0 : return ErrorUnexpected;
3947 : 0 : case ZigClangStmt_OMPParallelDirectiveClass:
3948 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPParallelDirectiveClass");
3949 : 0 : return ErrorUnexpected;
3950 : 0 : case ZigClangStmt_OMPParallelSectionsDirectiveClass:
3951 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPParallelSectionsDirectiveClass");
3952 : 0 : return ErrorUnexpected;
3953 : 0 : case ZigClangStmt_OMPSectionDirectiveClass:
3954 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPSectionDirectiveClass");
3955 : 0 : return ErrorUnexpected;
3956 : 0 : case ZigClangStmt_OMPSectionsDirectiveClass:
3957 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPSectionsDirectiveClass");
3958 : 0 : return ErrorUnexpected;
3959 : 0 : case ZigClangStmt_OMPSingleDirectiveClass:
3960 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPSingleDirectiveClass");
3961 : 0 : return ErrorUnexpected;
3962 : 0 : case ZigClangStmt_OMPTargetDataDirectiveClass:
3963 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetDataDirectiveClass");
3964 : 0 : return ErrorUnexpected;
3965 : 0 : case ZigClangStmt_OMPTargetDirectiveClass:
3966 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetDirectiveClass");
3967 : 0 : return ErrorUnexpected;
3968 : 0 : case ZigClangStmt_OMPTargetEnterDataDirectiveClass:
3969 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetEnterDataDirectiveClass");
3970 : 0 : return ErrorUnexpected;
3971 : 0 : case ZigClangStmt_OMPTargetExitDataDirectiveClass:
3972 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetExitDataDirectiveClass");
3973 : 0 : return ErrorUnexpected;
3974 : 0 : case ZigClangStmt_OMPTargetParallelDirectiveClass:
3975 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetParallelDirectiveClass");
3976 : 0 : return ErrorUnexpected;
3977 : 0 : case ZigClangStmt_OMPTargetParallelForDirectiveClass:
3978 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetParallelForDirectiveClass");
3979 : 0 : return ErrorUnexpected;
3980 : 0 : case ZigClangStmt_OMPTargetTeamsDirectiveClass:
3981 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetTeamsDirectiveClass");
3982 : 0 : return ErrorUnexpected;
3983 : 0 : case ZigClangStmt_OMPTargetUpdateDirectiveClass:
3984 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetUpdateDirectiveClass");
3985 : 0 : return ErrorUnexpected;
3986 : 0 : case ZigClangStmt_OMPTaskDirectiveClass:
3987 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTaskDirectiveClass");
3988 : 0 : return ErrorUnexpected;
3989 : 0 : case ZigClangStmt_OMPTaskgroupDirectiveClass:
3990 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTaskgroupDirectiveClass");
3991 : 0 : return ErrorUnexpected;
3992 : 0 : case ZigClangStmt_OMPTaskwaitDirectiveClass:
3993 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTaskwaitDirectiveClass");
3994 : 0 : return ErrorUnexpected;
3995 : 0 : case ZigClangStmt_OMPTaskyieldDirectiveClass:
3996 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTaskyieldDirectiveClass");
3997 : 0 : return ErrorUnexpected;
3998 : 0 : case ZigClangStmt_OMPTeamsDirectiveClass:
3999 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTeamsDirectiveClass");
4000 : 0 : return ErrorUnexpected;
4001 : 0 : case ZigClangStmt_ObjCAtCatchStmtClass:
4002 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAtCatchStmtClass");
4003 : 0 : return ErrorUnexpected;
4004 : 0 : case ZigClangStmt_ObjCAtFinallyStmtClass:
4005 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAtFinallyStmtClass");
4006 : 0 : return ErrorUnexpected;
4007 : 0 : case ZigClangStmt_ObjCAtSynchronizedStmtClass:
4008 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAtSynchronizedStmtClass");
4009 : 0 : return ErrorUnexpected;
4010 : 0 : case ZigClangStmt_ObjCAtThrowStmtClass:
4011 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAtThrowStmtClass");
4012 : 0 : return ErrorUnexpected;
4013 : 0 : case ZigClangStmt_ObjCAtTryStmtClass:
4014 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAtTryStmtClass");
4015 : 0 : return ErrorUnexpected;
4016 : 0 : case ZigClangStmt_ObjCAutoreleasePoolStmtClass:
4017 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAutoreleasePoolStmtClass");
4018 : 0 : return ErrorUnexpected;
4019 : 0 : case ZigClangStmt_ObjCForCollectionStmtClass:
4020 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCForCollectionStmtClass");
4021 : 0 : return ErrorUnexpected;
4022 : 0 : case ZigClangStmt_SEHExceptStmtClass:
4023 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SEHExceptStmtClass");
4024 : 0 : return ErrorUnexpected;
4025 : 0 : case ZigClangStmt_SEHFinallyStmtClass:
4026 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SEHFinallyStmtClass");
4027 : 0 : return ErrorUnexpected;
4028 : 0 : case ZigClangStmt_SEHLeaveStmtClass:
4029 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SEHLeaveStmtClass");
4030 : 0 : return ErrorUnexpected;
4031 : 0 : case ZigClangStmt_SEHTryStmtClass:
4032 : 0 : emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SEHTryStmtClass");
4033 : 0 : return ErrorUnexpected;
4034 : : }
4035 : 0 : zig_unreachable();
4036 : : }
4037 : :
4038 : : // Returns null if there was an error
4039 : 0 : static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const ZigClangExpr *expr,
4040 : : TransLRValue lrval)
4041 : : {
4042 : : AstNode *result_node;
4043 : : TransScope *result_scope;
4044 [ # # ]: 0 : if (trans_stmt_extra(c, scope, (const ZigClangStmt *)expr, result_used, lrval, &result_node, &result_scope, nullptr)) {
4045 : 0 : return nullptr;
4046 : : }
4047 : 0 : return result_node;
4048 : : }
4049 : :
4050 : : // Statements have no result and no concept of L or R value.
4051 : : // Returns child scope, or null if there was an error
4052 : 0 : static TransScope *trans_stmt(Context *c, TransScope *scope, const ZigClangStmt *stmt, AstNode **out_node) {
4053 : : TransScope *child_scope;
4054 [ # # ]: 0 : if (trans_stmt_extra(c, scope, stmt, ResultUsedNo, TransRValue, out_node, &child_scope, nullptr)) {
4055 : 0 : return nullptr;
4056 : : }
4057 : 0 : return child_scope;
4058 : : }
4059 : :
4060 : 0 : static void visit_fn_decl(Context *c, const ZigClangFunctionDecl *fn_decl) {
4061 : 0 : Buf *fn_name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)fn_decl));
4062 : :
4063 [ # # ]: 0 : if (get_global(c, fn_name)) {
4064 : : // we already saw this function
4065 : 0 : return;
4066 : : }
4067 : :
4068 : 0 : AstNode *proto_node = trans_qual_type(c, ZigClangFunctionDecl_getType(fn_decl),
4069 : 0 : ZigClangFunctionDecl_getLocation(fn_decl));
4070 [ # # ]: 0 : if (proto_node == nullptr) {
4071 : 0 : emit_warning(c, ZigClangFunctionDecl_getLocation(fn_decl),
4072 : : "unable to resolve prototype of function '%s'", buf_ptr(fn_name));
4073 : 0 : return;
4074 : : }
4075 : :
4076 : 0 : proto_node->data.fn_proto.name = fn_name;
4077 : 0 : proto_node->data.fn_proto.is_extern = !ZigClangFunctionDecl_hasBody(fn_decl);
4078 : :
4079 : 0 : ZigClangStorageClass sc = ZigClangFunctionDecl_getStorageClass(fn_decl);
4080 [ # # ]: 0 : if (sc == ZigClangStorageClass_None) {
4081 : 0 : proto_node->data.fn_proto.visib_mod = c->visib_mod;
4082 [ # # ]: 0 : proto_node->data.fn_proto.is_export = ZigClangFunctionDecl_hasBody(fn_decl) ? c->want_export : false;
4083 [ # # ][ # # ]: 0 : } else if (sc == ZigClangStorageClass_Extern || sc == ZigClangStorageClass_Static) {
4084 : 0 : proto_node->data.fn_proto.visib_mod = c->visib_mod;
4085 [ # # ]: 0 : } else if (sc == ZigClangStorageClass_PrivateExtern) {
4086 : 0 : emit_warning(c, ZigClangFunctionDecl_getLocation(fn_decl), "unsupported storage class: private extern");
4087 : 0 : return;
4088 : : } else {
4089 : 0 : emit_warning(c, ZigClangFunctionDecl_getLocation(fn_decl), "unsupported storage class: unknown");
4090 : 0 : return;
4091 : : }
4092 : :
4093 : 0 : TransScope *scope = &c->global_scope->base;
4094 : :
4095 [ # # ]: 0 : for (size_t i = 0; i < proto_node->data.fn_proto.params.length; i += 1) {
4096 : 0 : AstNode *param_node = proto_node->data.fn_proto.params.at(i);
4097 : 0 : const ZigClangParmVarDecl *param = ZigClangFunctionDecl_getParamDecl(fn_decl, i);
4098 : 0 : const char *name = ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)param);
4099 : :
4100 : : Buf *proto_param_name;
4101 [ # # ]: 0 : if (strlen(name) != 0) {
4102 : 0 : proto_param_name = buf_create_from_str(name);
4103 : : } else {
4104 : 0 : proto_param_name = param_node->data.param_decl.name;
4105 [ # # ]: 0 : if (proto_param_name == nullptr) {
4106 : 0 : proto_param_name = buf_sprintf("arg%" ZIG_PRI_usize "", i);
4107 : : }
4108 : : }
4109 : :
4110 : 0 : TransScopeVar *scope_var = trans_scope_var_create(c, scope, proto_param_name);
4111 : 0 : scope = &scope_var->base;
4112 : :
4113 : 0 : param_node->data.param_decl.name = scope_var->zig_name;
4114 : : }
4115 : :
4116 [ # # ]: 0 : if (!ZigClangFunctionDecl_hasBody(fn_decl)) {
4117 : : // just a prototype
4118 : 0 : add_top_level_decl(c, proto_node->data.fn_proto.name, proto_node);
4119 : 0 : return;
4120 : : }
4121 : :
4122 : : // actual function definition with body
4123 : 0 : c->ptr_params.clear();
4124 : 0 : const ZigClangStmt *body = ZigClangFunctionDecl_getBody(fn_decl);
4125 : : AstNode *actual_body_node;
4126 : 0 : TransScope *result_scope = trans_stmt(c, scope, body, &actual_body_node);
4127 [ # # ]: 0 : if (result_scope == nullptr) {
4128 : 0 : emit_warning(c, ZigClangFunctionDecl_getLocation(fn_decl), "unable to translate function");
4129 : 0 : return;
4130 : : }
4131 [ # # ]: 0 : assert(actual_body_node != nullptr);
4132 [ # # ]: 0 : assert(actual_body_node->type == NodeTypeBlock);
4133 : :
4134 : : // it worked
4135 : :
4136 : 0 : AstNode *body_node_with_param_inits = trans_create_node(c, NodeTypeBlock);
4137 : :
4138 [ # # ]: 0 : for (size_t i = 0; i < proto_node->data.fn_proto.params.length; i += 1) {
4139 : 0 : AstNode *param_node = proto_node->data.fn_proto.params.at(i);
4140 : 0 : Buf *good_name = param_node->data.param_decl.name;
4141 : :
4142 [ # # ]: 0 : if (c->ptr_params.maybe_get(good_name) != nullptr) {
4143 : : // TODO: avoid name collisions
4144 : 0 : Buf *mangled_name = buf_sprintf("_arg_%s", buf_ptr(good_name));
4145 : 0 : param_node->data.param_decl.name = mangled_name;
4146 : :
4147 : : // var c_name = _mangled_name;
4148 : 0 : AstNode *parameter_init = trans_create_node_var_decl_local(c, false, good_name, nullptr, trans_create_node_symbol(c, mangled_name));
4149 : :
4150 : 0 : body_node_with_param_inits->data.block.statements.append(parameter_init);
4151 : : }
4152 : : }
4153 : :
4154 [ # # ]: 0 : for (size_t i = 0; i < actual_body_node->data.block.statements.length; i += 1) {
4155 : 0 : body_node_with_param_inits->data.block.statements.append(actual_body_node->data.block.statements.at(i));
4156 : : }
4157 : :
4158 : 0 : AstNode *fn_def_node = trans_create_node(c, NodeTypeFnDef);
4159 : 0 : fn_def_node->data.fn_def.fn_proto = proto_node;
4160 : 0 : fn_def_node->data.fn_def.body = body_node_with_param_inits;
4161 : :
4162 : 0 : proto_node->data.fn_proto.fn_def_node = fn_def_node;
4163 : 0 : add_top_level_decl(c, fn_def_node->data.fn_def.fn_proto->data.fn_proto.name, fn_def_node);
4164 : : }
4165 : :
4166 : 0 : static AstNode *resolve_typdef_as_builtin(Context *c, const ZigClangTypedefNameDecl *typedef_decl, const char *primitive_name) {
4167 : 0 : AstNode *node = trans_create_node_symbol_str(c, primitive_name);
4168 : 0 : c->decl_table.put(typedef_decl, node);
4169 : 0 : return node;
4170 : : }
4171 : :
4172 : 0 : static AstNode *resolve_typedef_decl(Context *c, const ZigClangTypedefNameDecl *typedef_decl) {
4173 : 0 : auto existing_entry = c->decl_table.maybe_get((void*)ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl));
4174 [ # # ]: 0 : if (existing_entry) {
4175 : 0 : return existing_entry->value;
4176 : : }
4177 : :
4178 : 0 : ZigClangQualType child_qt = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);
4179 : 0 : Buf *type_name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)typedef_decl));
4180 : :
4181 [ # # ]: 0 : if (buf_eql_str(type_name, "uint8_t")) {
4182 : 0 : return resolve_typdef_as_builtin(c, typedef_decl, "u8");
4183 [ # # ]: 0 : } else if (buf_eql_str(type_name, "int8_t")) {
4184 : 0 : return resolve_typdef_as_builtin(c, typedef_decl, "i8");
4185 [ # # ]: 0 : } else if (buf_eql_str(type_name, "uint16_t")) {
4186 : 0 : return resolve_typdef_as_builtin(c, typedef_decl, "u16");
4187 [ # # ]: 0 : } else if (buf_eql_str(type_name, "int16_t")) {
4188 : 0 : return resolve_typdef_as_builtin(c, typedef_decl, "i16");
4189 [ # # ]: 0 : } else if (buf_eql_str(type_name, "uint32_t")) {
4190 : 0 : return resolve_typdef_as_builtin(c, typedef_decl, "u32");
4191 [ # # ]: 0 : } else if (buf_eql_str(type_name, "int32_t")) {
4192 : 0 : return resolve_typdef_as_builtin(c, typedef_decl, "i32");
4193 [ # # ]: 0 : } else if (buf_eql_str(type_name, "uint64_t")) {
4194 : 0 : return resolve_typdef_as_builtin(c, typedef_decl, "u64");
4195 [ # # ]: 0 : } else if (buf_eql_str(type_name, "int64_t")) {
4196 : 0 : return resolve_typdef_as_builtin(c, typedef_decl, "i64");
4197 [ # # ]: 0 : } else if (buf_eql_str(type_name, "intptr_t")) {
4198 : 0 : return resolve_typdef_as_builtin(c, typedef_decl, "isize");
4199 [ # # ]: 0 : } else if (buf_eql_str(type_name, "uintptr_t")) {
4200 : 0 : return resolve_typdef_as_builtin(c, typedef_decl, "usize");
4201 [ # # ]: 0 : } else if (buf_eql_str(type_name, "ssize_t")) {
4202 : 0 : return resolve_typdef_as_builtin(c, typedef_decl, "isize");
4203 [ # # ]: 0 : } else if (buf_eql_str(type_name, "size_t")) {
4204 : 0 : return resolve_typdef_as_builtin(c, typedef_decl, "usize");
4205 : : }
4206 : :
4207 : : // if the underlying type is anonymous, we can special case it to just
4208 : : // use the name of this typedef
4209 : : // TODO
4210 : :
4211 : : // trans_qual_type here might cause us to look at this typedef again so we put the item in the map first
4212 : 0 : AstNode *symbol_node = trans_create_node_symbol(c, type_name);
4213 : 0 : c->decl_table.put(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl), symbol_node);
4214 : :
4215 : 0 : AstNode *type_node = trans_qual_type(c, child_qt, ZigClangTypedefNameDecl_getLocation(typedef_decl));
4216 [ # # ]: 0 : if (type_node == nullptr) {
4217 : 0 : emit_warning(c, ZigClangTypedefNameDecl_getLocation(typedef_decl),
4218 : : "typedef %s - unresolved child type", buf_ptr(type_name));
4219 : 0 : c->decl_table.put(typedef_decl, nullptr);
4220 : : // TODO add global var with type_name equal to @compileError("unable to resolve C type")
4221 : 0 : return nullptr;
4222 : : }
4223 : 0 : add_global_var(c, type_name, type_node);
4224 : :
4225 : 0 : return symbol_node;
4226 : : }
4227 : :
4228 : 0 : struct AstNode *demote_enum_to_opaque(Context *c, const ZigClangEnumDecl *enum_decl, Buf *full_type_name,
4229 : : Buf *bare_name)
4230 : : {
4231 : 0 : AstNode *opaque_node = trans_create_node_opaque(c);
4232 [ # # ]: 0 : if (full_type_name == nullptr) {
4233 : 0 : c->decl_table.put(ZigClangEnumDecl_getCanonicalDecl(enum_decl), opaque_node);
4234 : 0 : return opaque_node;
4235 : : }
4236 : 0 : AstNode *symbol_node = trans_create_node_symbol(c, full_type_name);
4237 : 0 : add_global_weak_alias(c, bare_name, full_type_name);
4238 : 0 : add_global_var(c, full_type_name, opaque_node);
4239 : 0 : c->decl_table.put(ZigClangEnumDecl_getCanonicalDecl(enum_decl), symbol_node);
4240 : 0 : return symbol_node;
4241 : : }
4242 : :
4243 : 0 : static AstNode *resolve_enum_decl(Context *c, const ZigClangEnumDecl *enum_decl) {
4244 : 0 : auto existing_entry = c->decl_table.maybe_get(ZigClangEnumDecl_getCanonicalDecl(enum_decl));
4245 [ # # ]: 0 : if (existing_entry) {
4246 : 0 : return existing_entry->value;
4247 : : }
4248 : :
4249 : 0 : const char *raw_name = ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)enum_decl);
4250 : 0 : bool is_anonymous = (raw_name[0] == 0);
4251 [ # # ]: 0 : Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name);
4252 [ # # ]: 0 : Buf *full_type_name = is_anonymous ? nullptr : buf_sprintf("enum_%s", buf_ptr(bare_name));
4253 : :
4254 : 0 : const ZigClangEnumDecl *enum_def = ZigClangEnumDecl_getDefinition(enum_decl);
4255 [ # # ]: 0 : if (!enum_def) {
4256 : 0 : return demote_enum_to_opaque(c, enum_decl, full_type_name, bare_name);
4257 : : }
4258 : :
4259 : :
4260 : 0 : bool pure_enum = true;
4261 : 0 : uint32_t field_count = 0;
4262 : 0 : for (auto it = reinterpret_cast<const clang::EnumDecl *>(enum_def)->enumerator_begin(),
4263 : 0 : it_end = reinterpret_cast<const clang::EnumDecl *>(enum_def)->enumerator_end();
4264 [ # # ]: 0 : it != it_end; ++it, field_count += 1)
4265 : : {
4266 : 0 : const clang::EnumConstantDecl *enum_const = *it;
4267 [ # # ]: 0 : if (enum_const->getInitExpr()) {
4268 : 0 : pure_enum = false;
4269 : : }
4270 : : }
4271 : 0 : AstNode *tag_int_type = trans_qual_type(c, ZigClangEnumDecl_getIntegerType(enum_decl),
4272 : 0 : ZigClangEnumDecl_getLocation(enum_decl));
4273 [ # # ]: 0 : assert(tag_int_type);
4274 : :
4275 : 0 : AstNode *enum_node = trans_create_node(c, NodeTypeContainerDecl);
4276 : 0 : enum_node->data.container_decl.kind = ContainerKindEnum;
4277 : 0 : enum_node->data.container_decl.layout = ContainerLayoutExtern;
4278 : : // TODO only emit this tag type if the enum tag type is not the default.
4279 : : // I don't know what the default is, need to figure out how clang is deciding.
4280 : : // it appears to at least be different across gcc/msvc
4281 [ # # ]: 0 : if (!c_is_builtin_type(c, ZigClangEnumDecl_getIntegerType(enum_decl), ZigClangBuiltinTypeUInt) &&
[ # # # # ]
4282 : 0 : !c_is_builtin_type(c, ZigClangEnumDecl_getIntegerType(enum_decl), ZigClangBuiltinTypeInt))
4283 : : {
4284 : 0 : enum_node->data.container_decl.init_arg_expr = tag_int_type;
4285 : : }
4286 : 0 : enum_node->data.container_decl.fields.resize(field_count);
4287 : 0 : uint32_t i = 0;
4288 : 0 : for (auto it = reinterpret_cast<const clang::EnumDecl *>(enum_def)->enumerator_begin(),
4289 : 0 : it_end = reinterpret_cast<const clang::EnumDecl *>(enum_def)->enumerator_end();
4290 [ # # ]: 0 : it != it_end; ++it, i += 1)
4291 : : {
4292 : 0 : const clang::EnumConstantDecl *enum_const = *it;
4293 : :
4294 : 0 : Buf *enum_val_name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)enum_const));
4295 : : Buf *field_name;
4296 [ # # ][ # # ]: 0 : if (bare_name != nullptr && buf_starts_with_buf(enum_val_name, bare_name)) {
[ # # ]
4297 : 0 : field_name = buf_slice(enum_val_name, buf_len(bare_name), buf_len(enum_val_name));
4298 : : } else {
4299 : 0 : field_name = enum_val_name;
4300 : : }
4301 : :
4302 [ # # ][ # # ]: 0 : AstNode *int_node = pure_enum && !is_anonymous ?
4303 : 0 : nullptr : trans_create_node_apint(c, bitcast(&enum_const->getInitVal()));
4304 : 0 : AstNode *field_node = trans_create_node(c, NodeTypeStructField);
4305 : 0 : field_node->data.struct_field.name = field_name;
4306 : 0 : field_node->data.struct_field.type = nullptr;
4307 : 0 : field_node->data.struct_field.value = int_node;
4308 : 0 : enum_node->data.container_decl.fields.items[i] = field_node;
4309 : :
4310 : : // in C each enum value is in the global namespace. so we put them there too.
4311 : : // at this point we can rely on the enum emitting successfully
4312 [ # # ]: 0 : if (is_anonymous) {
4313 : 0 : Buf *enum_val_name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)enum_const));
4314 : 0 : add_global_var(c, enum_val_name, int_node);
4315 : : } else {
4316 : 0 : AstNode *field_access_node = trans_create_node_field_access(c,
4317 : 0 : trans_create_node_symbol(c, full_type_name), field_name);
4318 : 0 : add_global_var(c, enum_val_name, field_access_node);
4319 : : }
4320 : : }
4321 : :
4322 [ # # ]: 0 : if (is_anonymous) {
4323 : 0 : c->decl_table.put(ZigClangEnumDecl_getCanonicalDecl(enum_decl), enum_node);
4324 : 0 : return enum_node;
4325 : : } else {
4326 : 0 : AstNode *symbol_node = trans_create_node_symbol(c, full_type_name);
4327 : 0 : add_global_weak_alias(c, bare_name, full_type_name);
4328 : 0 : add_global_var(c, full_type_name, enum_node);
4329 : 0 : c->decl_table.put(ZigClangEnumDecl_getCanonicalDecl(enum_decl), symbol_node);
4330 : 0 : return enum_node;
4331 : : }
4332 : : }
4333 : :
4334 : 0 : static AstNode *demote_struct_to_opaque(Context *c, const ZigClangRecordDecl *record_decl,
4335 : : Buf *full_type_name, Buf *bare_name)
4336 : : {
4337 : 0 : AstNode *opaque_node = trans_create_node_opaque(c);
4338 [ # # ]: 0 : if (full_type_name == nullptr) {
4339 : 0 : c->decl_table.put(ZigClangRecordDecl_getCanonicalDecl(record_decl), opaque_node);
4340 : 0 : return opaque_node;
4341 : : }
4342 : 0 : AstNode *symbol_node = trans_create_node_symbol(c, full_type_name);
4343 : 0 : add_global_weak_alias(c, bare_name, full_type_name);
4344 : 0 : add_global_var(c, full_type_name, opaque_node);
4345 : 0 : c->decl_table.put(ZigClangRecordDecl_getCanonicalDecl(record_decl), symbol_node);
4346 : 0 : return symbol_node;
4347 : : }
4348 : :
4349 : 0 : static AstNode *resolve_record_decl(Context *c, const ZigClangRecordDecl *record_decl) {
4350 : 0 : auto existing_entry = c->decl_table.maybe_get(ZigClangRecordDecl_getCanonicalDecl(record_decl));
4351 [ # # ]: 0 : if (existing_entry) {
4352 : 0 : return existing_entry->value;
4353 : : }
4354 : :
4355 : 0 : const char *raw_name = ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)record_decl);
4356 : : const char *container_kind_name;
4357 : : ContainerKind container_kind;
4358 [ # # ]: 0 : if (ZigClangRecordDecl_isUnion(record_decl)) {
4359 : 0 : container_kind_name = "union";
4360 : 0 : container_kind = ContainerKindUnion;
4361 [ # # ]: 0 : } else if (ZigClangRecordDecl_isStruct(record_decl)) {
4362 : 0 : container_kind_name = "struct";
4363 : 0 : container_kind = ContainerKindStruct;
4364 : : } else {
4365 : 0 : emit_warning(c, ZigClangRecordDecl_getLocation(record_decl),
4366 : : "skipping record %s, not a struct or union", raw_name);
4367 : 0 : c->decl_table.put(ZigClangRecordDecl_getCanonicalDecl(record_decl), nullptr);
4368 : 0 : return nullptr;
4369 : : }
4370 : :
4371 [ # # ][ # # ]: 0 : bool is_anonymous = ZigClangRecordDecl_isAnonymousStructOrUnion(record_decl) || raw_name[0] == 0;
4372 [ # # ]: 0 : Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name);
4373 [ # # ]: 0 : Buf *full_type_name = (bare_name == nullptr) ?
4374 : 0 : nullptr : buf_sprintf("%s_%s", container_kind_name, buf_ptr(bare_name));
4375 : :
4376 : 0 : const ZigClangRecordDecl *record_def = ZigClangRecordDecl_getDefinition(record_decl);
4377 [ # # ]: 0 : if (record_def == nullptr) {
4378 : 0 : return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);
4379 : : }
4380 : :
4381 : : // count fields and validate
4382 : 0 : uint32_t field_count = 0;
4383 : 0 : for (auto it = reinterpret_cast<const clang::RecordDecl *>(record_def)->field_begin(),
4384 : 0 : it_end = reinterpret_cast<const clang::RecordDecl *>(record_def)->field_end();
4385 [ # # ]: 0 : it != it_end; ++it, field_count += 1)
4386 : : {
4387 : 0 : const clang::FieldDecl *field_decl = *it;
4388 : :
4389 [ # # ]: 0 : if (field_decl->isBitField()) {
4390 [ # # ]: 0 : emit_warning(c, bitcast(field_decl->getLocation()), "%s %s demoted to opaque type - has bitfield",
4391 : : container_kind_name,
4392 : : is_anonymous ? "(anon)" : buf_ptr(bare_name));
4393 : 0 : return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);
4394 : : }
4395 : : }
4396 : :
4397 : 0 : AstNode *struct_node = trans_create_node(c, NodeTypeContainerDecl);
4398 : 0 : struct_node->data.container_decl.kind = container_kind;
4399 : 0 : struct_node->data.container_decl.layout = ContainerLayoutExtern;
4400 : :
4401 : : // TODO handle attribute packed
4402 : :
4403 : 0 : struct_node->data.container_decl.fields.resize(field_count);
4404 : :
4405 : : // must be before fields in case a circular reference happens
4406 [ # # ]: 0 : if (is_anonymous) {
4407 : 0 : c->decl_table.put(ZigClangRecordDecl_getCanonicalDecl(record_decl), struct_node);
4408 : : } else {
4409 : 0 : c->decl_table.put(ZigClangRecordDecl_getCanonicalDecl(record_decl), trans_create_node_symbol(c, full_type_name));
4410 : : }
4411 : :
4412 : 0 : uint32_t i = 0;
4413 : 0 : for (auto it = reinterpret_cast<const clang::RecordDecl *>(record_def)->field_begin(),
4414 : 0 : it_end = reinterpret_cast<const clang::RecordDecl *>(record_def)->field_end();
4415 [ # # ]: 0 : it != it_end; ++it, i += 1)
4416 : : {
4417 : 0 : const clang::FieldDecl *field_decl = *it;
4418 : :
4419 : 0 : AstNode *field_node = trans_create_node(c, NodeTypeStructField);
4420 : 0 : field_node->data.struct_field.name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)field_decl));
4421 : 0 : field_node->data.struct_field.type = trans_qual_type(c, bitcast(field_decl->getType()),
4422 : : bitcast(field_decl->getLocation()));
4423 : :
4424 [ # # ]: 0 : if (field_node->data.struct_field.type == nullptr) {
4425 [ # # ]: 0 : emit_warning(c, bitcast(field_decl->getLocation()),
4426 : : "%s %s demoted to opaque type - unresolved type",
4427 : : container_kind_name,
4428 : : is_anonymous ? "(anon)" : buf_ptr(bare_name));
4429 : :
4430 : 0 : return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);
4431 : : }
4432 : :
4433 : 0 : struct_node->data.container_decl.fields.items[i] = field_node;
4434 : : }
4435 : :
4436 [ # # ]: 0 : if (is_anonymous) {
4437 : 0 : return struct_node;
4438 : : } else {
4439 : 0 : add_global_weak_alias(c, bare_name, full_type_name);
4440 : 0 : add_global_var(c, full_type_name, struct_node);
4441 : 0 : return trans_create_node_symbol(c, full_type_name);
4442 : : }
4443 : : }
4444 : :
4445 : 0 : static AstNode *trans_ap_value(Context *c, const ZigClangAPValue *ap_value, ZigClangQualType qt,
4446 : : ZigClangSourceLocation source_loc)
4447 : : {
4448 [ # # # # : 0 : switch (ZigClangAPValue_getKind(ap_value)) {
# # # # #
# # # # ]
4449 : 0 : case ZigClangAPValueInt:
4450 : 0 : return trans_create_node_apint(c, ZigClangAPValue_getInt(ap_value));
4451 : 0 : case ZigClangAPValueUninitialized:
4452 : 0 : return trans_create_node(c, NodeTypeUndefinedLiteral);
4453 : 0 : case ZigClangAPValueArray: {
4454 : 0 : emit_warning(c, source_loc, "TODO add a test case for this code");
4455 : :
4456 : 0 : unsigned init_count = ZigClangAPValue_getArrayInitializedElts(ap_value);
4457 : 0 : unsigned all_count = ZigClangAPValue_getArraySize(ap_value);
4458 : 0 : unsigned leftover_count = all_count - init_count;
4459 : 0 : AstNode *init_node = trans_create_node(c, NodeTypeContainerInitExpr);
4460 : 0 : AstNode *arr_type_node = trans_qual_type(c, qt, source_loc);
4461 [ # # ]: 0 : if (leftover_count != 0) { // We can't use the size of the final array for a partial initializer.
4462 : 0 : bigint_init_unsigned(arr_type_node->data.array_type.size->data.int_literal.bigint, init_count);
4463 : : }
4464 : 0 : init_node->data.container_init_expr.type = arr_type_node;
4465 : 0 : init_node->data.container_init_expr.kind = ContainerInitKindArray;
4466 : :
4467 : 0 : const clang::Type *qt_type = reinterpret_cast<const clang::Type *>(ZigClangQualType_getTypePtr(qt));
4468 : 0 : ZigClangQualType child_qt = bitcast(qt_type->getAsArrayTypeUnsafe()->getElementType());
4469 : :
4470 [ # # ]: 0 : for (size_t i = 0; i < init_count; i += 1) {
4471 : 0 : const ZigClangAPValue *elem_ap_val = ZigClangAPValue_getArrayInitializedElt(ap_value, i);
4472 : 0 : AstNode *elem_node = trans_ap_value(c, elem_ap_val, child_qt, source_loc);
4473 [ # # ]: 0 : if (elem_node == nullptr)
4474 : 0 : return nullptr;
4475 : 0 : init_node->data.container_init_expr.entries.append(elem_node);
4476 : : }
4477 [ # # ]: 0 : if (leftover_count == 0) {
4478 : 0 : return init_node;
4479 : : }
4480 : :
4481 : 0 : const ZigClangAPValue *filler_ap_val = ZigClangAPValue_getArrayFiller(ap_value);
4482 : 0 : AstNode *filler_node = trans_ap_value(c, filler_ap_val, child_qt, source_loc);
4483 [ # # ]: 0 : if (filler_node == nullptr)
4484 : 0 : return nullptr;
4485 : :
4486 : 0 : AstNode* filler_arr_type = trans_create_node(c, NodeTypeArrayType);
4487 : 0 : *filler_arr_type = *arr_type_node;
4488 : 0 : filler_arr_type->data.array_type.size = trans_create_node_unsigned(c, 1);
4489 : :
4490 : 0 : AstNode *filler_arr_1 = trans_create_node(c, NodeTypeContainerInitExpr);
4491 : 0 : filler_arr_1->data.container_init_expr.type = filler_arr_type;
4492 : 0 : filler_arr_1->data.container_init_expr.kind = ContainerInitKindArray;
4493 : 0 : filler_arr_1->data.container_init_expr.entries.append(filler_node);
4494 : :
4495 : : AstNode *rhs_node;
4496 [ # # ]: 0 : if (leftover_count == 1) {
4497 : 0 : rhs_node = filler_arr_1;
4498 : : } else {
4499 : 0 : AstNode *amt_node = trans_create_node_unsigned(c, leftover_count);
4500 : 0 : rhs_node = trans_create_node_bin_op(c, filler_arr_1, BinOpTypeArrayMult, amt_node);
4501 : : }
4502 : :
4503 [ # # ]: 0 : if (init_count == 0) {
4504 : 0 : return rhs_node;
4505 : : }
4506 : :
4507 : 0 : return trans_create_node_bin_op(c, init_node, BinOpTypeArrayCat, rhs_node);
4508 : : }
4509 : 0 : case ZigClangAPValueLValue: {
4510 : 0 : const ZigClangAPValueLValueBase lval_base = ZigClangAPValue_getLValueBase(ap_value);
4511 [ # # ]: 0 : if (const ZigClangExpr *expr = ZigClangAPValueLValueBase_dyn_cast_Expr(lval_base)) {
4512 : 0 : return trans_expr(c, ResultUsedYes, &c->global_scope->base, expr, TransRValue);
4513 : : }
4514 : : //const clang::ValueDecl *value_decl = lval_base.get<const clang::ValueDecl *>();
4515 : 0 : emit_warning(c, source_loc, "TODO handle initializer LValue clang::ValueDecl");
4516 : 0 : return nullptr;
4517 : : }
4518 : 0 : case ZigClangAPValueFloat:
4519 : 0 : emit_warning(c, source_loc, "unsupported initializer value kind: Float");
4520 : 0 : return nullptr;
4521 : 0 : case ZigClangAPValueComplexInt:
4522 : 0 : emit_warning(c, source_loc, "unsupported initializer value kind: ComplexInt");
4523 : 0 : return nullptr;
4524 : 0 : case ZigClangAPValueComplexFloat:
4525 : 0 : emit_warning(c, source_loc, "unsupported initializer value kind: ComplexFloat");
4526 : 0 : return nullptr;
4527 : 0 : case ZigClangAPValueVector:
4528 : 0 : emit_warning(c, source_loc, "unsupported initializer value kind: Vector");
4529 : 0 : return nullptr;
4530 : 0 : case ZigClangAPValueStruct:
4531 : 0 : emit_warning(c, source_loc, "unsupported initializer value kind: Struct");
4532 : 0 : return nullptr;
4533 : 0 : case ZigClangAPValueUnion:
4534 : 0 : emit_warning(c, source_loc, "unsupported initializer value kind: Union");
4535 : 0 : return nullptr;
4536 : 0 : case ZigClangAPValueMemberPointer:
4537 : 0 : emit_warning(c, source_loc, "unsupported initializer value kind: MemberPointer");
4538 : 0 : return nullptr;
4539 : 0 : case ZigClangAPValueAddrLabelDiff:
4540 : 0 : emit_warning(c, source_loc, "unsupported initializer value kind: AddrLabelDiff");
4541 : 0 : return nullptr;
4542 : : }
4543 : 0 : zig_unreachable();
4544 : : }
4545 : :
4546 : 0 : static void visit_var_decl(Context *c, const clang::VarDecl *var_decl) {
4547 : 0 : Buf *name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)var_decl));
4548 : :
4549 [ # # # # ]: 0 : switch (var_decl->getTLSKind()) {
4550 : 0 : case clang::VarDecl::TLS_None:
4551 : 0 : break;
4552 : 0 : case clang::VarDecl::TLS_Static:
4553 : 0 : emit_warning(c, bitcast(var_decl->getLocation()),
4554 : : "ignoring variable '%s' - static thread local storage", buf_ptr(name));
4555 : 0 : return;
4556 : 0 : case clang::VarDecl::TLS_Dynamic:
4557 : 0 : emit_warning(c, bitcast(var_decl->getLocation()),
4558 : : "ignoring variable '%s' - dynamic thread local storage", buf_ptr(name));
4559 : 0 : return;
4560 : : }
4561 : :
4562 : 0 : ZigClangQualType qt = bitcast(var_decl->getType());
4563 : 0 : AstNode *var_type = trans_qual_type(c, qt, bitcast(var_decl->getLocation()));
4564 [ # # ]: 0 : if (var_type == nullptr) {
4565 : 0 : emit_warning(c, bitcast(var_decl->getLocation()), "ignoring variable '%s' - unresolved type", buf_ptr(name));
4566 : 0 : return;
4567 : : }
4568 : :
4569 : 0 : bool is_extern = var_decl->hasExternalStorage();
4570 : 0 : bool is_static = var_decl->isFileVarDecl();
4571 : 0 : bool is_const = ZigClangQualType_isConstQualified(qt);
4572 : :
4573 [ # # ][ # # ]: 0 : if (is_static && !is_extern) {
4574 : : AstNode *init_node;
4575 [ # # ]: 0 : if (var_decl->hasInit()) {
4576 : 0 : const ZigClangAPValue *ap_value = bitcast(var_decl->evaluateValue());
4577 [ # # ]: 0 : if (ap_value == nullptr) {
4578 : 0 : emit_warning(c, bitcast(var_decl->getLocation()),
4579 : : "ignoring variable '%s' - unable to evaluate initializer", buf_ptr(name));
4580 : 0 : return;
4581 : : }
4582 : 0 : init_node = trans_ap_value(c, ap_value, qt, bitcast(var_decl->getLocation()));
4583 [ # # ]: 0 : if (init_node == nullptr)
4584 : 0 : return;
4585 : : } else {
4586 : 0 : init_node = trans_create_node(c, NodeTypeUndefinedLiteral);
4587 : : }
4588 : :
4589 : 0 : AstNode *var_node = trans_create_node_var_decl_global(c, is_const, name, var_type, init_node);
4590 : 0 : add_top_level_decl(c, name, var_node);
4591 : 0 : return;
4592 : : }
4593 : :
4594 [ # # ]: 0 : if (is_extern) {
4595 : 0 : AstNode *var_node = trans_create_node_var_decl_global(c, is_const, name, var_type, nullptr);
4596 : 0 : var_node->data.variable_declaration.is_extern = true;
4597 : 0 : add_top_level_decl(c, name, var_node);
4598 : 0 : return;
4599 : : }
4600 : :
4601 : 0 : emit_warning(c, bitcast(var_decl->getLocation()),
4602 : : "ignoring variable '%s' - non-extern, non-static variable", buf_ptr(name));
4603 : 0 : return;
4604 : : }
4605 : :
4606 : 0 : static bool decl_visitor(void *context, const ZigClangDecl *decl) {
4607 : 0 : Context *c = (Context*)context;
4608 : :
4609 [ # # # # : 0 : switch (ZigClangDecl_getKind(decl)) {
# # ]
4610 : 0 : case ZigClangDeclFunction:
4611 : 0 : visit_fn_decl(c, reinterpret_cast<const ZigClangFunctionDecl*>(decl));
4612 : 0 : break;
4613 : 0 : case ZigClangDeclTypedef:
4614 : 0 : resolve_typedef_decl(c, reinterpret_cast<const ZigClangTypedefNameDecl *>(decl));
4615 : 0 : break;
4616 : 0 : case ZigClangDeclEnum:
4617 : 0 : resolve_enum_decl(c, reinterpret_cast<const ZigClangEnumDecl *>(decl));
4618 : 0 : break;
4619 : 0 : case ZigClangDeclRecord:
4620 : 0 : resolve_record_decl(c, reinterpret_cast<const ZigClangRecordDecl *>(decl));
4621 : 0 : break;
4622 : 0 : case ZigClangDeclVar:
4623 : 0 : visit_var_decl(c, reinterpret_cast<const clang::VarDecl *>(decl));
4624 : 0 : break;
4625 : 0 : default:
4626 : 0 : emit_warning(c, ZigClangDecl_getLocation(decl), "ignoring %s decl", ZigClangDecl_getDeclKindName(decl));
4627 : : }
4628 : :
4629 : 0 : return true;
4630 : : }
4631 : :
4632 : 0 : static bool name_exists_global(Context *c, Buf *name) {
4633 : 0 : return get_global(c, name) != nullptr;
4634 : : }
4635 : :
4636 : 0 : static bool name_exists_scope(Context *c, Buf *name, TransScope *scope) {
4637 [ # # ]: 0 : while (scope != nullptr) {
4638 [ # # ]: 0 : if (scope->id == TransScopeIdVar) {
4639 : 0 : TransScopeVar *var_scope = (TransScopeVar *)scope;
4640 [ # # ]: 0 : if (buf_eql_buf(name, var_scope->zig_name)) {
4641 : 0 : return true;
4642 : : }
4643 : : }
4644 : 0 : scope = scope->parent;
4645 : : }
4646 : 0 : return name_exists_global(c, name);
4647 : : }
4648 : :
4649 : 0 : static Buf *get_unique_name(Context *c, Buf *name, TransScope *scope) {
4650 : 0 : Buf *proposed_name = name;
4651 : 0 : int count = 0;
4652 [ # # ]: 0 : while (name_exists_scope(c, proposed_name, scope)) {
4653 [ # # ]: 0 : if (proposed_name == name) {
4654 : 0 : proposed_name = buf_alloc();
4655 : : }
4656 : 0 : buf_resize(proposed_name, 0);
4657 : 0 : buf_appendf(proposed_name, "%s_%d", buf_ptr(name), count);
4658 : 0 : count += 1;
4659 : : }
4660 : 0 : return proposed_name;
4661 : : }
4662 : :
4663 : 0 : static TransScopeRoot *trans_scope_root_create(Context *c) {
4664 : 0 : TransScopeRoot *result = allocate<TransScopeRoot>(1);
4665 : 0 : result->base.id = TransScopeIdRoot;
4666 : 0 : return result;
4667 : : }
4668 : :
4669 : 0 : static TransScopeWhile *trans_scope_while_create(Context *c, TransScope *parent_scope) {
4670 : 0 : TransScopeWhile *result = allocate<TransScopeWhile>(1);
4671 : 0 : result->base.id = TransScopeIdWhile;
4672 : 0 : result->base.parent = parent_scope;
4673 : 0 : result->node = trans_create_node(c, NodeTypeWhileExpr);
4674 : 0 : return result;
4675 : : }
4676 : :
4677 : 0 : static TransScopeBlock *trans_scope_block_create(Context *c, TransScope *parent_scope) {
4678 : 0 : TransScopeBlock *result = allocate<TransScopeBlock>(1);
4679 : 0 : result->base.id = TransScopeIdBlock;
4680 : 0 : result->base.parent = parent_scope;
4681 : 0 : result->node = trans_create_node(c, NodeTypeBlock);
4682 : 0 : return result;
4683 : : }
4684 : :
4685 : 0 : static TransScopeVar *trans_scope_var_create(Context *c, TransScope *parent_scope, Buf *wanted_name) {
4686 : 0 : TransScopeVar *result = allocate<TransScopeVar>(1);
4687 : 0 : result->base.id = TransScopeIdVar;
4688 : 0 : result->base.parent = parent_scope;
4689 : 0 : result->c_name = wanted_name;
4690 : 0 : result->zig_name = get_unique_name(c, wanted_name, parent_scope);
4691 : 0 : return result;
4692 : : }
4693 : :
4694 : 0 : static TransScopeSwitch *trans_scope_switch_create(Context *c, TransScope *parent_scope) {
4695 : 0 : TransScopeSwitch *result = allocate<TransScopeSwitch>(1);
4696 : 0 : result->base.id = TransScopeIdSwitch;
4697 : 0 : result->base.parent = parent_scope;
4698 : 0 : result->switch_node = trans_create_node(c, NodeTypeSwitchExpr);
4699 : 0 : return result;
4700 : : }
4701 : :
4702 : 0 : static TransScopeBlock *trans_scope_block_find(TransScope *scope) {
4703 [ # # ]: 0 : while (scope != nullptr) {
4704 [ # # ]: 0 : if (scope->id == TransScopeIdBlock) {
4705 : 0 : return (TransScopeBlock *)scope;
4706 : : }
4707 : 0 : scope = scope->parent;
4708 : : }
4709 : 0 : return nullptr;
4710 : : }
4711 : :
4712 : 0 : static void render_aliases(Context *c) {
4713 [ # # ]: 0 : for (size_t i = 0; i < c->aliases.length; i += 1) {
4714 : 0 : Alias *alias = &c->aliases.at(i);
4715 [ # # ]: 0 : if (name_exists_global(c, alias->new_name))
4716 : 0 : continue;
4717 : :
4718 : 0 : add_global_var(c, alias->new_name, trans_create_node_symbol(c, alias->canon_name));
4719 : : }
4720 : 0 : }
4721 : :
4722 : : static AstNode *trans_lookup_ast_container_typeof(Context *c, AstNode *ref_node);
4723 : :
4724 : 0 : static AstNode *trans_lookup_ast_container(Context *c, AstNode *type_node) {
4725 [ # # ]: 0 : if (type_node == nullptr) {
4726 : 0 : return nullptr;
4727 [ # # ]: 0 : } else if (type_node->type == NodeTypeContainerDecl) {
4728 : 0 : return type_node;
4729 [ # # ]: 0 : } else if (type_node->type == NodeTypePrefixOpExpr) {
4730 : 0 : return type_node;
4731 [ # # ]: 0 : } else if (type_node->type == NodeTypeSymbol) {
4732 : 0 : AstNode *existing_node = get_global(c, type_node->data.symbol_expr.symbol);
4733 [ # # ]: 0 : if (existing_node == nullptr)
4734 : 0 : return nullptr;
4735 [ # # ]: 0 : if (existing_node->type != NodeTypeVariableDeclaration)
4736 : 0 : return nullptr;
4737 : 0 : return trans_lookup_ast_container(c, existing_node->data.variable_declaration.expr);
4738 [ # # ]: 0 : } else if (type_node->type == NodeTypeFieldAccessExpr) {
4739 : 0 : AstNode *container_node = trans_lookup_ast_container_typeof(c, type_node->data.field_access_expr.struct_expr);
4740 [ # # ]: 0 : if (container_node == nullptr)
4741 : 0 : return nullptr;
4742 [ # # ]: 0 : if (container_node->type != NodeTypeContainerDecl)
4743 : 0 : return container_node;
4744 : :
4745 [ # # ]: 0 : for (size_t i = 0; i < container_node->data.container_decl.fields.length; i += 1) {
4746 : 0 : AstNode *field_node = container_node->data.container_decl.fields.items[i];
4747 [ # # ]: 0 : if (buf_eql_buf(field_node->data.struct_field.name, type_node->data.field_access_expr.field_name)) {
4748 : 0 : return trans_lookup_ast_container(c, field_node->data.struct_field.type);
4749 : : }
4750 : : }
4751 : 0 : return nullptr;
4752 : : } else {
4753 : 0 : return nullptr;
4754 : : }
4755 : : }
4756 : :
4757 : 0 : static AstNode *trans_lookup_ast_container_typeof(Context *c, AstNode *ref_node) {
4758 [ # # ]: 0 : if (ref_node->type == NodeTypeSymbol) {
4759 : 0 : AstNode *existing_node = get_global(c, ref_node->data.symbol_expr.symbol);
4760 [ # # ]: 0 : if (existing_node == nullptr)
4761 : 0 : return nullptr;
4762 [ # # ]: 0 : if (existing_node->type != NodeTypeVariableDeclaration)
4763 : 0 : return nullptr;
4764 : 0 : return trans_lookup_ast_container(c, existing_node->data.variable_declaration.type);
4765 [ # # ]: 0 : } else if (ref_node->type == NodeTypeFieldAccessExpr) {
4766 : 0 : AstNode *container_node = trans_lookup_ast_container_typeof(c, ref_node->data.field_access_expr.struct_expr);
4767 [ # # ]: 0 : if (container_node == nullptr)
4768 : 0 : return nullptr;
4769 [ # # ]: 0 : if (container_node->type != NodeTypeContainerDecl)
4770 : 0 : return container_node;
4771 [ # # ]: 0 : for (size_t i = 0; i < container_node->data.container_decl.fields.length; i += 1) {
4772 : 0 : AstNode *field_node = container_node->data.container_decl.fields.items[i];
4773 [ # # ]: 0 : if (buf_eql_buf(field_node->data.struct_field.name, ref_node->data.field_access_expr.field_name)) {
4774 : 0 : return trans_lookup_ast_container(c, field_node->data.struct_field.type);
4775 : : }
4776 : : }
4777 : 0 : return nullptr;
4778 : : } else {
4779 : 0 : return nullptr;
4780 : : }
4781 : : }
4782 : :
4783 : 0 : static AstNode *trans_lookup_ast_maybe_fn(Context *c, AstNode *ref_node) {
4784 : 0 : AstNode *prefix_node = trans_lookup_ast_container_typeof(c, ref_node);
4785 [ # # ]: 0 : if (prefix_node == nullptr)
4786 : 0 : return nullptr;
4787 [ # # ]: 0 : if (prefix_node->type != NodeTypePrefixOpExpr)
4788 : 0 : return nullptr;
4789 [ # # ]: 0 : if (prefix_node->data.prefix_op_expr.prefix_op != PrefixOpOptional)
4790 : 0 : return nullptr;
4791 : :
4792 : 0 : AstNode *fn_proto_node = prefix_node->data.prefix_op_expr.primary_expr;
4793 [ # # ]: 0 : if (fn_proto_node->type != NodeTypeFnProto)
4794 : 0 : return nullptr;
4795 : :
4796 : 0 : return fn_proto_node;
4797 : : }
4798 : :
4799 : 0 : static void render_macros(Context *c) {
4800 : 0 : auto it = c->macro_table.entry_iterator();
4801 : : for (;;) {
4802 : 0 : auto *entry = it.next();
4803 [ # # ]: 0 : if (!entry)
4804 : 0 : break;
4805 : :
4806 : : AstNode *proto_node;
4807 : 0 : AstNode *value_node = entry->value;
4808 [ # # ]: 0 : if (value_node->type == NodeTypeFnDef) {
4809 : 0 : add_top_level_decl(c, value_node->data.fn_def.fn_proto->data.fn_proto.name, value_node);
4810 [ # # ]: 0 : } else if ((proto_node = trans_lookup_ast_maybe_fn(c, value_node))) {
4811 : : // If a macro aliases a global variable which is a function pointer, we conclude that
4812 : : // the macro is intended to represent a function that assumes the function pointer
4813 : : // variable is non-null and calls it.
4814 : 0 : AstNode *inline_fn_node = trans_create_node_inline_fn(c, entry->key, value_node, proto_node);
4815 : 0 : add_top_level_decl(c, entry->key, inline_fn_node);
4816 : : } else {
4817 : 0 : add_global_var(c, entry->key, value_node);
4818 : : }
4819 : 0 : }
4820 : 0 : }
4821 : :
4822 : : static AstNode *parse_ctok_primary_expr(Context *c, CTokenize *ctok, size_t *tok_i);
4823 : : static AstNode *parse_ctok_expr(Context *c, CTokenize *ctok, size_t *tok_i);
4824 : : static AstNode *parse_ctok_prefix_op_expr(Context *c, CTokenize *ctok, size_t *tok_i);
4825 : :
4826 : 0 : static AstNode *parse_ctok_num_lit(Context *c, CTokenize *ctok, size_t *tok_i, bool negate) {
4827 : 0 : CTok *tok = &ctok->tokens.at(*tok_i);
4828 [ # # ]: 0 : if (tok->id == CTokIdNumLitInt) {
4829 : 0 : *tok_i += 1;
4830 [ # # # # : 0 : switch (tok->data.num_lit_int.suffix) {
# # # ]
4831 : 0 : case CNumLitSuffixNone:
4832 : 0 : return trans_create_node_unsigned_negative(c, tok->data.num_lit_int.x, negate);
4833 : 0 : case CNumLitSuffixL:
4834 : 0 : return trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, "c_long");
4835 : 0 : case CNumLitSuffixU:
4836 : 0 : return trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, "c_uint");
4837 : 0 : case CNumLitSuffixLU:
4838 : 0 : return trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, "c_ulong");
4839 : 0 : case CNumLitSuffixLL:
4840 : 0 : return trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, "c_longlong");
4841 : 0 : case CNumLitSuffixLLU:
4842 : 0 : return trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, "c_ulonglong");
4843 : : }
4844 : 0 : zig_unreachable();
4845 [ # # ]: 0 : } else if (tok->id == CTokIdNumLitFloat) {
4846 : 0 : *tok_i += 1;
4847 [ # # ]: 0 : double value = negate ? -tok->data.num_lit_float : tok->data.num_lit_float;
4848 : 0 : return trans_create_node_float_lit(c, value);
4849 : : }
4850 : 0 : return nullptr;
4851 : : }
4852 : :
4853 : 0 : static AstNode *parse_ctok_primary_expr(Context *c, CTokenize *ctok, size_t *tok_i) {
4854 : 0 : CTok *tok = &ctok->tokens.at(*tok_i);
4855 [ # # # # : 0 : switch (tok->id) {
# # # # ]
4856 : 0 : case CTokIdCharLit:
4857 : 0 : *tok_i += 1;
4858 : 0 : return trans_create_node_unsigned(c, tok->data.char_lit);
4859 : 0 : case CTokIdStrLit:
4860 : 0 : *tok_i += 1;
4861 : 0 : return trans_create_node_str_lit_c(c, buf_create_from_buf(&tok->data.str_lit));
4862 : 0 : case CTokIdMinus:
4863 : 0 : *tok_i += 1;
4864 : 0 : return parse_ctok_num_lit(c, ctok, tok_i, true);
4865 : 0 : case CTokIdNumLitInt:
4866 : : case CTokIdNumLitFloat:
4867 : 0 : return parse_ctok_num_lit(c, ctok, tok_i, false);
4868 : 0 : case CTokIdSymbol:
4869 : : {
4870 : 0 : *tok_i += 1;
4871 : 0 : Buf *symbol_name = buf_create_from_buf(&tok->data.symbol);
4872 : 0 : return trans_create_node_symbol(c, symbol_name);
4873 : : }
4874 : 0 : case CTokIdLParen:
4875 : : {
4876 : 0 : *tok_i += 1;
4877 : 0 : AstNode *inner_node = parse_ctok_expr(c, ctok, tok_i);
4878 [ # # ]: 0 : if (inner_node == nullptr) {
4879 : 0 : return nullptr;
4880 : : }
4881 : :
4882 : 0 : CTok *next_tok = &ctok->tokens.at(*tok_i);
4883 [ # # ]: 0 : if (next_tok->id == CTokIdRParen) {
4884 : 0 : *tok_i += 1;
4885 : 0 : return inner_node;
4886 : : }
4887 : :
4888 : 0 : AstNode *node_to_cast = parse_ctok_expr(c, ctok, tok_i);
4889 [ # # ]: 0 : if (node_to_cast == nullptr) {
4890 : 0 : return nullptr;
4891 : : }
4892 : :
4893 : 0 : CTok *next_tok2 = &ctok->tokens.at(*tok_i);
4894 [ # # ]: 0 : if (next_tok2->id != CTokIdRParen) {
4895 : 0 : return nullptr;
4896 : : }
4897 : 0 : *tok_i += 1;
4898 : :
4899 : :
4900 : : //if (@typeId(@typeOf(x)) == @import("builtin").TypeId.Pointer)
4901 : : // @ptrCast(dest, x)
4902 : : //else if (@typeId(@typeOf(x)) == @import("builtin").TypeId.Integer)
4903 : : // @intToPtr(dest, x)
4904 : : //else
4905 : : // (dest)(x)
4906 : :
4907 : 0 : AstNode *import_builtin = trans_create_node_builtin_fn_call_str(c, "import");
4908 : 0 : import_builtin->data.fn_call_expr.params.append(trans_create_node_str_lit_non_c(c, buf_create_from_str("builtin")));
4909 : 0 : AstNode *typeid_type = trans_create_node_field_access_str(c, import_builtin, "TypeId");
4910 : 0 : AstNode *typeid_pointer = trans_create_node_field_access_str(c, typeid_type, "Pointer");
4911 : 0 : AstNode *typeid_integer = trans_create_node_field_access_str(c, typeid_type, "Int");
4912 : 0 : AstNode *typeof_x = trans_create_node_builtin_fn_call_str(c, "typeOf");
4913 : 0 : typeof_x->data.fn_call_expr.params.append(node_to_cast);
4914 : 0 : AstNode *typeid_value = trans_create_node_builtin_fn_call_str(c, "typeId");
4915 : 0 : typeid_value->data.fn_call_expr.params.append(typeof_x);
4916 : :
4917 : 0 : AstNode *outer_if_cond = trans_create_node_bin_op(c, typeid_value, BinOpTypeCmpEq, typeid_pointer);
4918 : 0 : AstNode *inner_if_cond = trans_create_node_bin_op(c, typeid_value, BinOpTypeCmpEq, typeid_integer);
4919 : 0 : AstNode *inner_if_then = trans_create_node_builtin_fn_call_str(c, "intToPtr");
4920 : 0 : inner_if_then->data.fn_call_expr.params.append(inner_node);
4921 : 0 : inner_if_then->data.fn_call_expr.params.append(node_to_cast);
4922 : 0 : AstNode *inner_if_else = trans_create_node_cast(c, inner_node, node_to_cast);
4923 : 0 : AstNode *inner_if = trans_create_node_if(c, inner_if_cond, inner_if_then, inner_if_else);
4924 : 0 : AstNode *outer_if_then = trans_create_node_builtin_fn_call_str(c, "ptrCast");
4925 : 0 : outer_if_then->data.fn_call_expr.params.append(inner_node);
4926 : 0 : outer_if_then->data.fn_call_expr.params.append(node_to_cast);
4927 : 0 : return trans_create_node_if(c, outer_if_cond, outer_if_then, inner_if);
4928 : : }
4929 : 0 : case CTokIdDot:
4930 : : case CTokIdEOF:
4931 : : case CTokIdRParen:
4932 : : case CTokIdAsterisk:
4933 : : case CTokIdBang:
4934 : : case CTokIdTilde:
4935 : : case CTokIdShl:
4936 : : case CTokIdLt:
4937 : : // not able to make sense of this
4938 : 0 : return nullptr;
4939 : : }
4940 : 0 : zig_unreachable();
4941 : : }
4942 : :
4943 : 0 : static AstNode *parse_ctok_expr(Context *c, CTokenize *ctok, size_t *tok_i) {
4944 : 0 : return parse_ctok_prefix_op_expr(c, ctok, tok_i);
4945 : : }
4946 : :
4947 : 0 : static AstNode *parse_ctok_suffix_op_expr(Context *c, CTokenize *ctok, size_t *tok_i) {
4948 : 0 : AstNode *node = parse_ctok_primary_expr(c, ctok, tok_i);
4949 [ # # ]: 0 : if (node == nullptr)
4950 : 0 : return nullptr;
4951 : :
4952 : : while (true) {
4953 : 0 : CTok *first_tok = &ctok->tokens.at(*tok_i);
4954 [ # # ]: 0 : if (first_tok->id == CTokIdDot) {
4955 : 0 : *tok_i += 1;
4956 : :
4957 : 0 : CTok *name_tok = &ctok->tokens.at(*tok_i);
4958 [ # # ]: 0 : if (name_tok->id != CTokIdSymbol) {
4959 : 0 : return nullptr;
4960 : : }
4961 : 0 : *tok_i += 1;
4962 : :
4963 : 0 : node = trans_create_node_field_access(c, node, buf_create_from_buf(&name_tok->data.symbol));
4964 [ # # ]: 0 : } else if (first_tok->id == CTokIdAsterisk) {
4965 : 0 : *tok_i += 1;
4966 : :
4967 : 0 : node = trans_create_node_ptr_type(c, false, false, node, PtrLenC);
4968 [ # # ]: 0 : } else if (first_tok->id == CTokIdShl) {
4969 : 0 : *tok_i += 1;
4970 : :
4971 : 0 : AstNode *rhs_node = parse_ctok_expr(c, ctok, tok_i);
4972 [ # # ]: 0 : if (rhs_node == nullptr)
4973 : 0 : return nullptr;
4974 : 0 : node = trans_create_node_bin_op(c, node, BinOpTypeBitShiftLeft, rhs_node);
4975 : : } else {
4976 : 0 : return node;
4977 : : }
4978 : 0 : }
4979 : : }
4980 : :
4981 : 0 : static AstNode *parse_ctok_prefix_op_expr(Context *c, CTokenize *ctok, size_t *tok_i) {
4982 : 0 : CTok *op_tok = &ctok->tokens.at(*tok_i);
4983 : :
4984 [ # # # # : 0 : switch (op_tok->id) {
# ]
4985 : 0 : case CTokIdBang:
4986 : : {
4987 : 0 : *tok_i += 1;
4988 : 0 : AstNode *prefix_op_expr = parse_ctok_prefix_op_expr(c, ctok, tok_i);
4989 [ # # ]: 0 : if (prefix_op_expr == nullptr)
4990 : 0 : return nullptr;
4991 : 0 : return trans_create_node_prefix_op(c, PrefixOpBoolNot, prefix_op_expr);
4992 : : }
4993 : 0 : case CTokIdMinus:
4994 : : {
4995 : 0 : *tok_i += 1;
4996 : 0 : AstNode *prefix_op_expr = parse_ctok_prefix_op_expr(c, ctok, tok_i);
4997 [ # # ]: 0 : if (prefix_op_expr == nullptr)
4998 : 0 : return nullptr;
4999 : 0 : return trans_create_node_prefix_op(c, PrefixOpNegation, prefix_op_expr);
5000 : : }
5001 : 0 : case CTokIdTilde:
5002 : : {
5003 : 0 : *tok_i += 1;
5004 : 0 : AstNode *prefix_op_expr = parse_ctok_prefix_op_expr(c, ctok, tok_i);
5005 [ # # ]: 0 : if (prefix_op_expr == nullptr)
5006 : 0 : return nullptr;
5007 : 0 : return trans_create_node_prefix_op(c, PrefixOpBinNot, prefix_op_expr);
5008 : : }
5009 : 0 : case CTokIdAsterisk:
5010 : : {
5011 : 0 : *tok_i += 1;
5012 : 0 : AstNode *prefix_op_expr = parse_ctok_prefix_op_expr(c, ctok, tok_i);
5013 [ # # ]: 0 : if (prefix_op_expr == nullptr)
5014 : 0 : return nullptr;
5015 : 0 : return trans_create_node_ptr_deref(c, prefix_op_expr);
5016 : : }
5017 : 0 : default:
5018 : 0 : return parse_ctok_suffix_op_expr(c, ctok, tok_i);
5019 : : }
5020 : : }
5021 : :
5022 : 0 : static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *char_ptr) {
5023 : 0 : tokenize_c_macro(ctok, (const uint8_t *)char_ptr);
5024 : :
5025 [ # # ]: 0 : if (ctok->error) {
5026 : 0 : return;
5027 : : }
5028 : :
5029 : 0 : size_t tok_i = 0;
5030 : 0 : CTok *name_tok = &ctok->tokens.at(tok_i);
5031 [ # # ][ # # ]: 0 : assert(name_tok->id == CTokIdSymbol && buf_eql_buf(&name_tok->data.symbol, name));
5032 : 0 : tok_i += 1;
5033 : :
5034 : 0 : AstNode *result_node = parse_ctok_suffix_op_expr(c, ctok, &tok_i);
5035 [ # # ]: 0 : if (result_node == nullptr) {
5036 : 0 : return;
5037 : : }
5038 : 0 : CTok *eof_tok = &ctok->tokens.at(tok_i);
5039 [ # # ]: 0 : if (eof_tok->id != CTokIdEOF) {
5040 : 0 : return;
5041 : : }
5042 [ # # ]: 0 : if (result_node->type == NodeTypeSymbol) {
5043 : : // if it equals itself, ignore. for example, from stdio.h:
5044 : : // #define stdin stdin
5045 : 0 : Buf *symbol_name = result_node->data.symbol_expr.symbol;
5046 [ # # ]: 0 : if (buf_eql_buf(name, symbol_name)) {
5047 : 0 : return;
5048 : : }
5049 : : }
5050 : 0 : c->macro_table.put(name, result_node);
5051 : : }
5052 : :
5053 : 0 : static void process_preprocessor_entities(Context *c, ZigClangASTUnit *zunit) {
5054 : 0 : clang::ASTUnit *unit = reinterpret_cast<clang::ASTUnit *>(zunit);
5055 : 0 : CTokenize ctok = {{0}};
5056 : :
5057 : : // TODO if we see #undef, delete it from the table
5058 : :
5059 [ # # ]: 0 : for (clang::PreprocessedEntity *entity : unit->getLocalPreprocessingEntities()) {
5060 [ # # # ]: 0 : switch (entity->getKind()) {
5061 : 0 : case clang::PreprocessedEntity::InvalidKind:
5062 : : case clang::PreprocessedEntity::InclusionDirectiveKind:
5063 : : case clang::PreprocessedEntity::MacroExpansionKind:
5064 : 0 : continue;
5065 : 0 : case clang::PreprocessedEntity::MacroDefinitionKind:
5066 : : {
5067 : 0 : clang::MacroDefinitionRecord *macro = static_cast<clang::MacroDefinitionRecord *>(entity);
5068 : 0 : const char *raw_name = macro->getName()->getNameStart();
5069 : 0 : clang::SourceRange range = macro->getSourceRange();
5070 : 0 : ZigClangSourceLocation begin_loc = bitcast(range.getBegin());
5071 : 0 : ZigClangSourceLocation end_loc = bitcast(range.getEnd());
5072 : :
5073 [ # # ]: 0 : if (ZigClangSourceLocation_eq(begin_loc, end_loc)) {
5074 : : // this means it is a macro without a value
5075 : : // we don't care about such things
5076 : 0 : continue;
5077 : : }
5078 : 0 : Buf *name = buf_create_from_str(raw_name);
5079 [ # # ]: 0 : if (name_exists_global(c, name)) {
5080 : 0 : continue;
5081 : : }
5082 : :
5083 : 0 : const char *begin_c = ZigClangSourceManager_getCharacterData(c->source_manager, begin_loc);
5084 : 0 : process_macro(c, &ctok, name, begin_c);
5085 : 0 : }
5086 : : }
5087 : : }
5088 : 0 : }
5089 : :
5090 : 0 : Error parse_h_file(CodeGen *codegen, AstNode **out_root_node,
5091 : : Stage2ErrorMsg **errors_ptr, size_t *errors_len,
5092 : : const char **args_begin, const char **args_end,
5093 : : Stage2TranslateMode mode, const char *resources_path)
5094 : : {
5095 : 0 : Context context = {0};
5096 : 0 : Context *c = &context;
5097 : 0 : c->warnings_on = codegen->verbose_cimport;
5098 [ # # ]: 0 : if (mode == Stage2TranslateModeImport) {
5099 : 0 : c->visib_mod = VisibModPub;
5100 : 0 : c->want_export = false;
5101 : : } else {
5102 : 0 : c->visib_mod = VisibModPub;
5103 : 0 : c->want_export = true;
5104 : : }
5105 : 0 : c->decl_table.init(8);
5106 : 0 : c->macro_table.init(8);
5107 : 0 : c->global_table.init(8);
5108 : 0 : c->ptr_params.init(8);
5109 : 0 : c->codegen = codegen;
5110 : 0 : c->global_scope = trans_scope_root_create(c);
5111 : :
5112 : : ZigClangASTUnit *ast_unit = ZigClangLoadFromCommandLine(args_begin, args_end, errors_ptr, errors_len,
5113 : 0 : resources_path);
5114 [ # # ]: 0 : if (ast_unit == nullptr) {
5115 [ # # ]: 0 : if (*errors_len == 0) return ErrorNoMem;
5116 : 0 : return ErrorCCompileErrors;
5117 : : }
5118 : :
5119 : 0 : c->ctx = ZigClangASTUnit_getASTContext(ast_unit);
5120 : 0 : c->source_manager = ZigClangASTUnit_getSourceManager(ast_unit);
5121 : 0 : c->root = trans_create_node(c, NodeTypeContainerDecl);
5122 : 0 : c->root->data.container_decl.is_root = true;
5123 : :
5124 : 0 : ZigClangASTUnit_visitLocalTopLevelDecls(ast_unit, c, decl_visitor);
5125 : :
5126 : 0 : process_preprocessor_entities(c, ast_unit);
5127 : :
5128 : 0 : render_macros(c);
5129 : 0 : render_aliases(c);
5130 : :
5131 : 0 : *out_root_node = c->root;
5132 : :
5133 : 0 : ZigClangASTUnit_delete(ast_unit);
5134 : :
5135 : 0 : return ErrorNone;
5136 : : }
|