31 CTASSERTF(
vector_len(path) == 1,
"expected 1 path element but got `%s`", attrib_name(path, arena));
66 #define MALFORMED_ENTRY(REPORTS, NODE) msg_notify(REPORTS, &kEvent_MalformedAttribute, NODE, "malformed entry point type, must be either `gui` or `cli`")
102 case 0:
return eLinkEntryCli;
103 case 1:
return choose_linkage(sema,
vector_tail(args));
106 msg_notify(sema->
reports, &kEvent_IncorrectParamCount,
tree_get_node(decl),
"entry attribute takes at most 1 argument, ignoring extra arguments");
107 return eLinkEntryCli;
123 if (!
tree_is(decl, eTreeDeclFunction))
125 msg_notify(sema->
reports, &kEvent_InvalidAttributeApplication, decl->
node,
"entry attribute can only be applied to functions");
130 if (old->
link != eLinkModule && old->
link != eLinkExport)
132 msg_notify(sema->
reports, &kEvent_InvalidAttributeApplication, decl->
node,
"entry attribute can only be applied to public functions");
137 copy->
link = get_linkage(sema, decl, args);
143 if (!
tree_is(decl, eTreeDeclFunction))
145 msg_notify(sema->
reports, &kEvent_InvalidAttributeApplication, decl->
node,
"deprecated attribute can only be applied to functions");
152 msg_notify(sema->
reports, &kEvent_DuplicateAttribute, decl->
node,
"deprecated attribute already applied");
156 const char *msg = get_first_string(sema, decl, args);
157 if (msg == NULL) {
return; }
166 if (!
tree_is(decl, eTreeDeclFunction))
168 msg_notify(sema->
reports, &kEvent_InvalidAttributeApplication, decl->
node,
"section attribute can only be applied to functions");
175 msg_notify(sema->
reports, &kEvent_DuplicateAttribute, decl->
node,
"section attribute already applied");
179 const char *msg = get_first_string(sema, decl, args);
180 if (msg == NULL) {
return; }
189 if (!
tree_is(decl, eTreeDeclFunction))
191 msg_notify(sema->
reports, &kEvent_InvalidAttributeApplication, decl->
node,
"`extern` can only be applied to functions");
198 msg_notify(sema->
reports, &kEvent_DuplicateAttribute, decl->
node,
"`extern` already applied to this symbol");
203 copy->
link = eLinkImport;
210 const char *msg = get_first_string(sema, decl, args);
211 if (msg == NULL) {
return; }
222 if (!
tree_is(decl, eTreeTypeStruct))
224 msg_notify(sema->
reports, &kEvent_InvalidAttributeApplication, decl->
node,
"layout attribute can only be applied to structs");
233 ctu_attrib_t *entry = attrib_create(
"entry", apply_entry, arena);
236 ctu_attrib_t *deprecated = attrib_create(
"deprecated", apply_deprecated, arena);
239 ctu_attrib_t *section = attrib_create(
"section", apply_section, arena);
242 ctu_attrib_t *attrib_extern = attrib_create(
"extern", apply_extern, arena);
245 ctu_attrib_t *layout = attrib_create(
"layout", apply_layout, arena);
253 for (
size_t i = 0; i < len; i++)
void ctu_apply_attribs(tree_t *sema, tree_t *decl, const vector_t *attribs)
#define MALFORMED_ENTRY(REPORTS, NODE)
void ctu_init_attribs(tree_t *sema, arena_t *arena)
CT_PUREFN CT_TREE_API const node_t * tree_get_node(const tree_t *tree)
CT_PUREFN CT_TREE_API const char * tree_get_name(const tree_t *tree)
CT_PUREFN CT_TREE_API bool tree_is(const tree_t *self, tree_kind_t kind)
CT_TREE_API const tree_attribs_t * tree_get_attrib(const tree_t *self)
ctu_attrib_t * ctu_get_attrib(tree_t *sema, const char *name)
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
#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...
#define ARENA_MALLOC(size, name, parent, arena)
allocate memory from a custom allocator
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
CT_NODISCARD CT_STD_API char * str_join(const char *sep, const vector_t *parts, arena_t *arena)
join strings
tree_linkage_t
the linkage of a declaration
CT_TREE_API void * tree_module_set(tree_t *self, size_t tag, const char *name, void *value)
set a declaration in the current module
CT_TREE_API void tree_set_attrib(tree_t *self, const tree_attribs_t *attrib)
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 void * vector_tail(const vector_t *vector)
get the last element of 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_attrib_apply_t)(tree_t *sema, tree_t *decl, const vector_t *args)
ctu_attrib_apply_t fn_apply
const vector_t * attrib_path
const vector_t * attrib_args
const char * mangle
override the mangle of the declaration
const char * deprecated
the reason for deprecation, or NULL if not deprecated
tree_linkage_t link
the link type of the declaration
const char * section
override the section of the declaration
a generic vector of pointers