X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=attribute.c;h=e709e61a16b334c7537587a895cab5229cd2c4d7;hb=18e875f4a36f2db033a1b991dd0485a132e0c395;hp=7ed121e14359397ad7d20f522cec753d9dbbfb68;hpb=6a7adde8512cf76b6cc5c67bece168b43c913c26;p=cparser diff --git a/attribute.c b/attribute.c index 7ed121e..e709e61 100644 --- a/attribute.c +++ b/attribute.c @@ -1,6 +1,6 @@ /* * This file is part of cparser. - * Copyright (C) 2007-2008 Matthias Braun + * Copyright (C) 2007-2009 Matthias Braun * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -24,6 +24,7 @@ #include "warning.h" #include "attribute_t.h" #include "symbol_t.h" +#include "adt/error.h" #include "type_t.h" static const char *const attribute_names[ATTRIBUTE_LAST+1] = { @@ -196,7 +197,7 @@ static void handle_attribute_aligned(const attribute_t *attribute, target machine */ if (attribute->a.arguments) { attribute_argument_t *argument = attribute->a.arguments; - alignment = fold_constant(argument->v.expression); + alignment = fold_constant_to_int(argument->v.expression); } if (!is_po2(alignment)) { @@ -246,18 +247,32 @@ static void warn_arguments(const attribute_t *attribute) } } -static void handle_attribute_packed(const attribute_t *attribute, - entity_t *entity) +static void handle_attribute_packed_e(const attribute_t *attribute, + entity_t *entity) { +#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); + return; + } +#endif + warn_arguments(attribute); + entity->compound.packed = true; +} - if (entity->kind == ENTITY_STRUCT) { - entity->compound.packed = true; - } else if (warning.other) { +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 %s ignored", - get_entity_kind_name(entity->kind)); + "packed attribute on type '%T' ignored", type); + return; } + + handle_attribute_packed_e(attribute, (entity_t*) type->compound.compound); } void handle_entity_attributes(const attribute_t *attributes, entity_t *entity) @@ -295,6 +310,7 @@ void handle_entity_attributes(const attribute_t *attributes, entity_t *entity) 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_MS_ALLOCATE: modifiers |= DM_MALLOC; break; case ATTRIBUTE_MS_DLLIMPORT: modifiers |= DM_DLLIMPORT; break; @@ -310,8 +326,9 @@ void handle_entity_attributes(const attribute_t *attributes, entity_t *entity) case ATTRIBUTE_MS_NOALIAS: modifiers |= DM_NOALIAS; break; case ATTRIBUTE_GNU_PACKED: - handle_attribute_packed(attribute, entity); - break; + handle_attribute_packed_e(attribute, entity); + break; + case ATTRIBUTE_MS_ALIGN: case ATTRIBUTE_GNU_ALIGNED: handle_attribute_aligned(attribute, entity); @@ -343,7 +360,7 @@ void handle_entity_attributes(const attribute_t *attributes, entity_t *entity) static type_t *change_calling_convention(type_t *type, cc_kind_t cconv) { - if (!is_type_function(type)) { + if (is_typeref(type) || !is_type_function(type)) { return type; } @@ -360,6 +377,9 @@ type_t *handle_type_attributes(const attribute_t *attributes, type_t *type) const attribute_t *attribute = attributes; for ( ; attribute != NULL; attribute = attribute->next) { switch(attribute->kind) { + case ATTRIBUTE_GNU_PACKED: + handle_attribute_packed(attribute, type); + break; case ATTRIBUTE_GNU_CDECL: case ATTRIBUTE_MS_CDECL: type = change_calling_convention(type, CC_CDECL); @@ -400,7 +420,56 @@ const char *get_deprecated_string(const attribute_t *attribute) expression_t *expression = argument->v.expression; if (expression->kind != EXPR_STRING_LITERAL) return NULL; - return expression->string.value.begin; + return expression->literal.value.begin; } return NULL; } + +static bool property_attribute_equal(const attribute_property_argument_t *prop1, + const attribute_property_argument_t *prop2) +{ + return prop1->put_symbol == prop2->put_symbol + && prop1->get_symbol == prop2->get_symbol; +} + +static bool attribute_argument_equal(const attribute_argument_t *arg1, + const attribute_argument_t *arg2) +{ + if (arg1->kind != arg2->kind) + return false; + + switch (arg1->kind) { + case ATTRIBUTE_ARGUMENT_SYMBOL: + return arg1->v.symbol == arg2->v.symbol; + case ATTRIBUTE_ARGUMENT_EXPRESSION: + /* TODO */ + return false; + } + panic("Unknown argument type found"); +} + +static bool attribute_arguments_equal(const attribute_argument_t *args1, + const attribute_argument_t *args2) +{ + for ( ; args1 != NULL && args2 != NULL; + args1 = args1->next, args2 = args2->next) { + if (!attribute_argument_equal(args1, args2)) + return false; + } + /* both should be NULL now */ + return args1 == args2; +} + +bool attributes_equal(const attribute_t *attr1, const attribute_t *attr2) +{ + if (attr1->kind != attr2->kind) + return false; + + switch (attr1->kind) { + case ATTRIBUTE_MS_PROPERTY: + return property_attribute_equal(attr1->a.property, attr2->a.property); + default: + return attribute_arguments_equal(attr1->a.arguments, + attr2->a.arguments); + } +}