static void handle_attribute_packed_e(const attribute_t *attribute, entity_t *entity) { warn_arguments(attribute); if (entity->kind == ENTITY_STRUCT) { compound_t *compound = &entity->compound; compound->packed = true; /* GCC: Specifying this attribute for `struct' and `union' types is * equivalent to specifying the `packed' attribute on each of the * structure or union members. */ for (entity_t *member = compound->members.first_entity; member != NULL; member = member->base.next) { if (member->kind != ENTITY_COMPOUND_MEMBER) continue; member->declaration.modifiers |= DM_PACKED; } } else if (is_declaration(entity)) { entity->declaration.modifiers |= DM_PACKED; } else { position_t const *const pos = &attribute->pos; warningf(WARN_OTHER, pos, "packed attribute on entity %N ignored", entity); return; } }
mxml_node * node_identify( void * doc, const mxml_char_t * str, parsing_context *ctx ) { mxml_node * doc_node = (mxml_node *)doc; mxml_node * ident_node = NULL; UNUSED_ARG( ctx ); if ( !doc_node ) return NULL; if ( is_declaration ( str ) ) ident_node = create_declaration( doc_node ); else if ( is_comment( str ) ) ident_node = create_comment( doc_node ); else if ( is_unknown( str ) ) ident_node = create_unknown( doc_node ); else if ( is_element( str ) ) ident_node = create_element( XML_T(""), doc_node ); else if ( is_text( str ) ) ident_node = create_text( doc_node ); else ident_node = create_unknown( doc_node ); return ident_node; }
static unsigned get_object_alignment(expression_t const *const expr) { entity_t *ent; switch (expr->kind) { case EXPR_ARRAY_ACCESS: return get_address_alignment(expr->array_access.array_ref); case EXPR_UNARY_DEREFERENCE: return get_address_alignment(expr->unary.value); case EXPR_REFERENCE: ent = expr->reference.entity; break; case EXPR_SELECT: ent = expr->select.compound_entry; break; default: return get_type_alignment(expr->base.type); } assert(is_declaration(ent)); return get_declaration_alignment(&ent->declaration); }
void statement(ecc_context *ctx) { const char *token; token = ctx->lex_look_ahead(ctx); if (is_declaration(token)) { declaration(ctx, token); return; } if (is_alpha(token[0])) { assignment(ctx, token); return; } expression(ctx, token); }
void declaration(ecc_context *ctx, const char *token) { ctx->lex_advance(ctx, str_nlen(token, TOKEN_MAX)); token = ctx->lex_look_ahead(ctx); if (!(is_valid_name(token))) { err_msg("token '"); err_msg(token); err_msg("' not a valid name\n"); die(); } ctx->stack_assign_name(ctx, token); token = ctx->lex_look_ahead(ctx); if (!(is_declaration(token))) { done_declaring(ctx); } }
void handle_entity_attributes(const attribute_t *attributes, entity_t *entity) { if (is_declaration(entity)) { type_t *type = entity->declaration.type; type = handle_type_attributes(attributes, type); entity->declaration.type = type; } decl_modifiers_t modifiers = 0; const attribute_t *attribute = attributes; for ( ; attribute != NULL; attribute = attribute->next) { switch (attribute->kind) { case ATTRIBUTE_GNU_CONST: modifiers |= DM_CONST; break; case ATTRIBUTE_GNU_DEPRECATED: modifiers |= DM_DEPRECATED; break; case ATTRIBUTE_GNU_NOINLINE: modifiers |= DM_NOINLINE; break; case ATTRIBUTE_GNU_NAKED: modifiers |= DM_NAKED; break; case ATTRIBUTE_GNU_PURE: modifiers |= DM_PURE; break; case ATTRIBUTE_GNU_ALWAYS_INLINE: modifiers |= DM_FORCEINLINE; break; case ATTRIBUTE_GNU_CONSTRUCTOR: modifiers |= DM_CONSTRUCTOR; break; case ATTRIBUTE_GNU_DESTRUCTOR: modifiers |= DM_DESTRUCTOR; break; case ATTRIBUTE_GNU_TRANSPARENT_UNION: modifiers |= DM_TRANSPARENT_UNION; break; case ATTRIBUTE_GNU_USED: modifiers |= DM_USED; break; case ATTRIBUTE_GNU_UNUSED: modifiers |= DM_UNUSED; break; case ATTRIBUTE_GNU_DLLIMPORT: modifiers |= DM_DLLIMPORT; break; case ATTRIBUTE_GNU_DLLEXPORT: modifiers |= DM_DLLEXPORT; break; case ATTRIBUTE_GNU_WEAK: modifiers |= DM_WEAK; break; case ATTRIBUTE_GNU_WEAK_IMPORT: modifiers |= DM_WEAK; break; case ATTRIBUTE_GNU_LEAF: modifiers |= DM_LEAF; break; case ATTRIBUTE_GNU_GNU_INLINE: modifiers |= DM_GNU_INLINE; break; case ATTRIBUTE_MS_DLLIMPORT: modifiers |= DM_DLLIMPORT; break; case ATTRIBUTE_MS_DLLEXPORT: modifiers |= DM_DLLEXPORT; break; case ATTRIBUTE_MS_NAKED: modifiers |= DM_NAKED; break; case ATTRIBUTE_MS_NOINLINE: modifiers |= DM_NOINLINE; break; case ATTRIBUTE_MS_THREAD: modifiers |= DM_THREAD; break; case ATTRIBUTE_MS_DEPRECATED: modifiers |= DM_DEPRECATED; break; case ATTRIBUTE_MS_RESTRICT: modifiers |= DM_RESTRICT; break; case ATTRIBUTE_MS_NOALIAS: modifiers |= DM_NOALIAS; break; case ATTRIBUTE_GNU_ALIAS: handle_attribute_alias(attribute, entity); break; case ATTRIBUTE_GNU_PACKED: handle_attribute_packed_e(attribute, entity); break; case ATTRIBUTE_GNU_ASM: handle_attribute_asm(attribute, entity); break; case ATTRIBUTE_GNU_VISIBILITY: handle_attribute_visibility(attribute, entity); break; case ATTRIBUTE_MS_ALIGN: case ATTRIBUTE_GNU_ALIGNED: handle_attribute_aligned(attribute, entity); break; case ATTRIBUTE_GNU_NORETURN: case ATTRIBUTE_MS_NORETURN: modifiers |= DM_NORETURN; break; default: break; } } if (modifiers != 0) { switch (entity->kind) { case ENTITY_UNION: case ENTITY_STRUCT: entity->compound.modifiers |= modifiers; break; case ENTITY_TYPEDEF: case ENTITY_COMPOUND_MEMBER: case ENTITY_VARIABLE: case ENTITY_FUNCTION: entity->declaration.modifiers |= modifiers; break; default: /* TODO: warning */ 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 {