27 #define TREE_KIND(ID, NAME, TAGS) case ID: return NAME;
30 default:
CT_NEVER(
"invalid tree kind %d", kind);
34 static const char *length_name(
size_t length,
arena_t *arena)
36 if (length == SIZE_MAX)
return "unbounded";
56 return str_format(arena,
"{ error: %s }", self->message);
61 case eTreeTypePointer:
64 case eTreeTypeReference:
74 if (has_name(self->kind))
95 return self->kind == kind;
109 # define EXPECT_STORAGE_DECL(SELF) CTASSERTF(tree_has_storage(SELF), "only globals and locals can have storage, got %s", tree_to_string(SELF))
111 # define EXPECT_STORAGE_DECL(SELF) (void)0
116 return tree_is(
self, eTreeDeclGlobal) ||
tree_is(
self, eTreeDeclLocal);
123 return self->storage;
131 CTASSERTF((quals & (eQualConst | eQualMutable)) != (eQualConst | eQualMutable),
"global %s has both const and mutable quals",
tree_to_string(
self));
172 case eTreeTypeClosure:
return self->return_type;
184 case eTreeTypeClosure:
return self->params;
195 case eTreeTypeClosure:
return self->arity;
196 case eTreeDeclFunction: {
212 for (
size_t i = 0; i < len; i++)
228 return find_field(self->fields, name);
235 return find_field(self->cases, name);
242 case eTreeTypePointer:
243 case eTreeTypeReference:
262 CTASSERTF((quals & (eQualConst | eQualMutable)) != (eQualConst | eQualMutable),
"type %s has both const and mutable quals",
tree_to_string(
self));
272 case eTreeTypePointer:
273 case eTreeTypeReference:
CT_PUREFN CT_TREE_API tree_kind_t tree_get_kind(const tree_t *tree)
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_CONSTFN CT_LOCAL bool kind_has_tag(tree_kind_t kind, tree_tags_t tags)
#define TREE_EXPECT(SELF, KIND)
vector_t * tree_enum_get_cases(const tree_t *self)
tree_storage_t get_storage(const tree_t *self)
bool tree_has_vis(const tree_t *self, tree_visibility_t visibility)
const tree_t * tree_ty_load_type(const tree_t *self)
get the type of a type after it has been loaded
const tree_attribs_t * tree_get_attrib(const tree_t *self)
tree_quals_t tree_ty_get_quals(const tree_t *self)
tree_t * tree_ty_get_field(const tree_t *self, const char *name)
bool tree_is(const tree_t *self, tree_kind_t kind)
const char * tree_to_string(const tree_t *self)
const vector_t * tree_fn_get_params(const tree_t *self)
const tree_t * tree_get_storage_type(const tree_t *self)
const char * tree_kind_to_string(tree_kind_t kind)
tree_t * tree_ty_get_case(const tree_t *self, const char *name)
bool tree_has_storage(const tree_t *self)
bool tree_ty_is_address(const tree_t *type)
tree_quals_t tree_get_storage_quals(const tree_t *self)
char * tree_to_string_arena(const tree_t *self, arena_t *arena)
#define EXPECT_STORAGE_DECL(SELF)
tree_arity_t tree_fn_get_arity(const tree_t *self)
size_t tree_get_storage_size(const tree_t *self)
const tree_t * tree_fn_get_return(const tree_t *self)
CT_NODISCARD CT_PUREFN CT_BASE_API bool str_equal(const char *lhs, const char *rhs)
compare strings equality
CT_MEMORY_API arena_t * get_global_arena(void)
get the global memory arena
CT_NODISCARD CT_ARENA_API char * arena_strdup(const char *str, arena_t *arena)
allocate a copy of a string from a custom allocator
#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_quals_t
all type qualifiers
tree_visibility_t
symbol visibility
tree_kind_t
all tree node types
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_PUREFN CT_STD_API size_t vector_len(const vector_t *vector)
get the length of a vector
STA_DECL char * str_format(arena_t *arena, const char *fmt,...)
tree_visibility_t visibility
the visibility of the declaration
tree_quals_t quals
the qualifiers for the storage
size_t length
the count of elements
const tree_t * storage
the underlying storage type
a generic vector of pointers