Commit 0919ea0afd

Andrew Kelley <superjoe30@gmail.com>
2017-02-04 16:22:07
ability to set global variable alignment and ...
..section in the initialization expression
1 parent 67b0232
src/all_types.hpp
@@ -222,6 +222,10 @@ struct TldVar {
     Tld base;
 
     VariableTableEntry *var;
+    AstNode *set_global_align_node;
+    uint64_t alignment;
+    AstNode *set_global_section_node;
+    Buf *section_name;
 };
 
 struct TldFn {
@@ -1235,7 +1239,7 @@ struct CodeGen {
     // The function prototypes this module includes. In the case of external declarations,
     // there will not be a corresponding fn_defs entry.
     ZigList<FnTableEntry *> fn_protos;
-    ZigList<VariableTableEntry *> global_vars;
+    ZigList<TldVar *> global_vars;
 
     OutType out_type;
     FnTableEntry *cur_fn;
@@ -1307,10 +1311,6 @@ struct VariableTableEntry {
     size_t mem_slot_index;
     size_t ref_count;
     VarLinkage linkage;
-    AstNode *set_global_align_node;
-    uint64_t alignment;
-    AstNode *set_global_section_node;
-    Buf *section_name;
 };
 
 struct ErrorTableEntry {
@@ -2256,14 +2256,14 @@ struct IrInstructionCanImplicitCast {
 struct IrInstructionSetGlobalAlign {
     IrInstruction base;
 
-    VariableTableEntry *var;
+    TldVar *tld_var;
     IrInstruction *value;
 };
 
 struct IrInstructionSetGlobalSection {
     IrInstruction base;
 
-    VariableTableEntry *var;
+    TldVar *tld_var;
     IrInstruction *value;
 };
 
src/analyze.cpp
@@ -1967,7 +1967,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
     tld_var->var = add_variable(g, source_node, tld_var->base.parent_scope, var_decl->symbol, is_const, init_val);
     tld_var->var->linkage = linkage;
 
-    g->global_vars.append(tld_var->var);
+    g->global_vars.append(tld_var);
 }
 
 static void resolve_decl_typedef(CodeGen *g, TldTypeDef *tld_typedef) {
src/ast_render.cpp
@@ -628,6 +628,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
                 if (entry->type == NodeTypeStructValueField) {
                     Buf *name = entry->data.struct_val_field.name;
                     AstNode *expr = entry->data.struct_val_field.expr;
+                    print_indent(ar);
                     fprintf(ar->f, ".%s = ", buf_ptr(name));
                     render_node_grouped(ar, expr);
                     fprintf(ar->f, ",\n");
@@ -637,10 +638,11 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
                     render_node_grouped(ar, entry);
                 }
             }
-            fprintf(ar->f, "}");
             if (node->data.container_init_expr.kind == ContainerInitKindStruct) {
                 ar->indent -= ar->indent_size;
             }
+            print_indent(ar);
+            fprintf(ar->f, "}");
             break;
         case NodeTypeArrayType:
             {
src/codegen.cpp
@@ -2808,7 +2808,8 @@ static void do_code_gen(CodeGen *g) {
 
     // Generate module level variables
     for (size_t i = 0; i < g->global_vars.length; i += 1) {
-        VariableTableEntry *var = g->global_vars.at(i);
+        TldVar *tld_var = g->global_vars.at(i);
+        VariableTableEntry *var = tld_var->var;
 
         if (var->value.type->id == TypeTableEntryIdNumLitFloat) {
             // Generate debug info for it but that's it.
@@ -2852,11 +2853,11 @@ static void do_code_gen(CodeGen *g) {
             if (var->linkage == VarLinkageExport) {
                 LLVMSetLinkage(global_value, LLVMExternalLinkage);
             }
-            if (var->section_name) {
-                LLVMSetSection(global_value, buf_ptr(var->section_name));
+            if (tld_var->section_name) {
+                LLVMSetSection(global_value, buf_ptr(tld_var->section_name));
             }
-            if (var->alignment) {
-                LLVMSetAlignment(global_value, var->alignment);
+            if (tld_var->alignment) {
+                LLVMSetAlignment(global_value, tld_var->alignment);
             }
 
             // TODO debug info for function pointers
src/ir.cpp
@@ -2062,11 +2062,11 @@ static IrInstruction *ir_build_can_implicit_cast(IrBuilder *irb, Scope *scope, A
 }
 
 static IrInstruction *ir_build_set_global_align(IrBuilder *irb, Scope *scope, AstNode *source_node,
-        VariableTableEntry *var, IrInstruction *value)
+        TldVar *tld_var, IrInstruction *value)
 {
     IrInstructionSetGlobalAlign *instruction = ir_build_instruction<IrInstructionSetGlobalAlign>(
             irb, scope, source_node);
-    instruction->var = var;
+    instruction->tld_var = tld_var;
     instruction->value = value;
 
     ir_ref_instruction(value, irb->current_basic_block);
@@ -2075,11 +2075,11 @@ static IrInstruction *ir_build_set_global_align(IrBuilder *irb, Scope *scope, As
 }
 
 static IrInstruction *ir_build_set_global_section(IrBuilder *irb, Scope *scope, AstNode *source_node,
-        VariableTableEntry *var, IrInstruction *value)
+        TldVar *tld_var, IrInstruction *value)
 {
     IrInstructionSetGlobalSection *instruction = ir_build_instruction<IrInstructionSetGlobalSection>(
             irb, scope, source_node);
-    instruction->var = var;
+    instruction->tld_var = tld_var;
     instruction->value = value;
 
     ir_ref_instruction(value, irb->current_basic_block);
@@ -4187,7 +4187,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
                     return irb->codegen->invalid_instruction;
                 }
                 TldVar *tld_var = (TldVar *)tld;
-                VariableTableEntry *var = tld_var->var;
 
                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
                 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
@@ -4195,9 +4194,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
                     return arg1_value;
 
                 if (builtin_fn->id == BuiltinFnIdSetGlobalAlign) {
-                    return ir_build_set_global_align(irb, scope, node, var, arg1_value);
+                    return ir_build_set_global_align(irb, scope, node, tld_var, arg1_value);
                 } else {
-                    return ir_build_set_global_section(irb, scope, node, var, arg1_value);
+                    return ir_build_set_global_section(irb, scope, node, tld_var, arg1_value);
                 }
             }
         case BuiltinFnIdVolatileStore:
@@ -9455,22 +9454,24 @@ static TypeTableEntry *ir_analyze_instruction_set_fn_visible(IrAnalyze *ira,
 static TypeTableEntry *ir_analyze_instruction_set_global_align(IrAnalyze *ira,
         IrInstructionSetGlobalAlign *instruction)
 {
-    VariableTableEntry *var = instruction->var;
+    TldVar *tld_var = instruction->tld_var;
     IrInstruction *align_value = instruction->value->other;
 
     uint64_t scalar_align;
     if (!ir_resolve_usize(ira, align_value, &scalar_align))
         return ira->codegen->builtin_types.entry_invalid;
 
+    // TODO error if not power of 2
+
     AstNode *source_node = instruction->base.source_node;
-    if (var->set_global_align_node) {
+    if (tld_var->set_global_align_node) {
         ErrorMsg *msg = ir_add_error_node(ira, source_node,
                 buf_sprintf("alignment set twice"));
-        add_error_note(ira->codegen, msg, var->set_global_align_node, buf_sprintf("first set here"));
+        add_error_note(ira->codegen, msg, tld_var->set_global_align_node, buf_sprintf("first set here"));
         return ira->codegen->builtin_types.entry_invalid;
     }
-    var->set_global_align_node = source_node;
-    var->alignment = scalar_align;
+    tld_var->set_global_align_node = source_node;
+    tld_var->alignment = scalar_align;
 
     ir_build_const_from(ira, &instruction->base, false);
     return ira->codegen->builtin_types.entry_void;
@@ -9479,7 +9480,7 @@ static TypeTableEntry *ir_analyze_instruction_set_global_align(IrAnalyze *ira,
 static TypeTableEntry *ir_analyze_instruction_set_global_section(IrAnalyze *ira,
         IrInstructionSetGlobalSection *instruction)
 {
-    VariableTableEntry *var = instruction->var;
+    TldVar *tld_var = instruction->tld_var;
     IrInstruction *section_value = instruction->value->other;
 
     Buf *section_name = ir_resolve_str(ira, section_value);
@@ -9487,13 +9488,13 @@ static TypeTableEntry *ir_analyze_instruction_set_global_section(IrAnalyze *ira,
         return ira->codegen->builtin_types.entry_invalid;
 
     AstNode *source_node = instruction->base.source_node;
-    if (var->set_global_section_node) {
+    if (tld_var->set_global_section_node) {
         ErrorMsg *msg = ir_add_error_node(ira, source_node, buf_sprintf("section set twice"));
-        add_error_note(ira->codegen, msg, var->set_global_section_node, buf_sprintf("first set here"));
+        add_error_note(ira->codegen, msg, tld_var->set_global_section_node, buf_sprintf("first set here"));
         return ira->codegen->builtin_types.entry_invalid;
     }
-    var->set_global_section_node = source_node;
-    var->section_name = section_name;
+    tld_var->set_global_section_node = source_node;
+    tld_var->section_name = section_name;
 
     ir_build_const_from(ira, &instruction->base, false);
     return ira->codegen->builtin_types.entry_void;
src/ir_print.cpp
@@ -835,13 +835,13 @@ static void ir_print_can_implicit_cast(IrPrint *irp, IrInstructionCanImplicitCas
 }
 
 static void ir_print_set_global_align(IrPrint *irp, IrInstructionSetGlobalAlign *instruction) {
-    fprintf(irp->f, "@setGlobalAlign(%s,", buf_ptr(&instruction->var->name));
+    fprintf(irp->f, "@setGlobalAlign(%s,", buf_ptr(instruction->tld_var->base.name));
     ir_print_other_instruction(irp, instruction->value);
     fprintf(irp->f, ")");
 }
 
 static void ir_print_set_global_section(IrPrint *irp, IrInstructionSetGlobalSection *instruction) {
-    fprintf(irp->f, "@setGlobalSection(%s,", buf_ptr(&instruction->var->name));
+    fprintf(irp->f, "@setGlobalSection(%s,", buf_ptr(instruction->tld_var->base.name));
     ir_print_other_instruction(irp, instruction->value);
     fprintf(irp->f, ")");
 }
src/parseh.cpp
@@ -152,7 +152,7 @@ static TldVar *create_global_var(Context *c, Buf *name, ConstExprValue *var_valu
     TldVar *tld_var = allocate<TldVar>(1);
     parseh_init_tld(c, &tld_var->base, TldIdVar, name);
     tld_var->var = add_variable(c->codegen, c->source_node, &c->import->decls_scope->base, name, is_const, var_value);
-    c->codegen->global_vars.append(tld_var->var);
+    c->codegen->global_vars.append(tld_var);
     return tld_var;
 }