19 case eDigitChar:
return (ty.
sign == eSignUnsigned) ?
"unsigned char" :
"char";
20 case eDigitShort:
return (ty.
sign == eSignUnsigned) ?
"unsigned short" :
"short";
21 case eDigitInt:
return (ty.
sign == eSignUnsigned) ?
"unsigned int" :
"int";
22 case eDigitLong:
return (ty.
sign == eSignUnsigned) ?
"unsigned long long" :
"long long";
23 case eDigitSize:
return (ty.
sign == eSignSigned) ?
"ptrdiff_t" :
"size_t" ;
24 case eDigitPtr:
return (ty.
sign == eSignSigned) ?
"intptr_t" :
"uintptr_t";
26 case eDigit8:
return (ty.
sign == eSignUnsigned) ?
"uint8_t" :
"int8_t";
27 case eDigit16:
return (ty.
sign == eSignUnsigned) ?
"uint16_t" :
"int16_t";
28 case eDigit32:
return (ty.
sign == eSignUnsigned) ?
"uint32_t" :
"int32_t";
29 case eDigit64:
return (ty.
sign == eSignUnsigned) ?
"uint64_t" :
"int64_t";
31 case eDigitFast8:
return (ty.
sign == eSignUnsigned) ?
"uint_fast8_t" :
"int_fast8_t";
32 case eDigitFast16:
return (ty.
sign == eSignUnsigned) ?
"uint_fast16_t" :
"int_fast16_t";
33 case eDigitFast32:
return (ty.
sign == eSignUnsigned) ?
"uint_fast32_t" :
"int_fast32_t";
34 case eDigitFast64:
return (ty.
sign == eSignUnsigned) ?
"uint_fast64_t" :
"int_fast64_t";
36 case eDigitLeast8:
return (ty.
sign == eSignUnsigned) ?
"uint_least8_t" :
"int_least8_t";
37 case eDigitLeast16:
return (ty.
sign == eSignUnsigned) ?
"uint_least16_t" :
"int_least16_t";
38 case eDigitLeast32:
return (ty.
sign == eSignUnsigned) ?
"uint_least32_t" :
"int_least32_t";
39 case eDigitLeast64:
return (ty.
sign == eSignUnsigned) ?
"uint_least64_t" :
"int_least64_t";
41 case eDigitFloat:
return "float";
42 case eDigitDouble:
return "double";
57 if (quals & eQualAtomic) {
vector_push(&vec,
"_Atomic"); }
58 if (quals & eQualVolatile) {
vector_push(&vec,
"volatile"); }
70 :
str_format(emit->arena,
"%s (*%s%s)(%s)", result, quals, name, params);
75 const char *tmp = (name == NULL) ?
"*" :
str_format(emit->
arena,
"*%s", name);
80 static const char *format_c89_enum(
c89_emit_t *emit,
const ssa_type_t *type,
const char *name,
const char *quals)
82 const char *padding =
ctu_strlen(quals) > 0 ?
" " :
"";
87 :
str_format(emit->arena,
"%s%s%s_underlying_t", quals, padding, type->name);
90 static const char *format_c89_struct(
c89_emit_t *emit,
const ssa_type_t *type,
const char *name,
const char *quals)
94 :
str_format(emit->arena,
"%sstruct %s", quals, type->name);
101 const char *quals = get_quals(type->
quals, flags, emit->
arena);
105 case eTypeUnit:
return (name != NULL)
109 case eTypeBool:
return (name != NULL)
115 return (name != NULL)
120 case eTypeOpaque:
return (name != NULL)
124 case eTypeClosure:
return format_c89_closure(emit, quals, type->
closure, name);
125 case eTypePointer:
return format_c89_pointer(emit, type->
pointer, name);
127 case eTypeEnum:
return format_c89_enum(emit, type, name, quals);
129 case eTypeStruct:
return format_c89_struct(emit, type, name, quals);
131 case eTypeEmpty:
CT_NEVER(
"cannot emit empty type `%s`", type->
name);
150 return variadic ?
"" :
"void";
154 for (
size_t i = 0; i < len; i++)
CT_NODISCARD CT_PUREFN CT_BASE_API size_t ctu_strlen(const char *str)
get the length of a string not including the null terminator equivalent to strlen but with safety che...
#define CT_NEVER(...)
assert that a code path is never reached
#define CTASSERT(expr)
assert a condition, prints the condition as a message
CT_NODISCARD CT_STD_API char * str_join(const char *sep, const vector_t *parts, arena_t *arena)
join strings
CT_NODISCARD STA_FORMAT_STRING const char * fmt
tree_quals_t
all type qualifiers
CT_TREE_API const char * digit_name(digit_t digit)
get the pretty name of a digit
CT_NODISCARD CT_PUREFN CT_STD_API size_t typevec_len(const typevec_t *vec)
get the length of a vector
CT_NODISCARD CT_PUREFN CT_STD_API void * typevec_offset(const typevec_t *vec, size_t index)
get a pointer to the value at the given index
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_push(vector_t **vector, void *value)
push a value onto the end of a vector
CT_STD_API void vector_set(vector_t *vector, size_t index, void *value)
set a value in a vector
STA_DECL char * str_format(arena_t *arena, const char *fmt,...)
ssa underlying storage type
size_t size
the number of elements in the storage
const ssa_type_t * type
the internal storage type
const ssa_type_t * result
const ssa_type_t * pointer
ssa_type_closure_t closure
ssa_type_pointer_t pointer
A vector with a fixed type size.
a generic vector of pointers
const char * type_to_string(const ssa_type_t *type, arena_t *arena)
const char * c89_format_type(c89_emit_t *emit, const ssa_type_t *type, const char *name, type_format_t flags)
const char * c89_format_storage(c89_emit_t *emit, ssa_storage_t storage, const char *name, type_format_t flags)
const char * c89_format_params(c89_emit_t *emit, typevec_t *params, bool variadic)