void print_function_signature(const type_t *const type, const scope_t *parameters) { separator_t sep = { "", ", " }; print_char('('); for (entity_t const *parameter = parameters->first_entity; parameter != NULL; parameter = parameter->base.next) { if (parameter->kind != ENTITY_PARAMETER) continue; print_string(sep_next(&sep)); const type_t *const param_type = parameter->declaration.type; if (param_type == NULL) { //print_string(parameter->base.symbol->string); print_string("TODO: NULL param_type"); } else { print_string("mut "); print_type_ext(param_type, parameter->base.symbol, NULL); } } print_char(')'); if (type->function.return_type) { print_string(" -> "); print_type(type->function.return_type); } }
/** * Print the second part (the postfix) of a type. * * @param type The type to print. */ static void print_function_type_post(const function_type_t *type, const scope_t *parameters) { print_string("("); bool first = true; if (parameters == NULL) { function_parameter_t *parameter = type->parameters; for( ; parameter != NULL; parameter = parameter->next) { if (first) { first = false; } else { print_string(", "); } print_type(parameter->type); } } else { entity_t *parameter = parameters->entities; for (; parameter != NULL; parameter = parameter->base.next) { if (parameter->kind != ENTITY_PARAMETER) continue; if (first) { first = false; } else { print_string(", "); } const type_t *const param_type = parameter->declaration.type; if (param_type == NULL) { print_string(parameter->base.symbol->string); } else { print_type_ext(param_type, parameter->base.symbol, NULL); } } } if (type->variadic) { if (first) { first = false; } else { print_string(", "); } print_string("..."); } if (first && !type->unspecified_parameters) { print_string("void"); } print_string(")"); intern_print_type_post(type->return_type); }
/** * Print the second part (the postfix) of a type. * * @param type The type to print. */ static void print_function_type_post(const function_type_t *type, const scope_t *parameters) { print_char('('); separator_t sep = { "", ", " }; if (parameters == NULL) { function_parameter_t *parameter = type->parameters; for ( ; parameter != NULL; parameter = parameter->next) { print_string(sep_next(&sep)); print_type(parameter->type); } } else { for (entity_t const *parameter = parameters->first_entity; parameter != NULL; parameter = parameter->base.next) { if (parameter->kind != ENTITY_PARAMETER) continue; print_string(sep_next(&sep)); const type_t *const param_type = parameter->declaration.type; if (param_type == NULL) { print_string(parameter->base.symbol->string); } else { print_type_ext(param_type, parameter->base.symbol, NULL); } } } if (type->variadic) { print_string(sep_next(&sep)); print_string("..."); } if (sep_at_first(&sep) && !type->unspecified_parameters) { print_string("void"); } print_char(')'); print_modifiers(type->modifiers); intern_print_type_post(type->return_type); }
void print_type(const type_t *const type) { print_type_ext(type, NULL, NULL); }
/** * Issue a diagnostic message. */ static void diagnosticvf(const char *const fmt, va_list ap) { for (const char* f = fmt; *f != '\0'; ++f) { if (*f == '%') { ++f; bool extended = false; if (*f == '#') { extended = true; ++f; } switch (*f) { case '%': fputc(*f, stderr); break; case 'c': { const unsigned char val = (unsigned char) va_arg(ap, int); fputc(val, stderr); break; } case 'd': { const int val = va_arg(ap, int); fprintf(stderr, "%d", val); break; } case 's': { const char* const str = va_arg(ap, const char*); fputs(str, stderr); break; } case 'S': { const string_t *str = va_arg(ap, const string_t*); for (size_t i = 0; i < str->size; ++i) { fputc(str->begin[i], stderr); } break; } case 'u': { const unsigned int val = va_arg(ap, unsigned int); fprintf(stderr, "%u", val); break; } case 'Y': { const symbol_t *const symbol = va_arg(ap, const symbol_t*); if (symbol == NULL) fputs("(null)", stderr); else fputs(symbol->string, stderr); break; } case 'E': { const expression_t* const expr = va_arg(ap, const expression_t*); print_expression(expr); break; } case 'Q': { const unsigned qualifiers = va_arg(ap, unsigned); print_type_qualifiers(qualifiers, QUAL_SEP_NONE); break; } case 'T': { const type_t* const type = va_arg(ap, const type_t*); const symbol_t* sym = NULL; if (extended) { sym = va_arg(ap, const symbol_t*); } print_type_ext(type, sym, NULL); break; } case 't': { const token_t *const token = va_arg(ap, const token_t*); print_pp_token(stderr, token); break; } case 'K': { const token_t* const token = va_arg(ap, const token_t*); print_token(stderr, token); break; } case 'k': { if (extended) { bool first = true; va_list* toks = va_arg(ap, va_list*); const char* const delimiter = va_arg(ap, const char*); for (;;) { const token_kind_t tok = va_arg(*toks, token_kind_t); if (tok == 0) break; if (first) { first = false; } else { fputs(delimiter, stderr); } print_token_kind(stderr, tok); } } else { const token_kind_t token = va_arg(ap, token_kind_t); print_token_kind(stderr, token); } break; } case 'N': { entity_t const *const ent = va_arg(ap, entity_t const*); if (extended && is_declaration(ent)) { print_type_ext(ent->declaration.type, ent->base.symbol, NULL); } else { char const *const kind = get_entity_kind_name(ent->kind); symbol_t const *const sym = ent->base.symbol; if (sym) { fprintf(stderr, "%s %s", kind, sym->string); } else { fprintf(stderr, "anonymous %s", kind); } } break; } case 'P': { const source_position_t *pos = va_arg(ap, const source_position_t *); print_source_position(stderr, pos); break; } default: panic("unknown format specifier"); } } else {