static void print_entity(const entity_t *entity) { print_indent(); switch (entity->kind) { case ENTITY_FUNCTION: print_function(&entity->function); break; case ENTITY_CONCEPT: print_concept(&entity->concept); break; case ENTITY_VARIABLE: print_variable(&entity->variable); break; case ENTITY_TYPEALIAS: print_typealias(&entity->typealias); break; case ENTITY_CONSTANT: print_constant(&entity->constant); break; case ENTITY_CONCEPT_FUNCTION: case ENTITY_FUNCTION_PARAMETER: case ENTITY_ERROR: // TODO fprintf(out, "some entity of type '%s'\n", get_entity_kind_name(entity->kind)); break; case ENTITY_TYPE_VARIABLE: case ENTITY_LABEL: break; case ENTITY_INVALID: fprintf(out, "invalid entity (%s)\n", get_entity_kind_name(entity->kind)); break; } }
/** * 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 {