aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-12-26 15:45:50 -0500
committerAndrew Kelley <superjoe30@gmail.com>2016-12-26 15:45:50 -0500
commit735cdbfdaca6405d1465ea859032412499c658d8 (patch)
treea3b6655d26985adafbf71903c5d5bb7049a45454 /src
parentaee7ad3de2e3c334ec5aac2d355e4eed086f1cdf (diff)
downloadzig-735cdbfdaca6405d1465ea859032412499c658d8.tar.gz
zig-735cdbfdaca6405d1465ea859032412499c658d8.zip
IR: pass intToPtrCast test
Diffstat (limited to 'src')
-rw-r--r--src/all_types.hpp21
-rw-r--r--src/codegen.cpp20
-rw-r--r--src/ir.cpp88
-rw-r--r--src/ir_print.cpp24
-rw-r--r--src/parseh.cpp2
5 files changed, 143 insertions, 12 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp
index 6f4947d436..360ffa3cba 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -90,6 +90,11 @@ enum ConstPtrSpecial {
// This means that the pointer points to inline memory, so attempting
// to write a non-compile-time known value is an error
ConstPtrSpecialInline,
+ // This means that we did a compile-time pointer reinterpret and we cannot
+ // understand the value of pointee at compile time. However, we will still
+ // emit a binary with a compile time known address.
+ // In this case index is the numeric address value.
+ ConstPtrSpecialRuntime,
};
struct ConstPtrValue {
@@ -427,8 +432,6 @@ struct AstNodeUnwrapErrorExpr {
enum CastOp {
CastOpNoCast, // signifies the function call expression is not a cast
CastOpNoop, // fn call expr is a cast, but does nothing
- CastOpPtrToInt,
- CastOpIntToPtr,
CastOpErrToInt,
CastOpIntToFloat,
CastOpFloatToInt,
@@ -1453,6 +1456,8 @@ enum IrInstructionId {
IrInstructionIdInitEnum,
IrInstructionIdPointerReinterpret,
IrInstructionIdWidenOrShorten,
+ IrInstructionIdIntToPtr,
+ IrInstructionIdPtrToInt,
};
struct IrInstruction {
@@ -2101,6 +2106,18 @@ struct IrInstructionWidenOrShorten {
IrInstruction *target;
};
+struct IrInstructionPtrToInt {
+ IrInstruction base;
+
+ IrInstruction *target;
+};
+
+struct IrInstructionIntToPtr {
+ IrInstruction base;
+
+ IrInstruction *target;
+};
+
enum LValPurpose {
LValPurposeNone,
LValPurposeAssign,
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 6ab14cffe1..cf737fc7c3 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -969,10 +969,6 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
} else {
zig_panic("TODO");
}
- case CastOpPtrToInt:
- return LLVMBuildPtrToInt(g->builder, expr_val, wanted_type->type_ref, "");
- case CastOpIntToPtr:
- return LLVMBuildIntToPtr(g->builder, expr_val, wanted_type->type_ref, "");
case CastOpResizeSlice:
{
assert(cast_instruction->tmp_ptr);
@@ -1114,6 +1110,18 @@ static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executa
instruction->base.value.type, target_val);
}
+static LLVMValueRef ir_render_int_to_ptr(CodeGen *g, IrExecutable *executable, IrInstructionIntToPtr *instruction) {
+ TypeTableEntry *wanted_type = instruction->base.value.type;
+ LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
+ return LLVMBuildIntToPtr(g->builder, target_val, wanted_type->type_ref, "");
+}
+
+static LLVMValueRef ir_render_ptr_to_int(CodeGen *g, IrExecutable *executable, IrInstructionPtrToInt *instruction) {
+ TypeTableEntry *wanted_type = instruction->base.value.type;
+ LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
+ return LLVMBuildPtrToInt(g->builder, target_val, wanted_type->type_ref, "");
+}
+
static LLVMValueRef ir_render_unreachable(CodeGen *g, IrExecutable *executable,
IrInstructionUnreachable *unreachable_instruction)
{
@@ -2347,6 +2355,10 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
return ir_render_pointer_reinterpret(g, executable, (IrInstructionPointerReinterpret *)instruction);
case IrInstructionIdWidenOrShorten:
return ir_render_widen_or_shorten(g, executable, (IrInstructionWidenOrShorten *)instruction);
+ case IrInstructionIdPtrToInt:
+ return ir_render_ptr_to_int(g, executable, (IrInstructionPtrToInt *)instruction);
+ case IrInstructionIdIntToPtr:
+ return ir_render_int_to_ptr(g, executable, (IrInstructionIntToPtr *)instruction);
case IrInstructionIdContainerInitList:
return ir_render_container_init_list(g, executable, (IrInstructionContainerInitList *)instruction);
case IrInstructionIdSwitchVar:
diff --git a/src/ir.cpp b/src/ir.cpp
index 51a652451b..7eac05def6 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -52,6 +52,7 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Typ
ConstExprValue *const_ptr_pointee(ConstExprValue *const_val) {
assert(const_val->special == ConstValSpecialStatic);
+ assert(const_val->data.x_ptr.special != ConstPtrSpecialRuntime);
ConstExprValue *base_ptr = const_val->data.x_ptr.base_ptr;
size_t index = const_val->data.x_ptr.index;
@@ -459,6 +460,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionWidenOrShorten *
return IrInstructionIdWidenOrShorten;
}
+static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrToInt *) {
+ return IrInstructionIdPtrToInt;
+}
+
+static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToPtr *) {
+ return IrInstructionIdIntToPtr;
+}
+
template<typename T>
static T *ir_create_instruction(IrExecutable *exec, Scope *scope, AstNode *source_node) {
T *special_instruction = allocate<T>(1);
@@ -1899,6 +1908,30 @@ static IrInstruction *ir_build_widen_or_shorten(IrBuilder *irb, Scope *scope, As
return &instruction->base;
}
+static IrInstruction *ir_build_int_to_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
+ IrInstruction *target)
+{
+ IrInstructionIntToPtr *instruction = ir_build_instruction<IrInstructionIntToPtr>(
+ irb, scope, source_node);
+ instruction->target = target;
+
+ ir_ref_instruction(target);
+
+ return &instruction->base;
+}
+
+static IrInstruction *ir_build_ptr_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node,
+ IrInstruction *target)
+{
+ IrInstructionPtrToInt *instruction = ir_build_instruction<IrInstructionPtrToInt>(
+ irb, scope, source_node);
+ instruction->target = target;
+
+ ir_ref_instruction(target);
+
+ return &instruction->base;
+}
+
static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
results[ReturnKindUnconditional] = 0;
results[ReturnKindError] = 0;
@@ -4657,8 +4690,6 @@ static void eval_const_expr_implicit_cast(CastOp cast_op,
*const_val = *other_val;
const_val->type = new_type;
break;
- case CastOpPtrToInt:
- case CastOpIntToPtr:
case CastOpResizeSlice:
case CastOpBytesToSlice:
// can't do it
@@ -5234,6 +5265,51 @@ static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction
return result;
}
+static IrInstruction *ir_analyze_ptr_to_int(IrAnalyze *ira, IrInstruction *source_instr,
+ IrInstruction *target, TypeTableEntry *wanted_type)
+{
+ assert(wanted_type->id == TypeTableEntryIdInt);
+
+ if (instr_is_comptime(target)) {
+ ConstExprValue *val = ir_resolve_const(ira, target, UndefBad);
+ if (!val)
+ return ira->codegen->invalid_instruction;
+ if (val->data.x_ptr.special == ConstPtrSpecialRuntime) {
+ IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,
+ source_instr->source_node, wanted_type, val->depends_on_compile_var);
+ bignum_init_unsigned(&result->value.data.x_bignum, val->data.x_ptr.index);
+ return result;
+ }
+ }
+
+ IrInstruction *result = ir_build_ptr_to_int(&ira->new_irb, source_instr->scope,
+ source_instr->source_node, target);
+ result->value.type = wanted_type;
+ return result;
+}
+
+static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr,
+ IrInstruction *target, TypeTableEntry *wanted_type)
+{
+ assert(wanted_type->id == TypeTableEntryIdPointer);
+
+ if (instr_is_comptime(target)) {
+ ConstExprValue *val = ir_resolve_const(ira, target, UndefBad);
+ if (!val)
+ return ira->codegen->invalid_instruction;
+ IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,
+ source_instr->source_node, wanted_type, val->depends_on_compile_var);
+ result->value.data.x_ptr.base_ptr = nullptr;
+ result->value.data.x_ptr.index = bignum_to_twos_complement(&val->data.x_bignum);
+ result->value.data.x_ptr.special = ConstPtrSpecialRuntime;
+ return result;
+ }
+
+ IrInstruction *result = ir_build_int_to_ptr(&ira->new_irb, source_instr->scope,
+ source_instr->source_node, target);
+ result->value.type = wanted_type;
+ return result;
+}
static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,
TypeTableEntry *wanted_type, IrInstruction *value)
@@ -5270,7 +5346,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
if ((wanted_type_canon == isize_type || wanted_type_canon == usize_type) &&
type_is_codegen_pointer(actual_type_canon))
{
- return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpPtrToInt, false);
+ return ir_analyze_ptr_to_int(ira, source_instr, value, wanted_type);
}
@@ -5278,7 +5354,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
if (wanted_type_canon->id == TypeTableEntryIdPointer &&
(actual_type_canon == isize_type || actual_type_canon == usize_type))
{
- return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpIntToPtr, false);
+ return ir_analyze_int_to_ptr(ira, source_instr, value, wanted_type);
}
// explicit widening or shortening cast
@@ -9937,6 +10013,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
case IrInstructionIdInvalid:
case IrInstructionIdPointerReinterpret:
case IrInstructionIdWidenOrShorten:
+ case IrInstructionIdIntToPtr:
+ case IrInstructionIdPtrToInt:
case IrInstructionIdStructInit:
case IrInstructionIdStructFieldPtr:
case IrInstructionIdEnumFieldPtr:
@@ -10244,6 +10322,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdInitEnum:
case IrInstructionIdPointerReinterpret:
case IrInstructionIdWidenOrShorten:
+ case IrInstructionIdPtrToInt:
+ case IrInstructionIdIntToPtr:
return false;
case IrInstructionIdAsm:
{
diff --git a/src/ir_print.cpp b/src/ir_print.cpp
index f0dda04c6d..3db8b32e4f 100644
--- a/src/ir_print.cpp
+++ b/src/ir_print.cpp
@@ -98,7 +98,11 @@ static void ir_print_const_value(IrPrint *irp, ConstExprValue *const_val) {
}
case TypeTableEntryIdPointer:
fprintf(irp->f, "&");
- ir_print_const_value(irp, const_ptr_pointee(const_val));
+ if (const_val->data.x_ptr.special == ConstPtrSpecialRuntime) {
+ fprintf(irp->f, "(runtime pointer value)");
+ } else {
+ ir_print_const_value(irp, const_ptr_pointee(const_val));
+ }
return;
case TypeTableEntryIdFn:
{
@@ -934,6 +938,18 @@ static void ir_print_widen_or_shorten(IrPrint *irp, IrInstructionWidenOrShorten
fprintf(irp->f, ")");
}
+static void ir_print_ptr_to_int(IrPrint *irp, IrInstructionPtrToInt *instruction) {
+ fprintf(irp->f, "@ptrToInt(");
+ ir_print_other_instruction(irp, instruction->target);
+ fprintf(irp->f, ")");
+}
+
+static void ir_print_int_to_ptr(IrPrint *irp, IrInstructionIntToPtr *instruction) {
+ fprintf(irp->f, "@intToPtr(");
+ ir_print_other_instruction(irp, instruction->target);
+ fprintf(irp->f, ")");
+}
+
static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
ir_print_prefix(irp, instruction);
switch (instruction->id) {
@@ -1179,6 +1195,12 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdWidenOrShorten:
ir_print_widen_or_shorten(irp, (IrInstructionWidenOrShorten *)instruction);
break;
+ case IrInstructionIdPtrToInt:
+ ir_print_ptr_to_int(irp, (IrInstructionPtrToInt *)instruction);
+ break;
+ case IrInstructionIdIntToPtr:
+ ir_print_int_to_ptr(irp, (IrInstructionIntToPtr *)instruction);
+ break;
}
fprintf(irp->f, "\n");
}
diff --git a/src/parseh.cpp b/src/parseh.cpp
index 9ebe47b44e..f84391aba9 100644
--- a/src/parseh.cpp
+++ b/src/parseh.cpp
@@ -1203,7 +1203,7 @@ static void process_symbol_macros(Context *c) {
if (var_type->id == TypeTableEntryIdMaybe && !tld_var->var->src_is_const) {
TypeTableEntry *child_type = var_type->data.maybe.child_type;
if (child_type->id == TypeTableEntryIdFn) {
- zig_panic("TODO");
+ zig_panic("TODO macro alias of function pointer in .h file");
//Tld *fn_tld = create_inline_fn_alias(c, ms.name, tld_var->var);
//c->macro_table.put(ms.name, fn_tld);
continue;