aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--doc/langref.html.in26
-rw-r--r--src-self-hosted/value.zig8
-rw-r--r--src/bigint.cpp11
-rw-r--r--src/codegen.cpp2
-rw-r--r--src/link.cpp32
-rw-r--r--src/main.cpp5
-rw-r--r--src/target.cpp17
-rw-r--r--src/translate_c.cpp778
-rw-r--r--src/zig_clang.cpp45
-rw-r--r--src/zig_clang.h15
-rw-r--r--std/debug.zig2
-rw-r--r--std/math/big.zig2
-rw-r--r--std/math/big/int.zig645
-rw-r--r--std/math/big/rational.zig896
-rw-r--r--std/special/compiler_rt.zig16
-rw-r--r--std/special/compiler_rt/divti3.zig6
-rw-r--r--std/special/compiler_rt/modti3.zig6
-rw-r--r--std/special/compiler_rt/muloti4.zig10
-rw-r--r--std/special/compiler_rt/multi3.zig6
-rw-r--r--std/special/compiler_rt/udivmodti4.zig5
-rw-r--r--std/special/compiler_rt/udivti3.zig5
-rw-r--r--std/special/compiler_rt/umodti3.zig6
-rw-r--r--test/stage1/behavior/bit_shifting.zig8
-rw-r--r--test/stage1/behavior/math.zig7
25 files changed, 1846 insertions, 714 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8588c3ae9e..2c34f334f9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -521,6 +521,7 @@ set(ZIG_STD_FILES
"math/atanh.zig"
"math/big.zig"
"math/big/int.zig"
+ "math/big/rational.zig"
"math/cbrt.zig"
"math/ceil.zig"
"math/complex.zig"
diff --git a/doc/langref.html.in b/doc/langref.html.in
index 1d80c73a3e..a73e5d94d9 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -7360,20 +7360,30 @@ fn List(comptime T: type) type {
<pre>{#syntax#}@truncate(comptime T: type, integer: var) T{#endsyntax#}</pre>
<p>
This function truncates bits from an integer type, resulting in a smaller
- integer type.
+ or same-sized integer type.
</p>
<p>
- The following produces a crash in {#link|Debug#} mode and {#link|Undefined Behavior#} in
- {#link|ReleaseFast#} mode:
+ The following produces safety-checked {#link|Undefined Behavior#}:
</p>
- <pre>{#syntax#}const a: u16 = 0xabcd;
-const b: u8 = u8(a);{#endsyntax#}</pre>
+ {#code_begin|test_err|cast truncated bits#}
+test "integer cast panic" {
+ var a: u16 = 0xabcd;
+ var b: u8 = @intCast(u8, a);
+}
+ {#code_end#}
<p>
However this is well defined and working code:
</p>
- <pre>{#syntax#}const a: u16 = 0xabcd;
-const b: u8 = @truncate(u8, a);
-// b is now 0xcd{#endsyntax#}</pre>
+ {#code_begin|test|truncate#}
+const std = @import("std");
+const assert = std.debug.assert;
+
+test "integer truncation" {
+ var a: u16 = 0xabcd;
+ var b: u8 = @truncate(u8, a);
+ assert(b == 0xcd);
+}
+ {#code_end#}
<p>
This function always truncates the significant bits of the integer, regardless
of endianness on the target platform.
diff --git a/src-self-hosted/value.zig b/src-self-hosted/value.zig
index d8c0f7b5c8..f1c7fc0b50 100644
--- a/src-self-hosted/value.zig
+++ b/src-self-hosted/value.zig
@@ -538,21 +538,21 @@ pub const Value = struct {
switch (self.base.typ.id) {
Type.Id.Int => {
const type_ref = try self.base.typ.getLlvmType(ofile.arena, ofile.context);
- if (self.big_int.len == 0) {
+ if (self.big_int.len() == 0) {
return llvm.ConstNull(type_ref);
}
- const unsigned_val = if (self.big_int.len == 1) blk: {
+ const unsigned_val = if (self.big_int.len() == 1) blk: {
break :blk llvm.ConstInt(type_ref, self.big_int.limbs[0], @boolToInt(false));
} else if (@sizeOf(std.math.big.Limb) == @sizeOf(u64)) blk: {
break :blk llvm.ConstIntOfArbitraryPrecision(
type_ref,
- @intCast(c_uint, self.big_int.len),
+ @intCast(c_uint, self.big_int.len()),
@ptrCast([*]u64, self.big_int.limbs.ptr),
);
} else {
@compileError("std.math.Big.Int.Limb size does not match LLVM");
};
- return if (self.big_int.positive) unsigned_val else llvm.ConstNeg(unsigned_val);
+ return if (self.big_int.isPositive()) unsigned_val else llvm.ConstNeg(unsigned_val);
},
Type.Id.ComptimeInt => unreachable,
else => unreachable,
diff --git a/src/bigint.cpp b/src/bigint.cpp
index d3178c35c6..dcd9dfc0bd 100644
--- a/src/bigint.cpp
+++ b/src/bigint.cpp
@@ -1410,12 +1410,19 @@ void bigint_shr(BigInt *dest, const BigInt *op1, const BigInt *op2) {
}
dest->digit_count = op1->digit_count - digit_shift_count;
- dest->data.digits = allocate<uint64_t>(dest->digit_count);
+ uint64_t *digits;
+ if (dest->digit_count == 1) {
+ digits = &dest->data.digit;
+ } else {
+ digits = allocate<uint64_t>(dest->digit_count);
+ dest->data.digits = digits;
+ }
+
uint64_t carry = 0;
for (size_t op_digit_index = op1->digit_count - 1;;) {
uint64_t digit = op1_digits[op_digit_index];
size_t dest_digit_index = op_digit_index - digit_shift_count;
- dest->data.digits[dest_digit_index] = carry | (digit >> leftover_shift_count);
+ digits[dest_digit_index] = carry | (digit >> leftover_shift_count);
carry = digit << (64 - leftover_shift_count);
if (dest_digit_index == 0) { break; }
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 568344fc09..7d21787809 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -424,7 +424,7 @@ static uint32_t get_err_ret_trace_arg_index(CodeGen *g, ZigFn *fn_table_entry) {
}
static void maybe_export_dll(CodeGen *g, LLVMValueRef global_value, GlobalLinkageId linkage) {
- if (linkage != GlobalLinkageIdInternal && g->zig_target->os == OsWindows) {
+ if (linkage != GlobalLinkageIdInternal && g->zig_target->os == OsWindows && g->is_dynamic) {
LLVMSetDLLStorageClass(global_value, LLVMDLLExportStorageClass);
}
}
diff --git a/src/link.cpp b/src/link.cpp
index d6093581f7..78e549c80b 100644
--- a/src/link.cpp
+++ b/src/link.cpp
@@ -1101,6 +1101,16 @@ static void construct_linker_job_wasm(LinkJob *lj) {
for (size_t i = 0; i < g->link_objects.length; i += 1) {
lj->args.append((const char *)buf_ptr(g->link_objects.at(i)));
}
+
+ if (g->out_type == OutTypeExe) {
+ if (g->libc_link_lib == nullptr) {
+ Buf *builtin_a_path = build_a(g, "builtin");
+ lj->args.append(buf_ptr(builtin_a_path));
+ }
+
+ Buf *compiler_rt_o_path = build_compiler_rt(g);
+ lj->args.append(buf_ptr(compiler_rt_o_path));
+ }
}
static void coff_append_machine_arg(CodeGen *g, ZigList<const char *> *list) {
@@ -1416,18 +1426,6 @@ static void get_darwin_platform(LinkJob *lj, DarwinPlatform *platform) {
}
}
-static bool darwin_version_lt(DarwinPlatform *platform, int major, int minor) {
- if (platform->major < major) {
- return true;
- } else if (platform->major > major) {
- return false;
- }
- if (platform->minor < minor) {
- return true;
- }
- return false;
-}
-
static void construct_linker_job_macho(LinkJob *lj) {
CodeGen *g = lj->codegen;
@@ -1552,16 +1550,6 @@ static void construct_linker_job_macho(LinkJob *lj) {
lj->args.append("dynamic_lookup");
}
- if (platform.kind == MacOS) {
- if (darwin_version_lt(&platform, 10, 5)) {
- lj->args.append("-lgcc_s.10.4");
- } else if (darwin_version_lt(&platform, 10, 6)) {
- lj->args.append("-lgcc_s.10.5");
- }
- } else {
- zig_panic("TODO");
- }
-
for (size_t i = 0; i < g->darwin_frameworks.length; i += 1) {
lj->args.append("-framework");
lj->args.append(buf_ptr(g->darwin_frameworks.at(i)));
diff --git a/src/main.cpp b/src/main.cpp
index bd3d574956..85e5b0c042 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1144,14 +1144,15 @@ int main(int argc, char **argv) {
codegen_print_timing_report(g, stdout);
if (cmd == CmdRun) {
+ const char *exec_path = buf_ptr(&g->output_file_path);
ZigList<const char*> args = {0};
+
+ args.append(exec_path);
if (runtime_args_start != -1) {
for (int i = runtime_args_start; i < argc; ++i) {
args.append(argv[i]);
}
}
-
- const char *exec_path = buf_ptr(&g->output_file_path);
args.append(nullptr);
os_execv(exec_path, args.items);
diff --git a/src/target.cpp b/src/target.cpp
index dda8188765..3b4265359c 100644
--- a/src/target.cpp
+++ b/src/target.cpp
@@ -894,10 +894,25 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
case CIntTypeCount:
zig_unreachable();
}
+ case OsIOS:
+ switch (id) {
+ case CIntTypeShort:
+ case CIntTypeUShort:
+ return 16;
+ case CIntTypeInt:
+ case CIntTypeUInt:
+ return 32;
+ case CIntTypeLong:
+ case CIntTypeULong:
+ case CIntTypeLongLong:
+ case CIntTypeULongLong:
+ return 64;
+ case CIntTypeCount:
+ zig_unreachable();
+ }
case OsAnanas:
case OsCloudABI:
case OsDragonFly:
- case OsIOS:
case OsKFreeBSD:
case OsLv2:
case OsSolaris:
diff --git a/src/translate_c.cpp b/src/translate_c.cpp
index 8abd66c0ff..5307e3030d 100644
--- a/src/translate_c.cpp
+++ b/src/translate_c.cpp
@@ -112,7 +112,7 @@ static TransScopeSwitch *trans_scope_switch_create(Context *c, TransScope *paren
static TransScopeBlock *trans_scope_block_find(TransScope *scope);
-static AstNode *resolve_record_decl(Context *c, const clang::RecordDecl *record_decl);
+static AstNode *resolve_record_decl(Context *c, const ZigClangRecordDecl *record_decl);
static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl);
static AstNode *resolve_typedef_decl(Context *c, const clang::TypedefNameDecl *typedef_decl);
@@ -122,9 +122,9 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st
TransScope **out_node_scope);
static TransScope *trans_stmt(Context *c, TransScope *scope, const clang::Stmt *stmt, AstNode **out_node);
static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::Expr *expr, TransLRValue lrval);
-static AstNode *trans_qual_type(Context *c, clang::QualType qt, const clang::SourceLocation &source_loc);
+static AstNode *trans_qual_type(Context *c, clang::QualType qt, ZigClangSourceLocation source_loc);
static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::Expr *expr, TransLRValue lrval);
-static AstNode *trans_ap_value(Context *c, clang::APValue *ap_value, clang::QualType qt, const clang::SourceLocation &source_loc);
+static AstNode *trans_ap_value(Context *c, clang::APValue *ap_value, clang::QualType qt, ZigClangSourceLocation source_loc);
static ZigClangSourceLocation bitcast(clang::SourceLocation src) {
ZigClangSourceLocation dest;
@@ -143,7 +143,7 @@ static clang::QualType bitcast(ZigClangQualType src) {
}
ATTRIBUTE_PRINTF(3, 4)
-static void emit_warning(Context *c, const clang::SourceLocation &clang_sl, const char *format, ...) {
+static void emit_warning(Context *c, ZigClangSourceLocation sl, const char *format, ...) {
if (!c->warnings_on) {
return;
}
@@ -153,7 +153,6 @@ static void emit_warning(Context *c, const clang::SourceLocation &clang_sl, cons
Buf *msg = buf_vprintf(format, ap);
va_end(ap);
- ZigClangSourceLocation sl = bitcast(clang_sl);
const char *filename_bytes = ZigClangSourceManager_getFilename(c->source_manager,
ZigClangSourceManager_getSpellingLoc(c->source_manager, sl));
Buf *path;
@@ -489,11 +488,6 @@ static Buf *string_ref_to_buf(llvm::StringRef string_ref) {
return buf_create_from_mem((const char *)string_ref.bytes_begin(), string_ref.size());
}
-static const char *decl_name(const clang::Decl *decl) {
- const clang::NamedDecl *named_decl = static_cast<const clang::NamedDecl *>(decl);
- return (const char *)named_decl->getName().bytes_begin();
-}
-
static AstNode *trans_create_node_apint(Context *c, const llvm::APSInt &aps_int) {
AstNode *node = trans_create_node(c, NodeTypeIntLiteral);
node->data.int_literal.bigint = allocate<BigInt>(1);
@@ -539,7 +533,7 @@ static clang::QualType get_expr_qual_type_before_implicit_cast(Context *c, const
}
static AstNode *get_expr_type(Context *c, const clang::Expr *expr) {
- return trans_qual_type(c, get_expr_qual_type(c, expr), expr->getBeginLoc());
+ return trans_qual_type(c, get_expr_qual_type(c, expr), bitcast(expr->getBeginLoc()));
}
static bool qual_types_equal(clang::QualType t1, clang::QualType t2) {
@@ -598,7 +592,7 @@ static bool qual_type_is_fn_ptr(clang::QualType qt) {
return false;
}
-static uint32_t qual_type_int_bit_width(Context *c, const clang::QualType &qt, const clang::SourceLocation &source_loc) {
+static uint32_t qual_type_int_bit_width(Context *c, const clang::QualType &qt, ZigClangSourceLocation source_loc) {
const clang::Type *ty = qt.getTypePtr();
switch (ty->getTypeClass()) {
case clang::Type::Builtin:
@@ -622,7 +616,7 @@ static uint32_t qual_type_int_bit_width(Context *c, const clang::QualType &qt, c
{
const clang::TypedefType *typedef_ty = static_cast<const clang::TypedefType*>(ty);
const clang::TypedefNameDecl *typedef_decl = typedef_ty->getDecl();
- const char *type_name = decl_name(typedef_decl);
+ 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) {
@@ -643,7 +637,7 @@ static uint32_t qual_type_int_bit_width(Context *c, const clang::QualType &qt, c
static AstNode *qual_type_to_log2_int_ref(Context *c, const clang::QualType &qt,
- const clang::SourceLocation &source_loc)
+ ZigClangSourceLocation source_loc)
{
uint32_t int_bit_width = qual_type_int_bit_width(c, qt, source_loc);
if (int_bit_width != 0) {
@@ -688,7 +682,7 @@ static bool qual_type_child_is_fn_proto(const clang::QualType &qt) {
return false;
}
-static AstNode* trans_c_cast(Context *c, const clang::SourceLocation &source_location, clang::QualType dest_type,
+static AstNode* trans_c_cast(Context *c, ZigClangSourceLocation source_location, clang::QualType dest_type,
clang::QualType src_type, AstNode *expr)
{
// The only way void pointer casts are valid C code, is if
@@ -788,7 +782,7 @@ static bool qual_type_has_wrapping_overflow(Context *c, clang::QualType qt) {
}
}
-static bool type_is_opaque(Context *c, const clang::Type *ty, const clang::SourceLocation &source_loc) {
+static bool type_is_opaque(Context *c, const clang::Type *ty, ZigClangSourceLocation source_loc) {
switch (ty->getTypeClass()) {
case clang::Type::Builtin: {
const clang::BuiltinType *builtin_ty = static_cast<const clang::BuiltinType*>(ty);
@@ -812,7 +806,7 @@ static bool type_is_opaque(Context *c, const clang::Type *ty, const clang::Sourc
}
}
-static AstNode *trans_type(Context *c, const clang::Type *ty, const clang::SourceLocation &source_loc) {
+static AstNode *trans_type(Context *c, const clang::Type *ty, ZigClangSourceLocation source_loc) {
switch (ty->getTypeClass()) {
case clang::Type::Builtin:
{
@@ -1129,8 +1123,8 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, const clang::Sourc
}
case clang::Type::Record:
{
- const clang::RecordType *record_ty = static_cast<const clang::RecordType*>(ty);
- return resolve_record_decl(c, record_ty->getDecl());
+ const ZigClangRecordType *record_ty = reinterpret_cast<const ZigClangRecordType*>(ty);
+ return resolve_record_decl(c, ZigClangRecordType_getDecl(record_ty));
}
case clang::Type::Enum:
{
@@ -1217,7 +1211,7 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, const clang::Sourc
zig_unreachable();
}
-static AstNode *trans_qual_type(Context *c, clang::QualType qt, const clang::SourceLocation &source_loc) {
+static AstNode *trans_qual_type(Context *c, clang::QualType qt, ZigClangSourceLocation source_loc) {
return trans_type(c, qt.getTypePtr(), source_loc);
}
@@ -1289,7 +1283,7 @@ static AstNode *trans_return_stmt(Context *c, TransScope *scope, const clang::Re
static AstNode *trans_integer_literal(Context *c, ResultUsed result_used, const clang::IntegerLiteral *stmt) {
clang::Expr::EvalResult result;
if (!stmt->EvaluateAsInt(result, *reinterpret_cast<clang::ASTContext *>(c->ctx))) {
- emit_warning(c, stmt->getBeginLoc(), "invalid integer literal");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "invalid integer literal");
return nullptr;
}
AstNode *node = trans_create_node_apint(c, result.Val.getInt());
@@ -1301,10 +1295,10 @@ static AstNode *trans_constant_expr(Context *c, ResultUsed result_used, const cl
if (!expr->EvaluateAsConstantExpr(result, clang::Expr::EvaluateForCodeGen,
*reinterpret_cast<clang::ASTContext *>(c->ctx)))
{
- emit_warning(c, expr->getBeginLoc(), "invalid constant expression");
+ emit_warning(c, bitcast(expr->getBeginLoc()), "invalid constant expression");
return nullptr;
}
- AstNode *node = trans_ap_value(c, &result.Val, expr->getType(), expr->getBeginLoc());
+ AstNode *node = trans_ap_value(c, &result.Val, expr->getType(), bitcast(expr->getBeginLoc()));
return maybe_suppress_result(c, result_used, node);
}
@@ -1417,7 +1411,7 @@ static AstNode *trans_create_assign(Context *c, ResultUsed result_used, TransSco
static AstNode *trans_create_shift_op(Context *c, TransScope *scope, clang::QualType result_type,
clang::Expr *lhs_expr, BinOpType bin_op, clang::Expr *rhs_expr)
{
- const clang::SourceLocation &rhs_location = rhs_expr->getBeginLoc();
+ ZigClangSourceLocation rhs_location = bitcast(rhs_expr->getBeginLoc());
AstNode *rhs_type = qual_type_to_log2_int_ref(c, result_type, rhs_location);
// lhs >> u5(rh)
@@ -1434,13 +1428,13 @@ static AstNode *trans_create_shift_op(Context *c, TransScope *scope, clang::Qual
static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransScope *scope, const clang::BinaryOperator *stmt) {
switch (stmt->getOpcode()) {
case clang::BO_PtrMemD:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle more C binary operators: BO_PtrMemD");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle more C binary operators: BO_PtrMemD");
return nullptr;
case clang::BO_PtrMemI:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle more C binary operators: BO_PtrMemI");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle more C binary operators: BO_PtrMemI");
return nullptr;
case clang::BO_Cmp:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle more C binary operators: BO_Cmp");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle more C binary operators: BO_Cmp");
return nullptr;
case clang::BO_Mul: {
AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(),
@@ -1584,7 +1578,7 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS
static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result_used, TransScope *scope,
const clang::CompoundAssignOperator *stmt, BinOpType assign_op, BinOpType bin_op)
{
- const clang::SourceLocation &rhs_location = stmt->getRHS()->getBeginLoc();
+ ZigClangSourceLocation rhs_location = bitcast(stmt->getRHS()->getBeginLoc());
AstNode *rhs_type = qual_type_to_log2_int_ref(c, stmt->getComputationLHSType(), rhs_location);
bool use_intermediate_casts = stmt->getComputationLHSType().getTypePtr() != stmt->getComputationResultType().getTypePtr();
@@ -1733,13 +1727,13 @@ static AstNode *trans_compound_assign_operator(Context *c, ResultUsed result_use
else
return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignTimes, BinOpTypeMult);
case clang::BO_DivAssign:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle more C compound assign operators: BO_DivAssign");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle more C compound assign operators: BO_DivAssign");
return nullptr;
case clang::BO_RemAssign:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle more C compound assign operators: BO_RemAssign");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle more C compound assign operators: BO_RemAssign");
return nullptr;
case clang::BO_Cmp:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle more C compound assign operators: BO_Cmp");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle more C compound assign operators: BO_Cmp");
return nullptr;
case clang::BO_AddAssign:
if (qual_type_has_wrapping_overflow(c, stmt->getType()))
@@ -1798,7 +1792,7 @@ static AstNode *trans_implicit_cast_expr(Context *c, ResultUsed result_used, Tra
AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);
if (target_node == nullptr)
return nullptr;
- AstNode *node = trans_c_cast(c, stmt->getExprLoc(), stmt->getType(),
+ AstNode *node = trans_c_cast(c, bitcast(stmt->getExprLoc()), stmt->getType(),
stmt->getSubExpr()->getType(), target_node);
return maybe_suppress_result(c, result_used, node);
}
@@ -1832,160 +1826,160 @@ static AstNode *trans_implicit_cast_expr(Context *c, ResultUsed result_used, Tra
case clang::CK_NoOp:
return trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);
case clang::CK_Dependent:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_Dependent");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_Dependent");
return nullptr;
case clang::CK_LValueBitCast:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_LValueBitCast");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_LValueBitCast");
return nullptr;
case clang::CK_BaseToDerived:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_BaseToDerived");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_BaseToDerived");
return nullptr;
case clang::CK_DerivedToBase:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_DerivedToBase");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_DerivedToBase");
return nullptr;
case clang::CK_UncheckedDerivedToBase:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_UncheckedDerivedToBase");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_UncheckedDerivedToBase");
return nullptr;
case clang::CK_Dynamic:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_Dynamic");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_Dynamic");
return nullptr;
case clang::CK_ToUnion:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_ToUnion");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_ToUnion");
return nullptr;
case clang::CK_NullToMemberPointer:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_NullToMemberPointer");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_NullToMemberPointer");
return nullptr;
case clang::CK_BaseToDerivedMemberPointer:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_BaseToDerivedMemberPointer");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_BaseToDerivedMemberPointer");
return nullptr;
case clang::CK_DerivedToBaseMemberPointer:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_DerivedToBaseMemberPointer");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_DerivedToBaseMemberPointer");
return nullptr;
case clang::CK_MemberPointerToBoolean:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_MemberPointerToBoolean");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_MemberPointerToBoolean");
return nullptr;
case clang::CK_ReinterpretMemberPointer:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_ReinterpretMemberPointer");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_ReinterpretMemberPointer");
return nullptr;
case clang::CK_UserDefinedConversion:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_UserDefinedConversion");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_UserDefinedConversion");
return nullptr;
case clang::CK_ConstructorConversion:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_ConstructorConversion");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ConstructorConversion");
return nullptr;
case clang::CK_IntegralToPointer:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntegralToPointer");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralToPointer");
return nullptr;
case clang::CK_PointerToIntegral:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_PointerToIntegral");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_PointerToIntegral");
return nullptr;
case clang::CK_PointerToBoolean:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_PointerToBoolean");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_PointerToBoolean");
return nullptr;
case clang::CK_ToVoid:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_ToVoid");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ToVoid");
return nullptr;
case clang::CK_VectorSplat:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_VectorSplat");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_VectorSplat");
return nullptr;
case clang::CK_IntegralToBoolean:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntegralToBoolean");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralToBoolean");
return nullptr;
case clang::CK_IntegralToFloating:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntegralToFloating");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralToFloating");
return nullptr;
case clang::CK_FixedPointCast:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FixedPointCast");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FixedPointCast");
return nullptr;
case clang::CK_FixedPointToBoolean:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FixedPointToBoolean");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FixedPointToBoolean");
return nullptr;
case clang::CK_FloatingToIntegral:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FloatingToIntegral");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingToIntegral");
return nullptr;
case clang::CK_FloatingToBoolean:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FloatingToBoolean");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingToBoolean");
return nullptr;
case clang::CK_BooleanToSignedIntegral:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_BooleanToSignedIntegral");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_BooleanToSignedIntegral");
return nullptr;
case clang::CK_FloatingCast:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FloatingCast");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingCast");
return nullptr;
case clang::CK_CPointerToObjCPointerCast:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_CPointerToObjCPointerCast");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_CPointerToObjCPointerCast");
return nullptr;
case clang::CK_BlockPointerToObjCPointerCast:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_BlockPointerToObjCPointerCast");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_BlockPointerToObjCPointerCast");
return nullptr;
case clang::CK_AnyPointerToBlockPointerCast:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_AnyPointerToBlockPointerCast");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_AnyPointerToBlockPointerCast");
return nullptr;
case clang::CK_ObjCObjectLValueCast:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_ObjCObjectLValueCast");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ObjCObjectLValueCast");
return nullptr;
case clang::CK_FloatingRealToComplex:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FloatingRealToComplex");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingRealToComplex");
return nullptr;
case clang::CK_FloatingComplexToReal:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FloatingComplexToReal");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingComplexToReal");
return nullptr;
case clang::CK_FloatingComplexToBoolean:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FloatingComplexToBoolean");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingComplexToBoolean");
return nullptr;
case clang::CK_FloatingComplexCast:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FloatingComplexCast");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingComplexCast");
return nullptr;
case clang::CK_FloatingComplexToIntegralComplex:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FloatingComplexToIntegralComplex");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingComplexToIntegralComplex");
return nullptr;
case clang::CK_IntegralRealToComplex:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntegralRealToComplex");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralRealToComplex");
return nullptr;
case clang::CK_IntegralComplexToReal:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntegralComplexToReal");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralComplexToReal");
return nullptr;
case clang::CK_IntegralComplexToBoolean:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntegralComplexToBoolean");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralComplexToBoolean");
return nullptr;
case clang::CK_IntegralComplexCast:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntegralComplexCast");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralComplexCast");
return nullptr;
case clang::CK_IntegralComplexToFloatingComplex:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntegralComplexToFloatingComplex");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralComplexToFloatingComplex");
return nullptr;
case clang::CK_ARCProduceObject:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_ARCProduceObject");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ARCProduceObject");
return nullptr;
case clang::CK_ARCConsumeObject:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_ARCConsumeObject");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ARCConsumeObject");
return nullptr;
case clang::CK_ARCReclaimReturnedObject:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_ARCReclaimReturnedObject");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ARCReclaimReturnedObject");
return nullptr;
case clang::CK_ARCExtendBlockObject:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_ARCExtendBlockObject");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ARCExtendBlockObject");
return nullptr;
case clang::CK_AtomicToNonAtomic:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_AtomicToNonAtomic");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_AtomicToNonAtomic");
return nullptr;
case clang::CK_NonAtomicToAtomic:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_NonAtomicToAtomic");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_NonAtomicToAtomic");
return nullptr;
case clang::CK_CopyAndAutoreleaseBlockObject:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_CopyAndAutoreleaseBlockObject");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_CopyAndAutoreleaseBlockObject");
return nullptr;
case clang::CK_BuiltinFnToFnPtr:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_BuiltinFnToFnPtr");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_BuiltinFnToFnPtr");
return nullptr;
case clang::CK_ZeroToOCLOpaqueType:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_ZeroToOCLOpaqueType");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ZeroToOCLOpaqueType");
return nullptr;
case clang::CK_AddressSpaceConversion:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_AddressSpaceConversion");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_AddressSpaceConversion");
return nullptr;
case clang::CK_IntToOCLSampler:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntToOCLSampler");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntToOCLSampler");
return nullptr;
}
zig_unreachable();
@@ -1993,7 +1987,7 @@ static AstNode *trans_implicit_cast_expr(Context *c, ResultUsed result_used, Tra
static AstNode *trans_decl_ref_expr(Context *c, TransScope *scope, const clang::DeclRefExpr *stmt, TransLRValue lrval) {
const clang::ValueDecl *value_decl = stmt->getDecl();
- Buf *c_symbol_name = buf_create_from_str(decl_name(value_decl));
+ 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);
@@ -2148,7 +2142,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc
return trans_create_node_ptr_deref(c, unwrapped);
}
case clang::UO_Plus:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation UO_Plus");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation UO_Plus");
return nullptr;
case clang::UO_Minus:
{
@@ -2174,7 +2168,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc
node->data.bin_op_expr.bin_op = BinOpTypeSubWrap;
return node;
} else {
- emit_warning(c, stmt->getBeginLoc(), "C negation with non float non integer");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "C negation with non float non integer");
return nullptr;
}
}
@@ -2197,15 +2191,15 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc
return trans_create_node_prefix_op(c, PrefixOpBoolNot, sub_node);
}
case clang::UO_Real:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation UO_Real");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation UO_Real");
return nullptr;
case clang::UO_Imag:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation UO_Imag");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation UO_Imag");
return nullptr;
case clang::UO_Extension:
return trans_expr(c, result_used, scope, stmt->getSubExpr(), TransLValue);
case clang::UO_Coawait:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation UO_Coawait");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation UO_Coawait");
return nullptr;
}
zig_unreachable();
@@ -2235,11 +2229,11 @@ static int trans_local_declaration(Context *c, TransScope *scope, const clang::D
} else {
init_node = trans_create_node(c, NodeTypeUndefinedLiteral);
}
- AstNode *type_node = trans_qual_type(c, qual_type, stmt->getBeginLoc());
+ AstNode *type_node = trans_qual_type(c, qual_type, bitcast(stmt->getBeginLoc()));
if (type_node == nullptr)
return ErrorUnexpected;
- Buf *c_symbol_name = buf_create_from_str(decl_name(var_decl));
+ 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;
@@ -2251,223 +2245,223 @@ static int trans_local_declaration(Context *c, TransScope *scope, const clang::D
continue;
}
case clang::Decl::AccessSpec:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle decl kind AccessSpec");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle decl kind AccessSpec");
return ErrorUnexpected;
case clang::Decl::Block:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C Block");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Block");
return ErrorUnexpected;
case clang::Decl::Captured:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C Captured");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Captured");
return ErrorUnexpected;
case clang::Decl::ClassScopeFunctionSpecialization:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ClassScopeFunctionSpecialization");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ClassScopeFunctionSpecialization");
return ErrorUnexpected;
case clang::Decl::Empty:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C Empty");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Empty");
return ErrorUnexpected;
case clang::Decl::Export:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C Export");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Export");
return ErrorUnexpected;
case clang::Decl::ExternCContext:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ExternCContext");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ExternCContext");
return ErrorUnexpected;
case clang::Decl::FileScopeAsm:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C FileScopeAsm");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C FileScopeAsm");
return ErrorUnexpected;
case clang::Decl::Friend:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C Friend");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Friend");
return ErrorUnexpected;
case clang::Decl::FriendTemplate:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C FriendTemplate");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C FriendTemplate");
return ErrorUnexpected;
case clang::Decl::Import:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C Import");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Import");
return ErrorUnexpected;
case clang::Decl::LinkageSpec:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C LinkageSpec");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C LinkageSpec");
return ErrorUnexpected;
case clang::Decl::Label:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C Label");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Label");
return ErrorUnexpected;
case clang::Decl::Namespace:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C Namespace");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Namespace");
return ErrorUnexpected;
case clang::Decl::NamespaceAlias:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C NamespaceAlias");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C NamespaceAlias");
return ErrorUnexpected;
case clang::Decl::ObjCCompatibleAlias:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCCompatibleAlias");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCCompatibleAlias");
return ErrorUnexpected;
case clang::Decl::ObjCCategory:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCCategory");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCCategory");
return ErrorUnexpected;
case clang::Decl::ObjCCategoryImpl:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCCategoryImpl");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCCategoryImpl");
return ErrorUnexpected;
case clang::Decl::ObjCImplementation:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCImplementation");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCImplementation");
return ErrorUnexpected;
case clang::Decl::ObjCInterface:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCInterface");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCInterface");
return ErrorUnexpected;
case clang::Decl::ObjCProtocol:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCProtocol");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCProtocol");
return ErrorUnexpected;
case clang::Decl::ObjCMethod:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCMethod");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCMethod");
return ErrorUnexpected;
case clang::Decl::ObjCProperty:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCProperty");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCProperty");
return ErrorUnexpected;
case clang::Decl::BuiltinTemplate:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C BuiltinTemplate");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C BuiltinTemplate");
return ErrorUnexpected;
case clang::Decl::ClassTemplate:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ClassTemplate");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ClassTemplate");
return ErrorUnexpected;
case clang::Decl::FunctionTemplate:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C FunctionTemplate");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C FunctionTemplate");
return ErrorUnexpected;
case clang::Decl::TypeAliasTemplate:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C TypeAliasTemplate");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TypeAliasTemplate");
return ErrorUnexpected;
case clang::Decl::VarTemplate:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C VarTemplate");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C VarTemplate");
return ErrorUnexpected;
case clang::Decl::TemplateTemplateParm:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C TemplateTemplateParm");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TemplateTemplateParm");
return ErrorUnexpected;
case clang::Decl::Enum:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C Enum");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Enum");
return ErrorUnexpected;
case clang::Decl::Record:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C Record");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Record");
return ErrorUnexpected;
case clang::Decl::CXXRecord:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXRecord");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXRecord");
return ErrorUnexpected;
case clang::Decl::ClassTemplateSpecialization:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ClassTemplateSpecialization");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ClassTemplateSpecialization");
return ErrorUnexpected;
case clang::Decl::ClassTemplatePartialSpecialization:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ClassTemplatePartialSpecialization");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ClassTemplatePartialSpecialization");
return ErrorUnexpected;
case clang::Decl::TemplateTypeParm:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C TemplateTypeParm");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TemplateTypeParm");
return ErrorUnexpected;
case clang::Decl::ObjCTypeParam:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCTypeParam");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCTypeParam");
return ErrorUnexpected;
case clang::Decl::TypeAlias:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C TypeAlias");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TypeAlias");
return ErrorUnexpected;
case clang::Decl::Typedef:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C Typedef");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Typedef");
return ErrorUnexpected;
case clang::Decl::UnresolvedUsingTypename:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C UnresolvedUsingTypename");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UnresolvedUsingTypename");
return ErrorUnexpected;
case clang::Decl::Using:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C Using");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Using");
return ErrorUnexpected;
case clang::Decl::UsingDirective:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C UsingDirective");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UsingDirective");
return ErrorUnexpected;
case clang::Decl::UsingPack:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C UsingPack");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UsingPack");
return ErrorUnexpected;
case clang::Decl::UsingShadow:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C UsingShadow");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UsingShadow");
return ErrorUnexpected;
case clang::Decl::ConstructorUsingShadow:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ConstructorUsingShadow");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ConstructorUsingShadow");
return ErrorUnexpected;
case clang::Decl::Binding:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C Binding");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Binding");
return ErrorUnexpected;
case clang::Decl::Field:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C Field");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Field");
return ErrorUnexpected;
case clang::Decl::ObjCAtDefsField:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCAtDefsField");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAtDefsField");
return ErrorUnexpected;
case clang::Decl::ObjCIvar:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCIvar");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCIvar");
return ErrorUnexpected;
case clang::Decl::Function:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C Function");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Function");
return ErrorUnexpected;
case clang::Decl::CXXDeductionGuide:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXDeductionGuide");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDeductionGuide");
return ErrorUnexpected;
case clang::Decl::CXXMethod:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXMethod");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXMethod");
return ErrorUnexpected;
case clang::Decl::CXXConstructor:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXConstructor");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXConstructor");
return ErrorUnexpected;
case clang::Decl::CXXConversion:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXConversion");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXConversion");
return ErrorUnexpected;
case clang::Decl::CXXDestructor:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXDestructor");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDestructor");
return ErrorUnexpected;
case clang::Decl::MSProperty:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C MSProperty");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C MSProperty");
return ErrorUnexpected;
case clang::Decl::NonTypeTemplateParm:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C NonTypeTemplateParm");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C NonTypeTemplateParm");
return ErrorUnexpected;
case clang::Decl::Decomposition:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C Decomposition");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Decomposition");
return ErrorUnexpected;
case clang::Decl::ImplicitParam:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ImplicitParam");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ImplicitParam");
return ErrorUnexpected;
case clang::Decl::OMPCapturedExpr:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPCapturedExpr");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPCapturedExpr");
return ErrorUnexpected;
case clang::Decl::ParmVar:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ParmVar");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ParmVar");
return ErrorUnexpected;
case clang::Decl::VarTemplateSpecialization:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C VarTemplateSpecialization");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C VarTemplateSpecialization");
return ErrorUnexpected;
case clang::Decl::VarTemplatePartialSpecialization:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C VarTemplatePartialSpecialization");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C VarTemplatePartialSpecialization");
return ErrorUnexpected;
case clang::Decl::EnumConstant:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C EnumConstant");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C EnumConstant");
return ErrorUnexpected;
case clang::Decl::IndirectField:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C IndirectField");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C IndirectField");
return ErrorUnexpected;
case clang::Decl::OMPDeclareReduction:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPDeclareReduction");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPDeclareReduction");
return ErrorUnexpected;
case clang::Decl::UnresolvedUsingValue:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C UnresolvedUsingValue");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UnresolvedUsingValue");
return ErrorUnexpected;
case clang::Decl::OMPRequires:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPRequires");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPRequires");
return ErrorUnexpected;
case clang::Decl::OMPThreadPrivate:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPThreadPrivate");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPThreadPrivate");
return ErrorUnexpected;
case clang::Decl::ObjCPropertyImpl:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCPropertyImpl");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCPropertyImpl");
return ErrorUnexpected;
case clang::Decl::PragmaComment:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C PragmaComment");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C PragmaComment");
return ErrorUnexpected;
case clang::Decl::PragmaDetectMismatch:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C PragmaDetectMismatch");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C PragmaDetectMismatch");
return ErrorUnexpected;
case clang::Decl::StaticAssert:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C StaticAssert");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C StaticAssert");
return ErrorUnexpected;
case clang::Decl::TranslationUnit:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C TranslationUnit");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TranslationUnit");
return ErrorUnexpected;
}
zig_unreachable();
@@ -2689,7 +2683,7 @@ static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *
const clang::ElaboratedType *elaborated_ty = static_cast<const clang::ElaboratedType*>(ty);
switch (elaborated_ty->getKeyword()) {
case clang::ETK_Enum: {
- AstNode *enum_type = trans_qual_type(c, elaborated_ty->getNamedType(), expr->getBeginLoc());
+ AstNode *enum_type = trans_qual_type(c, elaborated_ty->getNamedType(), bitcast(expr->getBeginLoc()));
return to_enum_zero_cmp(c, res, enum_type);
}
case clang::ETK_Struct:
@@ -2846,7 +2840,7 @@ static AstNode *trans_member_expr(Context *c, ResultUsed result_used, TransScope
container_node = trans_create_node_unwrap_null(c, container_node);
}
- const char *name = decl_name(stmt->getMemberDecl());
+ const char *name = ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)stmt->getMemberDecl());
AstNode *node = trans_create_node_field_access_str(c, container_node, name);
return maybe_suppress_result(c, result_used, node);
@@ -2875,7 +2869,7 @@ static AstNode *trans_c_style_cast_expr(Context *c, ResultUsed result_used, Tran
if (sub_expr_node == nullptr)
return nullptr;
- AstNode *cast = trans_c_cast(c, stmt->getBeginLoc(), stmt->getType(), stmt->getSubExpr()->getType(), sub_expr_node);
+ AstNode *cast = trans_c_cast(c, bitcast(stmt->getBeginLoc()), stmt->getType(), stmt->getSubExpr()->getType(), sub_expr_node);
if (cast == nullptr)
return nullptr;
@@ -2885,7 +2879,7 @@ static AstNode *trans_c_style_cast_expr(Context *c, ResultUsed result_used, Tran
static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, ResultUsed result_used,
TransScope *scope, const clang::UnaryExprOrTypeTraitExpr *stmt)
{
- AstNode *type_node = trans_qual_type(c, stmt->getTypeOfArgument(), stmt->getBeginLoc());
+ AstNode *type_node = trans_qual_type(c, stmt->getTypeOfArgument(), bitcast(stmt->getBeginLoc()));
if (type_node == nullptr)
return nullptr;
@@ -3092,7 +3086,7 @@ static int trans_switch_case(Context *c, TransScope *parent_scope, const clang::
*out_node = nullptr;
if (stmt->getRHS() != nullptr) {
- emit_warning(c, stmt->getBeginLoc(), "TODO support GNU switch case a ... b extension");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO support GNU switch case a ... b extension");
return ErrorUnexpected;
}
@@ -3177,13 +3171,13 @@ static AstNode *trans_string_literal(Context *c, ResultUsed result_used, TransSc
return maybe_suppress_result(c, result_used, node);
}
case clang::StringLiteral::UTF16:
- emit_warning(c, stmt->getBeginLoc(), "TODO support UTF16 string literals");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO support UTF16 string literals");
return nullptr;
case clang::StringLiteral::UTF32:
- emit_warning(c, stmt->getBeginLoc(), "TODO support UTF32 string literals");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO support UTF32 string literals");
return nullptr;
case clang::StringLiteral::Wide:
- emit_warning(c, stmt->getBeginLoc(), "TODO support wide string literals");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO support wide string literals");
return nullptr;
}
zig_unreachable();
@@ -3328,505 +3322,505 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st
return wrap_stmt(out_node, out_child_scope, scope,
trans_stmt_expr(c, result_used, scope, (const clang::StmtExpr *)stmt, out_node_scope));
case clang::Stmt::NoStmtClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C NoStmtClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C NoStmtClass");
return ErrorUnexpected;
case clang::Stmt::GCCAsmStmtClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C GCCAsmStmtClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C GCCAsmStmtClass");
return ErrorUnexpected;
case clang::Stmt::MSAsmStmtClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C MSAsmStmtClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C MSAsmStmtClass");
return ErrorUnexpected;
case clang::Stmt::AttributedStmtClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C AttributedStmtClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C AttributedStmtClass");
return ErrorUnexpected;
case clang::Stmt::CXXCatchStmtClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXCatchStmtClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXCatchStmtClass");
return ErrorUnexpected;
case clang::Stmt::CXXForRangeStmtClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXForRangeStmtClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXForRangeStmtClass");
return ErrorUnexpected;
case clang::Stmt::CXXTryStmtClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXTryStmtClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXTryStmtClass");
return ErrorUnexpected;
case clang::Stmt::CapturedStmtClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CapturedStmtClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CapturedStmtClass");
return ErrorUnexpected;
case clang::Stmt::CoreturnStmtClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CoreturnStmtClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CoreturnStmtClass");
return ErrorUnexpected;
case clang::Stmt::CoroutineBodyStmtClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CoroutineBodyStmtClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CoroutineBodyStmtClass");
return ErrorUnexpected;
case clang::Stmt::BinaryConditionalOperatorClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C BinaryConditionalOperatorClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C BinaryConditionalOperatorClass");
return ErrorUnexpected;
case clang::Stmt::AddrLabelExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C AddrLabelExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C AddrLabelExprClass");
return ErrorUnexpected;
case clang::Stmt::ArrayInitIndexExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ArrayInitIndexExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ArrayInitIndexExprClass");
return ErrorUnexpected;
case clang::Stmt::ArrayInitLoopExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ArrayInitLoopExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ArrayInitLoopExprClass");
return ErrorUnexpected;
case clang::Stmt::ArrayTypeTraitExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ArrayTypeTraitExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ArrayTypeTraitExprClass");
return ErrorUnexpected;
case clang::Stmt::AsTypeExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C AsTypeExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C AsTypeExprClass");
return ErrorUnexpected;
case clang::Stmt::AtomicExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C AtomicExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C AtomicExprClass");
return ErrorUnexpected;
case clang::Stmt::BlockExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C BlockExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C BlockExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXBindTemporaryExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXBindTemporaryExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXBindTemporaryExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXBoolLiteralExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXBoolLiteralExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXBoolLiteralExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXConstructExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXConstructExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXConstructExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXTemporaryObjectExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXTemporaryObjectExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXTemporaryObjectExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXDefaultArgExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXDefaultArgExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDefaultArgExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXDefaultInitExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXDefaultInitExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDefaultInitExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXDeleteExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXDeleteExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDeleteExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXDependentScopeMemberExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXDependentScopeMemberExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDependentScopeMemberExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXFoldExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXFoldExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXFoldExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXInheritedCtorInitExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXInheritedCtorInitExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXInheritedCtorInitExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXNewExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXNewExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXNewExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXNoexceptExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXNoexceptExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXNoexceptExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXNullPtrLiteralExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXNullPtrLiteralExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXNullPtrLiteralExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXPseudoDestructorExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXPseudoDestructorExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXPseudoDestructorExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXScalarValueInitExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXScalarValueInitExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXScalarValueInitExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXStdInitializerListExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXStdInitializerListExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXStdInitializerListExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXThisExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXThisExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXThisExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXThrowExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXThrowExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXThrowExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXTypeidExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXTypeidExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXTypeidExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXUnresolvedConstructExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXUnresolvedConstructExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXUnresolvedConstructExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXUuidofExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXUuidofExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXUuidofExprClass");
return ErrorUnexpected;
case clang::Stmt::CUDAKernelCallExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CUDAKernelCallExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CUDAKernelCallExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXMemberCallExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXMemberCallExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXMemberCallExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXOperatorCallExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXOperatorCallExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXOperatorCallExprClass");
return ErrorUnexpected;
case clang::Stmt::UserDefinedLiteralClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C UserDefinedLiteralClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UserDefinedLiteralClass");
return ErrorUnexpected;
case clang::Stmt::CXXFunctionalCastExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXFunctionalCastExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXFunctionalCastExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXConstCastExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXConstCastExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXConstCastExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXDynamicCastExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXDynamicCastExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDynamicCastExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXReinterpretCastExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXReinterpretCastExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXReinterpretCastExprClass");
return ErrorUnexpected;
case clang::Stmt::CXXStaticCastExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXStaticCastExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXStaticCastExprClass");
return ErrorUnexpected;
case clang::Stmt::ObjCBridgedCastExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCBridgedCastExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCBridgedCastExprClass");
return ErrorUnexpected;
case clang::Stmt::CharacterLiteralClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CharacterLiteralClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CharacterLiteralClass");
return ErrorUnexpected;
case clang::Stmt::ChooseExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ChooseExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ChooseExprClass");
return ErrorUnexpected;
case clang::Stmt::CompoundLiteralExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CompoundLiteralExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CompoundLiteralExprClass");
return ErrorUnexpected;
case clang::Stmt::ConvertVectorExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ConvertVectorExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ConvertVectorExprClass");
return ErrorUnexpected;
case clang::Stmt::CoawaitExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CoawaitExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CoawaitExprClass");
return ErrorUnexpected;
case clang::Stmt::CoyieldExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C CoyieldExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CoyieldExprClass");
return ErrorUnexpected;
case clang::Stmt::DependentCoawaitExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C DependentCoawaitExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C DependentCoawaitExprClass");
return ErrorUnexpected;
case clang::Stmt::DependentScopeDeclRefExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C DependentScopeDeclRefExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C DependentScopeDeclRefExprClass");
return ErrorUnexpected;
case clang::Stmt::DesignatedInitExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C DesignatedInitExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C DesignatedInitExprClass");
return ErrorUnexpected;
case clang::Stmt::DesignatedInitUpdateExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C DesignatedInitUpdateExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C DesignatedInitUpdateExprClass");
return ErrorUnexpected;
case clang::Stmt::ExpressionTraitExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ExpressionTraitExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ExpressionTraitExprClass");
return ErrorUnexpected;
case clang::Stmt::ExtVectorElementExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ExtVectorElementExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ExtVectorElementExprClass");
return ErrorUnexpected;
case clang::Stmt::FixedPointLiteralClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C FixedPointLiteralClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C FixedPointLiteralClass");
return ErrorUnexpected;
case clang::Stmt::FloatingLiteralClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C FloatingLiteralClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C FloatingLiteralClass");
return ErrorUnexpected;
case clang::Stmt::ExprWithCleanupsClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ExprWithCleanupsClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ExprWithCleanupsClass");
return ErrorUnexpected;
case clang::Stmt::FunctionParmPackExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C FunctionParmPackExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C FunctionParmPackExprClass");
return ErrorUnexpected;
case clang::Stmt::GNUNullExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C GNUNullExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C GNUNullExprClass");
return ErrorUnexpected;
case clang::Stmt::GenericSelectionExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C GenericSelectionExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C GenericSelectionExprClass");
return ErrorUnexpected;
case clang::Stmt::ImaginaryLiteralClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ImaginaryLiteralClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ImaginaryLiteralClass");
return ErrorUnexpected;
case clang::Stmt::ImplicitValueInitExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ImplicitValueInitExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ImplicitValueInitExprClass");
return ErrorUnexpected;
case clang::Stmt::InitListExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C InitListExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C InitListExprClass");
return ErrorUnexpected;
case clang::Stmt::LambdaExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C LambdaExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C LambdaExprClass");
return ErrorUnexpected;
case clang::Stmt::MSPropertyRefExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C MSPropertyRefExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C MSPropertyRefExprClass");
return ErrorUnexpected;
case clang::Stmt::MSPropertySubscriptExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C MSPropertySubscriptExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C MSPropertySubscriptExprClass");
return ErrorUnexpected;
case clang::Stmt::MaterializeTemporaryExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C MaterializeTemporaryExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C MaterializeTemporaryExprClass");
return ErrorUnexpected;
case clang::Stmt::NoInitExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C NoInitExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C NoInitExprClass");
return ErrorUnexpected;
case clang::Stmt::OMPArraySectionExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPArraySectionExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPArraySectionExprClass");
return ErrorUnexpected;
case clang::Stmt::ObjCArrayLiteralClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCArrayLiteralClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCArrayLiteralClass");
return ErrorUnexpected;
case clang::Stmt::ObjCAvailabilityCheckExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCAvailabilityCheckExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAvailabilityCheckExprClass");
return ErrorUnexpected;
case clang::Stmt::ObjCBoolLiteralExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCBoolLiteralExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCBoolLiteralExprClass");
return ErrorUnexpected;
case clang::Stmt::ObjCBoxedExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCBoxedExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCBoxedExprClass");
return ErrorUnexpected;
case clang::Stmt::ObjCDictionaryLiteralClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCDictionaryLiteralClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCDictionaryLiteralClass");
return ErrorUnexpected;
case clang::Stmt::ObjCEncodeExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCEncodeExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCEncodeExprClass");
return ErrorUnexpected;
case clang::Stmt::ObjCIndirectCopyRestoreExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCIndirectCopyRestoreExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCIndirectCopyRestoreExprClass");
return ErrorUnexpected;
case clang::Stmt::ObjCIsaExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCIsaExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCIsaExprClass");
return ErrorUnexpected;
case clang::Stmt::ObjCIvarRefExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCIvarRefExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCIvarRefExprClass");
return ErrorUnexpected;
case clang::Stmt::ObjCMessageExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCMessageExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCMessageExprClass");
return ErrorUnexpected;
case clang::Stmt::ObjCPropertyRefExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCPropertyRefExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCPropertyRefExprClass");
return ErrorUnexpected;
case clang::Stmt::ObjCProtocolExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCProtocolExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCProtocolExprClass");
return ErrorUnexpected;
case clang::Stmt::ObjCSelectorExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCSelectorExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCSelectorExprClass");
return ErrorUnexpected;
case clang::Stmt::ObjCStringLiteralClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCStringLiteralClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCStringLiteralClass");
return ErrorUnexpected;
case clang::Stmt::ObjCSubscriptRefExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCSubscriptRefExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCSubscriptRefExprClass");
return ErrorUnexpected;
case clang::Stmt::OffsetOfExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OffsetOfExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OffsetOfExprClass");
return ErrorUnexpected;
case clang::Stmt::OpaqueValueExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OpaqueValueExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OpaqueValueExprClass");
return ErrorUnexpected;
case clang::Stmt::UnresolvedLookupExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C UnresolvedLookupExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UnresolvedLookupExprClass");
return ErrorUnexpected;
case clang::Stmt::UnresolvedMemberExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C UnresolvedMemberExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UnresolvedMemberExprClass");
return ErrorUnexpected;
case clang::Stmt::PackExpansionExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C PackExpansionExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C PackExpansionExprClass");
return ErrorUnexpected;
case clang::Stmt::ParenListExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ParenListExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ParenListExprClass");
return ErrorUnexpected;
case clang::Stmt::PseudoObjectExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C PseudoObjectExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C PseudoObjectExprClass");
return ErrorUnexpected;
case clang::Stmt::ShuffleVectorExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ShuffleVectorExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ShuffleVectorExprClass");
return ErrorUnexpected;
case clang::Stmt::SizeOfPackExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C SizeOfPackExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SizeOfPackExprClass");
return ErrorUnexpected;
case clang::Stmt::SubstNonTypeTemplateParmExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C SubstNonTypeTemplateParmExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SubstNonTypeTemplateParmExprClass");
return ErrorUnexpected;
case clang::Stmt::SubstNonTypeTemplateParmPackExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C SubstNonTypeTemplateParmPackExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SubstNonTypeTemplateParmPackExprClass");
return ErrorUnexpected;
case clang::Stmt::TypeTraitExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C TypeTraitExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TypeTraitExprClass");
return ErrorUnexpected;
case clang::Stmt::TypoExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C TypoExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TypoExprClass");
return ErrorUnexpected;
case clang::Stmt::VAArgExprClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C VAArgExprClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C VAArgExprClass");
return ErrorUnexpected;
case clang::Stmt::GotoStmtClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C GotoStmtClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C GotoStmtClass");
return ErrorUnexpected;
case clang::Stmt::IndirectGotoStmtClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C IndirectGotoStmtClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C IndirectGotoStmtClass");
return ErrorUnexpected;
case clang::Stmt::LabelStmtClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C LabelStmtClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C LabelStmtClass");
return ErrorUnexpected;
case clang::Stmt::MSDependentExistsStmtClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C MSDependentExistsStmtClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C MSDependentExistsStmtClass");
return ErrorUnexpected;
case clang::Stmt::OMPAtomicDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPAtomicDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPAtomicDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPBarrierDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPBarrierDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPBarrierDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPCancelDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPCancelDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPCancelDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPCancellationPointDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPCancellationPointDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPCancellationPointDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPCriticalDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPCriticalDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPCriticalDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPFlushDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPFlushDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPFlushDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPDistributeDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPDistributeDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPDistributeDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPDistributeParallelForDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPDistributeParallelForDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPDistributeParallelForDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPDistributeParallelForSimdDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPDistributeParallelForSimdDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPDistributeParallelForSimdDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPDistributeSimdDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPDistributeSimdDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPDistributeSimdDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPForDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPForDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPForDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPForSimdDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPForSimdDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPForSimdDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPParallelForDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPParallelForDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPParallelForDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPParallelForSimdDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPParallelForSimdDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPParallelForSimdDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPSimdDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPSimdDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPSimdDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPTargetParallelForSimdDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetParallelForSimdDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetParallelForSimdDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPTargetSimdDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetSimdDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetSimdDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPTargetTeamsDistributeDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetTeamsDistributeDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetTeamsDistributeDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetTeamsDistributeParallelForDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetTeamsDistributeParallelForDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetTeamsDistributeParallelForSimdDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetTeamsDistributeParallelForSimdDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetTeamsDistributeSimdDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetTeamsDistributeSimdDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPTaskLoopDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTaskLoopDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTaskLoopDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPTaskLoopSimdDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTaskLoopSimdDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTaskLoopSimdDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPTeamsDistributeDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTeamsDistributeDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTeamsDistributeDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPTeamsDistributeParallelForDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTeamsDistributeParallelForDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTeamsDistributeParallelForDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTeamsDistributeParallelForSimdDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTeamsDistributeParallelForSimdDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPTeamsDistributeSimdDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTeamsDistributeSimdDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTeamsDistributeSimdDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPMasterDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPMasterDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPMasterDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPOrderedDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPOrderedDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPOrderedDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPParallelDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPParallelDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPParallelDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPParallelSectionsDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPParallelSectionsDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPParallelSectionsDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPSectionDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPSectionDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPSectionDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPSectionsDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPSectionsDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPSectionsDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPSingleDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPSingleDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPSingleDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPTargetDataDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetDataDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetDataDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPTargetDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPTargetEnterDataDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetEnterDataDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetEnterDataDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPTargetExitDataDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetExitDataDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetExitDataDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPTargetParallelDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetParallelDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetParallelDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPTargetParallelForDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetParallelForDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetParallelForDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPTargetTeamsDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetTeamsDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetTeamsDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPTargetUpdateDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetUpdateDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTargetUpdateDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPTaskDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTaskDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTaskDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPTaskgroupDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTaskgroupDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTaskgroupDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPTaskwaitDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTaskwaitDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTaskwaitDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPTaskyieldDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTaskyieldDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTaskyieldDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::OMPTeamsDirectiveClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTeamsDirectiveClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPTeamsDirectiveClass");
return ErrorUnexpected;
case clang::Stmt::ObjCAtCatchStmtClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCAtCatchStmtClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAtCatchStmtClass");
return ErrorUnexpected;
case clang::Stmt::ObjCAtFinallyStmtClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCAtFinallyStmtClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAtFinallyStmtClass");
return ErrorUnexpected;
case clang::Stmt::ObjCAtSynchronizedStmtClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCAtSynchronizedStmtClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAtSynchronizedStmtClass");
return ErrorUnexpected;
case clang::Stmt::ObjCAtThrowStmtClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCAtThrowStmtClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAtThrowStmtClass");
return ErrorUnexpected;
case clang::Stmt::ObjCAtTryStmtClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCAtTryStmtClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAtTryStmtClass");
return ErrorUnexpected;
case clang::Stmt::ObjCAutoreleasePoolStmtClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCAutoreleasePoolStmtClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAutoreleasePoolStmtClass");
return ErrorUnexpected;
case clang::Stmt::ObjCForCollectionStmtClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCForCollectionStmtClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCForCollectionStmtClass");
return ErrorUnexpected;
case clang::Stmt::SEHExceptStmtClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C SEHExceptStmtClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SEHExceptStmtClass");
return ErrorUnexpected;
case clang::Stmt::SEHFinallyStmtClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C SEHFinallyStmtClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SEHFinallyStmtClass");
return ErrorUnexpected;
case clang::Stmt::SEHLeaveStmtClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C SEHLeaveStmtClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SEHLeaveStmtClass");
return ErrorUnexpected;
case clang::Stmt::SEHTryStmtClass:
- emit_warning(c, stmt->getBeginLoc(), "TODO handle C SEHTryStmtClass");
+ emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C SEHTryStmtClass");
return ErrorUnexpected;
}
zig_unreachable();
@@ -3855,16 +3849,16 @@ static TransScope *trans_stmt(Context *c, TransScope *scope, const clang::Stmt *
}
static void visit_fn_decl(Context *c, const clang::FunctionDecl *fn_decl) {
- Buf *fn_name = buf_create_from_str(decl_name(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, fn_decl->getType(), fn_decl->getLocation());
+ AstNode *proto_node = trans_qual_type(c, fn_decl->getType(), bitcast(fn_decl->getLocation()));
if (proto_node == nullptr) {
- emit_warning(c, fn_decl->getLocation(), "unable to resolve prototype of function '%s'", buf_ptr(fn_name));
+ emit_warning(c, bitcast(fn_decl->getLocation()), "unable to resolve prototype of function '%s'", buf_ptr(fn_name));
return;
}
@@ -3878,10 +3872,10 @@ static void visit_fn_decl(Context *c, const clang::FunctionDecl *fn_decl) {
} else if (sc == clang::SC_Extern || sc == clang::SC_Static) {
proto_node->data.fn_proto.visib_mod = c->visib_mod;
} else if (sc == clang::SC_PrivateExtern) {
- emit_warning(c, fn_decl->getLocation(), "unsupported storage class: private extern");
+ emit_warning(c, bitcast(fn_decl->getLocation()), "unsupported storage class: private extern");
return;
} else {
- emit_warning(c, fn_decl->getLocation(), "unsupported storage class: unknown");
+ emit_warning(c, bitcast(fn_decl->getLocation()), "unsupported storage class: unknown");
return;
}
@@ -3890,7 +3884,7 @@ static void visit_fn_decl(Context *c, const clang::FunctionDecl *fn_decl) {
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 clang::ParmVarDecl *param = fn_decl->getParamDecl(i);
- const char *name = decl_name(param);
+ const char *name = ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)param);
Buf *proto_param_name;
if (strlen(name) != 0) {
@@ -3920,7 +3914,7 @@ static void visit_fn_decl(Context *c, const clang::FunctionDecl *fn_decl) {
AstNode *actual_body_node;
TransScope *result_scope = trans_stmt(c, scope, body, &actual_body_node);
if (result_scope == nullptr) {
- emit_warning(c, fn_decl->getLocation(), "unable to translate function");
+ emit_warning(c, bitcast(fn_decl->getLocation()), "unable to translate function");
return;
}
assert(actual_body_node != nullptr);
@@ -3971,7 +3965,7 @@ static AstNode *resolve_typedef_decl(Context *c, const clang::TypedefNameDecl *t
}
clang::QualType child_qt = typedef_decl->getUnderlyingType();
- Buf *type_name = buf_create_from_str(decl_name(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");
@@ -4007,9 +4001,9 @@ static AstNode *resolve_typedef_decl(Context *c, const clang::TypedefNameDecl *t
AstNode *symbol_node = trans_create_node_symbol(c, type_name);
c->decl_table.put(typedef_decl->getCanonicalDecl(), symbol_node);
- AstNode *type_node = trans_qual_type(c, child_qt, typedef_decl->getLocation());
+ AstNode *type_node = trans_qual_type(c, child_qt, bitcast(typedef_decl->getLocation()));
if (type_node == nullptr) {
- emit_warning(c, typedef_decl->getLocation(), "typedef %s - unresolved child type", buf_ptr(type_name));
+ emit_warning(c, bitcast(typedef_decl->getLocation()), "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;
@@ -4040,7 +4034,7 @@ static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl)
return existing_entry->value;
}
- const char *raw_name = decl_name(enum_decl);
+ 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));
@@ -4062,7 +4056,7 @@ static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl)
pure_enum = false;
}
}
- AstNode *tag_int_type = trans_qual_type(c, enum_decl->getIntegerType(), enum_decl->getLocation());
+ AstNode *tag_int_type = trans_qual_type(c, enum_decl->getIntegerType(), bitcast(enum_decl->getLocation()));
assert(tag_int_type);
AstNode *enum_node = trans_create_node(c, NodeTypeContainerDecl);
@@ -4084,7 +4078,7 @@ static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl)
{
const clang::EnumConstantDecl *enum_const = *it;
- Buf *enum_val_name = buf_create_from_str(decl_name(enum_const));
+ 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));
@@ -4102,7 +4096,7 @@ static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl)
// 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(decl_name(enum_const));
+ 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,
@@ -4123,62 +4117,63 @@ static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl)
}
}
-static AstNode *demote_struct_to_opaque(Context *c, const clang::RecordDecl *record_decl,
+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(record_decl->getCanonicalDecl(), opaque_node);
+ 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(record_decl->getCanonicalDecl(), symbol_node);
+ c->decl_table.put(ZigClangRecordDecl_getCanonicalDecl(record_decl), symbol_node);
return symbol_node;
}
-static AstNode *resolve_record_decl(Context *c, const clang::RecordDecl *record_decl) {
- auto existing_entry = c->decl_table.maybe_get((void*)record_decl->getCanonicalDecl());
+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 = decl_name(record_decl);
+ const char *raw_name = ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)record_decl);
const char *container_kind_name;
ContainerKind container_kind;
- if (record_decl->isUnion()) {
+ if (ZigClangRecordDecl_isUnion(record_decl)) {
container_kind_name = "union";
container_kind = ContainerKindUnion;
- } else if (record_decl->isStruct()) {
+ } else if (ZigClangRecordDecl_isStruct(record_decl)) {
container_kind_name = "struct";
container_kind = ContainerKindStruct;
} else {
- emit_warning(c, record_decl->getLocation(), "skipping record %s, not a struct or union", raw_name);
- c->decl_table.put(record_decl->getCanonicalDecl(), nullptr);
+ 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 = record_decl->isAnonymousStructOrUnion() || raw_name[0] == 0;
+ 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));
- clang::RecordDecl *record_def = record_decl->getDefinition();
+ 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 (auto it = record_def->field_begin(),
- it_end = record_def->field_end();
+ for (auto it = reinterpret_cast<const clang::RecordDecl *>(record_def)->field_begin(),
+ it_end = reinterpret_cast<const clang::RecordDecl *>(record_def)->field_end();
it != it_end; ++it, field_count += 1)
{
const clang::FieldDecl *field_decl = *it;
if (field_decl->isBitField()) {
- emit_warning(c, field_decl->getLocation(), "%s %s demoted to opaque type - has bitfield",
+ emit_warning(c, bitcast(field_decl->getLocation()), "%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);
@@ -4195,24 +4190,25 @@ static AstNode *resolve_record_decl(Context *c, const clang::RecordDecl *record_
// must be before fields in case a circular reference happens
if (is_anonymous) {
- c->decl_table.put(record_decl->getCanonicalDecl(), struct_node);
+ c->decl_table.put(ZigClangRecordDecl_getCanonicalDecl(record_decl), struct_node);
} else {
- c->decl_table.put(record_decl->getCanonicalDecl(), trans_create_node_symbol(c, full_type_name));
+ c->decl_table.put(ZigClangRecordDecl_getCanonicalDecl(record_decl), trans_create_node_symbol(c, full_type_name));
}
uint32_t i = 0;
- for (auto it = record_def->field_begin(),
- it_end = record_def->field_end();
+ for (auto it = reinterpret_cast<const clang::RecordDecl *>(record_def)->field_begin(),
+ it_end = reinterpret_cast<const clang::RecordDecl *>(record_def)->field_end();
it != it_end; ++it, i += 1)
{
const clang::FieldDecl *field_decl = *it;
AstNode *field_node = trans_create_node(c, NodeTypeStructField);
- field_node->data.struct_field.name = buf_create_from_str(decl_name(field_decl));
- field_node->data.struct_field.type = trans_qual_type(c, field_decl->getType(), field_decl->getLocation());
+ 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, field_decl->getType(),
+ bitcast(field_decl->getLocation()));
if (field_node->data.struct_field.type == nullptr) {
- emit_warning(c, field_decl->getLocation(),
+ emit_warning(c, bitcast(field_decl->getLocation()),
"%s %s demoted to opaque type - unresolved type",
container_kind_name,
is_anonymous ? "(anon)" : buf_ptr(bare_name));
@@ -4232,7 +4228,7 @@ static AstNode *resolve_record_decl(Context *c, const clang::RecordDecl *record_
}
}
-static AstNode *trans_ap_value(Context *c, clang::APValue *ap_value, clang::QualType qt, const clang::SourceLocation &source_loc) {
+static AstNode *trans_ap_value(Context *c, clang::APValue *ap_value, clang::QualType qt, ZigClangSourceLocation source_loc) {
switch (ap_value->getKind()) {
case clang::APValue::Int:
return trans_create_node_apint(c, ap_value->getInt());
@@ -4331,25 +4327,25 @@ static AstNode *trans_ap_value(Context *c, clang::APValue *ap_value, clang::Qual
}
static void visit_var_decl(Context *c, const clang::VarDecl *var_decl) {
- Buf *name = buf_create_from_str(decl_name(var_decl));
+ Buf *name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)var_decl));
switch (var_decl->getTLSKind()) {
case clang::VarDecl::TLS_None:
break;
case clang::VarDecl::TLS_Static:
- emit_warning(c, var_decl->getLocation(),
+ emit_warning(c, bitcast(var_decl->getLocation()),
"ignoring variable '%s' - static thread local storage", buf_ptr(name));
return;
case clang::VarDecl::TLS_Dynamic:
- emit_warning(c, var_decl->getLocation(),
+ emit_warning(c, bitcast(var_decl->getLocation()),
"ignoring variable '%s' - dynamic thread local storage", buf_ptr(name));
return;
}
clang::QualType qt = var_decl->getType();
- AstNode *var_type = trans_qual_type(c, qt, var_decl->getLocation());
+ AstNode *var_type = trans_qual_type(c, qt, bitcast(var_decl->getLocation()));
if (var_type == nullptr) {
- emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - unresolved type", buf_ptr(name));
+ emit_warning(c, bitcast(var_decl->getLocation()), "ignoring variable '%s' - unresolved type", buf_ptr(name));
return;
}
@@ -4362,11 +4358,11 @@ static void visit_var_decl(Context *c, const clang::VarDecl *var_decl) {
if (var_decl->hasInit()) {
clang::APValue *ap_value = var_decl->evaluateValue();
if (ap_value == nullptr) {
- emit_warning(c, var_decl->getLocation(),
+ emit_warning(c, bitcast(var_decl->getLocation()),
"ignoring variable '%s' - unable to evaluate initializer", buf_ptr(name));
return;
}
- init_node = trans_ap_value(c, ap_value, qt, var_decl->getLocation());
+ init_node = trans_ap_value(c, ap_value, qt, bitcast(var_decl->getLocation()));
if (init_node == nullptr)
return;
} else {
@@ -4385,7 +4381,7 @@ static void visit_var_decl(Context *c, const clang::VarDecl *var_decl) {
return;
}
- emit_warning(c, var_decl->getLocation(),
+ emit_warning(c, bitcast(var_decl->getLocation()),
"ignoring variable '%s' - non-extern, non-static variable", buf_ptr(name));
return;
}
@@ -4405,13 +4401,13 @@ static bool decl_visitor(void *context, const ZigClangDecl *zdecl) {
resolve_enum_decl(c, static_cast<const clang::EnumDecl *>(decl));
break;
case clang::Decl::Record:
- resolve_record_decl(c, static_cast<const clang::RecordDecl *>(decl));
+ resolve_record_decl(c, (const ZigClangRecordDecl *)(decl));
break;
case clang::Decl::Var:
visit_var_decl(c, static_cast<const clang::VarDecl *>(decl));
break;
default:
- emit_warning(c, decl->getLocation(), "ignoring %s decl", decl->getDeclKindName());
+ emit_warning(c, bitcast(decl->getLocation()), "ignoring %s decl", decl->getDeclKindName());
}
return true;
@@ -4846,10 +4842,10 @@ static void process_preprocessor_entities(Context *c, ZigClangASTUnit *zunit) {
clang::MacroDefinitionRecord *macro = static_cast<clang::MacroDefinitionRecord *>(entity);
const char *raw_name = macro->getName()->getNameStart();
clang::SourceRange range = macro->getSourceRange();
- clang::SourceLocation begin_loc = range.getBegin();
- clang::SourceLocation end_loc = range.getEnd();
+ ZigClangSourceLocation begin_loc = bitcast(range.getBegin());
+ ZigClangSourceLocation end_loc = bitcast(range.getEnd());
- if (begin_loc == end_loc) {
+ if (ZigClangSourceLocation_eq(begin_loc, end_loc)) {
// this means it is a macro without a value
// we don't care about such things
continue;
@@ -4859,7 +4855,7 @@ static void process_preprocessor_entities(Context *c, ZigClangASTUnit *zunit) {
continue;
}
- const char *begin_c = ZigClangSourceManager_getCharacterData(c->source_manager, bitcast(begin_loc));
+ const char *begin_c = ZigClangSourceManager_getCharacterData(c->source_manager, begin_loc);
process_macro(c, &ctok, name, begin_c);
}
}
diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp
index 230c3c3116..7c0c787e43 100644
--- a/src/zig_clang.cpp
+++ b/src/zig_clang.cpp
@@ -212,3 +212,48 @@ bool ZigClangASTUnit_visitLocalTopLevelDecls(ZigClangASTUnit *self, void *contex
return reinterpret_cast<clang::ASTUnit *>(self)->visitLocalTopLevelDecls(context,
reinterpret_cast<bool (*)(void *, const clang::Decl *)>(Fn));
}
+
+const ZigClangRecordDecl *ZigClangRecordType_getDecl(const ZigClangRecordType *record_ty) {
+ const clang::RecordDecl *record_decl = reinterpret_cast<const clang::RecordType *>(record_ty)->getDecl();
+ return reinterpret_cast<const ZigClangRecordDecl *>(record_decl);
+}
+
+const ZigClangTagDecl *ZigClangRecordDecl_getCanonicalDecl(const ZigClangRecordDecl *record_decl) {
+ const clang::TagDecl *tag_decl = reinterpret_cast<const clang::RecordDecl*>(record_decl)->getCanonicalDecl();
+ return reinterpret_cast<const ZigClangTagDecl *>(tag_decl);
+}
+
+const ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const ZigClangRecordDecl *zig_record_decl) {
+ const clang::RecordDecl *record_decl = reinterpret_cast<const clang::RecordDecl *>(zig_record_decl);
+ const clang::RecordDecl *definition = record_decl->getDefinition();
+ return reinterpret_cast<const ZigClangRecordDecl *>(definition);
+}
+
+bool ZigClangRecordDecl_isUnion(const ZigClangRecordDecl *record_decl) {
+ return reinterpret_cast<const clang::RecordDecl*>(record_decl)->isUnion();
+}
+
+bool ZigClangRecordDecl_isStruct(const ZigClangRecordDecl *record_decl) {
+ return reinterpret_cast<const clang::RecordDecl*>(record_decl)->isStruct();
+}
+
+bool ZigClangRecordDecl_isAnonymousStructOrUnion(const ZigClangRecordDecl *record_decl) {
+ return reinterpret_cast<const clang::RecordDecl*>(record_decl)->isAnonymousStructOrUnion();
+}
+
+const char *ZigClangDecl_getName_bytes_begin(const ZigClangDecl *zig_decl) {
+ const clang::Decl *decl = reinterpret_cast<const clang::Decl *>(zig_decl);
+ const clang::NamedDecl *named_decl = static_cast<const clang::NamedDecl *>(decl);
+ return (const char *)named_decl->getName().bytes_begin();
+}
+
+ZigClangSourceLocation ZigClangRecordDecl_getLocation(const ZigClangRecordDecl *zig_record_decl) {
+ const clang::RecordDecl *record_decl = reinterpret_cast<const clang::RecordDecl *>(zig_record_decl);
+ return bitcast(record_decl->getLocation());
+}
+
+bool ZigClangSourceLocation_eq(ZigClangSourceLocation zig_a, ZigClangSourceLocation zig_b) {
+ clang::SourceLocation a = bitcast(zig_a);
+ clang::SourceLocation b = bitcast(zig_b);
+ return a == b;
+}
diff --git a/src/zig_clang.h b/src/zig_clang.h
index c7d749cbd9..03c20c62d6 100644
--- a/src/zig_clang.h
+++ b/src/zig_clang.h
@@ -16,6 +16,7 @@
// ATTENTION: If you modify this file, be sure to update the corresponding
// extern function declarations in the self-hosted compiler.
+// Note: not yet, we don't have the corresponding clang.zig yet.
struct ZigClangSourceLocation {
unsigned ID;
@@ -86,6 +87,7 @@ struct ZigClangStorageClass;
struct ZigClangStringLiteral;
struct ZigClangStringRef;
struct ZigClangSwitchStmt;
+struct ZigClangTagDecl;
struct ZigClangType;
struct ZigClangTypedefNameDecl;
struct ZigClangTypedefType;
@@ -256,4 +258,17 @@ ZIG_EXTERN_C ZigClangASTContext *ZigClangASTUnit_getASTContext(ZigClangASTUnit *
ZIG_EXTERN_C ZigClangSourceManager *ZigClangASTUnit_getSourceManager(ZigClangASTUnit *);
ZIG_EXTERN_C bool ZigClangASTUnit_visitLocalTopLevelDecls(ZigClangASTUnit *, void *context,
bool (*Fn)(void *context, const ZigClangDecl *decl));
+
+ZIG_EXTERN_C const ZigClangRecordDecl *ZigClangRecordType_getDecl(const ZigClangRecordType *record_ty);
+
+ZIG_EXTERN_C const ZigClangTagDecl *ZigClangRecordDecl_getCanonicalDecl(const ZigClangRecordDecl *record_decl);
+ZIG_EXTERN_C bool ZigClangRecordDecl_isUnion(const ZigClangRecordDecl *record_decl);
+ZIG_EXTERN_C bool ZigClangRecordDecl_isStruct(const ZigClangRecordDecl *record_decl);
+ZIG_EXTERN_C bool ZigClangRecordDecl_isAnonymousStructOrUnion(const ZigClangRecordDecl *record_decl);
+ZIG_EXTERN_C const ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const ZigClangRecordDecl *);
+ZIG_EXTERN_C ZigClangSourceLocation ZigClangRecordDecl_getLocation(const ZigClangRecordDecl *);
+
+ZIG_EXTERN_C const char *ZigClangDecl_getName_bytes_begin(const ZigClangDecl *decl);
+
+ZIG_EXTERN_C bool ZigClangSourceLocation_eq(ZigClangSourceLocation a, ZigClangSourceLocation b);
#endif
diff --git a/std/debug.zig b/std/debug.zig
index ec3f609022..90b4ff31d5 100644
--- a/std/debug.zig
+++ b/std/debug.zig
@@ -1178,7 +1178,7 @@ pub const DwarfInfo = struct {
};
pub const DebugInfo = switch (builtin.os) {
- builtin.Os.macosx => struct {
+ builtin.Os.macosx, builtin.Os.ios => struct {
symbols: []const MachoSymbol,
strings: []const u8,
ofiles: OFileTable,
diff --git a/std/math/big.zig b/std/math/big.zig
index 94b6d864e7..44b5ce675f 100644
--- a/std/math/big.zig
+++ b/std/math/big.zig
@@ -1,5 +1,7 @@
pub use @import("big/int.zig");
+pub use @import("big/rational.zig");
test "math.big" {
_ = @import("big/int.zig");
+ _ = @import("big/rational.zig");
}
diff --git a/std/math/big/int.zig b/std/math/big/int.zig
index 8800c2c7a9..aced892e18 100644
--- a/std/math/big/int.zig
+++ b/std/math/big/int.zig
@@ -22,13 +22,18 @@ comptime {
}
pub const Int = struct {
- allocator: *Allocator,
- positive: bool,
+ const sign_bit: usize = 1 << (usize.bit_count - 1);
+
+ allocator: ?*Allocator,
// - little-endian ordered
// - len >= 1 always
// - zero value -> len == 1 with limbs[0] == 0
limbs: []Limb,
- len: usize,
+ // High bit is the sign bit. 1 is negative, 0 positive.
+ // Remaining bits indicate the number of used limbs.
+ //
+ // If Zig gets smarter about packing data, this can be rewritten as a u1 and usize - 1 field.
+ metadata: usize,
const default_capacity = 4;
@@ -45,54 +50,98 @@ pub const Int = struct {
pub fn initCapacity(allocator: *Allocator, capacity: usize) !Int {
return Int{
.allocator = allocator,
- .positive = true,
+ .metadata = 1,
.limbs = block: {
var limbs = try allocator.alloc(Limb, math.max(default_capacity, capacity));
limbs[0] = 0;
break :block limbs;
},
- .len = 1,
};
}
+ pub fn len(self: Int) usize {
+ return self.metadata & ~sign_bit;
+ }
+
+ pub fn isPositive(self: Int) bool {
+ return self.metadata & sign_bit == 0;
+ }
+
+ pub fn setSign(self: *Int, positive: bool) void {
+ if (positive) {
+ self.metadata &= ~sign_bit;
+ } else {
+ self.metadata |= sign_bit;
+ }
+ }
+
+ pub fn setLen(self: *Int, new_len: usize) void {
+ self.metadata &= sign_bit;
+ self.metadata |= new_len;
+ }
+
+ // Initialize an Int directly from a fixed set of limb values. This is considered read-only
+ // and cannot be used as a receiver argument to any functions. If this tries to allocate
+ // at any point a panic will occur due to the null allocator.
+ pub fn initFixed(limbs: []const Limb) Int {
+ var self = Int{
+ .allocator = null,
+ .metadata = limbs.len,
+ // Cast away the const, invalid use to pass as a pointer argument.
+ .limbs = @intToPtr([*]Limb, @ptrToInt(limbs.ptr))[0..limbs.len],
+ };
+
+ self.normalize(limbs.len);
+ return self;
+ }
+
pub fn ensureCapacity(self: *Int, capacity: usize) !void {
+ self.assertWritable();
if (capacity <= self.limbs.len) {
return;
}
- self.limbs = try self.allocator.realloc(self.limbs, capacity);
+ self.limbs = try self.allocator.?.realloc(self.limbs, capacity);
+ }
+
+ fn assertWritable(self: Int) void {
+ if (self.allocator == null) {
+ @panic("provided Int value is read-only but must be writable");
+ }
}
pub fn deinit(self: *Int) void {
- self.allocator.free(self.limbs);
+ self.assertWritable();
+ self.allocator.?.free(self.limbs);
self.* = undefined;
}
pub fn clone(other: Int) !Int {
+ other.assertWritable();
return Int{
.allocator = other.allocator,
- .positive = other.positive,
+ .metadata = other.metadata,
.limbs = block: {
- var limbs = try other.allocator.alloc(Limb, other.len);
- mem.copy(Limb, limbs[0..], other.limbs[0..other.len]);
+ var limbs = try other.allocator.?.alloc(Limb, other.len());
+ mem.copy(Limb, limbs[0..], other.limbs[0..other.len()]);
break :block limbs;
},
- .len = other.len,
};
}
pub fn copy(self: *Int, other: Int) !void {
- if (self == &other) {
+ self.assertWritable();
+ if (self.limbs.ptr == other.limbs.ptr) {
return;
}
- self.positive = other.positive;
- try self.ensureCapacity(other.len);
- mem.copy(Limb, self.limbs[0..], other.limbs[0..other.len]);
- self.len = other.len;
+ try self.ensureCapacity(other.len());
+ mem.copy(Limb, self.limbs[0..], other.limbs[0..other.len()]);
+ self.metadata = other.metadata;
}
pub fn swap(self: *Int, other: *Int) void {
+ self.assertWritable();
mem.swap(Int, self, other);
}
@@ -103,25 +152,25 @@ pub const Int = struct {
debug.warn("\n");
}
- pub fn negate(r: *Int) void {
- r.positive = !r.positive;
+ pub fn negate(self: *Int) void {
+ self.metadata ^= sign_bit;
}
- pub fn abs(r: *Int) void {
- r.positive = true;
+ pub fn abs(self: *Int) void {
+ self.metadata &= ~sign_bit;
}
- pub fn isOdd(r: Int) bool {
- return r.limbs[0] & 1 != 0;
+ pub fn isOdd(self: Int) bool {
+ return self.limbs[0] & 1 != 0;
}
- pub fn isEven(r: Int) bool {
- return !r.isOdd();
+ pub fn isEven(self: Int) bool {
+ return !self.isOdd();
}
// Returns the number of bits required to represent the absolute value of self.
fn bitCountAbs(self: Int) usize {
- return (self.len - 1) * Limb.bit_count + (Limb.bit_count - @clz(self.limbs[self.len - 1]));
+ return (self.len() - 1) * Limb.bit_count + (Limb.bit_count - @clz(self.limbs[self.len() - 1]));
}
// Returns the number of bits required to represent the integer in twos-complement form.
@@ -137,11 +186,11 @@ pub const Int = struct {
// If the entire value has only one bit set (e.g. 0b100000000) then the negation in twos
// complement requires one less bit.
- if (!self.positive) block: {
+ if (!self.isPositive()) block: {
bits += 1;
- if (@popCount(self.limbs[self.len - 1]) == 1) {
- for (self.limbs[0 .. self.len - 1]) |limb| {
+ if (@popCount(self.limbs[self.len() - 1]) == 1) {
+ for (self.limbs[0 .. self.len() - 1]) |limb| {
if (@popCount(limb) != 0) {
break :block;
}
@@ -158,11 +207,11 @@ pub const Int = struct {
if (self.eqZero()) {
return true;
}
- if (!is_signed and !self.positive) {
+ if (!is_signed and !self.isPositive()) {
return false;
}
- const req_bits = self.bitCountTwosComp() + @boolToInt(self.positive and is_signed);
+ const req_bits = self.bitCountTwosComp() + @boolToInt(self.isPositive() and is_signed);
return bit_count >= req_bits;
}
@@ -174,11 +223,12 @@ pub const Int = struct {
// the minus sign. This is used for determining the number of characters needed to print the
// value. It is inexact and will exceed the given value by 1-2 digits.
pub fn sizeInBase(self: Int, base: usize) usize {
- const bit_count = usize(@boolToInt(!self.positive)) + self.bitCountAbs();
+ const bit_count = usize(@boolToInt(!self.isPositive())) + self.bitCountAbs();
return (bit_count / math.log2(base)) + 1;
}
pub fn set(self: *Int, value: var) Allocator.Error!void {
+ self.assertWritable();
const T = @typeOf(value);
switch (@typeInfo(T)) {
@@ -186,19 +236,19 @@ pub const Int = struct {
const UT = if (T.is_signed) @IntType(false, T.bit_count - 1) else T;
try self.ensureCapacity(@sizeOf(UT) / @sizeOf(Limb));
- self.positive = value >= 0;
- self.len = 0;
+ self.metadata = 0;
+ self.setSign(value >= 0);
var w_value: UT = if (value < 0) @intCast(UT, -value) else @intCast(UT, value);
if (info.bits <= Limb.bit_count) {
self.limbs[0] = Limb(w_value);
- self.len = 1;
+ self.metadata += 1;
} else {
var i: usize = 0;
while (w_value != 0) : (i += 1) {
self.limbs[i] = @truncate(Limb, w_value);
- self.len += 1;
+ self.metadata += 1;
// TODO: shift == 64 at compile-time fails. Fails on u128 limbs.
w_value >>= Limb.bit_count / 2;
@@ -212,8 +262,8 @@ pub const Int = struct {
const req_limbs = @divFloor(math.log2(w_value), Limb.bit_count) + 1;
try self.ensureCapacity(req_limbs);
- self.positive = value >= 0;
- self.len = req_limbs;
+ self.metadata = req_limbs;
+ self.setSign(value >= 0);
if (w_value <= maxInt(Limb)) {
self.limbs[0] = w_value;
@@ -254,17 +304,17 @@ pub const Int = struct {
if (@sizeOf(UT) <= @sizeOf(Limb)) {
r = @intCast(UT, self.limbs[0]);
} else {
- for (self.limbs[0..self.len]) |_, ri| {
- const limb = self.limbs[self.len - ri - 1];
+ for (self.limbs[0..self.len()]) |_, ri| {
+ const limb = self.limbs[self.len() - ri - 1];
r <<= Limb.bit_count;
r |= limb;
}
}
if (!T.is_signed) {
- return if (self.positive) @intCast(T, r) else error.NegativeIntoUnsigned;
+ return if (self.isPositive()) @intCast(T, r) else error.NegativeIntoUnsigned;
} else {
- if (self.positive) {
+ if (self.isPositive()) {
return @intCast(T, r);
} else {
if (math.cast(T, r)) |ok| {
@@ -304,6 +354,7 @@ pub const Int = struct {
}
pub fn setString(self: *Int, base: u8, value: []const u8) !void {
+ self.assertWritable();
if (base < 2 or base > 16) {
return error.InvalidBase;
}
@@ -315,25 +366,18 @@ pub const Int = struct {
i += 1;
}
- // TODO values less than limb size should guarantee non allocating
- var base_buffer: [512]u8 = undefined;
- const base_al = &std.heap.FixedBufferAllocator.init(base_buffer[0..]).allocator;
- const base_ap = try Int.initSet(base_al, base);
-
- var d_buffer: [512]u8 = undefined;
- var d_fba = std.heap.FixedBufferAllocator.init(d_buffer[0..]);
- const d_al = &d_fba.allocator;
-
+ const ap_base = Int.initFixed(([]Limb{base})[0..]);
try self.set(0);
+
for (value[i..]) |ch| {
const d = try charToDigit(ch, base);
- d_fba.end_index = 0;
- const d_ap = try Int.initSet(d_al, d);
- try self.mul(self.*, base_ap);
- try self.add(self.*, d_ap);
+ const ap_d = Int.initFixed(([]Limb{d})[0..]);
+
+ try self.mul(self.*, ap_base);
+ try self.add(self.*, ap_d);
}
- self.positive = positive;
+ self.setSign(positive);
}
/// TODO make this call format instead of the other way around
@@ -355,7 +399,7 @@ pub const Int = struct {
if (base & (base - 1) == 0) {
const base_shift = math.log2_int(Limb, base);
- for (self.limbs[0..self.len]) |limb| {
+ for (self.limbs[0..self.len()]) |limb| {
var shift: usize = 0;
while (shift < Limb.bit_count) : (shift += base_shift) {
const r = @intCast(u8, (limb >> @intCast(Log2Limb, shift)) & Limb(base - 1));
@@ -382,11 +426,11 @@ pub const Int = struct {
}
var q = try self.clone();
- q.positive = true;
+ q.abs();
var r = try Int.init(allocator);
var b = try Int.initSet(allocator, limb_base);
- while (q.len >= 2) {
+ while (q.len() >= 2) {
try Int.divTrunc(&q, &r, q, b);
var r_word = r.limbs[0];
@@ -399,7 +443,7 @@ pub const Int = struct {
}
{
- debug.assert(q.len == 1);
+ debug.assert(q.len() == 1);
var r_word = q.limbs[0];
while (r_word != 0) {
@@ -410,7 +454,7 @@ pub const Int = struct {
}
}
- if (!self.positive) {
+ if (!self.isPositive()) {
try digits.append('-');
}
@@ -428,22 +472,24 @@ pub const Int = struct {
comptime FmtError: type,
output: fn (@typeOf(context), []const u8) FmtError!void,
) FmtError!void {
+ self.assertWritable();
// TODO look at fmt and support other bases
- const str = self.toString(self.allocator, 10) catch @panic("TODO make this non allocating");
- defer self.allocator.free(str);
+ // TODO support read-only fixed integers
+ const str = self.toString(self.allocator.?, 10) catch @panic("TODO make this non allocating");
+ defer self.allocator.?.free(str);
return output(context, str);
}
// returns -1, 0, 1 if |a| < |b|, |a| == |b| or |a| > |b| respectively.
pub fn cmpAbs(a: Int, b: Int) i8 {
- if (a.len < b.len) {
+ if (a.len() < b.len()) {
return -1;
}
- if (a.len > b.len) {
+ if (a.len() > b.len()) {
return 1;
}
- var i: usize = a.len - 1;
+ var i: usize = a.len() - 1;
while (i != 0) : (i -= 1) {
if (a.limbs[i] != b.limbs[i]) {
break;
@@ -461,17 +507,17 @@ pub const Int = struct {
// returns -1, 0, 1 if a < b, a == b or a > b respectively.
pub fn cmp(a: Int, b: Int) i8 {
- if (a.positive != b.positive) {
- return if (a.positive) i8(1) else -1;
+ if (a.isPositive() != b.isPositive()) {
+ return if (a.isPositive()) i8(1) else -1;
} else {
const r = cmpAbs(a, b);
- return if (a.positive) r else -r;
+ return if (a.isPositive()) r else -r;
}
}
// if a == 0
pub fn eqZero(a: Int) bool {
- return a.len == 1 and a.limbs[0] == 0;
+ return a.len() == 1 and a.limbs[0] == 0;
}
// if |a| == |b|
@@ -484,28 +530,12 @@ pub const Int = struct {
return cmp(a, b) == 0;
}
- // Normalize for a possible single carry digit.
- //
- // [1, 2, 3, 4, 0] -> [1, 2, 3, 4]
- // [1, 2, 3, 4, 5] -> [1, 2, 3, 4, 5]
- // [0] -> [0]
- fn norm1(r: *Int, length: usize) void {
- debug.assert(length > 0);
- debug.assert(length <= r.limbs.len);
-
- if (r.limbs[length - 1] == 0) {
- r.len = if (length > 1) length - 1 else 1;
- } else {
- r.len = length;
- }
- }
-
// Normalize a possible sequence of leading zeros.
//
// [1, 2, 3, 4, 0] -> [1, 2, 3, 4]
// [1, 2, 0, 0, 0] -> [1, 2]
// [0, 0, 0, 0, 0] -> [0]
- fn normN(r: *Int, length: usize) void {
+ fn normalize(r: *Int, length: usize) void {
debug.assert(length > 0);
debug.assert(length <= r.limbs.len);
@@ -517,11 +547,21 @@ pub const Int = struct {
}
// Handle zero
- r.len = if (j != 0) j else 1;
+ r.setLen(if (j != 0) j else 1);
+ }
+
+ // Cannot be used as a result argument to any function.
+ fn readOnlyPositive(a: Int) Int {
+ return Int{
+ .allocator = null,
+ .metadata = a.len(),
+ .limbs = a.limbs,
+ };
}
// r = a + b
pub fn add(r: *Int, a: Int, b: Int) Allocator.Error!void {
+ r.assertWritable();
if (a.eqZero()) {
try r.copy(b);
return;
@@ -530,38 +570,26 @@ pub const Int = struct {
return;
}
- if (a.positive != b.positive) {
- if (a.positive) {
+ if (a.isPositive() != b.isPositive()) {
+ if (a.isPositive()) {
// (a) + (-b) => a - b
- const bp = Int{
- .allocator = undefined,
- .positive = true,
- .limbs = b.limbs,
- .len = b.len,
- };
- try r.sub(a, bp);
+ try r.sub(a, readOnlyPositive(b));
} else {
// (-a) + (b) => b - a
- const ap = Int{
- .allocator = undefined,
- .positive = true,
- .limbs = a.limbs,
- .len = a.len,
- };
- try r.sub(b, ap);
+ try r.sub(b, readOnlyPositive(a));
}
} else {
- if (a.len >= b.len) {
- try r.ensureCapacity(a.len + 1);
- lladd(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]);
- r.norm1(a.len + 1);
+ if (a.len() >= b.len()) {
+ try r.ensureCapacity(a.len() + 1);
+ lladd(r.limbs[0..], a.limbs[0..a.len()], b.limbs[0..b.len()]);
+ r.normalize(a.len() + 1);
} else {
- try r.ensureCapacity(b.len + 1);
- lladd(r.limbs[0..], b.limbs[0..b.len], a.limbs[0..a.len]);
- r.norm1(b.len + 1);
+ try r.ensureCapacity(b.len() + 1);
+ lladd(r.limbs[0..], b.limbs[0..b.len()], a.limbs[0..a.len()]);
+ r.normalize(b.len() + 1);
}
- r.positive = a.positive;
+ r.setSign(a.isPositive());
}
}
@@ -591,53 +619,42 @@ pub const Int = struct {
// r = a - b
pub fn sub(r: *Int, a: Int, b: Int) !void {
- if (a.positive != b.positive) {
- if (a.positive) {
+ r.assertWritable();
+ if (a.isPositive() != b.isPositive()) {
+ if (a.isPositive()) {
// (a) - (-b) => a + b
- const bp = Int{
- .allocator = undefined,
- .positive = true,
- .limbs = b.limbs,
- .len = b.len,
- };
- try r.add(a, bp);
+ try r.add(a, readOnlyPositive(b));
} else {
// (-a) - (b) => -(a + b)
- const ap = Int{
- .allocator = undefined,
- .positive = true,
- .limbs = a.limbs,
- .len = a.len,
- };
- try r.add(ap, b);
- r.positive = false;
+ try r.add(readOnlyPositive(a), b);
+ r.setSign(false);
}
} else {
- if (a.positive) {
+ if (a.isPositive()) {
// (a) - (b) => a - b
if (a.cmp(b) >= 0) {
- try r.ensureCapacity(a.len + 1);
- llsub(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]);
- r.normN(a.len);
- r.positive = true;
+ try r.ensureCapacity(a.len() + 1);
+ llsub(r.limbs[0..], a.limbs[0..a.len()], b.limbs[0..b.len()]);
+ r.normalize(a.len());
+ r.setSign(true);
} else {
- try r.ensureCapacity(b.len + 1);
- llsub(r.limbs[0..], b.limbs[0..b.len], a.limbs[0..a.len]);
- r.normN(b.len);
- r.positive = false;
+ try r.ensureCapacity(b.len() + 1);
+ llsub(r.limbs[0..], b.limbs[0..b.len()], a.limbs[0..a.len()]);
+ r.normalize(b.len());
+ r.setSign(false);
}
} else {
// (-a) - (-b) => -(a - b)
if (a.cmp(b) < 0) {
- try r.ensureCapacity(a.len + 1);
- llsub(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]);
- r.normN(a.len);
- r.positive = false;
+ try r.ensureCapacity(a.len() + 1);
+ llsub(r.limbs[0..], a.limbs[0..a.len()], b.limbs[0..b.len()]);
+ r.normalize(a.len());
+ r.setSign(false);
} else {
- try r.ensureCapacity(b.len + 1);
- llsub(r.limbs[0..], b.limbs[0..b.len], a.limbs[0..a.len]);
- r.normN(b.len);
- r.positive = true;
+ try r.ensureCapacity(b.len() + 1);
+ llsub(r.limbs[0..], b.limbs[0..b.len()], a.limbs[0..a.len()]);
+ r.normalize(b.len());
+ r.setSign(true);
}
}
}
@@ -671,12 +688,14 @@ pub const Int = struct {
//
// For greatest efficiency, ensure rma does not alias a or b.
pub fn mul(rma: *Int, a: Int, b: Int) !void {
+ rma.assertWritable();
+
var r = rma;
var aliased = rma.limbs.ptr == a.limbs.ptr or rma.limbs.ptr == b.limbs.ptr;
var sr: Int = undefined;
if (aliased) {
- sr = try Int.initCapacity(rma.allocator, a.len + b.len);
+ sr = try Int.initCapacity(rma.allocator.?, a.len() + b.len());
r = &sr;
aliased = true;
}
@@ -685,16 +704,16 @@ pub const Int = struct {
r.deinit();
};
- try r.ensureCapacity(a.len + b.len);
+ try r.ensureCapacity(a.len() + b.len());
- if (a.len >= b.len) {
- llmul(r.limbs, a.limbs[0..a.len], b.limbs[0..b.len]);
+ if (a.len() >= b.len()) {
+ llmul(r.limbs, a.limbs[0..a.len()], b.limbs[0..b.len()]);
} else {
- llmul(r.limbs, b.limbs[0..b.len], a.limbs[0..a.len]);
+ llmul(r.limbs, b.limbs[0..b.len()], a.limbs[0..a.len()]);
}
- r.positive = a.positive == b.positive;
- r.normN(a.len + b.len);
+ r.normalize(a.len() + b.len());
+ r.setSign(a.isPositive() == b.isPositive());
}
// a + b * c + *carry, sets carry to the overflow bits
@@ -744,25 +763,24 @@ pub const Int = struct {
try div(q, r, a, b);
// Trunc -> Floor.
- if (!q.positive) {
- // TODO values less than limb size should guarantee non allocating
- var one_buffer: [512]u8 = undefined;
- const one_al = &std.heap.FixedBufferAllocator.init(one_buffer[0..]).allocator;
- const one_ap = try Int.initSet(one_al, 1);
-
- try q.sub(q.*, one_ap);
- try r.add(q.*, one_ap);
+ if (!q.isPositive()) {
+ const one = Int.initFixed(([]Limb{1})[0..]);
+ try q.sub(q.*, one);
+ try r.add(q.*, one);
}
- r.positive = b.positive;
+ r.setSign(b.isPositive());
}
pub fn divTrunc(q: *Int, r: *Int, a: Int, b: Int) !void {
try div(q, r, a, b);
- r.positive = a.positive;
+ r.setSign(a.isPositive());
}
// Truncates by default.
fn div(quo: *Int, rem: *Int, a: Int, b: Int) !void {
+ quo.assertWritable();
+ rem.assertWritable();
+
if (b.eqZero()) {
@panic("division by zero");
}
@@ -773,36 +791,67 @@ pub const Int = struct {
if (a.cmpAbs(b) < 0) {
// quo may alias a so handle rem first
try rem.copy(a);
- rem.positive = a.positive == b.positive;
+ rem.setSign(a.isPositive() == b.isPositive());
- quo.positive = true;
- quo.len = 1;
+ quo.metadata = 1;
quo.limbs[0] = 0;
return;
}
- if (b.len == 1) {
- try quo.ensureCapacity(a.len);
+ // Handle trailing zero-words of divisor/dividend. These are not handled in the following
+ // algorithms.
+ const a_zero_limb_count = blk: {
+ var i: usize = 0;
+ while (i < a.len()) : (i += 1) {
+ if (a.limbs[i] != 0) break;
+ }
+ break :blk i;
+ };
+ const b_zero_limb_count = blk: {
+ var i: usize = 0;
+ while (i < b.len()) : (i += 1) {
+ if (b.limbs[i] != 0) break;
+ }
+ break :blk i;
+ };
+
+ const ab_zero_limb_count = std.math.min(a_zero_limb_count, b_zero_limb_count);
+
+ if (b.len() - ab_zero_limb_count == 1) {
+ try quo.ensureCapacity(a.len());
- lldiv1(quo.limbs[0..], &rem.limbs[0], a.limbs[0..a.len], b.limbs[0]);
- quo.norm1(a.len);
- quo.positive = a.positive == b.positive;
+ lldiv1(quo.limbs[0..], &rem.limbs[0], a.limbs[ab_zero_limb_count..a.len()], b.limbs[b.len() - 1]);
+ quo.normalize(a.len() - ab_zero_limb_count);
+ quo.setSign(a.isPositive() == b.isPositive());
- rem.len = 1;
- rem.positive = true;
+ rem.metadata = 1;
} else {
// x and y are modified during division
- var x = try a.clone();
+ var x = try Int.initCapacity(quo.allocator.?, a.len());
defer x.deinit();
+ try x.copy(a);
- var y = try b.clone();
+ var y = try Int.initCapacity(quo.allocator.?, b.len());
defer y.deinit();
+ try y.copy(b);
// x may grow one limb during normalization
- try quo.ensureCapacity(a.len + y.len);
- try divN(quo.allocator, quo, rem, &x, &y);
+ try quo.ensureCapacity(a.len() + y.len());
+
+ // Shrink x, y such that the trailing zero limbs shared between are removed.
+ if (ab_zero_limb_count != 0) {
+ std.mem.copy(Limb, x.limbs[0..], x.limbs[ab_zero_limb_count..]);
+ std.mem.copy(Limb, y.limbs[0..], y.limbs[ab_zero_limb_count..]);
+ x.metadata -= ab_zero_limb_count;
+ y.metadata -= ab_zero_limb_count;
+ }
+
+ try divN(quo.allocator.?, quo, rem, &x, &y);
+ quo.setSign(a.isPositive() == b.isPositive());
+ }
- quo.positive = a.positive == b.positive;
+ if (ab_zero_limb_count != 0) {
+ try rem.shiftLeft(rem.*, ab_zero_limb_count * Limb.bit_count);
}
}
@@ -837,25 +886,28 @@ pub const Int = struct {
//
// x = qy + r where 0 <= r < y
fn divN(allocator: *Allocator, q: *Int, r: *Int, x: *Int, y: *Int) !void {
- debug.assert(y.len >= 2);
- debug.assert(x.len >= y.len);
- debug.assert(q.limbs.len >= x.len + y.len - 1);
+ debug.assert(y.len() >= 2);
+ debug.assert(x.len() >= y.len());
+ debug.assert(q.limbs.len >= x.len() + y.len() - 1);
debug.assert(default_capacity >= 3); // see 3.2
var tmp = try Int.init(allocator);
defer tmp.deinit();
- // Normalize so y > Limb.bit_count / 2 (i.e. leading bit is set)
- const norm_shift = @clz(y.limbs[y.len - 1]);
+ // Normalize so y > Limb.bit_count / 2 (i.e. leading bit is set) and even
+ var norm_shift = @clz(y.limbs[y.len() - 1]);
+ if (norm_shift == 0 and y.isOdd()) {
+ norm_shift = Limb.bit_count;
+ }
try x.shiftLeft(x.*, norm_shift);
try y.shiftLeft(y.*, norm_shift);
- const n = x.len - 1;
- const t = y.len - 1;
+ const n = x.len() - 1;
+ const t = y.len() - 1;
// 1.
- q.len = n - t + 1;
- mem.set(Limb, q.limbs[0..q.len], 0);
+ q.metadata = n - t + 1;
+ mem.set(Limb, q.limbs[0..q.len()], 0);
// 2.
try tmp.shiftLeft(y.*, Limb.bit_count * (n - t));
@@ -880,7 +932,7 @@ pub const Int = struct {
tmp.limbs[0] = if (i >= 2) x.limbs[i - 2] else 0;
tmp.limbs[1] = if (i >= 1) x.limbs[i - 1] else 0;
tmp.limbs[2] = x.limbs[i];
- tmp.normN(3);
+ tmp.normalize(3);
while (true) {
// 2x1 limb multiplication unrolled against single-limb q[i-t-1]
@@ -888,7 +940,7 @@ pub const Int = struct {
r.limbs[0] = addMulLimbWithCarry(0, if (t >= 1) y.limbs[t - 1] else 0, q.limbs[i - t - 1], &carry);
r.limbs[1] = addMulLimbWithCarry(0, y.limbs[t], q.limbs[i - t - 1], &carry);
r.limbs[2] = carry;
- r.normN(3);
+ r.normalize(3);
if (r.cmpAbs(tmp) <= 0) {
break;
@@ -903,7 +955,7 @@ pub const Int = struct {
try tmp.shiftLeft(tmp, Limb.bit_count * (i - t - 1));
try x.sub(x.*, tmp);
- if (!x.positive) {
+ if (!x.isPositive()) {
try tmp.shiftLeft(y.*, Limb.bit_count * (i - t - 1));
try x.add(x.*, tmp);
q.limbs[i - t - 1] -= 1;
@@ -911,18 +963,20 @@ pub const Int = struct {
}
// Denormalize
- q.normN(q.len);
+ q.normalize(q.len());
try r.shiftRight(x.*, norm_shift);
- r.normN(r.len);
+ r.normalize(r.len());
}
// r = a << shift, in other words, r = a * 2^shift
pub fn shiftLeft(r: *Int, a: Int, shift: usize) !void {
- try r.ensureCapacity(a.len + (shift / Limb.bit_count) + 1);
- llshl(r.limbs[0..], a.limbs[0..a.len], shift);
- r.norm1(a.len + (shift / Limb.bit_count) + 1);
- r.positive = a.positive;
+ r.assertWritable();
+
+ try r.ensureCapacity(a.len() + (shift / Limb.bit_count) + 1);
+ llshl(r.limbs[0..], a.limbs[0..a.len()], shift);
+ r.normalize(a.len() + (shift / Limb.bit_count) + 1);
+ r.setSign(a.isPositive());
}
fn llshl(r: []Limb, a: []const Limb, shift: usize) void {
@@ -950,17 +1004,18 @@ pub const Int = struct {
// r = a >> shift
pub fn shiftRight(r: *Int, a: Int, shift: usize) !void {
- if (a.len <= shift / Limb.bit_count) {
- r.len = 1;
+ r.assertWritable();
+
+ if (a.len() <= shift / Limb.bit_count) {
+ r.metadata = 1;
r.limbs[0] = 0;
- r.positive = true;
return;
}
- try r.ensureCapacity(a.len - (shift / Limb.bit_count));
- const r_len = llshr(r.limbs[0..], a.limbs[0..a.len], shift);
- r.len = a.len - (shift / Limb.bit_count);
- r.positive = a.positive;
+ try r.ensureCapacity(a.len() - (shift / Limb.bit_count));
+ const r_len = llshr(r.limbs[0..], a.limbs[0..a.len()], shift);
+ r.metadata = a.len() - (shift / Limb.bit_count);
+ r.setSign(a.isPositive());
}
fn llshr(r: []Limb, a: []const Limb, shift: usize) void {
@@ -985,14 +1040,16 @@ pub const Int = struct {
// r = a | b
pub fn bitOr(r: *Int, a: Int, b: Int) !void {
- if (a.len > b.len) {
- try r.ensureCapacity(a.len);
- llor(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]);
- r.len = a.len;
+ r.assertWritable();
+
+ if (a.len() > b.len()) {
+ try r.ensureCapacity(a.len());
+ llor(r.limbs[0..], a.limbs[0..a.len()], b.limbs[0..b.len()]);
+ r.setLen(a.len());
} else {
- try r.ensureCapacity(b.len);
- llor(r.limbs[0..], b.limbs[0..b.len], a.limbs[0..a.len]);
- r.len = b.len;
+ try r.ensureCapacity(b.len());
+ llor(r.limbs[0..], b.limbs[0..b.len()], a.limbs[0..a.len()]);
+ r.setLen(b.len());
}
}
@@ -1012,14 +1069,16 @@ pub const Int = struct {
// r = a & b
pub fn bitAnd(r: *Int, a: Int, b: Int) !void {
- if (a.len > b.len) {
- try r.ensureCapacity(b.len);
- lland(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]);
- r.normN(b.len);
+ r.assertWritable();
+
+ if (a.len() > b.len()) {
+ try r.ensureCapacity(b.len());
+ lland(r.limbs[0..], a.limbs[0..a.len()], b.limbs[0..b.len()]);
+ r.normalize(b.len());
} else {
- try r.ensureCapacity(a.len);
- lland(r.limbs[0..], b.limbs[0..b.len], a.limbs[0..a.len]);
- r.normN(a.len);
+ try r.ensureCapacity(a.len());
+ lland(r.limbs[0..], b.limbs[0..b.len()], a.limbs[0..a.len()]);
+ r.normalize(a.len());
}
}
@@ -1036,14 +1095,16 @@ pub const Int = struct {
// r = a ^ b
pub fn bitXor(r: *Int, a: Int, b: Int) !void {
- if (a.len > b.len) {
- try r.ensureCapacity(a.len);
- llxor(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]);
- r.normN(a.len);
+ r.assertWritable();
+
+ if (a.len() > b.len()) {
+ try r.ensureCapacity(a.len());
+ llxor(r.limbs[0..], a.limbs[0..a.len()], b.limbs[0..b.len()]);
+ r.normalize(a.len());
} else {
- try r.ensureCapacity(b.len);
- llxor(r.limbs[0..], b.limbs[0..b.len], a.limbs[0..a.len]);
- r.normN(b.len);
+ try r.ensureCapacity(b.len());
+ llxor(r.limbs[0..], b.limbs[0..b.len()], a.limbs[0..a.len()]);
+ r.normalize(b.len());
}
}
@@ -1067,7 +1128,9 @@ pub const Int = struct {
// They will still run on larger than this and should pass, but the multi-limb code-paths
// may be untested in some cases.
-const al = debug.global_allocator;
+var buffer: [64 * 8192]u8 = undefined;
+var fixed = std.heap.FixedBufferAllocator.init(buffer[0..]);
+const al = &fixed.allocator;
test "big.int comptime_int set" {
comptime var s = 0xefffffff00000001eeeeeeefaaaaaaab;
@@ -1088,14 +1151,14 @@ test "big.int comptime_int set negative" {
var a = try Int.initSet(al, -10);
testing.expect(a.limbs[0] == 10);
- testing.expect(a.positive == false);
+ testing.expect(a.isPositive() == false);
}
test "big.int int set unaligned small" {
var a = try Int.initSet(al, u7(45));
testing.expect(a.limbs[0] == 45);
- testing.expect(a.positive == true);
+ testing.expect(a.isPositive() == true);
}
test "big.int comptime_int to" {
@@ -1116,7 +1179,7 @@ test "big.int to target too small error" {
testing.expectError(error.TargetTooSmall, a.to(u8));
}
-test "big.int norm1" {
+test "big.int normalize" {
var a = try Int.init(al);
try a.ensureCapacity(8);
@@ -1124,26 +1187,26 @@ test "big.int norm1" {
a.limbs[1] = 2;
a.limbs[2] = 3;
a.limbs[3] = 0;
- a.norm1(4);
- testing.expect(a.len == 3);
+ a.normalize(4);
+ testing.expect(a.len() == 3);
a.limbs[0] = 1;
a.limbs[1] = 2;
a.limbs[2] = 3;
- a.norm1(3);
- testing.expect(a.len == 3);
+ a.normalize(3);
+ testing.expect(a.len() == 3);
a.limbs[0] = 0;
a.limbs[1] = 0;
- a.norm1(2);
- testing.expect(a.len == 1);
+ a.normalize(2);
+ testing.expect(a.len() == 1);
a.limbs[0] = 0;
- a.norm1(1);
- testing.expect(a.len == 1);
+ a.normalize(1);
+ testing.expect(a.len() == 1);
}
-test "big.int normN" {
+test "big.int normalize multi" {
var a = try Int.init(al);
try a.ensureCapacity(8);
@@ -1151,25 +1214,25 @@ test "big.int normN" {
a.limbs[1] = 2;
a.limbs[2] = 0;
a.limbs[3] = 0;
- a.normN(4);
- testing.expect(a.len == 2);
+ a.normalize(4);
+ testing.expect(a.len() == 2);
a.limbs[0] = 1;
a.limbs[1] = 2;
a.limbs[2] = 3;
- a.normN(3);
- testing.expect(a.len == 3);
+ a.normalize(3);
+ testing.expect(a.len() == 3);
a.limbs[0] = 0;
a.limbs[1] = 0;
a.limbs[2] = 0;
a.limbs[3] = 0;
- a.normN(4);
- testing.expect(a.len == 1);
+ a.normalize(4);
+ testing.expect(a.len() == 1);
a.limbs[0] = 0;
- a.normN(1);
- testing.expect(a.len == 1);
+ a.normalize(1);
+ testing.expect(a.len() == 1);
}
test "big.int parity" {
@@ -1204,7 +1267,7 @@ test "big.int bitcount + sizeInBase" {
try a.shiftLeft(a, 5000);
testing.expect(a.bitCountAbs() == 5032);
testing.expect(a.sizeInBase(2) >= 5032);
- a.positive = false;
+ a.setSign(false);
testing.expect(a.bitCountAbs() == 5032);
testing.expect(a.sizeInBase(2) >= 5033);
@@ -1980,6 +2043,98 @@ test "big.int div multi-multi (3.1/3.3 branch)" {
testing.expect((try r.to(u256)) == 0x1111111111111111111110b12222222222222222282);
}
+test "big.int div multi-single zero-limb trailing" {
+ var a = try Int.initSet(al, 0x60000000000000000000000000000000000000000000000000000000000000000);
+ var b = try Int.initSet(al, 0x10000000000000000);
+
+ var q = try Int.init(al);
+ var r = try Int.init(al);
+ try Int.divTrunc(&q, &r, a, b);
+
+ var expected = try Int.initSet(al, 0x6000000000000000000000000000000000000000000000000);
+ testing.expect(q.eq(expected));
+ testing.expect(r.eqZero());
+}
+
+test "big.int div multi-multi zero-limb trailing (with rem)" {
+ var a = try Int.initSet(al, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000);
+ var b = try Int.initSet(al, 0x8666666655555555444444443333333300000000000000000000000000000000);
+
+ var q = try Int.init(al);
+ var r = try Int.init(al);
+ try Int.divTrunc(&q, &r, a, b);
+
+ testing.expect((try q.to(u128)) == 0x10000000000000000);
+
+ const rs = try r.toString(al, 16);
+ testing.expect(std.mem.eql(u8, rs, "4444444344444443111111111111111100000000000000000000000000000000"));
+}
+
+test "big.int div multi-multi zero-limb trailing (with rem) and dividend zero-limb count > divisor zero-limb count" {
+ var a = try Int.initSet(al, 0x8666666655555555888888877777777611111111111111110000000000000000);
+ var b = try Int.initSet(al, 0x8666666655555555444444443333333300000000000000000000000000000000);
+
+ var q = try Int.init(al);
+ var r = try Int.init(al);
+ try Int.divTrunc(&q, &r, a, b);
+
+ testing.expect((try q.to(u128)) == 0x1);
+
+ const rs = try r.toString(al, 16);
+ testing.expect(std.mem.eql(u8, rs, "444444434444444311111111111111110000000000000000"));
+}
+
+test "big.int div multi-multi zero-limb trailing (with rem) and dividend zero-limb count < divisor zero-limb count" {
+ var a = try Int.initSet(al, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000);
+ var b = try Int.initSet(al, 0x866666665555555544444444333333330000000000000000);
+
+ var q = try Int.init(al);
+ var r = try Int.init(al);
+ try Int.divTrunc(&q, &r, a, b);
+
+ const qs = try q.toString(al, 16);
+ testing.expect(std.mem.eql(u8, qs, "10000000000000000820820803105186f"));
+
+ const rs = try r.toString(al, 16);
+ testing.expect(std.mem.eql(u8, rs, "4e11f2baa5896a321d463b543d0104e30000000000000000"));
+}
+
+test "big.int div multi-multi fuzz case #1" {
+ var a = try Int.init(al);
+ var b = try Int.init(al);
+
+ try a.setString(16, "ffffffffffffffffffffffffffffc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
+ try b.setString(16, "3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0000000000000000000000000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffc000000000000000000000000000000007fffffffffff");
+
+ var q = try Int.init(al);
+ var r = try Int.init(al);
+ try Int.divTrunc(&q, &r, a, b);
+
+ const qs = try q.toString(al, 16);
+ testing.expect(std.mem.eql(u8, qs, "3ffffffffffffffffffffffffffff0000000000000000000000000000000000001ffffffffffffffffffffffffffff7fffffffe000000000000000000000000000180000000000000000000003fffffbfffffffdfffffffffffffeffff800000100101000000100000000020003fffffdfbfffffe3ffffffffffffeffff7fffc00800a100000017ffe000002000400007efbfff7fe9f00000037ffff3fff7fffa004006100000009ffe00000190038200bf7d2ff7fefe80400060000f7d7f8fbf9401fe38e0403ffc0bdffffa51102c300d7be5ef9df4e5060007b0127ad3fa69f97d0f820b6605ff617ddf7f32ad7a05c0d03f2e7bc78a6000e087a8bbcdc59e07a5a079128a7861f553ddebed7e8e56701756f9ead39b48cd1b0831889ea6ec1fddf643d0565b075ff07e6caea4e2854ec9227fd635ed60a2f5eef2893052ffd54718fa08604acbf6a15e78a467c4a3c53c0278af06c4416573f925491b195e8fd79302cb1aaf7caf4ecfc9aec1254cc969786363ac729f914c6ddcc26738d6b0facd54eba026580aba2eb6482a088b0d224a8852420b91ec1"));
+
+ const rs = try r.toString(al, 16);
+ testing.expect(std.mem.eql(u8, rs, "310d1d4c414426b4836c2635bad1df3a424e50cbdd167ffccb4dfff57d36b4aae0d6ca0910698220171a0f3373c1060a046c2812f0027e321f72979daa5e7973214170d49e885de0c0ecc167837d44502430674a82522e5df6a0759548052420b91ec1"));
+}
+
+test "big.int div multi-multi fuzz case #2" {
+ var a = try Int.init(al);
+ var b = try Int.init(al);
+
+ try a.setString(16, "3ffffffffe00000000000000000000000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffe000000000000000000000000000000000000000000000000000000000000001fffffffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffc000000000000000000000000000000000000000000000000000000000000000");
+ try b.setString(16, "ffc0000000000000000000000000000000000000000000000000");
+
+ var q = try Int.init(al);
+ var r = try Int.init(al);
+ try Int.divTrunc(&q, &r, a, b);
+
+ const qs = try q.toString(al, 16);
+ testing.expect(std.mem.eql(u8, qs, "40100400fe3f8fe3f8fe3f8fe3f8fe3f8fe4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f91e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4992649926499264991e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4792e4b92e4b92e4b92e4b92a4a92a4a92a4"));
+
+ const rs = try r.toString(al, 16);
+ testing.expect(std.mem.eql(u8, rs, "a900000000000000000000000000000000000000000000000000"));
+}
+
test "big.int shift-right single" {
var a = try Int.initSet(al, 0xffff0000);
try a.shiftRight(a, 16);
diff --git a/std/math/big/rational.zig b/std/math/big/rational.zig
new file mode 100644
index 0000000000..34cf3bf764
--- /dev/null
+++ b/std/math/big/rational.zig
@@ -0,0 +1,896 @@
+const std = @import("../../std.zig");
+const builtin = @import("builtin");
+const debug = std.debug;
+const math = std.math;
+const mem = std.mem;
+const testing = std.testing;
+const Allocator = mem.Allocator;
+const ArrayList = std.ArrayList;
+
+const TypeId = builtin.TypeId;
+
+const bn = @import("int.zig");
+const Limb = bn.Limb;
+const DoubleLimb = bn.DoubleLimb;
+const Int = bn.Int;
+
+pub const Rational = struct {
+ // Sign of Rational is sign of p. Sign of q is ignored
+ p: Int,
+ q: Int,
+
+ pub fn init(a: *Allocator) !Rational {
+ return Rational{
+ .p = try Int.init(a),
+ .q = try Int.initSet(a, 1),
+ };
+ }
+
+ pub fn deinit(self: *Rational) void {
+ self.p.deinit();
+ self.q.deinit();
+ }
+
+ pub fn setInt(self: *Rational, a: var) !void {
+ try self.p.set(a);
+ try self.q.set(1);
+ }
+
+ // TODO: Accept a/b fractions and exponent form
+ pub fn setFloatString(self: *Rational, str: []const u8) !void {
+ if (str.len == 0) {
+ return error.InvalidFloatString;
+ }
+
+ const State = enum {
+ Integer,
+ Fractional,
+ };
+
+ var state = State.Integer;
+ var point: ?usize = null;
+
+ var start: usize = 0;
+ if (str[0] == '-') {
+ start += 1;
+ }
+
+ for (str) |c, i| {
+ switch (state) {
+ State.Integer => {
+ switch (c) {
+ '.' => {
+ state = State.Fractional;
+ point = i;
+ },
+ '0'...'9' => {
+ // okay
+ },
+ else => {
+ return error.InvalidFloatString;
+ },
+ }
+ },
+ State.Fractional => {
+ switch (c) {
+ '0'...'9' => {
+ // okay
+ },
+ else => {
+ return error.InvalidFloatString;
+ },
+ }
+ },
+ }
+ }
+
+ // TODO: batch the multiplies by 10
+ if (point) |i| {
+ try self.p.setString(10, str[0..i]);
+
+ const base = Int.initFixed(([]Limb{10})[0..]);
+
+ var j: usize = start;
+ while (j < str.len - i - 1) : (j += 1) {
+ try self.p.mul(self.p, base);
+ }
+
+ try self.q.setString(10, str[i + 1 ..]);
+ try self.p.add(self.p, self.q);
+
+ try self.q.set(1);
+ var k: usize = i + 1;
+ while (k < str.len) : (k += 1) {
+ try self.q.mul(self.q, base);
+ }
+
+ try self.reduce();
+ } else {
+ try self.p.setString(10, str[0..]);
+ try self.q.set(1);
+ }
+ }
+
+ // Translated from golang.go/src/math/big/rat.go.
+ pub fn setFloat(self: *Rational, comptime T: type, f: T) !void {
+ debug.assert(@typeId(T) == builtin.TypeId.Float);
+
+ const UnsignedIntType = @IntType(false, T.bit_count);
+ const f_bits = @bitCast(UnsignedIntType, f);
+
+ const exponent_bits = math.floatExponentBits(T);
+ const exponent_bias = (1 << (exponent_bits - 1)) - 1;
+ const mantissa_bits = math.floatMantissaBits(T);
+
+ const exponent_mask = (1 << exponent_bits) - 1;
+ const mantissa_mask = (1 << mantissa_bits) - 1;
+
+ var exponent = @intCast(i16, (f_bits >> mantissa_bits) & exponent_mask);
+ var mantissa = f_bits & mantissa_mask;
+
+ switch (exponent) {
+ exponent_mask => {
+ return error.NonFiniteFloat;
+ },
+ 0 => {
+ // denormal
+ exponent -= exponent_bias - 1;
+ },
+ else => {
+ // normal
+ mantissa |= 1 << mantissa_bits;
+ exponent -= exponent_bias;
+ },
+ }
+
+ var shift: i16 = mantissa_bits - exponent;
+
+ // factor out powers of two early from rational
+ while (mantissa & 1 == 0 and shift > 0) {
+ mantissa >>= 1;
+ shift -= 1;
+ }
+
+ try self.p.set(mantissa);
+ self.p.setSign(f >= 0);
+
+ try self.q.set(1);
+ if (shift >= 0) {
+ try self.q.shiftLeft(self.q, @intCast(usize, shift));
+ } else {
+ try self.p.shiftLeft(self.p, @intCast(usize, -shift));
+ }
+
+ try self.reduce();
+ }
+
+ // Translated from golang.go/src/math/big/rat.go.
+ pub fn toFloat(self: Rational, comptime T: type) !T {
+ debug.assert(@typeId(T) == builtin.TypeId.Float);
+
+ const fsize = T.bit_count;
+ const BitReprType = @IntType(false, T.bit_count);
+
+ const msize = math.floatMantissaBits(T);
+ const msize1 = msize + 1;
+ const msize2 = msize1 + 1;
+
+ const esize = math.floatExponentBits(T);
+ const ebias = (1 << (esize - 1)) - 1;
+ const emin = 1 - ebias;
+ const emax = ebias;
+
+ if (self.p.eqZero()) {
+ return 0;
+ }
+
+ // 1. left-shift a or sub so that a/b is in [1 << msize1, 1 << (msize2 + 1)]
+ var exp = @intCast(isize, self.p.bitCountTwosComp()) - @intCast(isize, self.q.bitCountTwosComp());
+
+ var a2 = try self.p.clone();
+ defer a2.deinit();
+
+ var b2 = try self.q.clone();
+ defer b2.deinit();
+
+ const shift = msize2 - exp;
+ if (shift >= 0) {
+ try a2.shiftLeft(a2, @intCast(usize, shift));
+ } else {
+ try b2.shiftLeft(b2, @intCast(usize, -shift));
+ }
+
+ // 2. compute quotient and remainder
+ var q = try Int.init(self.p.allocator.?);
+ defer q.deinit();
+
+ // unused
+ var r = try Int.init(self.p.allocator.?);
+ defer r.deinit();
+
+ try Int.divTrunc(&q, &r, a2, b2);
+
+ var mantissa = extractLowBits(q, BitReprType);
+ var have_rem = r.len() > 0;
+
+ // 3. q didn't fit in msize2 bits, redo division b2 << 1
+ if (mantissa >> msize2 == 1) {
+ if (mantissa & 1 == 1) {
+ have_rem = true;
+ }
+ mantissa >>= 1;
+ exp += 1;
+ }
+ if (mantissa >> msize1 != 1) {
+ // NOTE: This can be hit if the limb size is small (u8/16).
+ @panic("unexpected bits in result");
+ }
+
+ // 4. Rounding
+ if (emin - msize <= exp and exp <= emin) {
+ // denormal
+ const shift1 = @intCast(math.Log2Int(BitReprType), emin - (exp - 1));
+ const lost_bits = mantissa & ((@intCast(BitReprType, 1) << shift1) - 1);
+ have_rem = have_rem or lost_bits != 0;
+ mantissa >>= shift1;
+ exp = 2 - ebias;
+ }
+
+ // round q using round-half-to-even
+ var exact = !have_rem;
+ if (mantissa & 1 != 0) {
+ exact = false;
+ if (have_rem or (mantissa & 2 != 0)) {
+ mantissa += 1;
+ if (mantissa >= 1 << msize2) {
+ // 11...1 => 100...0
+ mantissa >>= 1;
+ exp += 1;
+ }
+ }
+ }
+ mantissa >>= 1;
+
+ const f = math.scalbn(@intToFloat(T, mantissa), @intCast(i32, exp - msize1));
+ if (math.isInf(f)) {
+ exact = false;
+ }
+
+ return if (self.p.isPositive()) f else -f;
+ }
+
+ pub fn setRatio(self: *Rational, p: var, q: var) !void {
+ try self.p.set(p);
+ try self.q.set(q);
+
+ self.p.setSign(@boolToInt(self.p.isPositive()) ^ @boolToInt(self.q.isPositive()) == 0);
+ self.q.setSign(true);
+
+ try self.reduce();
+
+ if (self.q.eqZero()) {
+ @panic("cannot set rational with denominator = 0");
+ }
+ }
+
+ pub fn copyInt(self: *Rational, a: Int) !void {
+ try self.p.copy(a);
+ try self.q.set(1);
+ }
+
+ pub fn copyRatio(self: *Rational, a: Int, b: Int) !void {
+ try self.p.copy(a);
+ try self.q.copy(b);
+
+ self.p.setSign(@boolToInt(self.p.isPositive()) ^ @boolToInt(self.q.isPositive()) == 0);
+ self.q.setSign(true);
+
+ try self.reduce();
+ }
+
+ pub fn abs(r: *Rational) void {
+ r.p.abs();
+ }
+
+ pub fn negate(r: *Rational) void {
+ r.p.negate();
+ }
+
+ pub fn swap(r: *Rational, other: *Rational) void {
+ r.p.swap(&other.p);
+ r.q.swap(&other.q);
+ }
+
+ pub fn cmp(a: Rational, b: Rational) !i8 {
+ return cmpInternal(a, b, true);
+ }
+
+ pub fn cmpAbs(a: Rational, b: Rational) !i8 {
+ return cmpInternal(a, b, false);
+ }
+
+ // p/q > x/y iff p*y > x*q
+ fn cmpInternal(a: Rational, b: Rational, is_abs: bool) !i8 {
+ // TODO: Would a div compare algorithm of sorts be viable and quicker? Can we avoid
+ // the memory allocations here?
+ var q = try Int.init(a.p.allocator.?);
+ defer q.deinit();
+
+ var p = try Int.init(b.p.allocator.?);
+ defer p.deinit();
+
+ try q.mul(a.p, b.q);
+ try p.mul(b.p, a.q);
+
+ return if (is_abs) q.cmpAbs(p) else q.cmp(p);
+ }
+
+ // r/q = ap/aq + bp/bq = (ap*bq + bp*aq) / (aq*bq)
+ //
+ // For best performance, rma should not alias a or b.
+ pub fn add(rma: *Rational, a: Rational, b: Rational) !void {
+ var r = rma;
+ var aliased = rma.p.limbs.ptr == a.p.limbs.ptr or rma.p.limbs.ptr == b.p.limbs.ptr;
+
+ var sr: Rational = undefined;
+ if (aliased) {
+ sr = try Rational.init(rma.p.allocator.?);
+ r = &sr;
+ aliased = true;
+ }
+ defer if (aliased) {
+ rma.swap(r);
+ r.deinit();
+ };
+
+ try r.p.mul(a.p, b.q);
+ try r.q.mul(b.p, a.q);
+ try r.p.add(r.p, r.q);
+
+ try r.q.mul(a.q, b.q);
+ try r.reduce();
+ }
+
+ // r/q = ap/aq - bp/bq = (ap*bq - bp*aq) / (aq*bq)
+ //
+ // For best performance, rma should not alias a or b.
+ pub fn sub(rma: *Rational, a: Rational, b: Rational) !void {
+ var r = rma;
+ var aliased = rma.p.limbs.ptr == a.p.limbs.ptr or rma.p.limbs.ptr == b.p.limbs.ptr;
+
+ var sr: Rational = undefined;
+ if (aliased) {
+ sr = try Rational.init(rma.p.allocator.?);
+ r = &sr;
+ aliased = true;
+ }
+ defer if (aliased) {
+ rma.swap(r);
+ r.deinit();
+ };
+
+ try r.p.mul(a.p, b.q);
+ try r.q.mul(b.p, a.q);
+ try r.p.sub(r.p, r.q);
+
+ try r.q.mul(a.q, b.q);
+ try r.reduce();
+ }
+
+ // r/q = ap/aq * bp/bq = ap*bp / aq*bq
+ pub fn mul(r: *Rational, a: Rational, b: Rational) !void {
+ try r.p.mul(a.p, b.p);
+ try r.q.mul(a.q, b.q);
+ try r.reduce();
+ }
+
+ // r/q = (ap/aq) / (bp/bq) = ap*bq / bp*aq
+ pub fn div(r: *Rational, a: Rational, b: Rational) !void {
+ if (b.p.eqZero()) {
+ @panic("division by zero");
+ }
+
+ try r.p.mul(a.p, b.q);
+ try r.q.mul(b.p, a.q);
+ try r.reduce();
+ }
+
+ // r/q = q/r
+ pub fn invert(r: *Rational) void {
+ Int.swap(&r.p, &r.q);
+ }
+
+ // reduce r/q such that gcd(r, q) = 1
+ fn reduce(r: *Rational) !void {
+ var a = try Int.init(r.p.allocator.?);
+ defer a.deinit();
+
+ const sign = r.p.isPositive();
+ r.p.abs();
+ try gcd(&a, r.p, r.q);
+ r.p.setSign(sign);
+
+ const one = Int.initFixed(([]Limb{1})[0..]);
+ if (a.cmp(one) != 0) {
+ var unused = try Int.init(r.p.allocator.?);
+ defer unused.deinit();
+
+ // TODO: divexact would be useful here
+ // TODO: don't copy r.q for div
+ try Int.divTrunc(&r.p, &unused, r.p, a);
+ try Int.divTrunc(&r.q, &unused, r.q, a);
+ }
+ }
+};
+
+const SignedDoubleLimb = @IntType(true, DoubleLimb.bit_count);
+
+fn gcd(rma: *Int, x: Int, y: Int) !void {
+ rma.assertWritable();
+ var r = rma;
+ var aliased = rma.limbs.ptr == x.limbs.ptr or rma.limbs.ptr == y.limbs.ptr;
+
+ var sr: Int = undefined;
+ if (aliased) {
+ sr = try Int.initCapacity(rma.allocator.?, math.max(x.len(), y.len()));
+ r = &sr;
+ aliased = true;
+ }
+ defer if (aliased) {
+ rma.swap(r);
+ r.deinit();
+ };
+
+ try gcdLehmer(r, x, y);
+}
+
+// Storage must live for the lifetime of the returned value
+fn FixedIntFromSignedDoubleLimb(A: SignedDoubleLimb, storage: []Limb) Int {
+ std.debug.assert(storage.len >= 2);
+
+ var A_is_positive = A >= 0;
+ const Au = @intCast(DoubleLimb, if (A < 0) -A else A);
+ storage[0] = @truncate(Limb, Au);
+ storage[1] = @truncate(Limb, Au >> Limb.bit_count);
+ var Ap = Int.initFixed(storage[0..2]);
+ Ap.setSign(A_is_positive);
+ return Ap;
+}
+
+fn gcdLehmer(r: *Int, xa: Int, ya: Int) !void {
+ var x = try xa.clone();
+ x.abs();
+ defer x.deinit();
+
+ var y = try ya.clone();
+ y.abs();
+ defer y.deinit();
+
+ if (x.cmp(y) < 0) {
+ x.swap(&y);
+ }
+
+ var T = try Int.init(r.allocator.?);
+ defer T.deinit();
+
+ while (y.len() > 1) {
+ debug.assert(x.isPositive() and y.isPositive());
+ debug.assert(x.len() >= y.len());
+
+ var xh: SignedDoubleLimb = x.limbs[x.len() - 1];
+ var yh: SignedDoubleLimb = if (x.len() > y.len()) 0 else y.limbs[x.len() - 1];
+
+ var A: SignedDoubleLimb = 1;
+ var B: SignedDoubleLimb = 0;
+ var C: SignedDoubleLimb = 0;
+ var D: SignedDoubleLimb = 1;
+
+ while (yh + C != 0 and yh + D != 0) {
+ const q = @divFloor(xh + A, yh + C);
+ const qp = @divFloor(xh + B, yh + D);
+ if (q != qp) {
+ break;
+ }
+
+ var t = A - q * C;
+ A = C;
+ C = t;
+ t = B - q * D;
+ B = D;
+ D = t;
+
+ t = xh - q * yh;
+ xh = yh;
+ yh = t;
+ }
+
+ if (B == 0) {
+ // T = x % y, r is unused
+ try Int.divTrunc(r, &T, x, y);
+ debug.assert(T.isPositive());
+
+ x.swap(&y);
+ y.swap(&T);
+ } else {
+ var storage: [8]Limb = undefined;
+ const Ap = FixedIntFromSignedDoubleLimb(A, storage[0..2]);
+ const Bp = FixedIntFromSignedDoubleLimb(B, storage[2..4]);
+ const Cp = FixedIntFromSignedDoubleLimb(C, storage[4..6]);
+ const Dp = FixedIntFromSignedDoubleLimb(D, storage[6..8]);
+
+ // T = Ax + By
+ try r.mul(x, Ap);
+ try T.mul(y, Bp);
+ try T.add(r.*, T);
+
+ // u = Cx + Dy, r as u
+ try x.mul(x, Cp);
+ try r.mul(y, Dp);
+ try r.add(x, r.*);
+
+ x.swap(&T);
+ y.swap(r);
+ }
+ }
+
+ // euclidean algorithm
+ debug.assert(x.cmp(y) >= 0);
+
+ while (!y.eqZero()) {
+ try Int.divTrunc(&T, r, x, y);
+ x.swap(&y);
+ y.swap(r);
+ }
+
+ r.swap(&x);
+}
+
+var buffer: [64 * 8192]u8 = undefined;
+var fixed = std.heap.FixedBufferAllocator.init(buffer[0..]);
+var al = &fixed.allocator;
+
+test "big.rational gcd non-one small" {
+ var a = try Int.initSet(al, 17);
+ var b = try Int.initSet(al, 97);
+ var r = try Int.init(al);
+
+ try gcd(&r, a, b);
+
+ testing.expect((try r.to(u32)) == 1);
+}
+
+test "big.rational gcd non-one small" {
+ var a = try Int.initSet(al, 4864);
+ var b = try Int.initSet(al, 3458);
+ var r = try Int.init(al);
+
+ try gcd(&r, a, b);
+
+ testing.expect((try r.to(u32)) == 38);
+}
+
+test "big.rational gcd non-one large" {
+ var a = try Int.initSet(al, 0xffffffffffffffff);
+ var b = try Int.initSet(al, 0xffffffffffffffff7777);
+ var r = try Int.init(al);
+
+ try gcd(&r, a, b);
+
+ testing.expect((try r.to(u32)) == 4369);
+}
+
+test "big.rational gcd large multi-limb result" {
+ var a = try Int.initSet(al, 0x12345678123456781234567812345678123456781234567812345678);
+ var b = try Int.initSet(al, 0x12345671234567123456712345671234567123456712345671234567);
+ var r = try Int.init(al);
+
+ try gcd(&r, a, b);
+
+ testing.expect((try r.to(u256)) == 0xf000000ff00000fff0000ffff000fffff00ffffff1);
+}
+
+test "big.rational gcd one large" {
+ var a = try Int.initSet(al, 1897056385327307);
+ var b = try Int.initSet(al, 2251799813685248);
+ var r = try Int.init(al);
+
+ try gcd(&r, a, b);
+
+ testing.expect((try r.to(u64)) == 1);
+}
+
+fn extractLowBits(a: Int, comptime T: type) T {
+ testing.expect(@typeId(T) == builtin.TypeId.Int);
+
+ if (T.bit_count <= Limb.bit_count) {
+ return @truncate(T, a.limbs[0]);
+ } else {
+ var r: T = 0;
+ comptime var i: usize = 0;
+
+ // Remainder is always 0 since if T.bit_count >= Limb.bit_count -> Limb | T and both
+ // are powers of two.
+ inline while (i < T.bit_count / Limb.bit_count) : (i += 1) {
+ r |= math.shl(T, a.limbs[i], i * Limb.bit_count);
+ }
+
+ return r;
+ }
+}
+
+test "big.rational extractLowBits" {
+ var a = try Int.initSet(al, 0x11112222333344441234567887654321);
+
+ const a1 = extractLowBits(a, u8);
+ testing.expect(a1 == 0x21);
+
+ const a2 = extractLowBits(a, u16);
+ testing.expect(a2 == 0x4321);
+
+ const a3 = extractLowBits(a, u32);
+ testing.expect(a3 == 0x87654321);
+
+ const a4 = extractLowBits(a, u64);
+ testing.expect(a4 == 0x1234567887654321);
+
+ const a5 = extractLowBits(a, u128);
+ testing.expect(a5 == 0x11112222333344441234567887654321);
+}
+
+test "big.rational set" {
+ var a = try Rational.init(al);
+
+ try a.setInt(5);
+ testing.expect((try a.p.to(u32)) == 5);
+ testing.expect((try a.q.to(u32)) == 1);
+
+ try a.setRatio(7, 3);
+ testing.expect((try a.p.to(u32)) == 7);
+ testing.expect((try a.q.to(u32)) == 3);
+
+ try a.setRatio(9, 3);
+ testing.expect((try a.p.to(i32)) == 3);
+ testing.expect((try a.q.to(i32)) == 1);
+
+ try a.setRatio(-9, 3);
+ testing.expect((try a.p.to(i32)) == -3);
+ testing.expect((try a.q.to(i32)) == 1);
+
+ try a.setRatio(9, -3);
+ testing.expect((try a.p.to(i32)) == -3);
+ testing.expect((try a.q.to(i32)) == 1);
+
+ try a.setRatio(-9, -3);
+ testing.expect((try a.p.to(i32)) == 3);
+ testing.expect((try a.q.to(i32)) == 1);
+}
+
+test "big.rational setFloat" {
+ var a = try Rational.init(al);
+
+ try a.setFloat(f64, 2.5);
+ testing.expect((try a.p.to(i32)) == 5);
+ testing.expect((try a.q.to(i32)) == 2);
+
+ try a.setFloat(f32, -2.5);
+ testing.expect((try a.p.to(i32)) == -5);
+ testing.expect((try a.q.to(i32)) == 2);
+
+ try a.setFloat(f32, 3.141593);
+
+ // = 3.14159297943115234375
+ testing.expect((try a.p.to(u32)) == 3294199);
+ testing.expect((try a.q.to(u32)) == 1048576);
+
+ try a.setFloat(f64, 72.141593120712409172417410926841290461290467124);
+
+ // = 72.1415931207124145885245525278151035308837890625
+ testing.expect((try a.p.to(u128)) == 5076513310880537);
+ testing.expect((try a.q.to(u128)) == 70368744177664);
+}
+
+test "big.rational setFloatString" {
+ var a = try Rational.init(al);
+
+ try a.setFloatString("72.14159312071241458852455252781510353");
+
+ // = 72.1415931207124145885245525278151035308837890625
+ testing.expect((try a.p.to(u128)) == 7214159312071241458852455252781510353);
+ testing.expect((try a.q.to(u128)) == 100000000000000000000000000000000000);
+}
+
+test "big.rational toFloat" {
+ var a = try Rational.init(al);
+
+ // = 3.14159297943115234375
+ try a.setRatio(3294199, 1048576);
+ testing.expect((try a.toFloat(f64)) == 3.14159297943115234375);
+
+ // = 72.1415931207124145885245525278151035308837890625
+ try a.setRatio(5076513310880537, 70368744177664);
+ testing.expect((try a.toFloat(f64)) == 72.141593120712409172417410926841290461290467124);
+}
+
+test "big.rational set/to Float round-trip" {
+ var a = try Rational.init(al);
+ var prng = std.rand.DefaultPrng.init(0x5EED);
+ var i: usize = 0;
+ while (i < 512) : (i += 1) {
+ const r = prng.random.float(f64);
+ try a.setFloat(f64, r);
+ testing.expect((try a.toFloat(f64)) == r);
+ }
+}
+
+test "big.rational copy" {
+ var a = try Rational.init(al);
+
+ const b = try Int.initSet(al, 5);
+
+ try a.copyInt(b);
+ testing.expect((try a.p.to(u32)) == 5);
+ testing.expect((try a.q.to(u32)) == 1);
+
+ const c = try Int.initSet(al, 7);
+ const d = try Int.initSet(al, 3);
+
+ try a.copyRatio(c, d);
+ testing.expect((try a.p.to(u32)) == 7);
+ testing.expect((try a.q.to(u32)) == 3);
+
+ const e = try Int.initSet(al, 9);
+ const f = try Int.initSet(al, 3);
+
+ try a.copyRatio(e, f);
+ testing.expect((try a.p.to(u32)) == 3);
+ testing.expect((try a.q.to(u32)) == 1);
+}
+
+test "big.rational negate" {
+ var a = try Rational.init(al);
+
+ try a.setInt(-50);
+ testing.expect((try a.p.to(i32)) == -50);
+ testing.expect((try a.q.to(i32)) == 1);
+
+ a.negate();
+ testing.expect((try a.p.to(i32)) == 50);
+ testing.expect((try a.q.to(i32)) == 1);
+
+ a.negate();
+ testing.expect((try a.p.to(i32)) == -50);
+ testing.expect((try a.q.to(i32)) == 1);
+}
+
+test "big.rational abs" {
+ var a = try Rational.init(al);
+
+ try a.setInt(-50);
+ testing.expect((try a.p.to(i32)) == -50);
+ testing.expect((try a.q.to(i32)) == 1);
+
+ a.abs();
+ testing.expect((try a.p.to(i32)) == 50);
+ testing.expect((try a.q.to(i32)) == 1);
+
+ a.abs();
+ testing.expect((try a.p.to(i32)) == 50);
+ testing.expect((try a.q.to(i32)) == 1);
+}
+
+test "big.rational swap" {
+ var a = try Rational.init(al);
+ var b = try Rational.init(al);
+
+ try a.setRatio(50, 23);
+ try b.setRatio(17, 3);
+
+ testing.expect((try a.p.to(u32)) == 50);
+ testing.expect((try a.q.to(u32)) == 23);
+
+ testing.expect((try b.p.to(u32)) == 17);
+ testing.expect((try b.q.to(u32)) == 3);
+
+ a.swap(&b);
+
+ testing.expect((try a.p.to(u32)) == 17);
+ testing.expect((try a.q.to(u32)) == 3);
+
+ testing.expect((try b.p.to(u32)) == 50);
+ testing.expect((try b.q.to(u32)) == 23);
+}
+
+test "big.rational cmp" {
+ var a = try Rational.init(al);
+ var b = try Rational.init(al);
+
+ try a.setRatio(500, 231);
+ try b.setRatio(18903, 8584);
+ testing.expect((try a.cmp(b)) < 0);
+
+ try a.setRatio(890, 10);
+ try b.setRatio(89, 1);
+ testing.expect((try a.cmp(b)) == 0);
+}
+
+test "big.rational add single-limb" {
+ var a = try Rational.init(al);
+ var b = try Rational.init(al);
+
+ try a.setRatio(500, 231);
+ try b.setRatio(18903, 8584);
+ testing.expect((try a.cmp(b)) < 0);
+
+ try a.setRatio(890, 10);
+ try b.setRatio(89, 1);
+ testing.expect((try a.cmp(b)) == 0);
+}
+
+test "big.rational add" {
+ var a = try Rational.init(al);
+ var b = try Rational.init(al);
+ var r = try Rational.init(al);
+
+ try a.setRatio(78923, 23341);
+ try b.setRatio(123097, 12441414);
+ try a.add(a, b);
+
+ try r.setRatio(984786924199, 290395044174);
+ testing.expect((try a.cmp(r)) == 0);
+}
+
+test "big.rational sub" {
+ var a = try Rational.init(al);
+ var b = try Rational.init(al);
+ var r = try Rational.init(al);
+
+ try a.setRatio(78923, 23341);
+ try b.setRatio(123097, 12441414);
+ try a.sub(a, b);
+
+ try r.setRatio(979040510045, 290395044174);
+ testing.expect((try a.cmp(r)) == 0);
+}
+
+test "big.rational mul" {
+ var a = try Rational.init(al);
+ var b = try Rational.init(al);
+ var r = try Rational.init(al);
+
+ try a.setRatio(78923, 23341);
+ try b.setRatio(123097, 12441414);
+ try a.mul(a, b);
+
+ try r.setRatio(571481443, 17082061422);
+ testing.expect((try a.cmp(r)) == 0);
+}
+
+test "big.rational div" {
+ var a = try Rational.init(al);
+ var b = try Rational.init(al);
+ var r = try Rational.init(al);
+
+ try a.setRatio(78923, 23341);
+ try b.setRatio(123097, 12441414);
+ try a.div(a, b);
+
+ try r.setRatio(75531824394, 221015929);
+ testing.expect((try a.cmp(r)) == 0);
+}
+
+test "big.rational div" {
+ var a = try Rational.init(al);
+ var r = try Rational.init(al);
+
+ try a.setRatio(78923, 23341);
+ a.invert();
+
+ try r.setRatio(23341, 78923);
+ testing.expect((try a.cmp(r)) == 0);
+
+ try a.setRatio(-78923, 23341);
+ a.invert();
+
+ try r.setRatio(-23341, 78923);
+ testing.expect((try a.cmp(r)) == 0);
+}
diff --git a/std/special/compiler_rt.zig b/std/special/compiler_rt.zig
index f15cf42be2..e2ecd1b0cf 100644
--- a/std/special/compiler_rt.zig
+++ b/std/special/compiler_rt.zig
@@ -160,10 +160,11 @@ comptime {
@export("__chkstk", __chkstk, strong_linkage);
@export("___chkstk_ms", ___chkstk_ms, linkage);
}
+ // The "ti" functions must use @Vector(2, u64) parameter types to adhere to the ABI
+ // that LLVM expects compiler-rt to have.
@export("__divti3", @import("compiler_rt/divti3.zig").__divti3_windows_x86_64, linkage);
@export("__modti3", @import("compiler_rt/modti3.zig").__modti3_windows_x86_64, linkage);
@export("__multi3", @import("compiler_rt/multi3.zig").__multi3_windows_x86_64, linkage);
- @export("__muloti4", @import("compiler_rt/muloti4.zig").__muloti4_windows_x86_64, linkage);
@export("__udivti3", @import("compiler_rt/udivti3.zig").__udivti3_windows_x86_64, linkage);
@export("__udivmodti4", @import("compiler_rt/udivmodti4.zig").__udivmodti4_windows_x86_64, linkage);
@export("__umodti3", @import("compiler_rt/umodti3.zig").__umodti3_windows_x86_64, linkage);
@@ -174,11 +175,11 @@ comptime {
@export("__divti3", @import("compiler_rt/divti3.zig").__divti3, linkage);
@export("__modti3", @import("compiler_rt/modti3.zig").__modti3, linkage);
@export("__multi3", @import("compiler_rt/multi3.zig").__multi3, linkage);
- @export("__muloti4", @import("compiler_rt/muloti4.zig").__muloti4, linkage);
@export("__udivti3", @import("compiler_rt/udivti3.zig").__udivti3, linkage);
@export("__udivmodti4", @import("compiler_rt/udivmodti4.zig").__udivmodti4, linkage);
@export("__umodti3", @import("compiler_rt/umodti3.zig").__umodti3, linkage);
}
+ @export("__muloti4", @import("compiler_rt/muloti4.zig").__muloti4, linkage);
}
const std = @import("std");
@@ -198,17 +199,6 @@ pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn
}
}
-pub fn setXmm0(comptime T: type, value: T) void {
- comptime assert(builtin.arch == builtin.Arch.x86_64);
- const aligned_value: T align(16) = value;
- asm volatile (
- \\movaps (%[ptr]), %%xmm0
- :
- : [ptr] "r" (&aligned_value)
- : "xmm0"
- );
-}
-
extern fn __udivdi3(a: u64, b: u64) u64 {
@setRuntimeSafety(is_test);
return __udivmoddi4(a, b, null);
diff --git a/std/special/compiler_rt/divti3.zig b/std/special/compiler_rt/divti3.zig
index e89a1ada5c..d5b2778a34 100644
--- a/std/special/compiler_rt/divti3.zig
+++ b/std/special/compiler_rt/divti3.zig
@@ -16,9 +16,9 @@ pub extern fn __divti3(a: i128, b: i128) i128 {
return (@bitCast(i128, r) ^ s) -% s;
}
-pub extern fn __divti3_windows_x86_64(a: *const i128, b: *const i128) void {
- @setRuntimeSafety(builtin.is_test);
- compiler_rt.setXmm0(i128, __divti3(a.*, b.*));
+const v128 = @Vector(2, u64);
+pub extern fn __divti3_windows_x86_64(a: v128, b: v128) v128 {
+ return @bitCast(v128, @inlineCall(__divti3, @bitCast(i128, a), @bitCast(i128, b)));
}
test "import divti3" {
diff --git a/std/special/compiler_rt/modti3.zig b/std/special/compiler_rt/modti3.zig
index 03222cadf5..16f2f38ba3 100644
--- a/std/special/compiler_rt/modti3.zig
+++ b/std/special/compiler_rt/modti3.zig
@@ -20,9 +20,9 @@ pub extern fn __modti3(a: i128, b: i128) i128 {
return (@bitCast(i128, r) ^ s_a) -% s_a; // negate if s == -1
}
-pub extern fn __modti3_windows_x86_64(a: *const i128, b: *const i128) void {
- @setRuntimeSafety(builtin.is_test);
- compiler_rt.setXmm0(i128, __modti3(a.*, b.*));
+const v128 = @Vector(2, u64);
+pub extern fn __modti3_windows_x86_64(a: v128, b: v128) v128 {
+ return @bitCast(v128, @inlineCall(__modti3, @bitCast(i128, a), @bitCast(i128, b)));
}
test "import modti3" {
diff --git a/std/special/compiler_rt/muloti4.zig b/std/special/compiler_rt/muloti4.zig
index fd6855072b..ccde8e3e6c 100644
--- a/std/special/compiler_rt/muloti4.zig
+++ b/std/special/compiler_rt/muloti4.zig
@@ -1,4 +1,3 @@
-const udivmod = @import("udivmod.zig").udivmod;
const builtin = @import("builtin");
const compiler_rt = @import("../compiler_rt.zig");
@@ -33,11 +32,11 @@ pub extern fn __muloti4(a: i128, b: i128, overflow: *c_int) i128 {
}
if (sa == sb) {
- if (abs_a > @divFloor(max, abs_b)) {
+ if (abs_a > @divTrunc(max, abs_b)) {
overflow.* = 1;
}
} else {
- if (abs_a > @divFloor(min, -abs_b)) {
+ if (abs_a > @divTrunc(min, -abs_b)) {
overflow.* = 1;
}
}
@@ -45,11 +44,6 @@ pub extern fn __muloti4(a: i128, b: i128, overflow: *c_int) i128 {
return r;
}
-pub extern fn __muloti4_windows_x86_64(a: *const i128, b: *const i128, overflow: *c_int) void {
- @setRuntimeSafety(builtin.is_test);
- compiler_rt.setXmm0(i128, __muloti4(a.*, b.*, overflow));
-}
-
test "import muloti4" {
_ = @import("muloti4_test.zig");
}
diff --git a/std/special/compiler_rt/multi3.zig b/std/special/compiler_rt/multi3.zig
index a0c84adaf4..799b1f575d 100644
--- a/std/special/compiler_rt/multi3.zig
+++ b/std/special/compiler_rt/multi3.zig
@@ -14,9 +14,9 @@ pub extern fn __multi3(a: i128, b: i128) i128 {
return r.all;
}
-pub extern fn __multi3_windows_x86_64(a: *const i128, b: *const i128) void {
- @setRuntimeSafety(builtin.is_test);
- compiler_rt.setXmm0(i128, __multi3(a.*, b.*));
+const v128 = @Vector(2, u64);
+pub extern fn __multi3_windows_x86_64(a: v128, b: v128) v128 {
+ return @bitCast(v128, @inlineCall(__multi3, @bitCast(i128, a), @bitCast(i128, b)));
}
fn __mulddi3(a: u64, b: u64) i128 {
diff --git a/std/special/compiler_rt/udivmodti4.zig b/std/special/compiler_rt/udivmodti4.zig
index 6a037d3bae..c74dff512d 100644
--- a/std/special/compiler_rt/udivmodti4.zig
+++ b/std/special/compiler_rt/udivmodti4.zig
@@ -7,9 +7,10 @@ pub extern fn __udivmodti4(a: u128, b: u128, maybe_rem: ?*u128) u128 {
return udivmod(u128, a, b, maybe_rem);
}
-pub extern fn __udivmodti4_windows_x86_64(a: *const u128, b: *const u128, maybe_rem: ?*u128) void {
+const v128 = @Vector(2, u64);
+pub extern fn __udivmodti4_windows_x86_64(a: v128, b: v128, maybe_rem: ?*u128) v128 {
@setRuntimeSafety(builtin.is_test);
- compiler_rt.setXmm0(u128, udivmod(u128, a.*, b.*, maybe_rem));
+ return @bitCast(v128, udivmod(u128, @bitCast(u128, a), @bitCast(u128, b), maybe_rem));
}
test "import udivmodti4" {
diff --git a/std/special/compiler_rt/udivti3.zig b/std/special/compiler_rt/udivti3.zig
index 510e21ac1d..ab451859bf 100644
--- a/std/special/compiler_rt/udivti3.zig
+++ b/std/special/compiler_rt/udivti3.zig
@@ -6,7 +6,8 @@ pub extern fn __udivti3(a: u128, b: u128) u128 {
return udivmodti4.__udivmodti4(a, b, null);
}
-pub extern fn __udivti3_windows_x86_64(a: *const u128, b: *const u128) void {
+const v128 = @Vector(2, u64);
+pub extern fn __udivti3_windows_x86_64(a: v128, b: v128) v128 {
@setRuntimeSafety(builtin.is_test);
- udivmodti4.__udivmodti4_windows_x86_64(a, b, null);
+ return udivmodti4.__udivmodti4_windows_x86_64(a, b, null);
}
diff --git a/std/special/compiler_rt/umodti3.zig b/std/special/compiler_rt/umodti3.zig
index 12aca8b036..7add0b2ffe 100644
--- a/std/special/compiler_rt/umodti3.zig
+++ b/std/special/compiler_rt/umodti3.zig
@@ -9,7 +9,7 @@ pub extern fn __umodti3(a: u128, b: u128) u128 {
return r;
}
-pub extern fn __umodti3_windows_x86_64(a: *const u128, b: *const u128) void {
- @setRuntimeSafety(builtin.is_test);
- compiler_rt.setXmm0(u128, __umodti3(a.*, b.*));
+const v128 = @Vector(2, u64);
+pub extern fn __umodti3_windows_x86_64(a: v128, b: v128) v128 {
+ return @bitCast(v128, @inlineCall(__umodti3, @bitCast(u128, a), @bitCast(u128, b)));
}
diff --git a/test/stage1/behavior/bit_shifting.zig b/test/stage1/behavior/bit_shifting.zig
index 610acc06c2..c638ec1709 100644
--- a/test/stage1/behavior/bit_shifting.zig
+++ b/test/stage1/behavior/bit_shifting.zig
@@ -86,3 +86,11 @@ fn testShardedTable(comptime Key: type, comptime mask_bit_count: comptime_int, c
expect(table.get(@intCast(Key, i)) == node);
}
}
+
+// #2225
+test "comptime shr of BigInt" {
+ comptime {
+ var n = 0xdeadbeef0000000000000000;
+ std.debug.assert(n >> 64 == 0xdeadbeef);
+ }
+}
diff --git a/test/stage1/behavior/math.zig b/test/stage1/behavior/math.zig
index 23dc6d1feb..acbd9209df 100644
--- a/test/stage1/behavior/math.zig
+++ b/test/stage1/behavior/math.zig
@@ -632,3 +632,10 @@ fn testNanEqNan(comptime F: type) void {
expect(!(nan1 < nan2));
expect(!(nan1 <= nan2));
}
+
+test "128-bit multiplication" {
+ var a: i128 = 3;
+ var b: i128 = 2;
+ var c = a * b;
+ expect(c == 6);
+}