Browse Source

Fix and clean up default procedure parameter code for non-constant types

gingerBill 4 years ago
parent
commit
609af3a651
6 changed files with 82 additions and 108 deletions
  1. 1 0
      src/check_type.cpp
  2. 2 0
      src/entity.cpp
  3. 38 49
      src/ir.cpp
  4. 38 58
      src/llvm_backend.cpp
  5. 3 0
      src/llvm_backend.hpp
  6. 0 1
      src/types.cpp

+ 1 - 0
src/check_type.cpp

@@ -1370,6 +1370,7 @@ bool is_expr_from_a_parameter(CheckerContext *ctx, Ast *expr) {
 
 ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type **out_type_, Ast *expr, bool allow_caller_location) {
 	ParameterValue param_value = {};
+	param_value.original_ast_expr = expr;
 	if (expr == nullptr) {
 		return param_value;
 	}

+ 2 - 0
src/entity.cpp

@@ -81,6 +81,7 @@ enum ParameterValueKind {
 
 struct ParameterValue {
 	ParameterValueKind kind;
+	Ast *original_ast_expr;
 	union {
 		ExactValue value;
 		Ast *ast_value;
@@ -126,6 +127,7 @@ struct Entity {
 			i32        field_src_index;
 
 			ParameterValue param_value;
+			Ast *          param_expr;
 
 			String     thread_local_model;
 			Entity *   foreign_library;

+ 38 - 49
src/ir.cpp

@@ -7450,8 +7450,43 @@ irValue *ir_build_builtin_proc(irProcedure *proc, Ast *expr, TypeAndValue tv, Bu
 	return nullptr;
 }
 
+
+irValue *ir_handle_param_value(irProcedure *proc, Type *parameter_type, ParameterValue const &param_value, TokenPos const &pos) {
+	switch (param_value.kind) {
+	case ParameterValue_Constant:
+		if (is_type_constant_type(parameter_type)) {
+			return ir_value_constant(parameter_type, param_value.value);
+		} else {
+			ExactValue ev = param_value.value;
+			irValue *arg = nullptr;
+			Type *type = type_of_expr(param_value.original_ast_expr);
+			if (type != nullptr) {
+				arg = ir_value_constant(type, ev);
+			} else {
+				arg = ir_value_constant(parameter_type, param_value.value);
+			}
+			return ir_emit_conv(proc, arg, parameter_type);
+		}
+
+	case ParameterValue_Nil:
+		return ir_value_nil(parameter_type);
+	case ParameterValue_Location:
+		{
+			String proc_name = {};
+			if (proc->entity != nullptr) {
+				proc_name = proc->entity->token.string;
+			}
+			return ir_emit_source_code_location(proc, proc_name, pos);
+		}
+	case ParameterValue_Value:
+		return ir_build_expr(proc, param_value.ast_value);
+	}
+	return ir_value_nil(parameter_type);
+}
+
 irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr);
 
+
 irValue *ir_build_expr(irProcedure *proc, Ast *expr) {
 	u64 prev_state_flags = proc->module->state_flags;
 	defer (proc->module->state_flags = prev_state_flags);
@@ -7562,20 +7597,7 @@ irValue *ir_build_call_expr(irProcedure *proc, Ast *expr) {
 			} else {
 				GB_ASSERT(e->kind == Entity_Variable);
 				if (args[i] == nullptr) {
-					switch (e->Variable.param_value.kind) {
-					case ParameterValue_Constant:
-						args[i] = ir_value_constant(e->type, e->Variable.param_value.value);
-						break;
-					case ParameterValue_Nil:
-						args[i] = ir_value_nil(e->type);
-						break;
-					case ParameterValue_Location:
-						args[i] = ir_emit_source_code_location(proc, proc->entity->token.string, ast_token(expr).pos);
-						break;
-					case ParameterValue_Value:
-						args[i] = ir_build_expr(proc, e->Variable.param_value.ast_value);
-						break;
-					}
+					args[i] = ir_handle_param_value(proc, e->type, e->Variable.param_value, ast_token(expr).pos);
 				} else {
 					args[i] = ir_emit_conv(proc, args[i], e->type);
 				}
@@ -7613,12 +7635,6 @@ irValue *ir_build_call_expr(irProcedure *proc, Ast *expr) {
 	bool vari_expand = ce->ellipsis.pos.line != 0;
 	bool is_c_vararg = pt->c_vararg;
 
-	String proc_name = {};
-	if (proc->entity != nullptr) {
-		proc_name = proc->entity->token.string;
-	}
-	TokenPos pos = ast_token(ce->proc).pos;
-
 	TypeTuple *param_tuple = nullptr;
 	if (pt->params) {
 		GB_ASSERT(pt->params->kind == Type_Tuple);
@@ -7658,21 +7674,7 @@ irValue *ir_build_call_expr(irProcedure *proc, Ast *expr) {
 			while (arg_index < end) {
 				Entity *e = param_tuple->variables[arg_index];
 				GB_ASSERT(e->kind == Entity_Variable);
-
-				switch (e->Variable.param_value.kind) {
-				case ParameterValue_Constant:
-					args[arg_index++] = ir_value_constant(e->type, e->Variable.param_value.value);
-					break;
-				case ParameterValue_Nil:
-					args[arg_index++] = ir_value_nil(e->type);
-					break;
-				case ParameterValue_Location:
-					args[arg_index++] = ir_emit_source_code_location(proc, proc_name, pos);
-					break;
-				case ParameterValue_Value:
-					args[arg_index++] = ir_build_expr(proc, e->Variable.param_value.ast_value);
-					break;
-				}
+				args[arg_index++] = ir_handle_param_value(proc, e->type, e->Variable.param_value, ast_token(expr).pos);
 			}
 		}
 
@@ -7753,20 +7755,7 @@ irValue *ir_build_call_expr(irProcedure *proc, Ast *expr) {
 	if (variadic && variadic_index+1 < param_count) {
 		for (isize i = variadic_index+1; i < param_count; i++) {
 			Entity *e = param_tuple->variables[i];
-			switch (e->Variable.param_value.kind) {
-			case ParameterValue_Constant:
-				args[i] = ir_value_constant(e->type, e->Variable.param_value.value);
-				break;
-			case ParameterValue_Nil:
-				args[i] = ir_value_nil(e->type);
-				break;
-			case ParameterValue_Location:
-				args[i] = ir_emit_source_code_location(proc, proc_name, pos);
-				break;
-			case ParameterValue_Value:
-				args[i] = ir_build_expr(proc, e->Variable.param_value.ast_value);
-				break;
-			}
+			args[i] = ir_handle_param_value(proc, e->type, e->Variable.param_value, ast_token(expr).pos);
 		}
 	}
 

+ 38 - 58
src/llvm_backend.cpp

@@ -370,21 +370,7 @@ void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) {
 			while (arg_index < end) {
 				Entity *e = param_tuple->variables[arg_index];
 				GB_ASSERT(e->kind == Entity_Variable);
-
-				switch (e->Variable.param_value.kind) {
-				case ParameterValue_Constant:
-					args[arg_index++] = lb_const_value(p->module, e->type, e->Variable.param_value.value);
-					break;
-				case ParameterValue_Nil:
-					args[arg_index++] = lb_const_nil(m, e->type);
-					break;
-				case ParameterValue_Location:
-					args[arg_index++] = lb_emit_source_code_location(p, proc_name, pos);
-					break;
-				case ParameterValue_Value:
-					args[arg_index++] = lb_build_expr(p, e->Variable.param_value.ast_value);
-					break;
-				}
+				args[arg_index++] = lb_handle_param_value(p, e->type, e->Variable.param_value, pos);
 			}
 		}
 
@@ -8072,6 +8058,40 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
 }
 
 
+lbValue lb_handle_param_value(lbProcedure *p, Type *parameter_type, ParameterValue const &param_value, TokenPos const &pos) {
+	switch (param_value.kind) {
+	case ParameterValue_Constant:
+		if (is_type_constant_type(parameter_type)) {
+			return lb_const_value(p->module, parameter_type, param_value.value);
+		} else {
+			ExactValue ev = param_value.value;
+			lbValue arg = {};
+			Type *type = type_of_expr(param_value.original_ast_expr);
+			if (type != nullptr) {
+				arg = lb_const_value(p->module, type, ev);
+			} else {
+				arg = lb_const_value(p->module, parameter_type, param_value.value);
+			}
+			return lb_emit_conv(p, arg, parameter_type);
+		}
+
+	case ParameterValue_Nil:
+		return lb_const_nil(p->module, parameter_type);
+	case ParameterValue_Location:
+		{
+			String proc_name = {};
+			if (p->entity != nullptr) {
+				proc_name = p->entity->token.string;
+			}
+			return lb_emit_source_code_location(p, proc_name, pos);
+		}
+	case ParameterValue_Value:
+		return lb_build_expr(p, param_value.ast_value);
+	}
+	return lb_const_nil(p->module, parameter_type);
+}
+
+
 lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) {
 	lbModule *m = p->module;
 
@@ -8166,20 +8186,7 @@ lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) {
 			} else {
 				GB_ASSERT(e->kind == Entity_Variable);
 				if (args[i].value == nullptr) {
-					switch (e->Variable.param_value.kind) {
-					case ParameterValue_Constant:
-						args[i] = lb_const_value(p->module, e->type, e->Variable.param_value.value);
-						break;
-					case ParameterValue_Nil:
-						args[i] = lb_const_nil(m, e->type);
-						break;
-					case ParameterValue_Location:
-						args[i] = lb_emit_source_code_location(p, p->entity->token.string, ast_token(expr).pos);
-						break;
-					case ParameterValue_Value:
-						args[i] = lb_build_expr(p, e->Variable.param_value.ast_value);
-						break;
-					}
+					args[i] = lb_handle_param_value(p, e->type, e->Variable.param_value, ast_token(expr).pos);
 				} else {
 					args[i] = lb_emit_conv(p, args[i], e->type);
 				}
@@ -8273,21 +8280,7 @@ lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) {
 			while (arg_index < end) {
 				Entity *e = param_tuple->variables[arg_index];
 				GB_ASSERT(e->kind == Entity_Variable);
-
-				switch (e->Variable.param_value.kind) {
-				case ParameterValue_Constant:
-					args[arg_index++] = lb_const_value(p->module, e->type, e->Variable.param_value.value);
-					break;
-				case ParameterValue_Nil:
-					args[arg_index++] = lb_const_nil(m, e->type);
-					break;
-				case ParameterValue_Location:
-					args[arg_index++] = lb_emit_source_code_location(p, proc_name, pos);
-					break;
-				case ParameterValue_Value:
-					args[arg_index++] = lb_build_expr(p, e->Variable.param_value.ast_value);
-					break;
-				}
+				args[arg_index++] = lb_handle_param_value(p, e->type, e->Variable.param_value, ast_token(expr).pos);
 			}
 		}
 
@@ -8371,20 +8364,7 @@ lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) {
 	if (variadic && variadic_index+1 < param_count) {
 		for (isize i = variadic_index+1; i < param_count; i++) {
 			Entity *e = param_tuple->variables[i];
-			switch (e->Variable.param_value.kind) {
-			case ParameterValue_Constant:
-				args[i] = lb_const_value(p->module, e->type, e->Variable.param_value.value);
-				break;
-			case ParameterValue_Nil:
-				args[i] = lb_const_nil(m, e->type);
-				break;
-			case ParameterValue_Location:
-				args[i] = lb_emit_source_code_location(p, proc_name, pos);
-				break;
-			case ParameterValue_Value:
-				args[i] = lb_build_expr(p, e->Variable.param_value.ast_value);
-				break;
-			}
+			args[i] = lb_handle_param_value(p, e->type, e->Variable.param_value, ast_token(expr).pos);
 		}
 	}
 

+ 3 - 0
src/llvm_backend.hpp

@@ -352,6 +352,9 @@ void lb_store_type_case_implicit(lbProcedure *p, Ast *clause, lbValue value);
 lbAddr lb_store_range_stmt_val(lbProcedure *p, Ast *stmt_val, lbValue value);
 lbValue lb_emit_source_code_location(lbProcedure *p, String const &procedure, TokenPos const &pos);
 
+lbValue lb_handle_param_value(lbProcedure *p, Type *parameter_type, ParameterValue const &param_value, TokenPos const &pos);
+
+
 #define LB_STARTUP_RUNTIME_PROC_NAME   "__$startup_runtime"
 #define LB_STARTUP_TYPE_INFO_PROC_NAME "__$startup_type_info"
 #define LB_TYPE_INFO_DATA_NAME       "__$type_info_data"

+ 0 - 1
src/types.cpp

@@ -953,7 +953,6 @@ Type *alloc_type_simd_vector(i64 count, Type *elem) {
 
 
 
-
 ////////////////////////////////////////////////////////////////