X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=entity.c;h=3a2db26d6598aa6938c675d8e7bc5f50b03492ab;hb=3a75131289ed543970968244180a5b828608b342;hp=37d22c00b716208b44e3d7984396b7db80d919ce;hpb=beeb51cc97aa077897c804b3e7602f9acc60d4fb;p=cparser diff --git a/entity.c b/entity.c index 37d22c0..3a2db26 100644 --- a/entity.c +++ b/entity.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 @@ -19,8 +19,13 @@ */ #include +#include + #include "entity_t.h" +#include "ast_t.h" #include "adt/error.h" +#include "adt/util.h" +#include "adt/strutil.h" const char *get_entity_kind_name(entity_kind_t kind) { @@ -28,7 +33,8 @@ const char *get_entity_kind_name(entity_kind_t kind) case ENTITY_FUNCTION: return "function"; case ENTITY_VARIABLE: return "variable"; case ENTITY_PARAMETER: return "parameter"; - case ENTITY_COMPOUND_MEMBER: return "compound type member"; + case ENTITY_COMPOUND_MEMBER: return "compound member"; + case ENTITY_CLASS: return "class"; case ENTITY_STRUCT: return "struct"; case ENTITY_UNION: return "union"; case ENTITY_ENUM: return "enum"; @@ -37,8 +43,75 @@ const char *get_entity_kind_name(entity_kind_t kind) case ENTITY_LOCAL_LABEL: return "local label"; case ENTITY_TYPEDEF: return "typedef"; case ENTITY_NAMESPACE: return "namespace"; - case ENTITY_INVALID: break; } panic("Invalid entity kind encountered in get_entity_kind_name"); } + +/** + * Returns the size of an entity node. + * + * @param kind the entity kind + */ +static size_t get_entity_struct_size(entity_kind_t kind) +{ + static const size_t sizes[] = { + [ENTITY_VARIABLE] = sizeof(variable_t), + [ENTITY_PARAMETER] = sizeof(variable_t), + [ENTITY_COMPOUND_MEMBER] = sizeof(compound_member_t), + [ENTITY_FUNCTION] = sizeof(function_t), + [ENTITY_TYPEDEF] = sizeof(typedef_t), + [ENTITY_STRUCT] = sizeof(compound_t), + [ENTITY_UNION] = sizeof(compound_t), + [ENTITY_ENUM] = sizeof(enum_t), + [ENTITY_ENUM_VALUE] = sizeof(enum_value_t), + [ENTITY_LABEL] = sizeof(label_t), + [ENTITY_LOCAL_LABEL] = sizeof(label_t), + [ENTITY_NAMESPACE] = sizeof(namespace_t) + }; + assert(kind < lengthof(sizes)); + assert(sizes[kind] != 0); + return sizes[kind]; +} + +/** + * Allocate an entity of given kind and initialize all + * fields with zero. + * + * @param kind the kind of the entity to allocate + */ +entity_t *allocate_entity_zero(entity_kind_t const kind, entity_namespace_t const namespc, symbol_t *const symbol, source_position_t const *const pos) +{ + size_t const size = get_entity_struct_size(kind); + entity_t *const entity = allocate_ast_zero(size); + entity->kind = kind; + entity->base.namespc = namespc; + entity->base.symbol = symbol; + entity->base.source_position = *pos; + return entity; +} + +elf_visibility_tag_t get_elf_visibility_from_string(const char *string) +{ + if (streq(string, "default")) { + return ELF_VISIBILITY_DEFAULT; + } else if (streq(string, "hidden")) { + return ELF_VISIBILITY_HIDDEN; + } else if (streq(string, "internal")) { + return ELF_VISIBILITY_INTERNAL; + } else if (streq(string, "protected")) { + return ELF_VISIBILITY_PROTECTED; + } else { + return ELF_VISIBILITY_ERROR; + } +} + +entity_t *skip_unnamed_bitfields(entity_t *entry) +{ + for (; entry != NULL; entry = entry->base.next) { + assert(entry->kind == ENTITY_COMPOUND_MEMBER); + if (!entry->compound_member.bitfield || entry->base.symbol != NULL) + break; + } + return entry; +}