LCOV - code coverage report
Current view: top level - src - translate_c.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 0 3290 0.0 %
Date: 1970-01-01 00:00:01 Functions: 0 148 0.0 %
Branches: 0 1336 0.0 %

           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                 :            : }

Generated by: LCOV version 1.14