} else if(strcmp(option, "pg") == 0) {
set_be_option("gprof");
add_flag(&ldflags_obst, "-pg");
- } else if(strcmp(option, "pedantic") == 0) {
+ } else if(strcmp(option, "pedantic") == 0
+ || strcmp(option, "ansi") == 0) {
fprintf(stderr, "warning: ignoring gcc option '%s'\n", arg);
} else if(strcmp(option, "shared") == 0) {
add_flag(&ldflags_obst, "-shared");
bool invalid;
bool have_arguments;
union {
- size_t value;
- string_t string;
+ size_t value;
+ string_t string;
+ atomic_type_kind_t akind;
} u;
};
/* at least: byte, word, pointer, list of machine modes
* __XXX___ is interpreted as XXX */
add_anchor_token(')');
- expect(T_IDENTIFIER);
+
+ if (token.type != T_IDENTIFIER) {
+ expect(T_IDENTIFIER);
+ }
+
+ /* This isn't really correct, the backend should provide a list of machine
+ * specific modes (according to gcc philosophy that is...) */
+ const char *symbol_str = token.v.symbol->string;
+ if(strcmp_underscore("QI", symbol_str) == 0) {
+ attribute->u.akind = ATOMIC_TYPE_CHAR;
+ } else if (strcmp_underscore("HI", symbol_str) == 0) {
+ attribute->u.akind = ATOMIC_TYPE_SHORT;
+ } else if(strcmp_underscore("SI", symbol_str) == 0) {
+ attribute->u.akind = ATOMIC_TYPE_INT;
+ } else if(strcmp_underscore("DI", symbol_str) == 0) {
+ attribute->u.akind = ATOMIC_TYPE_LONGLONG;
+ } else {
+ warningf(HERE, "ignoring unknown mode '%s'", symbol_str);
+ attribute->invalid = true;
+ }
+ next_token();
+
rem_anchor_token(')');
expect(')');
return;
}
declarator_finished:
- modifiers |= parse_attributes(&attributes);
- if (declaration != NULL) {
- declaration->modifiers |= modifiers;
- }
-
/* append inner_types at the end of the list, we don't to set last anymore
* as it's not needed anymore */
if (last == NULL) {
return NULL;
}
+static void parse_declaration_attributes(declaration_t *declaration)
+{
+ gnu_attribute_t *attributes = NULL;
+ decl_modifiers_t modifiers = parse_attributes(&attributes);
+
+ if (declaration == NULL)
+ return;
+
+ declaration->modifiers |= modifiers;
+ /* check if we have these stupid mode attributes... */
+ type_t *old_type = declaration->type;
+ if (old_type == NULL)
+ return;
+
+ gnu_attribute_t *attribute = attributes;
+ for ( ; attribute != NULL; attribute = attribute->next) {
+ if (attribute->kind != GNU_AK_MODE || attribute->invalid)
+ continue;
+
+ atomic_type_kind_t akind = attribute->u.akind;
+ if (!is_type_signed(old_type)) {
+ switch(akind) {
+ case ATOMIC_TYPE_CHAR: akind = ATOMIC_TYPE_UCHAR; break;
+ case ATOMIC_TYPE_SHORT: akind = ATOMIC_TYPE_USHORT; break;
+ case ATOMIC_TYPE_INT: akind = ATOMIC_TYPE_UINT; break;
+ case ATOMIC_TYPE_LONGLONG: akind = ATOMIC_TYPE_ULONGLONG; break;
+ default:
+ panic("invalid akind in mode attribute");
+ }
+ }
+ declaration->type
+ = make_atomic_type(akind, old_type->base.qualifiers);
+ }
+}
+
static type_t *construct_declarator_type(construct_type_t *construct_list,
type_t *type)
{
type_t *const type = specifiers->type;
declaration->type = construct_declarator_type(construct_type, type);
+ parse_declaration_attributes(declaration);
+
fix_declaration_type(declaration);
if (construct_type != NULL) {