check_decl.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
  1. bool check_is_terminating(AstNode *node);
  2. void check_stmt (Checker *c, AstNode *node, u32 flags);
  3. // NOTE(bill): 'content_name' is for debugging and error messages
  4. Type *check_init_variable(Checker *c, Entity *e, Operand *operand, String context_name) {
  5. if (operand->mode == Addressing_Invalid ||
  6. operand->type == t_invalid ||
  7. e->type == t_invalid) {
  8. if (operand->mode == Addressing_Builtin) {
  9. gbString expr_str = expr_to_string(operand->expr);
  10. // TODO(bill): is this a good enough error message?
  11. // TODO(bill): Actually allow built in procedures to be passed around and thus be created on use
  12. error(operand->expr,
  13. "Cannot assign built-in procedure '%s' in %.*s",
  14. expr_str,
  15. LIT(context_name));
  16. operand->mode = Addressing_Invalid;
  17. gb_string_free(expr_str);
  18. }
  19. if (operand->mode == Addressing_ProcGroup) {
  20. if (e->type == nullptr) {
  21. error(operand->expr, "Cannot determine type from overloaded procedure '%.*s'", LIT(operand->proc_group->token.string));
  22. } else {
  23. check_assignment(c, operand, e->type, str_lit("variable assignment"));
  24. if (operand->mode != Addressing_Type) {
  25. return operand->type;
  26. }
  27. }
  28. }
  29. if (e->type == nullptr) {
  30. e->type = t_invalid;
  31. }
  32. return nullptr;
  33. }
  34. if (e->type == nullptr) {
  35. // NOTE(bill): Use the type of the operand
  36. Type *t = operand->type;
  37. if (is_type_untyped(t)) {
  38. if (t == t_invalid || is_type_untyped_nil(t)) {
  39. error(e->token, "Invalid use of untyped nil in %.*s", LIT(context_name));
  40. e->type = t_invalid;
  41. return nullptr;
  42. }
  43. if (t == t_invalid || is_type_untyped_undef(t)) {
  44. error(e->token, "Invalid use of --- in %.*s", LIT(context_name));
  45. e->type = t_invalid;
  46. return nullptr;
  47. }
  48. t = default_type(t);
  49. }
  50. if (is_type_polymorphic(t)) {
  51. gbString str = type_to_string(t);
  52. defer (gb_string_free(str));
  53. error(e->token, "Invalid use of a polymorphic type '%s' in %.*s", str, LIT(context_name));
  54. e->type = t_invalid;
  55. return nullptr;
  56. } else if (is_type_empty_union(t)) {
  57. gbString str = type_to_string(t);
  58. defer (gb_string_free(str));
  59. error(e->token, "An empty union '%s' cannot be instantiated in %.*s", str, LIT(context_name));
  60. e->type = t_invalid;
  61. return nullptr;
  62. }
  63. if (is_type_bit_field_value(t)) {
  64. t = default_bit_field_value_type(t);
  65. }
  66. GB_ASSERT(is_type_typed(t));
  67. e->type = t;
  68. }
  69. e->parent_proc_decl = c->context.curr_proc_decl;
  70. check_assignment(c, operand, e->type, context_name);
  71. if (operand->mode == Addressing_Invalid) {
  72. return nullptr;
  73. }
  74. return e->type;
  75. }
  76. void check_init_variables(Checker *c, Entity **lhs, isize lhs_count, Array<AstNode *> inits, String context_name) {
  77. if ((lhs == nullptr || lhs_count == 0) && inits.count == 0) {
  78. return;
  79. }
  80. gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
  81. defer (gb_temp_arena_memory_end(tmp));
  82. // NOTE(bill): If there is a bad syntax error, rhs > lhs which would mean there would need to be
  83. // an extra allocation
  84. Array<Operand> operands = {};
  85. array_init(&operands, c->tmp_allocator, 2*lhs_count);
  86. check_unpack_arguments(c, lhs, lhs_count, &operands, inits, true);
  87. isize rhs_count = operands.count;
  88. for_array(i, operands) {
  89. if (operands[i].mode == Addressing_Invalid) {
  90. rhs_count--;
  91. }
  92. }
  93. isize max = gb_min(lhs_count, rhs_count);
  94. for (isize i = 0; i < max; i++) {
  95. Entity *e = lhs[i];
  96. DeclInfo *d = decl_info_of_entity(&c->info, e);
  97. Operand *o = &operands[i];
  98. check_init_variable(c, e, o, context_name);
  99. if (d != nullptr) {
  100. d->init_expr = o->expr;
  101. }
  102. }
  103. if (rhs_count > 0 && lhs_count != rhs_count) {
  104. error(lhs[0]->token, "Assignment count mismatch '%td' = '%td'", lhs_count, rhs_count);
  105. }
  106. }
  107. void check_init_constant(Checker *c, Entity *e, Operand *operand) {
  108. if (operand->mode == Addressing_Invalid ||
  109. operand->type == t_invalid ||
  110. e->type == t_invalid) {
  111. if (e->type == nullptr) {
  112. e->type = t_invalid;
  113. }
  114. return;
  115. }
  116. if (operand->mode != Addressing_Constant) {
  117. // TODO(bill): better error
  118. gbString str = expr_to_string(operand->expr);
  119. error(operand->expr, "'%s' is not a constant", str);
  120. gb_string_free(str);
  121. if (e->type == nullptr) {
  122. e->type = t_invalid;
  123. }
  124. return;
  125. }
  126. if (!is_type_constant_type(operand->type)) {
  127. gbString type_str = type_to_string(operand->type);
  128. error(operand->expr, "Invalid constant type: '%s'", type_str);
  129. gb_string_free(type_str);
  130. if (e->type == nullptr) {
  131. e->type = t_invalid;
  132. }
  133. return;
  134. }
  135. if (e->type == nullptr) { // NOTE(bill): type inference
  136. e->type = operand->type;
  137. }
  138. check_assignment(c, operand, e->type, str_lit("constant declaration"));
  139. if (operand->mode == Addressing_Invalid) {
  140. return;
  141. }
  142. e->parent_proc_decl = c->context.curr_proc_decl;
  143. e->Constant.value = operand->value;
  144. }
  145. AstNode *remove_type_alias(AstNode *node) {
  146. for (;;) {
  147. if (node == nullptr) {
  148. return nullptr;
  149. }
  150. if (node->kind == AstNode_ParenExpr) {
  151. node = node->ParenExpr.expr;
  152. } else if (node->kind == AstNode_AliasType) {
  153. node = node->AliasType.type;
  154. } else {
  155. return node;
  156. }
  157. }
  158. }
  159. void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def, bool is_alias) {
  160. GB_ASSERT(e->type == nullptr);
  161. DeclInfo *decl = decl_info_of_entity(&c->info, e);
  162. if (decl != nullptr && decl->attributes.count > 0) {
  163. error(decl->attributes[0], "Attributes are not allowed on type declarations");
  164. }
  165. AstNode *te = remove_type_alias(type_expr);
  166. e->type = t_invalid;
  167. String name = e->token.string;
  168. Type *named = make_type_named(c->allocator, name, nullptr, e);
  169. named->Named.type_name = e;
  170. if (def != nullptr && def->kind == Type_Named) {
  171. def->Named.base = named;
  172. }
  173. e->type = named;
  174. Type *bt = check_type(c, te, named);
  175. named->Named.base = base_type(bt);
  176. if (is_alias) {
  177. if (is_type_named(bt)) {
  178. e->type = bt;
  179. e->TypeName.is_type_alias = true;
  180. } else {
  181. gbString str = type_to_string(bt);
  182. error(type_expr, "Type alias declaration with a non-named type '%s'", str);
  183. gb_string_free(str);
  184. }
  185. }
  186. }
  187. void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init, Type *named_type) {
  188. GB_ASSERT(e->type == nullptr);
  189. GB_ASSERT(e->kind == Entity_Constant);
  190. if (e->flags & EntityFlag_Visited) {
  191. e->type = t_invalid;
  192. return;
  193. }
  194. e->flags |= EntityFlag_Visited;
  195. if (type_expr) {
  196. Type *t = check_type(c, type_expr);
  197. if (!is_type_constant_type(t)) {
  198. gbString str = type_to_string(t);
  199. error(type_expr, "Invalid constant type '%s'", str);
  200. gb_string_free(str);
  201. e->type = t_invalid;
  202. return;
  203. }
  204. e->type = t;
  205. }
  206. Operand operand = {};
  207. if (init != nullptr) {
  208. Entity *entity = nullptr;
  209. if (init->kind == AstNode_Ident) {
  210. entity = check_ident(c, &operand, init, nullptr, e->type, true);
  211. } else if (init->kind == AstNode_SelectorExpr) {
  212. entity = check_selector(c, &operand, init, e->type);
  213. } else {
  214. check_expr_or_type(c, &operand, init, e->type);
  215. }
  216. switch (operand.mode) {
  217. case Addressing_Type: {
  218. e->kind = Entity_TypeName;
  219. e->type = nullptr;
  220. DeclInfo *d = c->context.decl;
  221. if (d->type_expr != nullptr) {
  222. error(e->token, "A type declaration cannot have an type parameter");
  223. }
  224. d->type_expr = d->init_expr;
  225. check_type_decl(c, e, d->type_expr, named_type, false);
  226. return;
  227. }
  228. // NOTE(bill): Check to see if the expression it to be aliases
  229. case Addressing_Builtin:
  230. if (e->type != nullptr) {
  231. error(type_expr, "A constant alias of a built-in procedure may not have a type initializer");
  232. }
  233. e->kind = Entity_Builtin;
  234. e->Builtin.id = operand.builtin_id;
  235. e->type = t_invalid;
  236. return;
  237. case Addressing_ProcGroup:
  238. GB_ASSERT(operand.proc_group != nullptr);
  239. GB_ASSERT(operand.proc_group->kind == Entity_ProcGroup);
  240. e->kind = Entity_ProcGroup;
  241. e->type = t_invalid;
  242. gb_memmove(&e->ProcGroup, &operand.proc_group->ProcGroup, gb_size_of(e->ProcGroup));
  243. return;
  244. }
  245. if (entity != nullptr) {
  246. switch (entity->kind) {
  247. case Entity_Alias:
  248. e->kind = Entity_Alias;
  249. e->type = entity->type;
  250. e->Alias.base = entity->Alias.base;
  251. return;
  252. case Entity_Procedure:
  253. e->kind = Entity_Alias;
  254. e->type = entity->type;
  255. e->Alias.base = entity;
  256. return;
  257. case Entity_ImportName:
  258. e->kind = Entity_ImportName;
  259. e->type = entity->type;
  260. e->ImportName.path = entity->ImportName.path;
  261. e->ImportName.name = entity->ImportName.path;
  262. e->ImportName.scope = entity->ImportName.scope;
  263. e->ImportName.used = false;
  264. return;
  265. case Entity_LibraryName:
  266. e->kind = Entity_LibraryName;
  267. e->type = entity->type;
  268. e->LibraryName.path = entity->LibraryName.path;
  269. e->LibraryName.name = entity->LibraryName.path;
  270. e->LibraryName.used = false;
  271. return;
  272. }
  273. }
  274. }
  275. if (init != nullptr) {
  276. check_expr_or_type(c, &operand, init, e->type);
  277. }
  278. check_init_constant(c, e, &operand);
  279. if (operand.mode == Addressing_Invalid ||
  280. base_type(operand.type) == t_invalid) {
  281. gbString str = expr_to_string(init);
  282. error(e->token, "Invalid declaration type '%s'", str);
  283. gb_string_free(str);
  284. }
  285. DeclInfo *decl = decl_info_of_entity(&c->info, e);
  286. if (decl != nullptr && decl->attributes.count > 0) {
  287. error(decl->attributes[0], "Attributes are not allowed on constant value declarations");
  288. }
  289. }
  290. bool are_signatures_similar_enough(Type *a_, Type *b_) {
  291. GB_ASSERT(a_->kind == Type_Proc);
  292. GB_ASSERT(b_->kind == Type_Proc);
  293. TypeProc *a = &a_->Proc;
  294. TypeProc *b = &b_->Proc;
  295. if (a->param_count != b->param_count) {
  296. return false;
  297. }
  298. if (a->result_count != b->result_count) {
  299. return false;
  300. }
  301. for (isize i = 0; i < a->param_count; i++) {
  302. Type *x = core_type(a->params->Tuple.variables[i]->type);
  303. Type *y = core_type(b->params->Tuple.variables[i]->type);
  304. if (is_type_pointer(x) && is_type_pointer(y)) {
  305. continue;
  306. }
  307. if (is_type_integer(x) && is_type_integer(y)) {
  308. GB_ASSERT(x->kind == Type_Basic);
  309. GB_ASSERT(y->kind == Type_Basic);
  310. i64 sx = type_size_of(heap_allocator(), x);
  311. i64 sy = type_size_of(heap_allocator(), y);
  312. if (sx == sy) continue;
  313. }
  314. if (!are_types_identical(x, y)) return false;
  315. }
  316. for (isize i = 0; i < a->result_count; i++) {
  317. Type *x = base_type(a->results->Tuple.variables[i]->type);
  318. Type *y = base_type(b->results->Tuple.variables[i]->type);
  319. if (is_type_pointer(x) && is_type_pointer(y)) {
  320. continue;
  321. }
  322. if (is_type_integer(x) && is_type_integer(y)) {
  323. GB_ASSERT(x->kind == Type_Basic);
  324. GB_ASSERT(y->kind == Type_Basic);
  325. i64 sx = type_size_of(heap_allocator(), x);
  326. i64 sy = type_size_of(heap_allocator(), y);
  327. if (sx == sy) continue;
  328. }
  329. if (!are_types_identical(x, y)) {
  330. return false;
  331. }
  332. }
  333. return true;
  334. }
  335. void init_entity_foreign_library(Checker *c, Entity *e) {
  336. AstNode *ident = nullptr;
  337. Entity **foreign_library = nullptr;
  338. switch (e->kind) {
  339. case Entity_Procedure:
  340. ident = e->Procedure.foreign_library_ident;
  341. foreign_library = &e->Procedure.foreign_library;
  342. break;
  343. case Entity_Variable:
  344. ident = e->Variable.foreign_library_ident;
  345. foreign_library = &e->Variable.foreign_library;
  346. break;
  347. default:
  348. return;
  349. }
  350. if (ident == nullptr) {
  351. error(e->token, "foreign entiies must declare which library they are from");
  352. } else if (ident->kind != AstNode_Ident) {
  353. error(ident, "foreign library names must be an identifier");
  354. } else {
  355. String name = ident->Ident.token.string;
  356. Entity *found = scope_lookup_entity(c->context.scope, name);
  357. if (found == nullptr) {
  358. if (is_blank_ident(name)) {
  359. error(ident, "'_' cannot be used as a value type");
  360. } else {
  361. error(ident, "Undeclared name: %.*s", LIT(name));
  362. }
  363. } else if (found->kind != Entity_LibraryName) {
  364. error(ident, "'%.*s' cannot be used as a library name", LIT(name));
  365. } else {
  366. // TODO(bill): Extra stuff to do with library names?
  367. *foreign_library = found;
  368. found->LibraryName.used = true;
  369. add_entity_use(c, ident, found);
  370. }
  371. }
  372. }
  373. String handle_link_name(Checker *c, Token token, String link_name, String link_prefix) {
  374. if (link_prefix.len > 0) {
  375. if (link_name.len > 0) {
  376. error(token, "'link_name' and 'link_prefix' cannot be used together");
  377. } else {
  378. isize len = link_prefix.len + token.string.len;
  379. u8 *name = gb_alloc_array(c->allocator, u8, len+1);
  380. gb_memmove(name, &link_prefix[0], link_prefix.len);
  381. gb_memmove(name+link_prefix.len, &token.string[0], token.string.len);
  382. name[len] = 0;
  383. link_name = make_string(name, len);
  384. }
  385. }
  386. return link_name;
  387. }
  388. void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
  389. GB_ASSERT(e->type == nullptr);
  390. if (d->proc_lit->kind != AstNode_ProcLit) {
  391. // TOOD(bill): Better error message
  392. error(d->proc_lit, "Expected a procedure to check");
  393. return;
  394. }
  395. Type *proc_type = e->type;
  396. if (d->gen_proc_type != nullptr) {
  397. proc_type = d->gen_proc_type;
  398. } else {
  399. proc_type = make_type_proc(c->allocator, e->scope, nullptr, 0, nullptr, 0, false, ProcCC_Odin);
  400. }
  401. e->type = proc_type;
  402. ast_node(pl, ProcLit, d->proc_lit);
  403. check_open_scope(c, pl->type);
  404. defer (check_close_scope(c));
  405. auto prev_context = c->context;
  406. c->context.allow_polymorphic_types = true;
  407. check_procedure_type(c, proc_type, pl->type);
  408. c->context = prev_context;
  409. TypeProc *pt = &proc_type->Proc;
  410. bool is_foreign = e->Procedure.is_foreign;
  411. bool is_export = e->Procedure.is_export;
  412. bool is_require_results = (pl->tags & ProcTag_require_results) != 0;
  413. AttributeContext ac = make_attribute_context(e->Procedure.link_prefix);
  414. if (d != nullptr) {
  415. check_decl_attributes(c, d->attributes, proc_decl_attribute, &ac);
  416. }
  417. ac.link_name = handle_link_name(c, e->token, ac.link_name, ac.link_prefix);
  418. if (d->scope->file != nullptr && e->token.string == "main") {
  419. if (pt->param_count != 0 ||
  420. pt->result_count != 0) {
  421. gbString str = type_to_string(proc_type);
  422. error(e->token, "Procedure type of 'main' was expected to be 'proc()', got %s", str);
  423. gb_string_free(str);
  424. }
  425. if (pt->calling_convention != ProcCC_Odin &&
  426. pt->calling_convention != ProcCC_Contextless) {
  427. error(e->token, "Procedure 'main' cannot have a custom calling convention");
  428. }
  429. pt->calling_convention = ProcCC_Contextless;
  430. if (d->scope->is_init) {
  431. if (c->info.entry_point != nullptr) {
  432. error(e->token, "Redeclaration of the entry pointer procedure 'main'");
  433. } else {
  434. c->info.entry_point = e;
  435. }
  436. }
  437. }
  438. if (is_foreign && is_export) {
  439. error(pl->type, "A foreign procedure cannot have an 'export' tag");
  440. }
  441. if (pt->is_polymorphic) {
  442. if (pl->body == nullptr) {
  443. error(e->token, "Polymorphic procedures must have a body");
  444. }
  445. if (is_foreign) {
  446. error(e->token, "A foreign procedure cannot be a polymorphic");
  447. return;
  448. }
  449. }
  450. if (pl->body != nullptr) {
  451. if (is_foreign) {
  452. error(pl->body, "A foreign procedure cannot have a body");
  453. }
  454. if (proc_type->Proc.c_vararg) {
  455. error(pl->body, "A procedure with a '#c_vararg' field cannot have a body and must be foreign");
  456. }
  457. d->scope = c->context.scope;
  458. GB_ASSERT(pl->body->kind == AstNode_BlockStmt);
  459. if (!pt->is_polymorphic) {
  460. check_procedure_later(c, c->curr_ast_file, e->token, d, proc_type, pl->body, pl->tags);
  461. }
  462. } else if (!is_foreign) {
  463. if (e->Procedure.is_export) {
  464. error(e->token, "Foreign export procedures must have a body");
  465. } else {
  466. error(e->token, "Only a foreign procedure cannot have a body");
  467. }
  468. }
  469. if (pt->result_count == 0 && is_require_results) {
  470. error(pl->type, "'#require_results' is not needed on a procedure with no results");
  471. } else {
  472. pt->require_results = is_require_results;
  473. }
  474. if (ac.link_name.len > 0) {
  475. e->Procedure.link_name = ac.link_name;
  476. }
  477. if (is_foreign) {
  478. String name = e->token.string;
  479. if (e->Procedure.link_name.len > 0) {
  480. name = e->Procedure.link_name;
  481. }
  482. e->Procedure.is_foreign = true;
  483. e->Procedure.link_name = name;
  484. init_entity_foreign_library(c, e);
  485. auto *fp = &c->info.foreigns;
  486. HashKey key = hash_string(name);
  487. Entity **found = map_get(fp, key);
  488. if (found) {
  489. Entity *f = *found;
  490. TokenPos pos = f->token.pos;
  491. Type *this_type = base_type(e->type);
  492. Type *other_type = base_type(f->type);
  493. if (is_type_proc(this_type) && is_type_proc(other_type)) {
  494. if (!are_signatures_similar_enough(this_type, other_type)) {
  495. error(d->proc_lit,
  496. "Redeclaration of foreign procedure '%.*s' with different type signatures\n"
  497. "\tat %.*s(%td:%td)",
  498. LIT(name), LIT(pos.file), pos.line, pos.column);
  499. }
  500. } else if (!are_types_identical(this_type, other_type)) {
  501. error(d->proc_lit,
  502. "Foreign entity '%.*s' previously declared elsewhere with a different type\n"
  503. "\tat %.*s(%td:%td)",
  504. LIT(name), LIT(pos.file), pos.line, pos.column);
  505. }
  506. } else if (name == "main") {
  507. error(d->proc_lit, "The link name 'main' is reserved for internal use");
  508. } else {
  509. map_set(fp, key, e);
  510. }
  511. } else {
  512. String name = e->token.string;
  513. if (e->Procedure.link_name.len > 0) {
  514. name = e->Procedure.link_name;
  515. }
  516. if (e->Procedure.link_name.len > 0 || is_export) {
  517. auto *fp = &c->info.foreigns;
  518. HashKey key = hash_string(name);
  519. Entity **found = map_get(fp, key);
  520. if (found) {
  521. Entity *f = *found;
  522. TokenPos pos = f->token.pos;
  523. // TODO(bill): Better error message?
  524. error(d->proc_lit,
  525. "Non unique linking name for procedure '%.*s'\n"
  526. "\tother at %.*s(%td:%td)",
  527. LIT(name), LIT(pos.file), pos.line, pos.column);
  528. } else if (name == "main") {
  529. error(d->proc_lit, "The link name 'main' is reserved for internal use");
  530. } else {
  531. map_set(fp, key, e);
  532. }
  533. }
  534. }
  535. }
  536. void check_var_decl(Checker *c, Entity *e, Entity **entities, isize entity_count, AstNode *type_expr, Array<AstNode *> init_expr_list) {
  537. GB_ASSERT(e->type == nullptr);
  538. GB_ASSERT(e->kind == Entity_Variable);
  539. if (e->flags & EntityFlag_Visited) {
  540. e->type = t_invalid;
  541. return;
  542. }
  543. e->flags |= EntityFlag_Visited;
  544. AttributeContext ac = make_attribute_context(e->Variable.link_prefix);
  545. ac.init_expr_list_count = init_expr_list.count;
  546. DeclInfo *decl = decl_info_of_entity(&c->info, e);
  547. if (decl != nullptr) {
  548. check_decl_attributes(c, decl->attributes, var_decl_attribute, &ac);
  549. }
  550. ac.link_name = handle_link_name(c, e->token, ac.link_name, ac.link_prefix);
  551. e->Variable.thread_local_model = ac.thread_local_model;
  552. String context_name = str_lit("variable declaration");
  553. if (type_expr != nullptr) {
  554. e->type = check_type(c, type_expr);
  555. }
  556. if (e->type != nullptr) {
  557. if (is_type_polymorphic(base_type(e->type))) {
  558. gbString str = type_to_string(e->type);
  559. defer (gb_string_free(str));
  560. error(e->token, "Invalid use of a polymorphic type '%s' in %.*s", str, LIT(context_name));
  561. e->type = t_invalid;
  562. } else if (is_type_empty_union(e->type)) {
  563. gbString str = type_to_string(e->type);
  564. defer (gb_string_free(str));
  565. error(e->token, "An empty union '%s' cannot be instantiated in %.*s", str, LIT(context_name));
  566. e->type = t_invalid;
  567. }
  568. }
  569. if (e->Variable.is_foreign) {
  570. if (init_expr_list.count > 0) {
  571. error(e->token, "A foreign variable declaration cannot have a default value");
  572. }
  573. init_entity_foreign_library(c, e);
  574. }
  575. if (ac.link_name.len > 0) {
  576. e->Variable.link_name = ac.link_name;
  577. }
  578. if (e->Variable.is_foreign || e->Variable.is_export) {
  579. String name = e->token.string;
  580. if (e->Variable.link_name.len > 0) {
  581. name = e->Variable.link_name;
  582. }
  583. auto *fp = &c->info.foreigns;
  584. HashKey key = hash_string(name);
  585. Entity **found = map_get(fp, key);
  586. if (found) {
  587. Entity *f = *found;
  588. TokenPos pos = f->token.pos;
  589. Type *this_type = base_type(e->type);
  590. Type *other_type = base_type(f->type);
  591. if (!are_types_identical(this_type, other_type)) {
  592. error(e->token,
  593. "Foreign entity '%.*s' previously declared elsewhere with a different type\n"
  594. "\tat %.*s(%td:%td)",
  595. LIT(name), LIT(pos.file), pos.line, pos.column);
  596. }
  597. } else {
  598. map_set(fp, key, e);
  599. }
  600. }
  601. if (init_expr_list.count == 0) {
  602. if (type_expr == nullptr) {
  603. e->type = t_invalid;
  604. }
  605. return;
  606. }
  607. if (type_expr != nullptr) {
  608. for (isize i = 0; i < entity_count; i++) {
  609. entities[i]->type = e->type;
  610. }
  611. }
  612. check_init_variables(c, entities, entity_count, init_expr_list, context_name);
  613. }
  614. void check_proc_group_decl(Checker *c, Entity *pg_entity, DeclInfo *d) {
  615. GB_ASSERT(pg_entity->kind == Entity_ProcGroup);
  616. auto *pge = &pg_entity->ProcGroup;
  617. String proc_group_name = pg_entity->token.string;
  618. ast_node(pg, ProcGroup, d->init_expr);
  619. array_init(&pge->entities, c->allocator, pg->args.count);
  620. // NOTE(bill): This must be set here to prevent cycles in checking if someone
  621. // places the entity within itself
  622. pg_entity->type = t_invalid;
  623. PtrSet<Entity *> entity_map = {};
  624. ptr_set_init(&entity_map, heap_allocator());
  625. defer (ptr_set_destroy(&entity_map));
  626. for_array(i, pg->args) {
  627. AstNode *arg = pg->args[i];
  628. Entity *e = nullptr;
  629. Operand o = {};
  630. if (arg->kind == AstNode_Ident) {
  631. e = check_ident(c, &o, arg, nullptr, nullptr, true);
  632. } else if (arg->kind == AstNode_SelectorExpr) {
  633. e = check_selector(c, &o, arg, nullptr);
  634. }
  635. if (e == nullptr) {
  636. error(arg, "Expected a valid entity name in procedure group, got %.*s", LIT(ast_node_strings[arg->kind]));
  637. continue;
  638. }
  639. if (e->kind == Entity_Variable) {
  640. if (!is_type_proc(e->type)) {
  641. gbString s = type_to_string(e->type);
  642. defer (gb_string_free(s));
  643. error(arg, "Expected a procedure, got %s", s);
  644. continue;
  645. }
  646. } else if (e->kind != Entity_Procedure) {
  647. error(arg, "Expected a procedure entity");
  648. continue;
  649. }
  650. if (ptr_set_exists(&entity_map, e)) {
  651. error(arg, "Previous use of `%.*s` in procedure group", LIT(e->token.string));
  652. continue;
  653. }
  654. ptr_set_add(&entity_map, e);
  655. array_add(&pge->entities, e);
  656. }
  657. for_array(j, pge->entities) {
  658. Entity *p = pge->entities[j];
  659. if (p->type == t_invalid) {
  660. // NOTE(bill): This invalid overload has already been handled
  661. continue;
  662. }
  663. String name = p->token.string;
  664. for (isize k = j+1; k < pge->entities.count; k++) {
  665. Entity *q = pge->entities[k];
  666. GB_ASSERT(p != q);
  667. bool is_invalid = false;
  668. TokenPos pos = q->token.pos;
  669. if (q->type == nullptr || q->type == t_invalid) {
  670. continue;
  671. }
  672. ProcTypeOverloadKind kind = are_proc_types_overload_safe(p->type, q->type);
  673. switch (kind) {
  674. case ProcOverload_Identical:
  675. error(p->token, "Overloaded procedure '%.*s' as the same type as another procedure in this scope", LIT(name));
  676. is_invalid = true;
  677. break;
  678. // case ProcOverload_CallingConvention:
  679. // error(p->token, "Overloaded procedure '%.*s' as the same type as another procedure in this scope", LIT(name));
  680. // is_invalid = true;
  681. // break;
  682. case ProcOverload_ParamVariadic:
  683. error(p->token, "Overloaded procedure '%.*s' as the same type as another procedure in this scope", LIT(name));
  684. is_invalid = true;
  685. break;
  686. case ProcOverload_ResultCount:
  687. case ProcOverload_ResultTypes:
  688. error(p->token, "Overloaded procedure '%.*s' as the same parameters but different results in this scope", LIT(name));
  689. is_invalid = true;
  690. break;
  691. case ProcOverload_Polymorphic:
  692. #if 0
  693. error(p->token, "Overloaded procedure '%.*s' has a polymorphic counterpart in this scope which is not allowed", LIT(name));
  694. is_invalid = true;
  695. #endif
  696. break;
  697. case ProcOverload_ParamCount:
  698. case ProcOverload_ParamTypes:
  699. // This is okay :)
  700. break;
  701. }
  702. if (is_invalid) {
  703. gb_printf_err("\tprevious procedure at %.*s(%td:%td)\n", LIT(pos.file), pos.line, pos.column);
  704. q->type = t_invalid;
  705. }
  706. }
  707. }
  708. }
  709. void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
  710. if (e->type != nullptr) {
  711. return;
  712. }
  713. #if 0
  714. char buf[256] = {};
  715. isize n = gb_snprintf(buf, 256, "%.*s %d", LIT(e->token.string), e->kind);
  716. Timings timings = {};
  717. timings_init(&timings, make_string(cast(u8 *)buf, n-1), 16);
  718. defer ({
  719. timings_print_all(&timings);
  720. timings_destroy(&timings);
  721. });
  722. #define TIME_SECTION(str) timings_start_section(&timings, str_lit(str))
  723. #else
  724. #define TIME_SECTION(str)
  725. #endif
  726. if (d == nullptr) {
  727. d = decl_info_of_entity(&c->info, e);
  728. if (d == nullptr) {
  729. // TODO(bill): Err here?
  730. e->type = t_invalid;
  731. set_base_type(named_type, t_invalid);
  732. return;
  733. // GB_PANIC("'%.*s' should been declared!", LIT(e->token.string));
  734. }
  735. }
  736. CheckerContext prev = c->context;
  737. c->context.scope = d->scope;
  738. c->context.decl = d;
  739. e->parent_proc_decl = c->context.curr_proc_decl;
  740. switch (e->kind) {
  741. case Entity_Variable:
  742. check_var_decl(c, e, d->entities, d->entity_count, d->type_expr, d->init_expr_list);
  743. break;
  744. case Entity_Constant:
  745. check_const_decl(c, e, d->type_expr, d->init_expr, named_type);
  746. break;
  747. case Entity_TypeName: {
  748. bool is_alias = unparen_expr(d->type_expr)->kind == AstNode_AliasType;
  749. check_type_decl(c, e, d->type_expr, named_type, is_alias);
  750. break;
  751. }
  752. case Entity_Procedure:
  753. check_proc_decl(c, e, d);
  754. break;
  755. case Entity_ProcGroup:
  756. check_proc_group_decl(c, e, d);
  757. break;
  758. }
  759. c->context = prev;
  760. #undef TIME_SECTION
  761. }
  762. void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNode *body) {
  763. if (body == nullptr) {
  764. return;
  765. }
  766. GB_ASSERT(body->kind == AstNode_BlockStmt);
  767. String proc_name = {};
  768. if (token.kind == Token_Ident) {
  769. proc_name = token.string;
  770. } else {
  771. // TODO(bill): Better name
  772. proc_name = str_lit("(anonymous-procedure)");
  773. }
  774. CheckerContext old_context = c->context;
  775. defer (c->context = old_context);
  776. c->context.scope = decl->scope;
  777. c->context.decl = decl;
  778. c->context.proc_name = proc_name;
  779. c->context.curr_proc_decl = decl;
  780. GB_ASSERT(type->kind == Type_Proc);
  781. if (type->Proc.param_count > 0) {
  782. TypeTuple *params = &type->Proc.params->Tuple;
  783. for_array(i, params->variables) {
  784. Entity *e = params->variables[i];
  785. if (e->kind != Entity_Variable) {
  786. continue;
  787. }
  788. if (!(e->flags & EntityFlag_Using)) {
  789. continue;
  790. }
  791. bool is_immutable = e->Variable.is_immutable;
  792. bool is_value = (e->flags & EntityFlag_Value) != 0;
  793. String name = e->token.string;
  794. Type *t = base_type(type_deref(e->type));
  795. if (t->kind == Type_Struct) {
  796. Scope *scope = t->Struct.scope;
  797. if (scope == nullptr) {
  798. scope = scope_of_node(&c->info, t->Struct.node);
  799. }
  800. GB_ASSERT(scope != nullptr);
  801. for_array(i, scope->elements.entries) {
  802. Entity *f = scope->elements.entries[i].value;
  803. if (f->kind == Entity_Variable) {
  804. Entity *uvar = make_entity_using_variable(c->allocator, e, f->token, f->type);
  805. uvar->Variable.is_immutable = is_immutable;
  806. if (is_value) uvar->flags |= EntityFlag_Value;
  807. Entity *prev = scope_insert_entity(c->context.scope, uvar);
  808. if (prev != nullptr) {
  809. error(e->token, "Namespace collision while 'using' '%.*s' of: %.*s", LIT(name), LIT(prev->token.string));
  810. break;
  811. }
  812. }
  813. }
  814. } else {
  815. error(e->token, "'using' can only be applied to variables of type struct");
  816. break;
  817. }
  818. }
  819. }
  820. push_procedure(c, type);
  821. {
  822. ast_node(bs, BlockStmt, body);
  823. check_stmt_list(c, bs->stmts, Stmt_CheckScopeDecls);
  824. if (type->Proc.result_count > 0) {
  825. if (!check_is_terminating(body)) {
  826. if (token.kind == Token_Ident) {
  827. error(bs->close, "Missing return statement at the end of the procedure '%.*s'", LIT(token.string));
  828. } else {
  829. error(bs->close, "Missing return statement at the end of the procedure");
  830. }
  831. }
  832. }
  833. }
  834. pop_procedure(c);
  835. check_scope_usage(c, c->context.scope);
  836. if (decl->parent != nullptr) {
  837. // NOTE(bill): Add the dependencies from the procedure literal (lambda)
  838. for_array(i, decl->deps.entries) {
  839. Entity *e = decl->deps.entries[i].ptr;
  840. ptr_set_add(&decl->parent->deps, e);
  841. }
  842. }
  843. }