34 self->resolve = resolve;
50 if (
tree_is(decl, eTreeError)) {
return inner; }
53 if (res == NULL) {
return inner; }
56 if (index != SIZE_MAX)
60 return tree_error(decl->
node, &kEvent_CyclicDependency,
"cyclic dependency");
76 if (
tree_is(decl, eTreeError)) {
return inner; }
78 if (
tree_is(decl, eTreePartial))
89 if (!
tree_is(decl, eTreeDeclFunction)) {
return inner; }
92 if (res == NULL) {
return inner; }
107 if (index != SIZE_MAX)
111 return tree_error(decl->
node, &kEvent_CyclicDependency,
"cyclic dependency");
116 tree_t *result = resolve_type_inner(decl);
124 const node_t *node,
const char *name,
127 tree_t *
self = decl_open(node, name, type, eTreeDeclGlobal, NULL);
142 tree_t *
self = decl_open(node, name, type, eTreeDeclGlobal, dup_resolve_info(&resolve));
149 if (signature != NULL)
156 tree_t *
self = decl_open(node, name, signature, eTreeDeclFunction, dup_resolve_info(&resolve));
157 self->params = signature == NULL ? NULL : signature->
params;
164 decl_close(
self, eTreeDeclGlobal);
165 self->initial = value;
173 decl_close(
self, eTreeDeclFunction);
182 "decl %s has %zu params, expected %zu%s parameter(s)",
184 vector_len(params), (arity == eArityFixed) ?
"" :
" or more"
190 return tree_decl(eTreeDeclParam, node, type, name, eQualNone);
195 return tree_decl(eTreeDeclField, node, type, name, eQualNone);
208 self->case_value = expr;
214 return decl_open(node, name, NULL, eTreePartial, dup_resolve_info(&resolve));
225 const node_t *node,
const char *name,
const tree_t *signature,
229 tree_t *
self = decl_open(node, name, signature, eTreeDeclFunction, NULL);
230 self->params = params;
231 self->locals = locals;
238 tree_t *
self =
tree_decl(eTreeDeclAttrib, node, NULL, name, eQualNone);
239 self->params = params;
255 self->attrib = attrib;
260 CTASSERTF(tree != NULL && name != NULL,
"(tree=%p, name=%p)", (
void*)tree, (
void*)name);
276 if (type == NULL)
return NULL;
278 if (
tree_is(type, eTreeTypeAlias))
288 static void check_aggregate_fields(
vector_t *fields)
291 for (
size_t i = 0; i < len; i++)
300 check_aggregate_fields(fields);
302 tree_t *
self = decl_open(node, name, NULL, eTreeTypeStruct, NULL);
303 self->fields = fields;
310 tree_t *
self = decl_open(node, name, NULL, eTreeTypeStruct, dup_resolve_info(&resolve));
317 decl_close(
self, eTreeTypeStruct);
318 self->fields = fields;
319 check_aggregate_fields(fields);
328 check_aggregate_fields(fields);
330 tree_t *
self = decl_open(node, name, NULL, eTreeTypeUnion, NULL);
331 self->fields = fields;
338 tree_t *
self = decl_open(node, name, NULL, eTreeTypeUnion, dup_resolve_info(&resolve));
345 decl_close(
self, eTreeTypeUnion);
346 self->fields = fields;
347 check_aggregate_fields(fields);
354 #define CHECK_CASE(TY) CTASSERTF(tree_is(TY, eTreeDeclCase), "expected case, got %s", tree_to_string(TY));
356 static void check_enum_cases(
vector_t *cases)
359 for (
size_t i = 0; i < len; i++)
368 tree_t *
self = decl_open(node, name, NULL, eTreeTypeEnum, NULL);
376 tree_t *
self = decl_open(node, name, NULL, eTreeTypeEnum, dup_resolve_info(&resolve));
377 self->underlying = NULL;
379 self->default_case = NULL;
385 decl_close(
self, eTreeTypeEnum);
387 self->underlying = underlying;
391 self->default_case = default_case;
395 check_enum_cases(cases);
396 if (default_case != NULL)
CT_PUREFN CT_TREE_API const char * tree_get_name(const tree_t *tree)
CT_PUREFN CT_TREE_API const tree_t * tree_get_type(const tree_t *tree)
CT_PUREFN CT_TREE_API bool tree_is(const tree_t *self, tree_kind_t kind)
CT_TREE_API void tree_set_storage(tree_t *tree, tree_storage_t storage)
CT_PUREFN CT_TREE_API tree_arity_t tree_fn_get_arity(const tree_t *self)
CT_TREE_API const char * tree_to_string(const tree_t *self)
CT_BEGIN_API CT_TREE_API const char * tree_kind_to_string(tree_kind_t kind)
CT_PUREFN CT_TREE_API const vector_t * tree_fn_get_params(const tree_t *self)
CT_LOCAL tree_t * tree_decl(tree_kind_t kind, const node_t *node, const tree_t *type, const char *name, tree_quals_t quals)
#define TREE_EXPECT(SELF, KIND)
tree_t * tree_decl_attrib(const node_t *node, const char *name, vector_t *params)
CT_MEMORY_API arena_t * get_global_arena(void)
get the global memory arena
#define CT_UNUSED(x)
mark a variable as unused
CT_NODISCARD CT_ARENA_API void * arena_memdup(STA_READS(size) const void *ptr, size_t size, arena_t *arena)
duplicate a memory region from a custom allocator duplicate a region of memory and return a pointer t...
CT_NOTIFY_API event_builder_t msg_notify(INOUT_NOTNULL logger_t *logs, const diagnostic_t *diagnostic, const node_t *node, STA_FORMAT_STRING const char *fmt,...)
notify the logger of a new message
#define CTASSERT(expr)
assert a condition, prints the condition as a message
#define CTASSERTF(expr,...)
assert a condition with a message and optional format arguments
tree_t * tree_open_decl(const node_t *node, const char *name, tree_resolve_info_t resolve)
tree_t * tree_type_alias(const node_t *node, const char *name, const tree_t *type, tree_quals_t quals)
tree_t * tree_open_function(const node_t *node, const char *name, const tree_t *signature, tree_resolve_info_t resolve)
tree_t * tree_decl_enum(const node_t *node, const char *name, const tree_t *underlying, vector_t *fields, tree_t *default_case)
tree_t * tree_decl_struct(const node_t *node, const char *name, vector_t *fields)
void tree_close_enum(tree_t *self, const tree_t *underlying, vector_t *cases, tree_t *default_case)
void tree_close_union(tree_t *self, vector_t *fields)
tree_t * tree_open_global(const node_t *node, const char *name, const tree_t *type, tree_resolve_info_t resolve)
tree_quals_t
all type qualifiers
void tree_close_function(tree_t *self, tree_t *body)
tree_t * tree_decl_field(const node_t *node, const char *name, const tree_t *type)
tree_t * tree_open_struct(const node_t *node, const char *name, tree_resolve_info_t resolve)
tree_t * tree_decl_global(const node_t *node, const char *name, tree_storage_t storage, const tree_t *type, tree_t *value)
CT_TREE_API tree_t * tree_error(const node_t *node, const diagnostic_t *diagnostic, const char *message,...)
tree_t * tree_decl_union(const node_t *node, const char *name, vector_t *fields)
tree_t * tree_open_enum(const node_t *node, const char *name, tree_resolve_info_t resolve)
tree_t * tree_decl_param(const node_t *node, const char *name, const tree_t *type)
tree_t * tree_open_union(const node_t *node, const char *name, tree_resolve_info_t resolve)
void tree_close_global(tree_t *self, tree_t *value)
void tree_close_struct(tree_t *self, vector_t *fields)
tree_t * tree_resolve_type(tree_cookie_t *cookie, const tree_t *decl)
tree_kind_t
all tree node types
tree_t * tree_decl_case(const node_t *node, const char *name, const tree_t *type, tree_t *expr)
const tree_t * tree_follow_type(const tree_t *type)
void tree_add_local(tree_t *self, tree_t *decl)
tree_t * tree_alias(const tree_t *tree, const char *name)
void tree_close_decl(tree_t *self, const tree_t *other)
tree_t * tree_resolve(tree_cookie_t *cookie, const tree_t *decl)
void tree_set_attrib(tree_t *self, const tree_attribs_t *attrib)
tree_t * tree_decl_function(const node_t *node, const char *name, const tree_t *signature, const vector_t *params, vector_t *locals, tree_t *body)
tree_t * tree_decl_local(const node_t *node, const char *name, tree_storage_t storage, const tree_t *type)
CT_NODISCARD CT_PUREFN CT_STD_API void * vector_get(const vector_t *vector, size_t index)
get a value from a vector
CT_NODISCARD CT_STD_API vector_t * vector_new(size_t size, arena_t *arena)
create a new vector with an initial capacity
CT_STD_API void vector_push(vector_t **vector, void *value)
push a value onto the end of a vector
CT_STD_API void vector_drop(vector_t *vector)
pop a value from the end of a vector
CT_PUREFN CT_STD_API size_t vector_find(vector_t *vector, const void *element)
find an element in a vector searches via pointer equality
CT_NODISCARD CT_PUREFN CT_STD_API size_t vector_len(const vector_t *vector)
get the length of a vector
a position in a source file
tree_resolve_type_t fn_resolve_type
tree_resolve_t fn_resolve
const tree_t * storage
the underlying storage type
const char * name
the name of the declaration
const tree_resolve_info_t * resolve
the resolve configuration of the declaration, NULL if resolved
a generic vector of pointers