check_decl.cpp 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792
  1. gb_internal void check_stmt(CheckerContext *ctx, Ast *node, u32 flags);
  2. // NOTE(bill): 'content_name' is for debugging and error messages
  3. gb_internal Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *operand, String context_name) {
  4. if (operand->mode == Addressing_Invalid ||
  5. operand->type == t_invalid ||
  6. e->type == t_invalid) {
  7. if (operand->mode == Addressing_Builtin) {
  8. ERROR_BLOCK();
  9. gbString expr_str = expr_to_string(operand->expr);
  10. error(operand->expr,
  11. "Cannot assign built-in procedure '%s' in %.*s",
  12. expr_str,
  13. LIT(context_name));
  14. error_line("\tBuilt-in procedures are implemented by the compiler and might not be actually instantiated procedure\n");
  15. operand->mode = Addressing_Invalid;
  16. gb_string_free(expr_str);
  17. }
  18. if (operand->mode == Addressing_ProcGroup) {
  19. if (e->type == nullptr) {
  20. error(operand->expr, "Cannot determine type from overloaded procedure '%.*s'", LIT(operand->proc_group->token.string));
  21. } else {
  22. check_assignment(ctx, operand, e->type, str_lit("variable assignment"));
  23. if (operand->mode != Addressing_Type) {
  24. return operand->type;
  25. }
  26. }
  27. }
  28. if (e->type == nullptr) {
  29. e->type = t_invalid;
  30. }
  31. return nullptr;
  32. }
  33. if (e->kind == Entity_Variable) {
  34. e->Variable.init_expr = operand->expr;
  35. }
  36. if (operand->mode == Addressing_Type) {
  37. if (e->type != nullptr && is_type_typeid(e->type) && !is_type_polymorphic(operand->type)) {
  38. add_type_info_type(ctx, operand->type);
  39. add_type_and_value(ctx, operand->expr, Addressing_Value, e->type, exact_value_typeid(operand->type));
  40. return e->type;
  41. } else {
  42. ERROR_BLOCK();
  43. gbString t = type_to_string(operand->type);
  44. defer (gb_string_free(t));
  45. if (is_type_polymorphic(operand->type)) {
  46. error(operand->expr, "Cannot assign a non-specialized polymorphic type '%s' to variable '%.*s'", t, LIT(e->token.string));
  47. } else {
  48. error(operand->expr, "Cannot assign a type '%s' to variable '%.*s'", t, LIT(e->token.string));
  49. }
  50. if (e->type == nullptr) {
  51. error_line("\tThe type of the variable '%.*s' cannot be inferred as a type does not have a default type\n", LIT(e->token.string));
  52. }
  53. e->type = operand->type;
  54. return nullptr;
  55. }
  56. }
  57. if (e->type == nullptr) {
  58. // NOTE(bill): Use the type of the operand
  59. Type *t = operand->type;
  60. if (is_type_untyped(t)) {
  61. if (is_type_untyped_uninit(t)) {
  62. error(e->token, "Invalid use of --- in %.*s", LIT(context_name));
  63. e->type = t_invalid;
  64. return nullptr;
  65. } else if (t == t_invalid || is_type_untyped_nil(t)) {
  66. error(e->token, "Invalid use of untyped nil in %.*s", LIT(context_name));
  67. e->type = t_invalid;
  68. return nullptr;
  69. }
  70. t = default_type(t);
  71. }
  72. if (is_type_asm_proc(t)) {
  73. error(e->token, "Invalid use of inline asm in %.*s", LIT(context_name));
  74. e->type = t_invalid;
  75. return nullptr;
  76. } else if (is_type_polymorphic(t)) {
  77. Entity *e = entity_of_node(operand->expr);
  78. if (e == nullptr) {
  79. return nullptr;
  80. }
  81. if (e->state.load() != EntityState_Resolved) {
  82. gbString str = type_to_string(t);
  83. defer (gb_string_free(str));
  84. error(e->token, "Invalid use of a polymorphic type '%s' in %.*s", str, LIT(context_name));
  85. e->type = t_invalid;
  86. return nullptr;
  87. }
  88. } else if (is_type_empty_union(t)) {
  89. gbString str = type_to_string(t);
  90. defer (gb_string_free(str));
  91. error(e->token, "An empty union '%s' cannot be instantiated in %.*s", str, LIT(context_name));
  92. e->type = t_invalid;
  93. return nullptr;
  94. }
  95. GB_ASSERT(is_type_typed(t));
  96. e->type = t;
  97. }
  98. e->parent_proc_decl = ctx->curr_proc_decl;
  99. check_assignment(ctx, operand, e->type, context_name);
  100. if (operand->mode == Addressing_Invalid) {
  101. return nullptr;
  102. }
  103. return e->type;
  104. }
  105. gb_internal void check_init_variables(CheckerContext *ctx, Entity **lhs, isize lhs_count, Slice<Ast *> const &inits, String context_name) {
  106. if ((lhs == nullptr || lhs_count == 0) && inits.count == 0) {
  107. return;
  108. }
  109. // NOTE(bill): If there is a bad syntax error, rhs > lhs which would mean there would need to be
  110. // an extra allocation
  111. TEMPORARY_ALLOCATOR_GUARD();
  112. auto operands = array_make<Operand>(temporary_allocator(), 0, 2*lhs_count);
  113. check_unpack_arguments(ctx, lhs, lhs_count, &operands, inits, UnpackFlag_AllowOk|UnpackFlag_AllowUndef);
  114. isize rhs_count = operands.count;
  115. isize max = gb_min(lhs_count, rhs_count);
  116. for (isize i = 0; i < max; i++) {
  117. Entity *e = lhs[i];
  118. DeclInfo *d = decl_info_of_entity(e);
  119. Operand *o = &operands[i];
  120. check_init_variable(ctx, e, o, context_name);
  121. if (d != nullptr) {
  122. d->init_expr = o->expr;
  123. }
  124. if (o->type && is_type_no_copy(o->type)) {
  125. ERROR_BLOCK();
  126. if (check_no_copy_assignment(*o, str_lit("initialization"))) {
  127. error_line("\tInitialization of a #no_copy type must be either implicitly zero, a constant literal, or a return value from a call expression");
  128. }
  129. }
  130. }
  131. if (rhs_count > 0 && lhs_count != rhs_count) {
  132. error(lhs[0]->token, "Assignment count mismatch '%td' = '%td'", lhs_count, rhs_count);
  133. }
  134. }
  135. gb_internal void check_init_constant(CheckerContext *ctx, Entity *e, Operand *operand) {
  136. if (operand->mode == Addressing_Invalid ||
  137. operand->type == t_invalid ||
  138. e->type == t_invalid) {
  139. if (e->type == nullptr) {
  140. e->type = t_invalid;
  141. }
  142. return;
  143. }
  144. if (operand->mode != Addressing_Constant) {
  145. gbString str = expr_to_string(operand->expr);
  146. error(operand->expr, "'%s' is not a compile-time known constant", str);
  147. gb_string_free(str);
  148. if (e->type == nullptr) {
  149. e->type = t_invalid;
  150. }
  151. return;
  152. }
  153. if (e->type == nullptr) { // NOTE(bill): type inference
  154. e->type = operand->type;
  155. }
  156. check_assignment(ctx, operand, e->type, str_lit("constant declaration"));
  157. if (operand->mode == Addressing_Invalid) {
  158. return;
  159. }
  160. if (is_type_proc(e->type)) {
  161. error(e->token, "Illegal declaration of a constant procedure value");
  162. }
  163. e->parent_proc_decl = ctx->curr_proc_decl;
  164. e->Constant.value = operand->value;
  165. }
  166. gb_internal bool is_type_distinct(Ast *node) {
  167. for (;;) {
  168. if (node == nullptr) {
  169. return false;
  170. }
  171. if (node->kind == Ast_ParenExpr) {
  172. node = node->ParenExpr.expr;
  173. } else if (node->kind == Ast_HelperType) {
  174. node = node->HelperType.type;
  175. } else {
  176. break;
  177. }
  178. }
  179. switch (node->kind) {
  180. case Ast_DistinctType:
  181. return true;
  182. case Ast_StructType:
  183. case Ast_UnionType:
  184. case Ast_EnumType:
  185. case Ast_ProcType:
  186. case Ast_BitFieldType:
  187. return true;
  188. case Ast_PointerType:
  189. case Ast_ArrayType:
  190. case Ast_DynamicArrayType:
  191. case Ast_MapType:
  192. return false;
  193. }
  194. return false;
  195. }
  196. gb_internal Ast *remove_type_alias_clutter(Ast *node) {
  197. for (;;) {
  198. if (node == nullptr) {
  199. return nullptr;
  200. }
  201. if (node->kind == Ast_ParenExpr) {
  202. node = node->ParenExpr.expr;
  203. } else if (node->kind == Ast_DistinctType) {
  204. node = node->DistinctType.type;
  205. } else {
  206. return node;
  207. }
  208. }
  209. }
  210. gb_internal Type *clone_enum_type(CheckerContext *ctx, Type *original_enum_type, Type *named_type) {
  211. // NOTE(bill, 2022-02-05): Stupid edge case for `distinct` declarations
  212. //
  213. // X :: enum {A, B, C}
  214. // Y :: distinct X
  215. //
  216. // To make Y be just like X, it will need to copy the elements of X and change their type
  217. // so that they match Y rather than X.
  218. GB_ASSERT(original_enum_type != nullptr);
  219. GB_ASSERT(named_type != nullptr);
  220. GB_ASSERT(original_enum_type->kind == Type_Enum);
  221. GB_ASSERT(named_type->kind == Type_Named);
  222. Scope *parent = original_enum_type->Enum.scope->parent;
  223. Scope *scope = create_scope(nullptr, parent);
  224. Type *et = alloc_type_enum();
  225. et->Enum.base_type = original_enum_type->Enum.base_type;
  226. et->Enum.min_value = original_enum_type->Enum.min_value;
  227. et->Enum.max_value = original_enum_type->Enum.max_value;
  228. et->Enum.min_value_index = original_enum_type->Enum.min_value_index;
  229. et->Enum.max_value_index = original_enum_type->Enum.max_value_index;
  230. et->Enum.scope = scope;
  231. auto fields = array_make<Entity *>(permanent_allocator(), original_enum_type->Enum.fields.count);
  232. for_array(i, fields) {
  233. Entity *old = original_enum_type->Enum.fields[i];
  234. Entity *e = alloc_entity_constant(scope, old->token, named_type, old->Constant.value);
  235. e->file = old->file;
  236. e->identifier = clone_ast(old->identifier);
  237. e->flags |= EntityFlag_Visited;
  238. e->state = EntityState_Resolved;
  239. e->Constant.flags = old->Constant.flags;
  240. e->Constant.docs = old->Constant.docs;
  241. e->Constant.comment = old->Constant.comment;
  242. fields[i] = e;
  243. add_entity(ctx, scope, nullptr, e);
  244. add_entity_use(ctx, e->identifier, e);
  245. }
  246. et->Enum.fields = fields;
  247. return et;
  248. }
  249. gb_internal void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *def) {
  250. GB_ASSERT(e->type == nullptr);
  251. DeclInfo *decl = decl_info_of_entity(e);
  252. bool is_distinct = is_type_distinct(init_expr);
  253. Ast *te = remove_type_alias_clutter(init_expr);
  254. e->type = t_invalid;
  255. String name = e->token.string;
  256. Type *named = alloc_type_named(name, nullptr, e);
  257. if (def != nullptr && def->kind == Type_Named) {
  258. def->Named.base = named;
  259. }
  260. e->type = named;
  261. check_type_path_push(ctx, e);
  262. Type *bt = check_type_expr(ctx, te, named);
  263. check_type_path_pop(ctx);
  264. Type *base = base_type(bt);
  265. if (is_distinct && bt->kind == Type_Named && base->kind == Type_Enum) {
  266. base = clone_enum_type(ctx, base, named);
  267. }
  268. named->Named.base = base;
  269. if (is_distinct) {
  270. if (is_type_typeid(e->type)) {
  271. error(init_expr, "'distinct' cannot be applied to 'typeid'");
  272. is_distinct = false;
  273. } else if (is_type_any(e->type)) {
  274. error(init_expr, "'distinct' cannot be applied to 'any'");
  275. is_distinct = false;
  276. } else if (is_type_simd_vector(e->type) || is_type_soa_pointer(e->type)) {
  277. gbString str = type_to_string(e->type);
  278. error(init_expr, "'distinct' cannot be applied to '%s'", str);
  279. gb_string_free(str);
  280. is_distinct = false;
  281. }
  282. } else {
  283. if (is_type_typeid(e->type)) {
  284. error(init_expr, "'typeid' cannot be aliased");
  285. } else if (is_type_any(e->type)) {
  286. error(init_expr, "'any' cannot be aliased");
  287. }
  288. }
  289. if (!is_distinct) {
  290. e->type = bt;
  291. named->Named.base = bt;
  292. e->TypeName.is_type_alias = true;
  293. }
  294. if (decl->type_expr != nullptr) {
  295. Type *t = check_type(ctx, decl->type_expr);
  296. if (t != nullptr && !is_type_typeid(t)) {
  297. Operand operand = {};
  298. operand.mode = Addressing_Type;
  299. operand.type = e->type;
  300. operand.expr = init_expr;
  301. check_assignment(ctx, &operand, t, str_lit("constant declaration"));
  302. }
  303. }
  304. if (decl != nullptr) {
  305. AttributeContext ac = {};
  306. check_decl_attributes(ctx, decl->attributes, type_decl_attribute, &ac);
  307. if (e->kind == Entity_TypeName && ac.objc_class != "") {
  308. e->TypeName.objc_class_name = ac.objc_class;
  309. if (type_size_of(e->type) > 0) {
  310. error(e->token, "@(objc_class) marked type must be of zero size");
  311. }
  312. }
  313. }
  314. // using decl
  315. if (decl->is_using) {
  316. error(init_expr, "'using' an enum declaration is not allowed, prefer using implicit selector expressions e.g. '.A'");
  317. }
  318. }
  319. gb_internal void override_entity_in_scope(Entity *original_entity, Entity *new_entity) {
  320. // NOTE(bill): The original_entity's scope may not be same scope that it was inserted into
  321. // e.g. file entity inserted into its package scope
  322. String original_name = original_entity->token.string;
  323. Scope *found_scope = nullptr;
  324. Entity *found_entity = nullptr;
  325. scope_lookup_parent(original_entity->scope, original_name, &found_scope, &found_entity);
  326. if (found_scope == nullptr) {
  327. return;
  328. }
  329. rw_mutex_lock(&found_scope->mutex);
  330. defer (rw_mutex_unlock(&found_scope->mutex));
  331. // IMPORTANT NOTE(bill, 2021-04-10): Overriding behaviour was flawed in that the
  332. // original entity was still used check checked, but the checking was only
  333. // relying on "constant" data such as the Entity.type and Entity.Constant.value
  334. //
  335. // Therefore two things can be done: the type can be assigned to state that it
  336. // has been "evaluated" and the variant data can be copied across
  337. string_map_set(&found_scope->elements, original_name, new_entity);
  338. original_entity->flags |= EntityFlag_Overridden;
  339. original_entity->type = new_entity->type;
  340. original_entity->aliased_of = new_entity;
  341. Ast *empty_ident = nullptr;
  342. original_entity->identifier.compare_exchange_strong(empty_ident, new_entity->identifier);
  343. if (original_entity->identifier.load() != nullptr &&
  344. original_entity->identifier.load()->kind == Ast_Ident) {
  345. original_entity->identifier.load()->Ident.entity = new_entity;
  346. }
  347. // IMPORTANT NOTE(bill, 2021-04-10): copy only the variants
  348. // This is most likely NEVER required, but it does not at all hurt to keep
  349. isize offset = cast(u8 *)&original_entity->Dummy.start - cast(u8 *)original_entity;
  350. isize size = gb_size_of(*original_entity) - offset;
  351. gb_memmove(cast(u8 *)original_entity, cast(u8 *)new_entity, size);
  352. }
  353. gb_internal void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init, Type *named_type) {
  354. GB_ASSERT(e->type == nullptr);
  355. GB_ASSERT(e->kind == Entity_Constant);
  356. init = unparen_expr(init);
  357. if (e->flags & EntityFlag_Visited) {
  358. e->type = t_invalid;
  359. return;
  360. }
  361. e->flags |= EntityFlag_Visited;
  362. if (type_expr) {
  363. e->type = check_type(ctx, type_expr);
  364. if (are_types_identical(e->type, t_typeid)) {
  365. e->type = nullptr;
  366. e->kind = Entity_TypeName;
  367. check_type_decl(ctx, e, init, named_type);
  368. return;
  369. }
  370. }
  371. Operand operand = {};
  372. if (init != nullptr) {
  373. Entity *entity = check_entity_from_ident_or_selector(ctx, init, false);
  374. if (entity != nullptr && entity->kind == Entity_TypeName) {
  375. // @TypeAliasingProblem
  376. // NOTE(bill, 2022-02-03): This is used to solve the problem caused by type aliases
  377. // being "confused" as constants
  378. //
  379. // A :: B
  380. // C :: proc "c" (^A)
  381. // B :: struct {x: C}
  382. //
  383. // A gets evaluated first, and then checks B.
  384. // B then checks C.
  385. // C then tries to check A which is unresolved but thought to be a constant.
  386. // Therefore within C's check, A errs as "not a type".
  387. //
  388. // This is because a const declaration may or may not be a type and this cannot
  389. // be determined from a syntactical standpoint.
  390. // This check allows the compiler to override the entity to be checked as a type.
  391. //
  392. // There is no problem if B is prefixed with the `#type` helper enforcing at
  393. // both a syntax and semantic level that B must be a type.
  394. //
  395. // A :: #type B
  396. //
  397. // This approach is not fool proof and can fail in case such as:
  398. //
  399. // X :: type_of(x)
  400. // X :: Foo(int).Type
  401. //
  402. // Since even these kind of declarations may cause weird checking cycles.
  403. // For the time being, these are going to be treated as an unfortunate error
  404. // until there is a proper delaying system to try declaration again if they
  405. // have failed.
  406. e->kind = Entity_TypeName;
  407. check_type_decl(ctx, e, init, named_type);
  408. return;
  409. }
  410. entity = nullptr;
  411. if (init->kind == Ast_Ident) {
  412. entity = check_ident(ctx, &operand, init, nullptr, e->type, true);
  413. } else if (init->kind == Ast_SelectorExpr) {
  414. entity = check_selector(ctx, &operand, init, e->type);
  415. } else {
  416. check_expr_or_type(ctx, &operand, init, e->type);
  417. if (init->kind == Ast_CallExpr) {
  418. entity = init->CallExpr.entity_procedure_of;
  419. }
  420. }
  421. switch (operand.mode) {
  422. case Addressing_Type: {
  423. if (e->type != nullptr && !is_type_typeid(e->type)) {
  424. check_assignment(ctx, &operand, e->type, str_lit("constant declaration"));
  425. }
  426. e->kind = Entity_TypeName;
  427. e->type = nullptr;
  428. if (entity != nullptr && entity->type != nullptr &&
  429. is_type_polymorphic_record_unspecialized(entity->type)) {
  430. DeclInfo *decl = decl_info_of_entity(e);
  431. if (decl != nullptr) {
  432. if (decl->attributes.count > 0) {
  433. error(decl->attributes[0], "Constant alias declarations cannot have attributes");
  434. }
  435. }
  436. override_entity_in_scope(e, entity);
  437. return;
  438. }
  439. check_type_decl(ctx, e, ctx->decl->init_expr, named_type);
  440. return;
  441. }
  442. // NOTE(bill): Check to see if the expression it to be aliases
  443. case Addressing_Builtin:
  444. if (e->type != nullptr) {
  445. error(type_expr, "A constant alias of a built-in procedure may not have a type initializer");
  446. }
  447. e->kind = Entity_Builtin;
  448. e->Builtin.id = operand.builtin_id;
  449. e->type = t_invalid;
  450. return;
  451. case Addressing_ProcGroup:
  452. GB_ASSERT(operand.proc_group != nullptr);
  453. GB_ASSERT(operand.proc_group->kind == Entity_ProcGroup);
  454. // NOTE(bill, 2020-06-10): It is better to just clone the contents than overriding the entity in the scope
  455. // Thank goodness I made entities a tagged union to allow for this implace patching
  456. e->kind = Entity_ProcGroup;
  457. e->ProcGroup.entities = array_clone(heap_allocator(), operand.proc_group->ProcGroup.entities);
  458. return;
  459. }
  460. if (entity != nullptr) {
  461. if (e->type != nullptr) {
  462. Operand x = {};
  463. x.type = entity->type;
  464. x.mode = Addressing_Variable;
  465. if (!check_is_assignable_to(ctx, &x, e->type)) {
  466. gbString expr_str = expr_to_string(init);
  467. gbString op_type_str = type_to_string(entity->type);
  468. gbString type_str = type_to_string(e->type);
  469. error(e->token,
  470. "Cannot assign '%s' of type '%s' to '%s'",
  471. expr_str,
  472. op_type_str,
  473. type_str);
  474. gb_string_free(type_str);
  475. gb_string_free(op_type_str);
  476. gb_string_free(expr_str);
  477. }
  478. }
  479. // NOTE(bill): Override aliased entity
  480. switch (entity->kind) {
  481. case Entity_ProcGroup:
  482. case Entity_Procedure:
  483. case Entity_LibraryName:
  484. case Entity_ImportName:
  485. {
  486. DeclInfo *decl = decl_info_of_entity(e);
  487. if (decl != nullptr) {
  488. if (decl->attributes.count > 0) {
  489. error(decl->attributes[0], "Constant alias declarations cannot have attributes");
  490. }
  491. }
  492. override_entity_in_scope(e, entity);
  493. return;
  494. }
  495. }
  496. }
  497. }
  498. check_init_constant(ctx, e, &operand);
  499. if (operand.mode == Addressing_Invalid ||
  500. base_type(operand.type) == t_invalid) {
  501. gbString str = expr_to_string(init);
  502. error(init, "Invalid declaration value '%s'", str);
  503. gb_string_free(str);
  504. }
  505. DeclInfo *decl = decl_info_of_entity(e);
  506. if (decl != nullptr) {
  507. check_decl_attributes(ctx, decl->attributes, const_decl_attribute, nullptr);
  508. }
  509. }
  510. typedef bool TypeCheckSig(Type *t);
  511. gb_internal bool sig_compare(TypeCheckSig *a, Type *x, Type *y) {
  512. x = core_type(x);
  513. y = core_type(y);
  514. return (a(x) && a(y));
  515. }
  516. gb_internal bool sig_compare(TypeCheckSig *a, TypeCheckSig *b, Type *x, Type *y) {
  517. x = core_type(x);
  518. y = core_type(y);
  519. if (a == b) {
  520. return sig_compare(a, x, y);
  521. }
  522. return ((a(x) && b(y)) || (b(x) && a(y)));
  523. }
  524. gb_internal bool signature_parameter_similar_enough(Type *x, Type *y) {
  525. if (sig_compare(is_type_pointer, x, y)) {
  526. return true;
  527. }
  528. if (sig_compare(is_type_multi_pointer, x, y)) {
  529. return true;
  530. }
  531. if (sig_compare(is_type_proc, x, y)) {
  532. return true;
  533. }
  534. if (sig_compare(is_type_integer, x, y)) {
  535. GB_ASSERT(core_type(x)->kind == Type_Basic);
  536. GB_ASSERT(core_type(y)->kind == Type_Basic);
  537. i64 sx = type_size_of(x);
  538. i64 sy = type_size_of(y);
  539. if (sx == sy) return true;
  540. }
  541. if (sig_compare(is_type_integer, is_type_boolean, x, y)) {
  542. GB_ASSERT(core_type(x)->kind == Type_Basic);
  543. GB_ASSERT(core_type(y)->kind == Type_Basic);
  544. i64 sx = type_size_of(x);
  545. i64 sy = type_size_of(y);
  546. if (sx == sy) return true;
  547. }
  548. if (sig_compare(is_type_cstring, is_type_u8_ptr, x, y)) {
  549. return true;
  550. }
  551. if (sig_compare(is_type_cstring, is_type_u8_multi_ptr, x, y)) {
  552. return true;
  553. }
  554. if (sig_compare(is_type_uintptr, is_type_rawptr, x, y)) {
  555. return true;
  556. }
  557. if (sig_compare(is_type_proc, is_type_pointer, x, y)) {
  558. return true;
  559. }
  560. if (sig_compare(is_type_pointer, is_type_multi_pointer, x, y)) {
  561. return true;
  562. }
  563. if (sig_compare(is_type_proc, is_type_multi_pointer, x, y)) {
  564. return true;
  565. }
  566. return are_types_identical(x, y);
  567. }
  568. gb_internal bool are_signatures_similar_enough(Type *a_, Type *b_) {
  569. GB_ASSERT(a_->kind == Type_Proc);
  570. GB_ASSERT(b_->kind == Type_Proc);
  571. TypeProc *a = &a_->Proc;
  572. TypeProc *b = &b_->Proc;
  573. if (a->param_count != b->param_count) {
  574. return false;
  575. }
  576. if (a->result_count != b->result_count) {
  577. return false;
  578. }
  579. for (isize i = 0; i < a->param_count; i++) {
  580. Type *x = core_type(a->params->Tuple.variables[i]->type);
  581. Type *y = core_type(b->params->Tuple.variables[i]->type);
  582. if (!signature_parameter_similar_enough(x, y)) {
  583. return false;
  584. }
  585. }
  586. for (isize i = 0; i < a->result_count; i++) {
  587. Type *x = base_type(a->results->Tuple.variables[i]->type);
  588. Type *y = base_type(b->results->Tuple.variables[i]->type);
  589. if (!signature_parameter_similar_enough(x, y)) {
  590. return false;
  591. }
  592. }
  593. return true;
  594. }
  595. gb_internal Entity *init_entity_foreign_library(CheckerContext *ctx, Entity *e) {
  596. Ast *ident = nullptr;
  597. Entity **foreign_library = nullptr;
  598. switch (e->kind) {
  599. case Entity_Procedure:
  600. ident = e->Procedure.foreign_library_ident;
  601. foreign_library = &e->Procedure.foreign_library;
  602. break;
  603. case Entity_Variable:
  604. ident = e->Variable.foreign_library_ident;
  605. foreign_library = &e->Variable.foreign_library;
  606. break;
  607. default:
  608. return nullptr;
  609. }
  610. if (ident == nullptr) {
  611. error(e->token, "foreign entities must declare which library they are from");
  612. } else if (ident->kind != Ast_Ident) {
  613. error(ident, "foreign library names must be an identifier");
  614. } else {
  615. String name = ident->Ident.token.string;
  616. Entity *found = scope_lookup(ctx->scope, name);
  617. if (found == nullptr) {
  618. if (is_blank_ident(name)) {
  619. // NOTE(bill): link against nothing
  620. } else {
  621. error(ident, "Undeclared name: %.*s", LIT(name));
  622. }
  623. } else if (found->kind != Entity_LibraryName) {
  624. error(ident, "'%.*s' cannot be used as a library name", LIT(name));
  625. } else {
  626. // TODO(bill): Extra stuff to do with library names?
  627. *foreign_library = found;
  628. found->flags |= EntityFlag_Used;
  629. add_entity_use(ctx, ident, found);
  630. return found;
  631. }
  632. }
  633. return nullptr;
  634. }
  635. gb_internal String handle_link_name(CheckerContext *ctx, Token token, String link_name, String link_prefix, String link_suffix) {
  636. String original_link_name = link_name;
  637. if (link_prefix.len > 0) {
  638. if (original_link_name.len > 0) {
  639. error(token, "'link_name' and 'link_prefix' cannot be used together");
  640. } else {
  641. isize len = link_prefix.len + token.string.len;
  642. u8 *name = gb_alloc_array(permanent_allocator(), u8, len+1);
  643. gb_memmove(name, &link_prefix[0], link_prefix.len);
  644. gb_memmove(name+link_prefix.len, &token.string[0], token.string.len);
  645. name[len] = 0;
  646. link_name = make_string(name, len);
  647. }
  648. }
  649. if (link_suffix.len > 0) {
  650. if (original_link_name.len > 0) {
  651. error(token, "'link_name' and 'link_suffix' cannot be used together");
  652. } else {
  653. String new_name = token.string;
  654. if (link_name != original_link_name) {
  655. new_name = link_name;
  656. }
  657. isize len = new_name.len + link_suffix.len;
  658. u8 *name = gb_alloc_array(permanent_allocator(), u8, len+1);
  659. gb_memmove(name, &new_name[0], new_name.len);
  660. gb_memmove(name+new_name.len, &link_suffix[0], link_suffix.len);
  661. name[len] = 0;
  662. link_name = make_string(name, len);
  663. }
  664. }
  665. return link_name;
  666. }
  667. gb_internal void check_objc_methods(CheckerContext *ctx, Entity *e, AttributeContext const &ac) {
  668. if (!(ac.objc_name.len || ac.objc_is_class_method || ac.objc_type)) {
  669. return;
  670. }
  671. if (ac.objc_name.len == 0 && ac.objc_is_class_method) {
  672. error(e->token, "@(objc_name) is required with @(objc_is_class_method)");
  673. } else if (ac.objc_type == nullptr) {
  674. error(e->token, "@(objc_name) requires that @(objc_type) to be set");
  675. } else if (ac.objc_name.len == 0 && ac.objc_type) {
  676. error(e->token, "@(objc_name) is required with @(objc_type)");
  677. } else {
  678. Type *t = ac.objc_type;
  679. if (t->kind == Type_Named) {
  680. Entity *tn = t->Named.type_name;
  681. GB_ASSERT(tn->kind == Entity_TypeName);
  682. if (tn->scope != e->scope) {
  683. error(e->token, "@(objc_name) attribute may only be applied to procedures and types within the same scope");
  684. } else {
  685. mutex_lock(&global_type_name_objc_metadata_mutex);
  686. defer (mutex_unlock(&global_type_name_objc_metadata_mutex));
  687. if (!tn->TypeName.objc_metadata) {
  688. tn->TypeName.objc_metadata = create_type_name_obj_c_metadata();
  689. }
  690. auto *md = tn->TypeName.objc_metadata;
  691. mutex_lock(md->mutex);
  692. defer (mutex_unlock(md->mutex));
  693. if (!ac.objc_is_class_method) {
  694. bool ok = true;
  695. for (TypeNameObjCMetadataEntry const &entry : md->value_entries) {
  696. if (entry.name == ac.objc_name) {
  697. error(e->token, "Previous declaration of @(objc_name=\"%.*s\")", LIT(ac.objc_name));
  698. ok = false;
  699. break;
  700. }
  701. }
  702. if (ok) {
  703. array_add(&md->value_entries, TypeNameObjCMetadataEntry{ac.objc_name, e});
  704. }
  705. } else {
  706. bool ok = true;
  707. for (TypeNameObjCMetadataEntry const &entry : md->type_entries) {
  708. if (entry.name == ac.objc_name) {
  709. error(e->token, "Previous declaration of @(objc_name=\"%.*s\")", LIT(ac.objc_name));
  710. ok = false;
  711. break;
  712. }
  713. }
  714. if (ok) {
  715. array_add(&md->type_entries, TypeNameObjCMetadataEntry{ac.objc_name, e});
  716. }
  717. }
  718. }
  719. }
  720. }
  721. }
  722. gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
  723. GB_ASSERT(e->type == nullptr);
  724. if (d->proc_lit->kind != Ast_ProcLit) {
  725. // TOOD(bill): Better error message
  726. error(d->proc_lit, "Expected a procedure to check");
  727. return;
  728. }
  729. Type *proc_type = e->type;
  730. if (d->gen_proc_type != nullptr) {
  731. proc_type = d->gen_proc_type;
  732. } else {
  733. proc_type = alloc_type_proc(e->scope, nullptr, 0, nullptr, 0, false, default_calling_convention());
  734. }
  735. e->type = proc_type;
  736. ast_node(pl, ProcLit, d->proc_lit);
  737. check_open_scope(ctx, pl->type);
  738. defer (check_close_scope(ctx));
  739. ctx->scope->procedure_entity = e;
  740. Type *decl_type = nullptr;
  741. if (d->type_expr != nullptr) {
  742. decl_type = check_type(ctx, d->type_expr);
  743. if (!is_type_proc(decl_type)) {
  744. gbString str = type_to_string(decl_type);
  745. error(d->type_expr, "Expected a procedure type, got '%s'", str);
  746. gb_string_free(str);
  747. }
  748. }
  749. auto tmp_ctx = *ctx;
  750. tmp_ctx.allow_polymorphic_types = true;
  751. if (decl_type != nullptr) {
  752. tmp_ctx.type_hint = decl_type;
  753. }
  754. check_procedure_type(&tmp_ctx, proc_type, pl->type);
  755. if (decl_type != nullptr) {
  756. Operand x = {};
  757. x.type = e->type;
  758. x.mode = Addressing_Variable;
  759. if (!check_is_assignable_to(ctx, &x, decl_type)) {
  760. gbString expr_str = expr_to_string(d->proc_lit);
  761. gbString op_type_str = type_to_string(e->type);
  762. gbString type_str = type_to_string(decl_type);
  763. error(e->token,
  764. "Cannot assign '%s' of type '%s' to '%s'",
  765. expr_str,
  766. op_type_str,
  767. type_str);
  768. gb_string_free(type_str);
  769. gb_string_free(op_type_str);
  770. gb_string_free(expr_str);
  771. }
  772. }
  773. TypeProc *pt = &proc_type->Proc;
  774. AttributeContext ac = make_attribute_context(e->Procedure.link_prefix, e->Procedure.link_suffix);
  775. if (d != nullptr) {
  776. check_decl_attributes(ctx, d->attributes, proc_decl_attribute, &ac);
  777. }
  778. if (ac.test) {
  779. e->flags |= EntityFlag_Test;
  780. }
  781. if (ac.init && ac.fini) {
  782. error(e->token, "A procedure cannot be both declared as @(init) and @(fini)");
  783. } else if (ac.init) {
  784. e->flags |= EntityFlag_Init;
  785. } else if (ac.fini) {
  786. e->flags |= EntityFlag_Fini;
  787. }
  788. if (ac.set_cold) {
  789. e->flags |= EntityFlag_Cold;
  790. }
  791. e->Procedure.optimization_mode = cast(ProcedureOptimizationMode)ac.optimization_mode;
  792. check_objc_methods(ctx, e, ac);
  793. {
  794. if (ac.require_target_feature.len != 0 && ac.enable_target_feature.len != 0) {
  795. error(e->token, "A procedure cannot have both @(require_target_feature=\"...\") and @(enable_target_feature=\"...\")");
  796. }
  797. if (build_context.strict_target_features && ac.enable_target_feature.len != 0) {
  798. ac.require_target_feature = ac.enable_target_feature;
  799. ac.enable_target_feature.len = 0;
  800. }
  801. if (ac.require_target_feature.len != 0) {
  802. pt->require_target_feature = ac.require_target_feature;
  803. String invalid;
  804. if (!check_target_feature_is_valid_globally(ac.require_target_feature, &invalid)) {
  805. error(e->token, "Required target feature '%.*s' is not a valid target feature", LIT(invalid));
  806. } else if (!check_target_feature_is_enabled(ac.require_target_feature, nullptr)) {
  807. e->flags |= EntityFlag_Disabled;
  808. }
  809. } else if (ac.enable_target_feature.len != 0) {
  810. // NOTE: disallow wasm, features on that arch are always global to the module.
  811. if (is_arch_wasm()) {
  812. error(e->token, "@(enable_target_feature=\"...\") is not allowed on wasm, features for wasm must be declared globally");
  813. }
  814. pt->enable_target_feature = ac.enable_target_feature;
  815. String invalid;
  816. if (!check_target_feature_is_valid_globally(ac.enable_target_feature, &invalid)) {
  817. error(e->token, "Procedure enabled target feature '%.*s' is not a valid target feature", LIT(invalid));
  818. }
  819. }
  820. }
  821. switch (e->Procedure.optimization_mode) {
  822. case ProcedureOptimizationMode_None:
  823. case ProcedureOptimizationMode_Minimal:
  824. if (pl->inlining == ProcInlining_inline) {
  825. error(e->token, "#force_inline cannot be used in conjunction with the attribute 'optimization_mode' with neither \"none\" nor \"minimal\"");
  826. }
  827. break;
  828. }
  829. e->Procedure.entry_point_only = ac.entry_point_only;
  830. e->Procedure.is_export = ac.is_export;
  831. bool has_instrumentation = false;
  832. if (pl->body == nullptr) {
  833. has_instrumentation = false;
  834. if (ac.no_instrumentation != Instrumentation_Default) {
  835. error(e->token, "@(no_instrumentation) is not allowed on foreign procedures");
  836. }
  837. } else {
  838. AstFile *file = e->token.pos.file_id ? global_files[e->token.pos.file_id] : nullptr;
  839. if (file) {
  840. has_instrumentation = (file->flags & AstFile_NoInstrumentation) == 0;
  841. }
  842. switch (ac.no_instrumentation) {
  843. case Instrumentation_Enabled: has_instrumentation = true; break;
  844. case Instrumentation_Default: break;
  845. case Instrumentation_Disabled: has_instrumentation = false; break;
  846. }
  847. }
  848. auto const is_valid_instrumentation_call = [](Type *type) -> bool {
  849. if (type == nullptr || type->kind != Type_Proc) {
  850. return false;
  851. }
  852. if (type->Proc.calling_convention != ProcCC_Contextless) {
  853. return false;
  854. }
  855. if (type->Proc.result_count != 0) {
  856. return false;
  857. }
  858. if (type->Proc.param_count != 3) {
  859. return false;
  860. }
  861. Type *p0 = type->Proc.params->Tuple.variables[0]->type;
  862. Type *p1 = type->Proc.params->Tuple.variables[1]->type;
  863. Type *p3 = type->Proc.params->Tuple.variables[2]->type;
  864. return is_type_rawptr(p0) && is_type_rawptr(p1) && are_types_identical(p3, t_source_code_location);
  865. };
  866. static char const *instrumentation_proc_type_str = "proc \"contextless\" (proc_address: rawptr, call_site_return_address: rawptr, loc: runtime.Source_Code_Location)";
  867. if (ac.instrumentation_enter && ac.instrumentation_exit) {
  868. error(e->token, "A procedure cannot be marked with both @(instrumentation_enter) and @(instrumentation_exit)");
  869. has_instrumentation = false;
  870. e->flags |= EntityFlag_Require;
  871. } else if (ac.instrumentation_enter) {
  872. if (!is_valid_instrumentation_call(e->type)) {
  873. init_core_source_code_location(ctx->checker);
  874. gbString s = type_to_string(e->type);
  875. error(e->token, "@(instrumentation_enter) procedures must have the type '%s', got %s", instrumentation_proc_type_str, s);
  876. gb_string_free(s);
  877. }
  878. MUTEX_GUARD(&ctx->info->instrumentation_mutex);
  879. if (ctx->info->instrumentation_enter_entity != nullptr) {
  880. error(e->token, "@(instrumentation_enter) has already been set");
  881. } else {
  882. ctx->info->instrumentation_enter_entity = e;
  883. }
  884. has_instrumentation = false;
  885. e->flags |= EntityFlag_Require;
  886. } else if (ac.instrumentation_exit) {
  887. init_core_source_code_location(ctx->checker);
  888. if (!is_valid_instrumentation_call(e->type)) {
  889. gbString s = type_to_string(e->type);
  890. error(e->token, "@(instrumentation_exit) procedures must have the type '%s', got %s", instrumentation_proc_type_str, s);
  891. gb_string_free(s);
  892. }
  893. MUTEX_GUARD(&ctx->info->instrumentation_mutex);
  894. if (ctx->info->instrumentation_exit_entity != nullptr) {
  895. error(e->token, "@(instrumentation_exit) has already been set");
  896. } else {
  897. ctx->info->instrumentation_exit_entity = e;
  898. }
  899. has_instrumentation = false;
  900. e->flags |= EntityFlag_Require;
  901. }
  902. e->Procedure.has_instrumentation = has_instrumentation;
  903. e->deprecated_message = ac.deprecated_message;
  904. e->warning_message = ac.warning_message;
  905. ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix,ac.link_suffix);
  906. if (ac.has_disabled_proc) {
  907. if (ac.disabled_proc) {
  908. e->flags |= EntityFlag_Disabled;
  909. }
  910. Type *t = base_type(e->type);
  911. GB_ASSERT(t->kind == Type_Proc);
  912. if (t->Proc.result_count != 0) {
  913. error(e->token, "Procedure with the 'disabled' attribute may not have any return values");
  914. }
  915. }
  916. bool is_foreign = e->Procedure.is_foreign;
  917. bool is_export = e->Procedure.is_export;
  918. if (ac.linkage.len != 0) {
  919. if (ac.linkage == "internal") { e->flags |= EntityFlag_CustomLinkage_Internal; }
  920. else if (ac.linkage == "strong") { e->flags |= EntityFlag_CustomLinkage_Strong; }
  921. else if (ac.linkage == "weak") { e->flags |= EntityFlag_CustomLinkage_Weak; }
  922. else if (ac.linkage == "link_once") { e->flags |= EntityFlag_CustomLinkage_LinkOnce; }
  923. if (is_foreign && (e->flags & EntityFlag_CustomLinkage_Internal)) {
  924. error(e->token, "A foreign procedure may not have an \"internal\" linkage");
  925. }
  926. }
  927. if (ac.require_declaration) {
  928. e->flags |= EntityFlag_Require;
  929. pl->inlining = ProcInlining_no_inline;
  930. }
  931. if (e->pkg != nullptr && e->token.string == "main" && !build_context.no_entry_point) {
  932. if (e->pkg->kind != Package_Runtime) {
  933. if (pt->param_count != 0 ||
  934. pt->result_count != 0) {
  935. gbString str = type_to_string(proc_type);
  936. error(e->token, "Procedure type of 'main' was expected to be 'proc()', got %s", str);
  937. gb_string_free(str);
  938. }
  939. if (pt->calling_convention != default_calling_convention()) {
  940. error(e->token, "Procedure 'main' cannot have a custom calling convention");
  941. }
  942. pt->calling_convention = default_calling_convention();
  943. if (e->pkg->kind == Package_Init) {
  944. if (ctx->info->entry_point != nullptr) {
  945. error(e->token, "Redeclaration of the entry pointer procedure 'main'");
  946. } else {
  947. ctx->info->entry_point = e;
  948. }
  949. }
  950. }
  951. }
  952. if (is_foreign && is_export) {
  953. error(pl->type, "A foreign procedure cannot have an 'export' tag");
  954. }
  955. if (pt->is_polymorphic) {
  956. if (pl->body == nullptr) {
  957. error(e->token, "Polymorphic procedures must have a body");
  958. }
  959. if (is_foreign) {
  960. error(e->token, "A foreign procedure cannot be a polymorphic");
  961. return;
  962. }
  963. }
  964. if (pl->body != nullptr) {
  965. if (is_foreign) {
  966. error(pl->body, "A foreign procedure cannot have a body");
  967. }
  968. if (proc_type->Proc.c_vararg) {
  969. error(pl->body, "A procedure with a '#c_vararg' field cannot have a body and must be foreign");
  970. }
  971. d->scope = ctx->scope;
  972. GB_ASSERT(pl->body->kind == Ast_BlockStmt);
  973. if (!pt->is_polymorphic) {
  974. check_procedure_later(ctx->checker, ctx->file, e->token, d, proc_type, pl->body, pl->tags);
  975. }
  976. } else if (!is_foreign) {
  977. if (e->Procedure.is_export) {
  978. error(e->token, "Foreign export procedures must have a body");
  979. } else {
  980. error(e->token, "Only a foreign procedure cannot have a body");
  981. }
  982. }
  983. if (ac.require_results) {
  984. if (pt->result_count == 0) {
  985. error(pl->type, "'require_results' is not needed on a procedure with no results");
  986. } else {
  987. pt->require_results = true;
  988. }
  989. }
  990. if (ac.link_name.len > 0) {
  991. String ln = ac.link_name;
  992. e->Procedure.link_name = ln;
  993. if (ln == "memcpy" ||
  994. ln == "memmove" ||
  995. ln == "mem_copy" ||
  996. ln == "mem_copy_non_overlapping") {
  997. e->Procedure.is_memcpy_like = true;
  998. }
  999. }
  1000. if (ac.deferred_procedure.entity != nullptr) {
  1001. e->Procedure.deferred_procedure = ac.deferred_procedure;
  1002. mpsc_enqueue(&ctx->checker->procs_with_deferred_to_check, e);
  1003. }
  1004. if (is_foreign) {
  1005. String name = e->token.string;
  1006. if (e->Procedure.link_name.len > 0) {
  1007. name = e->Procedure.link_name;
  1008. }
  1009. Entity *foreign_library = init_entity_foreign_library(ctx, e);
  1010. if (is_arch_wasm() && foreign_library != nullptr) {
  1011. String module_name = str_lit("env");
  1012. GB_ASSERT (foreign_library->kind == Entity_LibraryName);
  1013. if (foreign_library->LibraryName.paths.count != 1) {
  1014. error(foreign_library->token, "'foreign import' for '%.*s' architecture may only have one path, got %td",
  1015. LIT(target_arch_names[build_context.metrics.arch]), foreign_library->LibraryName.paths.count);
  1016. }
  1017. if (foreign_library->LibraryName.paths.count >= 1) {
  1018. module_name = foreign_library->LibraryName.paths[0];
  1019. }
  1020. name = concatenate3_strings(permanent_allocator(), module_name, WASM_MODULE_NAME_SEPARATOR, name);
  1021. }
  1022. e->Procedure.is_foreign = true;
  1023. e->Procedure.link_name = name;
  1024. mutex_lock(&ctx->info->foreign_mutex);
  1025. auto *fp = &ctx->info->foreigns;
  1026. StringHashKey key = string_hash_string(name);
  1027. Entity **found = string_map_get(fp, key);
  1028. if (found && e != *found) {
  1029. Entity *f = *found;
  1030. TokenPos pos = f->token.pos;
  1031. Type *this_type = base_type(e->type);
  1032. Type *other_type = base_type(f->type);
  1033. if (is_type_proc(this_type) && is_type_proc(other_type)) {
  1034. if (!are_signatures_similar_enough(this_type, other_type)) {
  1035. error(d->proc_lit,
  1036. "Redeclaration of foreign procedure '%.*s' with different type signatures\n"
  1037. "\tat %s",
  1038. LIT(name), token_pos_to_string(pos));
  1039. }
  1040. } else if (!signature_parameter_similar_enough(this_type, other_type)) {
  1041. error(d->proc_lit,
  1042. "Foreign entity '%.*s' previously declared elsewhere with a different type\n"
  1043. "\tat %s",
  1044. LIT(name), token_pos_to_string(pos));
  1045. }
  1046. } else if (name == "main") {
  1047. error(d->proc_lit, "The link name 'main' is reserved for internal use");
  1048. } else {
  1049. string_map_set(fp, key, e);
  1050. }
  1051. mutex_unlock(&ctx->info->foreign_mutex);
  1052. } else {
  1053. String name = e->token.string;
  1054. if (e->Procedure.link_name.len > 0) {
  1055. name = e->Procedure.link_name;
  1056. }
  1057. if (e->Procedure.link_name.len > 0 || is_export) {
  1058. mutex_lock(&ctx->info->foreign_mutex);
  1059. auto *fp = &ctx->info->foreigns;
  1060. StringHashKey key = string_hash_string(name);
  1061. Entity **found = string_map_get(fp, key);
  1062. if (found) {
  1063. Entity *f = *found;
  1064. TokenPos pos = f->token.pos;
  1065. // TODO(bill): Better error message?
  1066. error(d->proc_lit,
  1067. "Non unique linking name for procedure '%.*s'\n"
  1068. "\tother at %s",
  1069. LIT(name), token_pos_to_string(pos));
  1070. } else if (name == "main") {
  1071. if (d->entity->pkg->kind != Package_Runtime) {
  1072. error(d->proc_lit, "The link name 'main' is reserved for internal use");
  1073. }
  1074. } else {
  1075. string_map_set(fp, key, e);
  1076. }
  1077. mutex_unlock(&ctx->info->foreign_mutex);
  1078. }
  1079. }
  1080. if (e->Procedure.link_name.len > 0 ) {
  1081. e->flags |= EntityFlag_CustomLinkName;
  1082. }
  1083. }
  1084. gb_internal void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast *type_expr, Ast *init_expr) {
  1085. GB_ASSERT(e->type == nullptr);
  1086. GB_ASSERT(e->kind == Entity_Variable);
  1087. if (e->flags & EntityFlag_Visited) {
  1088. e->type = t_invalid;
  1089. return;
  1090. }
  1091. e->flags |= EntityFlag_Visited;
  1092. AttributeContext ac = make_attribute_context(e->Variable.link_prefix, e->Variable.link_suffix);
  1093. ac.init_expr_list_count = init_expr != nullptr ? 1 : 0;
  1094. DeclInfo *decl = decl_info_of_entity(e);
  1095. GB_ASSERT(decl == ctx->decl);
  1096. if (decl != nullptr) {
  1097. check_decl_attributes(ctx, decl->attributes, var_decl_attribute, &ac);
  1098. }
  1099. if (ac.require_declaration) {
  1100. e->flags |= EntityFlag_Require;
  1101. mpsc_enqueue(&ctx->info->required_global_variable_queue, e);
  1102. }
  1103. e->Variable.thread_local_model = ac.thread_local_model;
  1104. e->Variable.is_export = ac.is_export;
  1105. e->flags &= ~EntityFlag_Static;
  1106. if (ac.is_static) {
  1107. error(e->token, "@(static) is not supported for global variables, nor required");
  1108. }
  1109. if (ac.rodata) {
  1110. e->Variable.is_rodata = true;
  1111. }
  1112. ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix, ac.link_suffix);
  1113. if (is_arch_wasm() && e->Variable.thread_local_model.len != 0) {
  1114. e->Variable.thread_local_model.len = 0;
  1115. // NOTE(bill): ignore this message for the time being
  1116. // error(e->token, "@(thread_local) is not supported for this target platform");
  1117. }
  1118. if(build_context.no_thread_local) {
  1119. e->Variable.thread_local_model.len = 0;
  1120. }
  1121. String context_name = str_lit("variable declaration");
  1122. if (type_expr != nullptr) {
  1123. e->type = check_type(ctx, type_expr);
  1124. }
  1125. if (e->type != nullptr) {
  1126. if (is_type_polymorphic(base_type(e->type))) {
  1127. gbString str = type_to_string(e->type);
  1128. defer (gb_string_free(str));
  1129. error(e->token, "Invalid use of a polymorphic type '%s' in %.*s", str, LIT(context_name));
  1130. e->type = t_invalid;
  1131. } else if (is_type_empty_union(e->type)) {
  1132. gbString str = type_to_string(e->type);
  1133. defer (gb_string_free(str));
  1134. error(e->token, "An empty union '%s' cannot be instantiated in %.*s", str, LIT(context_name));
  1135. e->type = t_invalid;
  1136. }
  1137. }
  1138. if (e->Variable.is_foreign) {
  1139. if (init_expr != nullptr) {
  1140. error(e->token, "A foreign variable declaration cannot have a default value");
  1141. }
  1142. init_entity_foreign_library(ctx, e);
  1143. if (is_arch_wasm() && e->Variable.foreign_library != nullptr) {
  1144. error(e->token, "A foreign variable declaration can not be scoped to a module and must be declared in a 'foreign {' (without a library) block");
  1145. }
  1146. }
  1147. if (ac.link_name.len > 0) {
  1148. e->Variable.link_name = ac.link_name;
  1149. }
  1150. if (ac.link_section.len > 0) {
  1151. e->Variable.link_section = ac.link_section;
  1152. }
  1153. if (e->Variable.is_foreign || e->Variable.is_export) {
  1154. String name = e->token.string;
  1155. if (e->Variable.link_name.len > 0) {
  1156. name = e->Variable.link_name;
  1157. }
  1158. auto *fp = &ctx->info->foreigns;
  1159. StringHashKey key = string_hash_string(name);
  1160. Entity **found = string_map_get(fp, key);
  1161. if (found) {
  1162. Entity *f = *found;
  1163. TokenPos pos = f->token.pos;
  1164. Type *this_type = base_type(e->type);
  1165. Type *other_type = base_type(f->type);
  1166. if (!signature_parameter_similar_enough(this_type, other_type)) {
  1167. error(e->token,
  1168. "Foreign entity '%.*s' previously declared elsewhere with a different type\n"
  1169. "\tat %s",
  1170. LIT(name), token_pos_to_string(pos));
  1171. }
  1172. } else {
  1173. string_map_set(fp, key, e);
  1174. }
  1175. }
  1176. if (e->Variable.link_name.len > 0) {
  1177. e->flags |= EntityFlag_CustomLinkName;
  1178. }
  1179. if (init_expr == nullptr) {
  1180. if (type_expr == nullptr) {
  1181. e->type = t_invalid;
  1182. }
  1183. return;
  1184. }
  1185. Operand o = {};
  1186. check_expr_with_type_hint(ctx, &o, init_expr, e->type);
  1187. check_init_variable(ctx, e, &o, str_lit("variable declaration"));
  1188. if (e->Variable.is_rodata && o.mode != Addressing_Constant) {
  1189. error(o.expr, "Variables declared with @(rodata) must have constant initialization");
  1190. }
  1191. check_rtti_type_disallowed(e->token, e->type, "A variable declaration is using a type, %s, which has been disallowed");
  1192. }
  1193. gb_internal void check_proc_group_decl(CheckerContext *ctx, Entity *pg_entity, DeclInfo *d) {
  1194. GB_ASSERT(pg_entity->kind == Entity_ProcGroup);
  1195. auto *pge = &pg_entity->ProcGroup;
  1196. String proc_group_name = pg_entity->token.string;
  1197. ast_node(pg, ProcGroup, d->init_expr);
  1198. pge->entities = array_make<Entity*>(permanent_allocator(), 0, pg->args.count);
  1199. // NOTE(bill): This must be set here to prevent cycles in checking if someone
  1200. // places the entity within itself
  1201. pg_entity->type = t_invalid;
  1202. PtrSet<Entity *> entity_set = {};
  1203. ptr_set_init(&entity_set, 2*pg->args.count);
  1204. for (Ast *arg : pg->args) {
  1205. Entity *e = nullptr;
  1206. Operand o = {};
  1207. if (arg->kind == Ast_Ident) {
  1208. e = check_ident(ctx, &o, arg, nullptr, nullptr, true);
  1209. } else if (arg->kind == Ast_SelectorExpr) {
  1210. e = check_selector(ctx, &o, arg, nullptr);
  1211. }
  1212. if (e == nullptr) {
  1213. error(arg, "Expected a valid entity name in procedure group, got %.*s", LIT(ast_strings[arg->kind]));
  1214. continue;
  1215. }
  1216. if (e->kind == Entity_Variable) {
  1217. if (!is_type_proc(e->type)) {
  1218. gbString s = type_to_string(e->type);
  1219. defer (gb_string_free(s));
  1220. error(arg, "Expected a procedure, got %s", s);
  1221. continue;
  1222. }
  1223. } else if (e->kind != Entity_Procedure) {
  1224. error(arg, "Expected a procedure entity");
  1225. continue;
  1226. }
  1227. if (ptr_set_update(&entity_set, e)) {
  1228. error(arg, "Previous use of `%.*s` in procedure group", LIT(e->token.string));
  1229. continue;
  1230. }
  1231. array_add(&pge->entities, e);
  1232. }
  1233. ptr_set_destroy(&entity_set);
  1234. for (isize j = 0; j < pge->entities.count; j++) {
  1235. Entity *p = pge->entities[j];
  1236. if (p->type == t_invalid) {
  1237. // NOTE(bill): This invalid overload has already been handled
  1238. continue;
  1239. }
  1240. if (p->flags & EntityFlag_Disabled) {
  1241. continue;
  1242. }
  1243. String name = p->token.string;
  1244. for (isize k = j+1; k < pge->entities.count; k++) {
  1245. Entity *q = pge->entities[k];
  1246. GB_ASSERT(p != q);
  1247. bool is_invalid = false;
  1248. TokenPos pos = q->token.pos;
  1249. if (q->type == nullptr || q->type == t_invalid) {
  1250. continue;
  1251. }
  1252. ERROR_BLOCK();
  1253. if (q->flags & EntityFlag_Disabled) {
  1254. continue;
  1255. }
  1256. ProcTypeOverloadKind kind = are_proc_types_overload_safe(p->type, q->type);
  1257. bool both_have_where_clauses = false;
  1258. if (p->decl_info->proc_lit != nullptr && q->decl_info->proc_lit != nullptr) {
  1259. GB_ASSERT(p->decl_info->proc_lit->kind == Ast_ProcLit);
  1260. GB_ASSERT(q->decl_info->proc_lit->kind == Ast_ProcLit);
  1261. auto pl = &p->decl_info->proc_lit->ProcLit;
  1262. auto ql = &q->decl_info->proc_lit->ProcLit;
  1263. // Allow collisions if the procedures both have 'where' clauses and are both polymorphic
  1264. bool pw = pl->where_token.kind != Token_Invalid && is_type_polymorphic(p->type, true);
  1265. bool qw = ql->where_token.kind != Token_Invalid && is_type_polymorphic(q->type, true);
  1266. both_have_where_clauses = pw && qw;
  1267. }
  1268. if (!both_have_where_clauses) switch (kind) {
  1269. case ProcOverload_Identical:
  1270. error(p->token, "Overloaded procedure '%.*s' has the same type as another procedure in the procedure group '%.*s'", LIT(name), LIT(proc_group_name));
  1271. is_invalid = true;
  1272. break;
  1273. // case ProcOverload_CallingConvention:
  1274. // error(p->token, "Overloaded procedure '%.*s' has the same type as another procedure in the procedure group '%.*s'", LIT(name), LIT(proc_group_name));
  1275. // is_invalid = true;
  1276. // break;
  1277. case ProcOverload_ParamVariadic:
  1278. error(p->token, "Overloaded procedure '%.*s' has the same type as another procedure in the procedure group '%.*s'", LIT(name), LIT(proc_group_name));
  1279. is_invalid = true;
  1280. break;
  1281. case ProcOverload_ResultCount:
  1282. case ProcOverload_ResultTypes:
  1283. error(p->token, "Overloaded procedure '%.*s' has the same parameters but different results in the procedure group '%.*s'", LIT(name), LIT(proc_group_name));
  1284. is_invalid = true;
  1285. break;
  1286. case ProcOverload_Polymorphic:
  1287. break;
  1288. case ProcOverload_ParamCount:
  1289. case ProcOverload_ParamTypes:
  1290. case ProcOverload_TargetFeatures:
  1291. // This is okay :)
  1292. break;
  1293. }
  1294. if (is_invalid) {
  1295. error_line("\tprevious procedure at %s\n", token_pos_to_string(pos));
  1296. q->type = t_invalid;
  1297. }
  1298. }
  1299. }
  1300. AttributeContext ac = {};
  1301. check_decl_attributes(ctx, d->attributes, proc_group_attribute, &ac);
  1302. check_objc_methods(ctx, pg_entity, ac);
  1303. }
  1304. gb_internal void check_entity_decl(CheckerContext *ctx, Entity *e, DeclInfo *d, Type *named_type) {
  1305. if (e->state == EntityState_Resolved) {
  1306. return;
  1307. }
  1308. if (e->flags & EntityFlag_Lazy) {
  1309. mutex_lock(&ctx->info->lazy_mutex);
  1310. }
  1311. String name = e->token.string;
  1312. if (e->type != nullptr || e->state != EntityState_Unresolved) {
  1313. error(e->token, "Illegal declaration cycle of `%.*s`", LIT(name));
  1314. } else {
  1315. GB_ASSERT(e->state == EntityState_Unresolved);
  1316. if (d == nullptr) {
  1317. d = decl_info_of_entity(e);
  1318. if (d == nullptr) {
  1319. // TODO(bill): Err here?
  1320. e->type = t_invalid;
  1321. e->state = EntityState_Resolved;
  1322. set_base_type(named_type, t_invalid);
  1323. goto end;
  1324. }
  1325. }
  1326. CheckerContext c = *ctx;
  1327. c.scope = d->scope;
  1328. c.decl = d;
  1329. c.type_level = 0;
  1330. e->parent_proc_decl = c.curr_proc_decl;
  1331. e->state = EntityState_InProgress;
  1332. switch (e->kind) {
  1333. case Entity_Variable:
  1334. check_global_variable_decl(&c, e, d->type_expr, d->init_expr);
  1335. break;
  1336. case Entity_Constant:
  1337. check_const_decl(&c, e, d->type_expr, d->init_expr, named_type);
  1338. break;
  1339. case Entity_TypeName: {
  1340. check_type_decl(&c, e, d->init_expr, named_type);
  1341. break;
  1342. }
  1343. case Entity_Procedure:
  1344. check_proc_decl(&c, e, d);
  1345. break;
  1346. case Entity_ProcGroup:
  1347. check_proc_group_decl(&c, e, d);
  1348. break;
  1349. }
  1350. e->state = EntityState_Resolved;
  1351. }
  1352. end:;
  1353. // NOTE(bill): Add it to the list of checked entities
  1354. if (e->flags & EntityFlag_Lazy) {
  1355. array_add(&ctx->info->entities, e);
  1356. mutex_unlock(&ctx->info->lazy_mutex);
  1357. }
  1358. }
  1359. gb_internal void add_deps_from_child_to_parent(DeclInfo *decl) {
  1360. if (decl && decl->parent) {
  1361. Scope *ps = decl->parent->scope;
  1362. if (ps->flags & (ScopeFlag_File & ScopeFlag_Pkg & ScopeFlag_Global)) {
  1363. return;
  1364. } else {
  1365. // NOTE(bill): Add the dependencies from the procedure literal (lambda)
  1366. // But only at the procedure level
  1367. rw_mutex_shared_lock(&decl->deps_mutex);
  1368. rw_mutex_lock(&decl->parent->deps_mutex);
  1369. for (Entity *e : decl->deps) {
  1370. ptr_set_add(&decl->parent->deps, e);
  1371. }
  1372. rw_mutex_unlock(&decl->parent->deps_mutex);
  1373. rw_mutex_shared_unlock(&decl->deps_mutex);
  1374. rw_mutex_shared_lock(&decl->type_info_deps_mutex);
  1375. rw_mutex_lock(&decl->parent->type_info_deps_mutex);
  1376. for (Type *t : decl->type_info_deps) {
  1377. ptr_set_add(&decl->parent->type_info_deps, t);
  1378. }
  1379. rw_mutex_unlock(&decl->parent->type_info_deps_mutex);
  1380. rw_mutex_shared_unlock(&decl->type_info_deps_mutex);
  1381. }
  1382. }
  1383. }
  1384. struct ProcUsingVar {
  1385. Entity *e;
  1386. Entity *uvar;
  1387. };
  1388. gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *type, Ast *body) {
  1389. if (body == nullptr) {
  1390. return false;
  1391. }
  1392. GB_ASSERT(body->kind == Ast_BlockStmt);
  1393. String proc_name = {};
  1394. if (token.kind == Token_Ident) {
  1395. proc_name = token.string;
  1396. } else {
  1397. // TODO(bill): Better name
  1398. proc_name = str_lit("(anonymous-procedure)");
  1399. }
  1400. CheckerContext new_ctx = *ctx_;
  1401. CheckerContext *ctx = &new_ctx;
  1402. GB_ASSERT(type->kind == Type_Proc);
  1403. ctx->scope = decl->scope;
  1404. ctx->decl = decl;
  1405. ctx->proc_name = proc_name;
  1406. ctx->curr_proc_decl = decl;
  1407. ctx->curr_proc_sig = type;
  1408. ctx->curr_proc_calling_convention = type->Proc.calling_convention;
  1409. if (ctx->pkg->name != "runtime") {
  1410. switch (type->Proc.calling_convention) {
  1411. case ProcCC_None:
  1412. error(body, "Procedures with the calling convention \"none\" are not allowed a body");
  1413. break;
  1414. }
  1415. }
  1416. ast_node(bs, BlockStmt, body);
  1417. Array<ProcUsingVar> using_entities = {};
  1418. using_entities.allocator = heap_allocator();
  1419. defer (array_free(&using_entities));
  1420. {
  1421. if (type->Proc.param_count > 0) {
  1422. TypeTuple *params = &type->Proc.params->Tuple;
  1423. for (Entity *e : params->variables) {
  1424. if (e->kind != Entity_Variable) {
  1425. continue;
  1426. }
  1427. if (is_type_polymorphic(e->type) && is_type_polymorphic_record_unspecialized(e->type)) {
  1428. gbString s = type_to_string(e->type);
  1429. char const *msg = "Unspecialized polymorphic types are not allowed in procedure parameters, got %s";
  1430. if (e->Variable.type_expr) {
  1431. error(e->Variable.type_expr, msg, s);
  1432. } else {
  1433. error(e->token, msg, s);
  1434. }
  1435. gb_string_free(s);
  1436. }
  1437. if (!(e->flags & EntityFlag_Using)) {
  1438. continue;
  1439. }
  1440. if (is_blank_ident(e->token)) {
  1441. error(e->token, "'using' a procedure parameter requires a non blank identifier");
  1442. break;
  1443. }
  1444. bool is_value = (e->flags & EntityFlag_Value) != 0 && !is_type_pointer(e->type);
  1445. String name = e->token.string;
  1446. Type *t = base_type(type_deref(e->type));
  1447. if (t->kind == Type_Struct) {
  1448. Scope *scope = t->Struct.scope;
  1449. GB_ASSERT(scope != nullptr);
  1450. rw_mutex_lock(&scope->mutex);
  1451. for (auto const &entry : scope->elements) {
  1452. Entity *f = entry.value;
  1453. if (f->kind == Entity_Variable) {
  1454. Entity *uvar = alloc_entity_using_variable(e, f->token, f->type, nullptr);
  1455. if (is_value) uvar->flags |= EntityFlag_Value;
  1456. ProcUsingVar puv = {e, uvar};
  1457. array_add(&using_entities, puv);
  1458. }
  1459. }
  1460. rw_mutex_unlock(&scope->mutex);
  1461. } else {
  1462. error(e->token, "'using' can only be applied to variables of type struct");
  1463. break;
  1464. }
  1465. }
  1466. }
  1467. }
  1468. rw_mutex_lock(&ctx->scope->mutex);
  1469. for (auto const &entry : using_entities) {
  1470. Entity *e = entry.e;
  1471. Entity *uvar = entry.uvar;
  1472. Entity *prev = scope_insert_no_mutex(ctx->scope, uvar);
  1473. if (prev != nullptr) {
  1474. ERROR_BLOCK();
  1475. error(e->token, "Namespace collision while 'using' procedure argument '%.*s' of: %.*s", LIT(e->token.string), LIT(prev->token.string));
  1476. error_line("%.*s != %.*s\n", LIT(uvar->token.string), LIT(prev->token.string));
  1477. break;
  1478. }
  1479. }
  1480. rw_mutex_unlock(&ctx->scope->mutex);
  1481. bool where_clause_ok = evaluate_where_clauses(ctx, nullptr, decl->scope, &decl->proc_lit->ProcLit.where_clauses, !decl->where_clauses_evaluated);
  1482. if (!where_clause_ok) {
  1483. // NOTE(bill, 2019-08-31): Don't check the body as the where clauses failed
  1484. return false;
  1485. }
  1486. check_open_scope(ctx, body);
  1487. {
  1488. for (auto const &entry : using_entities) {
  1489. Entity *uvar = entry.uvar;
  1490. Entity *prev = scope_insert(ctx->scope, uvar);
  1491. gb_unused(prev);
  1492. // NOTE(bill): Don't err here
  1493. }
  1494. GB_ASSERT(decl->proc_checked_state != ProcCheckedState_Checked);
  1495. if (decl->defer_use_checked) {
  1496. GB_ASSERT(is_type_polymorphic(type, true));
  1497. error(token, "Defer Use Checked: %.*s", LIT(decl->entity->token.string));
  1498. GB_ASSERT(decl->defer_use_checked == false);
  1499. }
  1500. check_stmt_list(ctx, bs->stmts, Stmt_CheckScopeDecls);
  1501. decl->defer_use_checked = true;
  1502. for (Ast *stmt : bs->stmts) {
  1503. if (stmt->kind == Ast_ValueDecl) {
  1504. ast_node(vd, ValueDecl, stmt);
  1505. for (Ast *name : vd->names) {
  1506. if (!is_blank_ident(name)) {
  1507. if (name->kind == Ast_Ident) {
  1508. GB_ASSERT(name->Ident.entity != nullptr);
  1509. }
  1510. }
  1511. }
  1512. }
  1513. }
  1514. if (type->Proc.result_count > 0) {
  1515. if (!check_is_terminating(body, str_lit(""))) {
  1516. if (token.kind == Token_Ident) {
  1517. error(bs->close, "Missing return statement at the end of the procedure '%.*s'", LIT(token.string));
  1518. } else {
  1519. // NOTE(bill): Anonymous procedure (lambda)
  1520. error(bs->close, "Missing return statement at the end of the procedure");
  1521. }
  1522. }
  1523. } else if (type->Proc.diverging) {
  1524. if (!check_is_terminating(body, str_lit(""))) {
  1525. if (token.kind == Token_Ident) {
  1526. error(bs->close, "Missing diverging call at the end of the procedure '%.*s'", LIT(token.string));
  1527. } else {
  1528. // NOTE(bill): Anonymous procedure (lambda)
  1529. error(bs->close, "Missing diverging call at the end of the procedure");
  1530. }
  1531. }
  1532. }
  1533. }
  1534. check_close_scope(ctx);
  1535. check_scope_usage(ctx->checker, ctx->scope, check_vet_flags(body));
  1536. add_deps_from_child_to_parent(decl);
  1537. return true;
  1538. }