Commit be9bb0a857

Jimmi Holst Christensen <jhc@liab.dk>
2018-11-16 14:07:23
Fixed #1663 and removed IrInstructionArrayLen
1 parent 332fdf3
src/all_types.hpp
@@ -2071,7 +2071,6 @@ enum IrInstructionId {
     IrInstructionIdCInclude,
     IrInstructionIdCDefine,
     IrInstructionIdCUndef,
-    IrInstructionIdArrayLen,
     IrInstructionIdRef,
     IrInstructionIdCompileErr,
     IrInstructionIdCompileLog,
@@ -2584,12 +2583,6 @@ struct IrInstructionImport {
     IrInstruction *name;
 };
 
-struct IrInstructionArrayLen {
-    IrInstruction base;
-
-    IrInstruction *array_value;
-};
-
 struct IrInstructionRef {
     IrInstruction base;
 
src/codegen.cpp
@@ -5102,7 +5102,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
         case IrInstructionIdContainerInitFields:
         case IrInstructionIdCompileErr:
         case IrInstructionIdCompileLog:
-        case IrInstructionIdArrayLen:
         case IrInstructionIdImport:
         case IrInstructionIdCImport:
         case IrInstructionIdCInclude:
src/ir.cpp
@@ -479,10 +479,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCUndef *) {
     return IrInstructionIdCUndef;
 }
 
-static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayLen *) {
-    return IrInstructionIdArrayLen;
-}
-
 static constexpr IrInstructionId ir_instruction_id(IrInstructionRef *) {
     return IrInstructionIdRef;
 }
@@ -1663,15 +1659,6 @@ static IrInstruction *ir_build_import(IrBuilder *irb, Scope *scope, AstNode *sou
     return &instruction->base;
 }
 
-static IrInstruction *ir_build_array_len(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *array_value) {
-    IrInstructionArrayLen *instruction = ir_build_instruction<IrInstructionArrayLen>(irb, scope, source_node);
-    instruction->array_value = array_value;
-
-    ir_ref_instruction(array_value, irb->current_basic_block);
-
-    return &instruction->base;
-}
-
 static IrInstruction *ir_build_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value,
         bool is_const, bool is_volatile)
 {
@@ -5351,7 +5338,9 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
     IrBasicBlock *else_block = else_node ? ir_create_basic_block(irb, child_scope, "ForElse") : end_block;
     IrBasicBlock *continue_block = ir_create_basic_block(irb, child_scope, "ForContinue");
 
-    IrInstruction *len_val = ir_build_array_len(irb, child_scope, node, array_val);
+    Buf *len_field_name = buf_create_from_str("len");
+    IrInstruction *len_ref = ir_build_field_ptr(irb, child_scope, node, array_val_ptr, len_field_name);
+    IrInstruction *len_val = ir_build_load_ptr(irb, child_scope, node, len_ref);
     ir_build_br(irb, child_scope, node, cond_block, is_comptime);
 
     ir_set_cursor_at_end_and_append_block(irb, cond_block);
@@ -9450,12 +9439,6 @@ static IrInstruction *ir_const_unsigned(IrAnalyze *ira, IrInstruction *source_in
     return result;
 }
 
-static IrInstruction *ir_const_usize(IrAnalyze *ira, IrInstruction *source_instruction, uint64_t value) {
-    IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_usize);
-    bigint_init_unsigned(&result->value.data.x_bigint, value);
-    return result;
-}
-
 static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instruction,
         ConstExprValue *pointee, ZigType *pointee_type,
         ConstPtrMut ptr_mut, bool ptr_is_const, bool ptr_is_volatile, uint32_t ptr_align)
