checker.cpp 65 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344
  1. #include "exact_value.cpp"
  2. #include "entity.cpp"
  3. enum ExprKind {
  4. Expr_Expr,
  5. Expr_Stmt,
  6. };
  7. // Statements and Declarations
  8. enum StmtFlag {
  9. Stmt_BreakAllowed = 1<<0,
  10. Stmt_ContinueAllowed = 1<<1,
  11. Stmt_FallthroughAllowed = 1<<2,
  12. Stmt_CheckScopeDecls = 1<<5,
  13. };
  14. struct BuiltinProc {
  15. String name;
  16. isize arg_count;
  17. bool variadic;
  18. ExprKind kind;
  19. };
  20. enum BuiltinProcId {
  21. BuiltinProc_Invalid,
  22. BuiltinProc_len,
  23. BuiltinProc_cap,
  24. BuiltinProc_new,
  25. BuiltinProc_make,
  26. BuiltinProc_free,
  27. BuiltinProc_reserve,
  28. BuiltinProc_clear,
  29. BuiltinProc_append,
  30. BuiltinProc_delete,
  31. BuiltinProc_size_of,
  32. BuiltinProc_align_of,
  33. BuiltinProc_offset_of,
  34. BuiltinProc_type_of,
  35. BuiltinProc_type_info,
  36. BuiltinProc_compile_assert,
  37. BuiltinProc_copy,
  38. BuiltinProc_swizzle,
  39. BuiltinProc_complex,
  40. BuiltinProc_real,
  41. BuiltinProc_imag,
  42. BuiltinProc_conj,
  43. BuiltinProc_slice_ptr,
  44. BuiltinProc_slice_to_bytes,
  45. BuiltinProc_expand_to_tuple,
  46. BuiltinProc_min,
  47. BuiltinProc_max,
  48. BuiltinProc_abs,
  49. BuiltinProc_clamp,
  50. BuiltinProc_transmute,
  51. BuiltinProc_DIRECTIVE, // NOTE(bill): This is used for specialized hash-prefixed procedures
  52. BuiltinProc_COUNT,
  53. };
  54. gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
  55. {STR_LIT(""), 0, false, Expr_Stmt},
  56. {STR_LIT("len"), 1, false, Expr_Expr},
  57. {STR_LIT("cap"), 1, false, Expr_Expr},
  58. {STR_LIT("new"), 1, false, Expr_Expr},
  59. {STR_LIT("make"), 1, true, Expr_Expr},
  60. {STR_LIT("free"), 1, false, Expr_Stmt},
  61. {STR_LIT("reserve"), 2, false, Expr_Stmt},
  62. {STR_LIT("clear"), 1, false, Expr_Stmt},
  63. {STR_LIT("append"), 1, true, Expr_Expr},
  64. {STR_LIT("delete"), 2, false, Expr_Stmt},
  65. {STR_LIT("size_of"), 1, false, Expr_Expr},
  66. {STR_LIT("align_of"), 1, false, Expr_Expr},
  67. {STR_LIT("offset_of"), 2, false, Expr_Expr},
  68. {STR_LIT("type_of_val"), 1, false, Expr_Expr},
  69. {STR_LIT("type_info"), 1, false, Expr_Expr},
  70. {STR_LIT("compile_assert"), 1, false, Expr_Expr},
  71. {STR_LIT("copy"), 2, false, Expr_Expr},
  72. {STR_LIT("swizzle"), 1, true, Expr_Expr},
  73. {STR_LIT("complex"), 2, false, Expr_Expr},
  74. {STR_LIT("real"), 1, false, Expr_Expr},
  75. {STR_LIT("imag"), 1, false, Expr_Expr},
  76. {STR_LIT("conj"), 1, false, Expr_Expr},
  77. {STR_LIT("slice_ptr"), 2, true, Expr_Expr},
  78. {STR_LIT("slice_to_bytes"), 1, false, Expr_Stmt},
  79. {STR_LIT("expand_to_tuple"), 1, false, Expr_Expr},
  80. {STR_LIT("min"), 2, false, Expr_Expr},
  81. {STR_LIT("max"), 2, false, Expr_Expr},
  82. {STR_LIT("abs"), 1, false, Expr_Expr},
  83. {STR_LIT("clamp"), 3, false, Expr_Expr},
  84. {STR_LIT("transmute"), 2, false, Expr_Expr},
  85. {STR_LIT(""), 0, true, Expr_Expr}, // DIRECTIVE
  86. };
  87. #include "types.cpp"
  88. enum AddressingMode {
  89. Addressing_Invalid, // invalid addressing mode
  90. Addressing_NoValue, // no value (void in C)
  91. Addressing_Value, // computed value (rvalue)
  92. Addressing_Immutable, // immutable computed value (const rvalue)
  93. Addressing_Variable, // addressable variable (lvalue)
  94. Addressing_Constant, // constant
  95. Addressing_Type, // type
  96. Addressing_Builtin, // built-in procedure
  97. Addressing_Overload, // overloaded procedure
  98. Addressing_MapIndex, // map index expression -
  99. // lhs: acts like a Variable
  100. // rhs: acts like OptionalOk
  101. Addressing_OptionalOk, // rhs: acts like a value with an optional boolean part (for existence check)
  102. };
  103. // Operand is used as an intermediate value whilst checking
  104. // Operands store an addressing mode, the expression being evaluated,
  105. // its type and node, and other specific information for certain
  106. // addressing modes
  107. // Its zero-value is a valid "invalid operand"
  108. struct Operand {
  109. AddressingMode mode;
  110. Type * type;
  111. ExactValue value;
  112. AstNode * expr;
  113. BuiltinProcId builtin_id;
  114. isize overload_count;
  115. Entity ** overload_entities;
  116. };
  117. struct TypeAndValue {
  118. AddressingMode mode;
  119. Type * type;
  120. ExactValue value;
  121. };
  122. bool is_operand_value(Operand o) {
  123. switch (o.mode) {
  124. case Addressing_Value:
  125. case Addressing_Variable:
  126. case Addressing_Immutable:
  127. case Addressing_Constant:
  128. case Addressing_MapIndex:
  129. return true;
  130. }
  131. return false;
  132. }
  133. bool is_operand_nil(Operand o) {
  134. return o.mode == Addressing_Value && o.type == t_untyped_nil;
  135. }
  136. struct BlockLabel {
  137. String name;
  138. AstNode *label; // AstNode_Label;
  139. };
  140. // DeclInfo is used to store information of certain declarations to allow for "any order" usage
  141. struct DeclInfo {
  142. DeclInfo * parent; // NOTE(bill): only used for procedure literals at the moment
  143. Scope * scope;
  144. Entity ** entities;
  145. isize entity_count;
  146. AstNode * type_expr;
  147. AstNode * init_expr;
  148. AstNode * proc_decl; // AstNode_ProcDecl
  149. Map<bool> deps; // Key: Entity *
  150. Array<BlockLabel> labels;
  151. };
  152. // ProcedureInfo stores the information needed for checking a procedure
  153. struct ProcedureInfo {
  154. AstFile * file;
  155. Token token;
  156. DeclInfo * decl;
  157. Type * type; // Type_Procedure
  158. AstNode * body; // AstNode_BlockStmt
  159. u32 tags;
  160. };
  161. // ExprInfo stores information used for "untyped" expressions
  162. struct ExprInfo {
  163. bool is_lhs; // Debug info
  164. AddressingMode mode;
  165. Type * type; // Type_Basic
  166. ExactValue value;
  167. };
  168. ExprInfo make_expr_info(bool is_lhs, AddressingMode mode, Type *type, ExactValue value) {
  169. ExprInfo ei = {is_lhs, mode, type, value};
  170. return ei;
  171. }
  172. struct Scope {
  173. Scope * parent;
  174. Scope * prev, *next;
  175. Scope * first_child;
  176. Scope * last_child;
  177. Map<Entity *> elements; // Key: String
  178. Map<bool> implicit; // Key: Entity *
  179. Array<Scope *> shared;
  180. Array<Scope *> imported;
  181. bool is_proc;
  182. bool is_global;
  183. bool is_file;
  184. bool is_init;
  185. bool has_been_imported; // This is only applicable to file scopes
  186. AstFile * file;
  187. };
  188. gb_global Scope *universal_scope = NULL;
  189. struct DelayedDecl {
  190. Scope * parent;
  191. AstNode *decl;
  192. };
  193. struct CheckerFileNode {
  194. i32 id;
  195. Array<i32> wheres;
  196. Array<i32> whats;
  197. i32 score; // Higher the score, the better
  198. };
  199. struct CheckerContext {
  200. Scope * file_scope;
  201. Scope * scope;
  202. DeclInfo * decl;
  203. u32 stmt_state_flags;
  204. bool in_defer; // TODO(bill): Actually handle correctly
  205. String proc_name;
  206. Type * type_hint;
  207. DeclInfo * curr_proc_decl;
  208. AstNode * curr_foreign_library;
  209. };
  210. // CheckerInfo stores all the symbol information for a type-checked program
  211. struct CheckerInfo {
  212. Map<TypeAndValue> types; // Key: AstNode * | Expression -> Type (and value)
  213. Map<Entity *> definitions; // Key: AstNode * | Identifier -> Entity
  214. Map<Entity *> uses; // Key: AstNode * | Identifier -> Entity
  215. Map<Scope *> scopes; // Key: AstNode * | Node -> Scope
  216. Map<ExprInfo> untyped; // Key: AstNode * | Expression -> ExprInfo
  217. Map<Entity *> implicits; // Key: AstNode *
  218. Map<DeclInfo *> entities; // Key: Entity *
  219. Map<Entity *> foreigns; // Key: String
  220. Map<AstFile *> files; // Key: String (full path)
  221. Map<isize> type_info_map; // Key: Type *
  222. isize type_info_count;
  223. };
  224. struct Checker {
  225. Parser * parser;
  226. CheckerInfo info;
  227. AstFile * curr_ast_file;
  228. Scope * global_scope;
  229. // NOTE(bill): Procedures to check
  230. Map<ProcedureInfo> procs; // Key: DeclInfo *
  231. Array<DelayedDecl> delayed_imports;
  232. Array<DelayedDecl> delayed_foreign_libraries;
  233. Array<CheckerFileNode> file_nodes;
  234. gbArena arena;
  235. gbArena tmp_arena;
  236. gbAllocator allocator;
  237. gbAllocator tmp_allocator;
  238. CheckerContext context;
  239. Array<Type *> proc_stack;
  240. bool done_preload;
  241. };
  242. HashKey hash_node (AstNode *node) { return hash_ptr_and_id(node, 0); }
  243. HashKey hash_ast_file (AstFile *file) { return hash_pointer(file); }
  244. HashKey hash_entity (Entity *e) { return hash_pointer(e); }
  245. HashKey hash_type (Type *t) { return hash_pointer(t); }
  246. HashKey hash_decl_info(DeclInfo *decl) { return hash_pointer(decl); }
  247. // CheckerInfo API
  248. TypeAndValue type_and_value_of_expr (CheckerInfo *i, AstNode *expr);
  249. Type * type_of_expr (CheckerInfo *i, AstNode *expr);
  250. Entity * entity_of_ident (CheckerInfo *i, AstNode *identifier);
  251. Entity * implicit_entity_of_node(CheckerInfo *i, AstNode *clause);
  252. Scope * scope_of_node (CheckerInfo *i, AstNode *node);
  253. DeclInfo * decl_info_of_ident (CheckerInfo *i, AstNode *ident);
  254. DeclInfo * decl_info_of_entity (CheckerInfo *i, Entity * e);
  255. AstFile * ast_file_of_filename (CheckerInfo *i, String filename);
  256. // IMPORTANT: Only to use once checking is done
  257. isize type_info_index (CheckerInfo *i, Type * type);
  258. Entity *current_scope_lookup_entity(Scope *s, String name);
  259. Entity *scope_lookup_entity (Scope *s, String name);
  260. void scope_lookup_parent_entity (Scope *s, String name, Scope **scope_, Entity **entity_);
  261. Entity *scope_insert_entity (Scope *s, Entity *entity);
  262. ExprInfo *check_get_expr_info(CheckerInfo *i, AstNode *expr);
  263. void check_set_expr_info(CheckerInfo *i, AstNode *expr, ExprInfo info);
  264. void check_remove_expr_info(CheckerInfo *i, AstNode *expr);
  265. void add_untyped(CheckerInfo *i, AstNode *expression, bool lhs, AddressingMode mode, Type *basic_type, ExactValue value);
  266. void add_type_and_value(CheckerInfo *i, AstNode *expression, AddressingMode mode, Type *type, ExactValue value);
  267. void add_entity_use(Checker *c, AstNode *identifier, Entity *entity);
  268. void add_implicit_entity(Checker *c, AstNode *node, Entity *e);
  269. void add_entity_and_decl_info(Checker *c, AstNode *identifier, Entity *e, DeclInfo *d);
  270. void add_implicit_entity(Checker *c, AstNode *node, Entity *e);
  271. void init_declaration_info(DeclInfo *d, Scope *scope, DeclInfo *parent) {
  272. d->parent = parent;
  273. d->scope = scope;
  274. map_init(&d->deps, heap_allocator());
  275. array_init(&d->labels, heap_allocator());
  276. }
  277. DeclInfo *make_declaration_info(gbAllocator a, Scope *scope, DeclInfo *parent) {
  278. DeclInfo *d = gb_alloc_item(a, DeclInfo);
  279. init_declaration_info(d, scope, parent);
  280. return d;
  281. }
  282. void destroy_declaration_info(DeclInfo *d) {
  283. map_destroy(&d->deps);
  284. }
  285. bool decl_info_has_init(DeclInfo *d) {
  286. if (d->init_expr != NULL) {
  287. return true;
  288. }
  289. if (d->proc_decl != NULL) {
  290. switch (d->proc_decl->kind) {
  291. case_ast_node(pd, ProcDecl, d->proc_decl);
  292. if (pd->body != NULL) {
  293. return true;
  294. }
  295. case_end;
  296. }
  297. }
  298. return false;
  299. }
  300. Scope *make_scope(Scope *parent, gbAllocator allocator) {
  301. Scope *s = gb_alloc_item(allocator, Scope);
  302. s->parent = parent;
  303. map_init(&s->elements, heap_allocator());
  304. map_init(&s->implicit, heap_allocator());
  305. array_init(&s->shared, heap_allocator());
  306. array_init(&s->imported, heap_allocator());
  307. if (parent != NULL && parent != universal_scope) {
  308. DLIST_APPEND(parent->first_child, parent->last_child, s);
  309. }
  310. return s;
  311. }
  312. void destroy_scope(Scope *scope) {
  313. for_array(i, scope->elements.entries) {
  314. Entity *e =scope->elements.entries[i].value;
  315. if (e->kind == Entity_Variable) {
  316. if (!(e->flags & EntityFlag_Used)) {
  317. #if 0
  318. warning(e->token, "Unused variable `%.*s`", LIT(e->token.string));
  319. #endif
  320. }
  321. }
  322. }
  323. for (Scope *child = scope->first_child; child != NULL; child = child->next) {
  324. destroy_scope(child);
  325. }
  326. map_destroy(&scope->elements);
  327. map_destroy(&scope->implicit);
  328. array_free(&scope->shared);
  329. array_free(&scope->imported);
  330. // NOTE(bill): No need to free scope as it "should" be allocated in an arena (except for the global scope)
  331. }
  332. void add_scope(Checker *c, AstNode *node, Scope *scope) {
  333. GB_ASSERT(node != NULL);
  334. GB_ASSERT(scope != NULL);
  335. map_set(&c->info.scopes, hash_node(node), scope);
  336. }
  337. void check_open_scope(Checker *c, AstNode *node) {
  338. GB_ASSERT(node != NULL);
  339. node = unparen_expr(node);
  340. GB_ASSERT(node->kind == AstNode_Invalid ||
  341. is_ast_node_stmt(node) ||
  342. is_ast_node_type(node));
  343. Scope *scope = make_scope(c->context.scope, c->allocator);
  344. add_scope(c, node, scope);
  345. if (node->kind == AstNode_ProcType) {
  346. scope->is_proc = true;
  347. }
  348. c->context.scope = scope;
  349. c->context.stmt_state_flags |= StmtStateFlag_bounds_check;
  350. }
  351. void check_close_scope(Checker *c) {
  352. c->context.scope = c->context.scope->parent;
  353. }
  354. Entity *current_scope_lookup_entity(Scope *s, String name) {
  355. HashKey key = hash_string(name);
  356. Entity **found = map_get(&s->elements, key);
  357. if (found) {
  358. return *found;
  359. }
  360. for_array(i, s->shared) {
  361. Scope *shared = s->shared[i];
  362. Entity **found = map_get(&shared->elements, key);
  363. if (found) {
  364. Entity *e = *found;
  365. if (e->kind == Entity_Variable &&
  366. !e->scope->is_file &&
  367. !e->scope->is_global) {
  368. continue;
  369. }
  370. if (e->scope != shared) {
  371. // Do not return imported entities even #include ones
  372. continue;
  373. }
  374. return e;
  375. }
  376. }
  377. return NULL;
  378. }
  379. void scope_lookup_parent_entity(Scope *scope, String name, Scope **scope_, Entity **entity_) {
  380. bool gone_thru_proc = false;
  381. bool gone_thru_file = false;
  382. HashKey key = hash_string(name);
  383. for (Scope *s = scope; s != NULL; s = s->parent) {
  384. Entity **found = map_get(&s->elements, key);
  385. if (found) {
  386. Entity *e = *found;
  387. if (gone_thru_proc) {
  388. // if (e->kind == Entity_Label) {
  389. // continue;
  390. // }
  391. // if (e->kind == Entity_Variable &&
  392. // !e->scope->is_file &&
  393. // !e->scope->is_global) {
  394. // continue;
  395. // }
  396. }
  397. if (entity_) *entity_ = e;
  398. if (scope_) *scope_ = s;
  399. return;
  400. }
  401. if (s->is_proc) {
  402. gone_thru_proc = true;
  403. } else {
  404. // Check shared scopes - i.e. other files @ global scope
  405. for_array(i, s->shared) {
  406. Scope *shared = s->shared[i];
  407. Entity **found = map_get(&shared->elements, key);
  408. if (found) {
  409. Entity *e = *found;
  410. if (e->kind == Entity_Variable &&
  411. !e->scope->is_file &&
  412. !e->scope->is_global) {
  413. continue;
  414. }
  415. if (e->scope != shared) {
  416. // Do not return imported entities even #include ones
  417. continue;
  418. }
  419. if ((e->kind == Entity_ImportName ||
  420. e->kind == Entity_LibraryName)
  421. && gone_thru_file) {
  422. continue;
  423. }
  424. if (entity_) *entity_ = e;
  425. if (scope_) *scope_ = shared;
  426. return;
  427. }
  428. }
  429. }
  430. if (s->is_file) {
  431. gone_thru_file = true;
  432. }
  433. }
  434. if (entity_) *entity_ = NULL;
  435. if (scope_) *scope_ = NULL;
  436. }
  437. Entity *scope_lookup_entity(Scope *s, String name) {
  438. Entity *entity = NULL;
  439. scope_lookup_parent_entity(s, name, NULL, &entity);
  440. return entity;
  441. }
  442. Entity *scope_insert_entity(Scope *s, Entity *entity) {
  443. String name = entity->token.string;
  444. HashKey key = hash_string(name);
  445. Entity **found = map_get(&s->elements, key);
  446. #if 1
  447. // IMPORTANT NOTE(bill): Procedure overloading code
  448. Entity *prev = NULL;
  449. if (found) {
  450. prev = *found;
  451. if (prev->kind != Entity_Procedure ||
  452. entity->kind != Entity_Procedure) {
  453. return prev;
  454. }
  455. }
  456. if (prev != NULL &&
  457. entity->kind == Entity_Procedure) {
  458. if (s->is_global) {
  459. return prev;
  460. }
  461. multi_map_insert(&s->elements, key, entity);
  462. } else {
  463. map_set(&s->elements, key, entity);
  464. }
  465. #else
  466. if (found) {
  467. return *found;
  468. }
  469. map_set(&s->elements, key, entity);
  470. #endif
  471. if (entity->scope == NULL) {
  472. entity->scope = s;
  473. }
  474. return NULL;
  475. }
  476. void check_scope_usage(Checker *c, Scope *scope) {
  477. // TODO(bill): Use this?
  478. }
  479. void add_dependency(DeclInfo *d, Entity *e) {
  480. map_set(&d->deps, hash_entity(e), cast(bool)true);
  481. }
  482. void add_declaration_dependency(Checker *c, Entity *e) {
  483. if (e == NULL) {
  484. return;
  485. }
  486. if (c->context.decl != NULL) {
  487. DeclInfo **found = map_get(&c->info.entities, hash_entity(e));
  488. if (found) {
  489. add_dependency(c->context.decl, e);
  490. }
  491. }
  492. }
  493. Entity *add_global_entity(Entity *entity) {
  494. String name = entity->token.string;
  495. if (gb_memchr(name.text, ' ', name.len)) {
  496. return entity; // NOTE(bill): `untyped thing`
  497. }
  498. if (scope_insert_entity(universal_scope, entity)) {
  499. compiler_error("double declaration");
  500. }
  501. return entity;
  502. }
  503. void add_global_constant(gbAllocator a, String name, Type *type, ExactValue value) {
  504. Entity *entity = alloc_entity(a, Entity_Constant, NULL, make_token_ident(name), type);
  505. entity->Constant.value = value;
  506. add_global_entity(entity);
  507. }
  508. void add_global_string_constant(gbAllocator a, String name, String value) {
  509. add_global_constant(a, name, t_untyped_string, exact_value_string(value));
  510. }
  511. void init_universal_scope(void) {
  512. BuildContext *bc = &build_context;
  513. // NOTE(bill): No need to free these
  514. gbAllocator a = heap_allocator();
  515. universal_scope = make_scope(NULL, a);
  516. // Types
  517. for (isize i = 0; i < gb_count_of(basic_types); i++) {
  518. add_global_entity(make_entity_type_name(a, NULL, make_token_ident(basic_types[i].Basic.name), &basic_types[i]));
  519. }
  520. #if 1
  521. // for (isize i = 0; i < gb_count_of(basic_type_aliases); i++) {
  522. // add_global_entity(make_entity_type_name(a, NULL, make_token_ident(basic_type_aliases[i].Basic.name), &basic_type_aliases[i]));
  523. // }
  524. #else
  525. {
  526. t_byte = add_global_type_alias(a, str_lit("byte"), &basic_types[Basic_u8]);
  527. }
  528. #endif
  529. // Constants
  530. add_global_constant(a, str_lit("true"), t_untyped_bool, exact_value_bool(true));
  531. add_global_constant(a, str_lit("false"), t_untyped_bool, exact_value_bool(false));
  532. add_global_entity(make_entity_nil(a, str_lit("nil"), t_untyped_nil));
  533. add_global_entity(make_entity_library_name(a, universal_scope,
  534. make_token_ident(str_lit("__llvm_core")), t_invalid,
  535. str_lit(""), str_lit("__llvm_core")));
  536. // TODO(bill): Set through flags in the compiler
  537. add_global_string_constant(a, str_lit("ODIN_OS"), bc->ODIN_OS);
  538. add_global_string_constant(a, str_lit("ODIN_ARCH"), bc->ODIN_ARCH);
  539. add_global_string_constant(a, str_lit("ODIN_ENDIAN"), bc->ODIN_ENDIAN);
  540. add_global_string_constant(a, str_lit("ODIN_VENDOR"), bc->ODIN_VENDOR);
  541. add_global_string_constant(a, str_lit("ODIN_VERSION"), bc->ODIN_VERSION);
  542. add_global_string_constant(a, str_lit("ODIN_ROOT"), bc->ODIN_ROOT);
  543. // Builtin Procedures
  544. for (isize i = 0; i < gb_count_of(builtin_procs); i++) {
  545. BuiltinProcId id = cast(BuiltinProcId)i;
  546. String name = builtin_procs[i].name;
  547. if (name != "") {
  548. Entity *entity = alloc_entity(a, Entity_Builtin, NULL, make_token_ident(name), t_invalid);
  549. entity->Builtin.id = id;
  550. add_global_entity(entity);
  551. }
  552. }
  553. t_u8_ptr = make_type_pointer(a, t_u8);
  554. t_int_ptr = make_type_pointer(a, t_int);
  555. t_i64_ptr = make_type_pointer(a, t_i64);
  556. t_i128_ptr = make_type_pointer(a, t_i128);
  557. t_f64_ptr = make_type_pointer(a, t_f64);
  558. t_u8_slice = make_type_slice(a, t_u8);
  559. t_string_slice = make_type_slice(a, t_string);
  560. }
  561. void init_checker_info(CheckerInfo *i) {
  562. gbAllocator a = heap_allocator();
  563. map_init(&i->types, a);
  564. map_init(&i->definitions, a);
  565. map_init(&i->uses, a);
  566. map_init(&i->scopes, a);
  567. map_init(&i->entities, a);
  568. map_init(&i->untyped, a);
  569. map_init(&i->foreigns, a);
  570. map_init(&i->implicits, a);
  571. map_init(&i->type_info_map, a);
  572. map_init(&i->files, a);
  573. i->type_info_count = 0;
  574. }
  575. void destroy_checker_info(CheckerInfo *i) {
  576. map_destroy(&i->types);
  577. map_destroy(&i->definitions);
  578. map_destroy(&i->uses);
  579. map_destroy(&i->scopes);
  580. map_destroy(&i->entities);
  581. map_destroy(&i->untyped);
  582. map_destroy(&i->foreigns);
  583. map_destroy(&i->implicits);
  584. map_destroy(&i->type_info_map);
  585. map_destroy(&i->files);
  586. }
  587. void init_checker(Checker *c, Parser *parser) {
  588. if (global_error_collector.count > 0) {
  589. gb_exit(1);
  590. }
  591. BuildContext *bc = &build_context;
  592. gbAllocator a = heap_allocator();
  593. c->parser = parser;
  594. init_checker_info(&c->info);
  595. array_init(&c->proc_stack, a);
  596. map_init(&c->procs, a);
  597. array_init(&c->delayed_imports, a);
  598. array_init(&c->delayed_foreign_libraries, a);
  599. array_init(&c->file_nodes, a);
  600. for_array(i, parser->files) {
  601. AstFile *file = &parser->files[i];
  602. CheckerFileNode node = {};
  603. node.id = file->id;
  604. array_init(&node.whats, a);
  605. array_init(&node.wheres, a);
  606. array_add(&c->file_nodes, node);
  607. }
  608. // NOTE(bill): Is this big enough or too small?
  609. isize item_size = gb_max3(gb_size_of(Entity), gb_size_of(Type), gb_size_of(Scope));
  610. isize total_token_count = 0;
  611. for_array(i, c->parser->files) {
  612. AstFile *f = &c->parser->files[i];
  613. total_token_count += f->tokens.count;
  614. }
  615. isize arena_size = 2 * item_size * total_token_count;
  616. gb_arena_init_from_allocator(&c->arena, a, arena_size);
  617. gb_arena_init_from_allocator(&c->tmp_arena, a, arena_size);
  618. c->allocator = gb_arena_allocator(&c->arena);
  619. c->tmp_allocator = gb_arena_allocator(&c->tmp_arena);
  620. c->global_scope = make_scope(universal_scope, c->allocator);
  621. c->context.scope = c->global_scope;
  622. }
  623. void destroy_checker(Checker *c) {
  624. destroy_checker_info(&c->info);
  625. destroy_scope(c->global_scope);
  626. array_free(&c->proc_stack);
  627. map_destroy(&c->procs);
  628. array_free(&c->delayed_imports);
  629. array_free(&c->delayed_foreign_libraries);
  630. array_free(&c->file_nodes);
  631. gb_arena_free(&c->arena);
  632. }
  633. Entity *entity_of_ident(CheckerInfo *i, AstNode *identifier) {
  634. if (identifier->kind == AstNode_Ident) {
  635. Entity **found = map_get(&i->definitions, hash_node(identifier));
  636. if (found) {
  637. return *found;
  638. }
  639. found = map_get(&i->uses, hash_node(identifier));
  640. if (found) {
  641. return *found;
  642. }
  643. }
  644. return NULL;
  645. }
  646. TypeAndValue type_and_value_of_expr(CheckerInfo *i, AstNode *expr) {
  647. TypeAndValue result = {};
  648. TypeAndValue *found = map_get(&i->types, hash_node(expr));
  649. if (found) result = *found;
  650. return result;
  651. }
  652. Type *type_of_expr(CheckerInfo *i, AstNode *expr) {
  653. TypeAndValue tav = type_and_value_of_expr(i, expr);
  654. if (tav.mode != Addressing_Invalid) {
  655. return tav.type;
  656. }
  657. if (expr->kind == AstNode_Ident) {
  658. Entity *entity = entity_of_ident(i, expr);
  659. if (entity) {
  660. return entity->type;
  661. }
  662. }
  663. return NULL;
  664. }
  665. Entity *implicit_entity_of_node(CheckerInfo *i, AstNode *clause) {
  666. Entity **found = map_get(&i->implicits, hash_node(clause));
  667. if (found != NULL) {
  668. return *found;
  669. }
  670. return NULL;
  671. }
  672. bool is_entity_implicitly_imported(Entity *import_name, Entity *e) {
  673. GB_ASSERT(import_name->kind == Entity_ImportName);
  674. return map_get(&import_name->ImportName.scope->implicit, hash_entity(e)) != NULL;
  675. }
  676. DeclInfo *decl_info_of_entity(CheckerInfo *i, Entity *e) {
  677. if (e != NULL) {
  678. DeclInfo **found = map_get(&i->entities, hash_entity(e));
  679. if (found != NULL) {
  680. return *found;
  681. }
  682. }
  683. return NULL;
  684. }
  685. DeclInfo *decl_info_of_ident(CheckerInfo *i, AstNode *ident) {
  686. return decl_info_of_entity(i, entity_of_ident(i, ident));
  687. }
  688. AstFile *ast_file_of_filename(CheckerInfo *i, String filename) {
  689. AstFile **found = map_get(&i->files, hash_string(filename));
  690. if (found != NULL) {
  691. return *found;
  692. }
  693. return NULL;
  694. }
  695. Scope *scope_of_node(CheckerInfo *i, AstNode *node) {
  696. Scope **found = map_get(&i->scopes, hash_node(node));
  697. if (found) {
  698. return *found;
  699. }
  700. return NULL;
  701. }
  702. ExprInfo *check_get_expr_info(CheckerInfo *i, AstNode *expr) {
  703. return map_get(&i->untyped, hash_node(expr));
  704. }
  705. void check_set_expr_info(CheckerInfo *i, AstNode *expr, ExprInfo info) {
  706. map_set(&i->untyped, hash_node(expr), info);
  707. }
  708. void check_remove_expr_info(CheckerInfo *i, AstNode *expr) {
  709. map_remove(&i->untyped, hash_node(expr));
  710. }
  711. isize type_info_index(CheckerInfo *info, Type *type) {
  712. type = default_type(type);
  713. isize entry_index = -1;
  714. HashKey key = hash_type(type);
  715. isize *found_entry_index = map_get(&info->type_info_map, key);
  716. if (found_entry_index) {
  717. entry_index = *found_entry_index;
  718. }
  719. if (entry_index < 0) {
  720. // NOTE(bill): Do manual search
  721. // TODO(bill): This is O(n) and can be very slow
  722. for_array(i, info->type_info_map.entries){
  723. auto *e = &info->type_info_map.entries[i];
  724. Type *prev_type = cast(Type *)e->key.ptr;
  725. if (are_types_identical(prev_type, type)) {
  726. entry_index = e->value;
  727. // NOTE(bill): Add it to the search map
  728. map_set(&info->type_info_map, key, entry_index);
  729. break;
  730. }
  731. }
  732. }
  733. if (entry_index < 0) {
  734. compiler_error("TypeInfo for `%s` could not be found", type_to_string(type));
  735. }
  736. return entry_index;
  737. }
  738. void add_untyped(CheckerInfo *i, AstNode *expression, bool lhs, AddressingMode mode, Type *basic_type, ExactValue value) {
  739. map_set(&i->untyped, hash_node(expression), make_expr_info(lhs, mode, basic_type, value));
  740. }
  741. void add_type_and_value(CheckerInfo *i, AstNode *expression, AddressingMode mode, Type *type, ExactValue value) {
  742. if (expression == NULL) {
  743. return;
  744. }
  745. if (mode == Addressing_Invalid) {
  746. return;
  747. }
  748. if (mode == Addressing_Constant) {
  749. if (is_type_constant_type(type)) {
  750. // if (value.kind == ExactValue_Invalid) {
  751. // TODO(bill): Is this correct?
  752. // return;
  753. // }
  754. if (!(type != t_invalid || is_type_constant_type(type))) {
  755. compiler_error("add_type_and_value - invalid type: %s", type_to_string(type));
  756. }
  757. }
  758. }
  759. TypeAndValue tv = {};
  760. tv.type = type;
  761. tv.value = value;
  762. tv.mode = mode;
  763. map_set(&i->types, hash_node(expression), tv);
  764. }
  765. void add_entity_definition(CheckerInfo *i, AstNode *identifier, Entity *entity) {
  766. GB_ASSERT(identifier != NULL);
  767. if (identifier->kind == AstNode_Ident) {
  768. if (identifier->Ident.string == "_") {
  769. return;
  770. }
  771. HashKey key = hash_node(identifier);
  772. map_set(&i->definitions, key, entity);
  773. } else {
  774. // NOTE(bill): Error should handled elsewhere
  775. }
  776. }
  777. bool add_entity(Checker *c, Scope *scope, AstNode *identifier, Entity *entity) {
  778. String name = entity->token.string;
  779. if (name != "_") {
  780. Entity *ie = scope_insert_entity(scope, entity);
  781. if (ie) {
  782. TokenPos pos = ie->token.pos;
  783. Entity *up = ie->using_parent;
  784. if (up != NULL) {
  785. if (token_pos_eq(pos, up->token.pos)) {
  786. // NOTE(bill): Error should have been handled already
  787. return false;
  788. }
  789. error(entity->token,
  790. "Redeclaration of `%.*s` in this scope through `using`\n"
  791. "\tat %.*s(%td:%td)",
  792. LIT(name),
  793. LIT(up->token.pos.file), up->token.pos.line, up->token.pos.column);
  794. return false;
  795. } else {
  796. if (token_pos_eq(pos, entity->token.pos)) {
  797. // NOTE(bill): Error should have been handled already
  798. return false;
  799. }
  800. error(entity->token,
  801. "Redeclaration of `%.*s` in this scope\n"
  802. "\tat %.*s(%td:%td)",
  803. LIT(name),
  804. LIT(pos.file), pos.line, pos.column);
  805. return false;
  806. }
  807. }
  808. }
  809. if (identifier != NULL) {
  810. add_entity_definition(&c->info, identifier, entity);
  811. }
  812. return true;
  813. }
  814. void add_entity_use(Checker *c, AstNode *identifier, Entity *entity) {
  815. GB_ASSERT(identifier != NULL);
  816. if (identifier->kind != AstNode_Ident) {
  817. return;
  818. }
  819. HashKey key = hash_node(identifier);
  820. map_set(&c->info.uses, key, entity);
  821. add_declaration_dependency(c, entity); // TODO(bill): Should this be here?
  822. }
  823. void add_entity_and_decl_info(Checker *c, AstNode *identifier, Entity *e, DeclInfo *d) {
  824. GB_ASSERT(identifier->kind == AstNode_Ident);
  825. GB_ASSERT(e != NULL && d != NULL);
  826. GB_ASSERT(identifier->Ident.string == e->token.string);
  827. add_entity(c, e->scope, identifier, e);
  828. map_set(&c->info.entities, hash_entity(e), d);
  829. }
  830. void add_implicit_entity(Checker *c, AstNode *node, Entity *e) {
  831. GB_ASSERT(node != NULL);
  832. GB_ASSERT(e != NULL);
  833. map_set(&c->info.implicits, hash_node(node), e);
  834. }
  835. void add_type_info_type(Checker *c, Type *t) {
  836. if (t == NULL) {
  837. return;
  838. }
  839. t = default_type(t);
  840. if (is_type_bit_field_value(t)) {
  841. t = default_bit_field_value_type(t);
  842. }
  843. if (is_type_untyped(t)) {
  844. return; // Could be nil
  845. }
  846. if (map_get(&c->info.type_info_map, hash_type(t)) != NULL) {
  847. // Types have already been added
  848. return;
  849. }
  850. isize ti_index = -1;
  851. for_array(i, c->info.type_info_map.entries) {
  852. auto *e = &c->info.type_info_map.entries[i];
  853. Type *prev_type = cast(Type *)e->key.ptr;
  854. if (are_types_identical(t, prev_type)) {
  855. // Duplicate entry
  856. ti_index = e->value;
  857. break;
  858. }
  859. }
  860. if (ti_index < 0) {
  861. // Unique entry
  862. // NOTE(bill): map entries grow linearly and in order
  863. ti_index = c->info.type_info_count;
  864. c->info.type_info_count++;
  865. }
  866. map_set(&c->info.type_info_map, hash_type(t), ti_index);
  867. // Add nested types
  868. if (t->kind == Type_Named) {
  869. // NOTE(bill): Just in case
  870. add_type_info_type(c, t->Named.base);
  871. return;
  872. }
  873. Type *bt = base_type(t);
  874. add_type_info_type(c, bt);
  875. switch (bt->kind) {
  876. case Type_Basic: {
  877. switch (bt->Basic.kind) {
  878. case Basic_string:
  879. add_type_info_type(c, t_u8_ptr);
  880. add_type_info_type(c, t_int);
  881. break;
  882. case Basic_any:
  883. add_type_info_type(c, t_type_info_ptr);
  884. add_type_info_type(c, t_rawptr);
  885. break;
  886. case Basic_complex64:
  887. add_type_info_type(c, t_type_info_float);
  888. add_type_info_type(c, t_f32);
  889. break;
  890. case Basic_complex128:
  891. add_type_info_type(c, t_type_info_float);
  892. add_type_info_type(c, t_f64);
  893. break;
  894. }
  895. } break;
  896. case Type_Pointer:
  897. add_type_info_type(c, bt->Pointer.elem);
  898. break;
  899. case Type_Atomic:
  900. add_type_info_type(c, bt->Atomic.elem);
  901. break;
  902. case Type_Array:
  903. add_type_info_type(c, bt->Array.elem);
  904. add_type_info_type(c, make_type_pointer(c->allocator, bt->Array.elem));
  905. add_type_info_type(c, t_int);
  906. break;
  907. case Type_DynamicArray:
  908. add_type_info_type(c, bt->DynamicArray.elem);
  909. add_type_info_type(c, make_type_pointer(c->allocator, bt->DynamicArray.elem));
  910. add_type_info_type(c, t_int);
  911. add_type_info_type(c, t_allocator);
  912. break;
  913. case Type_Slice:
  914. add_type_info_type(c, bt->Slice.elem);
  915. add_type_info_type(c, make_type_pointer(c->allocator, bt->Slice.elem));
  916. add_type_info_type(c, t_int);
  917. break;
  918. case Type_Vector:
  919. add_type_info_type(c, bt->Vector.elem);
  920. add_type_info_type(c, t_int);
  921. break;
  922. case Type_Record: {
  923. switch (bt->Record.kind) {
  924. case TypeRecord_Enum:
  925. add_type_info_type(c, bt->Record.enum_base_type);
  926. break;
  927. case TypeRecord_Union:
  928. add_type_info_type(c, t_int);
  929. for (isize i = 0; i < bt->Record.variant_count; i++) {
  930. Entity *f = bt->Record.variants[i];
  931. add_type_info_type(c, f->type);
  932. }
  933. /* fallthrough */
  934. default:
  935. for (isize i = 0; i < bt->Record.field_count; i++) {
  936. Entity *f = bt->Record.fields[i];
  937. add_type_info_type(c, f->type);
  938. }
  939. break;
  940. }
  941. } break;
  942. case Type_Map: {
  943. add_type_info_type(c, bt->Map.key);
  944. add_type_info_type(c, bt->Map.value);
  945. add_type_info_type(c, bt->Map.generated_struct_type);
  946. } break;
  947. case Type_Tuple:
  948. for (isize i = 0; i < bt->Tuple.variable_count; i++) {
  949. Entity *var = bt->Tuple.variables[i];
  950. add_type_info_type(c, var->type);
  951. }
  952. break;
  953. case Type_Proc:
  954. add_type_info_type(c, bt->Proc.params);
  955. add_type_info_type(c, bt->Proc.results);
  956. break;
  957. }
  958. }
  959. void check_procedure_later(Checker *c, AstFile *file, Token token, DeclInfo *decl, Type *type, AstNode *body, u32 tags) {
  960. ProcedureInfo info = {};
  961. info.file = file;
  962. info.token = token;
  963. info.decl = decl;
  964. info.type = type;
  965. info.body = body;
  966. info.tags = tags;
  967. map_set(&c->procs, hash_decl_info(decl), info);
  968. }
  969. void push_procedure(Checker *c, Type *type) {
  970. array_add(&c->proc_stack, type);
  971. }
  972. void pop_procedure(Checker *c) {
  973. array_pop(&c->proc_stack);
  974. }
  975. Type *const curr_procedure_type(Checker *c) {
  976. isize count = c->proc_stack.count;
  977. if (count > 0) {
  978. return c->proc_stack[count-1];
  979. }
  980. return NULL;
  981. }
  982. void add_curr_ast_file(Checker *c, AstFile *file) {
  983. if (file != NULL) {
  984. TokenPos zero_pos = {};
  985. global_error_collector.prev = zero_pos;
  986. c->curr_ast_file = file;
  987. c->context.decl = file->decl_info;
  988. c->context.scope = file->scope;
  989. c->context.file_scope = file->scope;
  990. }
  991. }
  992. void add_dependency_to_map(Map<Entity *> *map, CheckerInfo *info, Entity *entity) {
  993. if (entity == NULL) {
  994. return;
  995. }
  996. if (map_get(map, hash_entity(entity)) != NULL) {
  997. return;
  998. }
  999. map_set(map, hash_entity(entity), entity);
  1000. DeclInfo *decl = decl_info_of_entity(info, entity);
  1001. if (decl == NULL) {
  1002. return;
  1003. }
  1004. for_array(i, decl->deps.entries) {
  1005. Entity *e = cast(Entity *)decl->deps.entries[i].key.ptr;
  1006. add_dependency_to_map(map, info, e);
  1007. }
  1008. }
  1009. Map<Entity *> generate_minimum_dependency_map(CheckerInfo *info, Entity *start) {
  1010. Map<Entity *> map = {}; // Key: Entity *
  1011. map_init(&map, heap_allocator());
  1012. for_array(i, info->definitions.entries) {
  1013. Entity *e = info->definitions.entries[i].value;
  1014. if (e->scope->is_global) {
  1015. // NOTE(bill): Require runtime stuff
  1016. add_dependency_to_map(&map, info, e);
  1017. } else if (e->kind == Entity_Procedure) {
  1018. if ((e->Procedure.tags & ProcTag_export) != 0) {
  1019. add_dependency_to_map(&map, info, e);
  1020. }
  1021. if (e->Procedure.is_foreign) {
  1022. add_dependency_to_map(&map, info, e->Procedure.foreign_library);
  1023. }
  1024. }
  1025. }
  1026. add_dependency_to_map(&map, info, start);
  1027. return map;
  1028. }
  1029. bool is_entity_in_dependency_map(Map<Entity *> *map, Entity *e) {
  1030. return map_get(map, hash_entity(e)) != NULL;
  1031. }
  1032. Entity *find_core_entity(Checker *c, String name) {
  1033. Entity *e = current_scope_lookup_entity(c->global_scope, name);
  1034. if (e == NULL) {
  1035. compiler_error("Could not find type declaration for `%.*s`\n"
  1036. "Is `_preload.odin` missing from the `core` directory relative to odin.exe?", LIT(name));
  1037. // NOTE(bill): This will exit the program as it's cannot continue without it!
  1038. }
  1039. return e;
  1040. }
  1041. void init_preload(Checker *c) {
  1042. if (t_type_info == NULL) {
  1043. Entity *type_info_entity = find_core_entity(c, str_lit("TypeInfo"));
  1044. t_type_info = type_info_entity->type;
  1045. t_type_info_ptr = make_type_pointer(c->allocator, t_type_info);
  1046. GB_ASSERT(is_type_union(type_info_entity->type));
  1047. TypeRecord *record = &base_type(type_info_entity->type)->Record;
  1048. t_type_info_record = find_core_entity(c, str_lit("TypeInfoRecord"))->type;
  1049. t_type_info_record_ptr = make_type_pointer(c->allocator, t_type_info_record);
  1050. t_type_info_enum_value = find_core_entity(c, str_lit("TypeInfoEnumValue"))->type;
  1051. t_type_info_enum_value_ptr = make_type_pointer(c->allocator, t_type_info_enum_value);
  1052. if (record->variant_count != 23) {
  1053. compiler_error("Invalid `TypeInfo` layout");
  1054. }
  1055. t_type_info_named = record->variants[ 1]->type;
  1056. t_type_info_integer = record->variants[ 2]->type;
  1057. t_type_info_rune = record->variants[ 3]->type;
  1058. t_type_info_float = record->variants[ 4]->type;
  1059. t_type_info_complex = record->variants[ 5]->type;
  1060. t_type_info_string = record->variants[ 6]->type;
  1061. t_type_info_boolean = record->variants[ 7]->type;
  1062. t_type_info_any = record->variants[ 8]->type;
  1063. t_type_info_pointer = record->variants[ 9]->type;
  1064. t_type_info_atomic = record->variants[10]->type;
  1065. t_type_info_procedure = record->variants[11]->type;
  1066. t_type_info_array = record->variants[12]->type;
  1067. t_type_info_dynamic_array = record->variants[13]->type;
  1068. t_type_info_slice = record->variants[14]->type;
  1069. t_type_info_vector = record->variants[15]->type;
  1070. t_type_info_tuple = record->variants[16]->type;
  1071. t_type_info_struct = record->variants[17]->type;
  1072. t_type_info_raw_union = record->variants[18]->type;
  1073. t_type_info_union = record->variants[19]->type;
  1074. t_type_info_enum = record->variants[20]->type;
  1075. t_type_info_map = record->variants[21]->type;
  1076. t_type_info_bit_field = record->variants[22]->type;
  1077. t_type_info_named_ptr = make_type_pointer(c->allocator, t_type_info_named);
  1078. t_type_info_integer_ptr = make_type_pointer(c->allocator, t_type_info_integer);
  1079. t_type_info_rune_ptr = make_type_pointer(c->allocator, t_type_info_rune);
  1080. t_type_info_float_ptr = make_type_pointer(c->allocator, t_type_info_float);
  1081. t_type_info_complex_ptr = make_type_pointer(c->allocator, t_type_info_complex);
  1082. t_type_info_string_ptr = make_type_pointer(c->allocator, t_type_info_string);
  1083. t_type_info_boolean_ptr = make_type_pointer(c->allocator, t_type_info_boolean);
  1084. t_type_info_any_ptr = make_type_pointer(c->allocator, t_type_info_any);
  1085. t_type_info_pointer_ptr = make_type_pointer(c->allocator, t_type_info_pointer);
  1086. t_type_info_atomic_ptr = make_type_pointer(c->allocator, t_type_info_atomic);
  1087. t_type_info_procedure_ptr = make_type_pointer(c->allocator, t_type_info_procedure);
  1088. t_type_info_array_ptr = make_type_pointer(c->allocator, t_type_info_array);
  1089. t_type_info_dynamic_array_ptr = make_type_pointer(c->allocator, t_type_info_dynamic_array);
  1090. t_type_info_slice_ptr = make_type_pointer(c->allocator, t_type_info_slice);
  1091. t_type_info_vector_ptr = make_type_pointer(c->allocator, t_type_info_vector);
  1092. t_type_info_tuple_ptr = make_type_pointer(c->allocator, t_type_info_tuple);
  1093. t_type_info_struct_ptr = make_type_pointer(c->allocator, t_type_info_struct);
  1094. t_type_info_raw_union_ptr = make_type_pointer(c->allocator, t_type_info_raw_union);
  1095. t_type_info_union_ptr = make_type_pointer(c->allocator, t_type_info_union);
  1096. t_type_info_enum_ptr = make_type_pointer(c->allocator, t_type_info_enum);
  1097. t_type_info_map_ptr = make_type_pointer(c->allocator, t_type_info_map);
  1098. t_type_info_bit_field_ptr = make_type_pointer(c->allocator, t_type_info_bit_field);
  1099. }
  1100. if (t_allocator == NULL) {
  1101. Entity *e = find_core_entity(c, str_lit("Allocator"));
  1102. t_allocator = e->type;
  1103. t_allocator_ptr = make_type_pointer(c->allocator, t_allocator);
  1104. }
  1105. if (t_context == NULL) {
  1106. Entity *e = find_core_entity(c, str_lit("Context"));
  1107. e_context = e;
  1108. t_context = e->type;
  1109. t_context_ptr = make_type_pointer(c->allocator, t_context);
  1110. }
  1111. if (t_source_code_location == NULL) {
  1112. Entity *e = find_core_entity(c, str_lit("SourceCodeLocation"));
  1113. t_source_code_location = e->type;
  1114. t_source_code_location_ptr = make_type_pointer(c->allocator, t_allocator);
  1115. }
  1116. if (t_map_key == NULL) {
  1117. Entity *e = find_core_entity(c, str_lit("__MapKey"));
  1118. t_map_key = e->type;
  1119. }
  1120. if (t_map_header == NULL) {
  1121. Entity *e = find_core_entity(c, str_lit("__MapHeader"));
  1122. t_map_header = e->type;
  1123. }
  1124. c->done_preload = true;
  1125. }
  1126. bool check_arity_match(Checker *c, AstNodeValueSpec *s);
  1127. void check_collect_entities(Checker *c, Array<AstNode *> nodes, bool is_file_scope);
  1128. void check_collect_entities_from_when_stmt(Checker *c, AstNodeWhenStmt *ws, bool is_file_scope);
  1129. bool check_is_entity_overloaded(Entity *e) {
  1130. if (e->kind != Entity_Procedure) {
  1131. return false;
  1132. }
  1133. Scope *s = e->scope;
  1134. HashKey key = hash_string(e->token.string);
  1135. isize overload_count = multi_map_count(&s->elements, key);
  1136. return overload_count > 1;
  1137. }
  1138. void check_procedure_overloading(Checker *c, Entity *e) {
  1139. GB_ASSERT(e->kind == Entity_Procedure);
  1140. if (e->type == t_invalid) {
  1141. return;
  1142. }
  1143. if (e->Procedure.overload_kind != Overload_Unknown) {
  1144. // NOTE(bill): The overloading has already been handled
  1145. return;
  1146. }
  1147. // NOTE(bill): Procedures call only overload other procedures in the same scope
  1148. String name = e->token.string;
  1149. HashKey key = hash_string(name);
  1150. Scope *s = e->scope;
  1151. isize overload_count = multi_map_count(&s->elements, key);
  1152. GB_ASSERT(overload_count >= 1);
  1153. if (overload_count == 1) {
  1154. e->Procedure.overload_kind = Overload_No;
  1155. return;
  1156. }
  1157. GB_ASSERT(overload_count > 1);
  1158. gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
  1159. Entity **procs = gb_alloc_array(c->tmp_allocator, Entity *, overload_count);
  1160. multi_map_get_all(&s->elements, key, procs);
  1161. for (isize j = 0; j < overload_count; j++) {
  1162. Entity *p = procs[j];
  1163. if (p->type == t_invalid) {
  1164. // NOTE(bill): This invalid overload has already been handled
  1165. continue;
  1166. }
  1167. String name = p->token.string;
  1168. GB_ASSERT(p->kind == Entity_Procedure);
  1169. for (isize k = j+1; k < overload_count; k++) {
  1170. Entity *q = procs[k];
  1171. GB_ASSERT(p != q);
  1172. bool is_invalid = false;
  1173. GB_ASSERT(q->kind == Entity_Procedure);
  1174. TokenPos pos = q->token.pos;
  1175. if (q->type == NULL) {
  1176. continue;
  1177. }
  1178. if (is_type_proc(q->type)) {
  1179. TypeProc *ptq = &base_type(q->type)->Proc;
  1180. if (ptq->is_generic) {
  1181. q->type = t_invalid;
  1182. error(q->token, "Generic procedure `%.*s` cannot be overloaded", LIT(name));
  1183. continue;
  1184. }
  1185. }
  1186. ProcTypeOverloadKind kind = are_proc_types_overload_safe(p->type, q->type);
  1187. switch (kind) {
  1188. case ProcOverload_Identical:
  1189. error(p->token, "Overloaded procedure `%.*s` as the same type as another procedure in this scope", LIT(name));
  1190. is_invalid = true;
  1191. break;
  1192. // case ProcOverload_CallingConvention:
  1193. // error(p->token, "Overloaded procedure `%.*s` as the same type as another procedure in this scope", LIT(name));
  1194. // is_invalid = true;
  1195. // break;
  1196. case ProcOverload_ParamVariadic:
  1197. error(p->token, "Overloaded procedure `%.*s` as the same type as another procedure in this scope", LIT(name));
  1198. is_invalid = true;
  1199. break;
  1200. case ProcOverload_ResultCount:
  1201. case ProcOverload_ResultTypes:
  1202. error(p->token, "Overloaded procedure `%.*s` as the same parameters but different results in this scope", LIT(name));
  1203. is_invalid = true;
  1204. break;
  1205. case ProcOverload_ParamCount:
  1206. case ProcOverload_ParamTypes:
  1207. // This is okay :)
  1208. break;
  1209. }
  1210. if (is_invalid) {
  1211. gb_printf_err("\tprevious procedure at %.*s(%td:%td)\n", LIT(pos.file), pos.line, pos.column);
  1212. q->type = t_invalid;
  1213. }
  1214. }
  1215. }
  1216. for (isize j = 0; j < overload_count; j++) {
  1217. Entity *p = procs[j];
  1218. if (p->type != t_invalid) {
  1219. p->Procedure.overload_kind = Overload_Yes;
  1220. }
  1221. }
  1222. gb_temp_arena_memory_end(tmp);
  1223. }
  1224. #include "check_expr.cpp"
  1225. #include "check_decl.cpp"
  1226. #include "check_stmt.cpp"
  1227. bool check_arity_match(Checker *c, AstNodeValueSpec *spec) {
  1228. isize lhs = spec->names.count;
  1229. isize rhs = spec->values.count;
  1230. if (rhs == 0) {
  1231. if (spec->type == NULL) {
  1232. error(spec->names[0], "Missing type or initial expression");
  1233. return false;
  1234. }
  1235. } else if (lhs < rhs) {
  1236. if (lhs < spec->values.count) {
  1237. AstNode *n = spec->values[lhs];
  1238. gbString str = expr_to_string(n);
  1239. error(n, "Extra initial expression `%s`", str);
  1240. gb_string_free(str);
  1241. } else {
  1242. error(spec->names[0], "Extra initial expression");
  1243. }
  1244. return false;
  1245. } else if (lhs > rhs && rhs != 1) {
  1246. AstNode *n = spec->names[rhs];
  1247. gbString str = expr_to_string(n);
  1248. error(n, "Missing expression for `%s`", str);
  1249. gb_string_free(str);
  1250. return false;
  1251. }
  1252. return true;
  1253. }
  1254. void check_collect_entities_from_when_stmt(Checker *c, AstNodeWhenStmt *ws, bool is_file_scope) {
  1255. Operand operand = {Addressing_Invalid};
  1256. check_expr(c, &operand, ws->cond);
  1257. if (operand.mode != Addressing_Invalid && !is_type_boolean(operand.type)) {
  1258. error(ws->cond, "Non-boolean condition in `when` statement");
  1259. }
  1260. if (operand.mode != Addressing_Constant) {
  1261. error(ws->cond, "Non-constant condition in `when` statement");
  1262. }
  1263. if (ws->body == NULL || ws->body->kind != AstNode_BlockStmt) {
  1264. error(ws->cond, "Invalid body for `when` statement");
  1265. } else {
  1266. if (operand.value.kind == ExactValue_Bool &&
  1267. operand.value.value_bool) {
  1268. check_collect_entities(c, ws->body->BlockStmt.stmts, is_file_scope);
  1269. } else if (ws->else_stmt) {
  1270. switch (ws->else_stmt->kind) {
  1271. case AstNode_BlockStmt:
  1272. check_collect_entities(c, ws->else_stmt->BlockStmt.stmts, is_file_scope);
  1273. break;
  1274. case AstNode_WhenStmt:
  1275. check_collect_entities_from_when_stmt(c, &ws->else_stmt->WhenStmt, is_file_scope);
  1276. break;
  1277. default:
  1278. error(ws->else_stmt, "Invalid `else` statement in `when` statement");
  1279. break;
  1280. }
  1281. }
  1282. }
  1283. }
  1284. // NOTE(bill): If file_scopes == NULL, this will act like a local scope
  1285. void check_collect_entities(Checker *c, Array<AstNode *> nodes, bool is_file_scope) {
  1286. // NOTE(bill): File scope and local scope are different kinds of scopes
  1287. if (is_file_scope) {
  1288. GB_ASSERT(c->context.scope->is_file);
  1289. } else {
  1290. GB_ASSERT(!c->context.scope->is_file);
  1291. }
  1292. for_array(decl_index, nodes) {
  1293. AstNode *decl = nodes[decl_index];
  1294. if (!is_ast_node_decl(decl) && !is_ast_node_when_stmt(decl)) {
  1295. continue;
  1296. }
  1297. switch (decl->kind) {
  1298. case_ast_node(bd, BadDecl, decl);
  1299. case_end;
  1300. case_ast_node(ws, WhenStmt, decl);
  1301. if (c->context.scope->is_file) {
  1302. error(decl, "`when` statements are not allowed at file scope");
  1303. } else {
  1304. // Will be handled later
  1305. }
  1306. case_end;
  1307. case_ast_node(gd, GenDecl, decl);
  1308. AstNodeValueSpec empty_spec = {};
  1309. AstNodeValueSpec *last_spec = NULL;
  1310. for_array(i, gd->specs) {
  1311. AstNode *spec = gd->specs[i];
  1312. switch (gd->token.kind) {
  1313. case Token_const: {
  1314. ast_node(vs, ValueSpec, spec);
  1315. if (vs->type != NULL || vs->values.count > 0) {
  1316. last_spec = vs;
  1317. } else if (last_spec == NULL) {
  1318. last_spec = &empty_spec;
  1319. }
  1320. for_array(i, vs->names) {
  1321. AstNode *name = vs->names[i];
  1322. if (name->kind != AstNode_Ident) {
  1323. error(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[name->kind]));
  1324. continue;
  1325. }
  1326. AstNode *init = NULL;
  1327. if (i < vs->values.count) {
  1328. init = vs->values[i];
  1329. }
  1330. DeclInfo *d = make_declaration_info(c->allocator, c->context.scope, c->context.decl);
  1331. Entity *e = make_entity_constant(c->allocator, d->scope, name->Ident, NULL, empty_exact_value);
  1332. d->type_expr = last_spec->type;
  1333. d->init_expr = init;
  1334. e->identifier = name;
  1335. add_entity_and_decl_info(c, name, e, d);
  1336. }
  1337. check_arity_match(c, vs);
  1338. } break;
  1339. case Token_var:
  1340. case Token_let: {
  1341. if (!c->context.scope->is_file) {
  1342. // NOTE(bill): local scope -> handle later and in order
  1343. break;
  1344. }
  1345. ast_node(vs, ValueSpec, spec);
  1346. // NOTE(bill): You need to store the entity information here unline a constant declaration
  1347. isize entity_cap = vs->names.count;
  1348. isize entity_count = 0;
  1349. Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_cap);
  1350. DeclInfo *di = NULL;
  1351. if (vs->values.count > 0) {
  1352. di = make_declaration_info(heap_allocator(), c->context.scope, c->context.decl);
  1353. di->entities = entities;
  1354. di->type_expr = vs->type;
  1355. di->init_expr = vs->values[0];
  1356. if (gd->flags & VarDeclFlag_thread_local) {
  1357. error(decl, "#thread_local variable declarations cannot have initialization values");
  1358. }
  1359. }
  1360. for_array(i, vs->names) {
  1361. AstNode *name = vs->names[i];
  1362. AstNode *value = NULL;
  1363. if (i < vs->values.count) {
  1364. value = vs->values[i];
  1365. }
  1366. if (name->kind != AstNode_Ident) {
  1367. error(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[name->kind]));
  1368. continue;
  1369. }
  1370. Entity *e = make_entity_variable(c->allocator, c->context.scope, name->Ident, NULL, gd->token.kind == Token_let);
  1371. e->Variable.is_thread_local = (gd->flags & VarDeclFlag_thread_local) != 0;
  1372. e->identifier = name;
  1373. if (gd->flags & VarDeclFlag_using) {
  1374. gd->flags &= ~VarDeclFlag_using; // NOTE(bill): This error will be only caught once
  1375. error(name, "`using` is not allowed at the file scope");
  1376. }
  1377. AstNode *fl = c->context.curr_foreign_library;
  1378. if (fl != NULL) {
  1379. GB_ASSERT(fl->kind == AstNode_Ident);
  1380. e->Variable.is_foreign = true;
  1381. e->Variable.foreign_library_ident = fl;
  1382. }
  1383. entities[entity_count++] = e;
  1384. DeclInfo *d = di;
  1385. if (d == NULL) {
  1386. AstNode *init_expr = value;
  1387. d = make_declaration_info(heap_allocator(), e->scope, c->context.decl);
  1388. d->type_expr = vs->type;
  1389. d->init_expr = init_expr;
  1390. }
  1391. add_entity_and_decl_info(c, name, e, d);
  1392. }
  1393. if (di != NULL) {
  1394. di->entity_count = entity_count;
  1395. }
  1396. check_arity_match(c, vs);
  1397. } break;
  1398. case Token_type: {
  1399. ast_node(ts, TypeSpec, spec);
  1400. AstNode *name = ts->name;
  1401. if (name->kind != AstNode_Ident) {
  1402. error(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[name->kind]));
  1403. break;
  1404. }
  1405. DeclInfo *d = make_declaration_info(c->allocator, c->context.scope, c->context.decl);
  1406. Entity *e = NULL;
  1407. AstNode *type = unparen_expr(ts->type);
  1408. e = make_entity_type_name(c->allocator, d->scope, name->Ident, NULL);
  1409. d->type_expr = type;
  1410. d->init_expr = type;
  1411. e->identifier = name;
  1412. add_entity_and_decl_info(c, name, e, d);
  1413. } break;
  1414. case Token_import:
  1415. case Token_import_load: {
  1416. ast_node(ts, ImportSpec, spec);
  1417. if (!c->context.scope->is_file) {
  1418. if (ts->is_import) {
  1419. error(decl, "import declarations are only allowed in the file scope");
  1420. } else {
  1421. error(decl, "import_load declarations are only allowed in the file scope");
  1422. }
  1423. // NOTE(bill): _Should_ be caught by the parser
  1424. // TODO(bill): Better error handling if it isn't
  1425. continue;
  1426. }
  1427. DelayedDecl di = {c->context.scope, spec};
  1428. array_add(&c->delayed_imports, di);
  1429. } break;
  1430. case Token_foreign_library:
  1431. case Token_foreign_system_library: {
  1432. ast_node(fl, ForeignLibrarySpec, spec);
  1433. if (!c->context.scope->is_file) {
  1434. if (fl->is_system) {
  1435. error(spec, "foreign_system_library declarations are only allowed in the file scope");
  1436. } else {
  1437. error(spec, "foreign_library declarations are only allowed in the file scope");
  1438. }
  1439. // NOTE(bill): _Should_ be caught by the parser
  1440. // TODO(bill): Better error handling if it isn't
  1441. continue;
  1442. }
  1443. if (fl->cond != NULL) {
  1444. Operand operand = {Addressing_Invalid};
  1445. check_expr(c, &operand, fl->cond);
  1446. if (operand.mode != Addressing_Constant || !is_type_boolean(operand.type)) {
  1447. error(fl->cond, "Non-constant boolean `when` condition");
  1448. continue;
  1449. }
  1450. if (operand.value.kind == ExactValue_Bool &&
  1451. !operand.value.value_bool) {
  1452. continue;
  1453. }
  1454. }
  1455. DelayedDecl di = {c->context.scope, spec};
  1456. array_add(&c->delayed_foreign_libraries, di);
  1457. } break;
  1458. }
  1459. }
  1460. case_end;
  1461. case_ast_node(fb, ForeignBlockDecl, decl);
  1462. AstNode *foreign_library = fb->foreign_library;
  1463. if (foreign_library->kind != AstNode_Ident) {
  1464. error(foreign_library, "foreign library name must be an identifier");
  1465. foreign_library = NULL;
  1466. }
  1467. CheckerContext prev_context = c->context;
  1468. c->context.curr_foreign_library = foreign_library;
  1469. check_collect_entities(c, fb->decls, is_file_scope);
  1470. c->context = prev_context;
  1471. case_end;
  1472. case_ast_node(pd, ProcDecl, decl);
  1473. AstNode *name = pd->name;
  1474. if (name->kind != AstNode_Ident) {
  1475. error(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[name->kind]));
  1476. break;
  1477. }
  1478. DeclInfo *d = make_declaration_info(c->allocator, c->context.scope, c->context.decl);
  1479. Entity *e = NULL;
  1480. e = make_entity_procedure(c->allocator, d->scope, name->Ident, NULL, pd->tags);
  1481. AstNode *fl = c->context.curr_foreign_library;
  1482. if (fl != NULL) {
  1483. GB_ASSERT(fl->kind == AstNode_Ident);
  1484. e->Procedure.foreign_library_ident = fl;
  1485. pd->tags |= ProcTag_foreign;
  1486. }
  1487. d->proc_decl = decl;
  1488. d->type_expr = pd->type;
  1489. e->identifier = name;
  1490. add_entity_and_decl_info(c, name, e, d);
  1491. case_end;
  1492. default:
  1493. if (c->context.scope->is_file) {
  1494. error(decl, "Only declarations are allowed at file scope");
  1495. }
  1496. break;
  1497. }
  1498. }
  1499. // NOTE(bill): `when` stmts need to be handled after the other as the condition may refer to something
  1500. // declared after this stmt in source
  1501. if (!c->context.scope->is_file) {
  1502. for_array(i, nodes) {
  1503. AstNode *node = nodes[i];
  1504. switch (node->kind) {
  1505. case_ast_node(ws, WhenStmt, node);
  1506. check_collect_entities_from_when_stmt(c, ws, is_file_scope);
  1507. case_end;
  1508. }
  1509. }
  1510. }
  1511. }
  1512. void check_all_global_entities(Checker *c) {
  1513. Scope *prev_file = NULL;
  1514. for_array(i, c->info.entities.entries) {
  1515. auto *entry = &c->info.entities.entries[i];
  1516. Entity *e = cast(Entity *)entry->key.ptr;
  1517. DeclInfo *d = entry->value;
  1518. if (d->scope != e->scope) {
  1519. continue;
  1520. }
  1521. add_curr_ast_file(c, d->scope->file);
  1522. if (!d->scope->has_been_imported) {
  1523. // NOTE(bill): All of these unchecked entities could mean a lot of unused allocations
  1524. // TODO(bill): Should this be worried about?
  1525. continue;
  1526. }
  1527. if (e->token.string == "main") {
  1528. if (e->kind != Entity_Procedure) {
  1529. if (e->scope->is_init) {
  1530. error(e->token, "`main` is reserved as the entry point procedure in the initial scope");
  1531. continue;
  1532. }
  1533. } else if (e->scope->is_global) {
  1534. error(e->token, "`main` is reserved as the entry point procedure in the initial scope");
  1535. continue;
  1536. }
  1537. }
  1538. CheckerContext prev_context = c->context;
  1539. c->context.decl = d;
  1540. c->context.scope = d->scope;
  1541. check_entity_decl(c, e, d, NULL);
  1542. c->context = prev_context;
  1543. if (d->scope->is_init && !c->done_preload) {
  1544. init_preload(c);
  1545. }
  1546. }
  1547. for_array(i, c->info.entities.entries) {
  1548. auto *entry = &c->info.entities.entries[i];
  1549. Entity *e = cast(Entity *)entry->key.ptr;
  1550. if (e->kind != Entity_Procedure) {
  1551. continue;
  1552. }
  1553. check_procedure_overloading(c, e);
  1554. }
  1555. }
  1556. bool is_string_an_identifier(String s) {
  1557. isize offset = 0;
  1558. if (s.len < 1) {
  1559. return false;
  1560. }
  1561. while (offset < s.len) {
  1562. bool ok = false;
  1563. Rune r = -1;
  1564. isize size = gb_utf8_decode(s.text+offset, s.len-offset, &r);
  1565. if (offset == 0) {
  1566. ok = rune_is_letter(r);
  1567. } else {
  1568. ok = rune_is_letter(r) || rune_is_digit(r);
  1569. }
  1570. if (!ok) {
  1571. return false;
  1572. }
  1573. offset += size;
  1574. }
  1575. return offset == s.len;
  1576. }
  1577. String path_to_entity_name(String name, String fullpath) {
  1578. if (name.len != 0) {
  1579. return name;
  1580. }
  1581. // NOTE(bill): use file name (without extension) as the identifier
  1582. // If it is a valid identifier
  1583. String filename = fullpath;
  1584. isize slash = 0;
  1585. isize dot = 0;
  1586. for (isize i = filename.len-1; i >= 0; i--) {
  1587. u8 c = filename[i];
  1588. if (c == '/' || c == '\\') {
  1589. break;
  1590. }
  1591. slash = i;
  1592. }
  1593. filename.text += slash;
  1594. filename.len -= slash;
  1595. dot = filename.len;
  1596. while (dot --> 0) {
  1597. u8 c = filename[dot];
  1598. if (c == '.') {
  1599. break;
  1600. }
  1601. }
  1602. filename.len = dot;
  1603. if (is_string_an_identifier(filename)) {
  1604. return filename;
  1605. } else {
  1606. return str_lit("_");
  1607. }
  1608. }
  1609. void check_import_entities(Checker *c, Map<Scope *> *file_scopes) {
  1610. #if 0
  1611. // TODO(bill): Dependency ordering for imports
  1612. {
  1613. Array_i32 shared_global_file_ids = {};
  1614. array_init_reserve(&shared_global_file_ids, heap_allocator(), c->file_nodes.count);
  1615. for_array(i, c->file_nodes) {
  1616. CheckerFileNode *node = &c->file_nodes[i];
  1617. AstFile *f = &c->parser->files[node->id];
  1618. GB_ASSERT(f->id == node->id);
  1619. if (f->scope->is_global) {
  1620. array_add(&shared_global_file_ids, f->id);
  1621. }
  1622. }
  1623. for_array(i, c->file_nodes) {
  1624. CheckerFileNode *node = &c->file_nodes[i];
  1625. AstFile *f = &c->parser->files[node->id];
  1626. if (!f->scope->is_global) {
  1627. for_array(j, shared_global_file_ids) {
  1628. array_add(&node->whats, shared_global_file_ids[j]);
  1629. }
  1630. }
  1631. }
  1632. array_free(&shared_global_file_ids);
  1633. }
  1634. for_array(i, c->delayed_imports) {
  1635. Scope *parent_scope = c->delayed_imports[i].parent;
  1636. AstNode *decl = c->delayed_imports[i].decl;
  1637. ast_node(id, ImportDecl, decl);
  1638. Token token = id->relpath;
  1639. GB_ASSERT(parent_scope->is_file);
  1640. if (!parent_scope->has_been_imported) {
  1641. continue;
  1642. }
  1643. HashKey key = hash_string(id->fullpath);
  1644. Scope **found = map_get(file_scopes, key);
  1645. if (found == NULL) {
  1646. for_array(scope_index, file_scopes->entries) {
  1647. Scope *scope = file_scopes->entries[scope_index].value;
  1648. gb_printf_err("%.*s\n", LIT(scope->file->tokenizer.fullpath));
  1649. }
  1650. gb_printf_err("%.*s(%td:%td)\n", LIT(token.pos.file), token.pos.line, token.pos.column);
  1651. GB_PANIC("Unable to find scope for file: %.*s", LIT(id->fullpath));
  1652. }
  1653. Scope *scope = *found;
  1654. if (scope->is_global) {
  1655. continue;
  1656. }
  1657. i32 parent_id = parent_scope->file->id;
  1658. i32 child_id = scope->file->id;
  1659. // TODO(bill): Very slow
  1660. CheckerFileNode *parent_node = &c->file_nodes[parent_id];
  1661. bool add_child = true;
  1662. for_array(j, parent_node->whats) {
  1663. if (parent_node->whats[j] == child_id) {
  1664. add_child = false;
  1665. break;
  1666. }
  1667. }
  1668. if (add_child) {
  1669. array_add(&parent_node->whats, child_id);
  1670. }
  1671. CheckerFileNode *child_node = &c->file_nodes[child_id];
  1672. bool add_parent = true;
  1673. for_array(j, parent_node->wheres) {
  1674. if (parent_node->wheres[j] == parent_id) {
  1675. add_parent = false;
  1676. break;
  1677. }
  1678. }
  1679. if (add_parent) {
  1680. array_add(&child_node->wheres, parent_id);
  1681. }
  1682. }
  1683. for_array(i, c->file_nodes) {
  1684. CheckerFileNode *node = &c->file_nodes[i];
  1685. AstFile *f = &c->parser->files[node->id];
  1686. gb_printf_err("File %d %.*s", node->id, LIT(f->tokenizer.fullpath));
  1687. gb_printf_err("\n wheres:");
  1688. for_array(j, node->wheres) {
  1689. gb_printf_err(" %d", node->wheres[j]);
  1690. }
  1691. gb_printf_err("\n whats:");
  1692. for_array(j, node->whats) {
  1693. gb_printf_err(" %d", node->whats[j]);
  1694. }
  1695. gb_printf_err("\n");
  1696. }
  1697. #endif
  1698. for_array(i, c->delayed_imports) {
  1699. Scope *parent_scope = c->delayed_imports[i].parent;
  1700. AstNode *decl = c->delayed_imports[i].decl;
  1701. ast_node(id, ImportSpec, decl);
  1702. Token token = id->relpath;
  1703. GB_ASSERT(parent_scope->is_file);
  1704. if (!parent_scope->has_been_imported) {
  1705. continue;
  1706. }
  1707. HashKey key = hash_string(id->fullpath);
  1708. Scope **found = map_get(file_scopes, key);
  1709. if (found == NULL) {
  1710. for_array(scope_index, file_scopes->entries) {
  1711. Scope *scope = file_scopes->entries[scope_index].value;
  1712. gb_printf_err("%.*s\n", LIT(scope->file->tokenizer.fullpath));
  1713. }
  1714. gb_printf_err("%.*s(%td:%td)\n", LIT(token.pos.file), token.pos.line, token.pos.column);
  1715. GB_PANIC("Unable to find scope for file: %.*s", LIT(id->fullpath));
  1716. }
  1717. Scope *scope = *found;
  1718. if (scope->is_global) {
  1719. error(token, "Importing a #shared_global_scope is disallowed and unnecessary");
  1720. continue;
  1721. }
  1722. if (id->cond != NULL) {
  1723. Operand operand = {Addressing_Invalid};
  1724. check_expr(c, &operand, id->cond);
  1725. if (operand.mode != Addressing_Constant || !is_type_boolean(operand.type)) {
  1726. error(id->cond, "Non-constant boolean `when` condition");
  1727. continue;
  1728. }
  1729. if (operand.value.kind == ExactValue_Bool &&
  1730. operand.value.value_bool == false) {
  1731. continue;
  1732. }
  1733. }
  1734. bool previously_added = false;
  1735. for_array(import_index, parent_scope->imported) {
  1736. Scope *prev = parent_scope->imported[import_index];
  1737. if (prev == scope) {
  1738. previously_added = true;
  1739. break;
  1740. }
  1741. }
  1742. if (!previously_added) {
  1743. array_add(&parent_scope->imported, scope);
  1744. } else {
  1745. warning(token, "Multiple import of the same file within this scope");
  1746. }
  1747. scope->has_been_imported = true;
  1748. if (id->import_name.string == ".") {
  1749. // NOTE(bill): Add imported entities to this file's scope
  1750. for_array(elem_index, scope->elements.entries) {
  1751. Entity *e = scope->elements.entries[elem_index].value;
  1752. if (e->scope == parent_scope) {
  1753. continue;
  1754. }
  1755. if (!is_entity_kind_exported(e->kind)) {
  1756. continue;
  1757. }
  1758. if (id->is_import) {
  1759. if (is_entity_exported(e)) {
  1760. // TODO(bill): Should these entities be imported but cause an error when used?
  1761. bool ok = add_entity(c, parent_scope, e->identifier, e);
  1762. if (ok) {
  1763. map_set(&parent_scope->implicit, hash_entity(e), true);
  1764. }
  1765. }
  1766. } else {
  1767. add_entity(c, parent_scope, e->identifier, e);
  1768. }
  1769. }
  1770. } else {
  1771. String import_name = path_to_entity_name(id->import_name.string, id->fullpath);
  1772. if (import_name == "_") {
  1773. error(token, "File name, %.*s, cannot be as an import name as it is not a valid identifier", LIT(id->import_name.string));
  1774. } else {
  1775. GB_ASSERT(id->import_name.pos.line != 0);
  1776. id->import_name.string = import_name;
  1777. Entity *e = make_entity_import_name(c->allocator, parent_scope, id->import_name, t_invalid,
  1778. id->fullpath, id->import_name.string,
  1779. scope);
  1780. add_entity(c, parent_scope, NULL, e);
  1781. }
  1782. }
  1783. }
  1784. for_array(i, c->delayed_foreign_libraries) {
  1785. Scope *parent_scope = c->delayed_foreign_libraries[i].parent;
  1786. AstNode *spec = c->delayed_foreign_libraries[i].decl;
  1787. ast_node(fl, ForeignLibrarySpec, spec);
  1788. String file_str = fl->filepath.string;
  1789. String base_dir = fl->base_dir;
  1790. if (!fl->is_system) {
  1791. gbAllocator a = heap_allocator(); // TODO(bill): Change this allocator
  1792. String rel_path = get_fullpath_relative(a, base_dir, file_str);
  1793. String import_file = rel_path;
  1794. if (!gb_file_exists(cast(char *)rel_path.text)) { // NOTE(bill): This should be null terminated
  1795. String abs_path = get_fullpath_core(a, file_str);
  1796. if (gb_file_exists(cast(char *)abs_path.text)) {
  1797. import_file = abs_path;
  1798. }
  1799. }
  1800. file_str = import_file;
  1801. }
  1802. if (fl->cond != NULL) {
  1803. Operand operand = {Addressing_Invalid};
  1804. check_expr(c, &operand, fl->cond);
  1805. if (operand.mode != Addressing_Constant || !is_type_boolean(operand.type)) {
  1806. error(fl->cond, "Non-constant boolean `when` condition");
  1807. continue;
  1808. }
  1809. if (operand.value.kind == ExactValue_Bool &&
  1810. !operand.value.value_bool) {
  1811. continue;
  1812. }
  1813. }
  1814. String library_name = path_to_entity_name(fl->library_name.string, file_str);
  1815. if (library_name == "_") {
  1816. error(spec, "File name, %.*s, cannot be as a library name as it is not a valid identifier", LIT(fl->library_name.string));
  1817. } else {
  1818. GB_ASSERT(fl->library_name.pos.line != 0);
  1819. fl->library_name.string = library_name;
  1820. Entity *e = make_entity_library_name(c->allocator, parent_scope, fl->library_name, t_invalid,
  1821. file_str, library_name);
  1822. add_entity(c, parent_scope, NULL, e);
  1823. }
  1824. }
  1825. }
  1826. void check_parsed_files(Checker *c) {
  1827. Map<Scope *> file_scopes; // Key: String (fullpath)
  1828. map_init(&file_scopes, heap_allocator());
  1829. // Map full filepaths to Scopes
  1830. for_array(i, c->parser->files) {
  1831. AstFile *f = &c->parser->files[i];
  1832. Scope *scope = NULL;
  1833. scope = make_scope(c->global_scope, c->allocator);
  1834. scope->is_global = f->is_global_scope;
  1835. scope->is_file = true;
  1836. scope->file = f;
  1837. if (f->tokenizer.fullpath == c->parser->init_fullpath) {
  1838. scope->is_init = true;
  1839. }
  1840. if (scope->is_global) {
  1841. array_add(&c->global_scope->shared, scope);
  1842. }
  1843. if (scope->is_init || scope->is_global) {
  1844. scope->has_been_imported = true;
  1845. }
  1846. f->scope = scope;
  1847. f->decl_info = make_declaration_info(c->allocator, f->scope, c->context.decl);
  1848. HashKey key = hash_string(f->tokenizer.fullpath);
  1849. map_set(&file_scopes, key, scope);
  1850. map_set(&c->info.files, key, f);
  1851. }
  1852. // Collect Entities
  1853. for_array(i, c->parser->files) {
  1854. AstFile *f = &c->parser->files[i];
  1855. CheckerContext prev_context = c->context;
  1856. add_curr_ast_file(c, f);
  1857. check_collect_entities(c, f->decls, true);
  1858. c->context = prev_context;
  1859. }
  1860. check_import_entities(c, &file_scopes);
  1861. check_all_global_entities(c);
  1862. init_preload(c); // NOTE(bill): This could be setup previously through the use of `type_info(_of_val)`
  1863. // Check procedure bodies
  1864. // NOTE(bill): Nested procedures bodies will be added to this "queue"
  1865. for_array(i, c->procs.entries) {
  1866. ProcedureInfo *pi = &c->procs.entries[i].value;
  1867. CheckerContext prev_context = c->context;
  1868. defer (c->context = prev_context);
  1869. TypeProc *pt = &pi->type->Proc;
  1870. if (pt->is_generic) {
  1871. error(pi->token, "Generic procedures are not yet supported");
  1872. continue;
  1873. }
  1874. add_curr_ast_file(c, pi->file);
  1875. bool bounds_check = (pi->tags & ProcTag_bounds_check) != 0;
  1876. bool no_bounds_check = (pi->tags & ProcTag_no_bounds_check) != 0;
  1877. if (bounds_check) {
  1878. c->context.stmt_state_flags |= StmtStateFlag_bounds_check;
  1879. c->context.stmt_state_flags &= ~StmtStateFlag_no_bounds_check;
  1880. } else if (no_bounds_check) {
  1881. c->context.stmt_state_flags |= StmtStateFlag_no_bounds_check;
  1882. c->context.stmt_state_flags &= ~StmtStateFlag_bounds_check;
  1883. }
  1884. check_proc_body(c, pi->token, pi->decl, pi->type, pi->body);
  1885. }
  1886. // Add untyped expression values
  1887. for_array(i, c->info.untyped.entries) {
  1888. auto *entry = &c->info.untyped.entries[i];
  1889. HashKey key = entry->key;
  1890. AstNode *expr = cast(AstNode *)key.ptr;
  1891. ExprInfo *info = &entry->value;
  1892. if (info != NULL && expr != NULL) {
  1893. if (is_type_typed(info->type)) {
  1894. compiler_error("%s (type %s) is typed!", expr_to_string(expr), type_to_string(info->type));
  1895. }
  1896. add_type_and_value(&c->info, expr, info->mode, info->type, info->value);
  1897. }
  1898. }
  1899. // TODO(bill): Check for unused imports (and remove) or even warn/err
  1900. // TODO(bill): Any other checks?
  1901. #if 1
  1902. // Add "Basic" type information
  1903. for (isize i = 0; i < gb_count_of(basic_types)-1; i++) {
  1904. Type *t = &basic_types[i];
  1905. if (t->Basic.size > 0) {
  1906. add_type_info_type(c, t);
  1907. }
  1908. }
  1909. /*
  1910. for (isize i = 0; i < gb_count_of(basic_type_aliases)-1; i++) {
  1911. Type *t = &basic_type_aliases[i];
  1912. if (t->Basic.size > 0) {
  1913. add_type_info_type(c, t);
  1914. }
  1915. }
  1916. */
  1917. #endif
  1918. // NOTE(bill): Check for illegal cyclic type declarations
  1919. for_array(i, c->info.definitions.entries) {
  1920. Entity *e = c->info.definitions.entries[i].value;
  1921. if (e->kind == Entity_TypeName) {
  1922. if (e->type != NULL) {
  1923. // i64 size = type_size_of(c->sizes, c->allocator, e->type);
  1924. i64 align = type_align_of(c->allocator, e->type);
  1925. if (align > 0) {
  1926. // add_type_info_type(c, e->type);
  1927. }
  1928. }
  1929. }
  1930. }
  1931. // gb_printf_err("Count: %td\n", c->info.type_info_count++);
  1932. if (!build_context.is_dll) {
  1933. for_array(i, file_scopes.entries) {
  1934. Scope *s = file_scopes.entries[i].value;
  1935. if (s->is_init) {
  1936. Entity *e = current_scope_lookup_entity(s, str_lit("main"));
  1937. if (e == NULL) {
  1938. Token token = {};
  1939. if (s->file->tokens.count > 0) {
  1940. token = s->file->tokens[0];
  1941. } else {
  1942. token.pos.file = s->file->tokenizer.fullpath;
  1943. token.pos.line = 1;
  1944. token.pos.column = 1;
  1945. }
  1946. error(token, "Undefined entry point procedure `main`");
  1947. }
  1948. break;
  1949. }
  1950. }
  1951. }
  1952. map_destroy(&file_scopes);
  1953. }