X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=attribute.c;h=1ccdc5de09592fac95b80f4a9bbd7ffb683d5bff;hb=776944099aee0467915e9ea4f3c2f3f10f742aaa;hp=651c6ee5d91a3015e5cab4f1964d5b87f28aba83;hpb=9237a87907d3057e6014f4d326f03b16baed108a;p=cparser diff --git a/attribute.c b/attribute.c index 651c6ee..1ccdc5d 100644 --- a/attribute.c +++ b/attribute.c @@ -20,6 +20,7 @@ #include #include +#include "adt/strutil.h" #include "diagnostic.h" #include "warning.h" #include "attribute_t.h" @@ -119,22 +120,6 @@ const char *get_attribute_name(attribute_kind_t kind) return attribute_names[kind]; } -/** - * compare two string, ignoring double underscores on the second. - */ -static int strcmp_underscore(const char *s1, const char *s2) -{ - if (s2[0] == '_' && s2[1] == '_') { - size_t len2 = strlen(s2); - size_t len1 = strlen(s1); - if (len1 == len2-4 && s2[len2-2] == '_' && s2[len2-1] == '_') { - return strncmp(s1, s2+2, len2-4); - } - } - - return strcmp(s1, s2); -} - type_t *handle_attribute_mode(const attribute_t *attribute, type_t *orig_type) { type_t *type = skip_typeref(orig_type); @@ -154,35 +139,30 @@ type_t *handle_attribute_mode(const attribute_t *attribute, type_t *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) { + if (streq_underscore("QI", symbol_str) || + streq_underscore("byte", symbol_str)) { akind = sign ? ATOMIC_TYPE_CHAR : ATOMIC_TYPE_UCHAR; - } else if (strcmp_underscore("HI", symbol_str) == 0) { + } else if (streq_underscore("HI", symbol_str)) { akind = sign ? ATOMIC_TYPE_SHORT : ATOMIC_TYPE_USHORT; - } else if (strcmp_underscore("SI", symbol_str) == 0 - || strcmp_underscore("word", symbol_str) == 0 - || strcmp_underscore("pointer", symbol_str) == 0) { + } else if (streq_underscore("SI", symbol_str) + || streq_underscore("word", symbol_str) + || streq_underscore("pointer", symbol_str)) { akind = sign ? ATOMIC_TYPE_INT : ATOMIC_TYPE_UINT; - } else if (strcmp_underscore("DI", symbol_str) == 0) { + } else if (streq_underscore("DI", symbol_str)) { 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; } - if (type->kind == TYPE_ATOMIC) { + if (type->kind == TYPE_ATOMIC || type->kind == TYPE_ENUM) { type_t *copy = duplicate_type(type); copy->atomic.akind = akind; return identify_new_type(copy); - } else if (type->kind == TYPE_ENUM) { - type_t *copy = duplicate_type(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; } @@ -220,26 +200,25 @@ static void handle_attribute_aligned(const attribute_t *attribute, } switch (entity->kind) { - DECLARATION_KIND_CASES + case DECLARATION_KIND_CASES: entity->declaration.alignment = alignment; case ENTITY_TYPEDEF: entity->typedefe.alignment = alignment; 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) { - const char *what = get_entity_kind_name(entity->kind); - warningf(&attribute->source_position, - "alignment attribute specification on %s '%S' ignored", - what, 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) @@ -285,15 +264,14 @@ static void handle_attribute_visibility(const attribute_t *attribute, case ENTITY_FUNCTION: entity->function.elf_visibility = visibility; break; - default: - if (warning.other) { - const char *what = get_entity_kind_name(entity->kind); - warningf(&attribute->source_position, - "visibility attribute specification on %s '%S' ignored", - what, 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, "visibility attribute specification on %s '%S' ignored", what, sym); break; } + } } static void warn_arguments(const attribute_t *attribute) @@ -301,11 +279,9 @@ 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, @@ -313,10 +289,10 @@ 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 @@ -328,8 +304,8 @@ static void handle_attribute_packed_e(const attribute_t *attribute, 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; } @@ -370,15 +346,11 @@ void handle_entity_attributes(const attribute_t *attributes, entity_t *entity) 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_RETURNS_TWICE: modifiers |= DM_RETURNS_TWICE; break; - case ATTRIBUTE_GNU_NORETURN: modifiers |= DM_NORETURN; 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_MALLOC: modifiers |= DM_MALLOC; break; case ATTRIBUTE_GNU_CONSTRUCTOR: modifiers |= DM_CONSTRUCTOR; break; case ATTRIBUTE_GNU_DESTRUCTOR: modifiers |= DM_DESTRUCTOR; break; - case ATTRIBUTE_GNU_NOTHROW: modifiers |= DM_NOTHROW; break; case ATTRIBUTE_GNU_TRANSPARENT_UNION: modifiers |= DM_TRANSPARENT_UNION; break; @@ -388,14 +360,10 @@ void handle_entity_attributes(const attribute_t *attributes, entity_t *entity) case ATTRIBUTE_GNU_DLLEXPORT: modifiers |= DM_DLLEXPORT; break; case ATTRIBUTE_GNU_WEAK: modifiers |= DM_WEAK; break; - case ATTRIBUTE_MS_ALLOCATE: modifiers |= DM_MALLOC; 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_RETURNS_TWICE: modifiers |= DM_RETURNS_TWICE; break; - case ATTRIBUTE_MS_NORETURN: modifiers |= DM_NORETURN; break; - case ATTRIBUTE_MS_NOTHROW: modifiers |= DM_NOTHROW; 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; @@ -456,6 +424,20 @@ static type_t *change_calling_convention(type_t *type, cc_kind_t cconv) return identify_new_type(new_type); } +static type_t *add_modifiers(type_t *type, decl_modifiers_t modifiers) +{ + if (is_typeref(type) || !is_type_function(type)) { + return type; + } + + if ((type->function.modifiers & modifiers) == modifiers) + return type; + + type_t* new_type = duplicate_type(type); + new_type->function.modifiers |= modifiers; + return identify_new_type(new_type); +} + type_t *handle_type_attributes(const attribute_t *attributes, type_t *type) { const attribute_t *attribute = attributes; @@ -479,6 +461,22 @@ type_t *handle_type_attributes(const attribute_t *attributes, type_t *type) case ATTRIBUTE_MS_THISCALL: type = change_calling_convention(type, CC_THISCALL); break; + case ATTRIBUTE_GNU_RETURNS_TWICE: + case ATTRIBUTE_MS_RETURNS_TWICE: + type = add_modifiers(type, DM_RETURNS_TWICE); + break; + case ATTRIBUTE_GNU_NORETURN: + case ATTRIBUTE_MS_NORETURN: + type = add_modifiers(type, DM_NORETURN); + break; + case ATTRIBUTE_GNU_MALLOC: + case ATTRIBUTE_MS_ALLOCATE: + type = add_modifiers(type, DM_MALLOC); + break; + case ATTRIBUTE_GNU_NOTHROW: + case ATTRIBUTE_MS_NOTHROW: + type = add_modifiers(type, DM_NOTHROW); + break; case ATTRIBUTE_GNU_MODE: type = handle_attribute_mode(attribute, type); break;