Commit fceda07f94
Changed files (11)
src/c_tokenizer.cpp
@@ -1,840 +0,0 @@
-/*
- * Copyright (c) 2016 Andrew Kelley
- *
- * This file is part of zig, which is MIT licensed.
- * See http://opensource.org/licenses/MIT
- */
-
-#include "c_tokenizer.hpp"
-#include <inttypes.h>
-
-#define WHITESPACE_EXCEPT_N \
- ' ': \
- case '\t': \
- case '\v': \
- case '\f'
-
-#define DIGIT_NON_ZERO \
- '1': \
- case '2': \
- case '3': \
- case '4': \
- case '5': \
- case '6': \
- case '7': \
- case '8': \
- case '9'
-
-#define DIGIT \
- '0': \
- case DIGIT_NON_ZERO
-
-#define ALPHA \
- 'a': \
- case 'b': \
- case 'c': \
- case 'd': \
- case 'e': \
- case 'f': \
- case 'g': \
- case 'h': \
- case 'i': \
- case 'j': \
- case 'k': \
- case 'l': \
- case 'm': \
- case 'n': \
- case 'o': \
- case 'p': \
- case 'q': \
- case 'r': \
- case 's': \
- case 't': \
- case 'u': \
- case 'v': \
- case 'w': \
- case 'x': \
- case 'y': \
- case 'z': \
- case 'A': \
- case 'B': \
- case 'C': \
- case 'D': \
- case 'E': \
- case 'F': \
- case 'G': \
- case 'H': \
- case 'I': \
- case 'J': \
- case 'K': \
- case 'L': \
- case 'M': \
- case 'N': \
- case 'O': \
- case 'P': \
- case 'Q': \
- case 'R': \
- case 'S': \
- case 'T': \
- case 'U': \
- case 'V': \
- case 'W': \
- case 'X': \
- case 'Y': \
- case 'Z'
-
-#define IDENT_START \
- ALPHA: \
- case '_'
-
-#define IDENT \
- IDENT_START: \
- case DIGIT
-
-#define LINE_ENDING \
- '\r': \
- case '\n'
-
-static void begin_token(CTokenize *ctok, CTokId id) {
- assert(ctok->cur_tok == nullptr);
- ctok->tokens.add_one();
- ctok->cur_tok = &ctok->tokens.last();
- ctok->cur_tok->id = id;
-
- switch (id) {
- case CTokIdStrLit:
- memset(&ctok->cur_tok->data.str_lit, 0, sizeof(Buf));
- buf_resize(&ctok->cur_tok->data.str_lit, 0);
- break;
- case CTokIdSymbol:
- memset(&ctok->cur_tok->data.symbol, 0, sizeof(Buf));
- buf_resize(&ctok->cur_tok->data.symbol, 0);
- break;
- case CTokIdNumLitInt:
- ctok->cur_tok->data.num_lit_int.x = 0;
- ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixNone;
- break;
- case CTokIdCharLit:
- case CTokIdNumLitFloat:
- case CTokIdMinus:
- case CTokIdLParen:
- case CTokIdRParen:
- case CTokIdEOF:
- case CTokIdDot:
- case CTokIdAsterisk:
- case CTokIdBang:
- case CTokIdTilde:
- case CTokIdShl:
- case CTokIdLt:
- break;
- }
-}
-
-static void end_token(CTokenize *ctok) {
- ctok->cur_tok = nullptr;
-}
-
-static void mark_error(CTokenize *ctok) {
- ctok->error = true;
-}
-
-static void add_char(CTokenize *ctok, uint8_t c) {
- assert(ctok->cur_tok);
- if (ctok->cur_tok->id == CTokIdCharLit) {
- ctok->cur_tok->data.char_lit = c;
- ctok->state = CTokStateExpectEndQuot;
- } else if (ctok->cur_tok->id == CTokIdStrLit) {
- buf_append_char(&ctok->cur_tok->data.str_lit, c);
- ctok->state = CTokStateString;
- } else {
- zig_unreachable();
- }
-}
-
-static void hex_digit(CTokenize *ctok, uint8_t value) {
- // TODO @mul_with_overflow
- ctok->cur_tok->data.num_lit_int.x *= 16;
- // TODO @add_with_overflow
- ctok->cur_tok->data.num_lit_int.x += value;
-
- static const uint8_t hex_digit[] = "0123456789abcdef";
- buf_append_char(&ctok->buf, hex_digit[value]);
-}
-
-static void end_float(CTokenize *ctok) {
- // TODO detect errors, overflow, and underflow
- double value = strtod(buf_ptr(&ctok->buf), nullptr);
-
- ctok->cur_tok->data.num_lit_float = value;
-
- end_token(ctok);
- ctok->state = CTokStateStart;
-
-}
-
-void tokenize_c_macro(CTokenize *ctok, const uint8_t *c) {
- ctok->tokens.resize(0);
- ctok->state = CTokStateStart;
- ctok->error = false;
- ctok->cur_tok = nullptr;
-
- buf_resize(&ctok->buf, 0);
-
- for (; *c; c += 1) {
- switch (ctok->state) {
- case CTokStateStart:
- switch (*c) {
- case WHITESPACE_EXCEPT_N:
- break;
- case '\'':
- ctok->state = CTokStateExpectChar;
- begin_token(ctok, CTokIdCharLit);
- break;
- case '\"':
- ctok->state = CTokStateString;
- begin_token(ctok, CTokIdStrLit);
- break;
- case '/':
- ctok->state = CTokStateOpenComment;
- break;
- case '\\':
- ctok->state = CTokStateBackslash;
- break;
- case LINE_ENDING:
- goto found_end_of_macro;
- case IDENT_START:
- ctok->state = CTokStateIdentifier;
- begin_token(ctok, CTokIdSymbol);
- buf_append_char(&ctok->cur_tok->data.symbol, *c);
- break;
- case DIGIT_NON_ZERO:
- ctok->state = CTokStateDecimal;
- begin_token(ctok, CTokIdNumLitInt);
- ctok->cur_tok->data.num_lit_int.x = *c - '0';
- buf_resize(&ctok->buf, 0);
- buf_append_char(&ctok->buf, *c);
- break;
- case '0':
- ctok->state = CTokStateGotZero;
- begin_token(ctok, CTokIdNumLitInt);
- ctok->cur_tok->data.num_lit_int.x = 0;
- buf_resize(&ctok->buf, 0);
- buf_append_char(&ctok->buf, '0');
- break;
- case '.':
- begin_token(ctok, CTokIdDot);
- end_token(ctok);
- break;
- case '<':
- begin_token(ctok, CTokIdLt);
- ctok->state = CTokStateGotLt;
- break;
- case '(':
- begin_token(ctok, CTokIdLParen);
- end_token(ctok);
- break;
- case ')':
- begin_token(ctok, CTokIdRParen);
- end_token(ctok);
- break;
- case '*':
- begin_token(ctok, CTokIdAsterisk);
- end_token(ctok);
- break;
- case '-':
- begin_token(ctok, CTokIdMinus);
- end_token(ctok);
- break;
- case '!':
- begin_token(ctok, CTokIdBang);
- end_token(ctok);
- break;
- case '~':
- begin_token(ctok, CTokIdTilde);
- end_token(ctok);
- break;
- default:
- return mark_error(ctok);
- }
- break;
- case CTokStateGotLt:
- switch (*c) {
- case '<':
- ctok->cur_tok->id = CTokIdShl;
- end_token(ctok);
- ctok->state = CTokStateStart;
- break;
- default:
- end_token(ctok);
- ctok->state = CTokStateStart;
- continue;
- }
- break;
- case CTokStateFloat:
- switch (*c) {
- case '.':
- break;
- case 'e':
- case 'E':
- buf_append_char(&ctok->buf, 'e');
- ctok->state = CTokStateExpSign;
- break;
- case 'f':
- case 'F':
- case 'l':
- case 'L':
- end_float(ctok);
- break;
- case DIGIT:
- buf_append_char(&ctok->buf, *c);
- break;
- default:
- c -= 1;
- end_float(ctok);
- continue;
- }
- break;
- case CTokStateExpSign:
- switch (*c) {
- case '+':
- case '-':
- ctok->state = CTokStateFloatExpFirst;
- buf_append_char(&ctok->buf, *c);
- break;
- case DIGIT:
- ctok->state = CTokStateFloatExp;
- buf_append_char(&ctok->buf, *c);
- break;
- default:
- return mark_error(ctok);
- }
- break;
- case CTokStateFloatExpFirst:
- switch (*c) {
- case DIGIT:
- buf_append_char(&ctok->buf, *c);
- ctok->state = CTokStateFloatExp;
- break;
- default:
- return mark_error(ctok);
- }
- break;
- case CTokStateFloatExp:
- switch (*c) {
- case DIGIT:
- buf_append_char(&ctok->buf, *c);
- break;
- case 'f':
- case 'F':
- case 'l':
- case 'L':
- end_float(ctok);
- break;
- default:
- c -= 1;
- end_float(ctok);
- continue;
- }
- break;
- case CTokStateDecimal:
- switch (*c) {
- case DIGIT:
- buf_append_char(&ctok->buf, *c);
-
- // TODO @mul_with_overflow
- ctok->cur_tok->data.num_lit_int.x *= 10;
- // TODO @add_with_overflow
- ctok->cur_tok->data.num_lit_int.x += *c - '0';
- break;
- case '\'':
- break;
- case 'u':
- case 'U':
- ctok->state = CTokStateNumLitIntSuffixU;
- ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixU;
- break;
- case 'l':
- case 'L':
- ctok->state = CTokStateNumLitIntSuffixL;
- ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixL;
- break;
- case '.':
- buf_append_char(&ctok->buf, '.');
- ctok->cur_tok->id = CTokIdNumLitFloat;
- ctok->state = CTokStateFloat;
- break;
- default:
- c -= 1;
- end_token(ctok);
- ctok->state = CTokStateStart;
- continue;
- }
- break;
- case CTokStateGotZero:
- switch (*c) {
- case 'x':
- case 'X':
- ctok->state = CTokStateHex;
- break;
- case '.':
- ctok->state = CTokStateFloat;
- ctok->cur_tok->id = CTokIdNumLitFloat;
- buf_append_char(&ctok->buf, '.');
- break;
- case 'l':
- case 'L':
- case 'u':
- case 'U':
- c -= 1;
- ctok->state = CTokStateDecimal;
- continue;
- default:
- c -= 1;
- ctok->state = CTokStateOctal;
- continue;
- }
- break;
- case CTokStateOctal:
- switch (*c) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- // TODO @mul_with_overflow
- ctok->cur_tok->data.num_lit_int.x *= 8;
- // TODO @add_with_overflow
- ctok->cur_tok->data.num_lit_int.x += *c - '0';
- break;
- case '8':
- case '9':
- return mark_error(ctok);
- case '\'':
- break;
- default:
- c -= 1;
- end_token(ctok);
- ctok->state = CTokStateStart;
- continue;
- }
- break;
- case CTokStateHex:
- switch (*c) {
- case '0':
- hex_digit(ctok, 0);
- break;
- case '1':
- hex_digit(ctok, 1);
- break;
- case '2':
- hex_digit(ctok, 2);
- break;
- case '3':
- hex_digit(ctok, 3);
- break;
- case '4':
- hex_digit(ctok, 4);
- break;
- case '5':
- hex_digit(ctok, 5);
- break;
- case '6':
- hex_digit(ctok, 6);
- break;
- case '7':
- hex_digit(ctok, 7);
- break;
- case '8':
- hex_digit(ctok, 8);
- break;
- case '9':
- hex_digit(ctok, 9);
- break;
- case 'a':
- case 'A':
- hex_digit(ctok, 10);
- break;
- case 'b':
- case 'B':
- hex_digit(ctok, 11);
- break;
- case 'c':
- case 'C':
- hex_digit(ctok, 12);
- break;
- case 'd':
- case 'D':
- hex_digit(ctok, 13);
- break;
- case 'e':
- case 'E':
- hex_digit(ctok, 14);
- break;
- case 'f':
- case 'F':
- hex_digit(ctok, 15);
- break;
- case 'p':
- case 'P':
- ctok->cur_tok->id = CTokIdNumLitFloat;
- ctok->state = CTokStateExpSign;
- break;
- case 'u':
- case 'U':
- // marks the number literal as unsigned
- ctok->state = CTokStateNumLitIntSuffixU;
- ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixU;
- break;
- case 'l':
- case 'L':
- // marks the number literal as long
- ctok->state = CTokStateNumLitIntSuffixL;
- ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixL;
- break;
- default:
- c -= 1;
- end_token(ctok);
- ctok->state = CTokStateStart;
- continue;
- }
- break;
- case CTokStateNumLitIntSuffixU:
- switch (*c) {
- case 'l':
- case 'L':
- ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixLU;
- ctok->state = CTokStateNumLitIntSuffixUL;
- break;
- default:
- c -= 1;
- end_token(ctok);
- ctok->state = CTokStateStart;
- continue;
- }
- break;
- case CTokStateNumLitIntSuffixL:
- switch (*c) {
- case 'l':
- case 'L':
- ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixLL;
- ctok->state = CTokStateNumLitIntSuffixLL;
- break;
- case 'u':
- case 'U':
- ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixLU;
- end_token(ctok);
- ctok->state = CTokStateStart;
- break;
- default:
- c -= 1;
- end_token(ctok);
- ctok->state = CTokStateStart;
- continue;
- }
- break;
- case CTokStateNumLitIntSuffixLL:
- switch (*c) {
- case 'u':
- case 'U':
- ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixLLU;
- end_token(ctok);
- ctok->state = CTokStateStart;
- break;
- default:
- c -= 1;
- end_token(ctok);
- ctok->state = CTokStateStart;
- continue;
- }
- break;
- case CTokStateNumLitIntSuffixUL:
- switch (*c) {
- case 'l':
- case 'L':
- ctok->cur_tok->data.num_lit_int.suffix = CNumLitSuffixLLU;
- end_token(ctok);
- ctok->state = CTokStateStart;
- break;
- default:
- c -= 1;
- end_token(ctok);
- ctok->state = CTokStateStart;
- continue;
- }
- break;
- case CTokStateIdentifier:
- switch (*c) {
- case IDENT:
- buf_append_char(&ctok->cur_tok->data.symbol, *c);
- break;
- default:
- c -= 1;
- end_token(ctok);
- ctok->state = CTokStateStart;
- continue;
- }
- break;
- case CTokStateString:
- switch (*c) {
- case '\\':
- ctok->state = CTokStateCharEscape;
- break;
- case '\"':
- end_token(ctok);
- ctok->state = CTokStateStart;
- break;
- default:
- buf_append_char(&ctok->cur_tok->data.str_lit, *c);
- }
- break;
- case CTokStateExpectChar:
- switch (*c) {
- case '\\':
- ctok->state = CTokStateCharEscape;
- break;
- case '\'':
- return mark_error(ctok);
- default:
- ctok->cur_tok->data.char_lit = *c;
- ctok->state = CTokStateExpectEndQuot;
- }
- break;
- case CTokStateCharEscape:
- switch (*c) {
- case '\'':
- case '"':
- case '?':
- case '\\':
- add_char(ctok, *c);
- break;
- case 'a':
- add_char(ctok, '\a');
- break;
- case 'b':
- add_char(ctok, '\b');
- break;
- case 'f':
- add_char(ctok, '\f');
- break;
- case 'n':
- add_char(ctok, '\n');
- break;
- case 'r':
- add_char(ctok, '\r');
- break;
- case 't':
- add_char(ctok, '\t');
- break;
- case 'v':
- add_char(ctok, '\v');
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- ctok->state = CTokStateStrOctal;
- ctok->cur_char = (uint8_t)(*c - '0');
- ctok->octal_index = 1;
- break;
- case 'x':
- ctok->state = CTokStateStrHex;
- ctok->cur_char = 0;
- break;
- case 'u':
- zig_panic("TODO unicode");
- break;
- case 'U':
- zig_panic("TODO Unicode");
- break;
- default:
- return mark_error(ctok);
- }
- break;
- case CTokStateStrHex: {
- uint8_t value = 0;
- switch (*c) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- value = *c - '0';
- break;
- case 'a':
- case 'b':
- case 'c':
- case 'd':
- case 'e':
- case 'f':
- value = (*c - 'a') + 10;
- break;
- case 'A':
- case 'B':
- case 'C':
- case 'D':
- case 'E':
- case 'F':
- value = (*c - 'A') + 10;
- break;
- default:
- c -= 1;
- add_char(ctok, ctok->cur_char);
- continue;
- }
- // TODO @mul_with_overflow
- if (((long)ctok->cur_char) * 16 >= 256) {
- zig_panic("TODO str hex mul overflow");
- }
- ctok->cur_char = (uint8_t)(ctok->cur_char * (uint8_t)16);
- // TODO @add_with_overflow
- if (((long)ctok->cur_char) + (long)(value) >= 256) {
- zig_panic("TODO str hex add overflow");
- }
- ctok->cur_char = (uint8_t)(ctok->cur_char + value);
- break;
- }
- case CTokStateStrOctal:
- switch (*c) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- // TODO @mul_with_overflow
- if (((long)ctok->cur_char) * 8 >= 256) {
- zig_panic("TODO");
- }
- ctok->cur_char = (uint8_t)(ctok->cur_char * (uint8_t)8);
- // TODO @add_with_overflow
- if (((long)ctok->cur_char) + (long)(*c - '0') >= 256) {
- zig_panic("TODO");
- }
- ctok->cur_char = (uint8_t)(ctok->cur_char + (uint8_t)(*c - '0'));
- ctok->octal_index += 1;
- if (ctok->octal_index == 3) {
- add_char(ctok, ctok->cur_char);
- }
- break;
- default:
- c -= 1;
- add_char(ctok, ctok->cur_char);
- continue;
- }
- break;
- case CTokStateExpectEndQuot:
- switch (*c) {
- case '\'':
- end_token(ctok);
- ctok->state = CTokStateStart;
- break;
- default:
- return mark_error(ctok);
- }
- break;
- case CTokStateOpenComment:
- switch (*c) {
- case '/':
- ctok->state = CTokStateLineComment;
- break;
- case '*':
- ctok->state = CTokStateComment;
- break;
- default:
- return mark_error(ctok);
- }
- break;
- case CTokStateLineComment:
- if (*c == '\n') {
- ctok->state = CTokStateStart;
- goto found_end_of_macro;
- }
- break;
- case CTokStateComment:
- switch (*c) {
- case '*':
- ctok->state = CTokStateCommentStar;
- break;
- default:
- break;
- }
- break;
- case CTokStateCommentStar:
- switch (*c) {
- case '/':
- ctok->state = CTokStateStart;
- break;
- case '*':
- break;
- default:
- ctok->state = CTokStateComment;
- break;
- }
- break;
- case CTokStateBackslash:
- switch (*c) {
- case '\n':
- ctok->state = CTokStateStart;
- break;
- default:
- return mark_error(ctok);
- }
- break;
- }
- }
-found_end_of_macro:
-
- switch (ctok->state) {
- case CTokStateStart:
- break;
- case CTokStateIdentifier:
- case CTokStateDecimal:
- case CTokStateHex:
- case CTokStateOctal:
- case CTokStateGotZero:
- case CTokStateNumLitIntSuffixU:
- case CTokStateNumLitIntSuffixL:
- case CTokStateNumLitIntSuffixUL:
- case CTokStateNumLitIntSuffixLL:
- case CTokStateGotLt:
- end_token(ctok);
- break;
- case CTokStateFloat:
- case CTokStateFloatExp:
- end_float(ctok);
- break;
- case CTokStateExpectChar:
- case CTokStateExpectEndQuot:
- case CTokStateOpenComment:
- case CTokStateLineComment:
- case CTokStateComment:
- case CTokStateCommentStar:
- case CTokStateCharEscape:
- case CTokStateBackslash:
- case CTokStateString:
- case CTokStateExpSign:
- case CTokStateFloatExpFirst:
- case CTokStateStrHex:
- case CTokStateStrOctal:
- return mark_error(ctok);
- }
-
- assert(ctok->cur_tok == nullptr);
-
- begin_token(ctok, CTokIdEOF);
- end_token(ctok);
-}
src/c_tokenizer.hpp
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2016 Andrew Kelley
- *
- * This file is part of zig, which is MIT licensed.
- * See http://opensource.org/licenses/MIT
- */
-
-
-#ifndef ZIG_C_TOKENIZER_HPP
-#define ZIG_C_TOKENIZER_HPP
-
-#include "buffer.hpp"
-
-enum CTokId {
- CTokIdCharLit,
- CTokIdStrLit,
- CTokIdNumLitInt,
- CTokIdNumLitFloat,
- CTokIdSymbol,
- CTokIdMinus,
- CTokIdLParen,
- CTokIdRParen,
- CTokIdEOF,
- CTokIdDot,
- CTokIdAsterisk,
- CTokIdBang,
- CTokIdTilde,
- CTokIdShl,
- CTokIdLt,
-};
-
-enum CNumLitSuffix {
- CNumLitSuffixNone,
- CNumLitSuffixL,
- CNumLitSuffixU,
- CNumLitSuffixLU,
- CNumLitSuffixLL,
- CNumLitSuffixLLU,
-};
-
-struct CNumLitInt {
- uint64_t x;
- CNumLitSuffix suffix;
-};
-
-struct CTok {
- enum CTokId id;
- union {
- uint8_t char_lit;
- Buf str_lit;
- CNumLitInt num_lit_int;
- double num_lit_float;
- Buf symbol;
- } data;
-};
-
-enum CTokState {
- CTokStateStart,
- CTokStateExpectChar,
- CTokStateCharEscape,
- CTokStateExpectEndQuot,
- CTokStateOpenComment,
- CTokStateLineComment,
- CTokStateComment,
- CTokStateCommentStar,
- CTokStateBackslash,
- CTokStateString,
- CTokStateIdentifier,
- CTokStateDecimal,
- CTokStateOctal,
- CTokStateGotZero,
- CTokStateHex,
- CTokStateFloat,
- CTokStateExpSign,
- CTokStateFloatExp,
- CTokStateFloatExpFirst,
- CTokStateStrHex,
- CTokStateStrOctal,
- CTokStateNumLitIntSuffixU,
- CTokStateNumLitIntSuffixL,
- CTokStateNumLitIntSuffixLL,
- CTokStateNumLitIntSuffixUL,
- CTokStateGotLt,
-};
-
-struct CTokenize {
- ZigList<CTok> tokens;
- CTokState state;
- bool error;
- CTok *cur_tok;
- Buf buf;
- uint8_t cur_char;
- int octal_index;
-};
-
-void tokenize_c_macro(CTokenize *ctok, const uint8_t *c);
-
-#endif
src/codegen.cpp
@@ -15,7 +15,6 @@
#include "hash_map.hpp"
#include "ir.hpp"
#include "os.hpp"
-#include "translate_c.hpp"
#include "target.hpp"
#include "util.hpp"
#include "zig_llvm.h"
@@ -9090,7 +9089,7 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa
}
-void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_userland_implementation) {
+void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file) {
Error err;
Buf *src_basename = buf_alloc();
Buf *src_dirname = buf_alloc();
@@ -9103,10 +9102,6 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_us
init(g);
- TranslateMode trans_mode = buf_ends_with_str(full_path, ".h") ?
- TranslateModeImport : TranslateModeTranslate;
-
-
ZigList<const char *> clang_argv = {0};
add_cc_args(g, clang_argv, nullptr, true);
@@ -9126,15 +9121,9 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_us
Stage2ErrorMsg *errors_ptr;
size_t errors_len;
Stage2Ast *ast;
- AstNode *root_node;
- if (use_userland_implementation) {
- err = stage2_translate_c(&ast, &errors_ptr, &errors_len,
- &clang_argv.at(0), &clang_argv.last(), resources_path);
- } else {
- err = parse_h_file(g, &root_node, &errors_ptr, &errors_len, &clang_argv.at(0), &clang_argv.last(),
- trans_mode, resources_path);
- }
+ err = stage2_translate_c(&ast, &errors_ptr, &errors_len,
+ &clang_argv.at(0), &clang_argv.last(), resources_path);
if (err == ErrorCCompileErrors && errors_len > 0) {
for (size_t i = 0; i < errors_len; i += 1) {
@@ -9158,12 +9147,7 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_us
exit(1);
}
-
- if (use_userland_implementation) {
- stage2_render_ast(ast, out_file);
- } else {
- ast_render(out_file, root_node, 4);
- }
+ stage2_render_ast(ast, out_file);
}
static void update_test_functions_builtin_decl(CodeGen *g) {
src/codegen.hpp
@@ -54,7 +54,7 @@ ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const c
void codegen_add_assembly(CodeGen *g, Buf *path);
void codegen_add_object(CodeGen *g, Buf *object_path);
-void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_userland_implementation);
+void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file);
Buf *codegen_generate_builtin_source(CodeGen *g);
src/ir.cpp
@@ -13,7 +13,6 @@
#include "os.hpp"
#include "range_set.hpp"
#include "softfloat.hpp"
-#include "translate_c.hpp"
#include "util.hpp"
#include <errno.h>
@@ -23755,14 +23754,14 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
clang_argv.append(nullptr); // to make the [start...end] argument work
- AstNode *root_node;
Stage2ErrorMsg *errors_ptr;
size_t errors_len;
+ Stage2Ast *ast;
const char *resources_path = buf_ptr(ira->codegen->zig_c_headers_dir);
- if ((err = parse_h_file(ira->codegen, &root_node, &errors_ptr, &errors_len,
- &clang_argv.at(0), &clang_argv.last(), TranslateModeImport, resources_path)))
+ if ((err = stage2_translate_c(&ast, &errors_ptr, &errors_len,
+ &clang_argv.at(0), &clang_argv.last(), resources_path)))
{
if (err != ErrorCCompileErrors) {
ir_add_error_node(ira, node, buf_sprintf("C import failed: %s", err_str(err)));
@@ -23813,7 +23812,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
buf_sprintf("C import failed: unable to open output file: %s", strerror(errno)));
return ira->codegen->invalid_instruction;
}
- ast_render(out_file, root_node, 4);
+ stage2_render_ast(ast, out_file);
if (fclose(out_file) != 0) {
ir_add_error_node(ira, node,
buf_sprintf("C import failed: unable to write to output file: %s", strerror(errno)));
src/main.cpp
@@ -243,7 +243,6 @@ enum Cmd {
CmdTargets,
CmdTest,
CmdTranslateC,
- CmdTranslateCUserland,
CmdVersion,
CmdZen,
CmdLibC,
@@ -960,8 +959,6 @@ int main(int argc, char **argv) {
cmd = CmdLibC;
} else if (strcmp(arg, "translate-c") == 0) {
cmd = CmdTranslateC;
- } else if (strcmp(arg, "translate-c-2") == 0) {
- cmd = CmdTranslateCUserland;
} else if (strcmp(arg, "test") == 0) {
cmd = CmdTest;
out_type = OutTypeExe;
@@ -978,7 +975,6 @@ int main(int argc, char **argv) {
case CmdBuild:
case CmdRun:
case CmdTranslateC:
- case CmdTranslateCUserland:
case CmdTest:
case CmdLibC:
if (!in_file) {
@@ -1112,7 +1108,6 @@ int main(int argc, char **argv) {
case CmdRun:
case CmdBuild:
case CmdTranslateC:
- case CmdTranslateCUserland:
case CmdTest:
{
if (cmd == CmdBuild && !in_file && objects.length == 0 &&
@@ -1124,7 +1119,7 @@ int main(int argc, char **argv) {
" * --object argument\n"
" * --c-source argument\n");
return print_error_usage(arg0);
- } else if ((cmd == CmdTranslateC || cmd == CmdTranslateCUserland ||
+ } else if ((cmd == CmdTranslateC ||
cmd == CmdTest || cmd == CmdRun) && !in_file)
{
fprintf(stderr, "Expected source file argument.\n");
@@ -1136,7 +1131,7 @@ int main(int argc, char **argv) {
assert(cmd != CmdBuild || out_type != OutTypeUnknown);
- bool need_name = (cmd == CmdBuild || cmd == CmdTranslateC || cmd == CmdTranslateCUserland);
+ bool need_name = (cmd == CmdBuild || cmd == CmdTranslateC);
if (cmd == CmdRun) {
out_name = "run";
@@ -1170,8 +1165,7 @@ int main(int argc, char **argv) {
return print_error_usage(arg0);
}
- Buf *zig_root_source_file = (cmd == CmdTranslateC || cmd == CmdTranslateCUserland) ?
- nullptr : in_file_buf;
+ Buf *zig_root_source_file = cmd == CmdTranslateC ? nullptr : in_file_buf;
if (cmd == CmdRun && buf_out_name == nullptr) {
buf_out_name = buf_create_from_str("run");
@@ -1336,8 +1330,8 @@ int main(int argc, char **argv) {
} else {
zig_unreachable();
}
- } else if (cmd == CmdTranslateC || cmd == CmdTranslateCUserland) {
- codegen_translate_c(g, in_file_buf, stdout, cmd == CmdTranslateCUserland);
+ } else if (cmd == CmdTranslateC) {
+ codegen_translate_c(g, in_file_buf, stdout);
if (timing_info)
codegen_print_timing_report(g, stderr);
return main_exit(root_progress_node, EXIT_SUCCESS);
src/translate_c.cpp
@@ -1,5156 +0,0 @@
-/*
- * Copyright (c) 2015 Andrew Kelley
- *
- * This file is part of zig, which is MIT licensed.
- * See http://opensource.org/licenses/MIT
- */
-#include "all_types.hpp"
-#include "analyze.hpp"
-#include "c_tokenizer.hpp"
-#include "error.hpp"
-#include "ir.hpp"
-#include "os.hpp"
-#include "translate_c.hpp"
-#include "parser.hpp"
-#include "zig_clang.h"
-
-#include <string.h>
-
-struct Alias {
- Buf *new_name;
- Buf *canon_name;
-};
-
-enum TransScopeId {
- TransScopeIdSwitch,
- TransScopeIdVar,
- TransScopeIdBlock,
- TransScopeIdRoot,
- TransScopeIdWhile,
-};
-
-struct TransScope {
- TransScopeId id;
- TransScope *parent;
-};
-
-struct TransScopeSwitch {
- TransScope base;
- AstNode *switch_node;
- uint32_t case_index;
- bool found_default;
- Buf *end_label_name;
-};
-
-struct TransScopeVar {
- TransScope base;
- Buf *c_name;
- Buf *zig_name;
-};
-
-struct TransScopeBlock {
- TransScope base;
- AstNode *node;
-};
-
-struct TransScopeRoot {
- TransScope base;
-};
-
-struct TransScopeWhile {
- TransScope base;
- AstNode *node;
-};
-
-struct Context {
- AstNode *root;
- bool want_export;
- HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table;
- HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table;
- HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> global_table;
- ZigClangSourceManager *source_manager;
- ZigList<Alias> aliases;
- bool warnings_on;
-
- CodeGen *codegen;
- ZigClangASTContext *ctx;
-
- TransScopeRoot *global_scope;
- HashMap<Buf *, bool, buf_hash, buf_eql_buf> ptr_params;
-};
-
-enum ResultUsed {
- ResultUsedNo,
- ResultUsedYes,
-};
-
-enum TransLRValue {
- TransLValue,
- TransRValue,
-};
-
-static TransScopeRoot *trans_scope_root_create(Context *c);
-static TransScopeWhile *trans_scope_while_create(Context *c, TransScope *parent_scope);
-static TransScopeBlock *trans_scope_block_create(Context *c, TransScope *parent_scope);
-static TransScopeVar *trans_scope_var_create(Context *c, TransScope *parent_scope, Buf *wanted_name);
-static TransScopeSwitch *trans_scope_switch_create(Context *c, TransScope *parent_scope);
-
-static TransScopeBlock *trans_scope_block_find(TransScope *scope);
-
-static AstNode *resolve_record_decl(Context *c, const ZigClangRecordDecl *record_decl);
-static AstNode *resolve_enum_decl(Context *c, const ZigClangEnumDecl *enum_decl);
-static AstNode *resolve_typedef_decl(Context *c, const ZigClangTypedefNameDecl *typedef_decl);
-
-static int trans_stmt_extra(Context *c, TransScope *scope, const ZigClangStmt *stmt,
- ResultUsed result_used, TransLRValue lrval,
- AstNode **out_node, TransScope **out_child_scope,
- TransScope **out_node_scope);
-static TransScope *trans_stmt(Context *c, TransScope *scope, const ZigClangStmt *stmt, AstNode **out_node);
-static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const ZigClangExpr *expr, TransLRValue lrval);
-static AstNode *trans_type(Context *c, const ZigClangType *ty, ZigClangSourceLocation source_loc);
-static AstNode *trans_qual_type(Context *c, ZigClangQualType qt, ZigClangSourceLocation source_loc);
-static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *scope,
- const ZigClangExpr *expr, TransLRValue lrval);
-static AstNode *trans_ap_value(Context *c, const ZigClangAPValue *ap_value, ZigClangQualType qt,
- ZigClangSourceLocation source_loc);
-static bool c_is_unsigned_integer(Context *c, ZigClangQualType qt);
-
-
-ATTRIBUTE_PRINTF(3, 4)
-static void emit_warning(Context *c, ZigClangSourceLocation sl, const char *format, ...) {
- if (!c->warnings_on) {
- return;
- }
-
- va_list ap;
- va_start(ap, format);
- Buf *msg = buf_vprintf(format, ap);
- va_end(ap);
-
- const char *filename_bytes = ZigClangSourceManager_getFilename(c->source_manager,
- ZigClangSourceManager_getSpellingLoc(c->source_manager, sl));
- Buf *path;
- if (filename_bytes) {
- path = buf_create_from_str(filename_bytes);
- } else {
- path = buf_sprintf("(no file)");
- }
- unsigned line = ZigClangSourceManager_getSpellingLineNumber(c->source_manager, sl);
- unsigned column = ZigClangSourceManager_getSpellingColumnNumber(c->source_manager, sl);
- fprintf(stderr, "%s:%u:%u: warning: %s\n", buf_ptr(path), line, column, buf_ptr(msg));
-}
-
-static void add_global_weak_alias(Context *c, Buf *new_name, Buf *canon_name) {
- Alias *alias = c->aliases.add_one();
- alias->new_name = new_name;
- alias->canon_name = canon_name;
-}
-
-static Buf *trans_lookup_zig_symbol(Context *c, TransScope *scope, Buf *c_symbol_name) {
- while (scope != nullptr) {
- if (scope->id == TransScopeIdVar) {
- TransScopeVar *var_scope = (TransScopeVar *)scope;
- if (buf_eql_buf(var_scope->c_name, c_symbol_name)) {
- return var_scope->zig_name;
- }
- }
- scope = scope->parent;
- }
- return c_symbol_name;
-}
-
-static AstNode * trans_create_node(Context *c, NodeType id) {
- AstNode *node = allocate<AstNode>(1);
- node->type = id;
- // TODO line/column. mapping to C file??
- return node;
-}
-
-static AstNode *trans_create_node_break(Context *c, Buf *label_name, AstNode *value_node) {
- AstNode *node = trans_create_node(c, NodeTypeBreak);
- node->data.break_expr.name = label_name;
- node->data.break_expr.expr = value_node;
- return node;
-}
-
-static AstNode *trans_create_node_return(Context *c, AstNode *value_node) {
- AstNode *node = trans_create_node(c, NodeTypeReturnExpr);
- node->data.return_expr.kind = ReturnKindUnconditional;
- node->data.return_expr.expr = value_node;
- return node;
-}
-
-static AstNode *trans_create_node_if(Context *c, AstNode *cond_node, AstNode *then_node, AstNode *else_node) {
- AstNode *node = trans_create_node(c, NodeTypeIfBoolExpr);
- node->data.if_bool_expr.condition = cond_node;
- node->data.if_bool_expr.then_block = then_node;
- node->data.if_bool_expr.else_node = else_node;
- return node;
-}
-
-static AstNode *trans_create_node_float_lit(Context *c, double value) {
- AstNode *node = trans_create_node(c, NodeTypeFloatLiteral);
- node->data.float_literal.bigfloat = allocate<BigFloat>(1);
- bigfloat_init_64(node->data.float_literal.bigfloat, value);
- return node;
-}
-
-static AstNode *trans_create_node_symbol(Context *c, Buf *name) {
- AstNode *node = trans_create_node(c, NodeTypeSymbol);
- node->data.symbol_expr.symbol = name;
- return node;
-}
-
-static AstNode *trans_create_node_symbol_str(Context *c, const char *name) {
- return trans_create_node_symbol(c, buf_create_from_str(name));
-}
-
-static AstNode *trans_create_node_builtin_fn_call(Context *c, Buf *name) {
- AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
- node->data.fn_call_expr.fn_ref_expr = trans_create_node_symbol(c, name);
- node->data.fn_call_expr.modifier = CallModifierBuiltin;
- return node;
-}
-
-static AstNode *trans_create_node_builtin_fn_call_str(Context *c, const char *name) {
- return trans_create_node_builtin_fn_call(c, buf_create_from_str(name));
-}
-
-static AstNode *trans_create_node_opaque(Context *c) {
- return trans_create_node_builtin_fn_call_str(c, "OpaqueType");
-}
-
-static AstNode *trans_create_node_cast(Context *c, AstNode *dest_type, AstNode *operand) {
- AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
- node->data.fn_call_expr.fn_ref_expr = trans_create_node_symbol(c, buf_create_from_str("as"));
- node->data.fn_call_expr.modifier = CallModifierBuiltin;
- node->data.fn_call_expr.params.append(dest_type);
- node->data.fn_call_expr.params.append(operand);
- return node;
-}
-
-static AstNode *trans_create_node_fn_call_1(Context *c, AstNode *fn_ref_expr, AstNode *arg1) {
- AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
- node->data.fn_call_expr.fn_ref_expr = fn_ref_expr;
- node->data.fn_call_expr.params.append(arg1);
- return node;
-}
-
-static AstNode *trans_create_node_field_access(Context *c, AstNode *container, Buf *field_name) {
- AstNode *node = trans_create_node(c, NodeTypeFieldAccessExpr);
- if (container->type == NodeTypeSymbol) {
- assert(container->data.symbol_expr.symbol != nullptr);
- }
- node->data.field_access_expr.struct_expr = container;
- node->data.field_access_expr.field_name = field_name;
- return node;
-}
-
-static AstNode *trans_create_node_field_access_str(Context *c, AstNode *container, const char *field_name) {
- return trans_create_node_field_access(c, container, buf_create_from_str(field_name));
-}
-
-static AstNode *trans_create_node_ptr_deref(Context *c, AstNode *child_node) {
- AstNode *node = trans_create_node(c, NodeTypePtrDeref);
- node->data.ptr_deref_expr.target = child_node;
- return node;
-}
-
-static AstNode *trans_create_node_prefix_op(Context *c, PrefixOp op, AstNode *child_node) {
- AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);
- node->data.prefix_op_expr.prefix_op = op;
- node->data.prefix_op_expr.primary_expr = child_node;
- return node;
-}
-
-static AstNode *trans_create_node_unwrap_null(Context *c, AstNode *child_node) {
- AstNode *node = trans_create_node(c, NodeTypeUnwrapOptional);
- node->data.unwrap_optional.expr = child_node;
- return node;
-}
-
-static AstNode *trans_create_node_bin_op(Context *c, AstNode *lhs_node, BinOpType op, AstNode *rhs_node) {
- AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
- node->data.bin_op_expr.op1 = lhs_node;
- node->data.bin_op_expr.bin_op = op;
- node->data.bin_op_expr.op2 = rhs_node;
- return node;
-}
-
-static AstNode *maybe_suppress_result(Context *c, ResultUsed result_used, AstNode *node) {
- if (result_used == ResultUsedYes) return node;
- return trans_create_node_bin_op(c,
- trans_create_node_symbol_str(c, "_"),
- BinOpTypeAssign,
- node);
-}
-
-static TokenId ptr_len_to_token_id(PtrLen ptr_len) {
- switch (ptr_len) {
- case PtrLenSingle:
- return TokenIdStar;
- case PtrLenUnknown:
- return TokenIdLBracket;
- case PtrLenC:
- return TokenIdSymbol;
- }
- zig_unreachable();
-}
-
-static AstNode *trans_create_node_ptr_type(Context *c, bool is_const, bool is_volatile, AstNode *child_node, PtrLen ptr_len) {
- AstNode *node = trans_create_node(c, NodeTypePointerType);
- node->data.pointer_type.star_token = allocate<ZigToken>(1);
- node->data.pointer_type.star_token->id = ptr_len_to_token_id(ptr_len);
- node->data.pointer_type.is_const = is_const;
- node->data.pointer_type.is_volatile = is_volatile;
- node->data.pointer_type.op_expr = child_node;
- return node;
-}
-
-static AstNode *trans_create_node_addr_of(Context *c, AstNode *child_node) {
- AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);
- node->data.prefix_op_expr.prefix_op = PrefixOpAddrOf;
- node->data.prefix_op_expr.primary_expr = child_node;
- return node;
-}
-
-static AstNode *trans_create_node_bool(Context *c, bool value) {
- AstNode *bool_node = trans_create_node(c, NodeTypeBoolLiteral);
- bool_node->data.bool_literal.value = value;
- return bool_node;
-}
-
-static AstNode *trans_create_node_str_lit(Context *c, Buf *buf) {
- AstNode *node = trans_create_node(c, NodeTypeStringLiteral);
- node->data.string_literal.buf = buf;
- return node;
-}
-
-static AstNode *trans_create_node_unsigned_negative(Context *c, uint64_t x, bool is_negative) {
- AstNode *node = trans_create_node(c, NodeTypeIntLiteral);
- node->data.int_literal.bigint = allocate<BigInt>(1);
- bigint_init_data(node->data.int_literal.bigint, &x, 1, is_negative);
- return node;
-}
-
-static AstNode *trans_create_node_unsigned(Context *c, uint64_t x) {
- return trans_create_node_unsigned_negative(c, x, false);
-}
-
-static AstNode *trans_create_node_unsigned_negative_type(Context *c, uint64_t x, bool is_negative,
- const char *type_name)
-{
- AstNode *lit_node = trans_create_node_unsigned_negative(c, x, is_negative);
- return trans_create_node_cast(c, trans_create_node_symbol_str(c, type_name), lit_node);
-}
-
-static AstNode *trans_create_node_array_type(Context *c, AstNode *size_node, AstNode *child_type_node) {
- AstNode *node = trans_create_node(c, NodeTypeArrayType);
- node->data.array_type.size = size_node;
- node->data.array_type.child_type = child_type_node;
- return node;
-}
-
-static AstNode *trans_create_node_var_decl(Context *c, VisibMod visib_mod, bool is_const, Buf *var_name,
- AstNode *type_node, AstNode *init_node)
-{
- AstNode *node = trans_create_node(c, NodeTypeVariableDeclaration);
- node->data.variable_declaration.visib_mod = visib_mod;
- node->data.variable_declaration.symbol = var_name;
- node->data.variable_declaration.is_const = is_const;
- node->data.variable_declaration.type = type_node;
- node->data.variable_declaration.expr = init_node;
- return node;
-}
-
-static AstNode *trans_create_node_var_decl_global(Context *c, bool is_const, Buf *var_name, AstNode *type_node,
- AstNode *init_node)
-{
- return trans_create_node_var_decl(c, VisibModPub, is_const, var_name, type_node, init_node);
-}
-
-static AstNode *trans_create_node_var_decl_local(Context *c, bool is_const, Buf *var_name, AstNode *type_node,
- AstNode *init_node)
-{
- return trans_create_node_var_decl(c, VisibModPrivate, is_const, var_name, type_node, init_node);
-}
-
-static AstNode *trans_create_node_inline_fn(Context *c, Buf *fn_name, AstNode *ref_node, AstNode *src_proto_node) {
- AstNode *fn_def = trans_create_node(c, NodeTypeFnDef);
- AstNode *fn_proto = trans_create_node(c, NodeTypeFnProto);
- fn_proto->data.fn_proto.visib_mod = VisibModPub;
- fn_proto->data.fn_proto.name = fn_name;
- fn_proto->data.fn_proto.fn_inline = FnInlineAlways;
- fn_proto->data.fn_proto.return_type = src_proto_node->data.fn_proto.return_type; // TODO ok for these to alias?
-
- fn_def->data.fn_def.fn_proto = fn_proto;
- fn_proto->data.fn_proto.fn_def_node = fn_def;
-
- AstNode *unwrap_node = trans_create_node_unwrap_null(c, ref_node);
- AstNode *fn_call_node = trans_create_node(c, NodeTypeFnCallExpr);
- fn_call_node->data.fn_call_expr.fn_ref_expr = unwrap_node;
-
- for (size_t i = 0; i < src_proto_node->data.fn_proto.params.length; i += 1) {
- AstNode *src_param_node = src_proto_node->data.fn_proto.params.at(i);
- Buf *param_name = src_param_node->data.param_decl.name;
- if (!param_name) param_name = buf_sprintf("arg%" ZIG_PRI_usize "", i);
-
- AstNode *dest_param_node = trans_create_node(c, NodeTypeParamDecl);
- dest_param_node->data.param_decl.name = param_name;
- dest_param_node->data.param_decl.type = src_param_node->data.param_decl.type;
- dest_param_node->data.param_decl.is_noalias = src_param_node->data.param_decl.is_noalias;
- fn_proto->data.fn_proto.params.append(dest_param_node);
-
- fn_call_node->data.fn_call_expr.params.append(trans_create_node_symbol(c, param_name));
-
- }
-
- AstNode *block = trans_create_node(c, NodeTypeBlock);
- block->data.block.statements.resize(1);
- block->data.block.statements.items[0] = trans_create_node_return(c, fn_call_node);
-
- fn_def->data.fn_def.body = block;
- return fn_def;
-}
-
-static AstNode *trans_create_node_grouped_expr(Context *c, AstNode *child) {
- AstNode *node = trans_create_node(c, NodeTypeGroupedExpr);
- node->data.grouped_expr = child;
- return node;
-}
-
-static AstNode *get_global(Context *c, Buf *name) {
- {
- auto entry = c->global_table.maybe_get(name);
- if (entry) {
- return entry->value;
- }
- }
- {
- auto entry = c->macro_table.maybe_get(name);
- if (entry)
- return entry->value;
- }
- ZigType *type;
- if (get_primitive_type(c->codegen, name, &type) != ErrorPrimitiveTypeNotFound) {
- return trans_create_node_symbol(c, name);
- }
- return nullptr;
-}
-
-static void add_top_level_decl(Context *c, Buf *name, AstNode *node) {
- c->global_table.put(name, node);
- c->root->data.container_decl.decls.append(node);
-}
-
-static AstNode *add_global_var(Context *c, Buf *var_name, AstNode *value_node) {
- bool is_const = true;
- AstNode *type_node = nullptr;
- AstNode *node = trans_create_node_var_decl_global(c, is_const, var_name, type_node, value_node);
- add_top_level_decl(c, var_name, node);
- return node;
-}
-
-static AstNode *trans_create_node_apint(Context *c, const ZigClangAPSInt *aps_int) {
- AstNode *node = trans_create_node(c, NodeTypeIntLiteral);
- node->data.int_literal.bigint = allocate<BigInt>(1);
- bool is_negative = ZigClangAPSInt_isSigned(aps_int) && ZigClangAPSInt_isNegative(aps_int);
- if (!is_negative) {
- bigint_init_data(node->data.int_literal.bigint,
- ZigClangAPSInt_getRawData(aps_int),
- ZigClangAPSInt_getNumWords(aps_int),
- false);
- return node;
- }
- const ZigClangAPSInt *negated = ZigClangAPSInt_negate(aps_int);
- bigint_init_data(node->data.int_literal.bigint, ZigClangAPSInt_getRawData(negated),
- ZigClangAPSInt_getNumWords(negated), true);
- ZigClangAPSInt_free(negated);
- return node;
-}
-
-static AstNode *trans_create_node_apfloat(Context *c, const ZigClangAPFloat *ap_float) {
- uint8_t buf[128];
- size_t written = ZigClangAPFloat_convertToHexString(ap_float, (char *)buf, 0, false,
- ZigClangAPFloat_roundingMode_NearestTiesToEven);
- AstNode *node = trans_create_node(c, NodeTypeFloatLiteral);
- node->data.float_literal.bigfloat = allocate<BigFloat>(1);
- if (bigfloat_init_buf(node->data.float_literal.bigfloat, buf, written)) {
- node->data.float_literal.overflow = true;
- }
- return node;
-}
-
-static const ZigClangType *qual_type_canon(ZigClangQualType qt) {
- ZigClangQualType canon = ZigClangQualType_getCanonicalType(qt);
- return ZigClangQualType_getTypePtr(canon);
-}
-
-static ZigClangQualType get_expr_qual_type(Context *c, const ZigClangExpr *expr) {
- // String literals in C are `char *` but they should really be `const char *`.
- if (ZigClangExpr_getStmtClass(expr) == ZigClangStmt_ImplicitCastExprClass) {
- const ZigClangImplicitCastExpr *cast_expr = reinterpret_cast<const ZigClangImplicitCastExpr *>(expr);
- if (ZigClangImplicitCastExpr_getCastKind(cast_expr) == ZigClangCK_ArrayToPointerDecay) {
- const ZigClangExpr *sub_expr = ZigClangImplicitCastExpr_getSubExpr(cast_expr);
- if (ZigClangExpr_getStmtClass(sub_expr) == ZigClangStmt_StringLiteralClass) {
- ZigClangQualType array_qt = ZigClangExpr_getType(sub_expr);
- const ZigClangArrayType *array_type = reinterpret_cast<const ZigClangArrayType *>(
- ZigClangQualType_getTypePtr(array_qt));
- ZigClangQualType pointee_qt = ZigClangArrayType_getElementType(array_type);
- ZigClangQualType_addConst(&pointee_qt);
- return ZigClangASTContext_getPointerType(c->ctx, pointee_qt);
- }
- }
- }
- return ZigClangExpr_getType(expr);
-}
-
-static ZigClangQualType get_expr_qual_type_before_implicit_cast(Context *c, const ZigClangExpr *expr) {
- if (ZigClangExpr_getStmtClass(expr) == ZigClangStmt_ImplicitCastExprClass) {
- const ZigClangImplicitCastExpr *cast_expr = reinterpret_cast<const ZigClangImplicitCastExpr *>(expr);
- return get_expr_qual_type(c, ZigClangImplicitCastExpr_getSubExpr(cast_expr));
- }
- return ZigClangExpr_getType(expr);
-}
-
-static AstNode *get_expr_type(Context *c, const ZigClangExpr *expr) {
- return trans_qual_type(c, get_expr_qual_type(c, expr), ZigClangExpr_getBeginLoc(expr));
-}
-
-static bool is_c_void_type(AstNode *node) {
- return (node->type == NodeTypeSymbol && buf_eql_str(node->data.symbol_expr.symbol, "c_void"));
-}
-
-static bool qual_type_is_ptr(ZigClangQualType qt) {
- const ZigClangType *ty = qual_type_canon(qt);
- return ZigClangType_getTypeClass(ty) == ZigClangType_Pointer;
-}
-
-static const ZigClangFunctionProtoType *qual_type_get_fn_proto(ZigClangQualType qt, bool *is_ptr) {
- const ZigClangType *ty = qual_type_canon(qt);
- *is_ptr = false;
-
- if (ZigClangType_getTypeClass(ty) == ZigClangType_Pointer) {
- *is_ptr = true;
- ZigClangQualType child_qt = ZigClangType_getPointeeType(ty);
- ty = ZigClangQualType_getTypePtr(child_qt);
- }
-
- if (ZigClangType_getTypeClass(ty) == ZigClangType_FunctionProto) {
- return reinterpret_cast<const ZigClangFunctionProtoType*>(ty);
- }
-
- return nullptr;
-}
-
-static bool qual_type_is_fn_ptr(ZigClangQualType qt) {
- bool is_ptr;
- if (qual_type_get_fn_proto(qt, &is_ptr)) {
- return is_ptr;
- }
-
- return false;
-}
-
-static uint32_t qual_type_int_bit_width(Context *c, const ZigClangQualType qt, ZigClangSourceLocation source_loc) {
- const ZigClangType *ty = ZigClangQualType_getTypePtr(qt);
- switch (ZigClangType_getTypeClass(ty)) {
- case ZigClangType_Builtin:
- {
- const ZigClangBuiltinType *builtin_ty = reinterpret_cast<const ZigClangBuiltinType*>(ty);
- switch (ZigClangBuiltinType_getKind(builtin_ty)) {
- case ZigClangBuiltinTypeChar_U:
- case ZigClangBuiltinTypeUChar:
- case ZigClangBuiltinTypeChar_S:
- case ZigClangBuiltinTypeSChar:
- return 8;
- case ZigClangBuiltinTypeUInt128:
- case ZigClangBuiltinTypeInt128:
- return 128;
- default:
- return 0;
- }
- zig_unreachable();
- }
- case ZigClangType_Typedef:
- {
- const ZigClangTypedefType *typedef_ty = reinterpret_cast<const ZigClangTypedefType*>(ty);
- const ZigClangTypedefNameDecl *typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
- const char *type_name = ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)typedef_decl);
- if (strcmp(type_name, "uint8_t") == 0 || strcmp(type_name, "int8_t") == 0) {
- return 8;
- } else if (strcmp(type_name, "uint16_t") == 0 || strcmp(type_name, "int16_t") == 0) {
- return 16;
- } else if (strcmp(type_name, "uint32_t") == 0 || strcmp(type_name, "int32_t") == 0) {
- return 32;
- } else if (strcmp(type_name, "uint64_t") == 0 || strcmp(type_name, "int64_t") == 0) {
- return 64;
- } else {
- return 0;
- }
- }
- default:
- return 0;
- }
- zig_unreachable();
-}
-
-
-static AstNode *qual_type_to_log2_int_ref(Context *c, const ZigClangQualType qt,
- ZigClangSourceLocation source_loc)
-{
- uint32_t int_bit_width = qual_type_int_bit_width(c, qt, source_loc);
- if (int_bit_width != 0) {
- // we can perform the log2 now.
- uint64_t cast_bit_width = log2_u64(int_bit_width);
- return trans_create_node_symbol(c, buf_sprintf("u%" ZIG_PRI_u64, cast_bit_width));
- }
-
- AstNode *zig_type_node = trans_qual_type(c, qt, source_loc);
-
-// @import("std").math.Log2Int(c_long);
-//
-// FnCall
-// FieldAccess
-// FieldAccess
-// FnCall (.builtin = true)
-// Symbol "import"
-// ZigClangStringLiteral "std"
-// Symbol "math"
-// Symbol "Log2Int"
-// zig_type_node
-
- AstNode *import_fn_call = trans_create_node_builtin_fn_call_str(c, "import");
- import_fn_call->data.fn_call_expr.params.append(trans_create_node_str_lit(c, buf_create_from_str("std")));
- AstNode *inner_field_access = trans_create_node_field_access_str(c, import_fn_call, "math");
- AstNode *outer_field_access = trans_create_node_field_access_str(c, inner_field_access, "Log2Int");
- AstNode *log2int_fn_call = trans_create_node_fn_call_1(c, outer_field_access, zig_type_node);
-
- return log2int_fn_call;
-}
-
-static bool qual_type_child_is_fn_proto(ZigClangQualType qt) {
- const ZigClangType *ty = ZigClangQualType_getTypePtr(qt);
- if (ZigClangType_getTypeClass(ty) == ZigClangType_Paren) {
- const ZigClangParenType *paren_type = reinterpret_cast<const ZigClangParenType *>(ty);
- ZigClangQualType inner_type = ZigClangParenType_getInnerType(paren_type);
- if (ZigClangQualType_getTypeClass(inner_type) == ZigClangType_FunctionProto) {
- return true;
- }
- } else if (ZigClangType_getTypeClass(ty) == ZigClangType_Attributed) {
- const ZigClangAttributedType *attr_type = reinterpret_cast<const ZigClangAttributedType *>(ty);
- return qual_type_child_is_fn_proto(ZigClangAttributedType_getEquivalentType(attr_type));
- }
- return false;
-}
-
-static AstNode* trans_c_ptr_cast(Context *c, ZigClangSourceLocation source_location, ZigClangQualType dest_type,
- ZigClangQualType src_type, AstNode *expr)
-{
- const ZigClangType *ty = ZigClangQualType_getTypePtr(dest_type);
- const ZigClangQualType child_type = ZigClangType_getPointeeType(ty);
-
- AstNode *dest_type_node = trans_type(c, ty, source_location);
- AstNode *child_type_node = trans_qual_type(c, child_type, source_location);
-
- // Implicit downcasting from higher to lower alignment values is forbidden,
- // use @alignCast to side-step this problem
- AstNode *ptrcast_node = trans_create_node_builtin_fn_call_str(c, "ptrCast");
- ptrcast_node->data.fn_call_expr.params.append(dest_type_node);
-
- if (ZigClangType_isVoidType(qual_type_canon(child_type))) {
- // void has 1-byte alignment
- ptrcast_node->data.fn_call_expr.params.append(expr);
- } else {
- AstNode *alignof_node = trans_create_node_builtin_fn_call_str(c, "alignOf");
- alignof_node->data.fn_call_expr.params.append(child_type_node);
- AstNode *aligncast_node = trans_create_node_builtin_fn_call_str(c, "alignCast");
- aligncast_node->data.fn_call_expr.params.append(alignof_node);
- aligncast_node->data.fn_call_expr.params.append(expr);
-
- ptrcast_node->data.fn_call_expr.params.append(aligncast_node);
- }
-
- return ptrcast_node;
-}
-
-static AstNode* trans_c_cast(Context *c, ZigClangSourceLocation source_location, ZigClangQualType dest_type,
- ZigClangQualType src_type, AstNode *expr)
-{
- // The only way void pointer casts are valid C code, is if
- // the value of the expression is ignored. We therefore just
- // return the expr, and let the system that ignores values
- // translate this correctly.
- if (ZigClangType_isVoidType(qual_type_canon(dest_type))) {
- return expr;
- }
- if (ZigClangQualType_eq(dest_type, src_type)) {
- return expr;
- }
- if (qual_type_is_ptr(dest_type) && qual_type_is_ptr(src_type)) {
- return trans_c_ptr_cast(c, source_location, dest_type, src_type, expr);
- }
- if (c_is_unsigned_integer(c, dest_type) && qual_type_is_ptr(src_type)) {
- AstNode *addr_node = trans_create_node_builtin_fn_call_str(c, "ptrToInt");
- addr_node->data.fn_call_expr.params.append(expr);
- return trans_create_node_cast(c, trans_qual_type(c, dest_type, source_location), addr_node);
- }
- if (c_is_unsigned_integer(c, src_type) && qual_type_is_ptr(dest_type)) {
- AstNode *ptr_node = trans_create_node_builtin_fn_call_str(c, "intToPtr");
- ptr_node->data.fn_call_expr.params.append(trans_qual_type(c, dest_type, source_location));
- ptr_node->data.fn_call_expr.params.append(expr);
- return ptr_node;
- }
- // TODO: maybe widen to increase size
- // TODO: maybe bitcast to change sign
- // TODO: maybe truncate to reduce size
- return trans_create_node_cast(c, trans_qual_type(c, dest_type, source_location), expr);
-}
-
-static bool c_is_signed_integer(Context *c, ZigClangQualType qt) {
- const ZigClangType *c_type = qual_type_canon(qt);
- if (ZigClangType_getTypeClass(c_type) != ZigClangType_Builtin)
- return false;
- const ZigClangBuiltinType *builtin_ty = reinterpret_cast<const ZigClangBuiltinType*>(c_type);
- switch (ZigClangBuiltinType_getKind(builtin_ty)) {
- case ZigClangBuiltinTypeSChar:
- case ZigClangBuiltinTypeShort:
- case ZigClangBuiltinTypeInt:
- case ZigClangBuiltinTypeLong:
- case ZigClangBuiltinTypeLongLong:
- case ZigClangBuiltinTypeInt128:
- case ZigClangBuiltinTypeWChar_S:
- return true;
- default:
- return false;
- }
-}
-
-static bool c_is_unsigned_integer(Context *c, ZigClangQualType qt) {
- const ZigClangType *c_type = qual_type_canon(qt);
- if (ZigClangType_getTypeClass(c_type) != ZigClangType_Builtin)
- return false;
- const ZigClangBuiltinType *builtin_ty = reinterpret_cast<const ZigClangBuiltinType*>(c_type);
- switch (ZigClangBuiltinType_getKind(builtin_ty)) {
- case ZigClangBuiltinTypeChar_U:
- case ZigClangBuiltinTypeUChar:
- case ZigClangBuiltinTypeChar_S:
- case ZigClangBuiltinTypeUShort:
- case ZigClangBuiltinTypeUInt:
- case ZigClangBuiltinTypeULong:
- case ZigClangBuiltinTypeULongLong:
- case ZigClangBuiltinTypeUInt128:
- case ZigClangBuiltinTypeWChar_U:
- return true;
- default:
- return false;
- }
-}
-
-static bool c_is_builtin_type(Context *c, ZigClangQualType qt, ZigClangBuiltinTypeKind kind) {
- const ZigClangType *c_type = qual_type_canon(qt);
- if (ZigClangType_getTypeClass(c_type) != ZigClangType_Builtin)
- return false;
- const ZigClangBuiltinType *builtin_ty = reinterpret_cast<const ZigClangBuiltinType*>(c_type);
- return ZigClangBuiltinType_getKind(builtin_ty) == kind;
-}
-
-static bool c_is_float(Context *c, ZigClangQualType qt) {
- const ZigClangType *c_type = ZigClangQualType_getTypePtr(qt);
- if (ZigClangType_getTypeClass(c_type) != ZigClangType_Builtin)
- return false;
- const ZigClangBuiltinType *builtin_ty = reinterpret_cast<const ZigClangBuiltinType*>(c_type);
- switch (ZigClangBuiltinType_getKind(builtin_ty)) {
- case ZigClangBuiltinTypeHalf:
- case ZigClangBuiltinTypeFloat:
- case ZigClangBuiltinTypeDouble:
- case ZigClangBuiltinTypeFloat128:
- case ZigClangBuiltinTypeLongDouble:
- return true;
- default:
- return false;
- }
-}
-
-static bool qual_type_has_wrapping_overflow(Context *c, ZigClangQualType qt) {
- if (c_is_signed_integer(c, qt) || c_is_float(c, qt)) {
- // float and signed integer overflow is undefined behavior.
- return false;
- } else {
- // unsigned integer overflow wraps around.
- return true;
- }
-}
-
-static bool type_is_function(Context *c, const ZigClangType *ty, ZigClangSourceLocation source_loc) {
- switch (ZigClangType_getTypeClass(ty)) {
- case ZigClangType_FunctionProto:
- case ZigClangType_FunctionNoProto:
- return true;
- case ZigClangType_Elaborated: {
- const ZigClangElaboratedType *elaborated_ty = reinterpret_cast<const ZigClangElaboratedType*>(ty);
- ZigClangQualType qt = ZigClangElaboratedType_getNamedType(elaborated_ty);
- return type_is_function(c, ZigClangQualType_getTypePtr(qt), source_loc);
- }
- case ZigClangType_Typedef: {
- const ZigClangTypedefType *typedef_ty = reinterpret_cast<const ZigClangTypedefType*>(ty);
- const ZigClangTypedefNameDecl *typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
- ZigClangQualType underlying_type = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);
- return type_is_function(c, ZigClangQualType_getTypePtr(underlying_type), source_loc);
- }
- default:
- return false;
- }
-}
-
-static bool type_is_opaque(Context *c, const ZigClangType *ty, ZigClangSourceLocation source_loc) {
- switch (ZigClangType_getTypeClass(ty)) {
- case ZigClangType_Builtin: {
- const ZigClangBuiltinType *builtin_ty = reinterpret_cast<const ZigClangBuiltinType*>(ty);
- return ZigClangBuiltinType_getKind(builtin_ty) == ZigClangBuiltinTypeVoid;
- }
- case ZigClangType_Record: {
- const ZigClangRecordType *record_ty = reinterpret_cast<const ZigClangRecordType*>(ty);
- const ZigClangRecordDecl *record_decl = ZigClangRecordType_getDecl(record_ty);
- const ZigClangRecordDecl *record_def = ZigClangRecordDecl_getDefinition(record_decl);
- if (record_def == nullptr) {
- return true;
- }
- for (ZigClangRecordDecl_field_iterator it = ZigClangRecordDecl_field_begin(record_def),
- it_end = ZigClangRecordDecl_field_end(record_def);
- ZigClangRecordDecl_field_iterator_neq(it, it_end);
- it = ZigClangRecordDecl_field_iterator_next(it))
- {
- const ZigClangFieldDecl *field_decl = ZigClangRecordDecl_field_iterator_deref(it);
-
- if (ZigClangFieldDecl_isBitField(field_decl)) {
- return true;
- }
- }
- return false;
- }
- case ZigClangType_Elaborated: {
- const ZigClangElaboratedType *elaborated_ty = reinterpret_cast<const ZigClangElaboratedType*>(ty);
- ZigClangQualType qt = ZigClangElaboratedType_getNamedType(elaborated_ty);
- return type_is_opaque(c, ZigClangQualType_getTypePtr(qt), source_loc);
- }
- case ZigClangType_Typedef: {
- const ZigClangTypedefType *typedef_ty = reinterpret_cast<const ZigClangTypedefType*>(ty);
- const ZigClangTypedefNameDecl *typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
- ZigClangQualType underlying_type = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);
- return type_is_opaque(c, ZigClangQualType_getTypePtr(underlying_type), source_loc);
- }
- default:
- return false;
- }
-}
-
-static AstNode *trans_type(Context *c, const ZigClangType *ty, ZigClangSourceLocation source_loc) {
- switch (ZigClangType_getTypeClass(ty)) {
- case ZigClangType_Builtin:
- {
- const ZigClangBuiltinType *builtin_ty = reinterpret_cast<const ZigClangBuiltinType *>(ty);
- switch (ZigClangBuiltinType_getKind(builtin_ty)) {
- case ZigClangBuiltinTypeVoid:
- return trans_create_node_symbol_str(c, "c_void");
- case ZigClangBuiltinTypeBool:
- return trans_create_node_symbol_str(c, "bool");
- case ZigClangBuiltinTypeChar_U:
- case ZigClangBuiltinTypeUChar:
- case ZigClangBuiltinTypeChar_S:
- case ZigClangBuiltinTypeChar8:
- return trans_create_node_symbol_str(c, "u8");
- case ZigClangBuiltinTypeSChar:
- return trans_create_node_symbol_str(c, "i8");
- case ZigClangBuiltinTypeUShort:
- return trans_create_node_symbol_str(c, "c_ushort");
- case ZigClangBuiltinTypeUInt:
- return trans_create_node_symbol_str(c, "c_uint");
- case ZigClangBuiltinTypeULong:
- return trans_create_node_symbol_str(c, "c_ulong");
- case ZigClangBuiltinTypeULongLong:
- return trans_create_node_symbol_str(c, "c_ulonglong");
- case ZigClangBuiltinTypeShort:
- return trans_create_node_symbol_str(c, "c_short");
- case ZigClangBuiltinTypeInt:
- return trans_create_node_symbol_str(c, "c_int");
- case ZigClangBuiltinTypeLong:
- return trans_create_node_symbol_str(c, "c_long");
- case ZigClangBuiltinTypeLongLong:
- return trans_create_node_symbol_str(c, "c_longlong");
- case ZigClangBuiltinTypeUInt128:
- return trans_create_node_symbol_str(c, "u128");
- case ZigClangBuiltinTypeInt128:
- return trans_create_node_symbol_str(c, "i128");
- case ZigClangBuiltinTypeFloat:
- return trans_create_node_symbol_str(c, "f32");
- case ZigClangBuiltinTypeDouble:
- return trans_create_node_symbol_str(c, "f64");
- case ZigClangBuiltinTypeFloat128:
- return trans_create_node_symbol_str(c, "f128");
- case ZigClangBuiltinTypeFloat16:
- return trans_create_node_symbol_str(c, "f16");
- case ZigClangBuiltinTypeLongDouble:
- return trans_create_node_symbol_str(c, "c_longdouble");
- case ZigClangBuiltinTypeWChar_U:
- case ZigClangBuiltinTypeChar16:
- case ZigClangBuiltinTypeChar32:
- case ZigClangBuiltinTypeWChar_S:
- case ZigClangBuiltinTypeHalf:
- case ZigClangBuiltinTypeNullPtr:
- case ZigClangBuiltinTypeObjCId:
- case ZigClangBuiltinTypeObjCClass:
- case ZigClangBuiltinTypeObjCSel:
- case ZigClangBuiltinTypeOMPArraySection:
- case ZigClangBuiltinTypeDependent:
- case ZigClangBuiltinTypeOverload:
- case ZigClangBuiltinTypeBoundMember:
- case ZigClangBuiltinTypePseudoObject:
- case ZigClangBuiltinTypeUnknownAny:
- case ZigClangBuiltinTypeBuiltinFn:
- case ZigClangBuiltinTypeARCUnbridgedCast:
- case ZigClangBuiltinTypeShortAccum:
- case ZigClangBuiltinTypeAccum:
- case ZigClangBuiltinTypeLongAccum:
- case ZigClangBuiltinTypeUShortAccum:
- case ZigClangBuiltinTypeUAccum:
- case ZigClangBuiltinTypeULongAccum:
-
- case ZigClangBuiltinTypeOCLImage1dRO:
- case ZigClangBuiltinTypeOCLImage1dArrayRO:
- case ZigClangBuiltinTypeOCLImage1dBufferRO:
- case ZigClangBuiltinTypeOCLImage2dRO:
- case ZigClangBuiltinTypeOCLImage2dArrayRO:
- case ZigClangBuiltinTypeOCLImage2dDepthRO:
- case ZigClangBuiltinTypeOCLImage2dArrayDepthRO:
- case ZigClangBuiltinTypeOCLImage2dMSAARO:
- case ZigClangBuiltinTypeOCLImage2dArrayMSAARO:
- case ZigClangBuiltinTypeOCLImage2dMSAADepthRO:
- case ZigClangBuiltinTypeOCLImage2dArrayMSAADepthRO:
- case ZigClangBuiltinTypeOCLImage3dRO:
- case ZigClangBuiltinTypeOCLImage1dWO:
- case ZigClangBuiltinTypeOCLImage1dArrayWO:
- case ZigClangBuiltinTypeOCLImage1dBufferWO:
- case ZigClangBuiltinTypeOCLImage2dWO:
- case ZigClangBuiltinTypeOCLImage2dArrayWO:
- case ZigClangBuiltinTypeOCLImage2dDepthWO:
- case ZigClangBuiltinTypeOCLImage2dArrayDepthWO:
- case ZigClangBuiltinTypeOCLImage2dMSAAWO:
- case ZigClangBuiltinTypeOCLImage2dArrayMSAAWO:
- case ZigClangBuiltinTypeOCLImage2dMSAADepthWO:
- case ZigClangBuiltinTypeOCLImage2dArrayMSAADepthWO:
- case ZigClangBuiltinTypeOCLImage3dWO:
- case ZigClangBuiltinTypeOCLImage1dRW:
- case ZigClangBuiltinTypeOCLImage1dArrayRW:
- case ZigClangBuiltinTypeOCLImage1dBufferRW:
- case ZigClangBuiltinTypeOCLImage2dRW:
- case ZigClangBuiltinTypeOCLImage2dArrayRW:
- case ZigClangBuiltinTypeOCLImage2dDepthRW:
- case ZigClangBuiltinTypeOCLImage2dArrayDepthRW:
- case ZigClangBuiltinTypeOCLImage2dMSAARW:
- case ZigClangBuiltinTypeOCLImage2dArrayMSAARW:
- case ZigClangBuiltinTypeOCLImage2dMSAADepthRW:
- case ZigClangBuiltinTypeOCLImage2dArrayMSAADepthRW:
- case ZigClangBuiltinTypeOCLImage3dRW:
- case ZigClangBuiltinTypeOCLSampler:
- case ZigClangBuiltinTypeOCLEvent:
- case ZigClangBuiltinTypeOCLClkEvent:
- case ZigClangBuiltinTypeOCLQueue:
- case ZigClangBuiltinTypeOCLReserveID:
- case ZigClangBuiltinTypeShortFract:
- case ZigClangBuiltinTypeFract:
- case ZigClangBuiltinTypeLongFract:
- case ZigClangBuiltinTypeUShortFract:
- case ZigClangBuiltinTypeUFract:
- case ZigClangBuiltinTypeULongFract:
- case ZigClangBuiltinTypeSatShortAccum:
- case ZigClangBuiltinTypeSatAccum:
- case ZigClangBuiltinTypeSatLongAccum:
- case ZigClangBuiltinTypeSatUShortAccum:
- case ZigClangBuiltinTypeSatUAccum:
- case ZigClangBuiltinTypeSatULongAccum:
- case ZigClangBuiltinTypeSatShortFract:
- case ZigClangBuiltinTypeSatFract:
- case ZigClangBuiltinTypeSatLongFract:
- case ZigClangBuiltinTypeSatUShortFract:
- case ZigClangBuiltinTypeSatUFract:
- case ZigClangBuiltinTypeSatULongFract:
- case ZigClangBuiltinTypeOCLIntelSubgroupAVCMcePayload:
- case ZigClangBuiltinTypeOCLIntelSubgroupAVCImePayload:
- case ZigClangBuiltinTypeOCLIntelSubgroupAVCRefPayload:
- case ZigClangBuiltinTypeOCLIntelSubgroupAVCSicPayload:
- case ZigClangBuiltinTypeOCLIntelSubgroupAVCMceResult:
- case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResult:
- case ZigClangBuiltinTypeOCLIntelSubgroupAVCRefResult:
- case ZigClangBuiltinTypeOCLIntelSubgroupAVCSicResult:
- case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResultSingleRefStreamout:
- case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResultDualRefStreamout:
- case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeSingleRefStreamin:
- case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeDualRefStreamin:
- emit_warning(c, source_loc, "unsupported builtin type");
- return nullptr;
- }
- break;
- }
- case ZigClangType_Pointer:
- {
- ZigClangQualType child_qt = ZigClangType_getPointeeType(ty);
- AstNode *child_node = trans_qual_type(c, child_qt, source_loc);
- if (child_node == nullptr) {
- emit_warning(c, source_loc, "pointer to unsupported type");
- return nullptr;
- }
-
- if (qual_type_child_is_fn_proto(child_qt)) {
- return trans_create_node_prefix_op(c, PrefixOpOptional, child_node);
- }
-
- if (type_is_function(c, ZigClangQualType_getTypePtr(child_qt), source_loc)) {
- return trans_create_node_prefix_op(c, PrefixOpOptional, child_node);
- } else if (type_is_opaque(c, ZigClangQualType_getTypePtr(child_qt), source_loc)) {
- AstNode *pointer_node = trans_create_node_ptr_type(c,
- ZigClangQualType_isConstQualified(child_qt),
- ZigClangQualType_isVolatileQualified(child_qt),
- child_node, PtrLenSingle);
- return trans_create_node_prefix_op(c, PrefixOpOptional, pointer_node);
- } else {
- return trans_create_node_ptr_type(c,
- ZigClangQualType_isConstQualified(child_qt),
- ZigClangQualType_isVolatileQualified(child_qt),
- child_node, PtrLenC);
- }
- }
- case ZigClangType_Typedef:
- {
- const ZigClangTypedefType *typedef_ty = reinterpret_cast<const ZigClangTypedefType*>(ty);
- const ZigClangTypedefNameDecl *typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
- return resolve_typedef_decl(c, typedef_decl);
- }
- case ZigClangType_Elaborated:
- {
- const ZigClangElaboratedType *elaborated_ty = reinterpret_cast<const ZigClangElaboratedType*>(ty);
- switch (ZigClangElaboratedType_getKeyword(elaborated_ty)) {
- case ZigClangETK_Struct:
- case ZigClangETK_Enum:
- case ZigClangETK_Union:
- return trans_qual_type(c, ZigClangElaboratedType_getNamedType(elaborated_ty), source_loc);
- case ZigClangETK_Interface:
- case ZigClangETK_Class:
- case ZigClangETK_Typename:
- case ZigClangETK_None:
- emit_warning(c, source_loc, "unsupported elaborated type");
- return nullptr;
- }
- }
- case ZigClangType_FunctionProto:
- case ZigClangType_FunctionNoProto:
- {
- const ZigClangFunctionType *fn_ty = reinterpret_cast<const ZigClangFunctionType*>(ty);
-
- AstNode *proto_node = trans_create_node(c, NodeTypeFnProto);
- switch (ZigClangFunctionType_getCallConv(fn_ty)) {
- case ZigClangCallingConv_C: // __attribute__((cdecl))
- proto_node->data.fn_proto.cc = CallingConventionC;
- proto_node->data.fn_proto.is_extern = true;
- break;
- case ZigClangCallingConv_X86StdCall: // __attribute__((stdcall))
- proto_node->data.fn_proto.cc = CallingConventionStdcall;
- break;
- case ZigClangCallingConv_X86FastCall: // __attribute__((fastcall))
- emit_warning(c, source_loc, "unsupported calling convention: x86 fastcall");
- return nullptr;
- case ZigClangCallingConv_X86ThisCall: // __attribute__((thiscall))
- emit_warning(c, source_loc, "unsupported calling convention: x86 thiscall");
- return nullptr;
- case ZigClangCallingConv_X86VectorCall: // __attribute__((vectorcall))
- emit_warning(c, source_loc, "unsupported calling convention: x86 vectorcall");
- return nullptr;
- case ZigClangCallingConv_X86Pascal: // __attribute__((pascal))
- emit_warning(c, source_loc, "unsupported calling convention: x86 pascal");
- return nullptr;
- case ZigClangCallingConv_Win64: // __attribute__((ms_abi))
- emit_warning(c, source_loc, "unsupported calling convention: win64");
- return nullptr;
- case ZigClangCallingConv_X86_64SysV: // __attribute__((sysv_abi))
- emit_warning(c, source_loc, "unsupported calling convention: x86 64sysv");
- return nullptr;
- case ZigClangCallingConv_X86RegCall:
- emit_warning(c, source_loc, "unsupported calling convention: x86 reg");
- return nullptr;
- case ZigClangCallingConv_AAPCS: // __attribute__((pcs("aapcs")))
- emit_warning(c, source_loc, "unsupported calling convention: aapcs");
- return nullptr;
- case ZigClangCallingConv_AAPCS_VFP: // __attribute__((pcs("aapcs-vfp")))
- emit_warning(c, source_loc, "unsupported calling convention: aapcs-vfp");
- return nullptr;
- case ZigClangCallingConv_IntelOclBicc: // __attribute__((intel_ocl_bicc))
- emit_warning(c, source_loc, "unsupported calling convention: intel_ocl_bicc");
- return nullptr;
- case ZigClangCallingConv_SpirFunction: // default for OpenCL functions on SPIR target
- emit_warning(c, source_loc, "unsupported calling convention: SPIR function");
- return nullptr;
- case ZigClangCallingConv_OpenCLKernel:
- emit_warning(c, source_loc, "unsupported calling convention: OpenCLKernel");
- return nullptr;
- case ZigClangCallingConv_Swift:
- emit_warning(c, source_loc, "unsupported calling convention: Swift");
- return nullptr;
- case ZigClangCallingConv_PreserveMost:
- emit_warning(c, source_loc, "unsupported calling convention: PreserveMost");
- return nullptr;
- case ZigClangCallingConv_PreserveAll:
- emit_warning(c, source_loc, "unsupported calling convention: PreserveAll");
- return nullptr;
- case ZigClangCallingConv_AArch64VectorCall:
- emit_warning(c, source_loc, "unsupported calling convention: AArch64VectorCall");
- return nullptr;
- }
-
- if (ZigClangFunctionType_getNoReturnAttr(fn_ty)) {
- proto_node->data.fn_proto.return_type = trans_create_node_symbol_str(c, "noreturn");
- } else {
- proto_node->data.fn_proto.return_type = trans_qual_type(c,
- ZigClangFunctionType_getReturnType(fn_ty), source_loc);
- if (proto_node->data.fn_proto.return_type == nullptr) {
- emit_warning(c, source_loc, "unsupported function proto return type");
- return nullptr;
- }
- // convert c_void to actual void (only for return type)
- // we do want to look at the AstNode instead of ZigClangQualType, because
- // if they do something like:
- // typedef Foo void;
- // void foo(void) -> Foo;
- // we want to keep the return type AST node.
- if (is_c_void_type(proto_node->data.fn_proto.return_type)) {
- proto_node->data.fn_proto.return_type = trans_create_node_symbol_str(c, "void");
- }
- }
-
- //emit_warning(c, source_loc, "TODO figure out fn prototype fn name");
- const char *fn_name = nullptr;
- if (fn_name != nullptr) {
- proto_node->data.fn_proto.name = buf_create_from_str(fn_name);
- }
-
- if (ZigClangType_getTypeClass(ty) == ZigClangType_FunctionNoProto) {
- return proto_node;
- }
-
- const ZigClangFunctionProtoType *fn_proto_ty = reinterpret_cast<const ZigClangFunctionProtoType*>(ty);
-
- proto_node->data.fn_proto.is_var_args = ZigClangFunctionProtoType_isVariadic(fn_proto_ty);
- size_t param_count = ZigClangFunctionProtoType_getNumParams(fn_proto_ty);
-
- for (size_t i = 0; i < param_count; i += 1) {
- ZigClangQualType qt = ZigClangFunctionProtoType_getParamType(fn_proto_ty, i);
- AstNode *param_type_node = trans_qual_type(c, qt, source_loc);
-
- if (param_type_node == nullptr) {
- emit_warning(c, source_loc, "unresolved function proto parameter type");
- return nullptr;
- }
-
- AstNode *param_node = trans_create_node(c, NodeTypeParamDecl);
- //emit_warning(c, source_loc, "TODO figure out fn prototype param name");
- const char *param_name = nullptr;
- if (param_name != nullptr) {
- param_node->data.param_decl.name = buf_create_from_str(param_name);
- }
- param_node->data.param_decl.is_noalias = ZigClangQualType_isRestrictQualified(qt);
- param_node->data.param_decl.type = param_type_node;
- proto_node->data.fn_proto.params.append(param_node);
- }
- // TODO check for always_inline attribute
- // TODO check for align attribute
-
- return proto_node;
- }
- case ZigClangType_Record:
- {
- const ZigClangRecordType *record_ty = reinterpret_cast<const ZigClangRecordType*>(ty);
- return resolve_record_decl(c, ZigClangRecordType_getDecl(record_ty));
- }
- case ZigClangType_Enum:
- {
- const ZigClangEnumType *enum_ty = reinterpret_cast<const ZigClangEnumType*>(ty);
- return resolve_enum_decl(c, ZigClangEnumType_getDecl(enum_ty));
- }
- case ZigClangType_ConstantArray:
- {
- const ZigClangConstantArrayType *const_arr_ty = reinterpret_cast<const ZigClangConstantArrayType *>(ty);
- AstNode *child_type_node = trans_qual_type(c,
- ZigClangConstantArrayType_getElementType(const_arr_ty), source_loc);
- if (child_type_node == nullptr) {
- emit_warning(c, source_loc, "unresolved array element type");
- return nullptr;
- }
- const ZigClangAPInt *size_ap_int = ZigClangConstantArrayType_getSize(const_arr_ty);
- uint64_t size = ZigClangAPInt_getLimitedValue(size_ap_int, UINT64_MAX);
- AstNode *size_node = trans_create_node_unsigned(c, size);
- return trans_create_node_array_type(c, size_node, child_type_node);
- }
- case ZigClangType_Paren:
- {
- const ZigClangParenType *paren_ty = reinterpret_cast<const ZigClangParenType *>(ty);
- return trans_qual_type(c, ZigClangParenType_getInnerType(paren_ty), source_loc);
- }
- case ZigClangType_Decayed:
- {
- const ZigClangDecayedType *decayed_ty = reinterpret_cast<const ZigClangDecayedType *>(ty);
- return trans_qual_type(c, ZigClangDecayedType_getDecayedType(decayed_ty), source_loc);
- }
- case ZigClangType_Attributed:
- {
- const ZigClangAttributedType *attributed_ty = reinterpret_cast<const ZigClangAttributedType *>(ty);
- return trans_qual_type(c, ZigClangAttributedType_getEquivalentType(attributed_ty), source_loc);
- }
- case ZigClangType_MacroQualified:
- {
- const ZigClangMacroQualifiedType *macroqualified_ty = reinterpret_cast<const ZigClangMacroQualifiedType *>(ty);
- return trans_qual_type(c, ZigClangMacroQualifiedType_getModifiedType(macroqualified_ty), source_loc);
- }
- case ZigClangType_IncompleteArray:
- {
- const ZigClangIncompleteArrayType *incomplete_array_ty = reinterpret_cast<const ZigClangIncompleteArrayType *>(ty);
- ZigClangQualType child_qt = ZigClangIncompleteArrayType_getElementType(incomplete_array_ty);
- AstNode *child_type_node = trans_qual_type(c, child_qt, source_loc);
- if (child_type_node == nullptr) {
- emit_warning(c, source_loc, "unresolved array element type");
- return nullptr;
- }
- AstNode *pointer_node = trans_create_node_ptr_type(c,
- ZigClangQualType_isConstQualified(child_qt),
- ZigClangQualType_isVolatileQualified(child_qt),
- child_type_node, PtrLenC);
- return pointer_node;
- }
- case ZigClangType_BlockPointer:
- case ZigClangType_LValueReference:
- case ZigClangType_RValueReference:
- case ZigClangType_MemberPointer:
- case ZigClangType_VariableArray:
- case ZigClangType_DependentSizedArray:
- case ZigClangType_DependentSizedExtVector:
- case ZigClangType_Vector:
- case ZigClangType_ExtVector:
- case ZigClangType_UnresolvedUsing:
- case ZigClangType_Adjusted:
- case ZigClangType_TypeOfExpr:
- case ZigClangType_TypeOf:
- case ZigClangType_Decltype:
- case ZigClangType_UnaryTransform:
- case ZigClangType_TemplateTypeParm:
- case ZigClangType_SubstTemplateTypeParm:
- case ZigClangType_SubstTemplateTypeParmPack:
- case ZigClangType_TemplateSpecialization:
- case ZigClangType_Auto:
- case ZigClangType_InjectedClassName:
- case ZigClangType_DependentName:
- case ZigClangType_DependentTemplateSpecialization:
- case ZigClangType_PackExpansion:
- case ZigClangType_ObjCObject:
- case ZigClangType_ObjCInterface:
- case ZigClangType_Complex:
- case ZigClangType_ObjCObjectPointer:
- case ZigClangType_Atomic:
- case ZigClangType_Pipe:
- case ZigClangType_ObjCTypeParam:
- case ZigClangType_DeducedTemplateSpecialization:
- case ZigClangType_DependentAddressSpace:
- case ZigClangType_DependentVector:
- emit_warning(c, source_loc, "unsupported type: '%s'", ZigClangType_getTypeClassName(ty));
- return nullptr;
- }
- zig_unreachable();
-}
-
-static AstNode *trans_qual_type(Context *c, ZigClangQualType qt, ZigClangSourceLocation source_loc) {
- return trans_type(c, ZigClangQualType_getTypePtr(qt), source_loc);
-}
-
-static int trans_compound_stmt_inline(Context *c, TransScope *scope, const ZigClangCompoundStmt *stmt,
- AstNode *block_node, TransScope **out_node_scope)
-{
- assert(block_node->type == NodeTypeBlock);
- for (ZigClangCompoundStmt_const_body_iterator it = ZigClangCompoundStmt_body_begin(stmt),
- end_it = ZigClangCompoundStmt_body_end(stmt); it != end_it; ++it)
- {
- AstNode *child_node;
- scope = trans_stmt(c, scope, *it, &child_node);
- if (scope == nullptr)
- return ErrorUnexpected;
- if (child_node != nullptr)
- block_node->data.block.statements.append(child_node);
- }
- if (out_node_scope != nullptr) {
- *out_node_scope = scope;
- }
- return ErrorNone;
-}
-
-static AstNode *trans_compound_stmt(Context *c, TransScope *scope, const ZigClangCompoundStmt *stmt,
- TransScope **out_node_scope)
-{
- TransScopeBlock *child_scope_block = trans_scope_block_create(c, scope);
- if (trans_compound_stmt_inline(c, &child_scope_block->base, stmt, child_scope_block->node, out_node_scope))
- return nullptr;
- return child_scope_block->node;
-}
-
-static AstNode *trans_stmt_expr(Context *c, ResultUsed result_used, TransScope *scope,
- const ZigClangStmtExpr *stmt, TransScope **out_node_scope)
-{
- AstNode *block = trans_compound_stmt(c, scope, ZigClangStmtExpr_getSubStmt(stmt), out_node_scope);
- if (block == nullptr)
- return block;
- assert(block->type == NodeTypeBlock);
- if (block->data.block.statements.length == 0)
- return block;
-
- Buf *label = buf_create_from_str("x");
- block->data.block.name = label;
- AstNode *return_expr = block->data.block.statements.pop();
- if (return_expr->type == NodeTypeBinOpExpr &&
- return_expr->data.bin_op_expr.bin_op == BinOpTypeAssign &&
- return_expr->data.bin_op_expr.op1->type == NodeTypeSymbol)
- {
- Buf *symbol_buf = return_expr->data.bin_op_expr.op1->data.symbol_expr.symbol;
- if (strcmp("_", buf_ptr(symbol_buf)) == 0)
- return_expr = return_expr->data.bin_op_expr.op2;
- }
- block->data.block.statements.append(trans_create_node_break(c, label, return_expr));
- return maybe_suppress_result(c, result_used, block);
-}
-
-static AstNode *trans_return_stmt(Context *c, TransScope *scope, const ZigClangReturnStmt *stmt) {
- const ZigClangExpr *value_expr = ZigClangReturnStmt_getRetValue(stmt);
- if (value_expr == nullptr) {
- return trans_create_node(c, NodeTypeReturnExpr);
- } else {
- AstNode *return_node = trans_create_node(c, NodeTypeReturnExpr);
- return_node->data.return_expr.expr = trans_expr(c, ResultUsedYes, scope, value_expr, TransRValue);
- if (return_node->data.return_expr.expr == nullptr)
- return nullptr;
- return return_node;
- }
-}
-
-static AstNode *trans_integer_literal(Context *c, ResultUsed result_used, const ZigClangIntegerLiteral *stmt) {
- ZigClangExprEvalResult result;
- if (!ZigClangIntegerLiteral_EvaluateAsInt(stmt, &result, c->ctx)) {
- emit_warning(c, ZigClangExpr_getBeginLoc((ZigClangExpr*)stmt), "invalid integer literal");
- return nullptr;
- }
- AstNode *node = trans_create_node_apint(c, ZigClangAPValue_getInt(&result.Val));
- return maybe_suppress_result(c, result_used, node);
-}
-
-static AstNode *trans_floating_literal(Context *c, ResultUsed result_used, const ZigClangFloatingLiteral *stmt) {
- ZigClangAPFloat *result;
- if (!ZigClangExpr_EvaluateAsFloat((const ZigClangExpr *)stmt, &result, c->ctx)) {
- emit_warning(c, ZigClangExpr_getBeginLoc((ZigClangExpr*)stmt), "invalid floating literal");
- return nullptr;
- }
- AstNode *node = trans_create_node_apfloat(c, result);
- return maybe_suppress_result(c, result_used, node);
-}
-
-static AstNode *trans_character_literal(Context *c, ResultUsed result_used, const ZigClangCharacterLiteral *stmt) {
- switch (ZigClangCharacterLiteral_getKind(stmt)) {
- case ZigClangCharacterLiteral_CharacterKind_Ascii:
- {
- unsigned val = ZigClangCharacterLiteral_getValue(stmt);
- // C has a somewhat obscure feature called multi-character character
- // constant
- if (val > 255)
- return trans_create_node_unsigned(c, val);
- }
- // fallthrough
- case ZigClangCharacterLiteral_CharacterKind_UTF8:
- {
- AstNode *node = trans_create_node(c, NodeTypeCharLiteral);
- node->data.char_literal.value = ZigClangCharacterLiteral_getValue(stmt);
- return maybe_suppress_result(c, result_used, node);
- }
- case ZigClangCharacterLiteral_CharacterKind_UTF16:
- emit_warning(c, ZigClangCharacterLiteral_getBeginLoc(stmt), "TODO support UTF16 character literals");
- return nullptr;
- case ZigClangCharacterLiteral_CharacterKind_UTF32:
- emit_warning(c, ZigClangCharacterLiteral_getBeginLoc(stmt), "TODO support UTF32 character literals");
- return nullptr;
- case ZigClangCharacterLiteral_CharacterKind_Wide:
- emit_warning(c, ZigClangCharacterLiteral_getBeginLoc(stmt), "TODO support wide character literals");
- return nullptr;
- }
- zig_unreachable();
-}
-
-static AstNode *trans_constant_expr(Context *c, ResultUsed result_used, const ZigClangConstantExpr *expr) {
- const ZigClangExpr *as_expr = reinterpret_cast<const ZigClangExpr *>(expr);
- ZigClangExprEvalResult result;
- if (!ZigClangExpr_EvaluateAsConstantExpr((const ZigClangExpr *)expr, &result,
- ZigClangExpr_EvaluateForCodeGen, c->ctx))
- {
- emit_warning(c, ZigClangExpr_getBeginLoc(as_expr), "invalid constant expression");
- return nullptr;
- }
- AstNode *node = trans_ap_value(c, &result.Val, ZigClangExpr_getType(as_expr),
- ZigClangExpr_getBeginLoc(as_expr));
- return maybe_suppress_result(c, result_used, node);
-}
-
-static AstNode *trans_conditional_operator(Context *c, ResultUsed result_used, TransScope *scope,
- const ZigClangConditionalOperator *stmt)
-{
- AstNode *node = trans_create_node(c, NodeTypeIfBoolExpr);
-
- const ZigClangExpr *cond_expr = ZigClangConditionalOperator_getCond(stmt);
- const ZigClangExpr *true_expr = ZigClangConditionalOperator_getTrueExpr(stmt);
- const ZigClangExpr *false_expr = ZigClangConditionalOperator_getFalseExpr(stmt);
-
- node->data.if_bool_expr.condition = trans_expr(c, ResultUsedYes, scope, cond_expr, TransRValue);
- if (node->data.if_bool_expr.condition == nullptr)
- return nullptr;
-
- node->data.if_bool_expr.then_block = trans_expr(c, result_used, scope, true_expr, TransRValue);
- if (node->data.if_bool_expr.then_block == nullptr)
- return nullptr;
-
- node->data.if_bool_expr.else_node = trans_expr(c, result_used, scope, false_expr, TransRValue);
- if (node->data.if_bool_expr.else_node == nullptr)
- return nullptr;
-
- return maybe_suppress_result(c, result_used, node);
-}
-
-static AstNode *trans_create_bin_op(Context *c, TransScope *scope, const ZigClangExpr *lhs,
- BinOpType bin_op, const ZigClangExpr *rhs)
-{
- AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
- node->data.bin_op_expr.bin_op = bin_op;
-
- node->data.bin_op_expr.op1 = trans_expr(c, ResultUsedYes, scope, lhs, TransRValue);
- if (node->data.bin_op_expr.op1 == nullptr)
- return nullptr;
-
- node->data.bin_op_expr.op2 = trans_expr(c, ResultUsedYes, scope, rhs, TransRValue);
- if (node->data.bin_op_expr.op2 == nullptr)
- return nullptr;
-
- return node;
-}
-
-static AstNode *trans_create_bool_bin_op(Context *c, TransScope *scope, const ZigClangExpr *lhs,
- BinOpType bin_op, const ZigClangExpr *rhs)
-{
- assert(bin_op == BinOpTypeBoolAnd || bin_op == BinOpTypeBoolOr);
- AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
- node->data.bin_op_expr.bin_op = bin_op;
-
- node->data.bin_op_expr.op1 = trans_bool_expr(c, ResultUsedYes, scope, lhs, TransRValue);
- if (node->data.bin_op_expr.op1 == nullptr)
- return nullptr;
-
- node->data.bin_op_expr.op2 = trans_bool_expr(c, ResultUsedYes, scope, rhs, TransRValue);
- if (node->data.bin_op_expr.op2 == nullptr)
- return nullptr;
-
- return node;
-}
-
-static AstNode *trans_create_assign(Context *c, ResultUsed result_used, TransScope *scope,
- const ZigClangExpr *lhs, const ZigClangExpr *rhs)
-{
- if (result_used == ResultUsedNo) {
- // common case
- AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
- node->data.bin_op_expr.bin_op = BinOpTypeAssign;
-
- node->data.bin_op_expr.op1 = trans_expr(c, ResultUsedYes, scope, lhs, TransLValue);
- if (node->data.bin_op_expr.op1 == nullptr)
- return nullptr;
-
- node->data.bin_op_expr.op2 = trans_expr(c, ResultUsedYes, scope, rhs, TransRValue);
- if (node->data.bin_op_expr.op2 == nullptr)
- return nullptr;
-
- return node;
- } else {
- // worst case
- // c: lhs = rhs
- // zig: (x: {
- // zig: const _tmp = rhs;
- // zig: lhs = _tmp;
- // zig: break :x _tmp
- // zig: })
-
- TransScopeBlock *child_scope = trans_scope_block_create(c, scope);
- Buf *label_name = buf_create_from_str("x");
- child_scope->node->data.block.name = label_name;
-
- // const _tmp = rhs;
- AstNode *rhs_node = trans_expr(c, ResultUsedYes, &child_scope->base, rhs, TransRValue);
- if (rhs_node == nullptr) return nullptr;
- // TODO: avoid name collisions with generated variable names
- Buf* tmp_var_name = buf_create_from_str("_tmp");
- AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr, rhs_node);
- child_scope->node->data.block.statements.append(tmp_var_decl);
-
- // lhs = _tmp;
- AstNode *lhs_node = trans_expr(c, ResultUsedYes, &child_scope->base, lhs, TransLValue);
- if (lhs_node == nullptr) return nullptr;
- child_scope->node->data.block.statements.append(
- trans_create_node_bin_op(c, lhs_node, BinOpTypeAssign,
- trans_create_node_symbol(c, tmp_var_name)));
-
- // break :x _tmp
- AstNode *tmp_symbol_node = trans_create_node_symbol(c, tmp_var_name);
- child_scope->node->data.block.statements.append(trans_create_node_break(c, label_name, tmp_symbol_node));
-
- return trans_create_node_grouped_expr(c, child_scope->node);
- }
-}
-
-static AstNode *trans_create_shift_op(Context *c, TransScope *scope, ZigClangQualType result_type,
- const ZigClangExpr *lhs_expr, BinOpType bin_op, const ZigClangExpr *rhs_expr)
-{
- ZigClangSourceLocation rhs_location = ZigClangExpr_getBeginLoc(rhs_expr);
- AstNode *rhs_type = qual_type_to_log2_int_ref(c, result_type, rhs_location);
- // lhs >> u5(rh)
-
- AstNode *lhs = trans_expr(c, ResultUsedYes, scope, lhs_expr, TransLValue);
- if (lhs == nullptr) return nullptr;
-
- AstNode *rhs = trans_expr(c, ResultUsedYes, scope, rhs_expr, TransRValue);
- if (rhs == nullptr) return nullptr;
- AstNode *coerced_rhs = trans_create_node_cast(c, rhs_type, rhs);
-
- return trans_create_node_bin_op(c, lhs, bin_op, coerced_rhs);
-}
-
-static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransScope *scope,
- const ZigClangBinaryOperator *stmt)
-{
- switch (ZigClangBinaryOperator_getOpcode(stmt)) {
- case ZigClangBO_PtrMemD:
- emit_warning(c, ZigClangBinaryOperator_getBeginLoc(stmt), "TODO handle more C binary operators: BO_PtrMemD");
- return nullptr;
- case ZigClangBO_PtrMemI:
- emit_warning(c, ZigClangBinaryOperator_getBeginLoc(stmt), "TODO handle more C binary operators: BO_PtrMemI");
- return nullptr;
- case ZigClangBO_Cmp:
- emit_warning(c, ZigClangBinaryOperator_getBeginLoc(stmt), "TODO handle more C binary operators: BO_Cmp");
- return nullptr;
- case ZigClangBO_Mul: {
- AstNode *node = trans_create_bin_op(c, scope, ZigClangBinaryOperator_getLHS(stmt),
- qual_type_has_wrapping_overflow(c, ZigClangBinaryOperator_getType(stmt)) ? BinOpTypeMultWrap : BinOpTypeMult,
- ZigClangBinaryOperator_getRHS(stmt));
- return maybe_suppress_result(c, result_used, node);
- }
- case ZigClangBO_Div:
- if (qual_type_has_wrapping_overflow(c, ZigClangBinaryOperator_getType(stmt))) {
- // unsigned/float division uses the operator
- AstNode *node = trans_create_bin_op(c, scope, ZigClangBinaryOperator_getLHS(stmt), BinOpTypeDiv, ZigClangBinaryOperator_getRHS(stmt));
- return maybe_suppress_result(c, result_used, node);
- } else {
- // signed integer division uses @divTrunc
- AstNode *fn_call = trans_create_node_builtin_fn_call_str(c, "divTrunc");
- AstNode *lhs = trans_expr(c, ResultUsedYes, scope, ZigClangBinaryOperator_getLHS(stmt), TransLValue);
- if (lhs == nullptr) return nullptr;
- fn_call->data.fn_call_expr.params.append(lhs);
- AstNode *rhs = trans_expr(c, ResultUsedYes, scope, ZigClangBinaryOperator_getRHS(stmt), TransLValue);
- if (rhs == nullptr) return nullptr;
- fn_call->data.fn_call_expr.params.append(rhs);
- return maybe_suppress_result(c, result_used, fn_call);
- }
- case ZigClangBO_Rem:
- if (qual_type_has_wrapping_overflow(c, ZigClangBinaryOperator_getType(stmt))) {
- // unsigned/float division uses the operator
- AstNode *node = trans_create_bin_op(c, scope, ZigClangBinaryOperator_getLHS(stmt), BinOpTypeMod, ZigClangBinaryOperator_getRHS(stmt));
- return maybe_suppress_result(c, result_used, node);
- } else {
- // signed integer division uses @rem
- AstNode *fn_call = trans_create_node_builtin_fn_call_str(c, "rem");
- AstNode *lhs = trans_expr(c, ResultUsedYes, scope, ZigClangBinaryOperator_getLHS(stmt), TransLValue);
- if (lhs == nullptr) return nullptr;
- fn_call->data.fn_call_expr.params.append(lhs);
- AstNode *rhs = trans_expr(c, ResultUsedYes, scope, ZigClangBinaryOperator_getRHS(stmt), TransLValue);
- if (rhs == nullptr) return nullptr;
- fn_call->data.fn_call_expr.params.append(rhs);
- return maybe_suppress_result(c, result_used, fn_call);
- }
- case ZigClangBO_Add: {
- AstNode *node = trans_create_bin_op(c, scope, ZigClangBinaryOperator_getLHS(stmt),
- qual_type_has_wrapping_overflow(c, ZigClangBinaryOperator_getType(stmt)) ? BinOpTypeAddWrap : BinOpTypeAdd,
- ZigClangBinaryOperator_getRHS(stmt));
- return maybe_suppress_result(c, result_used, node);
- }
- case ZigClangBO_Sub: {
- AstNode *node = trans_create_bin_op(c, scope, ZigClangBinaryOperator_getLHS(stmt),
- qual_type_has_wrapping_overflow(c, ZigClangBinaryOperator_getType(stmt)) ? BinOpTypeSubWrap : BinOpTypeSub,
- ZigClangBinaryOperator_getRHS(stmt));
- return maybe_suppress_result(c, result_used, node);
- }
- case ZigClangBO_Shl: {
- AstNode *node = trans_create_shift_op(c, scope, ZigClangBinaryOperator_getType(stmt), ZigClangBinaryOperator_getLHS(stmt), BinOpTypeBitShiftLeft, ZigClangBinaryOperator_getRHS(stmt));
- return maybe_suppress_result(c, result_used, node);
- }
- case ZigClangBO_Shr: {
- AstNode *node = trans_create_shift_op(c, scope, ZigClangBinaryOperator_getType(stmt), ZigClangBinaryOperator_getLHS(stmt), BinOpTypeBitShiftRight, ZigClangBinaryOperator_getRHS(stmt));
- return maybe_suppress_result(c, result_used, node);
- }
- case ZigClangBO_LT: {
- AstNode *node =trans_create_bin_op(c, scope, ZigClangBinaryOperator_getLHS(stmt), BinOpTypeCmpLessThan, ZigClangBinaryOperator_getRHS(stmt));
- return maybe_suppress_result(c, result_used, node);
- }
- case ZigClangBO_GT: {
- AstNode *node = trans_create_bin_op(c, scope, ZigClangBinaryOperator_getLHS(stmt), BinOpTypeCmpGreaterThan, ZigClangBinaryOperator_getRHS(stmt));
- return maybe_suppress_result(c, result_used, node);
- }
- case ZigClangBO_LE: {
- AstNode *node = trans_create_bin_op(c, scope, ZigClangBinaryOperator_getLHS(stmt), BinOpTypeCmpLessOrEq, ZigClangBinaryOperator_getRHS(stmt));
- return maybe_suppress_result(c, result_used, node);
- }
- case ZigClangBO_GE: {
- AstNode *node = trans_create_bin_op(c, scope, ZigClangBinaryOperator_getLHS(stmt), BinOpTypeCmpGreaterOrEq, ZigClangBinaryOperator_getRHS(stmt));
- return maybe_suppress_result(c, result_used, node);
- }
- case ZigClangBO_EQ: {
- AstNode *node = trans_create_bin_op(c, scope, ZigClangBinaryOperator_getLHS(stmt), BinOpTypeCmpEq, ZigClangBinaryOperator_getRHS(stmt));
- return maybe_suppress_result(c, result_used, node);
- }
- case ZigClangBO_NE: {
- AstNode *node = trans_create_bin_op(c, scope, ZigClangBinaryOperator_getLHS(stmt), BinOpTypeCmpNotEq, ZigClangBinaryOperator_getRHS(stmt));
- return maybe_suppress_result(c, result_used, node);
- }
- case ZigClangBO_And: {
- AstNode *node = trans_create_bin_op(c, scope, ZigClangBinaryOperator_getLHS(stmt), BinOpTypeBinAnd, ZigClangBinaryOperator_getRHS(stmt));
- return maybe_suppress_result(c, result_used, node);
- }
- case ZigClangBO_Xor: {
- AstNode *node = trans_create_bin_op(c, scope, ZigClangBinaryOperator_getLHS(stmt), BinOpTypeBinXor, ZigClangBinaryOperator_getRHS(stmt));
- return maybe_suppress_result(c, result_used, node);
- }
- case ZigClangBO_Or: {
- AstNode *node = trans_create_bin_op(c, scope, ZigClangBinaryOperator_getLHS(stmt), BinOpTypeBinOr, ZigClangBinaryOperator_getRHS(stmt));
- return maybe_suppress_result(c, result_used, node);
- }
- case ZigClangBO_LAnd: {
- AstNode *node = trans_create_bool_bin_op(c, scope, ZigClangBinaryOperator_getLHS(stmt), BinOpTypeBoolAnd, ZigClangBinaryOperator_getRHS(stmt));
- return maybe_suppress_result(c, result_used, node);
- }
- case ZigClangBO_LOr: {
- AstNode *node = trans_create_bool_bin_op(c, scope, ZigClangBinaryOperator_getLHS(stmt), BinOpTypeBoolOr, ZigClangBinaryOperator_getRHS(stmt));
- return maybe_suppress_result(c, result_used, node);
- }
- case ZigClangBO_Assign:
- return trans_create_assign(c, result_used, scope, ZigClangBinaryOperator_getLHS(stmt), ZigClangBinaryOperator_getRHS(stmt));
- case ZigClangBO_Comma:
- {
- TransScopeBlock *scope_block = trans_scope_block_create(c, scope);
- Buf *label_name = buf_create_from_str("x");
- scope_block->node->data.block.name = label_name;
-
- AstNode *lhs = trans_expr(c, ResultUsedNo, &scope_block->base, ZigClangBinaryOperator_getLHS(stmt), TransRValue);
- if (lhs == nullptr)
- return nullptr;
- scope_block->node->data.block.statements.append(lhs);
-
- AstNode *rhs = trans_expr(c, ResultUsedYes, &scope_block->base, ZigClangBinaryOperator_getRHS(stmt), TransRValue);
- if (rhs == nullptr)
- return nullptr;
-
- rhs = trans_create_node_break(c, label_name, rhs);
- scope_block->node->data.block.statements.append(rhs);
- return maybe_suppress_result(c, result_used, scope_block->node);
- }
- case ZigClangBO_MulAssign:
- case ZigClangBO_DivAssign:
- case ZigClangBO_RemAssign:
- case ZigClangBO_AddAssign:
- case ZigClangBO_SubAssign:
- case ZigClangBO_ShlAssign:
- case ZigClangBO_ShrAssign:
- case ZigClangBO_AndAssign:
- case ZigClangBO_XorAssign:
- case ZigClangBO_OrAssign:
- zig_unreachable();
- }
-
- zig_unreachable();
-}
-
-static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result_used, TransScope *scope,
- const ZigClangCompoundAssignOperator *stmt, BinOpType assign_op, BinOpType bin_op)
-{
- ZigClangSourceLocation rhs_location = ZigClangExpr_getBeginLoc(ZigClangCompoundAssignOperator_getRHS(stmt));
- ZigClangQualType computation_lhs_type = ZigClangCompoundAssignOperator_getComputationLHSType(stmt);
- AstNode *rhs_type = qual_type_to_log2_int_ref(c, computation_lhs_type, rhs_location);
- ZigClangQualType computation_result_type = ZigClangCompoundAssignOperator_getComputationResultType(stmt);
-
- bool use_intermediate_casts = ZigClangQualType_getTypePtr(computation_lhs_type) !=
- ZigClangQualType_getTypePtr(computation_result_type);
- if (!use_intermediate_casts && result_used == ResultUsedNo) {
- // simple common case, where the C and Zig are identical:
- // lhs >>= rhs
- AstNode *lhs = trans_expr(c, ResultUsedYes, scope, ZigClangCompoundAssignOperator_getLHS(stmt), TransLValue);
- if (lhs == nullptr) return nullptr;
-
- AstNode *rhs = trans_expr(c, ResultUsedYes, scope, ZigClangCompoundAssignOperator_getRHS(stmt), TransRValue);
- if (rhs == nullptr) return nullptr;
- AstNode *coerced_rhs = trans_create_node_cast(c, rhs_type, rhs);
-
- return trans_create_node_bin_op(c, lhs, assign_op, coerced_rhs);
- } else {
- // need more complexity. worst case, this looks like this:
- // c: lhs >>= rhs
- // zig: (x: {
- // zig: const _ref = &lhs;
- // zig: *_ref = result_type(operation_type(*_ref) >> u5(rhs));
- // zig: break :x *_ref
- // zig: })
- // where u5 is the appropriate type
-
- TransScopeBlock *child_scope = trans_scope_block_create(c, scope);
- Buf *label_name = buf_create_from_str("x");
- child_scope->node->data.block.name = label_name;
-
- // const _ref = &lhs;
- AstNode *lhs = trans_expr(c, ResultUsedYes, &child_scope->base,
- ZigClangCompoundAssignOperator_getLHS(stmt), TransLValue);
- if (lhs == nullptr) return nullptr;
- AstNode *addr_of_lhs = trans_create_node_addr_of(c, lhs);
- // TODO: avoid name collisions with generated variable names
- Buf* tmp_var_name = buf_create_from_str("_ref");
- AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr, addr_of_lhs);
- child_scope->node->data.block.statements.append(tmp_var_decl);
-
- // *_ref = result_type(operation_type(*_ref) >> u5(rhs));
-
- AstNode *rhs = trans_expr(c, ResultUsedYes, &child_scope->base, ZigClangCompoundAssignOperator_getRHS(stmt), TransRValue);
- if (rhs == nullptr) return nullptr;
- AstNode *coerced_rhs = trans_create_node_cast(c, rhs_type, rhs);
-
- // operation_type(*_ref)
- AstNode *operation_type_cast = trans_c_cast(c, rhs_location,
- computation_lhs_type,
- ZigClangExpr_getType(ZigClangCompoundAssignOperator_getLHS(stmt)),
- trans_create_node_ptr_deref(c, trans_create_node_symbol(c, tmp_var_name)));
-
- // result_type(... >> u5(rhs))
- AstNode *result_type_cast = trans_c_cast(c, rhs_location,
- computation_result_type,
- computation_lhs_type,
- trans_create_node_bin_op(c,
- operation_type_cast,
- bin_op,
- coerced_rhs));
-
- // *_ref = ...
- AstNode *assign_statement = trans_create_node_bin_op(c,
- trans_create_node_ptr_deref(c,
- trans_create_node_symbol(c, tmp_var_name)),
- BinOpTypeAssign, result_type_cast);
-
- child_scope->node->data.block.statements.append(assign_statement);
-
- if (result_used == ResultUsedYes) {
- // break :x *_ref
- child_scope->node->data.block.statements.append(
- trans_create_node_break(c, label_name,
- trans_create_node_ptr_deref(c,
- trans_create_node_symbol(c, tmp_var_name))));
- }
-
- return trans_create_node_grouped_expr(c, child_scope->node);
- }
-}
-
-static AstNode *trans_create_compound_assign(Context *c, ResultUsed result_used, TransScope *scope,
- const ZigClangCompoundAssignOperator *stmt, BinOpType assign_op, BinOpType bin_op)
-{
- if (result_used == ResultUsedNo) {
- // simple common case, where the C and Zig are identical:
- // lhs += rhs
- AstNode *lhs = trans_expr(c, ResultUsedYes, scope, ZigClangCompoundAssignOperator_getLHS(stmt), TransLValue);
- if (lhs == nullptr) return nullptr;
- AstNode *rhs = trans_expr(c, ResultUsedYes, scope, ZigClangCompoundAssignOperator_getRHS(stmt), TransRValue);
- if (rhs == nullptr) return nullptr;
- return trans_create_node_bin_op(c, lhs, assign_op, rhs);
- } else {
- // need more complexity. worst case, this looks like this:
- // c: lhs += rhs
- // zig: (x: {
- // zig: const _ref = &lhs;
- // zig: *_ref = *_ref + rhs;
- // zig: break :x *_ref
- // zig: })
-
- TransScopeBlock *child_scope = trans_scope_block_create(c, scope);
- Buf *label_name = buf_create_from_str("x");
- child_scope->node->data.block.name = label_name;
-
- // const _ref = &lhs;
- AstNode *lhs = trans_expr(c, ResultUsedYes, &child_scope->base,
- ZigClangCompoundAssignOperator_getLHS(stmt), TransLValue);
- if (lhs == nullptr) return nullptr;
- AstNode *addr_of_lhs = trans_create_node_addr_of(c, lhs);
- // TODO: avoid name collisions with generated variable names
- Buf* tmp_var_name = buf_create_from_str("_ref");
- AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr, addr_of_lhs);
- child_scope->node->data.block.statements.append(tmp_var_decl);
-
- // *_ref = *_ref + rhs;
-
- AstNode *rhs = trans_expr(c, ResultUsedYes, &child_scope->base,
- ZigClangCompoundAssignOperator_getRHS(stmt), TransRValue);
- if (rhs == nullptr) return nullptr;
-
- AstNode *assign_statement = trans_create_node_bin_op(c,
- trans_create_node_ptr_deref(c,
- trans_create_node_symbol(c, tmp_var_name)),
- BinOpTypeAssign,
- trans_create_node_bin_op(c,
- trans_create_node_ptr_deref(c,
- trans_create_node_symbol(c, tmp_var_name)),
- bin_op,
- rhs));
- child_scope->node->data.block.statements.append(assign_statement);
-
- // break :x *_ref
- child_scope->node->data.block.statements.append(
- trans_create_node_break(c, label_name,
- trans_create_node_ptr_deref(c,
- trans_create_node_symbol(c, tmp_var_name))));
-
- return trans_create_node_grouped_expr(c, child_scope->node);
- }
-}
-
-
-static AstNode *trans_compound_assign_operator(Context *c, ResultUsed result_used, TransScope *scope,
- const ZigClangCompoundAssignOperator *stmt)
-{
- switch (ZigClangCompoundAssignOperator_getOpcode(stmt)) {
- case ZigClangBO_MulAssign:
- if (qual_type_has_wrapping_overflow(c, ZigClangCompoundAssignOperator_getType(stmt)))
- return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignTimesWrap, BinOpTypeMultWrap);
- else
- return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignTimes, BinOpTypeMult);
- case ZigClangBO_DivAssign:
- emit_warning(c, ZigClangCompoundAssignOperator_getBeginLoc(stmt), "TODO handle more C compound assign operators: BO_DivAssign");
- return nullptr;
- case ZigClangBO_RemAssign:
- emit_warning(c, ZigClangCompoundAssignOperator_getBeginLoc(stmt), "TODO handle more C compound assign operators: BO_RemAssign");
- return nullptr;
- case ZigClangBO_Cmp:
- emit_warning(c, ZigClangCompoundAssignOperator_getBeginLoc(stmt), "TODO handle more C compound assign operators: BO_Cmp");
- return nullptr;
- case ZigClangBO_AddAssign:
- if (qual_type_has_wrapping_overflow(c, ZigClangCompoundAssignOperator_getType(stmt)))
- return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignPlusWrap, BinOpTypeAddWrap);
- else
- return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignPlus, BinOpTypeAdd);
- case ZigClangBO_SubAssign:
- if (qual_type_has_wrapping_overflow(c, ZigClangCompoundAssignOperator_getType(stmt)))
- return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignMinusWrap, BinOpTypeSubWrap);
- else
- return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignMinus, BinOpTypeSub);
- case ZigClangBO_ShlAssign:
- return trans_create_compound_assign_shift(c, result_used, scope, stmt, BinOpTypeAssignBitShiftLeft, BinOpTypeBitShiftLeft);
- case ZigClangBO_ShrAssign:
- return trans_create_compound_assign_shift(c, result_used, scope, stmt, BinOpTypeAssignBitShiftRight, BinOpTypeBitShiftRight);
- case ZigClangBO_AndAssign:
- return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignBitAnd, BinOpTypeBinAnd);
- case ZigClangBO_XorAssign:
- return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignBitXor, BinOpTypeBinXor);
- case ZigClangBO_OrAssign:
- return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignBitOr, BinOpTypeBinOr);
- case ZigClangBO_PtrMemD:
- case ZigClangBO_PtrMemI:
- case ZigClangBO_Assign:
- case ZigClangBO_Mul:
- case ZigClangBO_Div:
- case ZigClangBO_Rem:
- case ZigClangBO_Add:
- case ZigClangBO_Sub:
- case ZigClangBO_Shl:
- case ZigClangBO_Shr:
- case ZigClangBO_LT:
- case ZigClangBO_GT:
- case ZigClangBO_LE:
- case ZigClangBO_GE:
- case ZigClangBO_EQ:
- case ZigClangBO_NE:
- case ZigClangBO_And:
- case ZigClangBO_Xor:
- case ZigClangBO_Or:
- case ZigClangBO_LAnd:
- case ZigClangBO_LOr:
- case ZigClangBO_Comma:
- zig_unreachable();
- }
-
- zig_unreachable();
-}
-
-static AstNode *trans_implicit_cast_expr(Context *c, ResultUsed result_used, TransScope *scope,
- const ZigClangImplicitCastExpr *stmt)
-{
- switch (ZigClangImplicitCastExpr_getCastKind(stmt)) {
- case ZigClangCK_LValueToRValue:
- return trans_expr(c, ResultUsedYes, scope, ZigClangImplicitCastExpr_getSubExpr(stmt), TransRValue);
- case ZigClangCK_IntegralCast:
- {
- AstNode *target_node = trans_expr(c, ResultUsedYes, scope, ZigClangImplicitCastExpr_getSubExpr(stmt), TransRValue);
- if (target_node == nullptr)
- return nullptr;
- AstNode *node = trans_c_cast(c, ZigClangImplicitCastExpr_getBeginLoc(stmt),
- ZigClangExpr_getType(reinterpret_cast<const ZigClangExpr *>(stmt)),
- ZigClangExpr_getType(ZigClangImplicitCastExpr_getSubExpr(stmt)),
- target_node);
- return maybe_suppress_result(c, result_used, node);
- }
- case ZigClangCK_FunctionToPointerDecay:
- case ZigClangCK_ArrayToPointerDecay:
- {
- AstNode *target_node = trans_expr(c, ResultUsedYes, scope, ZigClangImplicitCastExpr_getSubExpr(stmt), TransRValue);
- if (target_node == nullptr)
- return nullptr;
- return maybe_suppress_result(c, result_used, target_node);
- }
- case ZigClangCK_BitCast:
- {
- AstNode *target_node = trans_expr(c, ResultUsedYes, scope, ZigClangImplicitCastExpr_getSubExpr(stmt), TransRValue);
- if (target_node == nullptr)
- return nullptr;
-
- const ZigClangQualType dest_type = get_expr_qual_type(c, reinterpret_cast<const ZigClangExpr *>(stmt));
- const ZigClangQualType src_type = get_expr_qual_type(c, ZigClangImplicitCastExpr_getSubExpr(stmt));
-
- return trans_c_cast(c, ZigClangImplicitCastExpr_getBeginLoc(stmt),
- dest_type, src_type, target_node);
- }
- case ZigClangCK_NullToPointer:
- return trans_create_node(c, NodeTypeNullLiteral);
- case ZigClangCK_NoOp:
- return trans_expr(c, ResultUsedYes, scope, ZigClangImplicitCastExpr_getSubExpr(stmt), TransRValue);
- case ZigClangCK_Dependent:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C translation cast CK_Dependent");
- return nullptr;
- case ZigClangCK_LValueBitCast:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C translation cast CK_LValueBitCast");
- return nullptr;
- case ZigClangCK_BaseToDerived:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C translation cast CK_BaseToDerived");
- return nullptr;
- case ZigClangCK_DerivedToBase:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C translation cast CK_DerivedToBase");
- return nullptr;
- case ZigClangCK_UncheckedDerivedToBase:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C translation cast CK_UncheckedDerivedToBase");
- return nullptr;
- case ZigClangCK_Dynamic:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C translation cast CK_Dynamic");
- return nullptr;
- case ZigClangCK_ToUnion:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C translation cast CK_ToUnion");
- return nullptr;
- case ZigClangCK_NullToMemberPointer:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C translation cast CK_NullToMemberPointer");
- return nullptr;
- case ZigClangCK_BaseToDerivedMemberPointer:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C translation cast CK_BaseToDerivedMemberPointer");
- return nullptr;
- case ZigClangCK_DerivedToBaseMemberPointer:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C translation cast CK_DerivedToBaseMemberPointer");
- return nullptr;
- case ZigClangCK_MemberPointerToBoolean:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C translation cast CK_MemberPointerToBoolean");
- return nullptr;
- case ZigClangCK_ReinterpretMemberPointer:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C translation cast CK_ReinterpretMemberPointer");
- return nullptr;
- case ZigClangCK_UserDefinedConversion:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C translation cast CK_UserDefinedConversion");
- return nullptr;
- case ZigClangCK_ConstructorConversion:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_ConstructorConversion");
- return nullptr;
- case ZigClangCK_PointerToBoolean:
- {
- const ZigClangExpr *expr = ZigClangImplicitCastExpr_getSubExpr(stmt);
- AstNode *val = trans_expr(c, ResultUsedYes, scope, expr, TransRValue);
- if (val == nullptr)
- return nullptr;
-
- AstNode *val_ptr = trans_create_node_builtin_fn_call_str(c, "ptrToInt");
- val_ptr->data.fn_call_expr.params.append(val);
-
- AstNode *zero = trans_create_node_unsigned(c, 0);
-
- // Translate as @ptrToInt((&val) != 0)
- return trans_create_node_bin_op(c, val_ptr, BinOpTypeCmpNotEq, zero);
- }
- case ZigClangCK_ToVoid:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_ToVoid");
- return nullptr;
- case ZigClangCK_VectorSplat:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_VectorSplat");
- return nullptr;
- case ZigClangCK_IntegralToBoolean:
- {
- const ZigClangExpr *expr = ZigClangImplicitCastExpr_getSubExpr(stmt);
-
- bool expr_val;
- if (ZigClangExpr_EvaluateAsBooleanCondition(expr, &expr_val, c->ctx, false)) {
- return trans_create_node_bool(c, expr_val);
- }
-
- AstNode *val = trans_expr(c, ResultUsedYes, scope, expr, TransRValue);
- if (val == nullptr)
- return nullptr;
-
- AstNode *zero = trans_create_node_unsigned(c, 0);
-
- // Translate as val != 0
- return trans_create_node_bin_op(c, val, BinOpTypeCmpNotEq, zero);
- }
- case ZigClangCK_PointerToIntegral:
- {
- AstNode *target_node = trans_expr(c, ResultUsedYes, scope, ZigClangImplicitCastExpr_getSubExpr(stmt), TransRValue);
- if (target_node == nullptr)
- return nullptr;
-
- AstNode *dest_type_node = get_expr_type(c, (const ZigClangExpr *)stmt);
- if (dest_type_node == nullptr)
- return nullptr;
-
- AstNode *val_node = trans_create_node_builtin_fn_call_str(c, "ptrToInt");
- val_node->data.fn_call_expr.params.append(target_node);
- // @ptrToInt always returns a usize
- AstNode *node = trans_create_node_builtin_fn_call_str(c, "intCast");
- node->data.fn_call_expr.params.append(dest_type_node);
- node->data.fn_call_expr.params.append(val_node);
-
- return maybe_suppress_result(c, result_used, node);
- }
- case ZigClangCK_IntegralToPointer:
- {
- AstNode *target_node = trans_expr(c, ResultUsedYes, scope, ZigClangImplicitCastExpr_getSubExpr(stmt), TransRValue);
- if (target_node == nullptr)
- return nullptr;
-
- AstNode *dest_type_node = get_expr_type(c, (const ZigClangExpr *)stmt);
- if (dest_type_node == nullptr)
- return nullptr;
-
- AstNode *node = trans_create_node_builtin_fn_call_str(c, "intToPtr");
- node->data.fn_call_expr.params.append(dest_type_node);
- node->data.fn_call_expr.params.append(target_node);
-
- return maybe_suppress_result(c, result_used, node);
- }
- case ZigClangCK_IntegralToFloating:
- case ZigClangCK_FloatingToIntegral:
- {
- AstNode *target_node = trans_expr(c, ResultUsedYes, scope, ZigClangImplicitCastExpr_getSubExpr(stmt), TransRValue);
- if (target_node == nullptr)
- return nullptr;
-
- AstNode *dest_type_node = get_expr_type(c, (const ZigClangExpr *)stmt);
- if (dest_type_node == nullptr)
- return nullptr;
-
- char const *fn = (ZigClangImplicitCastExpr_getCastKind(stmt) == ZigClangCK_IntegralToFloating) ?
- "intToFloat" : "floatToInt";
- AstNode *node = trans_create_node_builtin_fn_call_str(c, fn);
- node->data.fn_call_expr.params.append(dest_type_node);
- node->data.fn_call_expr.params.append(target_node);
-
- return maybe_suppress_result(c, result_used, node);
- }
- case ZigClangCK_FixedPointCast:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_FixedPointCast");
- return nullptr;
- case ZigClangCK_FixedPointToBoolean:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_FixedPointToBoolean");
- return nullptr;
- case ZigClangCK_FloatingToBoolean:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_FloatingToBoolean");
- return nullptr;
- case ZigClangCK_BooleanToSignedIntegral:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_BooleanToSignedIntegral");
- return nullptr;
- case ZigClangCK_FloatingCast:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_FloatingCast");
- return nullptr;
- case ZigClangCK_CPointerToObjCPointerCast:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_CPointerToObjCPointerCast");
- return nullptr;
- case ZigClangCK_BlockPointerToObjCPointerCast:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_BlockPointerToObjCPointerCast");
- return nullptr;
- case ZigClangCK_AnyPointerToBlockPointerCast:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_AnyPointerToBlockPointerCast");
- return nullptr;
- case ZigClangCK_ObjCObjectLValueCast:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_ObjCObjectLValueCast");
- return nullptr;
- case ZigClangCK_FloatingRealToComplex:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_FloatingRealToComplex");
- return nullptr;
- case ZigClangCK_FloatingComplexToReal:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_FloatingComplexToReal");
- return nullptr;
- case ZigClangCK_FloatingComplexToBoolean:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_FloatingComplexToBoolean");
- return nullptr;
- case ZigClangCK_FloatingComplexCast:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_FloatingComplexCast");
- return nullptr;
- case ZigClangCK_FloatingComplexToIntegralComplex:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_FloatingComplexToIntegralComplex");
- return nullptr;
- case ZigClangCK_IntegralRealToComplex:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_IntegralRealToComplex");
- return nullptr;
- case ZigClangCK_IntegralComplexToReal:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_IntegralComplexToReal");
- return nullptr;
- case ZigClangCK_IntegralComplexToBoolean:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_IntegralComplexToBoolean");
- return nullptr;
- case ZigClangCK_IntegralComplexCast:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_IntegralComplexCast");
- return nullptr;
- case ZigClangCK_IntegralComplexToFloatingComplex:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_IntegralComplexToFloatingComplex");
- return nullptr;
- case ZigClangCK_ARCProduceObject:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_ARCProduceObject");
- return nullptr;
- case ZigClangCK_ARCConsumeObject:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_ARCConsumeObject");
- return nullptr;
- case ZigClangCK_ARCReclaimReturnedObject:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_ARCReclaimReturnedObject");
- return nullptr;
- case ZigClangCK_ARCExtendBlockObject:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_ARCExtendBlockObject");
- return nullptr;
- case ZigClangCK_AtomicToNonAtomic:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_AtomicToNonAtomic");
- return nullptr;
- case ZigClangCK_NonAtomicToAtomic:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_NonAtomicToAtomic");
- return nullptr;
- case ZigClangCK_CopyAndAutoreleaseBlockObject:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_CopyAndAutoreleaseBlockObject");
- return nullptr;
- case ZigClangCK_BuiltinFnToFnPtr:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_BuiltinFnToFnPtr");
- return nullptr;
- case ZigClangCK_ZeroToOCLOpaqueType:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_ZeroToOCLOpaqueType");
- return nullptr;
- case ZigClangCK_AddressSpaceConversion:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_AddressSpaceConversion");
- return nullptr;
- case ZigClangCK_IntToOCLSampler:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_IntToOCLSampler");
- return nullptr;
- case ZigClangCK_LValueToRValueBitCast:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_LValueToRValueBitCast");
- return nullptr;
- case ZigClangCK_FixedPointToIntegral:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_FixedPointToIntegral");
- return nullptr;
- case ZigClangCK_IntegralToFixedPoint:
- emit_warning(c, ZigClangImplicitCastExpr_getBeginLoc(stmt), "TODO handle C CK_IntegralToFixedPointral");
- return nullptr;
- }
- zig_unreachable();
-}
-
-static AstNode *trans_decl_ref_expr(Context *c, TransScope *scope, const ZigClangDeclRefExpr *stmt, TransLRValue lrval) {
- const ZigClangValueDecl *value_decl = ZigClangDeclRefExpr_getDecl(stmt);
- Buf *c_symbol_name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)value_decl));
- Buf *zig_symbol_name = trans_lookup_zig_symbol(c, scope, c_symbol_name);
- if (lrval == TransLValue) {
- c->ptr_params.put(zig_symbol_name, true);
- }
- return trans_create_node_symbol(c, zig_symbol_name);
-}
-
-static AstNode *trans_create_post_crement(Context *c, ResultUsed result_used, TransScope *scope,
- const ZigClangUnaryOperator *stmt, BinOpType assign_op)
-{
- const ZigClangExpr *op_expr = ZigClangUnaryOperator_getSubExpr(stmt);
-
- if (result_used == ResultUsedNo) {
- // common case
- // c: expr++
- // zig: expr += 1
- return trans_create_node_bin_op(c,
- trans_expr(c, ResultUsedYes, scope, op_expr, TransLValue),
- assign_op,
- trans_create_node_unsigned(c, 1));
- }
- // worst case
- // c: expr++
- // zig: (x: {
- // zig: const _ref = &expr;
- // zig: const _tmp = *_ref;
- // zig: *_ref += 1;
- // zig: break :x _tmp
- // zig: })
- TransScopeBlock *child_scope = trans_scope_block_create(c, scope);
- Buf *label_name = buf_create_from_str("x");
- child_scope->node->data.block.name = label_name;
-
- // const _ref = &expr;
- AstNode *expr = trans_expr(c, ResultUsedYes, &child_scope->base, op_expr, TransLValue);
- if (expr == nullptr) return nullptr;
- AstNode *addr_of_expr = trans_create_node_addr_of(c, expr);
- // TODO: avoid name collisions with generated variable names
- Buf* ref_var_name = buf_create_from_str("_ref");
- AstNode *ref_var_decl = trans_create_node_var_decl_local(c, true, ref_var_name, nullptr, addr_of_expr);
- child_scope->node->data.block.statements.append(ref_var_decl);
-
- // const _tmp = *_ref;
- Buf* tmp_var_name = buf_create_from_str("_tmp");
- AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr,
- trans_create_node_ptr_deref(c,
- trans_create_node_symbol(c, ref_var_name)));
- child_scope->node->data.block.statements.append(tmp_var_decl);
-
- // *_ref += 1;
- AstNode *assign_statement = trans_create_node_bin_op(c,
- trans_create_node_ptr_deref(c,
- trans_create_node_symbol(c, ref_var_name)),
- assign_op,
- trans_create_node_unsigned(c, 1));
- child_scope->node->data.block.statements.append(assign_statement);
-
- // break :x _tmp
- child_scope->node->data.block.statements.append(trans_create_node_break(c, label_name, trans_create_node_symbol(c, tmp_var_name)));
-
- return trans_create_node_grouped_expr(c, child_scope->node);
-}
-
-static AstNode *trans_create_pre_crement(Context *c, ResultUsed result_used, TransScope *scope,
- const ZigClangUnaryOperator *stmt, BinOpType assign_op)
-{
- const ZigClangExpr *op_expr = ZigClangUnaryOperator_getSubExpr(stmt);
-
- if (result_used == ResultUsedNo) {
- // common case
- // c: ++expr
- // zig: expr += 1
- return trans_create_node_bin_op(c,
- trans_expr(c, ResultUsedYes, scope, op_expr, TransLValue),
- assign_op,
- trans_create_node_unsigned(c, 1));
- }
- // worst case
- // c: ++expr
- // zig: (x: {
- // zig: const _ref = &expr;
- // zig: *_ref += 1;
- // zig: break :x *_ref
- // zig: })
- TransScopeBlock *child_scope = trans_scope_block_create(c, scope);
- Buf *label_name = buf_create_from_str("x");
- child_scope->node->data.block.name = label_name;
-
- // const _ref = &expr;
- AstNode *expr = trans_expr(c, ResultUsedYes, &child_scope->base, op_expr, TransLValue);
- if (expr == nullptr) return nullptr;
- AstNode *addr_of_expr = trans_create_node_addr_of(c, expr);
- // TODO: avoid name collisions with generated variable names
- Buf* ref_var_name = buf_create_from_str("_ref");
- AstNode *ref_var_decl = trans_create_node_var_decl_local(c, true, ref_var_name, nullptr, addr_of_expr);
- child_scope->node->data.block.statements.append(ref_var_decl);
-
- // *_ref += 1;
- AstNode *assign_statement = trans_create_node_bin_op(c,
- trans_create_node_ptr_deref(c,
- trans_create_node_symbol(c, ref_var_name)),
- assign_op,
- trans_create_node_unsigned(c, 1));
- child_scope->node->data.block.statements.append(assign_statement);
-
- // break :x *_ref
- AstNode *deref_expr = trans_create_node_ptr_deref(c,
- trans_create_node_symbol(c, ref_var_name));
- child_scope->node->data.block.statements.append(trans_create_node_break(c, label_name, deref_expr));
-
- return trans_create_node_grouped_expr(c, child_scope->node);
-}
-
-static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransScope *scope,
- const ZigClangUnaryOperator *stmt)
-{
- switch (ZigClangUnaryOperator_getOpcode(stmt)) {
- case ZigClangUO_PostInc:
- if (qual_type_has_wrapping_overflow(c, ZigClangUnaryOperator_getType(stmt)))
- return trans_create_post_crement(c, result_used, scope, stmt, BinOpTypeAssignPlusWrap);
- else
- return trans_create_post_crement(c, result_used, scope, stmt, BinOpTypeAssignPlus);
- case ZigClangUO_PostDec:
- if (qual_type_has_wrapping_overflow(c, ZigClangUnaryOperator_getType(stmt)))
- return trans_create_post_crement(c, result_used, scope, stmt, BinOpTypeAssignMinusWrap);
- else
- return trans_create_post_crement(c, result_used, scope, stmt, BinOpTypeAssignMinus);
- case ZigClangUO_PreInc:
- if (qual_type_has_wrapping_overflow(c, ZigClangUnaryOperator_getType(stmt)))
- return trans_create_pre_crement(c, result_used, scope, stmt, BinOpTypeAssignPlusWrap);
- else
- return trans_create_pre_crement(c, result_used, scope, stmt, BinOpTypeAssignPlus);
- case ZigClangUO_PreDec:
- if (qual_type_has_wrapping_overflow(c, ZigClangUnaryOperator_getType(stmt)))
- return trans_create_pre_crement(c, result_used, scope, stmt, BinOpTypeAssignMinusWrap);
- else
- return trans_create_pre_crement(c, result_used, scope, stmt, BinOpTypeAssignMinus);
- case ZigClangUO_AddrOf:
- {
- AstNode *value_node = trans_expr(c, result_used, scope, ZigClangUnaryOperator_getSubExpr(stmt), TransLValue);
- if (value_node == nullptr)
- return value_node;
- return trans_create_node_addr_of(c, value_node);
- }
- case ZigClangUO_Deref:
- {
- AstNode *value_node = trans_expr(c, result_used, scope, ZigClangUnaryOperator_getSubExpr(stmt), TransRValue);
- if (value_node == nullptr)
- return nullptr;
- bool is_fn_ptr = qual_type_is_fn_ptr(ZigClangExpr_getType(ZigClangUnaryOperator_getSubExpr(stmt)));
- if (is_fn_ptr)
- return value_node;
- AstNode *unwrapped = trans_create_node_unwrap_null(c, value_node);
- return trans_create_node_ptr_deref(c, unwrapped);
- }
- case ZigClangUO_Plus:
- emit_warning(c, ZigClangUnaryOperator_getBeginLoc(stmt), "TODO handle C translation UO_Plus");
- return nullptr;
- case ZigClangUO_Minus:
- {
- const ZigClangExpr *op_expr = ZigClangUnaryOperator_getSubExpr(stmt);
- if (!qual_type_has_wrapping_overflow(c, ZigClangExpr_getType(op_expr))) {
- AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);
- node->data.prefix_op_expr.prefix_op = PrefixOpNegation;
-
- node->data.prefix_op_expr.primary_expr = trans_expr(c, ResultUsedYes, scope, op_expr, TransRValue);
- if (node->data.prefix_op_expr.primary_expr == nullptr)
- return nullptr;
-
- return node;
- } else if (c_is_unsigned_integer(c, ZigClangExpr_getType(op_expr))) {
- // we gotta emit 0 -% x
- AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
- node->data.bin_op_expr.op1 = trans_create_node_unsigned(c, 0);
-
- node->data.bin_op_expr.op2 = trans_expr(c, ResultUsedYes, scope, op_expr, TransRValue);
- if (node->data.bin_op_expr.op2 == nullptr)
- return nullptr;
-
- node->data.bin_op_expr.bin_op = BinOpTypeSubWrap;
- return node;
- } else {
- emit_warning(c, ZigClangUnaryOperator_getBeginLoc(stmt), "C negation with non float non integer");
- return nullptr;
- }
- }
- case ZigClangUO_Not:
- {
- const ZigClangExpr *op_expr = ZigClangUnaryOperator_getSubExpr(stmt);
- AstNode *sub_node = trans_expr(c, ResultUsedYes, scope, op_expr, TransRValue);
- if (sub_node == nullptr)
- return nullptr;
-
- return trans_create_node_prefix_op(c, PrefixOpBinNot, sub_node);
- }
- case ZigClangUO_LNot:
- {
- const ZigClangExpr *op_expr = ZigClangUnaryOperator_getSubExpr(stmt);
- AstNode *sub_node = trans_bool_expr(c, ResultUsedYes, scope, op_expr, TransRValue);
- if (sub_node == nullptr)
- return nullptr;
-
- return trans_create_node_prefix_op(c, PrefixOpBoolNot, sub_node);
- }
- case ZigClangUO_Real:
- emit_warning(c, ZigClangUnaryOperator_getBeginLoc(stmt), "TODO handle C translation UO_Real");
- return nullptr;
- case ZigClangUO_Imag:
- emit_warning(c, ZigClangUnaryOperator_getBeginLoc(stmt), "TODO handle C translation UO_Imag");
- return nullptr;
- case ZigClangUO_Extension:
- return trans_expr(c, result_used, scope, ZigClangUnaryOperator_getSubExpr(stmt), TransLValue);
- case ZigClangUO_Coawait:
- emit_warning(c, ZigClangUnaryOperator_getBeginLoc(stmt), "TODO handle C translation UO_Coawait");
- return nullptr;
- }
- zig_unreachable();
-}
-
-static int trans_local_declaration(Context *c, TransScope *scope, const ZigClangDeclStmt *stmt,
- AstNode **out_node, TransScope **out_scope)
-{
- // declarations are added via the scope
- *out_node = nullptr;
-
- TransScopeBlock *scope_block = trans_scope_block_find(scope);
- assert(scope_block != nullptr);
-
- for (ZigClangDeclStmt_const_decl_iterator iter = ZigClangDeclStmt_decl_begin(stmt),
- iter_end = ZigClangDeclStmt_decl_end(stmt);
- iter != iter_end; ++iter)
- {
- ZigClangDecl *decl = *iter;
- switch (ZigClangDecl_getKind(decl)) {
- case ZigClangDeclVar: {
- ZigClangVarDecl *var_decl = (ZigClangVarDecl *)decl;
- ZigClangQualType qual_type = ZigClangVarDecl_getTypeSourceInfo_getType(var_decl);
- AstNode *init_node = nullptr;
- if (ZigClangVarDecl_hasInit(var_decl)) {
- init_node = trans_expr(c, ResultUsedYes, scope, ZigClangVarDecl_getInit(var_decl), TransRValue);
- if (init_node == nullptr)
- return ErrorUnexpected;
-
- } else {
- init_node = trans_create_node(c, NodeTypeUndefinedLiteral);
- }
- AstNode *type_node = trans_qual_type(c, qual_type, ZigClangDeclStmt_getBeginLoc(stmt));
- if (type_node == nullptr)
- return ErrorUnexpected;
-
- Buf *c_symbol_name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)var_decl));
-
- TransScopeVar *var_scope = trans_scope_var_create(c, scope, c_symbol_name);
- scope = &var_scope->base;
-
- AstNode *node = trans_create_node_var_decl_local(c,
- ZigClangQualType_isConstQualified(qual_type),
- var_scope->zig_name, type_node, init_node);
-
- scope_block->node->data.block.statements.append(node);
- continue;
- }
- case ZigClangDeclAccessSpec:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle decl kind AccessSpec");
- return ErrorUnexpected;
- case ZigClangDeclBlock:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C Block");
- return ErrorUnexpected;
- case ZigClangDeclCaptured:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C Captured");
- return ErrorUnexpected;
- case ZigClangDeclClassScopeFunctionSpecialization:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C ClassScopeFunctionSpecialization");
- return ErrorUnexpected;
- case ZigClangDeclEmpty:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C Empty");
- return ErrorUnexpected;
- case ZigClangDeclExport:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C Export");
- return ErrorUnexpected;
- case ZigClangDeclExternCContext:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C ExternCContext");
- return ErrorUnexpected;
- case ZigClangDeclFileScopeAsm:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C FileScopeAsm");
- return ErrorUnexpected;
- case ZigClangDeclFriend:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C Friend");
- return ErrorUnexpected;
- case ZigClangDeclFriendTemplate:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C FriendTemplate");
- return ErrorUnexpected;
- case ZigClangDeclImport:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C Import");
- return ErrorUnexpected;
- case ZigClangDeclLinkageSpec:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C LinkageSpec");
- return ErrorUnexpected;
- case ZigClangDeclLabel:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C Label");
- return ErrorUnexpected;
- case ZigClangDeclNamespace:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C Namespace");
- return ErrorUnexpected;
- case ZigClangDeclNamespaceAlias:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C NamespaceAlias");
- return ErrorUnexpected;
- case ZigClangDeclObjCCompatibleAlias:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C ObjCCompatibleAlias");
- return ErrorUnexpected;
- case ZigClangDeclObjCCategory:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C ObjCCategory");
- return ErrorUnexpected;
- case ZigClangDeclObjCCategoryImpl:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C ObjCCategoryImpl");
- return ErrorUnexpected;
- case ZigClangDeclObjCImplementation:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C ObjCImplementation");
- return ErrorUnexpected;
- case ZigClangDeclObjCInterface:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C ObjCInterface");
- return ErrorUnexpected;
- case ZigClangDeclObjCProtocol:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C ObjCProtocol");
- return ErrorUnexpected;
- case ZigClangDeclObjCMethod:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C ObjCMethod");
- return ErrorUnexpected;
- case ZigClangDeclObjCProperty:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C ObjCProperty");
- return ErrorUnexpected;
- case ZigClangDeclBuiltinTemplate:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C BuiltinTemplate");
- return ErrorUnexpected;
- case ZigClangDeclClassTemplate:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C ClassTemplate");
- return ErrorUnexpected;
- case ZigClangDeclFunctionTemplate:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C FunctionTemplate");
- return ErrorUnexpected;
- case ZigClangDeclTypeAliasTemplate:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C TypeAliasTemplate");
- return ErrorUnexpected;
- case ZigClangDeclVarTemplate:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C VarTemplate");
- return ErrorUnexpected;
- case ZigClangDeclTemplateTemplateParm:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C TemplateTemplateParm");
- return ErrorUnexpected;
- case ZigClangDeclEnum:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C Enum");
- return ErrorUnexpected;
- case ZigClangDeclRecord:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C Record");
- return ErrorUnexpected;
- case ZigClangDeclCXXRecord:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C CXXRecord");
- return ErrorUnexpected;
- case ZigClangDeclClassTemplateSpecialization:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C ClassTemplateSpecialization");
- return ErrorUnexpected;
- case ZigClangDeclClassTemplatePartialSpecialization:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C ClassTemplatePartialSpecialization");
- return ErrorUnexpected;
- case ZigClangDeclTemplateTypeParm:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C TemplateTypeParm");
- return ErrorUnexpected;
- case ZigClangDeclObjCTypeParam:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C ObjCTypeParam");
- return ErrorUnexpected;
- case ZigClangDeclTypeAlias:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C TypeAlias");
- return ErrorUnexpected;
- case ZigClangDeclTypedef:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C Typedef");
- return ErrorUnexpected;
- case ZigClangDeclUnresolvedUsingTypename:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C UnresolvedUsingTypename");
- return ErrorUnexpected;
- case ZigClangDeclUsing:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C Using");
- return ErrorUnexpected;
- case ZigClangDeclUsingDirective:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C UsingDirective");
- return ErrorUnexpected;
- case ZigClangDeclUsingPack:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C UsingPack");
- return ErrorUnexpected;
- case ZigClangDeclUsingShadow:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C UsingShadow");
- return ErrorUnexpected;
- case ZigClangDeclConstructorUsingShadow:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C ConstructorUsingShadow");
- return ErrorUnexpected;
- case ZigClangDeclBinding:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C Binding");
- return ErrorUnexpected;
- case ZigClangDeclField:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C Field");
- return ErrorUnexpected;
- case ZigClangDeclObjCAtDefsField:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C ObjCAtDefsField");
- return ErrorUnexpected;
- case ZigClangDeclObjCIvar:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C ObjCIvar");
- return ErrorUnexpected;
- case ZigClangDeclFunction:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C Function");
- return ErrorUnexpected;
- case ZigClangDeclCXXDeductionGuide:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C CXXDeductionGuide");
- return ErrorUnexpected;
- case ZigClangDeclCXXMethod:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C CXXMethod");
- return ErrorUnexpected;
- case ZigClangDeclCXXConstructor:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C CXXConstructor");
- return ErrorUnexpected;
- case ZigClangDeclCXXConversion:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C CXXConversion");
- return ErrorUnexpected;
- case ZigClangDeclCXXDestructor:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C CXXDestructor");
- return ErrorUnexpected;
- case ZigClangDeclMSProperty:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C MSProperty");
- return ErrorUnexpected;
- case ZigClangDeclNonTypeTemplateParm:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C NonTypeTemplateParm");
- return ErrorUnexpected;
- case ZigClangDeclDecomposition:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C Decomposition");
- return ErrorUnexpected;
- case ZigClangDeclImplicitParam:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C ImplicitParam");
- return ErrorUnexpected;
- case ZigClangDeclOMPCapturedExpr:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C OMPCapturedExpr");
- return ErrorUnexpected;
- case ZigClangDeclParmVar:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C ParmVar");
- return ErrorUnexpected;
- case ZigClangDeclVarTemplateSpecialization:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C VarTemplateSpecialization");
- return ErrorUnexpected;
- case ZigClangDeclVarTemplatePartialSpecialization:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C VarTemplatePartialSpecialization");
- return ErrorUnexpected;
- case ZigClangDeclEnumConstant:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C EnumConstant");
- return ErrorUnexpected;
- case ZigClangDeclIndirectField:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C IndirectField");
- return ErrorUnexpected;
- case ZigClangDeclOMPDeclareReduction:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C OMPDeclareReduction");
- return ErrorUnexpected;
- case ZigClangDeclUnresolvedUsingValue:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C UnresolvedUsingValue");
- return ErrorUnexpected;
- case ZigClangDeclOMPRequires:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C OMPRequires");
- return ErrorUnexpected;
- case ZigClangDeclOMPThreadPrivate:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C OMPThreadPrivate");
- return ErrorUnexpected;
- case ZigClangDeclObjCPropertyImpl:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C ObjCPropertyImpl");
- return ErrorUnexpected;
- case ZigClangDeclPragmaComment:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C PragmaComment");
- return ErrorUnexpected;
- case ZigClangDeclPragmaDetectMismatch:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C PragmaDetectMismatch");
- return ErrorUnexpected;
- case ZigClangDeclStaticAssert:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C StaticAssert");
- return ErrorUnexpected;
- case ZigClangDeclTranslationUnit:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C TranslationUnit");
- return ErrorUnexpected;
- case ZigClangDeclConcept:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C Concept");
- return ErrorUnexpected;
- case ZigClangDeclOMPDeclareMapper:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C OMPDeclareMapper");
- return ErrorUnexpected;
- case ZigClangDeclOMPAllocate:
- emit_warning(c, ZigClangDeclStmt_getBeginLoc(stmt), "TODO handle C OMPAllocate");
- return ErrorUnexpected;
- }
- zig_unreachable();
- }
-
- *out_scope = scope;
- return ErrorNone;
-}
-
-static AstNode *to_enum_zero_cmp(Context *c, AstNode *expr, AstNode *enum_type) {
- AstNode *tag_type = trans_create_node_builtin_fn_call_str(c, "TagType");
- tag_type->data.fn_call_expr.params.append(enum_type);
-
- // @TagType(Enum)(0)
- AstNode *zero = trans_create_node_unsigned_negative(c, 0, false);
- AstNode *casted_zero = trans_create_node_cast(c, tag_type, zero);
-
- // @bitCast(Enum, @TagType(Enum)(0))
- AstNode *bitcast = trans_create_node_builtin_fn_call_str(c, "bitCast");
- bitcast->data.fn_call_expr.params.append(enum_type);
- bitcast->data.fn_call_expr.params.append(casted_zero);
-
- return trans_create_node_bin_op(c, expr, BinOpTypeCmpNotEq, bitcast);
-}
-
-static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *scope, const ZigClangExpr *expr, TransLRValue lrval) {
- AstNode *res = trans_expr(c, result_used, scope, expr, lrval);
- if (res == nullptr)
- return nullptr;
-
- switch (res->type) {
- case NodeTypeBinOpExpr:
- switch (res->data.bin_op_expr.bin_op) {
- case BinOpTypeBoolOr:
- case BinOpTypeBoolAnd:
- case BinOpTypeCmpEq:
- case BinOpTypeCmpNotEq:
- case BinOpTypeCmpLessThan:
- case BinOpTypeCmpGreaterThan:
- case BinOpTypeCmpLessOrEq:
- case BinOpTypeCmpGreaterOrEq:
- return res;
- default:
- break;
- }
-
- case NodeTypePrefixOpExpr:
- switch (res->data.prefix_op_expr.prefix_op) {
- case PrefixOpBoolNot:
- return res;
- default:
- break;
- }
-
- case NodeTypeBoolLiteral:
- return res;
-
- default:
- break;
- }
-
-
- const ZigClangType *ty = ZigClangQualType_getTypePtr(get_expr_qual_type_before_implicit_cast(c, expr));
- auto classs = ZigClangType_getTypeClass(ty);
- switch (classs) {
- case ZigClangType_Builtin:
- {
- const ZigClangBuiltinType *builtin_ty = reinterpret_cast<const ZigClangBuiltinType*>(ty);
- switch (ZigClangBuiltinType_getKind(builtin_ty)) {
- case ZigClangBuiltinTypeBool:
- case ZigClangBuiltinTypeChar_U:
- case ZigClangBuiltinTypeUChar:
- case ZigClangBuiltinTypeChar_S:
- case ZigClangBuiltinTypeSChar:
- case ZigClangBuiltinTypeUShort:
- case ZigClangBuiltinTypeUInt:
- case ZigClangBuiltinTypeULong:
- case ZigClangBuiltinTypeULongLong:
- case ZigClangBuiltinTypeShort:
- case ZigClangBuiltinTypeInt:
- case ZigClangBuiltinTypeLong:
- case ZigClangBuiltinTypeLongLong:
- case ZigClangBuiltinTypeUInt128:
- case ZigClangBuiltinTypeInt128:
- case ZigClangBuiltinTypeFloat:
- case ZigClangBuiltinTypeDouble:
- case ZigClangBuiltinTypeFloat128:
- case ZigClangBuiltinTypeLongDouble:
- case ZigClangBuiltinTypeWChar_U:
- case ZigClangBuiltinTypeChar8:
- case ZigClangBuiltinTypeChar16:
- case ZigClangBuiltinTypeChar32:
- case ZigClangBuiltinTypeWChar_S:
- case ZigClangBuiltinTypeFloat16:
- return trans_create_node_bin_op(c, res, BinOpTypeCmpNotEq, trans_create_node_unsigned_negative(c, 0, false));
- case ZigClangBuiltinTypeNullPtr:
- return trans_create_node_bin_op(c, res, BinOpTypeCmpNotEq,
- trans_create_node(c, NodeTypeNullLiteral));
-
- case ZigClangBuiltinTypeVoid:
- case ZigClangBuiltinTypeHalf:
- case ZigClangBuiltinTypeObjCId:
- case ZigClangBuiltinTypeObjCClass:
- case ZigClangBuiltinTypeObjCSel:
- case ZigClangBuiltinTypeOMPArraySection:
- case ZigClangBuiltinTypeDependent:
- case ZigClangBuiltinTypeOverload:
- case ZigClangBuiltinTypeBoundMember:
- case ZigClangBuiltinTypePseudoObject:
- case ZigClangBuiltinTypeUnknownAny:
- case ZigClangBuiltinTypeBuiltinFn:
- case ZigClangBuiltinTypeARCUnbridgedCast:
- case ZigClangBuiltinTypeOCLImage1dRO:
- case ZigClangBuiltinTypeOCLImage1dArrayRO:
- case ZigClangBuiltinTypeOCLImage1dBufferRO:
- case ZigClangBuiltinTypeOCLImage2dRO:
- case ZigClangBuiltinTypeOCLImage2dArrayRO:
- case ZigClangBuiltinTypeOCLImage2dDepthRO:
- case ZigClangBuiltinTypeOCLImage2dArrayDepthRO:
- case ZigClangBuiltinTypeOCLImage2dMSAARO:
- case ZigClangBuiltinTypeOCLImage2dArrayMSAARO:
- case ZigClangBuiltinTypeOCLImage2dMSAADepthRO:
- case ZigClangBuiltinTypeOCLImage2dArrayMSAADepthRO:
- case ZigClangBuiltinTypeOCLImage3dRO:
- case ZigClangBuiltinTypeOCLImage1dWO:
- case ZigClangBuiltinTypeOCLImage1dArrayWO:
- case ZigClangBuiltinTypeOCLImage1dBufferWO:
- case ZigClangBuiltinTypeOCLImage2dWO:
- case ZigClangBuiltinTypeOCLImage2dArrayWO:
- case ZigClangBuiltinTypeOCLImage2dDepthWO:
- case ZigClangBuiltinTypeOCLImage2dArrayDepthWO:
- case ZigClangBuiltinTypeOCLImage2dMSAAWO:
- case ZigClangBuiltinTypeOCLImage2dArrayMSAAWO:
- case ZigClangBuiltinTypeOCLImage2dMSAADepthWO:
- case ZigClangBuiltinTypeOCLImage2dArrayMSAADepthWO:
- case ZigClangBuiltinTypeOCLImage3dWO:
- case ZigClangBuiltinTypeOCLImage1dRW:
- case ZigClangBuiltinTypeOCLImage1dArrayRW:
- case ZigClangBuiltinTypeOCLImage1dBufferRW:
- case ZigClangBuiltinTypeOCLImage2dRW:
- case ZigClangBuiltinTypeOCLImage2dArrayRW:
- case ZigClangBuiltinTypeOCLImage2dDepthRW:
- case ZigClangBuiltinTypeOCLImage2dArrayDepthRW:
- case ZigClangBuiltinTypeOCLImage2dMSAARW:
- case ZigClangBuiltinTypeOCLImage2dArrayMSAARW:
- case ZigClangBuiltinTypeOCLImage2dMSAADepthRW:
- case ZigClangBuiltinTypeOCLImage2dArrayMSAADepthRW:
- case ZigClangBuiltinTypeOCLImage3dRW:
- case ZigClangBuiltinTypeOCLSampler:
- case ZigClangBuiltinTypeOCLEvent:
- case ZigClangBuiltinTypeOCLClkEvent:
- case ZigClangBuiltinTypeOCLQueue:
- case ZigClangBuiltinTypeOCLReserveID:
- case ZigClangBuiltinTypeShortAccum:
- case ZigClangBuiltinTypeAccum:
- case ZigClangBuiltinTypeLongAccum:
- case ZigClangBuiltinTypeUShortAccum:
- case ZigClangBuiltinTypeUAccum:
- case ZigClangBuiltinTypeULongAccum:
- case ZigClangBuiltinTypeShortFract:
- case ZigClangBuiltinTypeFract:
- case ZigClangBuiltinTypeLongFract:
- case ZigClangBuiltinTypeUShortFract:
- case ZigClangBuiltinTypeUFract:
- case ZigClangBuiltinTypeULongFract:
- case ZigClangBuiltinTypeSatShortAccum:
- case ZigClangBuiltinTypeSatAccum:
- case ZigClangBuiltinTypeSatLongAccum:
- case ZigClangBuiltinTypeSatUShortAccum:
- case ZigClangBuiltinTypeSatUAccum:
- case ZigClangBuiltinTypeSatULongAccum:
- case ZigClangBuiltinTypeSatShortFract:
- case ZigClangBuiltinTypeSatFract:
- case ZigClangBuiltinTypeSatLongFract:
- case ZigClangBuiltinTypeSatUShortFract:
- case ZigClangBuiltinTypeSatUFract:
- case ZigClangBuiltinTypeSatULongFract:
- case ZigClangBuiltinTypeOCLIntelSubgroupAVCMcePayload:
- case ZigClangBuiltinTypeOCLIntelSubgroupAVCImePayload:
- case ZigClangBuiltinTypeOCLIntelSubgroupAVCRefPayload:
- case ZigClangBuiltinTypeOCLIntelSubgroupAVCSicPayload:
- case ZigClangBuiltinTypeOCLIntelSubgroupAVCMceResult:
- case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResult:
- case ZigClangBuiltinTypeOCLIntelSubgroupAVCRefResult:
- case ZigClangBuiltinTypeOCLIntelSubgroupAVCSicResult:
- case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResultSingleRefStreamout:
- case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResultDualRefStreamout:
- case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeSingleRefStreamin:
- case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeDualRefStreamin:
- return res;
- }
- break;
- }
- case ZigClangType_Pointer:
- return trans_create_node_bin_op(c, res, BinOpTypeCmpNotEq, trans_create_node(c, NodeTypeNullLiteral));
-
- case ZigClangType_Typedef:
- {
- const ZigClangTypedefType *typedef_ty = reinterpret_cast<const ZigClangTypedefType*>(ty);
- const ZigClangTypedefNameDecl *typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
- auto existing_entry = c->decl_table.maybe_get((void*)ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl));
- if (existing_entry) {
- return existing_entry->value;
- }
-
- return res;
- }
-
- case ZigClangType_Enum:
- {
- const ZigClangEnumType *enum_ty = reinterpret_cast<const ZigClangEnumType *>(ty);
- AstNode *enum_type = resolve_enum_decl(c, ZigClangEnumType_getDecl(enum_ty));
- return to_enum_zero_cmp(c, res, enum_type);
- }
-
- case ZigClangType_Elaborated:
- {
- const ZigClangElaboratedType *elaborated_ty = reinterpret_cast<const ZigClangElaboratedType*>(ty);
- switch (ZigClangElaboratedType_getKeyword(elaborated_ty)) {
- case ZigClangETK_Enum: {
- AstNode *enum_type = trans_qual_type(c, ZigClangElaboratedType_getNamedType(elaborated_ty),
- ZigClangExpr_getBeginLoc(expr));
- return to_enum_zero_cmp(c, res, enum_type);
- }
- case ZigClangETK_Struct:
- case ZigClangETK_Union:
- case ZigClangETK_Interface:
- case ZigClangETK_Class:
- case ZigClangETK_Typename:
- case ZigClangETK_None:
- return res;
- }
- }
-
- case ZigClangType_FunctionProto:
- case ZigClangType_Record:
- case ZigClangType_ConstantArray:
- case ZigClangType_Paren:
- case ZigClangType_Decayed:
- case ZigClangType_Attributed:
- case ZigClangType_IncompleteArray:
- case ZigClangType_BlockPointer:
- case ZigClangType_LValueReference:
- case ZigClangType_RValueReference:
- case ZigClangType_MemberPointer:
- case ZigClangType_VariableArray:
- case ZigClangType_DependentSizedArray:
- case ZigClangType_DependentSizedExtVector:
- case ZigClangType_Vector:
- case ZigClangType_ExtVector:
- case ZigClangType_FunctionNoProto:
- case ZigClangType_UnresolvedUsing:
- case ZigClangType_Adjusted:
- case ZigClangType_TypeOfExpr:
- case ZigClangType_TypeOf:
- case ZigClangType_Decltype:
- case ZigClangType_UnaryTransform:
- case ZigClangType_TemplateTypeParm:
- case ZigClangType_SubstTemplateTypeParm:
- case ZigClangType_SubstTemplateTypeParmPack:
- case ZigClangType_TemplateSpecialization:
- case ZigClangType_Auto:
- case ZigClangType_InjectedClassName:
- case ZigClangType_DependentName:
- case ZigClangType_DependentTemplateSpecialization:
- case ZigClangType_PackExpansion:
- case ZigClangType_ObjCObject:
- case ZigClangType_ObjCInterface:
- case ZigClangType_Complex:
- case ZigClangType_ObjCObjectPointer:
- case ZigClangType_Atomic:
- case ZigClangType_Pipe:
- case ZigClangType_ObjCTypeParam:
- case ZigClangType_DeducedTemplateSpecialization:
- case ZigClangType_DependentAddressSpace:
- case ZigClangType_DependentVector:
- case ZigClangType_MacroQualified:
- return res;
- }
- zig_unreachable();
-}
-
-static AstNode *trans_while_loop(Context *c, TransScope *scope, const ZigClangWhileStmt *stmt) {
- TransScopeWhile *while_scope = trans_scope_while_create(c, scope);
-
- while_scope->node->data.while_expr.condition = trans_bool_expr(c, ResultUsedYes, scope,
- ZigClangWhileStmt_getCond(stmt), TransRValue);
- if (while_scope->node->data.while_expr.condition == nullptr)
- return nullptr;
-
- TransScope *body_scope = trans_stmt(c, &while_scope->base, ZigClangWhileStmt_getBody(stmt),
- &while_scope->node->data.while_expr.body);
- if (body_scope == nullptr)
- return nullptr;
-
- return while_scope->node;
-}
-
-static AstNode *trans_if_statement(Context *c, TransScope *scope, const ZigClangIfStmt *stmt) {
- // if (c) t
- // if (c) t else e
- AstNode *if_node = trans_create_node(c, NodeTypeIfBoolExpr);
-
- TransScope *then_scope = trans_stmt(c, scope, ZigClangIfStmt_getThen(stmt), &if_node->data.if_bool_expr.then_block);
- if (then_scope == nullptr)
- return nullptr;
-
- if (ZigClangIfStmt_getElse(stmt) != nullptr) {
- TransScope *else_scope = trans_stmt(c, scope, ZigClangIfStmt_getElse(stmt), &if_node->data.if_bool_expr.else_node);
- if (else_scope == nullptr)
- return nullptr;
- }
-
- if_node->data.if_bool_expr.condition = trans_bool_expr(c, ResultUsedYes, scope, ZigClangIfStmt_getCond(stmt),
- TransRValue);
- if (if_node->data.if_bool_expr.condition == nullptr)
- return nullptr;
-
- return if_node;
-}
-
-static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *scope, const ZigClangCallExpr *stmt) {
- AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
-
- AstNode *callee_raw_node = trans_expr(c, ResultUsedYes, scope, ZigClangCallExpr_getCallee(stmt), TransRValue);
- if (callee_raw_node == nullptr)
- return nullptr;
-
- bool is_ptr = false;
- const ZigClangFunctionProtoType *fn_ty = qual_type_get_fn_proto(
- ZigClangExpr_getType(ZigClangCallExpr_getCallee(stmt)), &is_ptr);
- AstNode *callee_node = nullptr;
- if (is_ptr && fn_ty) {
- if (ZigClangExpr_getStmtClass(ZigClangCallExpr_getCallee(stmt)) == ZigClangStmt_ImplicitCastExprClass) {
- const ZigClangImplicitCastExpr *implicit_cast = reinterpret_cast<const ZigClangImplicitCastExpr *>(
- ZigClangCallExpr_getCallee(stmt));
- if (ZigClangImplicitCastExpr_getCastKind(implicit_cast) == ZigClangCK_FunctionToPointerDecay) {
- const ZigClangExpr *subexpr = ZigClangImplicitCastExpr_getSubExpr(implicit_cast);
- if (ZigClangExpr_getStmtClass(subexpr) == ZigClangStmt_DeclRefExprClass) {
- const ZigClangDeclRefExpr *decl_ref = reinterpret_cast<const ZigClangDeclRefExpr *>(subexpr);
- const ZigClangNamedDecl *named_decl = ZigClangDeclRefExpr_getFoundDecl(decl_ref);
- if (ZigClangDecl_getKind((const ZigClangDecl *)named_decl) == ZigClangDeclFunction) {
- callee_node = callee_raw_node;
- }
- }
- }
- }
- if (callee_node == nullptr) {
- callee_node = trans_create_node_unwrap_null(c, callee_raw_node);
- }
- } else {
- callee_node = callee_raw_node;
- }
-
- node->data.fn_call_expr.fn_ref_expr = callee_node;
-
- unsigned num_args = ZigClangCallExpr_getNumArgs(stmt);
- const ZigClangExpr * const* args = ZigClangCallExpr_getArgs(stmt);
- for (unsigned i = 0; i < num_args; i += 1) {
- AstNode *arg_node = trans_expr(c, ResultUsedYes, scope, args[i], TransRValue);
- if (arg_node == nullptr)
- return nullptr;
-
- node->data.fn_call_expr.params.append(arg_node);
- }
-
- if (result_used == ResultUsedNo && fn_ty &&
- !ZigClangType_isVoidType(qual_type_canon(ZigClangFunctionProtoType_getReturnType(fn_ty))))
- {
- node = trans_create_node_bin_op(c, trans_create_node_symbol_str(c, "_"), BinOpTypeAssign, node);
- }
-
- return node;
-}
-
-static AstNode *trans_member_expr(Context *c, ResultUsed result_used, TransScope *scope,
- const ZigClangMemberExpr *stmt)
-{
- AstNode *container_node = trans_expr(c, ResultUsedYes, scope, ZigClangMemberExpr_getBase(stmt), TransRValue);
- if (container_node == nullptr)
- return nullptr;
-
- if (ZigClangMemberExpr_isArrow(stmt)) {
- container_node = trans_create_node_ptr_deref(c, container_node);
- }
-
- const char *name = ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)ZigClangMemberExpr_getMemberDecl(stmt));
-
- AstNode *node = trans_create_node_field_access_str(c, container_node, name);
- return maybe_suppress_result(c, result_used, node);
-}
-
-static AstNode *trans_array_subscript_expr(Context *c, ResultUsed result_used, TransScope *scope,
- const ZigClangArraySubscriptExpr *stmt)
-{
- AstNode *container_node = trans_expr(c, ResultUsedYes, scope, ZigClangArraySubscriptExpr_getBase(stmt),
- TransRValue);
- if (container_node == nullptr)
- return nullptr;
-
- AstNode *idx_node = trans_expr(c, ResultUsedYes, scope, ZigClangArraySubscriptExpr_getIdx(stmt), TransRValue);
- if (idx_node == nullptr)
- return nullptr;
-
-
- AstNode *node = trans_create_node(c, NodeTypeArrayAccessExpr);
- node->data.array_access_expr.array_ref_expr = container_node;
- node->data.array_access_expr.subscript = idx_node;
- return maybe_suppress_result(c, result_used, node);
-}
-
-static AstNode *trans_c_style_cast_expr(Context *c, ResultUsed result_used, TransScope *scope,
- const ZigClangCStyleCastExpr *stmt, TransLRValue lrvalue)
-{
- AstNode *sub_expr_node = trans_expr(c, ResultUsedYes, scope, ZigClangCStyleCastExpr_getSubExpr(stmt), lrvalue);
- if (sub_expr_node == nullptr)
- return nullptr;
-
- AstNode *cast = trans_c_cast(c, ZigClangCStyleCastExpr_getBeginLoc(stmt), ZigClangCStyleCastExpr_getType(stmt),
- ZigClangExpr_getType(ZigClangCStyleCastExpr_getSubExpr(stmt)), sub_expr_node);
- if (cast == nullptr)
- return nullptr;
-
- return maybe_suppress_result(c, result_used, cast);
-}
-
-static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, ResultUsed result_used,
- TransScope *scope, const ZigClangUnaryExprOrTypeTraitExpr *stmt)
-{
- AstNode *type_node = trans_qual_type(c, ZigClangUnaryExprOrTypeTraitExpr_getTypeOfArgument(stmt),
- ZigClangUnaryExprOrTypeTraitExpr_getBeginLoc(stmt));
- if (type_node == nullptr)
- return nullptr;
-
- AstNode *node = trans_create_node_builtin_fn_call_str(c, "sizeOf");
- node->data.fn_call_expr.params.append(type_node);
- return maybe_suppress_result(c, result_used, node);
-}
-
-static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const ZigClangDoStmt *stmt) {
- TransScopeWhile *while_scope = trans_scope_while_create(c, parent_scope);
-
- while_scope->node->data.while_expr.condition = trans_create_node_bool(c, true);
-
- AstNode *body_node;
- TransScope *child_scope;
- if (ZigClangStmt_getStmtClass(ZigClangDoStmt_getBody(stmt)) == ZigClangStmt_CompoundStmtClass) {
- // there's already a block in C, so we'll append our condition to it.
- // c: do {
- // c: a;
- // c: b;
- // c: } while(c);
- // zig: while (true) {
- // zig: a;
- // zig: b;
- // zig: if (!cond) break;
- // zig: }
-
- // We call the low level function so that we can set child_scope to the scope of the generated block.
- if (trans_stmt_extra(c, &while_scope->base, ZigClangDoStmt_getBody(stmt), ResultUsedNo, TransRValue,
- &body_node, nullptr, &child_scope))
- {
- return nullptr;
- }
- assert(body_node->type == NodeTypeBlock);
- } else {
- // the C statement is without a block, so we need to create a block to contain it.
- // c: do
- // c: a;
- // c: while(c);
- // zig: while (true) {
- // zig: a;
- // zig: if (!cond) break;
- // zig: }
- TransScopeBlock *child_block_scope = trans_scope_block_create(c, &while_scope->base);
- body_node = child_block_scope->node;
- AstNode *child_statement;
- child_scope = trans_stmt(c, &child_block_scope->base, ZigClangDoStmt_getBody(stmt), &child_statement);
- if (child_scope == nullptr) return nullptr;
- if (child_statement != nullptr) {
- body_node->data.block.statements.append(child_statement);
- }
- }
-
- // if (!cond) break;
- AstNode *condition_node = trans_expr(c, ResultUsedYes, child_scope, ZigClangDoStmt_getCond(stmt), TransRValue);
- if (condition_node == nullptr) return nullptr;
- AstNode *terminator_node = trans_create_node(c, NodeTypeIfBoolExpr);
- terminator_node->data.if_bool_expr.condition = trans_create_node_prefix_op(c, PrefixOpBoolNot, condition_node);
- terminator_node->data.if_bool_expr.then_block = trans_create_node(c, NodeTypeBreak);
-
- assert(terminator_node != nullptr);
- body_node->data.block.statements.append(terminator_node);
-
- while_scope->node->data.while_expr.body = body_node;
-
- return while_scope->node;
-}
-
-static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const ZigClangForStmt *stmt) {
- AstNode *loop_block_node;
- TransScopeWhile *while_scope;
- TransScope *cond_scope;
- const ZigClangStmt *init_stmt = ZigClangForStmt_getInit(stmt);
- if (init_stmt == nullptr) {
- while_scope = trans_scope_while_create(c, parent_scope);
- loop_block_node = while_scope->node;
- cond_scope = parent_scope;
- } else {
- TransScopeBlock *child_scope = trans_scope_block_create(c, parent_scope);
- loop_block_node = child_scope->node;
-
- AstNode *vars_node;
- cond_scope = trans_stmt(c, &child_scope->base, init_stmt, &vars_node);
- if (cond_scope == nullptr)
- return nullptr;
- if (vars_node != nullptr)
- child_scope->node->data.block.statements.append(vars_node);
-
- while_scope = trans_scope_while_create(c, cond_scope);
-
- child_scope->node->data.block.statements.append(while_scope->node);
- }
-
- const ZigClangExpr *cond_expr = ZigClangForStmt_getCond(stmt);
- if (cond_expr == nullptr) {
- while_scope->node->data.while_expr.condition = trans_create_node_bool(c, true);
- } else {
- while_scope->node->data.while_expr.condition = trans_bool_expr(c, ResultUsedYes, cond_scope,
- cond_expr, TransRValue);
-
- if (while_scope->node->data.while_expr.condition == nullptr)
- return nullptr;
- }
-
- const ZigClangExpr *inc_expr = ZigClangForStmt_getInc(stmt);
- if (inc_expr != nullptr) {
- AstNode *inc_node = trans_expr(c, ResultUsedNo, cond_scope, inc_expr, TransRValue);
- if (inc_node == nullptr)
- return nullptr;
- while_scope->node->data.while_expr.continue_expr = inc_node;
- }
-
- AstNode *body_statement;
- TransScope *body_scope = trans_stmt(c, &while_scope->base, ZigClangForStmt_getBody(stmt), &body_statement);
- if (body_scope == nullptr)
- return nullptr;
-
- if (body_statement == nullptr) {
- while_scope->node->data.while_expr.body = trans_create_node(c, NodeTypeBlock);
- } else {
- while_scope->node->data.while_expr.body = body_statement;
- }
-
- return loop_block_node;
-}
-
-static AstNode *trans_switch_stmt(Context *c, TransScope *parent_scope, const ZigClangSwitchStmt *stmt) {
- TransScopeBlock *block_scope = trans_scope_block_create(c, parent_scope);
-
- TransScopeSwitch *switch_scope;
-
- const ZigClangDeclStmt *var_decl_stmt = ZigClangSwitchStmt_getConditionVariableDeclStmt(stmt);
- if (var_decl_stmt == nullptr) {
- switch_scope = trans_scope_switch_create(c, &block_scope->base);
- } else {
- AstNode *vars_node;
- TransScope *var_scope = trans_stmt(c, &block_scope->base, (const ZigClangStmt *)var_decl_stmt, &vars_node);
- if (var_scope == nullptr)
- return nullptr;
- if (vars_node != nullptr)
- block_scope->node->data.block.statements.append(vars_node);
- switch_scope = trans_scope_switch_create(c, var_scope);
- }
- block_scope->node->data.block.statements.append(switch_scope->switch_node);
-
- // TODO avoid name collisions
- Buf *end_label_name = buf_create_from_str("__switch");
- switch_scope->end_label_name = end_label_name;
- block_scope->node->data.block.name = end_label_name;
-
- const ZigClangExpr *cond_expr = ZigClangSwitchStmt_getCond(stmt);
- assert(cond_expr != nullptr);
-
- AstNode *expr_node = trans_expr(c, ResultUsedYes, &block_scope->base, cond_expr, TransRValue);
- if (expr_node == nullptr)
- return nullptr;
- switch_scope->switch_node->data.switch_expr.expr = expr_node;
-
- AstNode *body_node;
- const ZigClangStmt *body_stmt = ZigClangSwitchStmt_getBody(stmt);
- if (ZigClangStmt_getStmtClass(body_stmt) == ZigClangStmt_CompoundStmtClass) {
- if (trans_compound_stmt_inline(c, &switch_scope->base, (const ZigClangCompoundStmt *)body_stmt,
- block_scope->node, nullptr))
- {
- return nullptr;
- }
- } else {
- TransScope *body_scope = trans_stmt(c, &switch_scope->base, body_stmt, &body_node);
- if (body_scope == nullptr)
- return nullptr;
- if (body_node != nullptr)
- block_scope->node->data.block.statements.append(body_node);
- }
-
- if (!switch_scope->found_default && !ZigClangSwitchStmt_isAllEnumCasesCovered(stmt)) {
- AstNode *prong_node = trans_create_node(c, NodeTypeSwitchProng);
- prong_node->data.switch_prong.expr = trans_create_node_break(c, end_label_name, nullptr);
- switch_scope->switch_node->data.switch_expr.prongs.append(prong_node);
- }
-
- return block_scope->node;
-}
-
-static TransScopeSwitch *trans_scope_switch_find(TransScope *scope) {
- while (scope != nullptr) {
- if (scope->id == TransScopeIdSwitch) {
- return (TransScopeSwitch *)scope;
- }
- scope = scope->parent;
- }
- return nullptr;
-}
-
-static int trans_switch_case(Context *c, TransScope *parent_scope, const ZigClangCaseStmt *stmt, AstNode **out_node,
- TransScope **out_scope) {
- *out_node = nullptr;
-
- if (ZigClangCaseStmt_getRHS(stmt) != nullptr) {
- emit_warning(c, ZigClangCaseStmt_getBeginLoc(stmt), "TODO support GNU switch case a ... b extension");
- return ErrorUnexpected;
- }
-
- TransScopeSwitch *switch_scope = trans_scope_switch_find(parent_scope);
- assert(switch_scope != nullptr);
-
- Buf *label_name = buf_sprintf("__case_%" PRIu32, switch_scope->case_index);
- switch_scope->case_index += 1;
-
- {
- // Add the prong
- AstNode *prong_node = trans_create_node(c, NodeTypeSwitchProng);
- AstNode *item_node = trans_expr(c, ResultUsedYes, &switch_scope->base, ZigClangCaseStmt_getLHS(stmt),
- TransRValue);
- if (item_node == nullptr)
- return ErrorUnexpected;
- prong_node->data.switch_prong.items.append(item_node);
- prong_node->data.switch_prong.expr = trans_create_node_break(c, label_name, nullptr);
- switch_scope->switch_node->data.switch_expr.prongs.append(prong_node);
- }
-
- TransScopeBlock *scope_block = trans_scope_block_find(parent_scope);
-
- AstNode *case_block = trans_create_node(c, NodeTypeBlock);
- case_block->data.block.name = label_name;
- case_block->data.block.statements = scope_block->node->data.block.statements;
- scope_block->node->data.block.statements = {0};
- scope_block->node->data.block.statements.append(case_block);
-
- AstNode *sub_stmt_node;
- TransScope *new_scope = trans_stmt(c, parent_scope, ZigClangCaseStmt_getSubStmt(stmt), &sub_stmt_node);
- if (new_scope == nullptr)
- return ErrorUnexpected;
- if (sub_stmt_node != nullptr)
- scope_block->node->data.block.statements.append(sub_stmt_node);
-
- *out_scope = new_scope;
- return ErrorNone;
-}
-
-static int trans_switch_default(Context *c, TransScope *parent_scope, const ZigClangDefaultStmt *stmt,
- AstNode **out_node, TransScope **out_scope)
-{
- *out_node = nullptr;
-
- TransScopeSwitch *switch_scope = trans_scope_switch_find(parent_scope);
- assert(switch_scope != nullptr);
-
- Buf *label_name = buf_sprintf("__default");
-
- {
- // Add the prong
- AstNode *prong_node = trans_create_node(c, NodeTypeSwitchProng);
- prong_node->data.switch_prong.expr = trans_create_node_break(c, label_name, nullptr);
- switch_scope->switch_node->data.switch_expr.prongs.append(prong_node);
- switch_scope->found_default = true;
- }
-
- TransScopeBlock *scope_block = trans_scope_block_find(parent_scope);
-
- AstNode *case_block = trans_create_node(c, NodeTypeBlock);
- case_block->data.block.name = label_name;
- case_block->data.block.statements = scope_block->node->data.block.statements;
- scope_block->node->data.block.statements = {0};
- scope_block->node->data.block.statements.append(case_block);
-
- AstNode *sub_stmt_node;
- TransScope *new_scope = trans_stmt(c, parent_scope, ZigClangDefaultStmt_getSubStmt(stmt), &sub_stmt_node);
- if (new_scope == nullptr)
- return ErrorUnexpected;
- if (sub_stmt_node != nullptr)
- scope_block->node->data.block.statements.append(sub_stmt_node);
-
- *out_scope = new_scope;
- return ErrorNone;
-}
-
-static AstNode *trans_string_literal(Context *c, ResultUsed result_used, TransScope *scope,
- const ZigClangStringLiteral *stmt)
-{
- switch (ZigClangStringLiteral_getKind(stmt)) {
- case ZigClangStringLiteral_StringKind_Ascii:
- case ZigClangStringLiteral_StringKind_UTF8: {
- size_t str_len;
- const char *str_ptr = ZigClangStringLiteral_getString_bytes_begin_size(stmt, &str_len);
- AstNode *node = trans_create_node_str_lit(c, buf_create_from_mem(str_ptr, str_len));
- return maybe_suppress_result(c, result_used, node);
- }
- case ZigClangStringLiteral_StringKind_UTF16:
- emit_warning(c, ZigClangStmt_getBeginLoc((const ZigClangStmt *)stmt), "TODO support UTF16 string literals");
- return nullptr;
- case ZigClangStringLiteral_StringKind_UTF32:
- emit_warning(c, ZigClangStmt_getBeginLoc((const ZigClangStmt *)stmt), "TODO support UTF32 string literals");
- return nullptr;
- case ZigClangStringLiteral_StringKind_Wide:
- emit_warning(c, ZigClangStmt_getBeginLoc((const ZigClangStmt *)stmt), "TODO support wide string literals");
- return nullptr;
- }
- zig_unreachable();
-}
-
-static AstNode *trans_break_stmt(Context *c, TransScope *scope, const ZigClangBreakStmt *stmt) {
- TransScope *cur_scope = scope;
- while (cur_scope != nullptr) {
- if (cur_scope->id == TransScopeIdWhile) {
- return trans_create_node(c, NodeTypeBreak);
- } else if (cur_scope->id == TransScopeIdSwitch) {
- TransScopeSwitch *switch_scope = (TransScopeSwitch *)cur_scope;
- return trans_create_node_break(c, switch_scope->end_label_name, nullptr);
- }
- cur_scope = cur_scope->parent;
- }
- zig_unreachable();
-}
-
-static AstNode *trans_continue_stmt(Context *c, TransScope *scope, const ZigClangContinueStmt *stmt) {
- return trans_create_node(c, NodeTypeContinue);
-}
-
-static AstNode *trans_predefined_expr(Context *c, ResultUsed result_used, TransScope *scope,
- const ZigClangPredefinedExpr *expr)
-{
- return trans_string_literal(c, result_used, scope, ZigClangPredefinedExpr_getFunctionName(expr));
-}
-
-static int wrap_stmt(AstNode **out_node, TransScope **out_scope, TransScope *in_scope, AstNode *result_node) {
- if (result_node == nullptr)
- return ErrorUnexpected;
- *out_node = result_node;
- if (out_scope != nullptr)
- *out_scope = in_scope;
- return ErrorNone;
-}
-
-static int trans_stmt_extra(Context *c, TransScope *scope, const ZigClangStmt *stmt,
- ResultUsed result_used, TransLRValue lrvalue,
- AstNode **out_node, TransScope **out_child_scope,
- TransScope **out_node_scope)
-{
- ZigClangStmtClass sc = ZigClangStmt_getStmtClass(stmt);
- switch (sc) {
- case ZigClangStmt_ReturnStmtClass:
- return wrap_stmt(out_node, out_child_scope, scope,
- trans_return_stmt(c, scope, (const ZigClangReturnStmt *)stmt));
- case ZigClangStmt_CompoundStmtClass:
- return wrap_stmt(out_node, out_child_scope, scope,
- trans_compound_stmt(c, scope, (const ZigClangCompoundStmt *)stmt, out_node_scope));
- case ZigClangStmt_IntegerLiteralClass:
- return wrap_stmt(out_node, out_child_scope, scope,
- trans_integer_literal(c, result_used, (const ZigClangIntegerLiteral *)stmt));
- case ZigClangStmt_ConditionalOperatorClass:
- return wrap_stmt(out_node, out_child_scope, scope,
- trans_conditional_operator(c, result_used, scope, (const ZigClangConditionalOperator *)stmt));
- case ZigClangStmt_BinaryOperatorClass:
- return wrap_stmt(out_node, out_child_scope, scope,
- trans_binary_operator(c, result_used, scope, (const ZigClangBinaryOperator *)stmt));
- case ZigClangStmt_CompoundAssignOperatorClass:
- return wrap_stmt(out_node, out_child_scope, scope,
- trans_compound_assign_operator(c, result_used, scope, (const ZigClangCompoundAssignOperator *)stmt));
- case ZigClangStmt_ImplicitCastExprClass:
- return wrap_stmt(out_node, out_child_scope, scope,
- trans_implicit_cast_expr(c, result_used, scope, (const ZigClangImplicitCastExpr *)stmt));
- case ZigClangStmt_DeclRefExprClass:
- return wrap_stmt(out_node, out_child_scope, scope,
- trans_decl_ref_expr(c, scope, (const ZigClangDeclRefExpr *)stmt, lrvalue));
- case ZigClangStmt_UnaryOperatorClass:
- return wrap_stmt(out_node, out_child_scope, scope,
- trans_unary_operator(c, result_used, scope, (const ZigClangUnaryOperator *)stmt));
- case ZigClangStmt_DeclStmtClass:
- return trans_local_declaration(c, scope, (const ZigClangDeclStmt *)stmt, out_node, out_child_scope);
- case ZigClangStmt_DoStmtClass:
- case ZigClangStmt_WhileStmtClass: {
- AstNode *while_node = sc == ZigClangStmt_DoStmtClass
- ? trans_do_loop(c, scope, (const ZigClangDoStmt *)stmt)
- : trans_while_loop(c, scope, (const ZigClangWhileStmt *)stmt);
-
- if (while_node == nullptr)
- return ErrorUnexpected;
-
- assert(while_node->type == NodeTypeWhileExpr);
- if (while_node->data.while_expr.body == nullptr)
- while_node->data.while_expr.body = trans_create_node(c, NodeTypeBlock);
-
- return wrap_stmt(out_node, out_child_scope, scope, while_node);
- }
- case ZigClangStmt_IfStmtClass:
- return wrap_stmt(out_node, out_child_scope, scope,
- trans_if_statement(c, scope, (const ZigClangIfStmt *)stmt));
- case ZigClangStmt_CallExprClass:
- return wrap_stmt(out_node, out_child_scope, scope,
- trans_call_expr(c, result_used, scope, (const ZigClangCallExpr *)stmt));
- case ZigClangStmt_NullStmtClass:
- *out_node = trans_create_node(c, NodeTypeBlock);
- *out_child_scope = scope;
- return ErrorNone;
- case ZigClangStmt_MemberExprClass:
- return wrap_stmt(out_node, out_child_scope, scope,
- trans_member_expr(c, result_used, scope, (const ZigClangMemberExpr *)stmt));
- case ZigClangStmt_ArraySubscriptExprClass:
- return wrap_stmt(out_node, out_child_scope, scope,
- trans_array_subscript_expr(c, result_used, scope, (const ZigClangArraySubscriptExpr *)stmt));
- case ZigClangStmt_CStyleCastExprClass:
- return wrap_stmt(out_node, out_child_scope, scope,
- trans_c_style_cast_expr(c, result_used, scope, (const ZigClangCStyleCastExpr *)stmt, lrvalue));
- case ZigClangStmt_UnaryExprOrTypeTraitExprClass:
- return wrap_stmt(out_node, out_child_scope, scope,
- trans_unary_expr_or_type_trait_expr(c, result_used, scope, (const ZigClangUnaryExprOrTypeTraitExpr *)stmt));
- case ZigClangStmt_ForStmtClass: {
- AstNode *node = trans_for_loop(c, scope, (const ZigClangForStmt *)stmt);
- return wrap_stmt(out_node, out_child_scope, scope, node);
- }
- case ZigClangStmt_StringLiteralClass:
- return wrap_stmt(out_node, out_child_scope, scope,
- trans_string_literal(c, result_used, scope, (const ZigClangStringLiteral *)stmt));
- case ZigClangStmt_BreakStmtClass:
- return wrap_stmt(out_node, out_child_scope, scope,
- trans_break_stmt(c, scope, (const ZigClangBreakStmt *)stmt));
- case ZigClangStmt_ContinueStmtClass:
- return wrap_stmt(out_node, out_child_scope, scope,
- trans_continue_stmt(c, scope, (const ZigClangContinueStmt *)stmt));
- case ZigClangStmt_ParenExprClass:
- return wrap_stmt(out_node, out_child_scope, scope,
- trans_expr(c, result_used, scope,
- ZigClangParenExpr_getSubExpr((const ZigClangParenExpr *)stmt), lrvalue));
- case ZigClangStmt_SwitchStmtClass:
- return wrap_stmt(out_node, out_child_scope, scope,
- trans_switch_stmt(c, scope, (const ZigClangSwitchStmt *)stmt));
- case ZigClangStmt_CaseStmtClass:
- return trans_switch_case(c, scope, (const ZigClangCaseStmt *)stmt, out_node, out_child_scope);
- case ZigClangStmt_DefaultStmtClass:
- return trans_switch_default(c, scope, (const ZigClangDefaultStmt *)stmt, out_node, out_child_scope);
- case ZigClangStmt_ConstantExprClass:
- return wrap_stmt(out_node, out_child_scope, scope,
- trans_constant_expr(c, result_used, (const ZigClangConstantExpr *)stmt));
- case ZigClangStmt_PredefinedExprClass:
- return wrap_stmt(out_node, out_child_scope, scope,
- trans_predefined_expr(c, result_used, scope, (const ZigClangPredefinedExpr *)stmt));
- case ZigClangStmt_StmtExprClass:
- return wrap_stmt(out_node, out_child_scope, scope,
- trans_stmt_expr(c, result_used, scope, (const ZigClangStmtExpr *)stmt, out_node_scope));
- case ZigClangStmt_NoStmtClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C NoStmtClass");
- return ErrorUnexpected;
- case ZigClangStmt_GCCAsmStmtClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C GCCAsmStmtClass");
- return ErrorUnexpected;
- case ZigClangStmt_MSAsmStmtClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C MSAsmStmtClass");
- return ErrorUnexpected;
- case ZigClangStmt_AttributedStmtClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C AttributedStmtClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXCatchStmtClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXCatchStmtClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXForRangeStmtClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXForRangeStmtClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXTryStmtClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXTryStmtClass");
- return ErrorUnexpected;
- case ZigClangStmt_CapturedStmtClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CapturedStmtClass");
- return ErrorUnexpected;
- case ZigClangStmt_CoreturnStmtClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CoreturnStmtClass");
- return ErrorUnexpected;
- case ZigClangStmt_CoroutineBodyStmtClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CoroutineBodyStmtClass");
- return ErrorUnexpected;
- case ZigClangStmt_BinaryConditionalOperatorClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C BinaryConditionalOperatorClass");
- return ErrorUnexpected;
- case ZigClangStmt_AddrLabelExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C AddrLabelExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_ArrayInitIndexExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ArrayInitIndexExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_ArrayInitLoopExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ArrayInitLoopExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_ArrayTypeTraitExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ArrayTypeTraitExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_AsTypeExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C AsTypeExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_AtomicExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C AtomicExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_BlockExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C BlockExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXBindTemporaryExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXBindTemporaryExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXBoolLiteralExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXBoolLiteralExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXConstructExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXConstructExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXTemporaryObjectExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXTemporaryObjectExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXDefaultArgExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXDefaultArgExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXDefaultInitExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXDefaultInitExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXDeleteExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXDeleteExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXDependentScopeMemberExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXDependentScopeMemberExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXFoldExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXFoldExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXInheritedCtorInitExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXInheritedCtorInitExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXNewExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXNewExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXNoexceptExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXNoexceptExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXNullPtrLiteralExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXNullPtrLiteralExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXPseudoDestructorExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXPseudoDestructorExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXScalarValueInitExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXScalarValueInitExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXStdInitializerListExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXStdInitializerListExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXThisExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXThisExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXThrowExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXThrowExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXTypeidExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXTypeidExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXUnresolvedConstructExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXUnresolvedConstructExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXUuidofExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXUuidofExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CUDAKernelCallExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CUDAKernelCallExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXMemberCallExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXMemberCallExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXOperatorCallExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXOperatorCallExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_UserDefinedLiteralClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C UserDefinedLiteralClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXFunctionalCastExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXFunctionalCastExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXConstCastExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXConstCastExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXDynamicCastExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXDynamicCastExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXReinterpretCastExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXReinterpretCastExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CXXStaticCastExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXStaticCastExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_ObjCBridgedCastExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCBridgedCastExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CharacterLiteralClass:
- return wrap_stmt(out_node, out_child_scope, scope,
- trans_character_literal(c, result_used, (const ZigClangCharacterLiteral *)stmt));
- return ErrorUnexpected;
- case ZigClangStmt_ChooseExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ChooseExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CompoundLiteralExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CompoundLiteralExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_ConvertVectorExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ConvertVectorExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CoawaitExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CoawaitExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_CoyieldExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CoyieldExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_DependentCoawaitExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C DependentCoawaitExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_DependentScopeDeclRefExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C DependentScopeDeclRefExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_DesignatedInitExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C DesignatedInitExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_DesignatedInitUpdateExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C DesignatedInitUpdateExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_ExpressionTraitExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ExpressionTraitExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_ExtVectorElementExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ExtVectorElementExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_FixedPointLiteralClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C FixedPointLiteralClass");
- return ErrorUnexpected;
- case ZigClangStmt_FloatingLiteralClass:
- return wrap_stmt(out_node, out_child_scope, scope,
- trans_floating_literal(c, result_used, (const ZigClangFloatingLiteral *)stmt));
- case ZigClangStmt_ExprWithCleanupsClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ExprWithCleanupsClass");
- return ErrorUnexpected;
- case ZigClangStmt_FunctionParmPackExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C FunctionParmPackExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_GNUNullExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C GNUNullExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_GenericSelectionExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C GenericSelectionExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_ImaginaryLiteralClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ImaginaryLiteralClass");
- return ErrorUnexpected;
- case ZigClangStmt_ImplicitValueInitExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ImplicitValueInitExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_InitListExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C InitListExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_LambdaExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C LambdaExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_MSPropertyRefExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C MSPropertyRefExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_MSPropertySubscriptExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C MSPropertySubscriptExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_MaterializeTemporaryExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C MaterializeTemporaryExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_NoInitExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C NoInitExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPArraySectionExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPArraySectionExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_ObjCArrayLiteralClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCArrayLiteralClass");
- return ErrorUnexpected;
- case ZigClangStmt_ObjCAvailabilityCheckExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAvailabilityCheckExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_ObjCBoolLiteralExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCBoolLiteralExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_ObjCBoxedExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCBoxedExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_ObjCDictionaryLiteralClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCDictionaryLiteralClass");
- return ErrorUnexpected;
- case ZigClangStmt_ObjCEncodeExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCEncodeExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_ObjCIndirectCopyRestoreExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCIndirectCopyRestoreExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_ObjCIsaExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCIsaExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_ObjCIvarRefExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCIvarRefExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_ObjCMessageExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCMessageExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_ObjCPropertyRefExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCPropertyRefExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_ObjCProtocolExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCProtocolExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_ObjCSelectorExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCSelectorExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_ObjCStringLiteralClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCStringLiteralClass");
- return ErrorUnexpected;
- case ZigClangStmt_ObjCSubscriptRefExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCSubscriptRefExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_OffsetOfExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OffsetOfExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_OpaqueValueExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OpaqueValueExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_UnresolvedLookupExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C UnresolvedLookupExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_UnresolvedMemberExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C UnresolvedMemberExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_PackExpansionExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C PackExpansionExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_ParenListExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ParenListExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_PseudoObjectExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C PseudoObjectExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_ShuffleVectorExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ShuffleVectorExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_SizeOfPackExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SizeOfPackExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_SubstNonTypeTemplateParmExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SubstNonTypeTemplateParmExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_SubstNonTypeTemplateParmPackExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SubstNonTypeTemplateParmPackExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_TypeTraitExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C TypeTraitExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_TypoExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C TypoExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_VAArgExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C VAArgExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_GotoStmtClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C GotoStmtClass");
- return ErrorUnexpected;
- case ZigClangStmt_IndirectGotoStmtClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C IndirectGotoStmtClass");
- return ErrorUnexpected;
- case ZigClangStmt_LabelStmtClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C LabelStmtClass");
- return ErrorUnexpected;
- case ZigClangStmt_MSDependentExistsStmtClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C MSDependentExistsStmtClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPAtomicDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPAtomicDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPBarrierDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPBarrierDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPCancelDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPCancelDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPCancellationPointDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPCancellationPointDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPCriticalDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPCriticalDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPFlushDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPFlushDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPDistributeDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPDistributeDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPDistributeParallelForDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPDistributeParallelForDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPDistributeParallelForSimdDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPDistributeParallelForSimdDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPDistributeSimdDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPDistributeSimdDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPForDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPForDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPForSimdDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPForSimdDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPParallelForDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPParallelForDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPParallelForSimdDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPParallelForSimdDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPSimdDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPSimdDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPTargetParallelForSimdDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetParallelForSimdDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPTargetSimdDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetSimdDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPTargetTeamsDistributeDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetTeamsDistributeDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPTargetTeamsDistributeParallelForDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetTeamsDistributeParallelForDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetTeamsDistributeParallelForSimdDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPTargetTeamsDistributeSimdDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetTeamsDistributeSimdDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPTaskLoopDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTaskLoopDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPTaskLoopSimdDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTaskLoopSimdDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPTeamsDistributeDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTeamsDistributeDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPTeamsDistributeParallelForDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTeamsDistributeParallelForDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPTeamsDistributeParallelForSimdDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTeamsDistributeParallelForSimdDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPTeamsDistributeSimdDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTeamsDistributeSimdDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPMasterDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPMasterDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPOrderedDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPOrderedDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPParallelDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPParallelDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPParallelSectionsDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPParallelSectionsDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPSectionDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPSectionDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPSectionsDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPSectionsDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPSingleDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPSingleDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPTargetDataDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetDataDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPTargetDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPTargetEnterDataDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetEnterDataDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPTargetExitDataDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetExitDataDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPTargetParallelDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetParallelDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPTargetParallelForDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetParallelForDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPTargetTeamsDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetTeamsDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPTargetUpdateDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetUpdateDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPTaskDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTaskDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPTaskgroupDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTaskgroupDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPTaskwaitDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTaskwaitDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPTaskyieldDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTaskyieldDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_OMPTeamsDirectiveClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTeamsDirectiveClass");
- return ErrorUnexpected;
- case ZigClangStmt_ObjCAtCatchStmtClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAtCatchStmtClass");
- return ErrorUnexpected;
- case ZigClangStmt_ObjCAtFinallyStmtClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAtFinallyStmtClass");
- return ErrorUnexpected;
- case ZigClangStmt_ObjCAtSynchronizedStmtClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAtSynchronizedStmtClass");
- return ErrorUnexpected;
- case ZigClangStmt_ObjCAtThrowStmtClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAtThrowStmtClass");
- return ErrorUnexpected;
- case ZigClangStmt_ObjCAtTryStmtClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAtTryStmtClass");
- return ErrorUnexpected;
- case ZigClangStmt_ObjCAutoreleasePoolStmtClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAutoreleasePoolStmtClass");
- return ErrorUnexpected;
- case ZigClangStmt_ObjCForCollectionStmtClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCForCollectionStmtClass");
- return ErrorUnexpected;
- case ZigClangStmt_SEHExceptStmtClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SEHExceptStmtClass");
- return ErrorUnexpected;
- case ZigClangStmt_SEHFinallyStmtClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SEHFinallyStmtClass");
- return ErrorUnexpected;
- case ZigClangStmt_SEHLeaveStmtClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SEHLeaveStmtClass");
- return ErrorUnexpected;
- case ZigClangStmt_SEHTryStmtClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SEHTryStmtClass");
- return ErrorUnexpected;
- case ZigClangStmt_BuiltinBitCastExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C BuiltinBitCastExprClass");
- return ErrorUnexpected;
- case ZigClangStmt_SourceLocExprClass:
- emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SourceLocExprClass");
- return ErrorUnexpected;
- }
- zig_unreachable();
-}
-
-// Returns null if there was an error
-static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const ZigClangExpr *expr,
- TransLRValue lrval)
-{
- AstNode *result_node;
- TransScope *result_scope;
- if (trans_stmt_extra(c, scope, (const ZigClangStmt *)expr, result_used, lrval, &result_node, &result_scope, nullptr)) {
- return nullptr;
- }
- return result_node;
-}
-
-// Statements have no result and no concept of L or R value.
-// Returns child scope, or null if there was an error
-static TransScope *trans_stmt(Context *c, TransScope *scope, const ZigClangStmt *stmt, AstNode **out_node) {
- TransScope *child_scope;
- if (trans_stmt_extra(c, scope, stmt, ResultUsedNo, TransRValue, out_node, &child_scope, nullptr)) {
- return nullptr;
- }
- return child_scope;
-}
-
-static void visit_fn_decl(Context *c, const ZigClangFunctionDecl *fn_decl) {
- Buf *fn_name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)fn_decl));
-
- if (get_global(c, fn_name)) {
- // we already saw this function
- return;
- }
-
- AstNode *proto_node = trans_qual_type(c, ZigClangFunctionDecl_getType(fn_decl),
- ZigClangFunctionDecl_getLocation(fn_decl));
- if (proto_node == nullptr) {
- emit_warning(c, ZigClangFunctionDecl_getLocation(fn_decl),
- "unable to resolve prototype of function '%s'", buf_ptr(fn_name));
- return;
- }
-
- proto_node->data.fn_proto.name = fn_name;
- proto_node->data.fn_proto.is_extern = !ZigClangFunctionDecl_hasBody(fn_decl);
-
- ZigClangStorageClass sc = ZigClangFunctionDecl_getStorageClass(fn_decl);
- if (sc == ZigClangStorageClass_None) {
- proto_node->data.fn_proto.visib_mod = VisibModPub;
- proto_node->data.fn_proto.is_export = ZigClangFunctionDecl_hasBody(fn_decl) ? c->want_export : false;
- } else if (sc == ZigClangStorageClass_Extern || sc == ZigClangStorageClass_Static) {
- proto_node->data.fn_proto.visib_mod = VisibModPub;
- } else if (sc == ZigClangStorageClass_PrivateExtern) {
- emit_warning(c, ZigClangFunctionDecl_getLocation(fn_decl), "unsupported storage class: private extern");
- return;
- } else {
- emit_warning(c, ZigClangFunctionDecl_getLocation(fn_decl), "unsupported storage class: unknown");
- return;
- }
-
- TransScope *scope = &c->global_scope->base;
-
- for (size_t i = 0; i < proto_node->data.fn_proto.params.length; i += 1) {
- AstNode *param_node = proto_node->data.fn_proto.params.at(i);
- const ZigClangParmVarDecl *param = ZigClangFunctionDecl_getParamDecl(fn_decl, i);
- const char *name = ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)param);
-
- Buf *proto_param_name;
- if (strlen(name) != 0) {
- proto_param_name = buf_create_from_str(name);
- } else {
- proto_param_name = param_node->data.param_decl.name;
- if (proto_param_name == nullptr) {
- proto_param_name = buf_sprintf("arg%" ZIG_PRI_usize "", i);
- }
- }
-
- TransScopeVar *scope_var = trans_scope_var_create(c, scope, proto_param_name);
- scope = &scope_var->base;
-
- param_node->data.param_decl.name = scope_var->zig_name;
- }
-
- if (!ZigClangFunctionDecl_hasBody(fn_decl)) {
- // just a prototype
- add_top_level_decl(c, proto_node->data.fn_proto.name, proto_node);
- return;
- }
-
- // actual function definition with body
- c->ptr_params.clear();
- const ZigClangStmt *body = ZigClangFunctionDecl_getBody(fn_decl);
- AstNode *actual_body_node;
- TransScope *result_scope = trans_stmt(c, scope, body, &actual_body_node);
- if (result_scope == nullptr) {
- emit_warning(c, ZigClangFunctionDecl_getLocation(fn_decl), "unable to translate function");
- return;
- }
- assert(actual_body_node != nullptr);
- assert(actual_body_node->type == NodeTypeBlock);
-
- // it worked
-
- AstNode *body_node_with_param_inits = trans_create_node(c, NodeTypeBlock);
-
- for (size_t i = 0; i < proto_node->data.fn_proto.params.length; i += 1) {
- AstNode *param_node = proto_node->data.fn_proto.params.at(i);
- Buf *good_name = param_node->data.param_decl.name;
-
- if (c->ptr_params.maybe_get(good_name) != nullptr) {
- // TODO: avoid name collisions
- Buf *mangled_name = buf_sprintf("_arg_%s", buf_ptr(good_name));
- param_node->data.param_decl.name = mangled_name;
-
- // var c_name = _mangled_name;
- AstNode *parameter_init = trans_create_node_var_decl_local(c, false, good_name, nullptr, trans_create_node_symbol(c, mangled_name));
-
- body_node_with_param_inits->data.block.statements.append(parameter_init);
- }
- }
-
- for (size_t i = 0; i < actual_body_node->data.block.statements.length; i += 1) {
- body_node_with_param_inits->data.block.statements.append(actual_body_node->data.block.statements.at(i));
- }
-
- AstNode *fn_def_node = trans_create_node(c, NodeTypeFnDef);
- fn_def_node->data.fn_def.fn_proto = proto_node;
- fn_def_node->data.fn_def.body = body_node_with_param_inits;
-
- proto_node->data.fn_proto.fn_def_node = fn_def_node;
- add_top_level_decl(c, fn_def_node->data.fn_def.fn_proto->data.fn_proto.name, fn_def_node);
-}
-
-static AstNode *resolve_typdef_as_builtin(Context *c, const ZigClangTypedefNameDecl *typedef_decl, const char *primitive_name) {
- AstNode *node = trans_create_node_symbol_str(c, primitive_name);
- c->decl_table.put(typedef_decl, node);
- return node;
-}
-
-static AstNode *resolve_typedef_decl(Context *c, const ZigClangTypedefNameDecl *typedef_decl) {
- auto existing_entry = c->decl_table.maybe_get((void*)ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl));
- if (existing_entry) {
- return existing_entry->value;
- }
-
- ZigClangQualType child_qt = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);
- Buf *type_name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)typedef_decl));
-
- if (buf_eql_str(type_name, "uint8_t")) {
- return resolve_typdef_as_builtin(c, typedef_decl, "u8");
- } else if (buf_eql_str(type_name, "int8_t")) {
- return resolve_typdef_as_builtin(c, typedef_decl, "i8");
- } else if (buf_eql_str(type_name, "uint16_t")) {
- return resolve_typdef_as_builtin(c, typedef_decl, "u16");
- } else if (buf_eql_str(type_name, "int16_t")) {
- return resolve_typdef_as_builtin(c, typedef_decl, "i16");
- } else if (buf_eql_str(type_name, "uint32_t")) {
- return resolve_typdef_as_builtin(c, typedef_decl, "u32");
- } else if (buf_eql_str(type_name, "int32_t")) {
- return resolve_typdef_as_builtin(c, typedef_decl, "i32");
- } else if (buf_eql_str(type_name, "uint64_t")) {
- return resolve_typdef_as_builtin(c, typedef_decl, "u64");
- } else if (buf_eql_str(type_name, "int64_t")) {
- return resolve_typdef_as_builtin(c, typedef_decl, "i64");
- } else if (buf_eql_str(type_name, "intptr_t")) {
- return resolve_typdef_as_builtin(c, typedef_decl, "isize");
- } else if (buf_eql_str(type_name, "uintptr_t")) {
- return resolve_typdef_as_builtin(c, typedef_decl, "usize");
- } else if (buf_eql_str(type_name, "ssize_t")) {
- return resolve_typdef_as_builtin(c, typedef_decl, "isize");
- } else if (buf_eql_str(type_name, "size_t")) {
- return resolve_typdef_as_builtin(c, typedef_decl, "usize");
- }
-
- // if the underlying type is anonymous, we can special case it to just
- // use the name of this typedef
- // TODO
-
- // trans_qual_type here might cause us to look at this typedef again so we put the item in the map first
- AstNode *symbol_node = trans_create_node_symbol(c, type_name);
- c->decl_table.put(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl), symbol_node);
-
- AstNode *type_node = trans_qual_type(c, child_qt, ZigClangTypedefNameDecl_getLocation(typedef_decl));
- if (type_node == nullptr) {
- emit_warning(c, ZigClangTypedefNameDecl_getLocation(typedef_decl),
- "typedef %s - unresolved child type", buf_ptr(type_name));
- c->decl_table.put(typedef_decl, nullptr);
- // TODO add global var with type_name equal to @compileError("unable to resolve C type")
- return nullptr;
- }
- add_global_var(c, type_name, type_node);
-
- return symbol_node;
-}
-
-struct AstNode *demote_enum_to_opaque(Context *c, const ZigClangEnumDecl *enum_decl, Buf *full_type_name,
- Buf *bare_name)
-{
- AstNode *opaque_node = trans_create_node_opaque(c);
- if (full_type_name == nullptr) {
- c->decl_table.put(ZigClangEnumDecl_getCanonicalDecl(enum_decl), opaque_node);
- return opaque_node;
- }
- AstNode *symbol_node = trans_create_node_symbol(c, full_type_name);
- add_global_weak_alias(c, bare_name, full_type_name);
- add_global_var(c, full_type_name, opaque_node);
- c->decl_table.put(ZigClangEnumDecl_getCanonicalDecl(enum_decl), symbol_node);
- return symbol_node;
-}
-
-static AstNode *resolve_enum_decl(Context *c, const ZigClangEnumDecl *enum_decl) {
- auto existing_entry = c->decl_table.maybe_get(ZigClangEnumDecl_getCanonicalDecl(enum_decl));
- if (existing_entry) {
- return existing_entry->value;
- }
-
- const char *raw_name = ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)enum_decl);
- bool is_anonymous = (raw_name[0] == 0);
- Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name);
- Buf *full_type_name = is_anonymous ? nullptr : buf_sprintf("enum_%s", buf_ptr(bare_name));
-
- const ZigClangEnumDecl *enum_def = ZigClangEnumDecl_getDefinition(enum_decl);
- if (!enum_def) {
- return demote_enum_to_opaque(c, enum_decl, full_type_name, bare_name);
- }
-
-
- bool pure_enum = true;
- uint32_t field_count = 0;
- for (ZigClangEnumDecl_enumerator_iterator it = ZigClangEnumDecl_enumerator_begin(enum_def),
- it_end = ZigClangEnumDecl_enumerator_end(enum_def);
- ZigClangEnumDecl_enumerator_iterator_neq(it, it_end);
- it = ZigClangEnumDecl_enumerator_iterator_next(it), field_count += 1)
- {
- const ZigClangEnumConstantDecl *enum_const = ZigClangEnumDecl_enumerator_iterator_deref(it);
- if (ZigClangEnumConstantDecl_getInitExpr(enum_const)) {
- pure_enum = false;
- }
- }
- AstNode *tag_int_type = trans_qual_type(c, ZigClangEnumDecl_getIntegerType(enum_decl),
- ZigClangEnumDecl_getLocation(enum_decl));
- assert(tag_int_type);
-
- AstNode *enum_node = trans_create_node(c, NodeTypeContainerDecl);
- enum_node->data.container_decl.kind = ContainerKindEnum;
- enum_node->data.container_decl.layout = ContainerLayoutExtern;
- // TODO only emit this tag type if the enum tag type is not the default.
- // I don't know what the default is, need to figure out how clang is deciding.
- // it appears to at least be different across gcc/msvc
- if (!c_is_builtin_type(c, ZigClangEnumDecl_getIntegerType(enum_decl), ZigClangBuiltinTypeUInt) &&
- !c_is_builtin_type(c, ZigClangEnumDecl_getIntegerType(enum_decl), ZigClangBuiltinTypeInt))
- {
- enum_node->data.container_decl.init_arg_expr = tag_int_type;
- }
- enum_node->data.container_decl.fields.resize(field_count);
- uint32_t i = 0;
- for (ZigClangEnumDecl_enumerator_iterator it = ZigClangEnumDecl_enumerator_begin(enum_def),
- it_end = ZigClangEnumDecl_enumerator_end(enum_def);
- ZigClangEnumDecl_enumerator_iterator_neq(it, it_end);
- it = ZigClangEnumDecl_enumerator_iterator_next(it), i += 1)
- {
- const ZigClangEnumConstantDecl *enum_const = ZigClangEnumDecl_enumerator_iterator_deref(it);
-
- Buf *enum_val_name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)enum_const));
- Buf *field_name;
- if (bare_name != nullptr && buf_starts_with_buf(enum_val_name, bare_name)) {
- field_name = buf_slice(enum_val_name, buf_len(bare_name), buf_len(enum_val_name));
- } else {
- field_name = enum_val_name;
- }
-
- AstNode *int_node = pure_enum && !is_anonymous ?
- nullptr : trans_create_node_apint(c, ZigClangEnumConstantDecl_getInitVal(enum_const));
- AstNode *field_node = trans_create_node(c, NodeTypeStructField);
- field_node->data.struct_field.name = field_name;
- field_node->data.struct_field.type = nullptr;
- field_node->data.struct_field.value = int_node;
- enum_node->data.container_decl.fields.items[i] = field_node;
-
- // in C each enum value is in the global namespace. so we put them there too.
- // at this point we can rely on the enum emitting successfully
- if (is_anonymous) {
- Buf *enum_val_name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)enum_const));
- add_global_var(c, enum_val_name, int_node);
- } else {
- AstNode *field_access_node = trans_create_node_field_access(c,
- trans_create_node_symbol(c, full_type_name), field_name);
- add_global_var(c, enum_val_name, field_access_node);
- }
- }
-
- if (is_anonymous) {
- c->decl_table.put(ZigClangEnumDecl_getCanonicalDecl(enum_decl), enum_node);
- return enum_node;
- } else {
- AstNode *symbol_node = trans_create_node_symbol(c, full_type_name);
- add_global_weak_alias(c, bare_name, full_type_name);
- add_global_var(c, full_type_name, enum_node);
- c->decl_table.put(ZigClangEnumDecl_getCanonicalDecl(enum_decl), symbol_node);
- return enum_node;
- }
-}
-
-static AstNode *demote_struct_to_opaque(Context *c, const ZigClangRecordDecl *record_decl,
- Buf *full_type_name, Buf *bare_name)
-{
- AstNode *opaque_node = trans_create_node_opaque(c);
- if (full_type_name == nullptr) {
- c->decl_table.put(ZigClangRecordDecl_getCanonicalDecl(record_decl), opaque_node);
- return opaque_node;
- }
- AstNode *symbol_node = trans_create_node_symbol(c, full_type_name);
- add_global_weak_alias(c, bare_name, full_type_name);
- add_global_var(c, full_type_name, opaque_node);
- c->decl_table.put(ZigClangRecordDecl_getCanonicalDecl(record_decl), symbol_node);
- return symbol_node;
-}
-
-static AstNode *resolve_record_decl(Context *c, const ZigClangRecordDecl *record_decl) {
- auto existing_entry = c->decl_table.maybe_get(ZigClangRecordDecl_getCanonicalDecl(record_decl));
- if (existing_entry) {
- return existing_entry->value;
- }
-
- const char *raw_name = ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)record_decl);
- const char *container_kind_name;
- ContainerKind container_kind;
- if (ZigClangRecordDecl_isUnion(record_decl)) {
- container_kind_name = "union";
- container_kind = ContainerKindUnion;
- } else if (ZigClangRecordDecl_isStruct(record_decl)) {
- container_kind_name = "struct";
- container_kind = ContainerKindStruct;
- } else {
- emit_warning(c, ZigClangRecordDecl_getLocation(record_decl),
- "skipping record %s, not a struct or union", raw_name);
- c->decl_table.put(ZigClangRecordDecl_getCanonicalDecl(record_decl), nullptr);
- return nullptr;
- }
-
- bool is_anonymous = ZigClangRecordDecl_isAnonymousStructOrUnion(record_decl) || raw_name[0] == 0;
- Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name);
- Buf *full_type_name = (bare_name == nullptr) ?
- nullptr : buf_sprintf("%s_%s", container_kind_name, buf_ptr(bare_name));
-
- const ZigClangRecordDecl *record_def = ZigClangRecordDecl_getDefinition(record_decl);
- if (record_def == nullptr) {
- return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);
- }
-
- // count fields and validate
- uint32_t field_count = 0;
- for (ZigClangRecordDecl_field_iterator it = ZigClangRecordDecl_field_begin(record_def),
- it_end = ZigClangRecordDecl_field_end(record_def);
- ZigClangRecordDecl_field_iterator_neq(it, it_end);
- it = ZigClangRecordDecl_field_iterator_next(it), field_count += 1)
- {
- const ZigClangFieldDecl *field_decl = ZigClangRecordDecl_field_iterator_deref(it);
-
- if (ZigClangFieldDecl_isBitField(field_decl)) {
- emit_warning(c, ZigClangFieldDecl_getLocation(field_decl),
- "%s %s demoted to opaque type - has bitfield", container_kind_name,
- is_anonymous ? "(anon)" : buf_ptr(bare_name));
- return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);
- }
- }
-
- AstNode *struct_node = trans_create_node(c, NodeTypeContainerDecl);
- struct_node->data.container_decl.kind = container_kind;
- struct_node->data.container_decl.layout = ContainerLayoutExtern;
-
- // TODO handle attribute packed
-
- struct_node->data.container_decl.fields.resize(field_count);
-
- // must be before fields in case a circular reference happens
- if (is_anonymous) {
- c->decl_table.put(ZigClangRecordDecl_getCanonicalDecl(record_decl), struct_node);
- } else {
- c->decl_table.put(ZigClangRecordDecl_getCanonicalDecl(record_decl), trans_create_node_symbol(c, full_type_name));
- }
-
- uint32_t i = 0;
- for (ZigClangRecordDecl_field_iterator it = ZigClangRecordDecl_field_begin(record_def),
- it_end = ZigClangRecordDecl_field_end(record_def);
- ZigClangRecordDecl_field_iterator_neq(it, it_end);
- it = ZigClangRecordDecl_field_iterator_next(it), i += 1)
- {
- const ZigClangFieldDecl *field_decl = ZigClangRecordDecl_field_iterator_deref(it);
-
- AstNode *field_node = trans_create_node(c, NodeTypeStructField);
- field_node->data.struct_field.name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)field_decl));
- field_node->data.struct_field.type = trans_qual_type(c, ZigClangFieldDecl_getType(field_decl),
- ZigClangFieldDecl_getLocation(field_decl));
-
- if (field_node->data.struct_field.type == nullptr) {
- emit_warning(c, ZigClangFieldDecl_getLocation(field_decl),
- "%s %s demoted to opaque type - unresolved type",
- container_kind_name,
- is_anonymous ? "(anon)" : buf_ptr(bare_name));
-
- return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);
- }
-
- struct_node->data.container_decl.fields.items[i] = field_node;
- }
-
- if (is_anonymous) {
- return struct_node;
- } else {
- add_global_weak_alias(c, bare_name, full_type_name);
- add_global_var(c, full_type_name, struct_node);
- return trans_create_node_symbol(c, full_type_name);
- }
-}
-
-static AstNode *trans_ap_value(Context *c, const ZigClangAPValue *ap_value, ZigClangQualType qt,
- ZigClangSourceLocation source_loc)
-{
- switch (ZigClangAPValue_getKind(ap_value)) {
- case ZigClangAPValueInt:
- return trans_create_node_apint(c, ZigClangAPValue_getInt(ap_value));
- case ZigClangAPValueNone:
- return trans_create_node(c, NodeTypeUndefinedLiteral);
- case ZigClangAPValueArray: {
- emit_warning(c, source_loc, "TODO add a test case for this code");
-
- unsigned init_count = ZigClangAPValue_getArrayInitializedElts(ap_value);
- unsigned all_count = ZigClangAPValue_getArraySize(ap_value);
- unsigned leftover_count = all_count - init_count;
- AstNode *init_node = trans_create_node(c, NodeTypeContainerInitExpr);
- AstNode *arr_type_node = trans_qual_type(c, qt, source_loc);
- if (leftover_count != 0) { // We can't use the size of the final array for a partial initializer.
- bigint_init_unsigned(arr_type_node->data.array_type.size->data.int_literal.bigint, init_count);
- }
- init_node->data.container_init_expr.type = arr_type_node;
- init_node->data.container_init_expr.kind = ContainerInitKindArray;
-
- const ZigClangType *qt_type = ZigClangQualType_getTypePtr(qt);
- ZigClangQualType child_qt = ZigClangArrayType_getElementType(ZigClangType_getAsArrayTypeUnsafe(qt_type));
-
- for (size_t i = 0; i < init_count; i += 1) {
- const ZigClangAPValue *elem_ap_val = ZigClangAPValue_getArrayInitializedElt(ap_value, i);
- AstNode *elem_node = trans_ap_value(c, elem_ap_val, child_qt, source_loc);
- if (elem_node == nullptr)
- return nullptr;
- init_node->data.container_init_expr.entries.append(elem_node);
- }
- if (leftover_count == 0) {
- return init_node;
- }
-
- const ZigClangAPValue *filler_ap_val = ZigClangAPValue_getArrayFiller(ap_value);
- AstNode *filler_node = trans_ap_value(c, filler_ap_val, child_qt, source_loc);
- if (filler_node == nullptr)
- return nullptr;
-
- AstNode* filler_arr_type = trans_create_node(c, NodeTypeArrayType);
- *filler_arr_type = *arr_type_node;
- filler_arr_type->data.array_type.size = trans_create_node_unsigned(c, 1);
-
- AstNode *filler_arr_1 = trans_create_node(c, NodeTypeContainerInitExpr);
- filler_arr_1->data.container_init_expr.type = filler_arr_type;
- filler_arr_1->data.container_init_expr.kind = ContainerInitKindArray;
- filler_arr_1->data.container_init_expr.entries.append(filler_node);
-
- AstNode *rhs_node;
- if (leftover_count == 1) {
- rhs_node = filler_arr_1;
- } else {
- AstNode *amt_node = trans_create_node_unsigned(c, leftover_count);
- rhs_node = trans_create_node_bin_op(c, filler_arr_1, BinOpTypeArrayMult, amt_node);
- }
-
- if (init_count == 0) {
- return rhs_node;
- }
-
- return trans_create_node_bin_op(c, init_node, BinOpTypeArrayCat, rhs_node);
- }
- case ZigClangAPValueLValue: {
- const ZigClangAPValueLValueBase lval_base = ZigClangAPValue_getLValueBase(ap_value);
- if (const ZigClangExpr *expr = ZigClangAPValueLValueBase_dyn_cast_Expr(lval_base)) {
- return trans_expr(c, ResultUsedYes, &c->global_scope->base, expr, TransRValue);
- }
- emit_warning(c, source_loc, "TODO handle initializer LValue ValueDecl");
- return nullptr;
- }
- case ZigClangAPValueFloat:
- emit_warning(c, source_loc, "unsupported initializer value kind: Float");
- return nullptr;
- case ZigClangAPValueComplexInt:
- emit_warning(c, source_loc, "unsupported initializer value kind: ComplexInt");
- return nullptr;
- case ZigClangAPValueComplexFloat:
- emit_warning(c, source_loc, "unsupported initializer value kind: ComplexFloat");
- return nullptr;
- case ZigClangAPValueVector:
- emit_warning(c, source_loc, "unsupported initializer value kind: Vector");
- return nullptr;
- case ZigClangAPValueStruct:
- emit_warning(c, source_loc, "unsupported initializer value kind: Struct");
- return nullptr;
- case ZigClangAPValueUnion:
- emit_warning(c, source_loc, "unsupported initializer value kind: Union");
- return nullptr;
- case ZigClangAPValueMemberPointer:
- emit_warning(c, source_loc, "unsupported initializer value kind: MemberPointer");
- return nullptr;
- case ZigClangAPValueAddrLabelDiff:
- emit_warning(c, source_loc, "unsupported initializer value kind: AddrLabelDiff");
- return nullptr;
- case ZigClangAPValueIndeterminate:
- emit_warning(c, source_loc, "unsupported initializer value kind: Indeterminate");
- return nullptr;
- case ZigClangAPValueFixedPoint:
- emit_warning(c, source_loc, "unsupported initializer value kind: FixedPoint");
- return nullptr;
- }
- zig_unreachable();
-}
-
-static void visit_var_decl(Context *c, const ZigClangVarDecl *var_decl) {
- Buf *name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)var_decl));
-
- switch (ZigClangVarDecl_getTLSKind(var_decl)) {
- case ZigClangVarDecl_TLSKind_None:
- break;
- case ZigClangVarDecl_TLSKind_Static:
- emit_warning(c, ZigClangVarDecl_getLocation(var_decl),
- "ignoring variable '%s' - static thread local storage", buf_ptr(name));
- return;
- case ZigClangVarDecl_TLSKind_Dynamic:
- emit_warning(c, ZigClangVarDecl_getLocation(var_decl),
- "ignoring variable '%s' - dynamic thread local storage", buf_ptr(name));
- return;
- }
-
- ZigClangQualType qt = ZigClangVarDecl_getType(var_decl);
- AstNode *var_type = trans_qual_type(c, qt, ZigClangVarDecl_getLocation(var_decl));
- if (var_type == nullptr) {
- emit_warning(c, ZigClangVarDecl_getLocation(var_decl), "ignoring variable '%s' - unresolved type", buf_ptr(name));
- return;
- }
-
- bool is_extern = ZigClangVarDecl_hasExternalStorage(var_decl);
- bool is_static = ZigClangVarDecl_isFileVarDecl(var_decl);
- bool is_const = ZigClangQualType_isConstQualified(qt);
-
- if (is_static && !is_extern) {
- AstNode *init_node;
- if (ZigClangVarDecl_hasInit(var_decl)) {
- const ZigClangAPValue *ap_value = ZigClangVarDecl_evaluateValue(var_decl);
- if (ap_value == nullptr) {
- emit_warning(c, ZigClangVarDecl_getLocation(var_decl),
- "ignoring variable '%s' - unable to evaluate initializer", buf_ptr(name));
- return;
- }
- init_node = trans_ap_value(c, ap_value, qt, ZigClangVarDecl_getLocation(var_decl));
- if (init_node == nullptr)
- return;
- } else {
- init_node = trans_create_node(c, NodeTypeUndefinedLiteral);
- }
-
- AstNode *var_node = trans_create_node_var_decl_global(c, is_const, name, var_type, init_node);
- add_top_level_decl(c, name, var_node);
- return;
- }
-
- if (is_extern) {
- AstNode *var_node = trans_create_node_var_decl_global(c, is_const, name, var_type, nullptr);
- var_node->data.variable_declaration.is_extern = true;
- add_top_level_decl(c, name, var_node);
- return;
- }
-
- emit_warning(c, ZigClangVarDecl_getLocation(var_decl),
- "ignoring variable '%s' - non-extern, non-static variable", buf_ptr(name));
- return;
-}
-
-static bool decl_visitor(void *context, const ZigClangDecl *decl) {
- Context *c = (Context*)context;
-
- switch (ZigClangDecl_getKind(decl)) {
- case ZigClangDeclFunction:
- visit_fn_decl(c, reinterpret_cast<const ZigClangFunctionDecl*>(decl));
- break;
- case ZigClangDeclTypedef:
- resolve_typedef_decl(c, reinterpret_cast<const ZigClangTypedefNameDecl *>(decl));
- break;
- case ZigClangDeclEnum:
- resolve_enum_decl(c, reinterpret_cast<const ZigClangEnumDecl *>(decl));
- break;
- case ZigClangDeclRecord:
- resolve_record_decl(c, reinterpret_cast<const ZigClangRecordDecl *>(decl));
- break;
- case ZigClangDeclVar:
- visit_var_decl(c, reinterpret_cast<const ZigClangVarDecl *>(decl));
- break;
- default:
- emit_warning(c, ZigClangDecl_getLocation(decl), "ignoring %s decl", ZigClangDecl_getDeclKindName(decl));
- }
-
- return true;
-}
-
-static bool name_exists_global(Context *c, Buf *name) {
- return get_global(c, name) != nullptr;
-}
-
-static bool name_exists_scope(Context *c, Buf *name, TransScope *scope) {
- while (scope != nullptr) {
- if (scope->id == TransScopeIdVar) {
- TransScopeVar *var_scope = (TransScopeVar *)scope;
- if (buf_eql_buf(name, var_scope->zig_name)) {
- return true;
- }
- }
- scope = scope->parent;
- }
- return name_exists_global(c, name);
-}
-
-static Buf *get_unique_name(Context *c, Buf *name, TransScope *scope) {
- Buf *proposed_name = name;
- int count = 0;
- while (name_exists_scope(c, proposed_name, scope)) {
- if (proposed_name == name) {
- proposed_name = buf_alloc();
- }
- buf_resize(proposed_name, 0);
- buf_appendf(proposed_name, "%s_%d", buf_ptr(name), count);
- count += 1;
- }
- return proposed_name;
-}
-
-static TransScopeRoot *trans_scope_root_create(Context *c) {
- TransScopeRoot *result = allocate<TransScopeRoot>(1);
- result->base.id = TransScopeIdRoot;
- return result;
-}
-
-static TransScopeWhile *trans_scope_while_create(Context *c, TransScope *parent_scope) {
- TransScopeWhile *result = allocate<TransScopeWhile>(1);
- result->base.id = TransScopeIdWhile;
- result->base.parent = parent_scope;
- result->node = trans_create_node(c, NodeTypeWhileExpr);
- return result;
-}
-
-static TransScopeBlock *trans_scope_block_create(Context *c, TransScope *parent_scope) {
- TransScopeBlock *result = allocate<TransScopeBlock>(1);
- result->base.id = TransScopeIdBlock;
- result->base.parent = parent_scope;
- result->node = trans_create_node(c, NodeTypeBlock);
- return result;
-}
-
-static TransScopeVar *trans_scope_var_create(Context *c, TransScope *parent_scope, Buf *wanted_name) {
- TransScopeVar *result = allocate<TransScopeVar>(1);
- result->base.id = TransScopeIdVar;
- result->base.parent = parent_scope;
- result->c_name = wanted_name;
- result->zig_name = get_unique_name(c, wanted_name, parent_scope);
- return result;
-}
-
-static TransScopeSwitch *trans_scope_switch_create(Context *c, TransScope *parent_scope) {
- TransScopeSwitch *result = allocate<TransScopeSwitch>(1);
- result->base.id = TransScopeIdSwitch;
- result->base.parent = parent_scope;
- result->switch_node = trans_create_node(c, NodeTypeSwitchExpr);
- return result;
-}
-
-static TransScopeBlock *trans_scope_block_find(TransScope *scope) {
- while (scope != nullptr) {
- if (scope->id == TransScopeIdBlock) {
- return (TransScopeBlock *)scope;
- }
- scope = scope->parent;
- }
- return nullptr;
-}
-
-static void render_aliases(Context *c) {
- for (size_t i = 0; i < c->aliases.length; i += 1) {
- Alias *alias = &c->aliases.at(i);
- if (name_exists_global(c, alias->new_name))
- continue;
-
- add_global_var(c, alias->new_name, trans_create_node_symbol(c, alias->canon_name));
- }
-}
-
-static AstNode *trans_lookup_ast_container_typeof(Context *c, AstNode *ref_node);
-
-static AstNode *trans_lookup_ast_container(Context *c, AstNode *type_node) {
- if (type_node == nullptr) {
- return nullptr;
- } else if (type_node->type == NodeTypeContainerDecl) {
- return type_node;
- } else if (type_node->type == NodeTypePrefixOpExpr) {
- return type_node;
- } else if (type_node->type == NodeTypeSymbol) {
- AstNode *existing_node = get_global(c, type_node->data.symbol_expr.symbol);
- if (existing_node == nullptr)
- return nullptr;
- if (existing_node->type != NodeTypeVariableDeclaration)
- return nullptr;
- return trans_lookup_ast_container(c, existing_node->data.variable_declaration.expr);
- } else if (type_node->type == NodeTypeFieldAccessExpr) {
- AstNode *container_node = trans_lookup_ast_container_typeof(c, type_node->data.field_access_expr.struct_expr);
- if (container_node == nullptr)
- return nullptr;
- if (container_node->type != NodeTypeContainerDecl)
- return container_node;
-
- for (size_t i = 0; i < container_node->data.container_decl.fields.length; i += 1) {
- AstNode *field_node = container_node->data.container_decl.fields.items[i];
- if (buf_eql_buf(field_node->data.struct_field.name, type_node->data.field_access_expr.field_name)) {
- return trans_lookup_ast_container(c, field_node->data.struct_field.type);
- }
- }
- return nullptr;
- } else {
- return nullptr;
- }
-}
-
-static AstNode *trans_lookup_ast_container_typeof(Context *c, AstNode *ref_node) {
- if (ref_node->type == NodeTypeSymbol) {
- AstNode *existing_node = get_global(c, ref_node->data.symbol_expr.symbol);
- if (existing_node == nullptr)
- return nullptr;
- if (existing_node->type != NodeTypeVariableDeclaration)
- return nullptr;
- return trans_lookup_ast_container(c, existing_node->data.variable_declaration.type);
- } else if (ref_node->type == NodeTypeFieldAccessExpr) {
- AstNode *container_node = trans_lookup_ast_container_typeof(c, ref_node->data.field_access_expr.struct_expr);
- if (container_node == nullptr)
- return nullptr;
- if (container_node->type != NodeTypeContainerDecl)
- return container_node;
- for (size_t i = 0; i < container_node->data.container_decl.fields.length; i += 1) {
- AstNode *field_node = container_node->data.container_decl.fields.items[i];
- if (buf_eql_buf(field_node->data.struct_field.name, ref_node->data.field_access_expr.field_name)) {
- return trans_lookup_ast_container(c, field_node->data.struct_field.type);
- }
- }
- return nullptr;
- } else {
- return nullptr;
- }
-}
-
-static AstNode *trans_lookup_ast_maybe_fn(Context *c, AstNode *ref_node) {
- AstNode *prefix_node = trans_lookup_ast_container_typeof(c, ref_node);
- if (prefix_node == nullptr)
- return nullptr;
- if (prefix_node->type != NodeTypePrefixOpExpr)
- return nullptr;
- if (prefix_node->data.prefix_op_expr.prefix_op != PrefixOpOptional)
- return nullptr;
-
- AstNode *fn_proto_node = prefix_node->data.prefix_op_expr.primary_expr;
- if (fn_proto_node->type != NodeTypeFnProto)
- return nullptr;
-
- return fn_proto_node;
-}
-
-static void render_macros(Context *c) {
- auto it = c->macro_table.entry_iterator();
- for (;;) {
- auto *entry = it.next();
- if (!entry)
- break;
-
- AstNode *proto_node;
- AstNode *value_node = entry->value;
- if (value_node->type == NodeTypeFnDef) {
- add_top_level_decl(c, value_node->data.fn_def.fn_proto->data.fn_proto.name, value_node);
- } else if ((proto_node = trans_lookup_ast_maybe_fn(c, value_node))) {
- // If a macro aliases a global variable which is a function pointer, we conclude that
- // the macro is intended to represent a function that assumes the function pointer
- // variable is non-null and calls it.
- AstNode *inline_fn_node = trans_create_node_inline_fn(c, entry->key, value_node, proto_node);
- add_top_level_decl(c, entry->key, inline_fn_node);
- } else {
- add_global_var(c, entry->key, value_node);
- }
- }
-}
-
-static AstNode *parse_ctok_primary_expr(Context *c, CTokenize *ctok, size_t *tok_i);
-static AstNode *parse_ctok_expr(Context *c, CTokenize *ctok, size_t *tok_i);
-static AstNode *parse_ctok_prefix_op_expr(Context *c, CTokenize *ctok, size_t *tok_i);
-
-static AstNode *parse_ctok_num_lit(Context *c, CTokenize *ctok, size_t *tok_i, bool negate) {
- CTok *tok = &ctok->tokens.at(*tok_i);
- if (tok->id == CTokIdNumLitInt) {
- *tok_i += 1;
- switch (tok->data.num_lit_int.suffix) {
- case CNumLitSuffixNone:
- return trans_create_node_unsigned_negative(c, tok->data.num_lit_int.x, negate);
- case CNumLitSuffixL:
- return trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, "c_long");
- case CNumLitSuffixU:
- return trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, "c_uint");
- case CNumLitSuffixLU:
- return trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, "c_ulong");
- case CNumLitSuffixLL:
- return trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, "c_longlong");
- case CNumLitSuffixLLU:
- return trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, "c_ulonglong");
- }
- zig_unreachable();
- } else if (tok->id == CTokIdNumLitFloat) {
- *tok_i += 1;
- double value = negate ? -tok->data.num_lit_float : tok->data.num_lit_float;
- return trans_create_node_float_lit(c, value);
- }
- return nullptr;
-}
-
-static AstNode *parse_ctok_primary_expr(Context *c, CTokenize *ctok, size_t *tok_i) {
- CTok *tok = &ctok->tokens.at(*tok_i);
- switch (tok->id) {
- case CTokIdCharLit:
- *tok_i += 1;
- return trans_create_node_unsigned(c, tok->data.char_lit);
- case CTokIdStrLit:
- *tok_i += 1;
- return trans_create_node_str_lit(c, buf_create_from_buf(&tok->data.str_lit));
- case CTokIdMinus:
- *tok_i += 1;
- return parse_ctok_num_lit(c, ctok, tok_i, true);
- case CTokIdNumLitInt:
- case CTokIdNumLitFloat:
- return parse_ctok_num_lit(c, ctok, tok_i, false);
- case CTokIdSymbol:
- {
- *tok_i += 1;
- Buf *symbol_name = buf_create_from_buf(&tok->data.symbol);
- return trans_create_node_symbol(c, symbol_name);
- }
- case CTokIdLParen:
- {
- *tok_i += 1;
- AstNode *inner_node = parse_ctok_expr(c, ctok, tok_i);
- if (inner_node == nullptr) {
- return nullptr;
- }
-
- CTok *next_tok = &ctok->tokens.at(*tok_i);
- if (next_tok->id == CTokIdRParen) {
- *tok_i += 1;
- return inner_node;
- }
-
- AstNode *node_to_cast = parse_ctok_expr(c, ctok, tok_i);
- if (node_to_cast == nullptr) {
- return nullptr;
- }
-
- CTok *next_tok2 = &ctok->tokens.at(*tok_i);
- if (next_tok2->id != CTokIdRParen) {
- return nullptr;
- }
- *tok_i += 1;
-
-
- //if (@typeId(@TypeOf(x)) == @import("builtin").TypeId.Pointer)
- // @ptrCast(dest, x)
- //else if (@typeId(@TypeOf(x)) == @import("builtin").TypeId.Integer)
- // @intToPtr(dest, x)
- //else
- // (dest)(x)
-
- AstNode *import_builtin = trans_create_node_builtin_fn_call_str(c, "import");
- import_builtin->data.fn_call_expr.params.append(trans_create_node_str_lit(c, buf_create_from_str("builtin")));
- AstNode *typeid_type = trans_create_node_field_access_str(c, import_builtin, "TypeId");
- AstNode *typeid_pointer = trans_create_node_field_access_str(c, typeid_type, "Pointer");
- AstNode *typeid_integer = trans_create_node_field_access_str(c, typeid_type, "Int");
- AstNode *typeof_x = trans_create_node_builtin_fn_call_str(c, "TypeOf");
- typeof_x->data.fn_call_expr.params.append(node_to_cast);
- AstNode *typeid_value = trans_create_node_builtin_fn_call_str(c, "typeId");
- typeid_value->data.fn_call_expr.params.append(typeof_x);
-
- AstNode *outer_if_cond = trans_create_node_bin_op(c, typeid_value, BinOpTypeCmpEq, typeid_pointer);
- AstNode *inner_if_cond = trans_create_node_bin_op(c, typeid_value, BinOpTypeCmpEq, typeid_integer);
- AstNode *inner_if_then = trans_create_node_builtin_fn_call_str(c, "intToPtr");
- inner_if_then->data.fn_call_expr.params.append(inner_node);
- inner_if_then->data.fn_call_expr.params.append(node_to_cast);
- AstNode *inner_if_else = trans_create_node_cast(c, inner_node, node_to_cast);
- AstNode *inner_if = trans_create_node_if(c, inner_if_cond, inner_if_then, inner_if_else);
- AstNode *outer_if_then = trans_create_node_builtin_fn_call_str(c, "ptrCast");
- outer_if_then->data.fn_call_expr.params.append(inner_node);
- outer_if_then->data.fn_call_expr.params.append(node_to_cast);
- return trans_create_node_if(c, outer_if_cond, outer_if_then, inner_if);
- }
- case CTokIdDot:
- case CTokIdEOF:
- case CTokIdRParen:
- case CTokIdAsterisk:
- case CTokIdBang:
- case CTokIdTilde:
- case CTokIdShl:
- case CTokIdLt:
- // not able to make sense of this
- return nullptr;
- }
- zig_unreachable();
-}
-
-static AstNode *parse_ctok_expr(Context *c, CTokenize *ctok, size_t *tok_i) {
- return parse_ctok_prefix_op_expr(c, ctok, tok_i);
-}
-
-static AstNode *parse_ctok_suffix_op_expr(Context *c, CTokenize *ctok, size_t *tok_i) {
- AstNode *node = parse_ctok_primary_expr(c, ctok, tok_i);
- if (node == nullptr)
- return nullptr;
-
- while (true) {
- CTok *first_tok = &ctok->tokens.at(*tok_i);
- if (first_tok->id == CTokIdDot) {
- *tok_i += 1;
-
- CTok *name_tok = &ctok->tokens.at(*tok_i);
- if (name_tok->id != CTokIdSymbol) {
- return nullptr;
- }
- *tok_i += 1;
-
- node = trans_create_node_field_access(c, node, buf_create_from_buf(&name_tok->data.symbol));
- } else if (first_tok->id == CTokIdAsterisk) {
- *tok_i += 1;
-
- node = trans_create_node_ptr_type(c, false, false, node, PtrLenC);
- } else if (first_tok->id == CTokIdShl) {
- *tok_i += 1;
-
- AstNode *rhs_node = parse_ctok_expr(c, ctok, tok_i);
- if (rhs_node == nullptr)
- return nullptr;
- node = trans_create_node_bin_op(c, node, BinOpTypeBitShiftLeft, rhs_node);
- } else {
- return node;
- }
- }
-}
-
-static AstNode *parse_ctok_prefix_op_expr(Context *c, CTokenize *ctok, size_t *tok_i) {
- CTok *op_tok = &ctok->tokens.at(*tok_i);
-
- switch (op_tok->id) {
- case CTokIdBang:
- {
- *tok_i += 1;
- AstNode *prefix_op_expr = parse_ctok_prefix_op_expr(c, ctok, tok_i);
- if (prefix_op_expr == nullptr)
- return nullptr;
- return trans_create_node_prefix_op(c, PrefixOpBoolNot, prefix_op_expr);
- }
- case CTokIdMinus:
- {
- *tok_i += 1;
- AstNode *prefix_op_expr = parse_ctok_prefix_op_expr(c, ctok, tok_i);
- if (prefix_op_expr == nullptr)
- return nullptr;
- return trans_create_node_prefix_op(c, PrefixOpNegation, prefix_op_expr);
- }
- case CTokIdTilde:
- {
- *tok_i += 1;
- AstNode *prefix_op_expr = parse_ctok_prefix_op_expr(c, ctok, tok_i);
- if (prefix_op_expr == nullptr)
- return nullptr;
- return trans_create_node_prefix_op(c, PrefixOpBinNot, prefix_op_expr);
- }
- case CTokIdAsterisk:
- {
- *tok_i += 1;
- AstNode *prefix_op_expr = parse_ctok_prefix_op_expr(c, ctok, tok_i);
- if (prefix_op_expr == nullptr)
- return nullptr;
- return trans_create_node_ptr_deref(c, prefix_op_expr);
- }
- default:
- return parse_ctok_suffix_op_expr(c, ctok, tok_i);
- }
-}
-
-static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *char_ptr) {
- tokenize_c_macro(ctok, (const uint8_t *)char_ptr);
-
- if (ctok->error) {
- return;
- }
-
- size_t tok_i = 0;
- CTok *name_tok = &ctok->tokens.at(tok_i);
- assert(name_tok->id == CTokIdSymbol && buf_eql_buf(&name_tok->data.symbol, name));
- tok_i += 1;
-
- AstNode *result_node = parse_ctok_suffix_op_expr(c, ctok, &tok_i);
- if (result_node == nullptr) {
- return;
- }
- CTok *eof_tok = &ctok->tokens.at(tok_i);
- if (eof_tok->id != CTokIdEOF) {
- return;
- }
- if (result_node->type == NodeTypeSymbol) {
- // if it equals itself, ignore. for example, from stdio.h:
- // #define stdin stdin
- Buf *symbol_name = result_node->data.symbol_expr.symbol;
- if (buf_eql_buf(name, symbol_name)) {
- return;
- }
- }
- c->macro_table.put(name, result_node);
-}
-
-static void process_preprocessor_entities(Context *c, ZigClangASTUnit *unit) {
- CTokenize ctok = {{0}};
-
- // TODO if we see #undef, delete it from the table
- for (ZigClangPreprocessingRecord_iterator it = ZigClangASTUnit_getLocalPreprocessingEntities_begin(unit),
- it_end = ZigClangASTUnit_getLocalPreprocessingEntities_end(unit); it.I != it_end.I; it.I += 1)
- {
- ZigClangPreprocessedEntity *entity = ZigClangPreprocessingRecord_iterator_deref(it);
-
- switch (ZigClangPreprocessedEntity_getKind(entity)) {
- case ZigClangPreprocessedEntity_InvalidKind:
- case ZigClangPreprocessedEntity_InclusionDirectiveKind:
- case ZigClangPreprocessedEntity_MacroExpansionKind:
- continue;
- case ZigClangPreprocessedEntity_MacroDefinitionKind:
- {
- ZigClangMacroDefinitionRecord *macro = reinterpret_cast<ZigClangMacroDefinitionRecord *>(entity);
- const char *raw_name = ZigClangMacroDefinitionRecord_getName_getNameStart(macro);
- ZigClangSourceLocation begin_loc = ZigClangMacroDefinitionRecord_getSourceRange_getBegin(macro);
- ZigClangSourceLocation end_loc = ZigClangMacroDefinitionRecord_getSourceRange_getEnd(macro);
-
- if (ZigClangSourceLocation_eq(begin_loc, end_loc)) {
- // this means it is a macro without a value
- // we don't care about such things
- continue;
- }
- Buf *name = buf_create_from_str(raw_name);
- if (name_exists_global(c, name)) {
- continue;
- }
-
- const char *begin_c = ZigClangSourceManager_getCharacterData(c->source_manager, begin_loc);
- process_macro(c, &ctok, name, begin_c);
- }
- }
- }
-}
-
-Error parse_h_file(CodeGen *codegen, AstNode **out_root_node,
- Stage2ErrorMsg **errors_ptr, size_t *errors_len,
- const char **args_begin, const char **args_end,
- TranslateMode mode, const char *resources_path)
-{
- Context context = {0};
- Context *c = &context;
- c->warnings_on = codegen->verbose_cimport;
- if (mode == TranslateModeImport) {
- c->want_export = false;
- } else {
- c->want_export = true;
- }
- c->decl_table.init(8);
- c->macro_table.init(8);
- c->global_table.init(8);
- c->ptr_params.init(8);
- c->codegen = codegen;
- c->global_scope = trans_scope_root_create(c);
-
- ZigClangASTUnit *ast_unit = ZigClangLoadFromCommandLine(args_begin, args_end, errors_ptr, errors_len,
- resources_path);
- if (ast_unit == nullptr) {
- if (*errors_len == 0) return ErrorNoMem;
- return ErrorCCompileErrors;
- }
-
- c->ctx = ZigClangASTUnit_getASTContext(ast_unit);
- c->source_manager = ZigClangASTUnit_getSourceManager(ast_unit);
- c->root = trans_create_node(c, NodeTypeContainerDecl);
- c->root->data.container_decl.is_root = true;
-
- ZigClangASTUnit_visitLocalTopLevelDecls(ast_unit, c, decl_visitor);
-
- process_preprocessor_entities(c, ast_unit);
-
- render_macros(c);
- render_aliases(c);
-
- *out_root_node = c->root;
-
- ZigClangASTUnit_delete(ast_unit);
-
- return ErrorNone;
-}
src/translate_c.hpp
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2015 Andrew Kelley
- *
- * This file is part of zig, which is MIT licensed.
- * See http://opensource.org/licenses/MIT
- */
-
-
-#ifndef ZIG_PARSEC_HPP
-#define ZIG_PARSEC_HPP
-
-#include "all_types.hpp"
-
-enum TranslateMode {
- TranslateModeImport,
- TranslateModeTranslate,
-};
-
-Error parse_h_file(CodeGen *codegen, AstNode **out_root_node,
- Stage2ErrorMsg **errors_ptr, size_t *errors_len,
- const char **args_begin, const char **args_end,
- TranslateMode mode, const char *resources_path);
-
-#endif
test/tests.zig
@@ -1422,7 +1422,6 @@ pub const TranslateCContext = struct {
sources: ArrayList(SourceFile),
expected_lines: ArrayList([]const u8),
allow_warnings: bool,
- stage2: bool,
const SourceFile = struct {
filename: []const u8,
@@ -1475,7 +1474,7 @@ pub const TranslateCContext = struct {
var zig_args = ArrayList([]const u8).init(b.allocator);
zig_args.append(b.zig_exe) catch unreachable;
- const translate_c_cmd = if (self.case.stage2) "translate-c-2" else "translate-c";
+ const translate_c_cmd = "translate-c";
zig_args.append(translate_c_cmd) catch unreachable;
zig_args.append(b.pathFromRoot(root_src)) catch unreachable;
@@ -1583,7 +1582,6 @@ pub const TranslateCContext = struct {
.sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
.expected_lines = ArrayList([]const u8).init(self.b.allocator),
.allow_warnings = allow_warnings,
- .stage2 = false,
};
tc.addSourceFile(filename, source);
@@ -1604,53 +1602,6 @@ pub const TranslateCContext = struct {
self.addCase(tc);
}
- pub fn addC(
- self: *TranslateCContext,
- name: []const u8,
- source: []const u8,
- expected_lines: []const []const u8,
- ) void {
- const tc = self.create(false, "source.c", name, source, expected_lines);
- self.addCase(tc);
- }
-
- pub fn add_both(
- self: *TranslateCContext,
- name: []const u8,
- source: []const u8,
- expected_lines: []const []const u8,
- ) void {
- for ([_]bool{ false, true }) |stage2| {
- const tc = self.create(false, "source.h", name, source, expected_lines);
- tc.stage2 = stage2;
- self.addCase(tc);
- }
- }
-
- pub fn addC_both(
- self: *TranslateCContext,
- name: []const u8,
- source: []const u8,
- expected_lines: []const []const u8,
- ) void {
- for ([_]bool{ false, true }) |stage2| {
- const tc = self.create(false, "source.c", name, source, expected_lines);
- tc.stage2 = stage2;
- self.addCase(tc);
- }
- }
-
- pub fn add_2(
- self: *TranslateCContext,
- name: []const u8,
- source: []const u8,
- expected_lines: []const []const u8,
- ) void {
- const tc = self.create(false, "source.h", name, source, expected_lines);
- tc.stage2 = true;
- self.addCase(tc);
- }
-
pub fn addAllowWarnings(
self: *TranslateCContext,
name: []const u8,
@@ -1664,7 +1615,7 @@ pub const TranslateCContext = struct {
pub fn addCase(self: *TranslateCContext, case: *const TestCase) void {
const b = self.b;
- const translate_c_cmd = if (case.stage2) "translate-c-2" else "translate-c";
+ const translate_c_cmd = "translate-c";
const annotated_case_name = fmt.allocPrint(self.b.allocator, "{} {}", .{ translate_c_cmd, case.name }) catch unreachable;
if (self.test_filter) |filter| {
if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
test/translate_c.zig
@@ -1,15 +1,9 @@
const tests = @import("tests.zig");
const builtin = @import("builtin");
-// add_both - test for stage1 and stage2, in #include mode
-// add - test stage1 only, in #include mode
-// add_2 - test stage2 only
-// addC_both - test for stage1 and stage2, in -c mode
-// addC - test stage1 only, in -c mode
-
pub fn addCases(cases: *tests.TranslateCContext) void {
/////////////// Cases that pass for both stage1/stage2 ////////////////
- cases.add_both("simple function prototypes",
+ cases.add("simple function prototypes",
\\void __attribute__((noreturn)) foo(void);
\\int bar(void);
, &[_][]const u8{
@@ -17,7 +11,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub extern fn bar() c_int;
});
- cases.addC_both("simple var decls",
+ cases.add("simple var decls",
\\void foo(void) {
\\ int a;
\\ char b = 123;
@@ -33,7 +27,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.addC_both("ignore result, explicit function arguments",
+ cases.add("ignore result, explicit function arguments",
\\void foo(void) {
\\ int a;
\\ 1;
@@ -53,7 +47,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.addC_both("variables",
+ cases.add("variables",
\\extern int extern_var;
\\static const int int_var = 13;
, &[_][]const u8{
@@ -62,13 +56,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const int_var: c_int = 13;
});
- cases.add_both("const ptr initializer",
+ cases.add("const ptr initializer",
\\static const char *v0 = "0.0.0";
, &[_][]const u8{
\\pub var v0: [*c]const u8 = "0.0.0";
});
- cases.addC_both("static incomplete array inside function",
+ cases.add("static incomplete array inside function",
\\void foo(void) {
\\ static const char v2[] = "2.2.2";
\\}
@@ -78,7 +72,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.addC_both("simple function definition",
+ cases.add("simple function definition",
\\void foo(void) {}
\\static void bar(void) {}
, &[_][]const u8{
@@ -86,7 +80,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub fn bar() void {}
});
- cases.add_both("typedef void",
+ cases.add("typedef void",
\\typedef void Foo;
\\Foo fun(Foo *a);
, &[_][]const u8{
@@ -95,7 +89,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub extern fn fun(a: ?*Foo) Foo;
});
- cases.add_both("duplicate typedef",
+ cases.add("duplicate typedef",
\\typedef long foo;
\\typedef int bar;
\\typedef long foo;
@@ -106,7 +100,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const baz = c_int;
});
- cases.addC_both("casting pointers to ints and ints to pointers",
+ cases.add("casting pointers to ints and ints to pointers",
\\void foo(void);
\\void bar(void) {
\\ void *func_ptr = foo;
@@ -120,13 +114,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_both("noreturn attribute",
+ cases.add("noreturn attribute",
\\void foo(void) __attribute__((noreturn));
, &[_][]const u8{
\\pub extern fn foo() noreturn;
});
- cases.addC_both("add, sub, mul, div, rem",
+ cases.add("add, sub, mul, div, rem",
\\int s() {
\\ int a, b, c;
\\ c = a + b;
@@ -166,7 +160,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_both("typedef of function in struct field",
+ cases.add("typedef of function in struct field",
\\typedef void lws_callback_function(void);
\\struct Foo {
\\ void (*func)(void);
@@ -180,7 +174,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\};
});
- cases.add_both("pointer to struct demoted to opaque due to bit fields",
+ cases.add("pointer to struct demoted to opaque due to bit fields",
\\struct Foo {
\\ unsigned int: 1;
\\};
@@ -195,13 +189,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\};
});
- cases.add_both("macro with left shift",
+ cases.add("macro with left shift",
\\#define REDISMODULE_READ (1<<0)
, &[_][]const u8{
\\pub const REDISMODULE_READ = 1 << 0;
});
- cases.add_both("double define struct",
+ cases.add("double define struct",
\\typedef struct Bar Bar;
\\typedef struct Foo Foo;
\\
@@ -226,7 +220,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const Bar = struct_Bar;
});
- cases.add_both("simple struct",
+ cases.add("simple struct",
\\struct Foo {
\\ int x;
\\ char *y;
@@ -240,7 +234,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const Foo = struct_Foo;
});
- cases.add_both("self referential struct with function pointer",
+ cases.add("self referential struct with function pointer",
\\struct Foo {
\\ void (*derp)(struct Foo *foo);
\\};
@@ -252,7 +246,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const Foo = struct_Foo;
});
- cases.add_both("struct prototype used in func",
+ cases.add("struct prototype used in func",
\\struct Foo;
\\struct Foo *some_func(struct Foo *foo, int x);
, &[_][]const u8{
@@ -263,13 +257,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const Foo = struct_Foo;
});
- cases.add_both("#define an unsigned integer literal",
+ cases.add("#define an unsigned integer literal",
\\#define CHANNEL_COUNT 24
, &[_][]const u8{
\\pub const CHANNEL_COUNT = 24;
});
- cases.add_both("#define referencing another #define",
+ cases.add("#define referencing another #define",
\\#define THING2 THING1
\\#define THING1 1234
, &[_][]const u8{
@@ -278,7 +272,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const THING2 = THING1;
});
- cases.add_both("circular struct definitions",
+ cases.add("circular struct definitions",
\\struct Bar;
\\
\\struct Foo {
@@ -298,13 +292,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\};
});
- cases.add_both("#define string",
+ cases.add("#define string",
\\#define foo "a string"
, &[_][]const u8{
\\pub const foo = "a string";
});
- cases.add_both("zig keywords in C code",
+ cases.add("zig keywords in C code",
\\struct comptime {
\\ int defer;
\\};
@@ -316,13 +310,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const @"comptime" = struct_comptime;
});
- cases.add_both("macro with parens around negative number",
+ cases.add("macro with parens around negative number",
\\#define LUA_GLOBALSINDEX (-10002)
, &[_][]const u8{
\\pub const LUA_GLOBALSINDEX = -10002;
});
- cases.add_both(
+ cases.add(
"u integer suffix after 0 (zero) in macro definition",
"#define ZERO 0U",
&[_][]const u8{
@@ -330,7 +324,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
},
);
- cases.add_both(
+ cases.add(
"l integer suffix after 0 (zero) in macro definition",
"#define ZERO 0L",
&[_][]const u8{
@@ -338,7 +332,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
},
);
- cases.add_both(
+ cases.add(
"ul integer suffix after 0 (zero) in macro definition",
"#define ZERO 0UL",
&[_][]const u8{
@@ -346,7 +340,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
},
);
- cases.add_both(
+ cases.add(
"lu integer suffix after 0 (zero) in macro definition",
"#define ZERO 0LU",
&[_][]const u8{
@@ -354,7 +348,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
},
);
- cases.add_both(
+ cases.add(
"ll integer suffix after 0 (zero) in macro definition",
"#define ZERO 0LL",
&[_][]const u8{
@@ -362,7 +356,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
},
);
- cases.add_both(
+ cases.add(
"ull integer suffix after 0 (zero) in macro definition",
"#define ZERO 0ULL",
&[_][]const u8{
@@ -370,7 +364,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
},
);
- cases.add_both(
+ cases.add(
"llu integer suffix after 0 (zero) in macro definition",
"#define ZERO 0LLU",
&[_][]const u8{
@@ -378,7 +372,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
},
);
- cases.add_both(
+ cases.add(
"bitwise not on u-suffixed 0 (zero) in macro definition",
"#define NOT_ZERO (~0U)",
&[_][]const u8{
@@ -386,7 +380,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
},
);
- cases.addC_both("null statements",
+ cases.add("null statements",
\\void foo(void) {
\\ ;;;;;
\\}
@@ -402,7 +396,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
if (builtin.os != builtin.Os.windows) {
// Windows treats this as an enum with type c_int
- cases.add_both("big negative enum init values when C ABI supports long long enums",
+ cases.add("big negative enum init values when C ABI supports long long enums",
\\enum EnumWithInits {
\\ VAL01 = 0,
\\ VAL02 = 1,
@@ -457,7 +451,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
});
}
- cases.addC_both("predefined expressions",
+ cases.add("predefined expressions",
\\void foo(void) {
\\ __func__;
\\ __FUNCTION__;
@@ -471,7 +465,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.addC_both("ignore result, no function arguments",
+ cases.add("ignore result, no function arguments",
\\void foo() {
\\ int a;
\\ 1;
@@ -491,19 +485,19 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_both("constant size array",
+ cases.add("constant size array",
\\void func(int array[20]);
, &[_][]const u8{
\\pub extern fn func(array: [*c]c_int) void;
});
- cases.add_both("__cdecl doesn't mess up function pointers",
+ cases.add("__cdecl doesn't mess up function pointers",
\\void foo(void (__cdecl *fn_ptr)(void));
, &[_][]const u8{
\\pub extern fn foo(fn_ptr: ?extern fn () void) void;
});
- cases.addC_both("void cast",
+ cases.add("void cast",
\\void foo() {
\\ int a;
\\ (void) a;
@@ -515,7 +509,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.addC_both("implicit cast to void *",
+ cases.add("implicit cast to void *",
\\void *foo() {
\\ unsigned short *x;
\\ return x;
@@ -527,7 +521,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.addC_both("null pointer implicit cast",
+ cases.add("null pointer implicit cast",
\\int* foo(void) {
\\ return 0;
\\}
@@ -537,7 +531,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_both("simple union",
+ cases.add("simple union",
\\union Foo {
\\ int x;
\\ double y;
@@ -551,7 +545,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const Foo = union_Foo;
});
- cases.addC_both("string literal",
+ cases.add("string literal",
\\const char *foo(void) {
\\ return "bar";
\\}
@@ -561,7 +555,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.addC_both("return void",
+ cases.add("return void",
\\void foo(void) {
\\ return;
\\}
@@ -571,7 +565,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.addC_both("for loop",
+ cases.add("for loop",
\\void foo(void) {
\\ for (int i = 0; i; i = i + 1) { }
\\}
@@ -584,7 +578,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.addC_both("empty for loop",
+ cases.add("empty for loop",
\\void foo(void) {
\\ for (;;) { }
\\}
@@ -594,7 +588,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.addC_both("break statement",
+ cases.add("break statement",
\\void foo(void) {
\\ for (;;) {
\\ break;
@@ -608,7 +602,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.addC_both("continue statement",
+ cases.add("continue statement",
\\void foo(void) {
\\ for (;;) {
\\ continue;
@@ -622,7 +616,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.addC_both("pointer casting",
+ cases.add("pointer casting",
\\float *ptrcast() {
\\ int *a;
\\ return (float *)a;
@@ -634,7 +628,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.addC_both("pointer conversion with different alignment",
+ cases.add("pointer conversion with different alignment",
\\void test_ptr_cast() {
\\ void *p;
\\ {
@@ -668,7 +662,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.addC_both("while on non-bool",
+ cases.add("while on non-bool",
\\int while_none_bool() {
\\ int a;
\\ float b;
@@ -690,7 +684,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.addC_both("for on non-bool",
+ cases.add("for on non-bool",
\\int for_none_bool() {
\\ int a;
\\ float b;
@@ -712,7 +706,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.addC_both("bitshift",
+ cases.add("bitshift",
\\int foo(void) {
\\ return (1 << 2) >> 1;
\\}
@@ -722,7 +716,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.addC_both("sizeof",
+ cases.add("sizeof",
\\#include <stddef.h>
\\size_t size_of(void) {
\\ return sizeof(int);
@@ -733,7 +727,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.addC_both("normal deref",
+ cases.add("normal deref",
\\void foo() {
\\ int *x;
\\ *x = 1;
@@ -745,7 +739,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.addC_both("address of operator",
+ cases.add("address of operator",
\\int foo(void) {
\\ int x = 1234;
\\ int *ptr = &x;
@@ -759,7 +753,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.addC_both("bin not",
+ cases.add("bin not",
\\int foo() {
\\ int x;
\\ return ~x;
@@ -771,7 +765,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.addC_both("bool not",
+ cases.add("bool not",
\\int foo() {
\\ int a;
\\ float b;
@@ -793,7 +787,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.addC("__extension__ cast",
+ cases.add("__extension__ cast",
\\int foo(void) {
\\ return __extension__ 1;
\\}
@@ -805,16 +799,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
if (builtin.os != builtin.Os.windows) {
// sysv_abi not currently supported on windows
- cases.add_both("Macro qualified functions",
+ cases.add("Macro qualified functions",
\\void __attribute__((sysv_abi)) foo(void);
, &[_][]const u8{
\\pub extern fn foo() void;
});
}
- /////////////// Cases that pass for only stage2 ////////////////
-
- cases.add_2("Forward-declared enum",
+ cases.add("Forward-declared enum",
\\extern enum enum_ty my_enum;
\\enum enum_ty { FOO };
, &[_][]const u8{
@@ -825,7 +817,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub extern var my_enum: enum_enum_ty;
});
- cases.add_2("Parameterless function pointers",
+ cases.add("Parameterless function pointers",
\\typedef void (*fn0)();
\\typedef void (*fn1)(char);
, &[_][]const u8{
@@ -833,7 +825,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const fn1 = ?extern fn (u8) void;
});
- cases.add_2("Parameterless function prototypes",
+ cases.add("Parameterless function prototypes",
\\void a() {}
\\void b(void) {}
\\void c();
@@ -845,7 +837,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub extern fn d() void;
});
- cases.add_2("variable declarations",
+ cases.add("variable declarations",
\\extern char arr0[] = "hello";
\\static char arr1[] = "hello";
\\char arr2[] = "hello";
@@ -855,7 +847,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub export var arr2: [*c]u8 = "hello";
});
- cases.add_2("array initializer expr",
+ cases.add("array initializer expr",
\\static void foo(void){
\\ char arr[10] ={1};
\\ char *arr1[10] ={0};
@@ -871,7 +863,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("enums",
+ cases.add("enums",
\\typedef enum {
\\ a,
\\ b,
@@ -938,61 +930,61 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const Baz = struct_Baz;
});
- cases.add_2("#define a char literal",
+ cases.add("#define a char literal",
\\#define A_CHAR 'a'
, &[_][]const u8{
\\pub const A_CHAR = 'a';
});
- cases.add_2("comment after integer literal",
+ cases.add("comment after integer literal",
\\#define SDL_INIT_VIDEO 0x00000020 /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
, &[_][]const u8{
\\pub const SDL_INIT_VIDEO = 0x00000020;
});
- cases.add_2("u integer suffix after hex literal",
+ cases.add("u integer suffix after hex literal",
\\#define SDL_INIT_VIDEO 0x00000020u /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
, &[_][]const u8{
\\pub const SDL_INIT_VIDEO = @as(c_uint, 0x00000020);
});
- cases.add_2("l integer suffix after hex literal",
+ cases.add("l integer suffix after hex literal",
\\#define SDL_INIT_VIDEO 0x00000020l /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
, &[_][]const u8{
\\pub const SDL_INIT_VIDEO = @as(c_long, 0x00000020);
});
- cases.add_2("ul integer suffix after hex literal",
+ cases.add("ul integer suffix after hex literal",
\\#define SDL_INIT_VIDEO 0x00000020ul /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
, &[_][]const u8{
\\pub const SDL_INIT_VIDEO = @as(c_ulong, 0x00000020);
});
- cases.add_2("lu integer suffix after hex literal",
+ cases.add("lu integer suffix after hex literal",
\\#define SDL_INIT_VIDEO 0x00000020lu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
, &[_][]const u8{
\\pub const SDL_INIT_VIDEO = @as(c_ulong, 0x00000020);
});
- cases.add_2("ll integer suffix after hex literal",
+ cases.add("ll integer suffix after hex literal",
\\#define SDL_INIT_VIDEO 0x00000020ll /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
, &[_][]const u8{
\\pub const SDL_INIT_VIDEO = @as(c_longlong, 0x00000020);
});
- cases.add_2("ull integer suffix after hex literal",
+ cases.add("ull integer suffix after hex literal",
\\#define SDL_INIT_VIDEO 0x00000020ull /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
, &[_][]const u8{
\\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 0x00000020);
});
- cases.add_2("llu integer suffix after hex literal",
+ cases.add("llu integer suffix after hex literal",
\\#define SDL_INIT_VIDEO 0x00000020llu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
, &[_][]const u8{
\\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 0x00000020);
});
- cases.add_2("generate inline func for #define global extern fn",
+ cases.add("generate inline func for #define global extern fn",
\\extern void (*fn_ptr)(void);
\\#define foo fn_ptr
\\
@@ -1012,7 +1004,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("macros with field targets",
+ cases.add("macros with field targets",
\\typedef unsigned int GLbitfield;
\\typedef void (*PFNGLCLEARPROC) (GLbitfield mask);
\\typedef void(*OpenGLProc)(void);
@@ -1047,13 +1039,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const OpenGLProcs = union_OpenGLProcs;
});
- cases.add_2("macro pointer cast",
+ cases.add("macro pointer cast",
\\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)
, &[_][]const u8{
\\pub const NRF_GPIO = if (@typeId(@TypeOf(NRF_GPIO_BASE)) == .Pointer) @ptrCast([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeId(@TypeOf(NRF_GPIO_BASE)) == .Int) @intToPtr([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else @as([*c]NRF_GPIO_Type, NRF_GPIO_BASE);
});
- cases.add_2("basic macro function",
+ cases.add("basic macro function",
\\extern int c;
\\#define BASIC(c) (c*2)
, &[_][]const u8{
@@ -1064,7 +1056,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("macro defines string literal with hex",
+ cases.add("macro defines string literal with hex",
\\#define FOO "aoeu\xab derp"
\\#define FOO2 "aoeu\x0007a derp"
\\#define FOO_CHAR '\xfF'
@@ -1076,7 +1068,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const FOO_CHAR = '\xff';
});
- cases.add_2("variable aliasing",
+ cases.add("variable aliasing",
\\static long a = 2;
\\static long b = 2;
\\static int c = 4;
@@ -1105,7 +1097,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("comma operator",
+ cases.add("comma operator",
\\int foo(char c) {
\\ 2, 4;
\\ return 2, 4, 6;
@@ -1121,7 +1113,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("wors-case assign",
+ cases.add("wors-case assign",
\\int foo(char c) {
\\ int a;
\\ int b;
@@ -1140,7 +1132,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("if statements",
+ cases.add("if statements",
\\int foo(char c) {
\\ if (2) {
\\ int a = 2;
@@ -1164,7 +1156,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("while loops",
+ cases.add("while loops",
\\int foo() {
\\ int a = 5;
\\ while (2)
@@ -1204,7 +1196,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("for loops",
+ cases.add("for loops",
\\int foo() {
\\ for (int i = 2, b = 4; i + 2; i = 2) {
\\ int a = 2;
@@ -1228,13 +1220,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("shadowing primitive types",
+ cases.add("shadowing primitive types",
\\unsigned anyerror = 2;
, &[_][]const u8{
\\pub export var _anyerror: c_uint = @as(c_uint, 2);
});
- cases.add_2("floats",
+ cases.add("floats",
\\float a = 3.1415;
\\double b = 3.1415;
\\int c = 3.1415;
@@ -1246,7 +1238,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub export var d: f64 = @intToFloat(f64, 3);
});
- cases.add_2("conditional operator",
+ cases.add("conditional operator",
\\int bar(void) {
\\ if (2 ? 5 : 5 ? 4 : 6) 2;
\\ return 2 ? 5 : 5 ? 4 : 6;
@@ -1258,7 +1250,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("switch on int",
+ cases.add("switch on int",
\\int switch_fn(int i) {
\\ int res = 0;
\\ switch (i) {
@@ -1301,7 +1293,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("type referenced struct",
+ cases.add("type referenced struct",
\\struct Foo {
\\ struct Bar{
\\ int b;
@@ -1317,19 +1309,19 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\};
});
- cases.add_2("undefined array global",
+ cases.add("undefined array global",
\\int array[100] = {};
, &[_][]const u8{
\\pub export var array: [100]c_int = .{0} ** 100;
});
- cases.add_2("restrict -> noalias",
+ cases.add("restrict -> noalias",
\\void foo(void *restrict bar, void *restrict);
, &[_][]const u8{
\\pub extern fn foo(noalias bar: ?*c_void, noalias ?*c_void) void;
});
- cases.add_2("assign",
+ cases.add("assign",
\\int max(int a) {
\\ int tmp;
\\ tmp = a;
@@ -1344,7 +1336,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("chaining assign",
+ cases.add("chaining assign",
\\void max(int a) {
\\ int b, c;
\\ c = b = a;
@@ -1362,7 +1354,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("anonymous enum",
+ cases.add("anonymous enum",
\\enum {
\\ One,
\\ Two,
@@ -1376,7 +1368,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\};
});
- cases.add_2("c style cast",
+ cases.add("c style cast",
\\int float_to_int(float a) {
\\ return (int)a;
\\}
@@ -1387,7 +1379,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("escape sequences",
+ cases.add("escape sequences",
\\const char *escapes() {
\\char a = '\'',
\\ b = '\\',
@@ -1420,7 +1412,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("do loop",
+ cases.add("do loop",
\\void foo(void) {
\\ int a = 2;
\\ do {
@@ -1447,7 +1439,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("logical and, logical or, on non-bool values, extra parens",
+ cases.add("logical and, logical or, on non-bool values, extra parens",
\\enum Foo {
\\ FooA,
\\ FooB,
@@ -1500,7 +1492,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const Foo = enum_Foo;
});
- cases.add_2("qualified struct and enum",
+ cases.add("qualified struct and enum",
\\struct Foo {
\\ int x;
\\ int y;
@@ -1526,7 +1518,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const Bar = enum_Bar;
});
- cases.add_2("bitwise binary operators, simpler parens",
+ cases.add("bitwise binary operators, simpler parens",
\\int max(int a, int b) {
\\ return (a & b) ^ (a | b);
\\}
@@ -1538,7 +1530,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("comparison operators (no if)", // TODO Come up with less contrived tests? Make sure to cover all these comparisons.
+ cases.add("comparison operators (no if)", // TODO Come up with less contrived tests? Make sure to cover all these comparisons.
\\int test_comparisons(int a, int b) {
\\ int c = (a < b);
\\ int d = (a > b);
@@ -1564,7 +1556,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("==, !=",
+ cases.add("==, !=",
\\int max(int a, int b) {
\\ if (a == b)
\\ return a;
@@ -1582,7 +1574,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("typedeffed bool expression",
+ cases.add("typedeffed bool expression",
\\typedef char* yes;
\\void foo(void) {
\\ yes a;
@@ -1596,7 +1588,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("statement expression",
+ cases.add("statement expression",
\\int foo(void) {
\\ return ({
\\ int a = 1;
@@ -1614,7 +1606,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("field access expression",
+ cases.add("field access expression",
\\#define ARROW a->b
\\#define DOT a.b
\\extern struct Foo {
@@ -1643,7 +1635,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const ARROW = a.*.b;
});
- cases.add_2("array access",
+ cases.add("array access",
\\#define ACCESS array[2]
\\int array[100] = {};
\\int foo(int index) {
@@ -1659,7 +1651,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const ACCESS = array[2];
});
- cases.add_2("macro call",
+ cases.add("macro call",
\\#define CALL(arg) bar(arg)
, &[_][]const u8{
\\pub inline fn CALL(arg: var) @TypeOf(bar(arg)) {
@@ -1667,7 +1659,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("logical and, logical or",
+ cases.add("logical and, logical or",
\\int max(int a, int b) {
\\ if (a < b || a == b)
\\ return b;
@@ -1685,7 +1677,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("if statement",
+ cases.add("if statement",
\\int max(int a, int b) {
\\ if (a < b)
\\ return b;
@@ -1707,7 +1699,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("if on non-bool",
+ cases.add("if on non-bool",
\\enum SomeEnum { A, B, C };
\\int if_none_bool(int a, float b, void *c, enum SomeEnum d) {
\\ if (a) return 0;
@@ -1735,7 +1727,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("simple data types",
+ cases.add("simple data types",
\\#include <stdint.h>
\\int foo(char a, unsigned char b, signed char c);
\\int foo(char a, unsigned char b, signed char c); // test a duplicate prototype
@@ -1747,7 +1739,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub extern fn baz(a: i8, b: i16, c: i32, d: i64) void;
});
- cases.add_2("simple function",
+ cases.add("simple function",
\\int abs(int a) {
\\ return a < 0 ? -a : a;
\\}
@@ -1758,7 +1750,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("post increment",
+ cases.add("post increment",
\\unsigned foo1(unsigned a) {
\\ a++;
\\ return a;
@@ -1780,7 +1772,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("deref function pointer",
+ cases.add("deref function pointer",
\\void foo(void) {}
\\int baz(void) { return 0; }
\\void bar(void) {
@@ -1810,7 +1802,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("pre increment/decrement",
+ cases.add("pre increment/decrement",
\\void foo(void) {
\\ int i = 0;
\\ unsigned u = 0;
@@ -1854,7 +1846,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("shift right assign",
+ cases.add("shift right assign",
\\int log2(unsigned a) {
\\ int i = 0;
\\ while (a > 0) {
@@ -1873,7 +1865,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("shift right assign with a fixed size type",
+ cases.add("shift right assign with a fixed size type",
\\#include <stdint.h>
\\int log2(uint32_t a) {
\\ int i = 0;
@@ -1893,7 +1885,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("compound assignment operators",
+ cases.add("compound assignment operators",
\\void foo(void) {
\\ int a = 0;
\\ a += (a += 1);
@@ -1951,7 +1943,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("compound assignment operators unsigned",
+ cases.add("compound assignment operators unsigned",
\\void foo(void) {
\\ unsigned a = 0;
\\ a += (a += 1);
@@ -2009,7 +2001,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("post increment/decrement",
+ cases.add("post increment/decrement",
\\void foo(void) {
\\ int i = 0;
\\ unsigned u = 0;
@@ -2057,7 +2049,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("implicit casts",
+ cases.add("implicit casts",
\\#include <stdbool.h>
\\
\\void fn_int(int x);
@@ -2113,7 +2105,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("function call",
+ cases.add("function call",
\\static void bar(void) { }
\\void foo(int *(baz)(void)) {
\\ bar();
@@ -2128,7 +2120,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("macro defines string literal with octal",
+ cases.add("macro defines string literal with octal",
\\#define FOO "aoeu\023 derp"
\\#define FOO2 "aoeu\0234 derp"
\\#define FOO_CHAR '\077'
@@ -2140,7 +2132,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const FOO_CHAR = '\x3f';
});
- cases.add_2("enums",
+ cases.add("enums",
\\enum Foo {
\\ FooA,
\\ FooB,
@@ -2162,7 +2154,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const Foo = enum_Foo;
});
- cases.add_2("enums",
+ cases.add("enums",
\\enum Foo {
\\ FooA = 2,
\\ FooB = 5,
@@ -2184,7 +2176,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const Foo = enum_Foo;
});
- cases.add_2("macro cast",
+ cases.add("macro cast",
\\#define FOO(bar) baz((void *)(baz))
, &[_][]const u8{
\\pub inline fn FOO(bar: var) @TypeOf(baz(if (@typeId(@TypeOf(baz)) == .Pointer) @ptrCast([*c]void, baz) else if (@typeId(@TypeOf(baz)) == .Int) @intToPtr([*c]void, baz) else @as([*c]void, baz))) {
@@ -2192,1006 +2184,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("macro conditional operator",
+ cases.add("macro conditional operator",
\\#define FOO a ? b : c
, &[_][]const u8{
\\pub const FOO = if (a) b else c;
});
-
- /////////////// Cases for only stage1 because stage2 behavior is better ////////////////
- cases.addC("Parameterless function prototypes",
- \\void foo() {}
- \\void bar(void) {}
- , &[_][]const u8{
- \\pub export fn foo() void {}
- \\pub export fn bar() void {}
- });
-
- cases.add("#define a char literal",
- \\#define A_CHAR 'a'
- , &[_][]const u8{
- \\pub const A_CHAR = 97;
- });
-
- cases.add("generate inline func for #define global extern fn",
- \\extern void (*fn_ptr)(void);
- \\#define foo fn_ptr
- \\
- \\extern char (*fn_ptr2)(int, float);
- \\#define bar fn_ptr2
- , &[_][]const u8{
- \\pub extern var fn_ptr: ?extern fn () void;
- ,
- \\pub inline fn foo() void {
- \\ return fn_ptr.?();
- \\}
- ,
- \\pub extern var fn_ptr2: ?extern fn (c_int, f32) u8;
- ,
- \\pub inline fn bar(arg0: c_int, arg1: f32) u8 {
- \\ return fn_ptr2.?(arg0, arg1);
- \\}
- });
- cases.add("comment after integer literal",
- \\#define SDL_INIT_VIDEO 0x00000020 /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
- , &[_][]const u8{
- \\pub const SDL_INIT_VIDEO = 32;
- });
-
- cases.add("u integer suffix after hex literal",
- \\#define SDL_INIT_VIDEO 0x00000020u /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
- , &[_][]const u8{
- \\pub const SDL_INIT_VIDEO = @as(c_uint, 32);
- });
-
- cases.add("l integer suffix after hex literal",
- \\#define SDL_INIT_VIDEO 0x00000020l /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
- , &[_][]const u8{
- \\pub const SDL_INIT_VIDEO = @as(c_long, 32);
- });
-
- cases.add("ul integer suffix after hex literal",
- \\#define SDL_INIT_VIDEO 0x00000020ul /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
- , &[_][]const u8{
- \\pub const SDL_INIT_VIDEO = @as(c_ulong, 32);
- });
-
- cases.add("lu integer suffix after hex literal",
- \\#define SDL_INIT_VIDEO 0x00000020lu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
- , &[_][]const u8{
- \\pub const SDL_INIT_VIDEO = @as(c_ulong, 32);
- });
-
- cases.add("ll integer suffix after hex literal",
- \\#define SDL_INIT_VIDEO 0x00000020ll /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
- , &[_][]const u8{
- \\pub const SDL_INIT_VIDEO = @as(c_longlong, 32);
- });
-
- cases.add("ull integer suffix after hex literal",
- \\#define SDL_INIT_VIDEO 0x00000020ull /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
- , &[_][]const u8{
- \\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 32);
- });
-
- cases.add("llu integer suffix after hex literal",
- \\#define SDL_INIT_VIDEO 0x00000020llu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
- , &[_][]const u8{
- \\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 32);
- });
-
- cases.add("macros with field targets",
- \\typedef unsigned int GLbitfield;
- \\typedef void (*PFNGLCLEARPROC) (GLbitfield mask);
- \\typedef void(*OpenGLProc)(void);
- \\union OpenGLProcs {
- \\ OpenGLProc ptr[1];
- \\ struct {
- \\ PFNGLCLEARPROC Clear;
- \\ } gl;
- \\};
- \\extern union OpenGLProcs glProcs;
- \\#define glClearUnion glProcs.gl.Clear
- \\#define glClearPFN PFNGLCLEARPROC
- , &[_][]const u8{
- \\pub const GLbitfield = c_uint;
- ,
- \\pub const PFNGLCLEARPROC = ?extern fn (GLbitfield) void;
- ,
- \\pub const OpenGLProc = ?extern fn () void;
- ,
- \\pub const union_OpenGLProcs = extern union {
- \\ ptr: [1]OpenGLProc,
- \\ gl: extern struct {
- \\ Clear: PFNGLCLEARPROC,
- \\ },
- \\};
- ,
- \\pub extern var glProcs: union_OpenGLProcs;
- ,
- \\pub const glClearPFN = PFNGLCLEARPROC;
- ,
- \\pub inline fn glClearUnion(arg0: GLbitfield) void {
- \\ return glProcs.gl.Clear.?(arg0);
- \\}
- ,
- \\pub const OpenGLProcs = union_OpenGLProcs;
- });
-
- cases.add("macro pointer cast",
- \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)
- , &[_][]const u8{
- \\pub const NRF_GPIO = if (@typeId(@TypeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Pointer) @ptrCast([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeId(@TypeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Int) @intToPtr([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else @as([*c]NRF_GPIO_Type, NRF_GPIO_BASE);
- });
-
- cases.add("switch on int",
- \\int switch_fn(int i) {
- \\ int res = 0;
- \\ switch (i) {
- \\ case 0:
- \\ res = 1;
- \\ case 1:
- \\ res = 2;
- \\ default:
- \\ res = 3 * i;
- \\ break;
- \\ case 2:
- \\ res = 5;
- \\ }
- \\}
- , &[_][]const u8{
- \\pub fn switch_fn(i: c_int) c_int {
- \\ var res: c_int = 0;
- \\ __switch: {
- \\ __case_2: {
- \\ __default: {
- \\ __case_1: {
- \\ __case_0: {
- \\ switch (i) {
- \\ 0 => break :__case_0,
- \\ 1 => break :__case_1,
- \\ else => break :__default,
- \\ 2 => break :__case_2,
- \\ }
- \\ }
- \\ res = 1;
- \\ }
- \\ res = 2;
- \\ }
- \\ res = (3 * i);
- \\ break :__switch;
- \\ }
- \\ res = 5;
- \\ }
- \\}
- });
-
- cases.add("for loop with var init but empty body",
- \\void foo(void) {
- \\ for (int x = 0; x < 10; x++);
- \\}
- , &[_][]const u8{
- \\pub fn foo() void {
- \\ {
- \\ var x: c_int = 0;
- \\ while (x < 10) : (x += 1) {}
- \\ }
- \\}
- });
-
- cases.add("do while with empty body",
- \\void foo(void) {
- \\ do ; while (1);
- \\}
- , &[_][]const u8{ // TODO this should be if (1 != 0) break
- \\pub fn foo() void {
- \\ while (true) {
- \\ {}
- \\ if (!1) break;
- \\ }
- \\}
- });
-
- cases.add("for with empty body",
- \\void foo(void) {
- \\ for (;;);
- \\}
- , &[_][]const u8{
- \\pub fn foo() void {
- \\ while (true) {}
- \\}
- });
-
- cases.add("while with empty body",
- \\void foo(void) {
- \\ while (1);
- \\}
- , &[_][]const u8{
- \\pub fn foo() void {
- \\ while (1 != 0) {}
- \\}
- });
-
- cases.add("undefined array global",
- \\int array[100];
- , &[_][]const u8{
- \\pub var array: [100]c_int = undefined;
- });
-
- cases.add("qualified struct and enum",
- \\struct Foo {
- \\ int x;
- \\ int y;
- \\};
- \\enum Bar {
- \\ BarA,
- \\ BarB,
- \\};
- \\void func(struct Foo *a, enum Bar **b);
- , &[_][]const u8{
- \\pub const struct_Foo = extern struct {
- \\ x: c_int,
- \\ y: c_int,
- \\};
- ,
- \\pub const enum_Bar = extern enum {
- \\ A,
- \\ B,
- \\};
- ,
- \\pub const BarA = enum_Bar.A;
- ,
- \\pub const BarB = enum_Bar.B;
- ,
- \\pub extern fn func(a: [*c]struct_Foo, b: [*c]([*c]enum_Bar)) void;
- ,
- \\pub const Foo = struct_Foo;
- ,
- \\pub const Bar = enum_Bar;
- });
-
- cases.add("restrict -> noalias",
- \\void foo(void *restrict bar, void *restrict);
- , &[_][]const u8{
- \\pub extern fn foo(noalias bar: ?*c_void, noalias arg1: ?*c_void) void;
- });
-
- cases.addC("assign",
- \\int max(int a) {
- \\ int tmp;
- \\ tmp = a;
- \\ a = tmp;
- \\}
- , &[_][]const u8{
- \\pub export fn max(_arg_a: c_int) c_int {
- \\ var a = _arg_a;
- \\ var tmp: c_int = undefined;
- \\ tmp = a;
- \\ a = tmp;
- \\}
- });
-
- cases.addC("chaining assign",
- \\void max(int a) {
- \\ int b, c;
- \\ c = b = a;
- \\}
- , &[_][]const u8{
- \\pub export fn max(a: c_int) void {
- \\ var b: c_int = undefined;
- \\ var c: c_int = undefined;
- \\ c = (x: {
- \\ const _tmp = a;
- \\ b = _tmp;
- \\ break :x _tmp;
- \\ });
- \\}
- });
-
- cases.add("anonymous enum",
- \\enum {
- \\ One,
- \\ Two,
- \\};
- , &[_][]const u8{
- \\pub const One = 0;
- \\pub const Two = 1;
- });
-
- cases.addC("c style cast",
- \\int float_to_int(float a) {
- \\ return (int)a;
- \\}
- , &[_][]const u8{
- \\pub export fn float_to_int(a: f32) c_int {
- \\ return @as(c_int, a);
- \\}
- });
-
- cases.addC("comma operator",
- \\int foo(void) {
- \\ return 1, 2;
- \\}
- , &[_][]const u8{
- \\pub export fn foo() c_int {
- \\ return x: {
- \\ _ = 1;
- \\ break :x 2;
- \\ };
- \\}
- });
-
- cases.addC("escape sequences",
- \\const char *escapes() {
- \\char a = '\'',
- \\ b = '\\',
- \\ c = '\a',
- \\ d = '\b',
- \\ e = '\f',
- \\ f = '\n',
- \\ g = '\r',
- \\ h = '\t',
- \\ i = '\v',
- \\ j = '\0',
- \\ k = '\"';
- \\ return "\'\\\a\b\f\n\r\t\v\0\"";
- \\}
- \\
- , &[_][]const u8{
- \\pub export fn escapes() [*c]const u8 {
- \\ var a: u8 = @as(u8, '\'');
- \\ var b: u8 = @as(u8, '\\');
- \\ var c: u8 = @as(u8, '\x07');
- \\ var d: u8 = @as(u8, '\x08');
- \\ var e: u8 = @as(u8, '\x0c');
- \\ var f: u8 = @as(u8, '\n');
- \\ var g: u8 = @as(u8, '\r');
- \\ var h: u8 = @as(u8, '\t');
- \\ var i: u8 = @as(u8, '\x0b');
- \\ var j: u8 = @as(u8, '\x00');
- \\ var k: u8 = @as(u8, '\"');
- \\ return "\'\\\x07\x08\x0c\n\r\t\x0b\x00\"";
- \\}
- \\
- });
-
- cases.addC("do loop",
- \\void foo(void) {
- \\ int a = 2;
- \\ do {
- \\ a--;
- \\ } while (a != 0);
- \\
- \\ int b = 2;
- \\ do
- \\ b--;
- \\ while (b != 0);
- \\}
- , &[_][]const u8{
- \\pub export fn foo() void {
- \\ var a: c_int = 2;
- \\ while (true) {
- \\ a -= 1;
- \\ if (!(a != 0)) break;
- \\ }
- \\ var b: c_int = 2;
- \\ while (true) {
- \\ b -= 1;
- \\ if (!(b != 0)) break;
- \\ }
- \\}
- });
-
- cases.addC("==, !=",
- \\int max(int a, int b) {
- \\ if (a == b)
- \\ return a;
- \\ if (a != b)
- \\ return b;
- \\ return a;
- \\}
- , &[_][]const u8{
- \\pub export fn max(a: c_int, b: c_int) c_int {
- \\ if (a == b) return a;
- \\ if (a != b) return b;
- \\ return a;
- \\}
- });
-
- cases.addC("bitwise binary operators",
- \\int max(int a, int b) {
- \\ return (a & b) ^ (a | b);
- \\}
- , &[_][]const u8{
- \\pub export fn max(a: c_int, b: c_int) c_int {
- \\ return (a & b) ^ (a | b);
- \\}
- });
-
- cases.addC("statement expression",
- \\int foo(void) {
- \\ return ({
- \\ int a = 1;
- \\ a;
- \\ });
- \\}
- , &[_][]const u8{
- \\pub export fn foo() c_int {
- \\ return x: {
- \\ var a: c_int = 1;
- \\ break :x a;
- \\ };
- \\}
- });
-
- cases.addC("field access expression",
- \\struct Foo {
- \\ int field;
- \\};
- \\int read_field(struct Foo *foo) {
- \\ return foo->field;
- \\}
- , &[_][]const u8{
- \\pub const struct_Foo = extern struct {
- \\ field: c_int,
- \\};
- \\pub export fn read_field(foo: [*c]struct_Foo) c_int {
- \\ return foo.*.field;
- \\}
- });
-
- cases.addC("array access",
- \\int array[100];
- \\int foo(int index) {
- \\ return array[index];
- \\}
- , &[_][]const u8{
- \\pub var array: [100]c_int = undefined;
- \\pub export fn foo(index: c_int) c_int {
- \\ return array[index];
- \\}
- });
-
- cases.addC("logical and, logical or",
- \\int max(int a, int b) {
- \\ if (a < b || a == b)
- \\ return b;
- \\ if (a >= b && a == b)
- \\ return a;
- \\ return a;
- \\}
- , &[_][]const u8{
- \\pub export fn max(a: c_int, b: c_int) c_int {
- \\ if ((a < b) or (a == b)) return b;
- \\ if ((a >= b) and (a == b)) return a;
- \\ return a;
- \\}
- });
-
- cases.addC("if statement",
- \\int max(int a, int b) {
- \\ if (a < b)
- \\ return b;
- \\
- \\ if (a < b)
- \\ return b;
- \\ else
- \\ return a;
- \\
- \\ if (a < b) ; else ;
- \\}
- , &[_][]const u8{
- \\pub export fn max(a: c_int, b: c_int) c_int {
- \\ if (a < b) return b;
- \\ if (a < b) return b else return a;
- \\ if (a < b) {} else {}
- \\}
- });
-
- cases.add("variable name shadowing",
- \\int foo(void) {
- \\ int x = 1;
- \\ {
- \\ int x = 2;
- \\ x += 1;
- \\ }
- \\ return x;
- \\}
- , &[_][]const u8{
- \\pub fn foo() c_int {
- \\ var x: c_int = 1;
- \\ {
- \\ var x_0: c_int = 2;
- \\ x_0 += 1;
- \\ }
- \\ return x;
- \\}
- });
-
- cases.add("if on non-bool",
- \\enum SomeEnum { A, B, C };
- \\int if_none_bool(int a, float b, void *c, enum SomeEnum d) {
- \\ if (a) return 0;
- \\ if (b) return 1;
- \\ if (c) return 2;
- \\ if (d) return 3;
- \\ return 4;
- \\}
- , &[_][]const u8{
- \\pub const A = enum_SomeEnum.A;
- \\pub const B = enum_SomeEnum.B;
- \\pub const C = enum_SomeEnum.C;
- \\pub const enum_SomeEnum = extern enum {
- \\ A,
- \\ B,
- \\ C,
- \\};
- \\pub fn if_none_bool(a: c_int, b: f32, c: ?*c_void, d: enum_SomeEnum) c_int {
- \\ if (a != 0) return 0;
- \\ if (b != 0) return 1;
- \\ if (c != null) return 2;
- \\ if (d != @bitCast(enum_SomeEnum, @as(@TagType(enum_SomeEnum), 0))) return 3;
- \\ return 4;
- \\}
- });
-
- cases.addAllowWarnings("simple data types",
- \\#include <stdint.h>
- \\int foo(char a, unsigned char b, signed char c);
- \\int foo(char a, unsigned char b, signed char c); // test a duplicate prototype
- \\void bar(uint8_t a, uint16_t b, uint32_t c, uint64_t d);
- \\void baz(int8_t a, int16_t b, int32_t c, int64_t d);
- , &[_][]const u8{
- \\pub extern fn foo(a: u8, b: u8, c: i8) c_int;
- ,
- \\pub extern fn bar(a: u8, b: u16, c: u32, d: u64) void;
- ,
- \\pub extern fn baz(a: i8, b: i16, c: i32, d: i64) void;
- });
-
- cases.addC("simple function",
- \\int abs(int a) {
- \\ return a < 0 ? -a : a;
- \\}
- , &[_][]const u8{
- \\pub export fn abs(a: c_int) c_int {
- \\ return if (a < 0) -a else a;
- \\}
- });
-
- cases.addC("post increment",
- \\unsigned foo1(unsigned a) {
- \\ a++;
- \\ return a;
- \\}
- \\int foo2(int a) {
- \\ a++;
- \\ return a;
- \\}
- , &[_][]const u8{
- \\pub export fn foo1(_arg_a: c_uint) c_uint {
- \\ var a = _arg_a;
- \\ a +%= 1;
- \\ return a;
- \\}
- \\pub export fn foo2(_arg_a: c_int) c_int {
- \\ var a = _arg_a;
- \\ a += 1;
- \\ return a;
- \\}
- });
-
- cases.addC("deref function pointer",
- \\void foo(void) {}
- \\int baz(void) { return 0; }
- \\void bar(void) {
- \\ void(*f)(void) = foo;
- \\ int(*b)(void) = baz;
- \\ f();
- \\ (*(f))();
- \\ foo();
- \\ b();
- \\ (*(b))();
- \\ baz();
- \\}
- , &[_][]const u8{
- \\pub export fn foo() void {}
- \\pub export fn baz() c_int {
- \\ return 0;
- \\}
- \\pub export fn bar() void {
- \\ var f: ?extern fn () void = foo;
- \\ var b: ?extern fn () c_int = baz;
- \\ f.?();
- \\ f.?();
- \\ foo();
- \\ _ = b.?();
- \\ _ = b.?();
- \\ _ = baz();
- \\}
- });
-
- cases.addC("pre increment/decrement",
- \\void foo(void) {
- \\ int i = 0;
- \\ unsigned u = 0;
- \\ ++i;
- \\ --i;
- \\ ++u;
- \\ --u;
- \\ i = ++i;
- \\ i = --i;
- \\ u = ++u;
- \\ u = --u;
- \\}
- , &[_][]const u8{
- \\pub export fn foo() void {
- \\ var i: c_int = 0;
- \\ var u: c_uint = @as(c_uint, 0);
- \\ i += 1;
- \\ i -= 1;
- \\ u +%= 1;
- \\ u -%= 1;
- \\ i = (x: {
- \\ const _ref = &i;
- \\ _ref.* += 1;
- \\ break :x _ref.*;
- \\ });
- \\ i = (x: {
- \\ const _ref = &i;
- \\ _ref.* -= 1;
- \\ break :x _ref.*;
- \\ });
- \\ u = (x: {
- \\ const _ref = &u;
- \\ _ref.* +%= 1;
- \\ break :x _ref.*;
- \\ });
- \\ u = (x: {
- \\ const _ref = &u;
- \\ _ref.* -%= 1;
- \\ break :x _ref.*;
- \\ });
- \\}
- });
-
- cases.addC("shift right assign",
- \\int log2(unsigned a) {
- \\ int i = 0;
- \\ while (a > 0) {
- \\ a >>= 1;
- \\ }
- \\ return i;
- \\}
- , &[_][]const u8{
- \\pub export fn log2(_arg_a: c_uint) c_int {
- \\ var a = _arg_a;
- \\ var i: c_int = 0;
- \\ while (a > @as(c_uint, 0)) {
- \\ a >>= @as(@import("std").math.Log2Int(c_uint), 1);
- \\ }
- \\ return i;
- \\}
- });
-
- cases.addC("shift right assign with a fixed size type",
- \\#include <stdint.h>
- \\int log2(uint32_t a) {
- \\ int i = 0;
- \\ while (a > 0) {
- \\ a >>= 1;
- \\ }
- \\ return i;
- \\}
- , &[_][]const u8{
- \\pub export fn log2(_arg_a: u32) c_int {
- \\ var a = _arg_a;
- \\ var i: c_int = 0;
- \\ while (a > @as(c_uint, 0)) {
- \\ a >>= @as(u5, 1);
- \\ }
- \\ return i;
- \\}
- });
-
- cases.addC("compound assignment operators",
- \\void foo(void) {
- \\ int a = 0;
- \\ a += (a += 1);
- \\ a -= (a -= 1);
- \\ a *= (a *= 1);
- \\ a &= (a &= 1);
- \\ a |= (a |= 1);
- \\ a ^= (a ^= 1);
- \\ a >>= (a >>= 1);
- \\ a <<= (a <<= 1);
- \\}
- , &[_][]const u8{
- \\pub export fn foo() void {
- \\ var a: c_int = 0;
- \\ a += (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* + 1);
- \\ break :x _ref.*;
- \\ });
- \\ a -= (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* - 1);
- \\ break :x _ref.*;
- \\ });
- \\ a *= (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* * 1);
- \\ break :x _ref.*;
- \\ });
- \\ a &= (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* & 1);
- \\ break :x _ref.*;
- \\ });
- \\ a |= (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* | 1);
- \\ break :x _ref.*;
- \\ });
- \\ a ^= (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* ^ 1);
- \\ break :x _ref.*;
- \\ });
- \\ a >>= @as(@import("std").math.Log2Int(c_int), (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* >> @as(@import("std").math.Log2Int(c_int), 1));
- \\ break :x _ref.*;
- \\ }));
- \\ a <<= @as(@import("std").math.Log2Int(c_int), (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* << @as(@import("std").math.Log2Int(c_int), 1));
- \\ break :x _ref.*;
- \\ }));
- \\}
- });
-
- cases.addC("compound assignment operators unsigned",
- \\void foo(void) {
- \\ unsigned a = 0;
- \\ a += (a += 1);
- \\ a -= (a -= 1);
- \\ a *= (a *= 1);
- \\ a &= (a &= 1);
- \\ a |= (a |= 1);
- \\ a ^= (a ^= 1);
- \\ a >>= (a >>= 1);
- \\ a <<= (a <<= 1);
- \\}
- , &[_][]const u8{
- \\pub export fn foo() void {
- \\ var a: c_uint = @as(c_uint, 0);
- \\ a +%= (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* +% @as(c_uint, 1));
- \\ break :x _ref.*;
- \\ });
- \\ a -%= (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* -% @as(c_uint, 1));
- \\ break :x _ref.*;
- \\ });
- \\ a *%= (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* *% @as(c_uint, 1));
- \\ break :x _ref.*;
- \\ });
- \\ a &= (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* & @as(c_uint, 1));
- \\ break :x _ref.*;
- \\ });
- \\ a |= (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* | @as(c_uint, 1));
- \\ break :x _ref.*;
- \\ });
- \\ a ^= (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* ^ @as(c_uint, 1));
- \\ break :x _ref.*;
- \\ });
- \\ a >>= @as(@import("std").math.Log2Int(c_uint), (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* >> @as(@import("std").math.Log2Int(c_uint), 1));
- \\ break :x _ref.*;
- \\ }));
- \\ a <<= @as(@import("std").math.Log2Int(c_uint), (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* << @as(@import("std").math.Log2Int(c_uint), 1));
- \\ break :x _ref.*;
- \\ }));
- \\}
- });
-
- cases.addC("post increment/decrement",
- \\void foo(void) {
- \\ int i = 0;
- \\ unsigned u = 0;
- \\ i++;
- \\ i--;
- \\ u++;
- \\ u--;
- \\ i = i++;
- \\ i = i--;
- \\ u = u++;
- \\ u = u--;
- \\}
- , &[_][]const u8{
- \\pub export fn foo() void {
- \\ var i: c_int = 0;
- \\ var u: c_uint = @as(c_uint, 0);
- \\ i += 1;
- \\ i -= 1;
- \\ u +%= 1;
- \\ u -%= 1;
- \\ i = (x: {
- \\ const _ref = &i;
- \\ const _tmp = _ref.*;
- \\ _ref.* += 1;
- \\ break :x _tmp;
- \\ });
- \\ i = (x: {
- \\ const _ref = &i;
- \\ const _tmp = _ref.*;
- \\ _ref.* -= 1;
- \\ break :x _tmp;
- \\ });
- \\ u = (x: {
- \\ const _ref = &u;
- \\ const _tmp = _ref.*;
- \\ _ref.* +%= 1;
- \\ break :x _tmp;
- \\ });
- \\ u = (x: {
- \\ const _ref = &u;
- \\ const _tmp = _ref.*;
- \\ _ref.* -%= 1;
- \\ break :x _tmp;
- \\ });
- \\}
- });
-
- cases.addC("implicit casts",
- \\#include <stdbool.h>
- \\
- \\void fn_int(int x);
- \\void fn_f32(float x);
- \\void fn_f64(double x);
- \\void fn_char(char x);
- \\void fn_bool(bool x);
- \\void fn_ptr(void *x);
- \\
- \\void call(int q) {
- \\ fn_int(3.0f);
- \\ fn_int(3.0);
- \\ fn_int(3.0L);
- \\ fn_int('ABCD');
- \\ fn_f32(3);
- \\ fn_f64(3);
- \\ fn_char('3');
- \\ fn_char('\x1');
- \\ fn_char(0);
- \\ fn_f32(3.0f);
- \\ fn_f64(3.0);
- \\ fn_bool(123);
- \\ fn_bool(0);
- \\ fn_bool(&fn_int);
- \\ fn_int(&fn_int);
- \\ fn_ptr(42);
- \\}
- , &[_][]const u8{
- \\pub extern fn fn_int(x: c_int) void;
- \\pub extern fn fn_f32(x: f32) void;
- \\pub extern fn fn_f64(x: f64) void;
- \\pub extern fn fn_char(x: u8) void;
- \\pub extern fn fn_bool(x: bool) void;
- \\pub extern fn fn_ptr(x: ?*c_void) void;
- \\pub export fn call(q: c_int) void {
- \\ fn_int(@floatToInt(c_int, 3.000000));
- \\ fn_int(@floatToInt(c_int, 3.000000));
- \\ fn_int(@floatToInt(c_int, 3.000000));
- \\ fn_int(1094861636);
- \\ fn_f32(@intToFloat(f32, 3));
- \\ fn_f64(@intToFloat(f64, 3));
- \\ fn_char(@as(u8, '3'));
- \\ fn_char(@as(u8, '\x01'));
- \\ fn_char(@as(u8, 0));
- \\ fn_f32(3.000000);
- \\ fn_f64(3.000000);
- \\ fn_bool(true);
- \\ fn_bool(false);
- \\ fn_bool(@ptrToInt(&fn_int) != 0);
- \\ fn_int(@intCast(c_int, @ptrToInt(&fn_int)));
- \\ fn_ptr(@intToPtr(?*c_void, 42));
- \\}
- });
-
- cases.addC("function call",
- \\static void bar(void) { }
- \\void foo(int *(baz)(void)) {
- \\ bar();
- \\ baz();
- \\}
- , &[_][]const u8{
- \\pub fn bar() void {}
- \\pub export fn foo(baz: ?extern fn () [*c]c_int) void {
- \\ bar();
- \\ _ = baz.?();
- \\}
- });
-
- cases.add("macro defines string literal with hex",
- \\#define FOO "aoeu\xab derp"
- \\#define FOO2 "aoeu\x0007a derp"
- \\#define FOO_CHAR '\xfF'
- , &[_][]const u8{
- \\pub const FOO = "aoeu\xab derp";
- ,
- \\pub const FOO2 = "aoeuz derp";
- ,
- \\pub const FOO_CHAR = 255;
- });
-
- cases.add("macro defines string literal with octal",
- \\#define FOO "aoeu\023 derp"
- \\#define FOO2 "aoeu\0234 derp"
- \\#define FOO_CHAR '\077'
- , &[_][]const u8{
- \\pub const FOO = "aoeu\x13 derp";
- ,
- \\pub const FOO2 = "aoeu\x134 derp";
- ,
- \\pub const FOO_CHAR = 63;
- });
-
- cases.add("enums",
- \\enum Foo {
- \\ FooA,
- \\ FooB,
- \\ Foo1,
- \\};
- , &[_][]const u8{
- \\pub const enum_Foo = extern enum {
- \\ A,
- \\ B,
- \\ @"1",
- \\};
- ,
- \\pub const FooA = enum_Foo.A;
- ,
- \\pub const FooB = enum_Foo.B;
- ,
- \\pub const Foo1 = enum_Foo.@"1";
- ,
- \\pub const Foo = enum_Foo;
- });
-
- cases.add("enums",
- \\enum Foo {
- \\ FooA = 2,
- \\ FooB = 5,
- \\ Foo1,
- \\};
- , &[_][]const u8{
- \\pub const enum_Foo = extern enum {
- \\ A = 2,
- \\ B = 5,
- \\ @"1" = 6,
- \\};
- ,
- \\pub const FooA = enum_Foo.A;
- ,
- \\pub const FooB = enum_Foo.B;
- ,
- \\pub const Foo1 = enum_Foo.@"1";
- ,
- \\pub const Foo = enum_Foo;
- });
}
CMakeLists.txt
@@ -448,7 +448,6 @@ set(ZIG_SOURCES
"${CMAKE_SOURCE_DIR}/src/bigfloat.cpp"
"${CMAKE_SOURCE_DIR}/src/bigint.cpp"
"${CMAKE_SOURCE_DIR}/src/buffer.cpp"
- "${CMAKE_SOURCE_DIR}/src/c_tokenizer.cpp"
"${CMAKE_SOURCE_DIR}/src/cache_hash.cpp"
"${CMAKE_SOURCE_DIR}/src/codegen.cpp"
"${CMAKE_SOURCE_DIR}/src/compiler.cpp"
@@ -465,7 +464,6 @@ set(ZIG_SOURCES
"${CMAKE_SOURCE_DIR}/src/range_set.cpp"
"${CMAKE_SOURCE_DIR}/src/target.cpp"
"${CMAKE_SOURCE_DIR}/src/tokenizer.cpp"
- "${CMAKE_SOURCE_DIR}/src/translate_c.cpp"
"${CMAKE_SOURCE_DIR}/src/util.cpp"
"${ZIG_SOURCES_MEM_PROFILE}"
)