/** * Print the first part (the prefix) of a type. * * @param type The type to print. */ static void print_function_type_pre(const function_type_t *type) { switch (type->linkage) { case LINKAGE_C: if (dialect.cpp) print_string("extern \"C\" "); break; case LINKAGE_CXX: if (!dialect.cpp) print_string("extern \"C++\" "); break; } print_type_qualifiers(type->base.qualifiers, QUAL_SEP_END); intern_print_type_pre(type->return_type); cc_kind_t cc = type->calling_convention; restart: switch (cc) { case CC_CDECL: print_string(" __cdecl"); break; case CC_STDCALL: print_string(" __stdcall"); break; case CC_FASTCALL: print_string(" __fastcall"); break; case CC_THISCALL: print_string(" __thiscall"); break; case CC_DEFAULT: if (default_calling_convention != CC_CDECL) { /* show the default calling convention if its not cdecl */ cc = default_calling_convention; goto restart; } break; } }
/** * Prints the prefix part of a pointer type. * * @param type The pointer type. */ static void print_pointer_type_pre(const pointer_type_t *type) { type_t const *const points_to = type->points_to; intern_print_type_pre(points_to); if (points_to->kind == TYPE_ARRAY || points_to->kind == TYPE_FUNCTION) print_string(" ("); print_char('*'); print_type_qualifiers(type->base.qualifiers, QUAL_SEP_START); }
/** * Prints a compound type. * * @param kind The name of the compound kind. * @param type The compound type. */ static void print_compound_type(char const *const kind, compound_type_t const *const type) { print_type_qualifiers(type->base.qualifiers, QUAL_SEP_END); print_string(kind); compound_t *compound = type->compound; symbol_t *symbol = compound->base.symbol; if (symbol != NULL) { print_string(symbol->string); } else { print_compound_definition(compound); } }
/** * Prints an enum type. * * @param type The enum type. */ static void print_type_enum(const enum_type_t *type) { print_type_qualifiers(type->base.base.qualifiers, QUAL_SEP_END); print_string("enum "); enum_t *enume = type->enume; symbol_t *symbol = enume->base.symbol; if (symbol != NULL) { print_string(symbol->string); } else { print_enum_definition(enume); } }
/** * Prints the postfix part of an array type. * * @param type The array type. */ static void print_array_type_post(const array_type_t *type) { print_char('['); if (type->is_static) { print_string("static "); } print_type_qualifiers(type->base.qualifiers, QUAL_SEP_END); if (type->size_expression != NULL && (print_implicit_array_size || !type->has_implicit_size)) { print_expression(type->size_expression); } print_char(']'); intern_print_type_post(type->element_type); }
/** * Prints the prefix part of a pointer type. * * @param type The pointer type. */ static void print_pointer_type_pre(const pointer_type_t *type) { type_t const *const points_to = type->points_to; intern_print_type_pre(points_to); if (points_to->kind == TYPE_ARRAY || points_to->kind == TYPE_FUNCTION) print_string(" ("); variable_t *const variable = type->base_variable; if (variable != NULL) { print_string(" __based("); print_string(variable->base.base.symbol->string); print_string(") "); } print_char('*'); print_type_qualifiers(type->base.qualifiers, QUAL_SEP_START); }
/** * Prints a compound type. * * @param type The compound type. */ static void print_compound_type(const compound_type_t *type) { print_type_qualifiers(type->base.qualifiers, QUAL_SEP_END); if (type->base.kind == TYPE_COMPOUND_STRUCT) { print_string("struct "); } else { assert(type->base.kind == TYPE_COMPOUND_UNION); print_string("union "); } compound_t *compound = type->compound; symbol_t *symbol = compound->base.symbol; if (symbol != NULL) { print_string(symbol->string); } else { print_compound_definition(compound); } }
static void print_template_type_pre(type_t const *const type) { print_type_qualifiers(type->base.qualifiers, QUAL_SEP_END); print_string("$T$"); }
/** * Prints the prefix part of a typedef type. * * @param type The typedef type. */ static void print_typedef_type_pre(const typedef_type_t *const type) { print_type_qualifiers(type->base.qualifiers, QUAL_SEP_END); print_string(type->typedefe->base.symbol->string); }
/** * Prints the name of an imaginary type. * * @param type The type. */ static void print_imaginary_type(const atomic_type_t *type) { print_type_qualifiers(type->base.qualifiers, QUAL_SEP_END); print_string("_Imaginary "); print_atomic_kinds(type->akind); }
/** * Prints the name of a complex type. * * @param type The type. */ static void print_complex_type(const atomic_type_t *type) { print_type_qualifiers(type->base.qualifiers, QUAL_SEP_END); print_string("_Complex "); print_atomic_kinds(type->akind); }
/** * 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 {