/* * return the next definition you see */ definition * get_definition (void) { definition *defp; token tok; defp = ALLOC (definition); get_token (&tok); switch (tok.kind) { case TOK_STRUCT: def_struct (defp); break; case TOK_UNION: def_union (defp); break; case TOK_TYPEDEF: def_typedef (defp); break; case TOK_ENUM: def_enum (defp); break; case TOK_PROGRAM: def_program (defp); break; case TOK_CONST: def_const (defp); break; case TOK_EOF: free (defp); return (NULL); default: error ("definition keyword expected"); } scan (TOK_SEMICOLON, &tok); isdefined (defp); return (defp); }
// Write a definition for a type and return its name (possibly a typedef). // If the type was already written, return mangle only. // Note about mangling: // - The main issue is making anonymous, structural types like tuples work. To // get proper defined C behavior, we must use the same struct for the same // types across all translation units. For example, (int, bool) must always // be backed by the same C struct. That is, the C struct must consist of the // same members (name and type) and have the same name. // - Some types must be disambiguated. (Consider different structs nested in // different functions, but with the same name.) // - This is no "public" mangling, as it's needed e.g. for C++ symbols. It's // merely needed for accomplishing the above goals. // - This function also returns a valid C type name. This is a misguided attempt // to stuff everything into one function, instead of requiring one function // to get the typename, and one to get the mangle, or maybe even just having // a bool parameter telling whether to return a type or a mangle. static char* def_type(CTX *ctx, struct ir_type t) { // @ALL ir_type_type switch (t.type) { case IR_TYPE_error: abort(); case IR_TYPE_any: return NULL; case IR_TYPE_tuntyped: return (char *)"void"; case IR_TYPE_tbool: return (char *)"bool"; case IR_TYPE_tint: return def_int(t); case IR_TYPE_tdouble: return (char *)"double"; case IR_TYPE_tptr: return def_ptr(ctx, *GET_UNION(IR_TYPE, tptr, &t)); case IR_TYPE_tstruct: return def_struct(ctx, *GET_UNION(IR_TYPE, tstruct, &t)); case IR_TYPE_ttuple: return def_tuple(ctx, *GET_UNION(IR_TYPE, ttuple, &t), false); case IR_TYPE_tcompound: return def_tuple(ctx, *GET_UNION(IR_TYPE, tcompound, &t), true); case IR_TYPE_tfn: return def_fn_type(ctx, *GET_UNION(IR_TYPE, tfn, &t)); case IR_TYPE_tstackclosure: return (char *)CLOSURE_MANGLE; case IR_TYPE_tarray: return def_array_type(ctx, *GET_UNION(IR_TYPE, tarray, &t)); case IR_TYPE_tslice: return (char *)SLICE_MANGLE; default: assert(false); } }