check_decl.cpp 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338
  1. void check_stmt (CheckerContext *ctx, Ast *node, u32 flags);
  2. // NOTE(bill): 'content_name' is for debugging and error messages
  3. 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. gbString expr_str = expr_to_string(operand->expr);
  9. // TODO(bill): is this a good enough error message?
  10. // TODO(bill): Actually allow built in procedures to be passed around and thus be created on use
  11. error(operand->expr,
  12. "Cannot assign built-in procedure '%s' in %.*s",
  13. expr_str,
  14. LIT(context_name));
  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)) {
  38. add_type_info_type(ctx, operand->type);
  39. add_type_and_value(ctx->info, operand->expr, Addressing_Value, e->type, exact_value_typeid(operand->type));
  40. return e->type;
  41. } else {
  42. gbString t = type_to_string(operand->type);
  43. defer (gb_string_free(t));
  44. error(operand->expr, "Cannot assign a type '%s' to variable '%.*s'", t, LIT(e->token.string));
  45. if (e->type == nullptr) {
  46. 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));
  47. }
  48. e->type = operand->type;
  49. return nullptr;
  50. }
  51. }
  52. if (e->type == nullptr) {
  53. // NOTE(bill): Use the type of the operand
  54. Type *t = operand->type;
  55. if (is_type_untyped(t)) {
  56. if (t == t_invalid || is_type_untyped_nil(t)) {
  57. error(e->token, "Invalid use of untyped nil in %.*s", LIT(context_name));
  58. e->type = t_invalid;
  59. return nullptr;
  60. }
  61. if (t == t_invalid || is_type_untyped_undef(t)) {
  62. error(e->token, "Invalid use of --- in %.*s", LIT(context_name));
  63. e->type = t_invalid;
  64. return nullptr;
  65. }
  66. t = default_type(t);
  67. }
  68. if (is_type_asm_proc(t)) {
  69. error(e->token, "Invalid use of inline asm in %.*s", LIT(context_name));
  70. e->type = t_invalid;
  71. return nullptr;
  72. } else if (is_type_polymorphic(t)) {
  73. gbString str = type_to_string(t);
  74. defer (gb_string_free(str));
  75. error(e->token, "Invalid use of a polymorphic type '%s' in %.*s", str, LIT(context_name));
  76. e->type = t_invalid;
  77. return nullptr;
  78. } else if (is_type_empty_union(t)) {
  79. gbString str = type_to_string(t);
  80. defer (gb_string_free(str));
  81. error(e->token, "An empty union '%s' cannot be instantiated in %.*s", str, LIT(context_name));
  82. e->type = t_invalid;
  83. return nullptr;
  84. }
  85. GB_ASSERT(is_type_typed(t));
  86. e->type = t;
  87. }
  88. e->parent_proc_decl = ctx->curr_proc_decl;
  89. check_assignment(ctx, operand, e->type, context_name);
  90. if (operand->mode == Addressing_Invalid) {
  91. return nullptr;
  92. }
  93. return e->type;
  94. }
  95. void check_init_variables(CheckerContext *ctx, Entity **lhs, isize lhs_count, Slice<Ast *> const &inits, String context_name) {
  96. if ((lhs == nullptr || lhs_count == 0) && inits.count == 0) {
  97. return;
  98. }
  99. // NOTE(bill): If there is a bad syntax error, rhs > lhs which would mean there would need to be
  100. // an extra allocation
  101. auto operands = array_make<Operand>(temporary_allocator(), 0, 2*lhs_count);
  102. check_unpack_arguments(ctx, lhs, lhs_count, &operands, inits, true, false);
  103. isize rhs_count = operands.count;
  104. for_array(i, operands) {
  105. if (operands[i].mode == Addressing_Invalid) {
  106. // TODO(bill): Should I ignore invalid parameters?
  107. // rhs_count--;
  108. }
  109. }
  110. isize max = gb_min(lhs_count, rhs_count);
  111. for (isize i = 0; i < max; i++) {
  112. Entity *e = lhs[i];
  113. DeclInfo *d = decl_info_of_entity(e);
  114. Operand *o = &operands[i];
  115. check_init_variable(ctx, e, o, context_name);
  116. if (d != nullptr) {
  117. d->init_expr = o->expr;
  118. }
  119. }
  120. if (rhs_count > 0 && lhs_count != rhs_count) {
  121. error(lhs[0]->token, "Assignment count mismatch '%td' = '%td'", lhs_count, rhs_count);
  122. }
  123. }
  124. void check_init_constant(CheckerContext *ctx, Entity *e, Operand *operand) {
  125. if (operand->mode == Addressing_Invalid ||
  126. operand->type == t_invalid ||
  127. e->type == t_invalid) {
  128. if (e->type == nullptr) {
  129. e->type = t_invalid;
  130. }
  131. return;
  132. }
  133. if (operand->mode != Addressing_Constant) {
  134. // TODO(bill): better error
  135. gbString str = expr_to_string(operand->expr);
  136. error(operand->expr, "'%s' is not a constant", str);
  137. gb_string_free(str);
  138. if (e->type == nullptr) {
  139. e->type = t_invalid;
  140. }
  141. return;
  142. }
  143. if (e->type == nullptr) { // NOTE(bill): type inference
  144. e->type = operand->type;
  145. }
  146. check_assignment(ctx, operand, e->type, str_lit("constant declaration"));
  147. if (operand->mode == Addressing_Invalid) {
  148. return;
  149. }
  150. e->parent_proc_decl = ctx->curr_proc_decl;
  151. e->Constant.value = operand->value;
  152. }
  153. bool is_type_distinct(Ast *node) {
  154. for (;;) {
  155. if (node == nullptr) {
  156. return false;
  157. }
  158. if (node->kind == Ast_ParenExpr) {
  159. node = node->ParenExpr.expr;
  160. } else if (node->kind == Ast_HelperType) {
  161. node = node->HelperType.type;
  162. } else {
  163. break;
  164. }
  165. }
  166. switch (node->kind) {
  167. case Ast_DistinctType:
  168. return true;
  169. case Ast_StructType:
  170. case Ast_UnionType:
  171. case Ast_EnumType:
  172. case Ast_ProcType:
  173. return true;
  174. case Ast_PointerType:
  175. case Ast_ArrayType:
  176. case Ast_DynamicArrayType:
  177. case Ast_MapType:
  178. return false;
  179. }
  180. return false;
  181. }
  182. Ast *remove_type_alias_clutter(Ast *node) {
  183. for (;;) {
  184. if (node == nullptr) {
  185. return nullptr;
  186. }
  187. if (node->kind == Ast_ParenExpr) {
  188. node = node->ParenExpr.expr;
  189. } else if (node->kind == Ast_DistinctType) {
  190. node = node->DistinctType.type;
  191. } else {
  192. return node;
  193. }
  194. }
  195. }
  196. isize total_attribute_count(DeclInfo *decl) {
  197. isize attribute_count = 0;
  198. for_array(i, decl->attributes) {
  199. Ast *attr = decl->attributes[i];
  200. if (attr->kind != Ast_Attribute) continue;
  201. attribute_count += attr->Attribute.elems.count;
  202. }
  203. return attribute_count;
  204. }
  205. void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *def) {
  206. GB_ASSERT(e->type == nullptr);
  207. DeclInfo *decl = decl_info_of_entity(e);
  208. bool is_distinct = is_type_distinct(init_expr);
  209. Ast *te = remove_type_alias_clutter(init_expr);
  210. e->type = t_invalid;
  211. String name = e->token.string;
  212. Type *named = alloc_type_named(name, nullptr, e);
  213. if (def != nullptr && def->kind == Type_Named) {
  214. def->Named.base = named;
  215. }
  216. e->type = named;
  217. check_type_path_push(ctx, e);
  218. Type *bt = check_type_expr(ctx, te, named);
  219. check_type_path_pop(ctx);
  220. named->Named.base = base_type(bt);
  221. if (is_distinct && is_type_typeid(e->type)) {
  222. error(init_expr, "'distinct' cannot be applied to 'typeid'");
  223. is_distinct = false;
  224. }
  225. if (is_distinct && is_type_any(e->type)) {
  226. error(init_expr, "'distinct' cannot be applied to 'any'");
  227. is_distinct = false;
  228. }
  229. if (!is_distinct) {
  230. e->type = bt;
  231. named->Named.base = bt;
  232. e->TypeName.is_type_alias = true;
  233. }
  234. if (decl->type_expr != nullptr) {
  235. Type *t = check_type(ctx, decl->type_expr);
  236. if (t != nullptr && !is_type_typeid(t)) {
  237. Operand operand = {};
  238. operand.mode = Addressing_Type;
  239. operand.type = e->type;
  240. operand.expr = init_expr;
  241. check_assignment(ctx, &operand, t, str_lit("constant declaration"));
  242. }
  243. }
  244. if (decl != nullptr) {
  245. AttributeContext ac = {};
  246. check_decl_attributes(ctx, decl->attributes, type_decl_attribute, &ac);
  247. if (ac.atom_op_table != nullptr) {
  248. Type *bt = base_type(e->type);
  249. switch (bt->kind) {
  250. case Type_Struct:
  251. bt->Struct.atom_op_table = ac.atom_op_table;
  252. break;
  253. default:
  254. error(e->token, "Only struct types can have custom atom operations");
  255. break;
  256. }
  257. }
  258. }
  259. // using decl
  260. if (decl->is_using) {
  261. // NOTE(bill): Must be an enum declaration
  262. if (te->kind == Ast_EnumType) {
  263. Scope *parent = e->scope;
  264. if (parent->flags&ScopeFlag_File) {
  265. // NOTE(bill): Use package scope
  266. parent = parent->parent;
  267. }
  268. Type *t = base_type(e->type);
  269. if (t->kind == Type_Enum) {
  270. for_array(i, t->Enum.fields) {
  271. Entity *f = t->Enum.fields[i];
  272. if (f->kind != Entity_Constant) {
  273. continue;
  274. }
  275. String name = f->token.string;
  276. if (is_blank_ident(name)) {
  277. continue;
  278. }
  279. add_entity(ctx->checker, parent, nullptr, f);
  280. }
  281. }
  282. }
  283. }
  284. }
  285. void override_entity_in_scope(Entity *original_entity, Entity *new_entity) {
  286. // NOTE(bill): The original_entity's scope may not be same scope that it was inserted into
  287. // e.g. file entity inserted into its package scope
  288. String original_name = original_entity->token.string;
  289. Scope *found_scope = nullptr;
  290. Entity *found_entity = nullptr;
  291. scope_lookup_parent(original_entity->scope, original_name, &found_scope, &found_entity);
  292. if (found_scope == nullptr) {
  293. return;
  294. }
  295. // IMPORTANT NOTE(bill, 2021-04-10): Overriding behaviour was flawed in that the
  296. // original entity was still used check checked, but the checking was only
  297. // relying on "constant" data such as the Entity.type and Entity.Constant.value
  298. //
  299. // Therefore two things can be done: the type can be assigned to state that it
  300. // has been "evaluated" and the variant data can be copied across
  301. string_map_set(&found_scope->elements, original_name, new_entity);
  302. original_entity->flags |= EntityFlag_Overridden;
  303. original_entity->type = new_entity->type;
  304. original_entity->aliased_of = new_entity;
  305. if (original_entity->identifier == nullptr) {
  306. original_entity->identifier = new_entity->identifier;
  307. }
  308. if (original_entity->identifier != nullptr &&
  309. original_entity->identifier->kind == Ast_Ident) {
  310. original_entity->identifier->Ident.entity = new_entity;
  311. }
  312. // IMPORTANT NOTE(bill, 2021-04-10): copy only the variants
  313. // This is most likely NEVER required, but it does not at all hurt to keep
  314. isize offset = cast(u8 *)&original_entity->Dummy.start - cast(u8 *)original_entity;
  315. isize size = gb_size_of(*original_entity) - offset;
  316. gb_memmove(cast(u8 *)original_entity, cast(u8 *)new_entity, size);
  317. }
  318. void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init, Type *named_type) {
  319. GB_ASSERT(e->type == nullptr);
  320. GB_ASSERT(e->kind == Entity_Constant);
  321. init = unparen_expr(init);
  322. if (e->flags & EntityFlag_Visited) {
  323. e->type = t_invalid;
  324. return;
  325. }
  326. e->flags |= EntityFlag_Visited;
  327. if (type_expr) {
  328. e->type = check_type(ctx, type_expr);
  329. }
  330. Operand operand = {};
  331. Entity *other_entity = nullptr;
  332. if (init != nullptr) {
  333. Entity *entity = nullptr;
  334. if (init->kind == Ast_Ident) {
  335. entity = check_ident(ctx, &operand, init, nullptr, e->type, true);
  336. } else if (init->kind == Ast_SelectorExpr) {
  337. entity = check_selector(ctx, &operand, init, e->type);
  338. } else {
  339. check_expr_or_type(ctx, &operand, init, e->type);
  340. }
  341. switch (operand.mode) {
  342. case Addressing_Type: {
  343. if (e->type != nullptr && !is_type_typeid(e->type)) {
  344. check_assignment(ctx, &operand, e->type, str_lit("constant declaration"));
  345. }
  346. e->kind = Entity_TypeName;
  347. e->type = nullptr;
  348. if (entity != nullptr && entity->type != nullptr &&
  349. is_type_polymorphic_record_unspecialized(entity->type)) {
  350. DeclInfo *decl = decl_info_of_entity(e);
  351. if (decl != nullptr) {
  352. if (decl->attributes.count > 0) {
  353. error(decl->attributes[0], "Constant alias declarations cannot have attributes");
  354. }
  355. }
  356. override_entity_in_scope(e, entity);
  357. return;
  358. }
  359. check_type_decl(ctx, e, ctx->decl->init_expr, named_type);
  360. return;
  361. }
  362. // NOTE(bill): Check to see if the expression it to be aliases
  363. case Addressing_Builtin:
  364. if (e->type != nullptr) {
  365. error(type_expr, "A constant alias of a built-in procedure may not have a type initializer");
  366. }
  367. e->kind = Entity_Builtin;
  368. e->Builtin.id = operand.builtin_id;
  369. e->type = t_invalid;
  370. return;
  371. case Addressing_ProcGroup:
  372. GB_ASSERT(operand.proc_group != nullptr);
  373. GB_ASSERT(operand.proc_group->kind == Entity_ProcGroup);
  374. // NOTE(bill, 2020-06-10): It is better to just clone the contents than overriding the entity in the scope
  375. // Thank goodness I made entities a tagged union to allow for this implace patching
  376. e->kind = Entity_ProcGroup;
  377. e->ProcGroup.entities = array_clone(heap_allocator(), operand.proc_group->ProcGroup.entities);
  378. return;
  379. }
  380. if (entity != nullptr) {
  381. if (e->type != nullptr) {
  382. Operand x = {};
  383. x.type = entity->type;
  384. x.mode = Addressing_Variable;
  385. if (!check_is_assignable_to(ctx, &x, e->type)) {
  386. gbString expr_str = expr_to_string(init);
  387. gbString op_type_str = type_to_string(entity->type);
  388. gbString type_str = type_to_string(e->type);
  389. error(e->token,
  390. "Cannot assign '%s' of type '%s' to '%s'",
  391. expr_str,
  392. op_type_str,
  393. type_str);
  394. gb_string_free(type_str);
  395. gb_string_free(op_type_str);
  396. gb_string_free(expr_str);
  397. }
  398. }
  399. // NOTE(bill): Override aliased entity
  400. switch (entity->kind) {
  401. case Entity_ProcGroup:
  402. case Entity_Procedure:
  403. case Entity_LibraryName:
  404. case Entity_ImportName:
  405. {
  406. DeclInfo *decl = decl_info_of_entity(e);
  407. if (decl != nullptr) {
  408. if (decl->attributes.count > 0) {
  409. error(decl->attributes[0], "Constant alias declarations cannot have attributes");
  410. }
  411. }
  412. override_entity_in_scope(e, entity);
  413. return;
  414. }
  415. }
  416. }
  417. }
  418. check_init_constant(ctx, e, &operand);
  419. if (operand.mode == Addressing_Invalid ||
  420. base_type(operand.type) == t_invalid) {
  421. gbString str = expr_to_string(init);
  422. error(e->token, "Invalid declaration type '%s'", str);
  423. gb_string_free(str);
  424. }
  425. DeclInfo *decl = decl_info_of_entity(e);
  426. if (decl != nullptr) {
  427. check_decl_attributes(ctx, decl->attributes, const_decl_attribute, nullptr);
  428. }
  429. }
  430. typedef bool TypeCheckSig(Type *t);
  431. bool sig_compare(TypeCheckSig *a, Type *x, Type *y) {
  432. x = core_type(x);
  433. y = core_type(y);
  434. return (a(x) && a(y));
  435. }
  436. bool sig_compare(TypeCheckSig *a, TypeCheckSig *b, Type *x, Type *y) {
  437. x = core_type(x);
  438. y = core_type(y);
  439. if (a == b) {
  440. return sig_compare(a, x, y);
  441. }
  442. return ((a(x) && b(y)) || (b(x) && a(y)));
  443. }
  444. bool signature_parameter_similar_enough(Type *x, Type *y) {
  445. if (sig_compare(is_type_pointer, x, y)) {
  446. return true;
  447. }
  448. if (sig_compare(is_type_integer, x, y)) {
  449. GB_ASSERT(core_type(x)->kind == Type_Basic);
  450. GB_ASSERT(core_type(y)->kind == Type_Basic);
  451. i64 sx = type_size_of(x);
  452. i64 sy = type_size_of(y);
  453. if (sx == sy) return true;
  454. }
  455. if (sig_compare(is_type_integer, is_type_boolean, x, y)) {
  456. GB_ASSERT(core_type(x)->kind == Type_Basic);
  457. GB_ASSERT(core_type(y)->kind == Type_Basic);
  458. i64 sx = type_size_of(x);
  459. i64 sy = type_size_of(y);
  460. if (sx == sy) return true;
  461. }
  462. if (sig_compare(is_type_cstring, is_type_u8_ptr, x, y)) {
  463. return true;
  464. }
  465. if (sig_compare(is_type_uintptr, is_type_rawptr, x, y)) {
  466. return true;
  467. }
  468. if (sig_compare(is_type_proc, is_type_proc, x, y)) {
  469. return true;
  470. }
  471. if (sig_compare(is_type_proc, is_type_pointer, x, y)) {
  472. return true;
  473. }
  474. return are_types_identical(x, y);
  475. }
  476. bool are_signatures_similar_enough(Type *a_, Type *b_) {
  477. GB_ASSERT(a_->kind == Type_Proc);
  478. GB_ASSERT(b_->kind == Type_Proc);
  479. TypeProc *a = &a_->Proc;
  480. TypeProc *b = &b_->Proc;
  481. if (a->param_count != b->param_count) {
  482. return false;
  483. }
  484. if (a->result_count != b->result_count) {
  485. return false;
  486. }
  487. for (isize i = 0; i < a->param_count; i++) {
  488. Type *x = core_type(a->params->Tuple.variables[i]->type);
  489. Type *y = core_type(b->params->Tuple.variables[i]->type);
  490. if (!signature_parameter_similar_enough(x, y)) {
  491. return false;
  492. }
  493. }
  494. for (isize i = 0; i < a->result_count; i++) {
  495. Type *x = base_type(a->results->Tuple.variables[i]->type);
  496. Type *y = base_type(b->results->Tuple.variables[i]->type);
  497. if (!signature_parameter_similar_enough(x, y)) {
  498. return false;
  499. }
  500. }
  501. return true;
  502. }
  503. void init_entity_foreign_library(CheckerContext *ctx, Entity *e) {
  504. Ast *ident = nullptr;
  505. Entity **foreign_library = nullptr;
  506. switch (e->kind) {
  507. case Entity_Procedure:
  508. ident = e->Procedure.foreign_library_ident;
  509. foreign_library = &e->Procedure.foreign_library;
  510. break;
  511. case Entity_Variable:
  512. ident = e->Variable.foreign_library_ident;
  513. foreign_library = &e->Variable.foreign_library;
  514. break;
  515. default:
  516. return;
  517. }
  518. if (ident == nullptr) {
  519. error(e->token, "foreign entiies must declare which library they are from");
  520. } else if (ident->kind != Ast_Ident) {
  521. error(ident, "foreign library names must be an identifier");
  522. } else {
  523. String name = ident->Ident.token.string;
  524. Entity *found = scope_lookup(ctx->scope, name);
  525. if (found == nullptr) {
  526. if (is_blank_ident(name)) {
  527. // NOTE(bill): link against nothing
  528. } else {
  529. error(ident, "Undeclared name: %.*s", LIT(name));
  530. }
  531. } else if (found->kind != Entity_LibraryName) {
  532. error(ident, "'%.*s' cannot be used as a library name", LIT(name));
  533. } else {
  534. // TODO(bill): Extra stuff to do with library names?
  535. *foreign_library = found;
  536. found->flags |= EntityFlag_Used;
  537. add_entity_use(ctx, ident, found);
  538. }
  539. }
  540. }
  541. String handle_link_name(CheckerContext *ctx, Token token, String link_name, String link_prefix) {
  542. if (link_prefix.len > 0) {
  543. if (link_name.len > 0) {
  544. error(token, "'link_name' and 'link_prefix' cannot be used together");
  545. } else {
  546. isize len = link_prefix.len + token.string.len;
  547. u8 *name = gb_alloc_array(permanent_allocator(), u8, len+1);
  548. gb_memmove(name, &link_prefix[0], link_prefix.len);
  549. gb_memmove(name+link_prefix.len, &token.string[0], token.string.len);
  550. name[len] = 0;
  551. link_name = make_string(name, len);
  552. }
  553. }
  554. return link_name;
  555. }
  556. void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
  557. GB_ASSERT(e->type == nullptr);
  558. if (d->proc_lit->kind != Ast_ProcLit) {
  559. // TOOD(bill): Better error message
  560. error(d->proc_lit, "Expected a procedure to check");
  561. return;
  562. }
  563. Type *proc_type = e->type;
  564. if (d->gen_proc_type != nullptr) {
  565. proc_type = d->gen_proc_type;
  566. } else {
  567. proc_type = alloc_type_proc(e->scope, nullptr, 0, nullptr, 0, false, ProcCC_Odin);
  568. }
  569. e->type = proc_type;
  570. ast_node(pl, ProcLit, d->proc_lit);
  571. check_open_scope(ctx, pl->type);
  572. defer (check_close_scope(ctx));
  573. ctx->scope->procedure_entity = e;
  574. Type *decl_type = nullptr;
  575. if (d->type_expr != nullptr) {
  576. decl_type = check_type(ctx, d->type_expr);
  577. if (!is_type_proc(decl_type)) {
  578. gbString str = type_to_string(decl_type);
  579. error(d->type_expr, "Expected a procedure type, got '%s'", str);
  580. gb_string_free(str);
  581. }
  582. }
  583. auto tmp_ctx = *ctx;
  584. tmp_ctx.allow_polymorphic_types = true;
  585. if (decl_type != nullptr) {
  586. tmp_ctx.type_hint = decl_type;
  587. }
  588. check_procedure_type(&tmp_ctx, proc_type, pl->type);
  589. if (decl_type != nullptr) {
  590. Operand x = {};
  591. x.type = e->type;
  592. x.mode = Addressing_Variable;
  593. if (!check_is_assignable_to(ctx, &x, decl_type)) {
  594. gbString expr_str = expr_to_string(d->proc_lit);
  595. gbString op_type_str = type_to_string(e->type);
  596. gbString type_str = type_to_string(decl_type);
  597. error(e->token,
  598. "Cannot assign '%s' of type '%s' to '%s'",
  599. expr_str,
  600. op_type_str,
  601. type_str);
  602. gb_string_free(type_str);
  603. gb_string_free(op_type_str);
  604. gb_string_free(expr_str);
  605. }
  606. }
  607. TypeProc *pt = &proc_type->Proc;
  608. AttributeContext ac = make_attribute_context(e->Procedure.link_prefix);
  609. if (d != nullptr) {
  610. check_decl_attributes(ctx, d->attributes, proc_decl_attribute, &ac);
  611. }
  612. if (ac.test) {
  613. e->flags |= EntityFlag_Test;
  614. }
  615. if (ac.set_cold) {
  616. e->flags |= EntityFlag_Cold;
  617. }
  618. e->Procedure.optimization_mode = cast(ProcedureOptimizationMode)ac.optimization_mode;
  619. switch (e->Procedure.optimization_mode) {
  620. case ProcedureOptimizationMode_None:
  621. case ProcedureOptimizationMode_Minimal:
  622. if (pl->inlining == ProcInlining_inline) {
  623. error(e->token, "#force_inline cannot be used in conjunction with the attribute 'optimization_mode' with neither \"none\" nor \"minimal\"");
  624. }
  625. break;
  626. }
  627. e->Procedure.is_export = ac.is_export;
  628. e->deprecated_message = ac.deprecated_message;
  629. ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix);
  630. if (ac.has_disabled_proc) {
  631. if (ac.disabled_proc) {
  632. e->flags |= EntityFlag_Disabled;
  633. }
  634. Type *t = base_type(e->type);
  635. GB_ASSERT(t->kind == Type_Proc);
  636. if (t->Proc.result_count != 0) {
  637. error(e->token, "Procedure with the 'disabled' attribute may not have any return values");
  638. }
  639. }
  640. bool is_foreign = e->Procedure.is_foreign;
  641. bool is_export = e->Procedure.is_export;
  642. if (e->pkg != nullptr && e->token.string == "main") {
  643. if (pt->param_count != 0 ||
  644. pt->result_count != 0) {
  645. gbString str = type_to_string(proc_type);
  646. error(e->token, "Procedure type of 'main' was expected to be 'proc()', got %s", str);
  647. gb_string_free(str);
  648. }
  649. if (pt->calling_convention != ProcCC_Odin) {
  650. error(e->token, "Procedure 'main' cannot have a custom calling convention");
  651. }
  652. pt->calling_convention = ProcCC_Odin;
  653. if (e->pkg->kind == Package_Init) {
  654. if (ctx->info->entry_point != nullptr) {
  655. error(e->token, "Redeclaration of the entry pointer procedure 'main'");
  656. } else {
  657. ctx->info->entry_point = e;
  658. }
  659. }
  660. }
  661. if (is_foreign && is_export) {
  662. error(pl->type, "A foreign procedure cannot have an 'export' tag");
  663. }
  664. if (pt->is_polymorphic) {
  665. if (pl->body == nullptr) {
  666. error(e->token, "Polymorphic procedures must have a body");
  667. }
  668. if (is_foreign) {
  669. error(e->token, "A foreign procedure cannot be a polymorphic");
  670. return;
  671. }
  672. }
  673. if (pl->body != nullptr) {
  674. if (is_foreign) {
  675. error(pl->body, "A foreign procedure cannot have a body");
  676. }
  677. if (proc_type->Proc.c_vararg) {
  678. error(pl->body, "A procedure with a '#c_vararg' field cannot have a body and must be foreign");
  679. }
  680. d->scope = ctx->scope;
  681. GB_ASSERT(pl->body->kind == Ast_BlockStmt);
  682. if (!pt->is_polymorphic) {
  683. check_procedure_later(ctx->checker, ctx->file, e->token, d, proc_type, pl->body, pl->tags);
  684. }
  685. } else if (!is_foreign) {
  686. if (e->Procedure.is_export) {
  687. error(e->token, "Foreign export procedures must have a body");
  688. } else {
  689. error(e->token, "Only a foreign procedure cannot have a body");
  690. }
  691. }
  692. if (pt->result_count == 0 && ac.require_results) {
  693. error(pl->type, "'require_results' is not needed on a procedure with no results");
  694. } else {
  695. pt->require_results = ac.require_results;
  696. }
  697. if (ac.link_name.len > 0) {
  698. e->Procedure.link_name = ac.link_name;
  699. }
  700. if (ac.deferred_procedure.entity != nullptr) {
  701. e->Procedure.deferred_procedure = ac.deferred_procedure;
  702. array_add(&ctx->checker->procs_with_deferred_to_check, e);
  703. }
  704. if (is_foreign) {
  705. String name = e->token.string;
  706. if (e->Procedure.link_name.len > 0) {
  707. name = e->Procedure.link_name;
  708. }
  709. e->Procedure.is_foreign = true;
  710. e->Procedure.link_name = name;
  711. init_entity_foreign_library(ctx, e);
  712. auto *fp = &ctx->info->foreigns;
  713. StringHashKey key = string_hash_string(name);
  714. Entity **found = string_map_get(fp, key);
  715. if (found) {
  716. Entity *f = *found;
  717. TokenPos pos = f->token.pos;
  718. Type *this_type = base_type(e->type);
  719. Type *other_type = base_type(f->type);
  720. if (is_type_proc(this_type) && is_type_proc(other_type)) {
  721. if (!are_signatures_similar_enough(this_type, other_type)) {
  722. error(d->proc_lit,
  723. "Redeclaration of foreign procedure '%.*s' with different type signatures\n"
  724. "\tat %s",
  725. LIT(name), token_pos_to_string(pos));
  726. }
  727. } else if (!are_types_identical(this_type, other_type)) {
  728. error(d->proc_lit,
  729. "Foreign entity '%.*s' previously declared elsewhere with a different type\n"
  730. "\tat %s",
  731. LIT(name), token_pos_to_string(pos));
  732. }
  733. } else if (name == "main") {
  734. error(d->proc_lit, "The link name 'main' is reserved for internal use");
  735. } else {
  736. string_map_set(fp, key, e);
  737. }
  738. } else {
  739. String name = e->token.string;
  740. if (e->Procedure.link_name.len > 0) {
  741. name = e->Procedure.link_name;
  742. }
  743. if (e->Procedure.link_name.len > 0 || is_export) {
  744. auto *fp = &ctx->info->foreigns;
  745. StringHashKey key = string_hash_string(name);
  746. Entity **found = string_map_get(fp, key);
  747. if (found) {
  748. Entity *f = *found;
  749. TokenPos pos = f->token.pos;
  750. // TODO(bill): Better error message?
  751. error(d->proc_lit,
  752. "Non unique linking name for procedure '%.*s'\n"
  753. "\tother at %s",
  754. LIT(name), token_pos_to_string(pos));
  755. } else if (name == "main") {
  756. error(d->proc_lit, "The link name 'main' is reserved for internal use");
  757. } else {
  758. string_map_set(fp, key, e);
  759. }
  760. }
  761. }
  762. }
  763. void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast *type_expr, Ast *init_expr) {
  764. GB_ASSERT(e->type == nullptr);
  765. GB_ASSERT(e->kind == Entity_Variable);
  766. if (e->flags & EntityFlag_Visited) {
  767. e->type = t_invalid;
  768. return;
  769. }
  770. e->flags |= EntityFlag_Visited;
  771. AttributeContext ac = make_attribute_context(e->Variable.link_prefix);
  772. ac.init_expr_list_count = init_expr != nullptr ? 1 : 0;
  773. DeclInfo *decl = decl_info_of_entity(e);
  774. GB_ASSERT(decl == ctx->decl);
  775. if (decl != nullptr) {
  776. check_decl_attributes(ctx, decl->attributes, var_decl_attribute, &ac);
  777. }
  778. if (ac.require_declaration) {
  779. array_add(&ctx->info->required_global_variables, e);
  780. }
  781. e->Variable.thread_local_model = ac.thread_local_model;
  782. e->Variable.is_export = ac.is_export;
  783. if (ac.is_static) {
  784. e->flags |= EntityFlag_Static;
  785. } else {
  786. e->flags &= ~EntityFlag_Static;
  787. }
  788. ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix);
  789. String context_name = str_lit("variable declaration");
  790. if (type_expr != nullptr) {
  791. e->type = check_type(ctx, type_expr);
  792. }
  793. if (e->type != nullptr) {
  794. if (is_type_polymorphic(base_type(e->type))) {
  795. gbString str = type_to_string(e->type);
  796. defer (gb_string_free(str));
  797. error(e->token, "Invalid use of a polymorphic type '%s' in %.*s", str, LIT(context_name));
  798. e->type = t_invalid;
  799. } else if (is_type_empty_union(e->type)) {
  800. gbString str = type_to_string(e->type);
  801. defer (gb_string_free(str));
  802. error(e->token, "An empty union '%s' cannot be instantiated in %.*s", str, LIT(context_name));
  803. e->type = t_invalid;
  804. }
  805. }
  806. if (e->Variable.is_foreign) {
  807. if (init_expr != nullptr) {
  808. error(e->token, "A foreign variable declaration cannot have a default value");
  809. }
  810. init_entity_foreign_library(ctx, e);
  811. }
  812. if (ac.link_name.len > 0) {
  813. e->Variable.link_name = ac.link_name;
  814. }
  815. if (e->Variable.is_foreign || e->Variable.is_export) {
  816. String name = e->token.string;
  817. if (e->Variable.link_name.len > 0) {
  818. name = e->Variable.link_name;
  819. }
  820. auto *fp = &ctx->info->foreigns;
  821. StringHashKey key = string_hash_string(name);
  822. Entity **found = string_map_get(fp, key);
  823. if (found) {
  824. Entity *f = *found;
  825. TokenPos pos = f->token.pos;
  826. Type *this_type = base_type(e->type);
  827. Type *other_type = base_type(f->type);
  828. if (!are_types_identical(this_type, other_type)) {
  829. error(e->token,
  830. "Foreign entity '%.*s' previously declared elsewhere with a different type\n"
  831. "\tat %s",
  832. LIT(name), token_pos_to_string(pos));
  833. }
  834. } else {
  835. string_map_set(fp, key, e);
  836. }
  837. }
  838. if (init_expr == nullptr) {
  839. if (type_expr == nullptr) {
  840. e->type = t_invalid;
  841. }
  842. return;
  843. }
  844. Operand o = {};
  845. check_expr_with_type_hint(ctx, &o, init_expr, e->type);
  846. check_init_variable(ctx, e, &o, str_lit("variable declaration"));
  847. }
  848. void check_proc_group_decl(CheckerContext *ctx, Entity *&pg_entity, DeclInfo *d) {
  849. GB_ASSERT(pg_entity->kind == Entity_ProcGroup);
  850. auto *pge = &pg_entity->ProcGroup;
  851. String proc_group_name = pg_entity->token.string;
  852. ast_node(pg, ProcGroup, d->init_expr);
  853. pge->entities = array_make<Entity*>(permanent_allocator(), 0, pg->args.count);
  854. // NOTE(bill): This must be set here to prevent cycles in checking if someone
  855. // places the entity within itself
  856. pg_entity->type = t_invalid;
  857. PtrSet<Entity *> entity_set = {};
  858. ptr_set_init(&entity_set, heap_allocator(), 2*pg->args.count);
  859. for_array(i, pg->args) {
  860. Ast *arg = pg->args[i];
  861. Entity *e = nullptr;
  862. Operand o = {};
  863. if (arg->kind == Ast_Ident) {
  864. e = check_ident(ctx, &o, arg, nullptr, nullptr, true);
  865. } else if (arg->kind == Ast_SelectorExpr) {
  866. e = check_selector(ctx, &o, arg, nullptr);
  867. }
  868. if (e == nullptr) {
  869. error(arg, "Expected a valid entity name in procedure group, got %.*s", LIT(ast_strings[arg->kind]));
  870. continue;
  871. }
  872. if (e->kind == Entity_Variable) {
  873. if (!is_type_proc(e->type)) {
  874. gbString s = type_to_string(e->type);
  875. defer (gb_string_free(s));
  876. error(arg, "Expected a procedure, got %s", s);
  877. continue;
  878. }
  879. } else if (e->kind != Entity_Procedure) {
  880. error(arg, "Expected a procedure entity");
  881. continue;
  882. }
  883. if (ptr_set_update(&entity_set, e)) {
  884. error(arg, "Previous use of `%.*s` in procedure group", LIT(e->token.string));
  885. continue;
  886. }
  887. array_add(&pge->entities, e);
  888. }
  889. ptr_set_destroy(&entity_set);
  890. for_array(j, pge->entities) {
  891. Entity *p = pge->entities[j];
  892. if (p->type == t_invalid) {
  893. // NOTE(bill): This invalid overload has already been handled
  894. continue;
  895. }
  896. String name = p->token.string;
  897. for (isize k = j+1; k < pge->entities.count; k++) {
  898. Entity *q = pge->entities[k];
  899. GB_ASSERT(p != q);
  900. bool is_invalid = false;
  901. TokenPos pos = q->token.pos;
  902. if (q->type == nullptr || q->type == t_invalid) {
  903. continue;
  904. }
  905. begin_error_block();
  906. defer (end_error_block());
  907. ProcTypeOverloadKind kind = are_proc_types_overload_safe(p->type, q->type);
  908. bool both_have_where_clauses = false;
  909. if (p->decl_info->proc_lit != nullptr && q->decl_info->proc_lit != nullptr) {
  910. GB_ASSERT(p->decl_info->proc_lit->kind == Ast_ProcLit);
  911. GB_ASSERT(q->decl_info->proc_lit->kind == Ast_ProcLit);
  912. auto pl = &p->decl_info->proc_lit->ProcLit;
  913. auto ql = &q->decl_info->proc_lit->ProcLit;
  914. // Allow collisions if the procedures both have 'where' clauses and are both polymorphic
  915. bool pw = pl->where_token.kind != Token_Invalid && is_type_polymorphic(p->type, true);
  916. bool qw = ql->where_token.kind != Token_Invalid && is_type_polymorphic(q->type, true);
  917. both_have_where_clauses = pw && qw;
  918. }
  919. if (!both_have_where_clauses) switch (kind) {
  920. case ProcOverload_Identical:
  921. error(p->token, "Overloaded procedure '%.*s' as the same type as another procedure in the procedure group '%.*s'", LIT(name), LIT(proc_group_name));
  922. is_invalid = true;
  923. break;
  924. // case ProcOverload_CallingConvention:
  925. // error(p->token, "Overloaded procedure '%.*s' as the same type as another procedure in the procedure group '%.*s'", LIT(name), LIT(proc_group_name));
  926. // is_invalid = true;
  927. // break;
  928. case ProcOverload_ParamVariadic:
  929. error(p->token, "Overloaded procedure '%.*s' as the same type as another procedure in the procedure group '%.*s'", LIT(name), LIT(proc_group_name));
  930. is_invalid = true;
  931. break;
  932. case ProcOverload_ResultCount:
  933. case ProcOverload_ResultTypes:
  934. error(p->token, "Overloaded procedure '%.*s' as the same parameters but different results in the procedure group '%.*s'", LIT(name), LIT(proc_group_name));
  935. is_invalid = true;
  936. break;
  937. case ProcOverload_Polymorphic:
  938. #if 0
  939. error(p->token, "Overloaded procedure '%.*s' has a polymorphic counterpart in the procedure group '%.*s' which is not allowed", LIT(name), LIT(proc_group_name));
  940. is_invalid = true;
  941. #endif
  942. break;
  943. case ProcOverload_ParamCount:
  944. case ProcOverload_ParamTypes:
  945. // This is okay :)
  946. break;
  947. }
  948. if (is_invalid) {
  949. error_line("\tprevious procedure at %s\n", token_pos_to_string(pos));
  950. q->type = t_invalid;
  951. }
  952. }
  953. }
  954. }
  955. void check_entity_decl(CheckerContext *ctx, Entity *e, DeclInfo *d, Type *named_type) {
  956. if (e->state == EntityState_Resolved) {
  957. return;
  958. }
  959. String name = e->token.string;
  960. if (e->type != nullptr || e->state != EntityState_Unresolved) {
  961. error(e->token, "Illegal declaration cycle of `%.*s`", LIT(name));
  962. return;
  963. }
  964. GB_ASSERT(e->state == EntityState_Unresolved);
  965. #if 0
  966. char buf[256] = {};
  967. isize n = gb_snprintf(buf, 256, "%.*s %d", LIT(name), e->kind);
  968. Timings timings = {};
  969. timings_init(&timings, make_string(cast(u8 *)buf, n-1), 16);
  970. defer ({
  971. timings_print_all(&timings);
  972. timings_destroy(&timings);
  973. });
  974. #define TIME_SECTION(str) timings_start_section(&timings, str_lit(str))
  975. #else
  976. #define TIME_SECTION(str)
  977. #endif
  978. if (d == nullptr) {
  979. d = decl_info_of_entity(e);
  980. if (d == nullptr) {
  981. // TODO(bill): Err here?
  982. e->type = t_invalid;
  983. e->state = EntityState_Resolved;
  984. set_base_type(named_type, t_invalid);
  985. return;
  986. // GB_PANIC("'%.*s' should been declared!", LIT(name));
  987. }
  988. }
  989. CheckerContext c = *ctx;
  990. c.scope = d->scope;
  991. c.decl = d;
  992. c.type_level = 0;
  993. e->parent_proc_decl = c.curr_proc_decl;
  994. e->state = EntityState_InProgress;
  995. switch (e->kind) {
  996. case Entity_Variable:
  997. check_global_variable_decl(&c, e, d->type_expr, d->init_expr);
  998. break;
  999. case Entity_Constant:
  1000. check_const_decl(&c, e, d->type_expr, d->init_expr, named_type);
  1001. break;
  1002. case Entity_TypeName: {
  1003. check_type_decl(&c, e, d->init_expr, named_type);
  1004. break;
  1005. }
  1006. case Entity_Procedure:
  1007. check_proc_decl(&c, e, d);
  1008. break;
  1009. case Entity_ProcGroup:
  1010. check_proc_group_decl(&c, e, d);
  1011. break;
  1012. }
  1013. e->state = EntityState_Resolved;
  1014. #undef TIME_SECTION
  1015. }
  1016. struct ProcUsingVar {
  1017. Entity *e;
  1018. Entity *uvar;
  1019. };
  1020. void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *type, Ast *body) {
  1021. if (body == nullptr) {
  1022. return;
  1023. }
  1024. GB_ASSERT(body->kind == Ast_BlockStmt);
  1025. String proc_name = {};
  1026. if (token.kind == Token_Ident) {
  1027. proc_name = token.string;
  1028. } else {
  1029. // TODO(bill): Better name
  1030. proc_name = str_lit("(anonymous-procedure)");
  1031. }
  1032. CheckerContext new_ctx = *ctx_;
  1033. CheckerContext *ctx = &new_ctx;
  1034. GB_ASSERT(type->kind == Type_Proc);
  1035. ctx->scope = decl->scope;
  1036. ctx->decl = decl;
  1037. ctx->proc_name = proc_name;
  1038. ctx->curr_proc_decl = decl;
  1039. ctx->curr_proc_sig = type;
  1040. ctx->curr_proc_calling_convention = type->Proc.calling_convention;
  1041. if (ctx->pkg->name != "runtime") {
  1042. switch (type->Proc.calling_convention) {
  1043. case ProcCC_None:
  1044. error(body, "Procedures with the calling convention \"none\" are not allowed a body");
  1045. break;
  1046. }
  1047. }
  1048. ast_node(bs, BlockStmt, body);
  1049. Array<ProcUsingVar> using_entities = {};
  1050. using_entities.allocator = heap_allocator();
  1051. defer (array_free(&using_entities));
  1052. {
  1053. if (type->Proc.param_count > 0) {
  1054. TypeTuple *params = &type->Proc.params->Tuple;
  1055. for_array(i, params->variables) {
  1056. Entity *e = params->variables[i];
  1057. if (e->kind != Entity_Variable) {
  1058. continue;
  1059. }
  1060. if (!(e->flags & EntityFlag_Using)) {
  1061. continue;
  1062. }
  1063. bool is_value = (e->flags & EntityFlag_Value) != 0 && !is_type_pointer(e->type);
  1064. String name = e->token.string;
  1065. Type *t = base_type(type_deref(e->type));
  1066. if (t->kind == Type_Struct) {
  1067. Scope *scope = t->Struct.scope;
  1068. if (scope == nullptr) {
  1069. scope = scope_of_node(t->Struct.node);
  1070. }
  1071. GB_ASSERT(scope != nullptr);
  1072. for_array(i, scope->elements.entries) {
  1073. Entity *f = scope->elements.entries[i].value;
  1074. if (f->kind == Entity_Variable) {
  1075. Entity *uvar = alloc_entity_using_variable(e, f->token, f->type, nullptr);
  1076. if (is_value) uvar->flags |= EntityFlag_Value;
  1077. ProcUsingVar puv = {e, uvar};
  1078. array_add(&using_entities, puv);
  1079. }
  1080. }
  1081. } else {
  1082. error(e->token, "'using' can only be applied to variables of type struct");
  1083. break;
  1084. }
  1085. }
  1086. }
  1087. }
  1088. for_array(i, using_entities) {
  1089. Entity *e = using_entities[i].e;
  1090. Entity *uvar = using_entities[i].uvar;
  1091. Entity *prev = scope_insert(ctx->scope, uvar);
  1092. if (prev != nullptr) {
  1093. error(e->token, "Namespace collision while 'using' '%.*s' of: %.*s", LIT(e->token.string), LIT(prev->token.string));
  1094. break;
  1095. }
  1096. }
  1097. bool where_clause_ok = evaluate_where_clauses(ctx, nullptr, decl->scope, &decl->proc_lit->ProcLit.where_clauses, !decl->where_clauses_evaluated);
  1098. if (!where_clause_ok) {
  1099. // NOTE(bill, 2019-08-31): Don't check the body as the where clauses failed
  1100. return;
  1101. }
  1102. check_open_scope(ctx, body);
  1103. {
  1104. for_array(i, using_entities) {
  1105. Entity *e = using_entities[i].e;
  1106. Entity *uvar = using_entities[i].uvar;
  1107. Entity *prev = scope_insert(ctx->scope, uvar);
  1108. // NOTE(bill): Don't err here
  1109. }
  1110. check_stmt_list(ctx, bs->stmts, Stmt_CheckScopeDecls);
  1111. if (type->Proc.result_count > 0) {
  1112. if (!check_is_terminating(body, str_lit(""))) {
  1113. if (token.kind == Token_Ident) {
  1114. error(bs->close, "Missing return statement at the end of the procedure '%.*s'", LIT(token.string));
  1115. } else {
  1116. // NOTE(bill): Anonymous procedure (lambda)
  1117. error(bs->close, "Missing return statement at the end of the procedure");
  1118. }
  1119. }
  1120. }
  1121. }
  1122. check_close_scope(ctx);
  1123. check_scope_usage(ctx->checker, ctx->scope);
  1124. #if 1
  1125. if (decl->parent != nullptr) {
  1126. Scope *ps = decl->parent->scope;
  1127. if (ps->flags & (ScopeFlag_File & ScopeFlag_Pkg & ScopeFlag_Global)) {
  1128. return;
  1129. } else {
  1130. // NOTE(bill): Add the dependencies from the procedure literal (lambda)
  1131. // But only at the procedure level
  1132. for_array(i, decl->deps.entries) {
  1133. Entity *e = decl->deps.entries[i].ptr;
  1134. ptr_set_add(&decl->parent->deps, e);
  1135. }
  1136. for_array(i, decl->type_info_deps.entries) {
  1137. Type *t = decl->type_info_deps.entries[i].ptr;
  1138. ptr_set_add(&decl->parent->type_info_deps, t);
  1139. }
  1140. }
  1141. }
  1142. #endif
  1143. }