entity.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. struct Scope;
  2. struct Checker;
  3. struct Type;
  4. struct DeclInfo;
  5. #define ENTITY_KINDS \
  6. ENTITY_KIND(Invalid) \
  7. ENTITY_KIND(Constant) \
  8. ENTITY_KIND(Variable) \
  9. ENTITY_KIND(TypeName) \
  10. ENTITY_KIND(Procedure) \
  11. ENTITY_KIND(ProcGroup) \
  12. ENTITY_KIND(Builtin) \
  13. ENTITY_KIND(ImportName) \
  14. ENTITY_KIND(LibraryName) \
  15. ENTITY_KIND(Nil) \
  16. ENTITY_KIND(Label)
  17. enum EntityKind {
  18. #define ENTITY_KIND(k) GB_JOIN2(Entity_, k),
  19. ENTITY_KINDS
  20. #undef ENTITY_KIND
  21. Entity_Count,
  22. };
  23. String const entity_strings[] = {
  24. #define ENTITY_KIND(k) {cast(u8 *)#k, gb_size_of(#k)-1},
  25. ENTITY_KINDS
  26. #undef ENTITY_KIND
  27. };
  28. enum EntityFlag {
  29. EntityFlag_Visited = 1<<0,
  30. EntityFlag_Used = 1<<1,
  31. EntityFlag_Using = 1<<2,
  32. EntityFlag_Field = 1<<3,
  33. EntityFlag_Param = 1<<4,
  34. EntityFlag_Result = 1<<5,
  35. EntityFlag_ArrayElem = 1<<6,
  36. EntityFlag_Ellipsis = 1<<7,
  37. EntityFlag_NoAlias = 1<<8,
  38. EntityFlag_TypeField = 1<<9,
  39. EntityFlag_Value = 1<<10,
  40. EntityFlag_Sret = 1<<11,
  41. EntityFlag_BitFieldValue = 1<<12,
  42. EntityFlag_PolyConst = 1<<13,
  43. EntityFlag_CVarArg = 1<<20,
  44. };
  45. enum EntityState {
  46. EntityState_Unresolved = 0,
  47. EntityState_InProgress = 1,
  48. EntityState_Resolved = 2,
  49. };
  50. // An Entity is a named "thing" in the language
  51. struct Entity {
  52. EntityKind kind;
  53. u64 id;
  54. u32 flags;
  55. EntityState state;
  56. Token token;
  57. Scope * scope;
  58. Type * type;
  59. Ast * identifier; // Can be nullptr
  60. DeclInfo * decl_info;
  61. DeclInfo * parent_proc_decl; // nullptr if in file/global scope
  62. AstPackage *pkg;
  63. // TODO(bill): Cleanup how `using` works for entities
  64. Entity * using_parent;
  65. Ast * using_expr;
  66. isize order_in_src;
  67. String deprecated_message;
  68. union {
  69. struct {
  70. ExactValue value;
  71. } Constant;
  72. struct {
  73. i32 field_index;
  74. i32 field_src_index;
  75. ExactValue default_value;
  76. String thread_local_model;
  77. Entity * foreign_library;
  78. Ast * foreign_library_ident;
  79. String link_name;
  80. String link_prefix;
  81. bool is_foreign;
  82. bool is_export;
  83. bool default_is_nil;
  84. bool default_is_undef;
  85. bool default_is_location;
  86. bool is_immutable;
  87. } Variable;
  88. struct {
  89. bool is_type_alias;
  90. Type * type_parameter_specialization;
  91. String ir_mangled_name;
  92. } TypeName;
  93. struct {
  94. u64 tags;
  95. Entity * foreign_library;
  96. Ast * foreign_library_ident;
  97. String link_name;
  98. String link_prefix;
  99. bool is_foreign;
  100. bool is_export;
  101. } Procedure;
  102. struct {
  103. Array<Entity *> entities;
  104. } ProcGroup;
  105. struct {
  106. i32 id;
  107. } Builtin;
  108. struct {
  109. String path;
  110. String name;
  111. Scope *scope;
  112. } ImportName;
  113. struct {
  114. Array<String> paths;
  115. String name;
  116. } LibraryName;
  117. i32 Nil;
  118. struct {
  119. String name;
  120. Ast *node;
  121. } Label;
  122. };
  123. };
  124. bool is_entity_kind_exported(EntityKind kind) {
  125. switch (kind) {
  126. case Entity_Builtin:
  127. case Entity_ImportName:
  128. case Entity_LibraryName:
  129. case Entity_Nil:
  130. return false;
  131. }
  132. return true;
  133. }
  134. bool is_entity_exported(Entity *e) {
  135. // TODO(bill): Determine the actual exportation rules for imports of entities
  136. GB_ASSERT(e != nullptr);
  137. if (!is_entity_kind_exported(e->kind)) {
  138. return false;
  139. }
  140. String name = e->token.string;
  141. if (name.len == 0) {
  142. return false;
  143. }
  144. return name[0] != '_';
  145. }
  146. gb_global u64 global_entity_id = 0;
  147. Entity *alloc_entity(EntityKind kind, Scope *scope, Token token, Type *type) {
  148. gbAllocator a = heap_allocator();
  149. Entity *entity = gb_alloc_item(a, Entity);
  150. entity->kind = kind;
  151. entity->state = EntityState_Unresolved;
  152. entity->scope = scope;
  153. entity->token = token;
  154. entity->type = type;
  155. entity->id = ++global_entity_id;
  156. return entity;
  157. }
  158. Entity *alloc_entity_variable(Scope *scope, Token token, Type *type, bool is_immutable, EntityState state = EntityState_Unresolved) {
  159. Entity *entity = alloc_entity(Entity_Variable, scope, token, type);
  160. entity->Variable.is_immutable = is_immutable;
  161. entity->state = state;
  162. return entity;
  163. }
  164. Entity *alloc_entity_using_variable(Entity *parent, Token token, Type *type) {
  165. GB_ASSERT(parent != nullptr);
  166. token.pos = parent->token.pos;
  167. Entity *entity = alloc_entity(Entity_Variable, parent->scope, token, type);
  168. entity->using_parent = parent;
  169. entity->parent_proc_decl = parent->parent_proc_decl;
  170. entity->flags |= EntityFlag_Using;
  171. entity->flags |= EntityFlag_Used;
  172. entity->state = EntityState_Resolved;
  173. return entity;
  174. }
  175. Entity *alloc_entity_constant(Scope *scope, Token token, Type *type, ExactValue value) {
  176. Entity *entity = alloc_entity(Entity_Constant, scope, token, type);
  177. entity->Constant.value = value;
  178. return entity;
  179. }
  180. Entity *alloc_entity_type_name(Scope *scope, Token token, Type *type, EntityState state = EntityState_Unresolved) {
  181. Entity *entity = alloc_entity(Entity_TypeName, scope, token, type);
  182. entity->state = state;
  183. return entity;
  184. }
  185. Entity *alloc_entity_param(Scope *scope, Token token, Type *type, bool is_using, bool is_value) {
  186. bool is_immutable = false;
  187. Entity *entity = alloc_entity_variable(scope, token, type, is_immutable);
  188. entity->flags |= EntityFlag_Used;
  189. entity->flags |= EntityFlag_Param;
  190. entity->state = EntityState_Resolved;
  191. if (is_using) entity->flags |= EntityFlag_Using;
  192. if (is_value) entity->flags |= EntityFlag_Value;
  193. return entity;
  194. }
  195. Entity *alloc_entity_const_param(Scope *scope, Token token, Type *type, ExactValue value, bool poly_const) {
  196. Entity *entity = alloc_entity_constant(scope, token, type, value);
  197. entity->flags |= EntityFlag_Used;
  198. if (poly_const) entity->flags |= EntityFlag_PolyConst;
  199. entity->flags |= EntityFlag_Param;
  200. return entity;
  201. }
  202. Entity *alloc_entity_field(Scope *scope, Token token, Type *type, bool is_using, i32 field_src_index, EntityState state = EntityState_Unresolved) {
  203. Entity *entity = alloc_entity_variable(scope, token, type, false);
  204. entity->Variable.field_src_index = field_src_index;
  205. entity->Variable.field_index = field_src_index;
  206. if (is_using) entity->flags |= EntityFlag_Using;
  207. entity->flags |= EntityFlag_Field;
  208. entity->state = state;
  209. return entity;
  210. }
  211. Entity *alloc_entity_array_elem(Scope *scope, Token token, Type *type, i32 field_src_index) {
  212. Entity *entity = alloc_entity_variable(scope, token, type, false);
  213. entity->Variable.field_src_index = field_src_index;
  214. entity->Variable.field_index = field_src_index;
  215. entity->flags |= EntityFlag_Field;
  216. entity->flags |= EntityFlag_ArrayElem;
  217. entity->state = EntityState_Resolved;
  218. return entity;
  219. }
  220. Entity *alloc_entity_procedure(Scope *scope, Token token, Type *signature_type, u64 tags) {
  221. Entity *entity = alloc_entity(Entity_Procedure, scope, token, signature_type);
  222. entity->Procedure.tags = tags;
  223. return entity;
  224. }
  225. Entity *alloc_entity_proc_group(Scope *scope, Token token, Type *type) {
  226. Entity *entity = alloc_entity(Entity_ProcGroup, scope, token, type);
  227. return entity;
  228. }
  229. Entity *alloc_entity_builtin(Scope *scope, Token token, Type *type, i32 id) {
  230. Entity *entity = alloc_entity(Entity_Builtin, scope, token, type);
  231. entity->Builtin.id = id;
  232. entity->state = EntityState_Resolved;
  233. return entity;
  234. }
  235. Entity *alloc_entity_import_name(Scope *scope, Token token, Type *type,
  236. String path, String name, Scope *import_scope) {
  237. Entity *entity = alloc_entity(Entity_ImportName, scope, token, type);
  238. entity->ImportName.path = path;
  239. entity->ImportName.name = name;
  240. entity->ImportName.scope = import_scope;
  241. entity->state = EntityState_Resolved; // TODO(bill): Is this correct?
  242. return entity;
  243. }
  244. Entity *alloc_entity_library_name(Scope *scope, Token token, Type *type,
  245. Array<String> paths, String name) {
  246. Entity *entity = alloc_entity(Entity_LibraryName, scope, token, type);
  247. entity->LibraryName.paths = paths;
  248. entity->LibraryName.name = name;
  249. entity->state = EntityState_Resolved; // TODO(bill): Is this correct?
  250. return entity;
  251. }
  252. Entity *alloc_entity_nil(String name, Type *type) {
  253. Entity *entity = alloc_entity(Entity_Nil, nullptr, make_token_ident(name), type);
  254. return entity;
  255. }
  256. Entity *alloc_entity_label(Scope *scope, Token token, Type *type, Ast *node) {
  257. Entity *entity = alloc_entity(Entity_Label, scope, token, type);
  258. entity->Label.node = node;
  259. entity->state = EntityState_Resolved;
  260. return entity;
  261. }
  262. Entity *alloc_entity_dummy_variable(Scope *scope, Token token) {
  263. token.string = str_lit("_");
  264. return alloc_entity_variable(scope, token, nullptr, false);
  265. }