@@ -14971,8 +14954,14 @@ static IrInstruction *ir_analyze_instruction_to_ptr_type(IrAnalyze *ira,
 
     ZigType *ptr_type;
     if (type_entry->id == ZigTypeIdArray) {
+        // TODO: Allow capturing pointer to const array.
+        // const a = "123"; for (a) |*c| continue;
+        // error: expected type '*u8', found '*const u8'
         ptr_type = get_pointer_to_type(ira->codegen, type_entry->data.array.child_type, false);
-    } else if (is_slice(type_entry)) {
+    } else if (is_array_ref(type_entry)) {
+        ptr_type = get_pointer_to_type(ira->codegen,
+            type_entry->data.pointer.child_type->data.array.child_type, type_entry->data.pointer.is_const);
+    }  else if (is_slice(type_entry)) {
         ptr_type = adjust_ptr_len(ira->codegen, type_entry->data.structure.fields[0].type_entry, PtrLenSingle);
     } else if (type_entry->id == ZigTypeIdArgTuple) {
         ConstExprValue *arg_tuple_val = ir_resolve_const(ira, value, UndefBad);
@@ -15959,39 +15948,6 @@ static IrInstruction *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructio
     return result;
 }
 
-static IrInstruction *ir_analyze_instruction_array_len(IrAnalyze *ira,
-        IrInstructionArrayLen *array_len_instruction)
-{
-    IrInstruction *array_value = array_len_instruction->array_value->child;
-    ZigType *type_entry = array_value->value.type;
-    if (type_is_invalid(type_entry)) {
-        return ira->codegen->invalid_instruction;
-    } else if (type_entry->id == ZigTypeIdArray) {
-        return ir_const_usize(ira, &array_len_instruction->base,
-                type_entry->data.array.len);
-    } else if (is_slice(type_entry)) {
-        if (array_value->value.special != ConstValSpecialRuntime) {
-            ConstExprValue *len_val = &array_value->value.data.x_struct.fields[slice_len_index];
-            if (len_val->special != ConstValSpecialRuntime) {
-                return ir_const_usize(ira, &array_len_instruction->base,
-                        bigint_as_unsigned(&len_val->data.x_bigint));
-            }
-        }
-        TypeStructField *field = &type_entry->data.structure.fields[slice_len_index];
-        IrInstruction *len_ptr = ir_build_struct_field_ptr(&ira->new_irb, array_len_instruction->base.scope,
-                array_len_instruction->base.source_node, array_value, field);
-        len_ptr->value.type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_usize, true);
-        IrInstruction *result = ir_build_load_ptr(&ira->new_irb,
-            array_len_instruction->base.scope, array_len_instruction->base.source_node, len_ptr);
-        result->value.type = ira->codegen->builtin_types.entry_usize;
-        return result;
-    } else {
-        ir_add_error_node(ira, array_len_instruction->base.source_node,
-            buf_sprintf("type '%s' has no field 'len'", buf_ptr(&array_value->value.type->name)));
-        return ira->codegen->invalid_instruction;
-    }
-}
-
 static IrInstruction *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRef *ref_instruction) {
     IrInstruction *value = ref_instruction->value->child;
     if (type_is_invalid(value->value.type))
@@ -20893,8 +20849,6 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
             return ir_analyze_instruction_union_tag(ira, (IrInstructionUnionTag *)instruction);
         case IrInstructionIdImport:
             return ir_analyze_instruction_import(ira, (IrInstructionImport *)instruction);
-        case IrInstructionIdArrayLen:
-            return ir_analyze_instruction_array_len(ira, (IrInstructionArrayLen *)instruction);
         case IrInstructionIdRef:
             return ir_analyze_instruction_ref(ira, (IrInstructionRef *)instruction);
         case IrInstructionIdContainerInitList:
@@ -21228,7 +21182,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
         case IrInstructionIdTypeOf:
         case IrInstructionIdToPtrType:
         case IrInstructionIdPtrTypeChild:
-        case IrInstructionIdArrayLen:
         case IrInstructionIdStructFieldPtr:
         case IrInstructionIdUnionFieldPtr:
         case IrInstructionIdArrayType:
src/ir_print.cpp
@@ -553,11 +553,6 @@ static void ir_print_import(IrPrint *irp, IrInstructionImport *instruction) {
     fprintf(irp->f, ")");
 }
 
-static void ir_print_array_len(IrPrint *irp, IrInstructionArrayLen *instruction) {
-    ir_print_other_instruction(irp, instruction->array_value);
-    fprintf(irp->f, ".len");
-}
-
 static void ir_print_ref(IrPrint *irp, IrInstructionRef *instruction) {
     const char *const_str = instruction->is_const ? "const " : "";
     const char *volatile_str = instruction->is_volatile ? "volatile " : "";
@@ -1462,9 +1457,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
         case IrInstructionIdImport:
             ir_print_import(irp, (IrInstructionImport *)instruction);
             break;
-        case IrInstructionIdArrayLen:
-            ir_print_array_len(irp, (IrInstructionArrayLen *)instruction);
-            break;
         case IrInstructionIdRef:
             ir_print_ref(irp, (IrInstructionRef *)instruction);
             break;
test/cases/for.zig
@@ -35,7 +35,7 @@ fn mangleString(s: []u8) void {
 }
 
 test "basic for loop" {
-    const expected_result = []u8{ 9, 8, 7, 6, 0, 1, 2, 3, 9, 8, 7, 6, 0, 1, 2, 3 };
+    const expected_result = []u8{ 9, 8, 7, 6, 0, 1, 2, 3 } ** 3;
 
     var buffer: [expected_result.len]u8 = undefined;
     var buf_index: usize = 0;
@@ -49,6 +49,15 @@ test "basic for loop" {
         buffer[buf_index] = @intCast(u8, index);
         buf_index += 1;
     }
+    const array_ptr = &array;
+    for (array_ptr) |item| {
+        buffer[buf_index] = item;
+        buf_index += 1;
+    }
+    for (array_ptr) |item, index| {
+        buffer[buf_index] = @intCast(u8, index);
+        buf_index += 1;
+    }
     const unknown_size: []const u8 = array;
     for (unknown_size) |item| {
         buffer[buf_index] = item;