~sircmpwn/hare-dev

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
9 3

[PATCH harec v3 1/8] scan_decl: insert @flag functions with generated name

Details
Message ID
<20230207043208.29916-1-tb46305@gmail.com>
DKIM signature
pass
Download raw message
Patch: +24 -7
name generation in gen will be removed in a later commit

Signed-off-by: Armin Weigl <tb46305@gmail.com>
---
 src/check.c | 31 ++++++++++++++++++++++++-------
 1 file changed, 24 insertions(+), 7 deletions(-)

diff --git a/src/check.c b/src/check.c
index e814a09..f771b44 100644
--- a/src/check.c
+++ b/src/check.c
@@ -4089,16 +4089,33 @@ scan_decl(struct context *ctx, struct scope *imports, struct ast_decl *decl)
			idecl->imports = imports;
		}
		break;
	case AST_DECL_FUNC:
		if (decl->function.flags) {
			return;
		}
	case AST_DECL_FUNC:;
		struct ast_function_decl *func = &decl->function;
		struct identifier with_ns = {0};
		mkident(ctx, &with_ns, &func->ident, func->symbol);
		struct identifier ident = {0}, *name = NULL;
		if (func->flags) {
			const char *template = NULL;
			if (func->flags & FN_TEST) {
				template = "testfunc.%d";
			} else if (func->flags & FN_INIT) {
				template = "initfunc.%d";
			} else if (func->flags & FN_FINI) {
				template = "finifunc.%d";
			}
			assert(template);

			int n = snprintf(NULL, 0, template, ctx->id);
			ident.name = xcalloc(n + 1, 1);
			snprintf(ident.name, n + 1, template, ctx->id);
			++ctx->id;

			name = &ident;
		} else {
			mkident(ctx, &ident, &func->ident, func->symbol);
			name = &func->ident;
		}
		struct incomplete_declaration *idecl =
			incomplete_declaration_create(ctx, decl->loc,
					ctx->scope, &with_ns, &func->ident);
					ctx->scope, &ident, name);
		idecl->type = IDECL_DECL;
		idecl->decl = (struct ast_decl){
			.decl_type = AST_DECL_FUNC,

base-commit: 847cf9b70c80ed7df4cb062956b9ab12c9ebb88c
-- 
2.39.1

[PATCH harec v3 2/8] check: keep defines in their own scope

Details
Message ID
<20230207043208.29916-2-tb46305@gmail.com>
In-Reply-To
<20230207043208.29916-1-tb46305@gmail.com> (view parent)
DKIM signature
pass
Download raw message
Patch: +15 -25
This has multiple effects:
	- All objects in SCOPE_UNIT are now guaranteed to be
	  incomplete_declarations, which is a prerequisite for a later
	  patch.
	- Defines are no longer (redundantly) imported from
	  type definitions.

Signed-off-by: Armin Weigl <tb46305@gmail.com>
---
 docs/declaration_solver.txt |  2 +-
 include/check.h             |  1 +
 include/scope.h             |  1 +
 src/check.c                 | 34 +++++++++++-----------------------
 tests/36-defines.ha         |  2 +-
 5 files changed, 15 insertions(+), 25 deletions(-)

diff --git a/docs/declaration_solver.txt b/docs/declaration_solver.txt
index b55fa1f..531f51b 100644
--- a/docs/declaration_solver.txt
+++ b/docs/declaration_solver.txt
@@ -20,7 +20,7 @@ in this algorithm. Enum types never have dependencies and can be completed
on the spot. Enum values are put into a special scope that is created for each
enum type and marked incomplete.

At this point the defines can be copied from the dedicated scope into the unit
At this point the dedicated scope for defines is reparented on the unit
scope, shadowing the declarations from the source files.

Next, aliases of enum types are detected and taken care of. Because an enum
diff --git a/include/check.h b/include/check.h
index fcc17ae..d9c7e24 100644
--- a/include/check.h
+++ b/include/check.h
@@ -33,6 +33,7 @@ struct context {
	bool is_test;
	struct scope *unit;
	struct scope *scope;
	struct scope *defines;
	bool deferring;
	int id;
	struct errors *errors;
diff --git a/include/scope.h b/include/scope.h
index 8a74582..55f0223 100644
--- a/include/scope.h
+++ b/include/scope.h
@@ -35,6 +35,7 @@ enum scope_class {
	SCOPE_MATCH,
	SCOPE_SUBUNIT,
	SCOPE_UNIT,
	SCOPE_DEFINES,
};

struct expression;
diff --git a/src/check.c b/src/check.c
index f771b44..3a8ff34 100644
--- a/src/check.c
+++ b/src/check.c
@@ -3325,7 +3325,7 @@ check_const(struct context *ctx,
	}
	struct declaration *decl = xcalloc(1, sizeof(struct declaration));
	const struct scope_object *obj = scope_lookup(
			ctx->unit, &adecl->ident);
			ctx->defines, &adecl->ident);
	decl->type = DECL_CONST;
	decl->constant.type = type;
	decl->constant.value = obj->value;
@@ -3688,7 +3688,7 @@ scan_types(struct context *ctx, struct scope *imp, struct ast_decl *decl)
			scope_push((struct scope **)&type->_enum.values, SCOPE_ENUM);
			scan_enum_field(ctx, imp,
				type->_enum.values, type, t->type->_enum.values);
			type->_enum.values->parent = ctx->unit;
			type->_enum.values->parent = ctx->defines;
			idecl->obj.otype = O_TYPE;
			idecl->obj.type = type;
		} else {
@@ -4176,7 +4176,7 @@ wrap_resolver(struct context *ctx, const struct scope_object *obj,
	struct incomplete_declaration *idecl = (struct incomplete_declaration *)obj;

	// load this declaration's subunit context
	ctx->scope = ctx->unit;
	ctx->scope = ctx->defines;
	ctx->unit->parent = idecl->imports;

	// resolving a declaration that is already in progress -> cycle
@@ -4328,15 +4328,15 @@ check_internal(struct type_store *ts,

	// Put defines into a temporary scope (-D on the command line)
	ctx.scope = NULL;
	ctx.unit = scope_push(&ctx.scope, SCOPE_UNIT);
	ctx.unit = scope_push(&ctx.scope, SCOPE_DEFINES);
	for (struct ast_global_decl *def = defines; def; def = def->next) {
		struct incomplete_declaration *idecl =
			scan_const(&ctx, NULL, false , defineloc, def);
		resolve_const(&ctx, idecl);
	}
	struct scope *def_scope = ctx.scope;
	ctx.defines = ctx.scope;
	ctx.scope = NULL;
	ctx.unit = scope_push(&ctx.scope, SCOPE_UNIT);
	ctx.defines->parent = ctx.unit = scope_push(&ctx.scope, SCOPE_UNIT);

	// Populate the imports and put declarations into a scope.
	// Each declaration holds a reference to its subunit's imports
@@ -4379,29 +4379,17 @@ check_internal(struct type_store *ts,
		next = &(*next)->next;
	}

	// Put defines into unit scope
	// We have to insert them *after* declarations, because this way they
	// shadow declarations, not the other way around
	//
	// XXX: shadowed declarations are not checked for consistency
	for (const struct scope_object *obj = def_scope->objects;
			obj; obj = obj->lnext) {
		if (obj->otype == O_SCAN) {
			continue;
		}
		scope_insert(ctx.unit, O_CONST, &obj->ident, &obj->name,
			obj->type, obj->value);
	}
	scope_free(def_scope);

	// Find enum aliases and store them in incomplete enum value declarations
	for (const struct scope_object *obj = ctx.scope->objects;
			obj; obj = obj->lnext) {
		scan_enum_field_aliases(&ctx, obj);
	}

	// XXX: shadowed declarations are not checked for consistency
	ctx.scope = ctx.defines;

	// Perform actual declaration resolution
	for (const struct scope_object *obj = ctx.scope->objects;
	for (const struct scope_object *obj = ctx.unit->objects;
			obj; obj = obj->lnext) {
		wrap_resolver(&ctx, obj, resolve_decl);
	}
@@ -4420,7 +4408,7 @@ check_internal(struct type_store *ts,
	for (const struct ast_subunit *su = &aunit->subunits;
			su; su = su->next) {
		// subunit scope has to be *behind* unit scope
		ctx.scope->parent = scope->scope;
		ctx.unit->parent = scope->scope;
		next_decl = check_declarations(&ctx, su->decls, next_decl);
		scope = scope->next;
	}
diff --git a/tests/36-defines.ha b/tests/36-defines.ha
index 9592a70..90be8b5 100644
--- a/tests/36-defines.ha
+++ b/tests/36-defines.ha
@@ -44,7 +44,7 @@ fn compatibility() void = {
};

export fn main() void = {
	// TODO: import();
	import();
	mandatory();
	optional();
	// TODO: compatibility();
-- 
2.39.1

[PATCH harec v3 3/8] check: iterate on incomplete declarations instead of ast declarations

Details
Message ID
<20230207043208.29916-3-tb46305@gmail.com>
In-Reply-To
<20230207043208.29916-1-tb46305@gmail.com> (view parent)
DKIM signature
pass
Download raw message
Patch: +41 -81
This reduces code duplication between scan and check, making scan the
single source of truth. And simplifies reuse of information (idents,
names, types) already calculated in scan or resolve.

Signed-off-by: Armin Weigl <tb46305@gmail.com>
---
 src/check.c | 122 ++++++++++++++++++----------------------------------
 1 file changed, 41 insertions(+), 81 deletions(-)

diff --git a/src/check.c b/src/check.c
index 3a8ff34..1a50f67 100644
--- a/src/check.c
+++ b/src/check.c
@@ -3534,70 +3534,34 @@ check_type(struct context *ctx,
}

static struct declarations **
check_declarations(struct context *ctx,
		const struct ast_decls *adecls,
check_declaration(struct context *ctx,
		const struct incomplete_declaration *idecl,
		struct declarations **next)
{
	while (adecls) {
		struct declaration *decl = NULL;
		const struct ast_decl *adecl = &adecls->decl;
		switch (adecl->decl_type) {
		case AST_DECL_CONST:
			for (const struct ast_global_decl *c = &adecl->constant;
					c; c = c->next) {
				decl = check_const(ctx, c);
				struct declarations *decls = *next =
					xcalloc(1, sizeof(struct declarations));
				decl->exported = adecl->exported;
				decl->loc = adecl->loc;
				decls->decl = decl;
				next = &decls->next;
			}
			decl = NULL;
			break;
		case AST_DECL_FUNC:
			decl = check_function(ctx, adecl);
			break;
		case AST_DECL_GLOBAL:
			for (const struct ast_global_decl *g = &adecl->global;
					g; g = g->next) {
				decl = check_global(ctx, g);
				if (decl == NULL) {
					continue;
				}
				struct declarations *decls = *next =
					xcalloc(1, sizeof(struct declarations));
				decl->exported = adecl->exported;
				decl->loc = adecl->loc;
				decls->decl = decl;
				next = &decls->next;
			}
			decl = NULL;
			break;
		case AST_DECL_TYPE:
			for (const struct ast_type_decl *t = &adecl->type;
					t; t = t->next) {
				decl = check_type(ctx, t, adecl->exported);
				struct declarations *decls = *next =
					xcalloc(1, sizeof(struct declarations));
				decl->exported = adecl->exported;
				decls->decl = decl;
				next = &decls->next;
			}
			decl = NULL;
			break;
		}

		if (decl) {
			struct declarations *decls = *next =
				xcalloc(1, sizeof(struct declarations));
			decl->exported = adecl->exported;
			decl->loc = adecl->loc;
			decls->decl = decl;
			next = &decls->next;
		}
	const struct ast_decl *adecl = &idecl->decl;
	struct declaration *decl = NULL;
	switch (adecl->decl_type) {
	case AST_DECL_CONST:
		decl = check_const(ctx, &adecl->constant);
		break;
	case AST_DECL_FUNC:
		decl = check_function(ctx, adecl);
		break;
	case AST_DECL_GLOBAL:
		decl = check_global(ctx, &adecl->global);
		break;
	case AST_DECL_TYPE:
		decl = check_type(ctx, &adecl->type, adecl->exported);
		break;
	}

		adecls = adecls->next;
	if (decl) {
		struct declarations *decls = *next =
			xcalloc(1, sizeof(struct declarations));
		decl->exported = adecl->exported;
		decl->loc = adecl->loc;
		decls->decl = decl;
		next = &decls->next;
	}
	return next;
}
@@ -4167,6 +4131,10 @@ wrap_resolver(struct context *ctx, const struct scope_object *obj,
	struct scope *scope = ctx->scope;
	struct scope *subunit = ctx->unit->parent;
	ctx->unit->parent = NULL;
	const struct type *fntype = ctx->fntype;
	ctx->fntype = NULL;
	bool deferring = ctx->deferring;
	ctx->deferring = false;

	// ensure this declaration wasn't already scanned
	if (!obj || obj->otype != O_SCAN) {
@@ -4198,6 +4166,8 @@ wrap_resolver(struct context *ctx, const struct scope_object *obj,
	idecl->in_progress = false;
exit:
	// load stored context
	ctx->deferring = deferring;
	ctx->fntype = fntype;
	ctx->unit->parent = subunit;
	ctx->scope = scope;
}
@@ -4388,38 +4358,28 @@ check_internal(struct type_store *ts,
	// XXX: shadowed declarations are not checked for consistency
	ctx.scope = ctx.defines;

	struct declarations **next_decl = &unit->declarations;
	// Perform actual declaration resolution
	for (const struct scope_object *obj = ctx.unit->objects;
			obj; obj = obj->lnext) {
		wrap_resolver(&ctx, obj, resolve_decl);
		// Populate the expression graph
		const struct incomplete_declaration *idecl =
			(const struct incomplete_declaration *)obj;
		if (idecl->type != IDECL_DECL) {
			continue;
		}
		ctx.unit->parent = idecl->imports;
		next_decl = check_declaration(&ctx, idecl, next_decl);
	}

	handle_errors(ctx.errors);

	if (scan_only) {
		ctx.store->check_context = NULL;
		ctx.unit->parent = NULL;
		return ctx.unit;
	}

	// Populate the expression graph
	struct scopes *scope = subunit_scopes;
	struct declarations **next_decl = &unit->declarations;
	for (const struct ast_subunit *su = &aunit->subunits;
			su; su = su->next) {
		// subunit scope has to be *behind* unit scope
		ctx.unit->parent = scope->scope;
		next_decl = check_declarations(&ctx, su->decls, next_decl);
		scope = scope->next;
	}

	if (!unit->declarations) {
	if (!(scan_only || unit->declarations)) {
		fprintf(stderr, "Error: module contains no declarations\n");
		exit(EXIT_FAILURE);
	}

	handle_errors(ctx.errors);

	ctx.store->check_context = NULL;
	ctx.unit->parent = NULL;
	return ctx.unit;
-- 
2.39.1

[PATCH harec v3 4/8] check_type: reuse resolved type

Details
Message ID
<20230207043208.29916-4-tb46305@gmail.com>
In-Reply-To
<20230207043208.29916-1-tb46305@gmail.com> (view parent)
DKIM signature
pass
Download raw message
Patch: +4 -22
Signed-off-by: Armin Weigl <tb46305@gmail.com>
---
 src/check.c | 26 ++++----------------------
 1 file changed, 4 insertions(+), 22 deletions(-)

diff --git a/src/check.c b/src/check.c
index 1a50f67..ea26252 100644
--- a/src/check.c
+++ b/src/check.c
@@ -3504,32 +3504,14 @@ check_global(struct context *ctx,

static struct declaration *
check_type(struct context *ctx,
	const struct scope_object *obj,
	const struct ast_type_decl *adecl,
	bool exported)
{
	struct declaration *decl = xcalloc(1, sizeof(struct declaration));
	mkident(ctx, &decl->ident, &adecl->ident, NULL);
	decl->type = DECL_TYPE;
	if (adecl->type->storage == STORAGE_ENUM) {
		decl->_type =
			type_store_lookup_enum(ctx->store, adecl->type, exported);
	} else {
		const struct type *type =
			type_store_lookup_atype(ctx->store, adecl->type);
		struct type _alias = {
			.storage = STORAGE_ALIAS,
			.alias = {
				.ident = decl->ident,
				.name = adecl->ident,
				.type = type,
				.exported = exported,
			},
			.size = type->size,
			.align = type->align,
			.flags = type->flags,
		};
		decl->_type = type_store_lookup_alias(ctx->store, &_alias, NULL);
	}
	decl->ident = obj->ident;
	decl->_type = obj->type;
	return decl;
}

@@ -3551,7 +3533,7 @@ check_declaration(struct context *ctx,
		decl = check_global(ctx, &adecl->global);
		break;
	case AST_DECL_TYPE:
		decl = check_type(ctx, &adecl->type, adecl->exported);
		decl = check_type(ctx, &idecl->obj, &adecl->type, adecl->exported);
		break;
	}

-- 
2.39.1

[PATCH harec v3 5/8] check_const: reuse resolved type

Details
Message ID
<20230207043208.29916-5-tb46305@gmail.com>
In-Reply-To
<20230207043208.29916-1-tb46305@gmail.com> (view parent)
DKIM signature
pass
Download raw message
Patch: +6 -9
Signed-off-by: Armin Weigl <tb46305@gmail.com>
---
 src/check.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/src/check.c b/src/check.c
index ea26252..ff387e3 100644
--- a/src/check.c
+++ b/src/check.c
@@ -3317,19 +3317,16 @@ check_expression(struct context *ctx,

static struct declaration *
check_const(struct context *ctx,
	const struct scope_object *obj,
	const struct ast_global_decl *adecl)
{
	const struct type *type = NULL;
	if (adecl->type) {
		type = type_store_lookup_atype(ctx->store, adecl->type);
	}
	struct declaration *decl = xcalloc(1, sizeof(struct declaration));
	const struct scope_object *obj = scope_lookup(
	const struct scope_object *shadow_obj = scope_lookup(
			ctx->defines, &adecl->ident);
	decl->type = DECL_CONST;
	decl->constant.type = type;
	decl->constant.value = obj->value;
	mkident(ctx, &decl->ident, &adecl->ident, NULL);
	decl->constant.type = obj->type;
	decl->constant.value = shadow_obj->value;
	decl->ident = obj->ident;
	return decl;
}

@@ -3524,7 +3521,7 @@ check_declaration(struct context *ctx,
	struct declaration *decl = NULL;
	switch (adecl->decl_type) {
	case AST_DECL_CONST:
		decl = check_const(ctx, &adecl->constant);
		decl = check_const(ctx, &idecl->obj, &adecl->constant);
		break;
	case AST_DECL_FUNC:
		decl = check_function(ctx, adecl);
-- 
2.39.1

[PATCH harec v3 7/8] check_global: reuse resolved type

Details
Message ID
<20230207043208.29916-7-tb46305@gmail.com>
In-Reply-To
<20230207043208.29916-1-tb46305@gmail.com> (view parent)
DKIM signature
pass
Download raw message
Patch: +14 -30
Signed-off-by: Armin Weigl <tb46305@gmail.com>
---
v3:
	rebase
 src/check.c | 44 ++++++++++++++------------------------------
 1 file changed, 14 insertions(+), 30 deletions(-)

diff --git a/src/check.c b/src/check.c
index 6b162ae..4cbc7e0 100644
--- a/src/check.c
+++ b/src/check.c
@@ -3429,21 +3429,15 @@ check_function(struct context *ctx,

static struct declaration *
check_global(struct context *ctx,
	const struct scope_object *obj,
	const struct ast_global_decl *adecl)
{
	const struct type *type = NULL;
	if (adecl->type) {
		type = type_store_lookup_atype(ctx->store, adecl->type);
	}

	struct declaration *decl = xcalloc(1, sizeof(struct declaration));
	decl->type = DECL_GLOBAL;
	decl->global.type = type;
	decl->global.type = obj->type;
	decl->global.threadlocal = adecl->threadlocal;

	if (adecl->symbol) {
		decl->symbol = xstrdup(adecl->symbol);
	}
	decl->symbol = ident_to_sym(&obj->ident);
	mkident(ctx, &decl->ident, &adecl->ident, NULL);

	if (!adecl->init) {
@@ -3453,29 +3447,19 @@ check_global(struct context *ctx,
	// TODO: Free initialier
	struct expression *initializer =
		xcalloc(1, sizeof(struct expression));
	check_expression(ctx, adecl->init, initializer, type);
	check_expression(ctx, adecl->init, initializer, obj->type);
	// TODO: Pass errors up and deal with them at the end of check

	if (type) {
		char *typename1 = gen_typename(initializer->result);
		char *typename2 = gen_typename(type);
		expect(ctx, &adecl->init->loc,
			type_is_assignable(type, initializer->result),
			"Initializer type %s is not assignable to constant type %s",
			typename1, typename2);
		free(typename1);
		free(typename2);
	}

	bool context = adecl->type
		&& adecl->type->storage == STORAGE_ARRAY
		&& adecl->type->array.contextual;
	if (context || !type) {
		// XXX: Do we need to do anything more here
		type = lower_const(initializer->result, NULL);
	}
	char *typename1 = gen_typename(initializer->result);
	char *typename2 = gen_typename(obj->type);
	expect(ctx, &adecl->init->loc,
		type_is_assignable(obj->type, initializer->result),
		"Initializer type %s is not assignable to constant type %s",
		typename1, typename2);
	free(typename1);
	free(typename2);

	initializer = lower_implicit_cast(type, initializer);
	initializer = lower_implicit_cast(obj->type, initializer);

	struct expression *value =
		xcalloc(1, sizeof(struct expression));
@@ -3518,7 +3502,7 @@ check_declaration(struct context *ctx,
		decl = check_function(ctx, &idecl->obj, adecl);
		break;
	case AST_DECL_GLOBAL:
		decl = check_global(ctx, &adecl->global);
		decl = check_global(ctx, &idecl->obj, &adecl->global);
		break;
	case AST_DECL_TYPE:
		decl = check_type(ctx, &idecl->obj, &adecl->type, adecl->exported);
-- 
2.39.1

[PATCH harec v3 6/8] check_function: reuse resolved type

Details
Message ID
<20230207043208.29916-6-tb46305@gmail.com>
In-Reply-To
<20230207043208.29916-1-tb46305@gmail.com> (view parent)
DKIM signature
pass
Download raw message
Patch: +15 -24
Signed-off-by: Armin Weigl <tb46305@gmail.com>
---
v3:
	rebase
 src/check.c | 39 +++++++++++++++------------------------
 1 file changed, 15 insertions(+), 24 deletions(-)

diff --git a/src/check.c b/src/check.c
index ff387e3..6b162ae 100644
--- a/src/check.c
+++ b/src/check.c
@@ -3332,30 +3332,21 @@ check_const(struct context *ctx,

static struct declaration *
check_function(struct context *ctx,
	const struct scope_object *obj,
	const struct ast_decl *adecl)
{
	const struct ast_function_decl *afndecl = &adecl->function;
	if ((adecl->function.flags & FN_TEST) && !ctx->is_test) {
		return NULL;
	}

	const struct ast_type fn_atype = {
		.storage = STORAGE_FUNCTION,
		.flags = TYPE_CONST,
		.func = afndecl->prototype,
	};
	const struct type *fntype = type_store_lookup_atype(
			ctx->store, &fn_atype);
	ctx->fntype = fntype;
	ctx->fntype = obj->type;

	struct declaration *decl = xcalloc(1, sizeof(struct declaration));
	decl->type = DECL_FUNC;
	decl->func.type = fntype;
	decl->func.type = obj->type;
	decl->func.flags = afndecl->flags;

	if (afndecl->symbol) {
		decl->symbol = xstrdup(afndecl->symbol);
	}
	decl->symbol = ident_to_sym(&obj->ident);
	mkident(ctx, &decl->ident, &afndecl->ident, NULL);

	if (!adecl->function.body) {
@@ -3372,7 +3363,7 @@ check_function(struct context *ctx,
		};
		const struct type *type = type_store_lookup_atype(
				ctx->store, params->type);
		if (fntype->func.variadism == VARIADISM_HARE
		if (obj->type->func.variadism == VARIADISM_HARE
				&& !params->next) {
			type = type_store_lookup_slice(ctx->store,
				params->loc, type);
@@ -3383,20 +3374,20 @@ check_function(struct context *ctx,
	}

	struct expression *body = xcalloc(1, sizeof(struct expression));
	check_expression(ctx, afndecl->body, body, fntype->func.result);
	check_expression(ctx, afndecl->body, body, obj->type->func.result);
	// TODO: Pass errors up and deal with them at the end of check
	handle_errors(ctx->errors);

	char *restypename = gen_typename(body->result);
	char *fntypename = gen_typename(fntype->func.result);
	char *fntypename = gen_typename(obj->type->func.result);
	expect(ctx, &afndecl->body->loc,
		body->terminates || type_is_assignable(fntype->func.result, body->result),
		body->terminates || type_is_assignable(obj->type->func.result, body->result),
		"Result value %s is not assignable to function result type %s",
		restypename, fntypename);
	free(restypename);
	free(fntypename);
	if (!body->terminates && fntype->func.result != body->result) {
		body = lower_implicit_cast(fntype->func.result, body);
	if (!body->terminates && obj->type->func.result != body->result) {
		body = lower_implicit_cast(obj->type->func.result, body);
	}
	decl->func.body = body;

@@ -3417,17 +3408,17 @@ check_function(struct context *ctx,
			expect(ctx, &adecl->loc, 0,
				"Only one of @init, @fini, or @test may be used in a function declaration");
		};
		expect(ctx, &adecl->loc, fntype->func.result == &builtin_type_void,
		expect(ctx, &adecl->loc, obj->type->func.result == &builtin_type_void,
				"%s function must return void", flag);
		expect(ctx, &adecl->loc, (fntype->func.flags & FN_NORETURN) == 0,
		expect(ctx, &adecl->loc, (obj->type->func.flags & FN_NORETURN) == 0,
				"%s function must return", flag);
		expect(ctx, &adecl->loc, !decl->exported,
				"%s function cannot be exported", flag);
		expect(ctx, &adecl->loc, !afndecl->prototype.params,
				"%s function cannot have parameters", flag);
	}
	if (fntype->func.flags & FN_NORETURN) {
		expect(ctx, &adecl->loc, fntype->func.result == &builtin_type_void,
	if (obj->type->func.flags & FN_NORETURN) {
		expect(ctx, &adecl->loc, obj->type->func.result == &builtin_type_void,
				"@noreturn function must return void");
	};

@@ -3524,7 +3515,7 @@ check_declaration(struct context *ctx,
		decl = check_const(ctx, &idecl->obj, &adecl->constant);
		break;
	case AST_DECL_FUNC:
		decl = check_function(ctx, adecl);
		decl = check_function(ctx, &idecl->obj, adecl);
		break;
	case AST_DECL_GLOBAL:
		decl = check_global(ctx, &adecl->global);
-- 
2.39.1

[PATCH harec v3 8/8] gen_function_decl: remove no longer necessary function name generation

Details
Message ID
<20230207043208.29916-8-tb46305@gmail.com>
In-Reply-To
<20230207043208.29916-1-tb46305@gmail.com> (view parent)
DKIM signature
pass
Download raw message
Patch: +2 -10
Signed-off-by: Armin Weigl <tb46305@gmail.com>
---
v3:
	rebase
 src/gen.c | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/src/gen.c b/src/gen.c
index bc4bc8d..08c92e1 100644
--- a/src/gen.c
+++ b/src/gen.c
@@ -3301,16 +3301,8 @@ gen_function_decl(struct gen_context *ctx, const struct declaration *decl)
	qdef->exported = decl->exported;
	ctx->current = &qdef->func;

	if (func->flags & FN_TEST) {
		qdef->name = gen_name(ctx, "testfunc.%d");
	} else if (func->flags & FN_INIT) {
		qdef->name = gen_name(ctx, "initfunc.%d");
	} else if (func->flags & FN_FINI) {
		qdef->name = gen_name(ctx, "finifunc.%d");
	} else {
		qdef->name = decl->symbol ? xstrdup(decl->symbol)
			: ident_to_sym(&decl->ident);
	}
	qdef->name = decl->symbol ? xstrdup(decl->symbol)
		: ident_to_sym(&decl->ident);

	struct qbe_statement start_label = {0};
	mklabel(ctx, &start_label, "start.%d");
-- 
2.39.1

[harec/patches] build success

builds.sr.ht <builds@sr.ht>
Details
Message ID
<CQC1TTQ20PEN.TYRQ653GM4WU@cirno2>
In-Reply-To
<20230207043208.29916-8-tb46305@gmail.com> (view parent)
DKIM signature
missing
Download raw message
harec/patches: SUCCESS in 59s

[scan_decl: insert @flag functions with generated name][0] v3 from [Armin Weigl][1]

[0]: https://lists.sr.ht/~sircmpwn/hare-dev/patches/38797
[1]: tb46305@gmail.com

✓ #935972 SUCCESS harec/patches/alpine.yml  https://builds.sr.ht/~sircmpwn/job/935972
✓ #935974 SUCCESS harec/patches/netbsd.yml  https://builds.sr.ht/~sircmpwn/job/935974
✓ #935973 SUCCESS harec/patches/freebsd.yml https://builds.sr.ht/~sircmpwn/job/935973

Re: [PATCH harec v3 8/8] gen_function_decl: remove no longer necessary function name generation

Details
Message ID
<CQC2FHWGQKSG.BEP667CP9BL5@attila>
In-Reply-To
<20230207043208.29916-8-tb46305@gmail.com> (view parent)
DKIM signature
pass
Download raw message
Thanks!

To git@git.sr.ht:~sircmpwn/harec
   42f5397..6ef434a  master -> master
Reply to thread Export thread (mbox)