Browse Source

Fix compound literals for constant procedure fields

gingerBill 5 years ago
parent
commit
01d12770fa
3 changed files with 46 additions and 26 deletions
  1. 3 0
      src/check_expr.cpp
  2. 14 4
      src/ir.cpp
  3. 29 22
      src/llvm_backend.cpp

+ 3 - 0
src/check_expr.cpp

@@ -7761,6 +7761,9 @@ bool check_range(CheckerContext *c, Ast *node, Operand *x, Operand *y, ExactValu
 }
 }
 
 
 bool check_is_operand_compound_lit_constant(CheckerContext *c, Operand *o) {
 bool check_is_operand_compound_lit_constant(CheckerContext *c, Operand *o) {
+	if (is_operand_nil(*o)) {
+		return true;
+	}
 	Ast *expr = unparen_expr(o->expr);
 	Ast *expr = unparen_expr(o->expr);
 	if (expr != nullptr) {
 	if (expr != nullptr) {
 		Entity *e = strip_entity_wrapping(entity_from_expr(expr));
 		Entity *e = strip_entity_wrapping(entity_from_expr(expr));

+ 14 - 4
src/ir.cpp

@@ -1615,10 +1615,10 @@ irDefer ir_add_defer_proc(irProcedure *proc, isize scope_index, irValue *deferre
 }
 }
 
 
 
 
-void ir_check_compound_lit_constant(irModule *m, Ast *expr) {
+irValue *ir_check_compound_lit_constant(irModule *m, Ast *expr) {
 	expr = unparen_expr(expr);
 	expr = unparen_expr(expr);
 	if (expr == nullptr) {
 	if (expr == nullptr) {
-		return;
+		return nullptr;
 	}
 	}
 	if (expr->kind == Ast_CompoundLit) {
 	if (expr->kind == Ast_CompoundLit) {
 		ast_node(cl, CompoundLit, expr);
 		ast_node(cl, CompoundLit, expr);
@@ -1633,8 +1633,9 @@ void ir_check_compound_lit_constant(irModule *m, Ast *expr) {
 		}
 		}
 	}
 	}
 	if (expr->kind == Ast_ProcLit) {
 	if (expr->kind == Ast_ProcLit) {
-		ir_gen_anonymous_proc_lit(m, str_lit("_proclit"), expr);
+		return ir_gen_anonymous_proc_lit(m, str_lit("_proclit"), expr);
 	}
 	}
+	return 	nullptr;
 }
 }
 
 
 irValue *ir_add_module_constant(irModule *m, Type *type, ExactValue value) {
 irValue *ir_add_module_constant(irModule *m, Type *type, ExactValue value) {
@@ -1674,7 +1675,11 @@ irValue *ir_add_module_constant(irModule *m, Type *type, ExactValue value) {
 	}
 	}
 
 
 	if (value.kind == ExactValue_Compound) {
 	if (value.kind == ExactValue_Compound) {
-		ir_check_compound_lit_constant(m, value.value_compound);
+		// NOTE(bill): Removed for numerous reasons
+		irValue *lit = ir_check_compound_lit_constant(m, value.value_compound);
+		if (lit != nullptr) {
+			return lit;
+		}
 	}
 	}
 
 
 	return ir_value_constant(type, value);
 	return ir_value_constant(type, value);
@@ -6530,6 +6535,11 @@ void ir_pop_target_list(irProcedure *proc) {
 
 
 
 
 irValue *ir_gen_anonymous_proc_lit(irModule *m, String prefix_name, Ast *expr, irProcedure *proc) {
 irValue *ir_gen_anonymous_proc_lit(irModule *m, String prefix_name, Ast *expr, irProcedure *proc) {
+	auto *found = map_get(&m->anonymous_proc_lits, hash_pointer(expr));
+	if (found != nullptr) {
+		return *found;
+	}
+
 	ast_node(pl, ProcLit, expr);
 	ast_node(pl, ProcLit, expr);
 
 
 	// NOTE(bill): Generate a new name
 	// NOTE(bill): Generate a new name

+ 29 - 22
src/llvm_backend.cpp

@@ -53,6 +53,24 @@ LLVMValueRef llvm_cstring(lbModule *m, String const &str) {
 	return LLVMConstExtractValue(v.value, indices, gb_count_of(indices));
 	return LLVMConstExtractValue(v.value, indices, gb_count_of(indices));
 }
 }
 
 
+bool lb_is_instr_terminating(LLVMValueRef instr) {
+	if (instr != nullptr) {
+		LLVMOpcode op = LLVMGetInstructionOpcode(instr);
+		switch (op) {
+		case LLVMRet:
+		case LLVMBr:
+		case LLVMSwitch:
+		case LLVMIndirectBr:
+		case LLVMInvoke:
+		case LLVMUnreachable:
+		case LLVMCallBr:
+			return true;
+		}
+	}
+	return false;
+}
+
+
 
 
 lbAddr lb_addr(lbValue addr) {
 lbAddr lb_addr(lbValue addr) {
 	lbAddr v = {lbAddr_Default, addr};
 	lbAddr v = {lbAddr_Default, addr};
@@ -2497,7 +2515,7 @@ void lb_end_procedure_body(lbProcedure *p) {
 
 
 	if (p->type->Proc.result_count == 0) {
 	if (p->type->Proc.result_count == 0) {
 	    LLVMValueRef instr = LLVMGetLastInstruction(p->curr_block->block);
 	    LLVMValueRef instr = LLVMGetLastInstruction(p->curr_block->block);
-	    if (!LLVMIsAReturnInst(instr)) {
+	    if (!lb_is_instr_terminating(instr)) {
 	    	lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr);
 	    	lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr);
 			LLVMBuildRetVoid(p->builder);
 			LLVMBuildRetVoid(p->builder);
 		}
 		}
@@ -3882,25 +3900,6 @@ lbValue lb_emit_logical_binary_expr(lbProcedure *p, TokenKind op, Ast *left, Ast
 	return res;
 	return res;
 }
 }
 
 
-
-bool lb_is_instr_terminating(LLVMValueRef instr) {
-
-	if (instr != nullptr) {
-		LLVMOpcode op = LLVMGetInstructionOpcode(instr);
-		switch (op) {
-		case LLVMRet:
-		case LLVMBr:
-		case LLVMSwitch:
-		case LLVMIndirectBr:
-		case LLVMInvoke:
-		case LLVMUnreachable:
-		case LLVMCallBr:
-			return true;
-		}
-	}
-	return false;
-}
-
 void lb_build_stmt(lbProcedure *p, Ast *node) {
 void lb_build_stmt(lbProcedure *p, Ast *node) {
 	if (p->curr_block != nullptr) {
 	if (p->curr_block != nullptr) {
 		LLVMValueRef last_instr = LLVMGetLastInstruction(p->curr_block->block);
 		LLVMValueRef last_instr = LLVMGetLastInstruction(p->curr_block->block);
@@ -4200,7 +4199,7 @@ void lb_build_stmt(lbProcedure *p, Ast *node) {
 				if (e->token.string != "") {
 				if (e->token.string != "") {
 					lbValue *found = map_get(&p->module->values, hash_entity(e));
 					lbValue *found = map_get(&p->module->values, hash_entity(e));
 					GB_ASSERT(found != nullptr);
 					GB_ASSERT(found != nullptr);
-					lb_emit_store(p, *found, res);
+					lb_emit_store(p, *found, lb_emit_conv(p, res, e->type));
 				}
 				}
 			}
 			}
 
 
@@ -4246,7 +4245,7 @@ void lb_build_stmt(lbProcedure *p, Ast *node) {
 					}
 					}
 					lbValue *found = map_get(&p->module->values, hash_entity(e));
 					lbValue *found = map_get(&p->module->values, hash_entity(e));
 					GB_ASSERT(found != nullptr);
 					GB_ASSERT(found != nullptr);
-					lb_emit_store(p, *found, results[i]);
+					lb_emit_store(p, *found, lb_emit_conv(p, results[i], e->type));
 				}
 				}
 			}
 			}
 
 
@@ -8897,6 +8896,14 @@ lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue ri
 
 
 
 
 lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, Ast *expr, lbProcedure *parent) {
 lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, Ast *expr, lbProcedure *parent) {
+	auto *found = map_get(&m->anonymous_proc_lits, hash_pointer(expr));
+	if (found != nullptr) {
+		lbValue value = {};
+		value.value = (*found)->value;
+		value.type = (*found)->type;
+		return value;
+	}
+
 	ast_node(pl, ProcLit, expr);
 	ast_node(pl, ProcLit, expr);
 
 
 	// NOTE(bill): Generate a new name
 	// NOTE(bill): Generate a new name