Browse Source

Allow for default parameters that are non-constant entities, but not any non-constant expression

gingerBill 7 years ago
parent
commit
ae2af8315e
3 changed files with 30 additions and 7 deletions
  1. 16 6
      src/check_type.cpp
  2. 5 1
      src/entity.cpp
  3. 9 0
      src/ir.cpp

+ 16 - 6
src/check_type.cpp

@@ -1038,7 +1038,8 @@ ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type *
 				param_value.value = exact_value_procedure(expr);
 			} else {
 				Entity *e = nullptr;
-				if (o.mode == Addressing_Value && is_type_proc(o.type)) {
+				// if (o.mode == Addressing_Value && is_type_proc(o.type)) {
+				if (o.mode == Addressing_Value || o.mode == Addressing_Variable) {
 					Operand x = {};
 					if (expr->kind == Ast_Ident) {
 						e = check_ident(ctx, &x, expr, nullptr, nullptr, false);
@@ -1047,12 +1048,21 @@ ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type *
 					}
 				}
 
-				if (e != nullptr && e->kind == Entity_Procedure) {
-					param_value.kind = ParameterValue_Constant;
-					param_value.value = exact_value_procedure(e->identifier);
-					add_entity_use(ctx, e->identifier, e);
+				if (e != nullptr) {
+					if (e->kind == Entity_Procedure) {
+						param_value.kind = ParameterValue_Constant;
+						param_value.value = exact_value_procedure(e->identifier);
+						add_entity_use(ctx, e->identifier, e);
+					} else {
+						param_value.kind = ParameterValue_Value;
+						param_value.ast_value = expr;
+						add_entity_use(ctx, e->identifier, e);
+					}
+				} else if (allow_caller_location && o.mode == Addressing_Context) {
+					param_value.kind = ParameterValue_Value;
+					param_value.ast_value = expr;
 				} else {
-					error(expr, "Default parameter must be a constant %d", o.mode);
+					error(expr, "Default parameter must be a constant");
 				}
 			}
 		} else {

+ 5 - 1
src/entity.cpp

@@ -62,11 +62,15 @@ enum ParameterValueKind {
 	ParameterValue_Constant,
 	ParameterValue_Nil,
 	ParameterValue_Location,
+	ParameterValue_Value,
 };
 
 struct ParameterValue {
 	ParameterValueKind kind;
-	ExactValue value;
+	union {
+		ExactValue value;
+		Ast *ast_value;
+	};
 };
 
 

+ 9 - 0
src/ir.cpp

@@ -5128,6 +5128,9 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) {
 							// args[i] =
 							GB_PANIC("TODO ParameterValue_Location");
 							break;
+						case ParameterValue_Value:
+							args[i] = ir_build_expr(proc, e->Variable.param_value.ast_value);
+							break;
 						}
 					} else {
 						args[i] = ir_emit_conv(proc, args[i], e->type);
@@ -5221,6 +5224,9 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) {
 					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;
 					}
 				}
 			}
@@ -5312,6 +5318,9 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) {
 				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;
 				}
 			}
 		}