check_decl.cpp 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572
  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. if (is_type_proc(e->type)) {
  151. error(e->token, "Illegal declaration of a constant procedure value");
  152. }
  153. e->parent_proc_decl = ctx->curr_proc_decl;
  154. e->Constant.value = operand->value;
  155. }
  156. bool is_type_distinct(Ast *node) {
  157. for (;;) {
  158. if (node == nullptr) {
  159. return false;
  160. }
  161. if (node->kind == Ast_ParenExpr) {
  162. node = node->ParenExpr.expr;
  163. } else if (node->kind == Ast_HelperType) {
  164. node = node->HelperType.type;
  165. } else {
  166. break;
  167. }
  168. }
  169. switch (node->kind) {
  170. case Ast_DistinctType:
  171. return true;
  172. case Ast_StructType:
  173. case Ast_UnionType:
  174. case Ast_EnumType:
  175. case Ast_ProcType:
  176. return true;
  177. case Ast_PointerType:
  178. case Ast_ArrayType:
  179. case Ast_DynamicArrayType:
  180. case Ast_MapType:
  181. return false;
  182. }
  183. return false;
  184. }
  185. Ast *remove_type_alias_clutter(Ast *node) {
  186. for (;;) {
  187. if (node == nullptr) {
  188. return nullptr;
  189. }
  190. if (node->kind == Ast_ParenExpr) {
  191. node = node->ParenExpr.expr;
  192. } else if (node->kind == Ast_DistinctType) {
  193. node = node->DistinctType.type;
  194. } else {
  195. return node;
  196. }
  197. }
  198. }
  199. isize total_attribute_count(DeclInfo *decl) {
  200. isize attribute_count = 0;
  201. for_array(i, decl->attributes) {
  202. Ast *attr = decl->attributes[i];
  203. if (attr->kind != Ast_Attribute) continue;
  204. attribute_count += attr->Attribute.elems.count;
  205. }
  206. return attribute_count;
  207. }
  208. Type *clone_enum_type(CheckerContext *ctx, Type *original_enum_type, Type *named_type) {
  209. // NOTE(bill, 2022-02-05): Stupid edge case for `distinct` declarations
  210. //
  211. // X :: enum {A, B, C}
  212. // Y :: distinct X
  213. //
  214. // To make Y be just like X, it will need to copy the elements of X and change their type
  215. // so that they match Y rather than X.
  216. GB_ASSERT(original_enum_type != nullptr);
  217. GB_ASSERT(named_type != nullptr);
  218. GB_ASSERT(original_enum_type->kind == Type_Enum);
  219. GB_ASSERT(named_type->kind == Type_Named);
  220. Scope *parent = original_enum_type->Enum.scope->parent;
  221. Scope *scope = create_scope(nullptr, parent);
  222. Type *et = alloc_type_enum();
  223. et->Enum.base_type = original_enum_type->Enum.base_type;
  224. et->Enum.min_value = original_enum_type->Enum.min_value;
  225. et->Enum.max_value = original_enum_type->Enum.max_value;
  226. et->Enum.min_value_index = original_enum_type->Enum.min_value_index;
  227. et->Enum.max_value_index = original_enum_type->Enum.max_value_index;
  228. et->Enum.scope = scope;
  229. auto fields = array_make<Entity *>(permanent_allocator(), original_enum_type->Enum.fields.count);
  230. for_array(i, fields) {
  231. Entity *old = original_enum_type->Enum.fields[i];
  232. Entity *e = alloc_entity_constant(scope, old->token, named_type, old->Constant.value);
  233. e->file = old->file;
  234. e->identifier = clone_ast(old->identifier);
  235. e->flags |= EntityFlag_Visited;
  236. e->state = EntityState_Resolved;
  237. e->Constant.flags = old->Constant.flags;
  238. e->Constant.docs = old->Constant.docs;
  239. e->Constant.comment = old->Constant.comment;
  240. fields[i] = e;
  241. add_entity(ctx, scope, nullptr, e);
  242. add_entity_use(ctx, e->identifier, e);
  243. }
  244. et->Enum.fields = fields;
  245. return et;
  246. }
  247. void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *def) {
  248. GB_ASSERT(e->type == nullptr);
  249. DeclInfo *decl = decl_info_of_entity(e);
  250. bool is_distinct = is_type_distinct(init_expr);
  251. Ast *te = remove_type_alias_clutter(init_expr);
  252. e->type = t_invalid;
  253. String name = e->token.string;
  254. Type *named = alloc_type_named(name, nullptr, e);
  255. if (def != nullptr && def->kind == Type_Named) {
  256. def->Named.base = named;
  257. }
  258. e->type = named;
  259. check_type_path_push(ctx, e);
  260. Type *bt = check_type_expr(ctx, te, named);
  261. check_type_path_pop(ctx);
  262. Type *base = base_type(bt);
  263. if (is_distinct && bt->kind == Type_Named && base->kind == Type_Enum) {
  264. base = clone_enum_type(ctx, base, named);
  265. }
  266. named->Named.base = base;
  267. if (is_distinct && is_type_typeid(e->type)) {
  268. error(init_expr, "'distinct' cannot be applied to 'typeid'");
  269. is_distinct = false;
  270. }
  271. if (is_distinct && is_type_any(e->type)) {
  272. error(init_expr, "'distinct' cannot be applied to 'any'");
  273. is_distinct = false;
  274. }
  275. if (!is_distinct) {
  276. e->type = bt;
  277. named->Named.base = bt;
  278. e->TypeName.is_type_alias = true;
  279. }
  280. if (decl->type_expr != nullptr) {
  281. Type *t = check_type(ctx, decl->type_expr);
  282. if (t != nullptr && !is_type_typeid(t)) {
  283. Operand operand = {};
  284. operand.mode = Addressing_Type;
  285. operand.type = e->type;
  286. operand.expr = init_expr;
  287. check_assignment(ctx, &operand, t, str_lit("constant declaration"));
  288. }
  289. }
  290. if (decl != nullptr) {
  291. AttributeContext ac = {};
  292. check_decl_attributes(ctx, decl->attributes, type_decl_attribute, &ac);
  293. if (e->kind == Entity_TypeName && ac.objc_class != "") {
  294. e->TypeName.objc_class_name = ac.objc_class;
  295. if (type_size_of(e->type) > 0) {
  296. error(e->token, "@(objc_class) marked type must be of zero size");
  297. }
  298. }
  299. }
  300. // using decl
  301. if (decl->is_using) {
  302. warning(init_expr, "'using' an enum declaration is not allowed, prefer using implicit selector expressions e.g. '.A'");
  303. #if 1
  304. // NOTE(bill): Must be an enum declaration
  305. if (te->kind == Ast_EnumType) {
  306. Scope *parent = e->scope;
  307. if (parent->flags&ScopeFlag_File) {
  308. // NOTE(bill): Use package scope
  309. parent = parent->parent;
  310. }
  311. Type *t = base_type(e->type);
  312. if (t->kind == Type_Enum) {
  313. for_array(i, t->Enum.fields) {
  314. Entity *f = t->Enum.fields[i];
  315. if (f->kind != Entity_Constant) {
  316. continue;
  317. }
  318. String name = f->token.string;
  319. if (is_blank_ident(name)) {
  320. continue;
  321. }
  322. add_entity(ctx, parent, nullptr, f);
  323. }
  324. }
  325. }
  326. #endif
  327. }
  328. }
  329. void override_entity_in_scope(Entity *original_entity, Entity *new_entity) {
  330. // NOTE(bill): The original_entity's scope may not be same scope that it was inserted into
  331. // e.g. file entity inserted into its package scope
  332. String original_name = original_entity->token.string;
  333. Scope *found_scope = nullptr;
  334. Entity *found_entity = nullptr;
  335. scope_lookup_parent(original_entity->scope, original_name, &found_scope, &found_entity);
  336. if (found_scope == nullptr) {
  337. return;
  338. }
  339. mutex_lock(&found_scope->mutex);
  340. defer (mutex_unlock(&found_scope->mutex));
  341. // IMPORTANT NOTE(bill, 2021-04-10): Overriding behaviour was flawed in that the
  342. // original entity was still used check checked, but the checking was only
  343. // relying on "constant" data such as the Entity.type and Entity.Constant.value
  344. //
  345. // Therefore two things can be done: the type can be assigned to state that it
  346. // has been "evaluated" and the variant data can be copied across
  347. string_map_set(&found_scope->elements, original_name, new_entity);
  348. original_entity->flags |= EntityFlag_Overridden;
  349. original_entity->type = new_entity->type;
  350. original_entity->aliased_of = new_entity;
  351. Ast *empty_ident = nullptr;
  352. original_entity->identifier.compare_exchange_strong(empty_ident, new_entity->identifier);
  353. if (original_entity->identifier.load() != nullptr &&
  354. original_entity->identifier.load()->kind == Ast_Ident) {
  355. original_entity->identifier.load()->Ident.entity = new_entity;
  356. }
  357. // IMPORTANT NOTE(bill, 2021-04-10): copy only the variants
  358. // This is most likely NEVER required, but it does not at all hurt to keep
  359. isize offset = cast(u8 *)&original_entity->Dummy.start - cast(u8 *)original_entity;
  360. isize size = gb_size_of(*original_entity) - offset;
  361. gb_memmove(cast(u8 *)original_entity, cast(u8 *)new_entity, size);
  362. }
  363. void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init, Type *named_type) {
  364. GB_ASSERT(e->type == nullptr);
  365. GB_ASSERT(e->kind == Entity_Constant);
  366. init = unparen_expr(init);
  367. if (e->flags & EntityFlag_Visited) {
  368. e->type = t_invalid;
  369. return;
  370. }
  371. e->flags |= EntityFlag_Visited;
  372. if (type_expr) {
  373. e->type = check_type(ctx, type_expr);
  374. }
  375. Operand operand = {};
  376. if (init != nullptr) {
  377. Entity *entity = check_entity_from_ident_or_selector(ctx, init, false);
  378. if (entity != nullptr && entity->kind == Entity_TypeName) {
  379. // @TypeAliasingProblem
  380. // NOTE(bill, 2022-02-03): This is used to solve the problem caused by type aliases
  381. // being "confused" as constants
  382. //
  383. // A :: B
  384. // C :: proc "c" (^A)
  385. // B :: struct {x: C}
  386. //
  387. // A gets evaluated first, and then checks B.
  388. // B then checks C.
  389. // C then tries to check A which is unresolved but thought to be a constant.
  390. // Therefore within C's check, A errs as "not a type".
  391. //
  392. // This is because a const declaration may or may not be a type and this cannot
  393. // be determined from a syntactical standpoint.
  394. // This check allows the compiler to override the entity to be checked as a type.
  395. //
  396. // There is no problem if B is prefixed with the `#type` helper enforcing at
  397. // both a syntax and semantic level that B must be a type.
  398. //
  399. // A :: #type B
  400. //
  401. // This approach is not fool proof and can fail in case such as:
  402. //
  403. // X :: type_of(x)
  404. // X :: Foo(int).Type
  405. //
  406. // Since even these kind of declarations may cause weird checking cycles.
  407. // For the time being, these are going to be treated as an unfortunate error
  408. // until there is a proper delaying system to try declaration again if they
  409. // have failed.
  410. e->kind = Entity_TypeName;
  411. check_type_decl(ctx, e, init, named_type);
  412. return;
  413. }
  414. entity = nullptr;
  415. if (init->kind == Ast_Ident) {
  416. entity = check_ident(ctx, &operand, init, nullptr, e->type, true);
  417. } else if (init->kind == Ast_SelectorExpr) {
  418. entity = check_selector(ctx, &operand, init, e->type);
  419. } else {
  420. check_expr_or_type(ctx, &operand, init, e->type);
  421. }
  422. switch (operand.mode) {
  423. case Addressing_Type: {
  424. if (e->type != nullptr && !is_type_typeid(e->type)) {
  425. check_assignment(ctx, &operand, e->type, str_lit("constant declaration"));
  426. }
  427. e->kind = Entity_TypeName;
  428. e->type = nullptr;
  429. if (entity != nullptr && entity->type != nullptr &&
  430. is_type_polymorphic_record_unspecialized(entity->type)) {
  431. DeclInfo *decl = decl_info_of_entity(e);
  432. if (decl != nullptr) {
  433. if (decl->attributes.count > 0) {
  434. error(decl->attributes[0], "Constant alias declarations cannot have attributes");
  435. }
  436. }
  437. override_entity_in_scope(e, entity);
  438. return;
  439. }
  440. check_type_decl(ctx, e, ctx->decl->init_expr, named_type);
  441. return;
  442. }
  443. // NOTE(bill): Check to see if the expression it to be aliases
  444. case Addressing_Builtin:
  445. if (e->type != nullptr) {
  446. error(type_expr, "A constant alias of a built-in procedure may not have a type initializer");
  447. }
  448. e->kind = Entity_Builtin;
  449. e->Builtin.id = operand.builtin_id;
  450. e->type = t_invalid;
  451. return;
  452. case Addressing_ProcGroup:
  453. GB_ASSERT(operand.proc_group != nullptr);
  454. GB_ASSERT(operand.proc_group->kind == Entity_ProcGroup);
  455. // NOTE(bill, 2020-06-10): It is better to just clone the contents than overriding the entity in the scope
  456. // Thank goodness I made entities a tagged union to allow for this implace patching
  457. e->kind = Entity_ProcGroup;
  458. e->ProcGroup.entities = array_clone(heap_allocator(), operand.proc_group->ProcGroup.entities);
  459. return;
  460. }
  461. if (entity != nullptr) {
  462. if (e->type != nullptr) {
  463. Operand x = {};
  464. x.type = entity->type;
  465. x.mode = Addressing_Variable;
  466. if (!check_is_assignable_to(ctx, &x, e->type)) {
  467. gbString expr_str = expr_to_string(init);
  468. gbString op_type_str = type_to_string(entity->type);
  469. gbString type_str = type_to_string(e->type);
  470. error(e->token,
  471. "Cannot assign '%s' of type '%s' to '%s'",
  472. expr_str,
  473. op_type_str,
  474. type_str);
  475. gb_string_free(type_str);
  476. gb_string_free(op_type_str);
  477. gb_string_free(expr_str);
  478. }
  479. }
  480. // NOTE(bill): Override aliased entity
  481. switch (entity->kind) {
  482. case Entity_ProcGroup:
  483. case Entity_Procedure:
  484. case Entity_LibraryName:
  485. case Entity_ImportName:
  486. {
  487. DeclInfo *decl = decl_info_of_entity(e);
  488. if (decl != nullptr) {
  489. if (decl->attributes.count > 0) {
  490. error(decl->attributes[0], "Constant alias declarations cannot have attributes");
  491. }
  492. }
  493. override_entity_in_scope(e, entity);
  494. return;
  495. }
  496. }
  497. }
  498. }
  499. check_init_constant(ctx, e, &operand);
  500. if (operand.mode == Addressing_Invalid ||
  501. base_type(operand.type) == t_invalid) {
  502. gbString str = expr_to_string(init);
  503. error(e->token, "Invalid declaration type '%s'", str);
  504. gb_string_free(str);
  505. }
  506. DeclInfo *decl = decl_info_of_entity(e);
  507. if (decl != nullptr) {
  508. check_decl_attributes(ctx, decl->attributes, const_decl_attribute, nullptr);
  509. }
  510. }
  511. typedef bool TypeCheckSig(Type *t);
  512. bool sig_compare(TypeCheckSig *a, Type *x, Type *y) {
  513. x = core_type(x);
  514. y = core_type(y);
  515. return (a(x) && a(y));
  516. }
  517. bool sig_compare(TypeCheckSig *a, TypeCheckSig *b, Type *x, Type *y) {
  518. x = core_type(x);
  519. y = core_type(y);
  520. if (a == b) {
  521. return sig_compare(a, x, y);
  522. }
  523. return ((a(x) && b(y)) || (b(x) && a(y)));
  524. }
  525. bool signature_parameter_similar_enough(Type *x, Type *y) {
  526. if (sig_compare(is_type_pointer, x, y)) {
  527. return true;
  528. }
  529. if (sig_compare(is_type_multi_pointer, x, y)) {
  530. return true;
  531. }
  532. if (sig_compare(is_type_proc, x, y)) {
  533. return true;
  534. }
  535. if (sig_compare(is_type_integer, x, y)) {
  536. GB_ASSERT(core_type(x)->kind == Type_Basic);
  537. GB_ASSERT(core_type(y)->kind == Type_Basic);
  538. i64 sx = type_size_of(x);
  539. i64 sy = type_size_of(y);
  540. if (sx == sy) return true;
  541. }
  542. if (sig_compare(is_type_integer, is_type_boolean, x, y)) {
  543. GB_ASSERT(core_type(x)->kind == Type_Basic);
  544. GB_ASSERT(core_type(y)->kind == Type_Basic);
  545. i64 sx = type_size_of(x);
  546. i64 sy = type_size_of(y);
  547. if (sx == sy) return true;
  548. }
  549. if (sig_compare(is_type_cstring, is_type_u8_ptr, x, y)) {
  550. return true;
  551. }
  552. if (sig_compare(is_type_cstring, is_type_u8_multi_ptr, x, y)) {
  553. return true;
  554. }
  555. if (sig_compare(is_type_uintptr, is_type_rawptr, x, y)) {
  556. return true;
  557. }
  558. if (sig_compare(is_type_proc, is_type_pointer, x, y)) {
  559. return true;
  560. }
  561. if (sig_compare(is_type_pointer, is_type_multi_pointer, x, y)) {
  562. return true;
  563. }
  564. if (sig_compare(is_type_proc, is_type_multi_pointer, x, y)) {
  565. return true;
  566. }
  567. return are_types_identical(x, y);
  568. }
  569. bool are_signatures_similar_enough(Type *a_, Type *b_) {
  570. GB_ASSERT(a_->kind == Type_Proc);
  571. GB_ASSERT(b_->kind == Type_Proc);
  572. TypeProc *a = &a_->Proc;
  573. TypeProc *b = &b_->Proc;
  574. if (a->param_count != b->param_count) {
  575. return false;
  576. }
  577. if (a->result_count != b->result_count) {
  578. return false;
  579. }
  580. for (isize i = 0; i < a->param_count; i++) {
  581. Type *x = core_type(a->params->Tuple.variables[i]->type);
  582. Type *y = core_type(b->params->Tuple.variables[i]->type);
  583. if (!signature_parameter_similar_enough(x, y)) {
  584. return false;
  585. }
  586. }
  587. for (isize i = 0; i < a->result_count; i++) {
  588. Type *x = base_type(a->results->Tuple.variables[i]->type);
  589. Type *y = base_type(b->results->Tuple.variables[i]->type);
  590. if (!signature_parameter_similar_enough(x, y)) {
  591. return false;
  592. }
  593. }
  594. return true;
  595. }
  596. Entity *init_entity_foreign_library(CheckerContext *ctx, Entity *e) {
  597. Ast *ident = nullptr;
  598. Entity **foreign_library = nullptr;
  599. switch (e->kind) {
  600. case Entity_Procedure:
  601. ident = e->Procedure.foreign_library_ident;
  602. foreign_library = &e->Procedure.foreign_library;
  603. break;
  604. case Entity_Variable:
  605. ident = e->Variable.foreign_library_ident;
  606. foreign_library = &e->Variable.foreign_library;
  607. break;
  608. default:
  609. return nullptr;
  610. }
  611. if (ident == nullptr) {
  612. error(e->token, "foreign entiies must declare which library they are from");
  613. } else if (ident->kind != Ast_Ident) {
  614. error(ident, "foreign library names must be an identifier");
  615. } else {
  616. String name = ident->Ident.token.string;
  617. Entity *found = scope_lookup(ctx->scope, name);
  618. if (found == nullptr) {
  619. if (is_blank_ident(name)) {
  620. // NOTE(bill): link against nothing
  621. } else {
  622. error(ident, "Undeclared name: %.*s", LIT(name));
  623. }
  624. } else if (found->kind != Entity_LibraryName) {
  625. error(ident, "'%.*s' cannot be used as a library name", LIT(name));
  626. } else {
  627. // TODO(bill): Extra stuff to do with library names?
  628. *foreign_library = found;
  629. found->flags |= EntityFlag_Used;
  630. add_entity_use(ctx, ident, found);
  631. return found;
  632. }
  633. }
  634. return nullptr;
  635. }
  636. String handle_link_name(CheckerContext *ctx, Token token, String link_name, String link_prefix) {
  637. if (link_prefix.len > 0) {
  638. if (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. return link_name;
  650. }
  651. void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
  652. GB_ASSERT(e->type == nullptr);
  653. if (d->proc_lit->kind != Ast_ProcLit) {
  654. // TOOD(bill): Better error message
  655. error(d->proc_lit, "Expected a procedure to check");
  656. return;
  657. }
  658. Type *proc_type = e->type;
  659. if (d->gen_proc_type != nullptr) {
  660. proc_type = d->gen_proc_type;
  661. } else {
  662. proc_type = alloc_type_proc(e->scope, nullptr, 0, nullptr, 0, false, default_calling_convention());
  663. }
  664. e->type = proc_type;
  665. ast_node(pl, ProcLit, d->proc_lit);
  666. check_open_scope(ctx, pl->type);
  667. defer (check_close_scope(ctx));
  668. ctx->scope->procedure_entity = e;
  669. Type *decl_type = nullptr;
  670. if (d->type_expr != nullptr) {
  671. decl_type = check_type(ctx, d->type_expr);
  672. if (!is_type_proc(decl_type)) {
  673. gbString str = type_to_string(decl_type);
  674. error(d->type_expr, "Expected a procedure type, got '%s'", str);
  675. gb_string_free(str);
  676. }
  677. }
  678. auto tmp_ctx = *ctx;
  679. tmp_ctx.allow_polymorphic_types = true;
  680. if (decl_type != nullptr) {
  681. tmp_ctx.type_hint = decl_type;
  682. }
  683. check_procedure_type(&tmp_ctx, proc_type, pl->type);
  684. if (decl_type != nullptr) {
  685. Operand x = {};
  686. x.type = e->type;
  687. x.mode = Addressing_Variable;
  688. if (!check_is_assignable_to(ctx, &x, decl_type)) {
  689. gbString expr_str = expr_to_string(d->proc_lit);
  690. gbString op_type_str = type_to_string(e->type);
  691. gbString type_str = type_to_string(decl_type);
  692. error(e->token,
  693. "Cannot assign '%s' of type '%s' to '%s'",
  694. expr_str,
  695. op_type_str,
  696. type_str);
  697. gb_string_free(type_str);
  698. gb_string_free(op_type_str);
  699. gb_string_free(expr_str);
  700. }
  701. }
  702. TypeProc *pt = &proc_type->Proc;
  703. AttributeContext ac = make_attribute_context(e->Procedure.link_prefix);
  704. if (d != nullptr) {
  705. check_decl_attributes(ctx, d->attributes, proc_decl_attribute, &ac);
  706. }
  707. if (ac.test) {
  708. e->flags |= EntityFlag_Test;
  709. }
  710. if (ac.init) {
  711. e->flags |= EntityFlag_Init;
  712. }
  713. if (ac.set_cold) {
  714. e->flags |= EntityFlag_Cold;
  715. }
  716. e->Procedure.optimization_mode = cast(ProcedureOptimizationMode)ac.optimization_mode;
  717. if (ac.objc_name.len || ac.objc_is_class_method || ac.objc_type) {
  718. if (ac.objc_name.len == 0 && ac.objc_is_class_method) {
  719. error(e->token, "@(objc_name) is required with @(objc_is_class_method)");
  720. } else if (ac.objc_type == nullptr) {
  721. error(e->token, "@(objc_name) requires that @(objc_type) to be set");
  722. } else if (ac.objc_name.len == 0 && ac.objc_type) {
  723. error(e->token, "@(objc_name) is required with @(objc_type)");
  724. } else {
  725. Type *t = ac.objc_type;
  726. if (t->kind == Type_Named) {
  727. Entity *tn = t->Named.type_name;
  728. GB_ASSERT(tn->kind == Entity_TypeName);
  729. if (tn->scope != e->scope) {
  730. error(e->token, "@(objc_name) attribute may only be applied to procedures and types within the same scope");
  731. } else {
  732. mutex_lock(&global_type_name_objc_metadata_mutex);
  733. defer (mutex_unlock(&global_type_name_objc_metadata_mutex));
  734. if (!tn->TypeName.objc_metadata) {
  735. tn->TypeName.objc_metadata = create_type_name_obj_c_metadata();
  736. }
  737. auto *md = tn->TypeName.objc_metadata;
  738. mutex_lock(md->mutex);
  739. defer (mutex_unlock(md->mutex));
  740. if (!ac.objc_is_class_method) {
  741. bool ok = true;
  742. for (TypeNameObjCMetadataEntry const &entry : md->value_entries) {
  743. if (entry.name == ac.objc_name) {
  744. error(e->token, "Previous declaration of @(objc_name=\"%.*s\")", LIT(ac.objc_name));
  745. ok = false;
  746. break;
  747. }
  748. }
  749. if (ok) {
  750. array_add(&md->value_entries, TypeNameObjCMetadataEntry{ac.objc_name, e});
  751. }
  752. } else {
  753. bool ok = true;
  754. for (TypeNameObjCMetadataEntry const &entry : md->type_entries) {
  755. if (entry.name == ac.objc_name) {
  756. error(e->token, "Previous declaration of @(objc_name=\"%.*s\")", LIT(ac.objc_name));
  757. ok = false;
  758. break;
  759. }
  760. }
  761. if (ok) {
  762. array_add(&md->type_entries, TypeNameObjCMetadataEntry{ac.objc_name, e});
  763. }
  764. }
  765. }
  766. }
  767. }
  768. }
  769. switch (e->Procedure.optimization_mode) {
  770. case ProcedureOptimizationMode_None:
  771. case ProcedureOptimizationMode_Minimal:
  772. if (pl->inlining == ProcInlining_inline) {
  773. error(e->token, "#force_inline cannot be used in conjunction with the attribute 'optimization_mode' with neither \"none\" nor \"minimal\"");
  774. }
  775. break;
  776. }
  777. e->Procedure.is_export = ac.is_export;
  778. e->deprecated_message = ac.deprecated_message;
  779. e->warning_message = ac.warning_message;
  780. ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix);
  781. if (ac.has_disabled_proc) {
  782. if (ac.disabled_proc) {
  783. e->flags |= EntityFlag_Disabled;
  784. }
  785. Type *t = base_type(e->type);
  786. GB_ASSERT(t->kind == Type_Proc);
  787. if (t->Proc.result_count != 0) {
  788. error(e->token, "Procedure with the 'disabled' attribute may not have any return values");
  789. }
  790. }
  791. bool is_foreign = e->Procedure.is_foreign;
  792. bool is_export = e->Procedure.is_export;
  793. if (ac.linkage.len != 0) {
  794. if (ac.linkage == "internal") { e->flags |= EntityFlag_CustomLinkage_Internal; }
  795. else if (ac.linkage == "strong") { e->flags |= EntityFlag_CustomLinkage_Strong; }
  796. else if (ac.linkage == "weak") { e->flags |= EntityFlag_CustomLinkage_Weak; }
  797. else if (ac.linkage == "link_once") { e->flags |= EntityFlag_CustomLinkage_LinkOnce; }
  798. if (is_foreign && (e->flags & EntityFlag_CustomLinkage_Internal)) {
  799. error(e->token, "A foreign procedure may not have an \"internal\" linkage");
  800. }
  801. }
  802. if (ac.require_declaration) {
  803. e->flags |= EntityFlag_Require;
  804. }
  805. if (e->pkg != nullptr && e->token.string == "main") {
  806. if (e->pkg->kind != Package_Runtime) {
  807. if (pt->param_count != 0 ||
  808. pt->result_count != 0) {
  809. gbString str = type_to_string(proc_type);
  810. error(e->token, "Procedure type of 'main' was expected to be 'proc()', got %s", str);
  811. gb_string_free(str);
  812. }
  813. if (pt->calling_convention != default_calling_convention()) {
  814. error(e->token, "Procedure 'main' cannot have a custom calling convention");
  815. }
  816. pt->calling_convention = default_calling_convention();
  817. if (e->pkg->kind == Package_Init) {
  818. if (ctx->info->entry_point != nullptr) {
  819. error(e->token, "Redeclaration of the entry pointer procedure 'main'");
  820. } else {
  821. ctx->info->entry_point = e;
  822. }
  823. }
  824. }
  825. }
  826. if (is_foreign && is_export) {
  827. error(pl->type, "A foreign procedure cannot have an 'export' tag");
  828. }
  829. if (pt->is_polymorphic) {
  830. if (pl->body == nullptr) {
  831. error(e->token, "Polymorphic procedures must have a body");
  832. }
  833. if (is_foreign) {
  834. error(e->token, "A foreign procedure cannot be a polymorphic");
  835. return;
  836. }
  837. }
  838. if (pl->body != nullptr) {
  839. if (is_foreign) {
  840. error(pl->body, "A foreign procedure cannot have a body");
  841. }
  842. if (proc_type->Proc.c_vararg) {
  843. error(pl->body, "A procedure with a '#c_vararg' field cannot have a body and must be foreign");
  844. }
  845. d->scope = ctx->scope;
  846. GB_ASSERT(pl->body->kind == Ast_BlockStmt);
  847. if (!pt->is_polymorphic) {
  848. check_procedure_later(ctx, ctx->file, e->token, d, proc_type, pl->body, pl->tags);
  849. }
  850. } else if (!is_foreign) {
  851. if (e->Procedure.is_export) {
  852. error(e->token, "Foreign export procedures must have a body");
  853. } else {
  854. error(e->token, "Only a foreign procedure cannot have a body");
  855. }
  856. }
  857. if (pt->result_count == 0 && ac.require_results) {
  858. error(pl->type, "'require_results' is not needed on a procedure with no results");
  859. } else {
  860. pt->require_results = ac.require_results;
  861. }
  862. if (ac.link_name.len > 0) {
  863. e->Procedure.link_name = ac.link_name;
  864. }
  865. if (ac.deferred_procedure.entity != nullptr) {
  866. e->Procedure.deferred_procedure = ac.deferred_procedure;
  867. mpmc_enqueue(&ctx->checker->procs_with_deferred_to_check, e);
  868. }
  869. if (is_foreign) {
  870. String name = e->token.string;
  871. if (e->Procedure.link_name.len > 0) {
  872. name = e->Procedure.link_name;
  873. }
  874. Entity *foreign_library = init_entity_foreign_library(ctx, e);
  875. if (is_arch_wasm()) {
  876. String module_name = str_lit("env");
  877. if (foreign_library != nullptr) {
  878. GB_ASSERT (foreign_library->kind == Entity_LibraryName);
  879. if (foreign_library->LibraryName.paths.count != 1) {
  880. error(foreign_library->token, "'foreign import' for '%.*s' architecture may only have one path, got %td",
  881. LIT(target_arch_names[build_context.metrics.arch]), foreign_library->LibraryName.paths.count);
  882. }
  883. if (foreign_library->LibraryName.paths.count >= 1) {
  884. module_name = foreign_library->LibraryName.paths[0];
  885. }
  886. }
  887. name = concatenate3_strings(permanent_allocator(), module_name, WASM_MODULE_NAME_SEPARATOR, name);
  888. }
  889. e->Procedure.is_foreign = true;
  890. e->Procedure.link_name = name;
  891. mutex_lock(&ctx->info->foreign_mutex);
  892. auto *fp = &ctx->info->foreigns;
  893. StringHashKey key = string_hash_string(name);
  894. Entity **found = string_map_get(fp, key);
  895. if (found) {
  896. Entity *f = *found;
  897. TokenPos pos = f->token.pos;
  898. Type *this_type = base_type(e->type);
  899. Type *other_type = base_type(f->type);
  900. if (is_type_proc(this_type) && is_type_proc(other_type)) {
  901. if (!are_signatures_similar_enough(this_type, other_type)) {
  902. error(d->proc_lit,
  903. "Redeclaration of foreign procedure '%.*s' with different type signatures\n"
  904. "\tat %s",
  905. LIT(name), token_pos_to_string(pos));
  906. }
  907. } else if (!are_types_identical(this_type, other_type)) {
  908. error(d->proc_lit,
  909. "Foreign entity '%.*s' previously declared elsewhere with a different type\n"
  910. "\tat %s",
  911. LIT(name), token_pos_to_string(pos));
  912. }
  913. } else if (name == "main") {
  914. error(d->proc_lit, "The link name 'main' is reserved for internal use");
  915. } else {
  916. string_map_set(fp, key, e);
  917. }
  918. mutex_unlock(&ctx->info->foreign_mutex);
  919. } else {
  920. String name = e->token.string;
  921. if (e->Procedure.link_name.len > 0) {
  922. name = e->Procedure.link_name;
  923. }
  924. if (e->Procedure.link_name.len > 0 || is_export) {
  925. mutex_lock(&ctx->info->foreign_mutex);
  926. auto *fp = &ctx->info->foreigns;
  927. StringHashKey key = string_hash_string(name);
  928. Entity **found = string_map_get(fp, key);
  929. if (found) {
  930. Entity *f = *found;
  931. TokenPos pos = f->token.pos;
  932. // TODO(bill): Better error message?
  933. error(d->proc_lit,
  934. "Non unique linking name for procedure '%.*s'\n"
  935. "\tother at %s",
  936. LIT(name), token_pos_to_string(pos));
  937. } else if (name == "main") {
  938. if (d->entity->pkg->kind != Package_Runtime) {
  939. error(d->proc_lit, "The link name 'main' is reserved for internal use");
  940. }
  941. } else {
  942. string_map_set(fp, key, e);
  943. }
  944. mutex_unlock(&ctx->info->foreign_mutex);
  945. }
  946. }
  947. if (e->Procedure.link_name.len > 0 ) {
  948. e->flags |= EntityFlag_CustomLinkName;
  949. }
  950. }
  951. void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast *type_expr, Ast *init_expr) {
  952. GB_ASSERT(e->type == nullptr);
  953. GB_ASSERT(e->kind == Entity_Variable);
  954. if (e->flags & EntityFlag_Visited) {
  955. e->type = t_invalid;
  956. return;
  957. }
  958. e->flags |= EntityFlag_Visited;
  959. AttributeContext ac = make_attribute_context(e->Variable.link_prefix);
  960. ac.init_expr_list_count = init_expr != nullptr ? 1 : 0;
  961. DeclInfo *decl = decl_info_of_entity(e);
  962. GB_ASSERT(decl == ctx->decl);
  963. if (decl != nullptr) {
  964. check_decl_attributes(ctx, decl->attributes, var_decl_attribute, &ac);
  965. }
  966. if (ac.require_declaration) {
  967. e->flags |= EntityFlag_Require;
  968. mpmc_enqueue(&ctx->info->required_global_variable_queue, e);
  969. }
  970. e->Variable.thread_local_model = ac.thread_local_model;
  971. e->Variable.is_export = ac.is_export;
  972. e->flags &= ~EntityFlag_Static;
  973. if (ac.is_static) {
  974. error(e->token, "@(static) is not supported for global variables, nor required");
  975. }
  976. ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix);
  977. String context_name = str_lit("variable declaration");
  978. if (type_expr != nullptr) {
  979. e->type = check_type(ctx, type_expr);
  980. }
  981. if (e->type != nullptr) {
  982. if (is_type_polymorphic(base_type(e->type))) {
  983. gbString str = type_to_string(e->type);
  984. defer (gb_string_free(str));
  985. error(e->token, "Invalid use of a polymorphic type '%s' in %.*s", str, LIT(context_name));
  986. e->type = t_invalid;
  987. } else if (is_type_empty_union(e->type)) {
  988. gbString str = type_to_string(e->type);
  989. defer (gb_string_free(str));
  990. error(e->token, "An empty union '%s' cannot be instantiated in %.*s", str, LIT(context_name));
  991. e->type = t_invalid;
  992. }
  993. }
  994. if (e->Variable.is_foreign) {
  995. if (init_expr != nullptr) {
  996. error(e->token, "A foreign variable declaration cannot have a default value");
  997. }
  998. init_entity_foreign_library(ctx, e);
  999. if (is_arch_wasm()) {
  1000. error(e->token, "A foreign variable declaration are not allowed for the '%.*s' architecture", LIT(target_arch_names[build_context.metrics.arch]));
  1001. }
  1002. }
  1003. if (ac.link_name.len > 0) {
  1004. e->Variable.link_name = ac.link_name;
  1005. }
  1006. if (ac.link_section.len > 0) {
  1007. e->Variable.link_section = ac.link_section;
  1008. }
  1009. if (e->Variable.is_foreign || e->Variable.is_export) {
  1010. String name = e->token.string;
  1011. if (e->Variable.link_name.len > 0) {
  1012. name = e->Variable.link_name;
  1013. }
  1014. auto *fp = &ctx->info->foreigns;
  1015. StringHashKey key = string_hash_string(name);
  1016. Entity **found = string_map_get(fp, key);
  1017. if (found) {
  1018. Entity *f = *found;
  1019. TokenPos pos = f->token.pos;
  1020. Type *this_type = base_type(e->type);
  1021. Type *other_type = base_type(f->type);
  1022. if (!are_types_identical(this_type, other_type)) {
  1023. error(e->token,
  1024. "Foreign entity '%.*s' previously declared elsewhere with a different type\n"
  1025. "\tat %s",
  1026. LIT(name), token_pos_to_string(pos));
  1027. }
  1028. } else {
  1029. string_map_set(fp, key, e);
  1030. }
  1031. }
  1032. if (e->Variable.link_name.len > 0) {
  1033. e->flags |= EntityFlag_CustomLinkName;
  1034. }
  1035. if (init_expr == nullptr) {
  1036. if (type_expr == nullptr) {
  1037. e->type = t_invalid;
  1038. }
  1039. return;
  1040. }
  1041. Operand o = {};
  1042. check_expr_with_type_hint(ctx, &o, init_expr, e->type);
  1043. check_init_variable(ctx, e, &o, str_lit("variable declaration"));
  1044. }
  1045. void check_proc_group_decl(CheckerContext *ctx, Entity *&pg_entity, DeclInfo *d) {
  1046. GB_ASSERT(pg_entity->kind == Entity_ProcGroup);
  1047. auto *pge = &pg_entity->ProcGroup;
  1048. String proc_group_name = pg_entity->token.string;
  1049. ast_node(pg, ProcGroup, d->init_expr);
  1050. pge->entities = array_make<Entity*>(permanent_allocator(), 0, pg->args.count);
  1051. // NOTE(bill): This must be set here to prevent cycles in checking if someone
  1052. // places the entity within itself
  1053. pg_entity->type = t_invalid;
  1054. PtrSet<Entity *> entity_set = {};
  1055. ptr_set_init(&entity_set, heap_allocator(), 2*pg->args.count);
  1056. for_array(i, pg->args) {
  1057. Ast *arg = pg->args[i];
  1058. Entity *e = nullptr;
  1059. Operand o = {};
  1060. if (arg->kind == Ast_Ident) {
  1061. e = check_ident(ctx, &o, arg, nullptr, nullptr, true);
  1062. } else if (arg->kind == Ast_SelectorExpr) {
  1063. e = check_selector(ctx, &o, arg, nullptr);
  1064. }
  1065. if (e == nullptr) {
  1066. error(arg, "Expected a valid entity name in procedure group, got %.*s", LIT(ast_strings[arg->kind]));
  1067. continue;
  1068. }
  1069. if (e->kind == Entity_Variable) {
  1070. if (!is_type_proc(e->type)) {
  1071. gbString s = type_to_string(e->type);
  1072. defer (gb_string_free(s));
  1073. error(arg, "Expected a procedure, got %s", s);
  1074. continue;
  1075. }
  1076. } else if (e->kind != Entity_Procedure) {
  1077. error(arg, "Expected a procedure entity");
  1078. continue;
  1079. }
  1080. if (ptr_set_update(&entity_set, e)) {
  1081. error(arg, "Previous use of `%.*s` in procedure group", LIT(e->token.string));
  1082. continue;
  1083. }
  1084. array_add(&pge->entities, e);
  1085. }
  1086. ptr_set_destroy(&entity_set);
  1087. for_array(j, pge->entities) {
  1088. Entity *p = pge->entities[j];
  1089. if (p->type == t_invalid) {
  1090. // NOTE(bill): This invalid overload has already been handled
  1091. continue;
  1092. }
  1093. String name = p->token.string;
  1094. for (isize k = j+1; k < pge->entities.count; k++) {
  1095. Entity *q = pge->entities[k];
  1096. GB_ASSERT(p != q);
  1097. bool is_invalid = false;
  1098. TokenPos pos = q->token.pos;
  1099. if (q->type == nullptr || q->type == t_invalid) {
  1100. continue;
  1101. }
  1102. begin_error_block();
  1103. defer (end_error_block());
  1104. ProcTypeOverloadKind kind = are_proc_types_overload_safe(p->type, q->type);
  1105. bool both_have_where_clauses = false;
  1106. if (p->decl_info->proc_lit != nullptr && q->decl_info->proc_lit != nullptr) {
  1107. GB_ASSERT(p->decl_info->proc_lit->kind == Ast_ProcLit);
  1108. GB_ASSERT(q->decl_info->proc_lit->kind == Ast_ProcLit);
  1109. auto pl = &p->decl_info->proc_lit->ProcLit;
  1110. auto ql = &q->decl_info->proc_lit->ProcLit;
  1111. // Allow collisions if the procedures both have 'where' clauses and are both polymorphic
  1112. bool pw = pl->where_token.kind != Token_Invalid && is_type_polymorphic(p->type, true);
  1113. bool qw = ql->where_token.kind != Token_Invalid && is_type_polymorphic(q->type, true);
  1114. both_have_where_clauses = pw && qw;
  1115. }
  1116. if (!both_have_where_clauses) switch (kind) {
  1117. case ProcOverload_Identical:
  1118. error(p->token, "Overloaded procedure '%.*s' as the same type as another procedure in the procedure group '%.*s'", LIT(name), LIT(proc_group_name));
  1119. is_invalid = true;
  1120. break;
  1121. // case ProcOverload_CallingConvention:
  1122. // error(p->token, "Overloaded procedure '%.*s' as the same type as another procedure in the procedure group '%.*s'", LIT(name), LIT(proc_group_name));
  1123. // is_invalid = true;
  1124. // break;
  1125. case ProcOverload_ParamVariadic:
  1126. error(p->token, "Overloaded procedure '%.*s' as the same type as another procedure in the procedure group '%.*s'", LIT(name), LIT(proc_group_name));
  1127. is_invalid = true;
  1128. break;
  1129. case ProcOverload_ResultCount:
  1130. case ProcOverload_ResultTypes:
  1131. error(p->token, "Overloaded procedure '%.*s' as the same parameters but different results in the procedure group '%.*s'", LIT(name), LIT(proc_group_name));
  1132. is_invalid = true;
  1133. break;
  1134. case ProcOverload_Polymorphic:
  1135. #if 0
  1136. 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));
  1137. is_invalid = true;
  1138. #endif
  1139. break;
  1140. case ProcOverload_ParamCount:
  1141. case ProcOverload_ParamTypes:
  1142. // This is okay :)
  1143. break;
  1144. }
  1145. if (is_invalid) {
  1146. error_line("\tprevious procedure at %s\n", token_pos_to_string(pos));
  1147. q->type = t_invalid;
  1148. }
  1149. }
  1150. }
  1151. }
  1152. void check_entity_decl(CheckerContext *ctx, Entity *e, DeclInfo *d, Type *named_type) {
  1153. if (e->state == EntityState_Resolved) {
  1154. return;
  1155. }
  1156. if (e->flags & EntityFlag_Lazy) {
  1157. mutex_lock(&ctx->info->lazy_mutex);
  1158. }
  1159. String name = e->token.string;
  1160. if (e->type != nullptr || e->state != EntityState_Unresolved) {
  1161. error(e->token, "Illegal declaration cycle of `%.*s`", LIT(name));
  1162. } else {
  1163. GB_ASSERT(e->state == EntityState_Unresolved);
  1164. if (d == nullptr) {
  1165. d = decl_info_of_entity(e);
  1166. if (d == nullptr) {
  1167. // TODO(bill): Err here?
  1168. e->type = t_invalid;
  1169. e->state = EntityState_Resolved;
  1170. set_base_type(named_type, t_invalid);
  1171. goto end;
  1172. }
  1173. }
  1174. CheckerContext c = *ctx;
  1175. c.scope = d->scope;
  1176. c.decl = d;
  1177. c.type_level = 0;
  1178. e->parent_proc_decl = c.curr_proc_decl;
  1179. e->state = EntityState_InProgress;
  1180. switch (e->kind) {
  1181. case Entity_Variable:
  1182. check_global_variable_decl(&c, e, d->type_expr, d->init_expr);
  1183. break;
  1184. case Entity_Constant:
  1185. check_const_decl(&c, e, d->type_expr, d->init_expr, named_type);
  1186. break;
  1187. case Entity_TypeName: {
  1188. check_type_decl(&c, e, d->init_expr, named_type);
  1189. break;
  1190. }
  1191. case Entity_Procedure:
  1192. check_proc_decl(&c, e, d);
  1193. break;
  1194. case Entity_ProcGroup:
  1195. check_proc_group_decl(&c, e, d);
  1196. break;
  1197. }
  1198. e->state = EntityState_Resolved;
  1199. }
  1200. end:;
  1201. // NOTE(bill): Add it to the list of checked entities
  1202. if (e->flags & EntityFlag_Lazy) {
  1203. array_add(&ctx->info->entities, e);
  1204. mutex_unlock(&ctx->info->lazy_mutex);
  1205. }
  1206. }
  1207. struct ProcUsingVar {
  1208. Entity *e;
  1209. Entity *uvar;
  1210. };
  1211. void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *type, Ast *body) {
  1212. if (body == nullptr) {
  1213. return;
  1214. }
  1215. GB_ASSERT(body->kind == Ast_BlockStmt);
  1216. String proc_name = {};
  1217. if (token.kind == Token_Ident) {
  1218. proc_name = token.string;
  1219. } else {
  1220. // TODO(bill): Better name
  1221. proc_name = str_lit("(anonymous-procedure)");
  1222. }
  1223. CheckerContext new_ctx = *ctx_;
  1224. CheckerContext *ctx = &new_ctx;
  1225. GB_ASSERT(type->kind == Type_Proc);
  1226. ctx->scope = decl->scope;
  1227. ctx->decl = decl;
  1228. ctx->proc_name = proc_name;
  1229. ctx->curr_proc_decl = decl;
  1230. ctx->curr_proc_sig = type;
  1231. ctx->curr_proc_calling_convention = type->Proc.calling_convention;
  1232. if (ctx->pkg->name != "runtime") {
  1233. switch (type->Proc.calling_convention) {
  1234. case ProcCC_None:
  1235. error(body, "Procedures with the calling convention \"none\" are not allowed a body");
  1236. break;
  1237. }
  1238. }
  1239. ast_node(bs, BlockStmt, body);
  1240. Array<ProcUsingVar> using_entities = {};
  1241. using_entities.allocator = heap_allocator();
  1242. defer (array_free(&using_entities));
  1243. {
  1244. if (type->Proc.param_count > 0) {
  1245. TypeTuple *params = &type->Proc.params->Tuple;
  1246. for_array(i, params->variables) {
  1247. Entity *e = params->variables[i];
  1248. if (e->kind != Entity_Variable) {
  1249. continue;
  1250. }
  1251. if (!(e->flags & EntityFlag_Using)) {
  1252. continue;
  1253. }
  1254. bool is_value = (e->flags & EntityFlag_Value) != 0 && !is_type_pointer(e->type);
  1255. String name = e->token.string;
  1256. Type *t = base_type(type_deref(e->type));
  1257. if (t->kind == Type_Struct) {
  1258. Scope *scope = t->Struct.scope;
  1259. GB_ASSERT(scope != nullptr);
  1260. MUTEX_GUARD_BLOCK(scope->mutex) for_array(i, scope->elements.entries) {
  1261. Entity *f = scope->elements.entries[i].value;
  1262. if (f->kind == Entity_Variable) {
  1263. Entity *uvar = alloc_entity_using_variable(e, f->token, f->type, nullptr);
  1264. if (is_value) uvar->flags |= EntityFlag_Value;
  1265. ProcUsingVar puv = {e, uvar};
  1266. array_add(&using_entities, puv);
  1267. }
  1268. }
  1269. } else {
  1270. error(e->token, "'using' can only be applied to variables of type struct");
  1271. break;
  1272. }
  1273. }
  1274. }
  1275. }
  1276. MUTEX_GUARD_BLOCK(ctx->scope->mutex) for_array(i, using_entities) {
  1277. Entity *e = using_entities[i].e;
  1278. Entity *uvar = using_entities[i].uvar;
  1279. Entity *prev = scope_insert(ctx->scope, uvar, false);
  1280. if (prev != nullptr) {
  1281. error(e->token, "Namespace collision while 'using' procedure argument '%.*s' of: %.*s", LIT(e->token.string), LIT(prev->token.string));
  1282. error_line("%.*s != %.*s\n", LIT(uvar->token.string), LIT(prev->token.string));
  1283. break;
  1284. }
  1285. }
  1286. bool where_clause_ok = evaluate_where_clauses(ctx, nullptr, decl->scope, &decl->proc_lit->ProcLit.where_clauses, !decl->where_clauses_evaluated);
  1287. if (!where_clause_ok) {
  1288. // NOTE(bill, 2019-08-31): Don't check the body as the where clauses failed
  1289. return;
  1290. }
  1291. check_open_scope(ctx, body);
  1292. {
  1293. for_array(i, using_entities) {
  1294. Entity *uvar = using_entities[i].uvar;
  1295. Entity *prev = scope_insert(ctx->scope, uvar);
  1296. gb_unused(prev);
  1297. // NOTE(bill): Don't err here
  1298. }
  1299. check_stmt_list(ctx, bs->stmts, Stmt_CheckScopeDecls);
  1300. for_array(i, bs->stmts) {
  1301. Ast *stmt = bs->stmts[i];
  1302. if (stmt->kind == Ast_ValueDecl) {
  1303. ast_node(vd, ValueDecl, stmt);
  1304. for_array(j, vd->names) {
  1305. Ast *name = vd->names[j];
  1306. if (!is_blank_ident(name)) {
  1307. if (name->kind == Ast_Ident) {
  1308. GB_ASSERT(name->Ident.entity != nullptr);
  1309. }
  1310. }
  1311. }
  1312. }
  1313. }
  1314. if (type->Proc.result_count > 0) {
  1315. if (!check_is_terminating(body, str_lit(""))) {
  1316. if (token.kind == Token_Ident) {
  1317. error(bs->close, "Missing return statement at the end of the procedure '%.*s'", LIT(token.string));
  1318. } else {
  1319. // NOTE(bill): Anonymous procedure (lambda)
  1320. error(bs->close, "Missing return statement at the end of the procedure");
  1321. }
  1322. }
  1323. } else if (type->Proc.diverging) {
  1324. if (!check_is_terminating(body, str_lit(""))) {
  1325. if (token.kind == Token_Ident) {
  1326. error(bs->close, "Missing diverging call at the end of the procedure '%.*s'", LIT(token.string));
  1327. } else {
  1328. // NOTE(bill): Anonymous procedure (lambda)
  1329. error(bs->close, "Missing diverging call at the end of the procedure");
  1330. }
  1331. }
  1332. }
  1333. }
  1334. check_close_scope(ctx);
  1335. check_scope_usage(ctx->checker, ctx->scope);
  1336. if (decl->parent != nullptr) {
  1337. Scope *ps = decl->parent->scope;
  1338. if (ps->flags & (ScopeFlag_File & ScopeFlag_Pkg & ScopeFlag_Global)) {
  1339. return;
  1340. } else {
  1341. mutex_lock(&ctx->info->deps_mutex);
  1342. // NOTE(bill): Add the dependencies from the procedure literal (lambda)
  1343. // But only at the procedure level
  1344. for_array(i, decl->deps.entries) {
  1345. Entity *e = decl->deps.entries[i].ptr;
  1346. ptr_set_add(&decl->parent->deps, e);
  1347. }
  1348. for_array(i, decl->type_info_deps.entries) {
  1349. Type *t = decl->type_info_deps.entries[i].ptr;
  1350. ptr_set_add(&decl->parent->type_info_deps, t);
  1351. }
  1352. mutex_unlock(&ctx->info->deps_mutex);
  1353. }
  1354. }
  1355. }