32 .visibility = eVisiblePrivate
37 .visibility = eVisiblePublic
42 .visibility = eVisiblePublic
47 .visibility = eVisiblePrivate
65 static void ctu_resolve_global(
tree_t *sema,
tree_t *
self,
void *user)
75 CTASSERT(expr != NULL || type != NULL);
79 if (!decl->
mut && !
tree_is(real_type, eTreeError))
94 .quals = decl->
mut ? eQualMutable : eQualConst
97 const tree_t *ref = real_type;
98 if (!
tree_is(real_type, eTreeTypeArray))
108 static void ctu_resolve_typealias(
tree_t *sema,
tree_t *
self,
void *user)
134 for (
size_t i = 0; i < len; i++)
138 char *name = field->
name == NULL ?
str_format(arena,
"field%zu", i) : field->name;
144 msg_notify(sema->
reports, &kEvent_DuplicateField, field->
node,
"aggregate decl `%s` has duplicate field `%s`", decl->
name, name);
154 static void ctu_resolve_struct(
tree_t *sema,
tree_t *
self,
void *user)
157 vector_t *items = ctu_collect_fields(sema,
self, decl);
161 static void ctu_resolve_union(
tree_t *sema,
tree_t *
self,
void *user)
164 vector_t *items = ctu_collect_fields(sema,
self, decl);
168 static void ctu_resolve_variant(
tree_t *sema,
tree_t *
self,
void *user)
178 if (!
tree_is(underlying, eTreeTypeDigit))
180 msg_notify(sema->
reports, &kEvent_InvalidEnumUnderlyingType, decl->
node,
"decl `%s` has non-integer underlying type", decl->
name);
186 tree_t *default_case = NULL;
189 for (
size_t i = 0; i < len; i++)
201 if (default_case != NULL)
208 default_case = field;
232 .fn_resolve = ctu_resolve_global
238 .quals = decl->
mut ? eQualMutable : eQualConst
268 .fn_resolve = ctu_resolve_typealias,
269 .fn_resolve_type = ctu_resolve_typealias
282 .fn_resolve = ctu_resolve_struct
295 .fn_resolve = ctu_resolve_union
308 .fn_resolve = ctu_resolve_variant
329 return new_forward(eCtuTagValues, ctu_forward_global(sema, decl));
331 return new_forward(eCtuTagFunctions, ctu_forward_function(sema, decl));
333 return new_forward(eCtuTagTypes, ctu_forward_type(sema, decl));
335 return new_forward(eCtuTagTypes, ctu_forward_union(sema, decl));
337 return new_forward(eCtuTagTypes, ctu_forward_struct(sema, decl));
339 return new_forward(eCtuTagTypes, ctu_forward_variant(sema, decl));
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_TREE_API void tree_set_qualifiers(tree_t *tree, tree_quals_t qualifiers)
CT_PUREFN CT_TREE_API tree_quals_t tree_ty_get_quals(const tree_t *self)
const tree_t * ctu_resolve_storage_type(const tree_t *type)
size_t ctu_resolve_storage_length(const tree_t *type)
tree_t * ctu_sema_rvalue(ctu_sema_t *sema, const ctu_t *expr, const tree_t *implicit_type)
tree_t * ctu_get_int_type(digit_t digit, sign_t sign)
ctu_sema_t ctu_sema_init(tree_t *sema, tree_t *decl, vector_t *block)
tree_t * ctu_sema_type(ctu_sema_t *sema, const ctu_t *type)
void ctu_resolve_function(tree_t *sema, tree_t *self, void *user)
void ctu_resolve_function_type(tree_t *sema, tree_t *self, void *user)
CT_MEMORY_API arena_t * get_global_arena(void)
get the global memory arena
CT_NODISCARD CT_STD_API map_t * map_optimal(size_t size, hash_info_t info, arena_t *arena)
create a new map with an optimal size
CT_STD_API void map_set(map_t *map, const void *key, void *value)
set a key-value pair in a map
CT_NODISCARD CT_PUREFN CT_STD_API void * map_get(const map_t *map, const void *key)
get a value from a map
#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
CT_NOTIFY_API void msg_append(event_builder_t builder, const node_t *node, STA_FORMAT_STRING const char *fmt,...)
append additional information to a message
#define CT_NEVER(...)
assert that a code path is never reached
#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)
CT_TREE_API tree_t * tree_type_reference(const node_t *node, const char *name, const tree_t *reference)
create a reference type
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
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_open_enum(const node_t *node, const char *name, tree_resolve_info_t resolve)
CT_TREE_API tree_cookie_t * tree_get_cookie(tree_t *sema)
return a resolution cookie
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_decl_case(const node_t *node, const char *name, const tree_t *type, tree_t *expr)
CT_TREE_API void tree_set_type(tree_t *self, const tree_t *type)
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)
CT_STD_API const hash_info_t kTypeInfoString
type information for a c style string
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_NODISCARD CT_STD_API vector_t * vector_of(size_t len, arena_t *arena)
create a new vector with a specified length
CT_STD_API void vector_set(vector_t *vector, size_t index, void *value)
set a value in a vector
CT_NODISCARD CT_PUREFN CT_STD_API size_t vector_len(const vector_t *vector)
get the length of a vector
void ctu_apply_attribs(tree_t *sema, tree_t *decl, const vector_t *attribs)
ctu_forward_t ctu_forward_decl(tree_t *sema, ctu_t *decl)
ctu_t * begin_resolve(tree_t *sema, tree_t *self, void *user, ctu_kind_t kind)
STA_DECL char * str_format(arena_t *arena, const char *fmt,...)
an event builder handles adding additional information to an event
tree_linkage_t link
the link type of the declaration
const tree_t * storage
the underlying storage type
a generic vector of pointers