/* This isn't really correct, the backend should provide a list of machine
* specific modes (according to gcc philosophy that is...) */
- attribute_argument_t *arg = attribute->a.arguments;
- const char *symbol_str = arg->v.symbol->string;
- bool sign = is_type_signed(type);
+ attribute_argument_t *arg = attribute->a.arguments;
+ if (arg == NULL) {
+ errorf(&attribute->source_position,
+ "__attribute__((mode(X))) misses argument");
+ return orig_type;
+ }
+
+ const char *symbol_str = arg->v.symbol->string;
+ bool sign = is_type_signed(type);
atomic_type_kind_t akind;
if (strcmp_underscore("QI", symbol_str) == 0 ||
strcmp_underscore("byte", symbol_str) == 0) {
} else if (strcmp_underscore("DI", symbol_str) == 0) {
akind = sign ? ATOMIC_TYPE_LONGLONG : ATOMIC_TYPE_ULONGLONG;
} else {
- if (warning.other)
- warningf(&attribute->source_position, "ignoring unknown mode '%s'",
- symbol_str);
+ source_position_t const *const pos = &attribute->source_position;
+ warningf(WARN_OTHER, pos, "ignoring unknown mode '%s'", symbol_str);
return orig_type;
}
copy->enumt.akind = akind;
return identify_new_type(copy);
} else if (is_type_pointer(type)) {
- warningf(&attribute->source_position,
- "__attribute__((mode)) on pointers not implemented yet (ignored)");
+ source_position_t const *const pos = &attribute->source_position;
+ warningf(WARN_OTHER, pos, "__attribute__((mode)) on pointers not implemented yet (ignored)");
return type;
}
break;
case ENTITY_STRUCT:
case ENTITY_UNION:
- if (alignment > entity->compound.alignment) {
+ if (alignment > (int)entity->compound.alignment) {
entity->compound.alignment = alignment;
}
break;
- default:
- if (warning.other) {
- warningf(&attribute->source_position,
- "alignment attribute specification on '%S' ignored",
- entity->base.symbol);
- }
+ default: {
+ source_position_t const *const pos = &attribute->source_position;
+ char const *const what = get_entity_kind_name(entity->kind);
+ symbol_t const *const sym = entity->base.symbol;
+ warningf(WARN_OTHER, pos, "alignment attribute specification on %s '%S' ignored", what, sym);
+ break;
+ }
+ }
+}
+
+static const char *get_argument_string(const attribute_argument_t *argument)
+{
+ if (argument == NULL)
+ return NULL;
+ if (argument->kind != ATTRIBUTE_ARGUMENT_EXPRESSION)
+ return NULL;
+ expression_t *expression = argument->v.expression;
+ if (expression->kind != EXPR_STRING_LITERAL)
+ return NULL;
+ return expression->literal.value.begin;
+}
+
+static void handle_attribute_visibility(const attribute_t *attribute,
+ entity_t *entity)
+{
+ /* This isn't really correct, the backend should provide a list of machine
+ * specific modes (according to gcc philosophy that is...) */
+ attribute_argument_t *arg = attribute->a.arguments;
+ if (arg == NULL) {
+ errorf(&attribute->source_position,
+ "__attribute__((visibility(X))) misses argument");
+ return;
+ }
+ const char *string = get_argument_string(arg);
+ if (string == NULL) {
+ errorf(&attribute->source_position,
+ "__attribute__((visibility(X))) argument is not a string");
+ return;
+ }
+ elf_visibility_tag_t visibility = get_elf_visibility_from_string(string);
+ if (visibility == ELF_VISIBILITY_ERROR) {
+ errorf(&attribute->source_position,
+ "unknown visibility type '%s'", string);
+ return;
+ }
+
+ switch (entity->kind) {
+ case ENTITY_VARIABLE:
+ entity->variable.elf_visibility = visibility;
+ break;
+ case ENTITY_FUNCTION:
+ entity->function.elf_visibility = visibility;
+ break;
+ default: {
+ source_position_t const *const pos = &attribute->source_position;
+ char const *const what = get_entity_kind_name(entity->kind);
+ symbol_t const *const sym = entity->base.symbol;
+ warningf(WARN_OTHER, pos, "visibility attribute specification on %s '%S' ignored", what, sym);
break;
}
+ }
}
static void warn_arguments(const attribute_t *attribute)
if (attribute->a.arguments == NULL)
return;
- if (warning.other) {
- warningf(&attribute->source_position,
- "attribute '%s' needs no arguments",
- get_attribute_name(attribute->kind));
- }
+ source_position_t const *const pos = &attribute->source_position;
+ char const *const what = get_attribute_name(attribute->kind);
+ warningf(WARN_OTHER, pos, "attribute '%s' needs no arguments", what);
}
static void handle_attribute_packed_e(const attribute_t *attribute,
{
#if 0
if (entity->kind != ENTITY_STRUCT) {
- warningf(&attribute->source_position,
- "packed attribute on %s '%s' ignored",
- get_entity_kind_name(entity->kind),
- entity->base.symbol->string);
+ source_position_t const *const pos = &attribute->source_position;
+ char const *const what = get_entity_kind_name(entity->kind);
+ symbol_t const *const sym = entity->base.symbol;
+ warningf(WARN_OTHER, pos, "packed attribute on %s '%S' ignored", what, sym);
return;
}
#endif
static void handle_attribute_packed(const attribute_t *attribute, type_t *type)
{
if (type->kind != TYPE_COMPOUND_STRUCT) {
- warningf(&attribute->source_position,
- "packed attribute on type '%T' ignored", type);
+ source_position_t const *const pos = &attribute->source_position;
+ warningf(WARN_OTHER, pos, "packed attribute on type '%T' ignored", type);
return;
}
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);
continue;
attribute_argument_t *argument = attribute->a.arguments;
- if (argument == NULL)
- return NULL;
- if (argument->kind != ATTRIBUTE_ARGUMENT_EXPRESSION)
- return NULL;
- expression_t *expression = argument->v.expression;
- if (expression->kind != EXPR_STRING_LITERAL)
- return NULL;
- return expression->literal.value.begin;
+ return get_argument_string(argument);
}
return NULL;
}