Commit a5c9da0de2

Andrew Kelley <superjoe30@gmail.com>
2016-11-10 06:41:17
IR: gen string literal
1 parent 9d19b8d
Changed files (3)
src/all_types.hpp
@@ -1593,6 +1593,7 @@ struct IrInstructionFieldPtr {
 
     IrInstruction *container_ptr;
     Buf *field_name;
+    bool is_const;
 };
 
 struct IrInstructionStructFieldPtr {
@@ -1600,6 +1601,7 @@ struct IrInstructionStructFieldPtr {
 
     IrInstruction *struct_ptr;
     TypeStructField *field;
+    bool is_const;
 };
 
 struct IrInstructionReadField {
@@ -1614,12 +1616,14 @@ struct IrInstructionElemPtr {
 
     IrInstruction *array_ptr;
     IrInstruction *elem_index;
+    bool is_const;
 };
 
 struct IrInstructionVarPtr {
     IrInstruction base;
 
     VariableTableEntry *var;
+    bool is_const;
 };
 
 struct IrInstructionCall {
@@ -1716,6 +1720,7 @@ enum LValPurpose {
     LValPurposeNone,
     LValPurposeAssign,
     LValPurposeAddressOf,
+    LValPurposeConstAddressOf,
 };
 
 #endif
src/ir.cpp
@@ -367,6 +367,55 @@ static IrInstruction *ir_build_const_bool(IrBuilder *irb, AstNode *source_node,
     return &const_instruction->base;
 }
 
+static IrInstruction *ir_build_const_str_lit(IrBuilder *irb, AstNode *source_node, Buf *str) {
+    IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);
+    TypeTableEntry *u8_type = irb->codegen->builtin_types.entry_u8;
+    TypeTableEntry *type_entry = get_array_type(irb->codegen, u8_type, buf_len(str));
+    const_instruction->base.type_entry = type_entry;
+    ConstExprValue *const_val = &const_instruction->base.static_value;
+    const_val->ok = true;
+    const_val->data.x_array.fields = allocate<ConstExprValue*>(buf_len(str));
+
+    ConstExprValue *all_chars = allocate<ConstExprValue>(buf_len(str));
+    for (size_t i = 0; i < buf_len(str); i += 1) {
+        ConstExprValue *this_char = &all_chars[i];
+        this_char->ok = true;
+        bignum_init_unsigned(&this_char->data.x_bignum, buf_ptr(str)[i]);
+        const_val->data.x_array.fields[i] = this_char;
+    }
+
+    return &const_instruction->base;
+}
+
+static IrInstruction *ir_build_const_c_str_lit(IrBuilder *irb, AstNode *source_node, Buf *str) {
+    IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);
+    TypeTableEntry *u8_type = irb->codegen->builtin_types.entry_u8;
+    TypeTableEntry *type_entry = get_pointer_to_type(irb->codegen, u8_type, true);
+    const_instruction->base.type_entry = type_entry;
+    ConstExprValue *const_val = &const_instruction->base.static_value;
+    const_val->ok = true;
+
+    size_t len_with_null = buf_len(str) + 1;
+    const_val->data.x_ptr.ptr = allocate<ConstExprValue*>(len_with_null);
+    const_val->data.x_ptr.len = len_with_null;
+    const_val->data.x_ptr.is_c_str = true;
+
+    ConstExprValue *all_chars = allocate<ConstExprValue>(len_with_null);
+    for (size_t i = 0; i < buf_len(str); i += 1) {
+        ConstExprValue *this_char = &all_chars[i];
+        this_char->ok = true;
+        bignum_init_unsigned(&this_char->data.x_bignum, buf_ptr(str)[i]);
+        const_val->data.x_ptr.ptr[i] = this_char;
+    }
+
+    ConstExprValue *null_char = &all_chars[len_with_null - 1];
+    null_char->ok = true;
+    bignum_init_unsigned(&null_char->data.x_bignum, 0);
+    const_val->data.x_ptr.ptr[len_with_null - 1] = null_char;
+
+    return &const_instruction->base;
+}
+
 static IrInstruction *ir_build_bin_op(IrBuilder *irb, AstNode *source_node, IrBinOp op_id,
         IrInstruction *op1, IrInstruction *op2)
 {
@@ -398,9 +447,7 @@ static IrInstruction *ir_build_var_ptr(IrBuilder *irb, AstNode *source_node, Var
     return &instruction->base;
 }
 
-static IrInstruction *ir_build_var_ptr_from(IrBuilder *irb, IrInstruction *old_instruction,
-        VariableTableEntry *var)
-{
+static IrInstruction *ir_build_var_ptr_from(IrBuilder *irb, IrInstruction *old_instruction, VariableTableEntry *var) {
     IrInstruction *new_instruction = ir_build_var_ptr(irb, old_instruction->source_node, var);
     ir_link_new_instruction(new_instruction, old_instruction);
     return new_instruction;
@@ -1589,6 +1636,16 @@ static IrInstruction *ir_gen_bool_literal(IrBuilder *irb, AstNode *node) {
     return ir_build_const_bool(irb, node, node->data.bool_literal.value);
 }
 
+static IrInstruction *ir_gen_string_literal(IrBuilder *irb, AstNode *node) {
+    assert(node->type == NodeTypeStringLiteral);
+
+    if (node->data.string_literal.c) {
+        return ir_build_const_c_str_lit(irb, node, node->data.string_literal.buf);
+    } else {
+        return ir_build_const_str_lit(irb, node, node->data.string_literal.buf);
+    }
+}
+
 static IrInstruction *ir_gen_array_type(IrBuilder *irb, AstNode *node) {
     assert(node->type == NodeTypeArrayType);
 
@@ -1662,6 +1719,8 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont
             return ir_gen_bool_literal(irb, node);
         case NodeTypeArrayType:
             return ir_gen_array_type(irb, node);
+        case NodeTypeStringLiteral:
+            return ir_gen_string_literal(irb, node);
         case NodeTypeUnwrapErrorExpr:
         case NodeTypeDefer:
         case NodeTypeSliceExpr:
@@ -1672,7 +1731,6 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont
         case NodeTypeContinue:
         case NodeTypeLabel:
         case NodeTypeSwitchExpr:
-        case NodeTypeStringLiteral:
         case NodeTypeCharLiteral:
         case NodeTypeNullLiteral:
         case NodeTypeUndefinedLiteral:
@@ -3331,11 +3389,14 @@ static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstruct
     if (var->type->id == TypeTableEntryIdInvalid)
         return var->type;
 
+    zig_panic("TODO if var is a global, this code is wrong");
+
     TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, var->type, false);
-    // TODO once the anlayze code is fully ported over to IR we won't need this SIZE_MAX thing.
+    // TODO once the analyze code is fully ported over to IR we won't need this SIZE_MAX thing.
     if (var->mem_slot_index != SIZE_MAX) {
         ConstExprValue *mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index];
         if (mem_slot->ok) {
+            zig_panic("TODO do we really want to set up this fake pointer to do constant evaluation?");
             ConstExprValue *out_val = ir_build_const_from(ira, &var_ptr_instruction->base,
                     mem_slot->depends_on_compile_var);
 
@@ -6995,16 +7056,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
 //    return g->builtin_types.entry_void;
 //}
 //
-//static TypeTableEntry *analyze_string_literal_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
-//        TypeTableEntry *expected_type, AstNode *node)
-//{
-//    if (node->data.string_literal.c) {
-//        return resolve_expr_const_val_as_c_string_lit(g, node, node->data.string_literal.buf);
-//    } else {
-//        return resolve_expr_const_val_as_string_lit(g, node, node->data.string_literal.buf);
-//    }
-//}
-//
 //static TypeTableEntry *analyze_block_expr(CodeGen *g, ImportTableEntry *import, BlockContext *parent_context,
 //        TypeTableEntry *expected_type, AstNode *node)
 //{
src/ir_print.cpp
@@ -84,9 +84,22 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const
                 fprintf(irp->f, "(scope:%zu:%zu)", node->line + 1, node->column + 1);
                 break;
             }
+        case TypeTableEntryIdArray:
+            {
+                uint64_t len = type_entry->data.array.len;
+                fprintf(irp->f, "%s{", buf_ptr(&type_entry->name));
+                for (uint64_t i = 0; i < len; i += 1) {
+                    if (i != 0)
+                        fprintf(irp->f, ",");
+                    ConstExprValue *child_value = const_val->data.x_array.fields[i];
+                    TypeTableEntry *child_type = type_entry->data.array.child_type;
+                    ir_print_const_value(irp, child_type, child_value);
+                }
+                fprintf(irp->f, "}");
+                break;
+            }
         case TypeTableEntryIdVar:
         case TypeTableEntryIdFloat:
-        case TypeTableEntryIdArray:
         case TypeTableEntryIdStruct:
         case TypeTableEntryIdUndefLit:
         case TypeTableEntryIdNullLit: