Browse Source

Allow `@(require_results)` on `foreign` blocks

gingerBill 1 year ago
parent
commit
fd5376ba88
3 changed files with 14 additions and 1 deletions
  1. 3 1
      src/check_decl.cpp
  2. 7 0
      src/checker.cpp
  3. 4 0
      src/checker.hpp

+ 3 - 1
src/check_decl.cpp

@@ -1124,7 +1124,7 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
 
 	e->deprecated_message = ac.deprecated_message;
 	e->warning_message = ac.warning_message;
-	ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix,ac.link_suffix);
+	ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix, ac.link_suffix);
 	if (ac.has_disabled_proc) {
 		if (ac.disabled_proc) {
 			e->flags |= EntityFlag_Disabled;
@@ -1221,6 +1221,8 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
 		} else {
 			pt->require_results = true;
 		}
+	} else if (d->foreign_require_results && pt->result_count != 0) {
+		pt->require_results = true;
 	}
 
 	if (ac.link_name.len > 0) {

+ 7 - 0
src/checker.cpp

@@ -3212,6 +3212,12 @@ gb_internal DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) {
 		}
 		c->foreign_context.visibility_kind = kind;
 		return true;
+	} else if (name == "require_results") {
+		if (value != nullptr) {
+			error(elem, "Expected no value for '%.*s'", LIT(name));
+		}
+		c->foreign_context.require_results = true;
+		return true;
 	}
 
 	return false;
@@ -4300,6 +4306,7 @@ gb_internal void check_collect_value_decl(CheckerContext *c, Ast *decl) {
 				}
 				ast_node(pl, ProcLit, init);
 				e = alloc_entity_procedure(d->scope, token, nullptr, pl->tags);
+				d->foreign_require_results = c->foreign_context.require_results;
 				if (fl != nullptr) {
 					GB_ASSERT(fl->kind == Ast_Ident);
 					e->Procedure.foreign_library_ident = fl;

+ 4 - 0
src/checker.hpp

@@ -204,9 +204,12 @@ struct DeclInfo {
 	Array<Ast *>  attributes;
 	Ast *         proc_lit;      // Ast_ProcLit
 	Type *        gen_proc_type; // Precalculated
+
 	bool          is_using;
 	bool          where_clauses_evaluated;
+	bool          foreign_require_results;
 	std::atomic<ProcCheckedState> proc_checked_state;
+
 	BlockingMutex proc_checked_mutex;
 	isize         defer_used;
 	bool          defer_use_checked;
@@ -322,6 +325,7 @@ struct ForeignContext {
 	String                link_prefix;
 	String                link_suffix;
 	EntityVisiblityKind   visibility_kind;
+	bool                  require_results;
 };
 
 typedef Array<Entity *> CheckerTypePath;