Browse Source

Begin to handle split arguments correctly

gingerBill 2 years ago
parent
commit
15a0d9f900
1 changed files with 273 additions and 275 deletions
  1. 273 275
      src/check_expr.cpp

+ 273 - 275
src/check_expr.cpp

@@ -66,7 +66,7 @@ gb_internal int valid_index_and_score_cmp(void const *a, void const *b) {
 
 
 
-#define CALL_ARGUMENT_CHECKER(name) CallArgumentError name(CheckerContext *c, Ast *call, Type *proc_type, Entity *entity, Array<Operand> operands, Array<Operand> const &named_operands, CallArgumentErrorMode show_error_mode, CallArgumentData *data)
+#define CALL_ARGUMENT_CHECKER(name) CallArgumentError name(CheckerContext *c, Ast *call, Type *proc_type, Entity *entity, Array<Operand> positional_operands, Array<Operand> const &named_operands, CallArgumentErrorMode show_error_mode, CallArgumentData *data)
 typedef CALL_ARGUMENT_CHECKER(CallArgumentCheckerType);
 
 
@@ -5351,77 +5351,280 @@ gb_internal CALL_ARGUMENT_CHECKER(check_call_arguments_internal) {
 	i64 score = 0;
 	bool show_error = show_error_mode == CallArgumentMode_ShowErrors;
 
-	auto ordered_operands = array_make<Operand>(temporary_allocator(), pt->param_count);
-	bool *visited = gb_alloc_array(temporary_allocator(), bool, pt->param_count);
+	Type *final_proc_type = proc_type;
+	Entity *gen_entity = nullptr;
+
+	if (vari_expand && !variadic) {
+		if (show_error) {
+			error(ce->ellipsis,
+			      "Cannot use '..' in call to a non-variadic procedure: '%.*s'",
+			      LIT(ce->proc->Ident.token.string));
+		}
+		err = CallArgumentError_NonVariadicExpand;
+	} else if (vari_expand && pt->c_vararg) {
+		if (show_error) {
+			error(ce->ellipsis,
+			      "Cannot use '..' in call to a '#c_vararg' variadic procedure: '%.*s'",
+			      LIT(ce->proc->Ident.token.string));
+		}
+		err = CallArgumentError_NonVariadicExpand;
+	}
 
 	if (ce->split_args) {
-		GB_ASSERT(ce->split_args->named.count == named_operands.count);
-		for_array(i, ce->split_args->named) {
-			Ast *arg = ce->split_args->named[i];
-			Operand operand = named_operands[i];
+		auto ordered_operands = array_make<Operand>(temporary_allocator(), pt->param_count);
+		auto visited = slice_make<bool>(temporary_allocator(), pt->param_count);
 
-			ast_node(fv, FieldValue, arg);
-			if (fv->field->kind != Ast_Ident) {
-				if (show_error) {
-					gbString expr_str = expr_to_string(fv->field);
-					error(arg, "Invalid parameter name '%s' in procedure call", expr_str);
-					gb_string_free(expr_str);
+		isize positional_operand_count = positional_operands.count;
+		if (variadic) {
+			positional_operand_count = gb_min(positional_operands.count, pt->variadic_index);
+		} else if (positional_operand_count > pt->param_count) {
+			err = CallArgumentError_TooManyArguments;
+			char const *err_fmt = "Too many arguments for '%s', expected %td arguments, got %td";
+			if (show_error) {
+				gbString proc_str = expr_to_string(ce->proc);
+				defer (gb_string_free(proc_str));
+				error(call, err_fmt, proc_str, param_count_excluding_defaults, positional_operands.count);
+			}
+			return err;
+		}
+		positional_operand_count = gb_min(positional_operand_count, pt->param_count);
+
+		for (isize i = 0; i < positional_operand_count; i++) {
+			ordered_operands[i] = positional_operands[i];
+			visited[i] = true;
+		}
+
+		auto variadic_operands = slice(slice_from_array(positional_operands), positional_operand_count, positional_operands.count);
+
+		if (named_operands.count != 0) {
+			GB_ASSERT(ce->split_args->named.count == named_operands.count);
+			for_array(i, ce->split_args->named) {
+				Ast *arg = ce->split_args->named[i];
+				Operand operand = named_operands[i];
+
+				ast_node(fv, FieldValue, arg);
+				if (fv->field->kind != Ast_Ident) {
+					if (show_error) {
+						gbString expr_str = expr_to_string(fv->field);
+						error(arg, "Invalid parameter name '%s' in procedure call", expr_str);
+						gb_string_free(expr_str);
+					}
+					err = CallArgumentError_InvalidFieldValue;
+					continue;
 				}
-				err = CallArgumentError_InvalidFieldValue;
-				continue;
+				String name = fv->field->Ident.token.string;
+				isize param_index = lookup_procedure_parameter(pt, name);
+				if (param_index < 0) {
+					if (show_error) {
+						error(arg, "No parameter named '%.*s' for this procedure type", LIT(name));
+					}
+					err = CallArgumentError_ParameterNotFound;
+					continue;
+				}
+				if (visited[param_index]) {
+					if (show_error) {
+						error(arg, "Duplicate parameter '%.*s' in procedure call", LIT(name));
+					}
+					err = CallArgumentError_DuplicateParameter;
+					continue;
+				}
+				Entity *e = pt->params->Tuple.variables[param_index];
+
+				check_assignment(c, &operand, e->type, str_lit("named argument"));
+
+				visited[param_index] = true;
+				ordered_operands[param_index] = operand;
+
+				err = CallArgumentError_DuplicateParameter;
 			}
-			String name = fv->field->Ident.token.string;
-			isize param_index = lookup_procedure_parameter(pt, name);
-			if (param_index < 0) {
+		}
+
+		if (variadic) {
+			if (visited[pt->variadic_index] &&
+			    positional_operand_count < positional_operands.count) {
 				if (show_error) {
-					error(arg, "No parameter named '%.*s' for this procedure type", LIT(name));
+					String name = pt->params->Tuple.variables[pt->variadic_index]->token.string;
+					error(call, "Variadic parameters already handled with a named argument '%.*s' in procedure call", LIT(name));
 				}
-				err = CallArgumentError_ParameterNotFound;
-				continue;
+				err = CallArgumentError_DuplicateParameter;
+			} else {
+				visited[pt->variadic_index] = true;
+			}
+
+		}
+
+
+		for (Operand const &o : ordered_operands) {
+			if (o.mode != Addressing_Invalid) {
+				check_no_copy_assignment(o, str_lit("procedure call expression"));
 			}
-			if (visited[param_index]) {
+		}
+
+		for (isize i = 0; i < pt->param_count; i++) {
+			if (!visited[i]) {
+				Entity *e = pt->params->Tuple.variables[i];
+				if (is_blank_ident(e->token)) {
+					continue;
+				}
+				if (e->kind == Entity_Variable) {
+					if (e->Variable.param_value.kind != ParameterValue_Invalid) {
+						score += assign_score_function(1);
+						continue;
+					}
+				}
+
 				if (show_error) {
-					error(arg, "Duplicate parameter '%.*s' in procedure call", LIT(name));
+					if (e->kind == Entity_TypeName) {
+						error(call, "Type parameter '%.*s' is missing in procedure call",
+						      LIT(e->token.string));
+					} else if (e->kind == Entity_Constant && e->Constant.value.kind != ExactValue_Invalid) {
+						// Ignore
+					} else {
+						gbString str = type_to_string(e->type);
+						error(call, "Parameter '%.*s' of type '%s' is missing in procedure call",
+						      LIT(e->token.string), str);
+						gb_string_free(str);
+					}
 				}
-				err = CallArgumentError_DuplicateParameter;
-				continue;
+				err = CallArgumentError_ParameterMissing;
 			}
+		}
 
-			visited[param_index] = true;
-			ordered_operands[param_index] = operand;
+		if (ordered_operands.count == 0 && param_count_excluding_defaults == 0) {
+			err = CallArgumentError_None;
 
-			err = CallArgumentError_DuplicateParameter;
+			if (variadic) {
+				GB_ASSERT(pt->params != nullptr && pt->params->Tuple.variables.count > 0);
+				Type *t = pt->params->Tuple.variables[0]->type;
+				if (is_type_polymorphic(t)) {
+					error(call, "Ambiguous call to a polymorphic variadic procedure with no variadic input");
+					err = CallArgumentError_AmbiguousPolymorphicVariadic;
+				}
+			}
+		} else {
+			if (pt->is_polymorphic && !pt->is_poly_specialized && err == CallArgumentError_None) {
+				PolyProcData poly_proc_data = {};
+				if (find_or_generate_polymorphic_procedure_from_parameters(c, entity, &ordered_operands, call, &poly_proc_data)) {
+					gen_entity = poly_proc_data.gen_entity;
+					Type *gept = base_type(gen_entity->type);
+					GB_ASSERT(is_type_proc(gept));
+					proc_type = gept;
+					pt = &gept->Proc;
+				} else {
+					err = CallArgumentError_WrongTypes;
+				}
+			}
+
+			for (isize i = 0; i < pt->param_count; i++) {
+				Entity *e = pt->params->Tuple.variables[i];
+				Operand *o = &ordered_operands[i];
+				bool param_is_variadic = pt->variadic && pt->variadic_index == i;
+
+				if (o->mode == Addressing_Invalid) {
+					if (param_is_variadic) {
+						Type *slice = e->type;
+						GB_ASSERT(is_type_slice(slice));
+						Type *elem = base_type(slice)->Slice.elem;
+
+						if (variadic_operands.count == 0) {
+							if (is_type_polymorphic(elem)) {
+								error(call, "Ambiguous call to a polymorphic variadic procedure with no variadic input");
+								err = CallArgumentError_AmbiguousPolymorphicVariadic;
+								return err;
+							}
+						} else {
+							if (vari_expand) {
+								GB_ASSERT(variadic_operands.count == 1);
+								check_assignment(c, &variadic_operands[0], slice, str_lit("variadic expanded argument"));
+							} else {
+								for (Operand &vo : variadic_operands) {
+									check_assignment(c, &vo, elem, str_lit("variadic argument"));
+								}
+							}
+						}
+					}
+					continue;
+				}
+
+				if (e->kind == Entity_TypeName) {
+					GB_ASSERT(pt->is_polymorphic);
+					if (o->mode != Addressing_Type) {
+						if (show_error) {
+							error(o->expr, "Expected a type for the argument '%.*s'", LIT(e->token.string));
+						}
+						err = CallArgumentError_WrongTypes;
+					}
+					if (are_types_identical(e->type, o->type)) {
+						score += assign_score_function(1);
+					} else {
+						score += assign_score_function(MAXIMUM_TYPE_DISTANCE);
+					}
+				} else {
+					i64 s = 0;
+					if (!check_is_assignable_to_with_score(c, o, e->type, &s, param_is_variadic)) {
+						bool ok = false;
+						if (ok) {
+							s = assign_score_function(MAXIMUM_TYPE_DISTANCE);
+						} else {
+							if (show_error) {
+								check_assignment(c, o, e->type, str_lit("procedure argument"));
+							}
+							err = CallArgumentError_WrongTypes;
+						}
+
+						if (e->flags & EntityFlag_ConstInput) {
+							if (o->mode != Addressing_Constant) {
+								if (show_error) {
+									error(o->expr, "Expected a constant value for the argument '%.*s'", LIT(e->token.string));
+								}
+								err = CallArgumentError_NoneConstantParameter;
+							}
+						}
+					} else if (show_error) {
+						check_assignment(c, o, e->type, str_lit("procedure argument"));
+					}
+					score += s;
+				}
+
+				if (o->mode == Addressing_Type && is_type_typeid(e->type)) {
+					add_type_info_type(c, o->type);
+					add_type_and_value(c, o->expr, Addressing_Value, e->type, exact_value_typeid(o->type));
+				}
+			}
 		}
-		if (err) {
-			return err;
+
+		if (data) {
+			data->score = score;
+			data->result_type = final_proc_type->Proc.results;
+			data->gen_entity = gen_entity;
+
+
+			Ast *proc_lit = nullptr;
+			if (ce->proc->tav.value.kind == ExactValue_Procedure) {
+				Ast *vp = unparen_expr(ce->proc->tav.value.value_procedure);
+				if (vp && vp->kind == Ast_ProcLit) {
+					proc_lit = vp;
+				}
+			}
+			if (proc_lit == nullptr) {
+				add_type_and_value(c, ce->proc, Addressing_Value, final_proc_type, {});
+			}
 		}
+
+		return err;
 	}
 
+	if (err) {
+		return err;
+	}
 
+	auto operands = positional_operands;
 	TypeTuple *param_tuple = nullptr;
 	if (pt->params != nullptr) {
 		param_tuple = &pt->params->Tuple;
 	}
 
-
-	Type *final_proc_type = proc_type;
-	Entity *gen_entity = nullptr;
-
-	if (vari_expand && !variadic) {
-		if (show_error) {
-			error(ce->ellipsis,
-			      "Cannot use '..' in call to a non-variadic procedure: '%.*s'",
-			      LIT(ce->proc->Ident.token.string));
-		}
-		err = CallArgumentError_NonVariadicExpand;
-	} else if (vari_expand && pt->c_vararg) {
-		if (show_error) {
-			error(ce->ellipsis,
-			      "Cannot use '..' in call to a '#c_vararg' variadic procedure: '%.*s'",
-			      LIT(ce->proc->Ident.token.string));
-		}
-		err = CallArgumentError_NonVariadicExpand;
-	} else if (operands.count == 0 && param_count_excluding_defaults == 0) {
+	if (operands.count == 0 && param_count_excluding_defaults == 0) {
 		err = CallArgumentError_None;
 
 		if (variadic) {
@@ -5641,6 +5844,7 @@ gb_internal bool is_call_expr_field_value(AstCallExpr *ce) {
 }
 
 gb_internal CALL_ARGUMENT_CHECKER(check_named_call_arguments) {
+	auto operands = positional_operands;
 	ast_node(ce, CallExpr, call);
 	GB_ASSERT(is_type_proc(proc_type));
 	proc_type = base_type(proc_type);
@@ -6705,37 +6909,26 @@ gb_internal CallArgumentData check_call_arguments_new_and_improved(CheckerContex
 			return data;
 		}
 
+		// if (pt->variadic) {
+		// 	isize param_index = pt->variadic_index;
 
-		for_array(i, positional_operands) {
-			Operand &o = positional_operands[i];
-			isize param_index = i;
+		// 	Entity *e = pt->params->Tuple.variables[param_index];
+		// 	GB_ASSERT(e->kind == Entity_Variable);
+		// 	GB_ASSERT(e->flags & EntityFlag_Ellipsis);
+		// 	GB_ASSERT(is_type_slice(e->type));
 
-			Entity *e = pt->params->Tuple.variables[param_index];
-			GB_ASSERT(e->kind == Entity_Variable);
-
-			check_assignment(c, &o, e->type, str_lit("procedure call expression"));
-		}
-
-		if (pt->variadic) {
-			isize param_index = pt->variadic_index;
-
-			Entity *e = pt->params->Tuple.variables[param_index];
-			GB_ASSERT(e->kind == Entity_Variable);
-			GB_ASSERT(e->flags & EntityFlag_Ellipsis);
-			GB_ASSERT(is_type_slice(e->type));
-
-			if (vari_expand) {
-				if (variadic_operands.count != 0) {
-					GB_ASSERT(variadic_operands.count == 1);
-					check_assignment(c, &variadic_operands[0], e->type, str_lit("procedure call expression"));
-				}
-			} else {
-				Type *elem = e->type->Slice.elem;
-				for (Operand &o : variadic_operands) {
-					check_assignment(c, &o, elem, str_lit("procedure call expression"));
-				}
-			}
-		}
+		// 	if (vari_expand) {
+		// 		if (variadic_operands.count != 0) {
+		// 			GB_ASSERT(variadic_operands.count == 1);
+		// 			check_assignment(c, &variadic_operands[0], e->type, str_lit("procedure call expression"));
+		// 		}
+		// 	} else {
+		// 		Type *elem = e->type->Slice.elem;
+		// 		for (Operand &o : variadic_operands) {
+		// 			check_assignment(c, &o, elem, str_lit("procedure call expression"));
+		// 		}
+		// 	}
+		// }
 
 		array_resize(&positional_operands, pt->param_count);
 
@@ -6770,68 +6963,6 @@ gb_internal CallArgumentData check_call_arguments_new_and_improved(CheckerContex
 			array_add(&named_parameters, NamedParameter{name, fv->value});
 		}
 
-		StringMap<Type *> type_hint_map = {}; // Key: String
-		string_map_init(&type_hint_map, 2*named_args.count);
-		defer (string_map_destroy(&type_hint_map));
-
-		if (pt != nullptr) {
-			TypeTuple *param_tuple = &pt->params->Tuple;
-			for (Entity *e : param_tuple->variables) {
-				if (is_blank_ident(e->token)) {
-					continue;
-				}
-				string_map_set(&type_hint_map, e->token.string, e->type);
-			}
-		} else if (operand->mode == Addressing_ProcGroup) {
-			Array<Entity *> procs = proc_group_entities(c, *operand);
-			for (Entity *proc : procs) {
-				Type *proc_type = base_type(proc->type);
-				if (is_type_proc(proc_type)) {
-					TypeProc *pt = &proc_type->Proc;
-					TypeTuple *param_tuple = nullptr;
-					if (pt->params != nullptr) {
-						param_tuple = &pt->params->Tuple;
-					}
-					if (param_tuple == nullptr) {
-						continue;
-					}
-					for (Entity *e : param_tuple->variables) {
-						if (is_blank_ident(e->token)) {
-							continue;
-						}
-						StringHashKey key = string_hash_string(e->token.string);
-						Type **found = string_map_get(&type_hint_map, key);
-						if (found) {
-							Type *t = *found;
-							if (t == nullptr) {
-								// NOTE(bill): Ambiguous named parameter across all types
-								continue;
-							}
-							if (are_types_identical(t, e->type)) {
-								// NOTE(bill): No need to set again
-							} else {
-								// NOTE(bill): Ambiguous named parameter across all types so set it to a nullptr
-								string_map_set(&type_hint_map, key, cast(Type *)nullptr);
-							}
-						} else {
-							string_map_set(&type_hint_map, key, e->type);
-						}
-					}
-				}
-			}
-		}
-
-		for (NamedParameter &param : named_parameters) {
-			Type *type_hint = nullptr;
-			if (Type **found = string_map_get(&type_hint_map, param.key)) {
-				type_hint = *found;
-			}
-
-			Operand operand = {};
-			check_expr_or_type(c, &operand, param.value, type_hint);
-			array_add(&named_operands, operand);
-		}
-
 		for (NamedParameter const &param : named_parameters) {
 			isize param_index = lookup_procedure_parameter(pt, param.key);
 			if (param_index < 0) {
@@ -6856,11 +6987,10 @@ gb_internal CallArgumentData check_call_arguments_new_and_improved(CheckerContex
 				any_failure = true;
 			}
 
-			check_assignment(c, &o, e->type, str_lit("procedure call expression"));
-
 			if (!prev_visited) {
 				positional_operands[param_index] = o;
 			}
+			array_add(&named_operands, o);
 		}
 
 	}
@@ -6891,17 +7021,6 @@ gb_internal CallArgumentData check_call_arguments_new_and_improved(CheckerContex
 		}
 	}
 
-	for (Operand const &o : positional_operands) {
-		check_no_copy_assignment(o, str_lit("procedure call expression"));
-	}
-	for (Operand const &o : variadic_operands) {
-		check_no_copy_assignment(o, str_lit("procedure call expression"));
-	}
-	for (Operand const &o : named_operands) {
-		check_no_copy_assignment(o, str_lit("procedure call expression"));
-	}
-
-
 	if (any_failure) {
 		return data;
 	}
@@ -6917,7 +7036,7 @@ gb_internal CallArgumentData check_call_arguments_new_and_improved(CheckerContex
 
 		Array<Operand> operands = array_clone(heap_allocator(), positional_operands);
 
-		CallArgumentError err = check_call_arguments_internal(c, call, proc_type, e, operands, named_operands, CallArgumentMode_ShowErrors, &data);
+		CallArgumentError err = check_call_arguments_internal(c, call, proc_type, e, operands, {}, CallArgumentMode_ShowErrors, &data);
 		gb_unused(err);
 		Entity *entity_to_use = data.gen_entity != nullptr ? data.gen_entity : e;
 		add_entity_use(c, ident, entity_to_use);
@@ -6948,127 +7067,6 @@ gb_internal CallArgumentData check_call_arguments_new_and_improved(CheckerContex
 		data.result_type = pt->results;
 	}
 	return data;
-#if 0
-
-
-
-	/*
-	auto visited = slice_make<bool>(temporary_allocator(), pt->param_count);
-	auto ordered_values = slice_make<ParameterValue>(temporary_allocator(), pt->param_count);
-
-
-	for_array(i, ce->args) {
-		Ast *arg = ce->args[i];
-
-		isize param_index = i;
-		String param_name = {};
-
-		if (arg->kind == Ast_FieldValue) {
-			ast_node(fv, FieldValue, arg);
-			if (fv->field->kind != Ast_Ident) {
-				gbString expr_str = expr_to_string(fv->field);
-				error(arg, "Invalid parameter name '%s' in procedure call", expr_str);
-				any_failure = true;
-				gb_string_free(expr_str);
-				continue;
-			}
-			param_name = fv->field->Ident.token.string;
-			param_index = lookup_procedure_parameter(pt, param_name);
-			if (param_index < 0) {
-				error(arg, "No parameter named '%.*s' for this procedure type", LIT(param_name));
-				any_failure = true;
-				continue;
-			}
-			arg = fv->value;
-		} else {
-			if (param_index >= pt->param_count) {
-				error(arg, "Too many parameters in procedure call, expected a maximum of %td, got %td", pt->param_count, ce->args.count);
-				any_failure = true;
-				break;
-			}
-
-			param_name = pt->params->Tuple.variables[param_index]->token.string;
-		}
-		if (visited[param_index]) {
-			error(arg, "Duplicate parameter '%.*s' in procedure call", LIT(param_name));
-			any_failure = true;
-		} else {
-			ParameterValue value = {};
-			value.kind = ParameterValue_Value;
-			value.original_ast_expr = arg;
-			value.ast_value = arg;
-			ordered_values[param_index] = value;
-		}
-		visited[param_index] = true;
-	}
-
-	for (isize i = 0; i < pt->param_count; i++) {
-		if (!visited[i]) {
-			Entity *e = pt->params->Tuple.variables[i];
-			if (e->kind == Entity_Variable &&
-			    has_parameter_value(e->Variable.param_value)) {
-				ordered_values[i] = e->Variable.param_value;
-				visited[i] = true;
-			}
-		}
-	}
-
-	for (isize i = 0; i < visited.count; i++) {
-		if (!visited[i]) {
-			Entity *e = pt->params->Tuple.variables[i];
-			gbString t = type_to_string(e->type);
-			defer (gb_string_free(t));
-			if (is_blank_ident(e->token)) {
-				error(call, "Missing parameter of type '%s' at index %td", t, i);
-			} else {
-				error(call, "Missing parameter '%.*s' of type '%s'", LIT(e->token.string), t, i);
-			}
-			return data;
-		}
-	}
-	*/
-	if (any_failure) {
-		return data;
-	}
-
-	Array<Operand> operands = {};
-	defer (array_free(&operands));
-
-	Ast *ident = unparen_expr(operand->expr);
-	while (ident->kind == Ast_SelectorExpr) {
-		Ast *s = ident->SelectorExpr.selector;
-		ident = unparen_expr(s);
-	}
-
-	Entity *e = entity_of_node(ident);
-
-	CallArgumentError err = check_call_arguments_internal(c, call, proc_type, e, operands, CallArgumentMode_ShowErrors, &data);
-	gb_unused(err);
-	Entity *entity_to_use = data.gen_entity != nullptr ? data.gen_entity : e;
-	add_entity_use(c, ident, entity_to_use);
-	if (entity_to_use != nullptr) {
-		update_untyped_expr_type(c, operand->expr, entity_to_use->type, true);
-	}
-	if (data.gen_entity != nullptr) {
-		Entity *e = data.gen_entity;
-		DeclInfo *decl = data.gen_entity->decl_info;
-		CheckerContext ctx = *c;
-		ctx.scope = decl->scope;
-		ctx.decl = decl;
-		ctx.proc_name = e->token.string;
-		ctx.curr_proc_decl = decl;
-		ctx.curr_proc_sig  = e->type;
-
-		GB_ASSERT(decl->proc_lit->kind == Ast_ProcLit);
-		bool ok = evaluate_where_clauses(&ctx, call, decl->scope, &decl->proc_lit->ProcLit.where_clauses, true);
-		decl->where_clauses_evaluated = true;
-
-		if (ok && (data.gen_entity->flags & EntityFlag_ProcBodyChecked) == 0) {
-			check_procedure_later(c->checker, e->file, e->token, decl, e->type, decl->proc_lit->ProcLit.body, decl->proc_lit->ProcLit.tags);
-		}
-	}
-	return data;
-#endif
 }