Reformat switches for better readability.
[cparser] / attribute.c
index 215a8e6..1ccdc5d 100644 (file)
@@ -20,6 +20,7 @@
 #include <config.h>
 
 #include <assert.h>
+#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,16 +139,16 @@ 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 {
                source_position_t const *const pos = &attribute->source_position;
@@ -215,7 +200,7 @@ 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;
@@ -361,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;
@@ -379,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;
@@ -447,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;
@@ -470,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;