1 /*
2 * This file is part of cparser.
3 * Copyright (C) 2007-2009 Matthias Braun <matze@braunis.de>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18 * 02111-1307, USA.
19 */
20 #include <config.h>
21
22 #include <assert.h>
23
24 #include "entity_t.h"
25 #include "ast_t.h"
26 #include "adt/error.h"
27 #include "adt/util.h"
28 #include "adt/strutil.h"
29
get_entity_kind_name(entity_kind_t kind)30 const char *get_entity_kind_name(entity_kind_t kind)
31 {
32 switch ((entity_kind_tag_t) kind) {
33 case ENTITY_FUNCTION: return "function";
34 case ENTITY_VARIABLE: return "variable";
35 case ENTITY_PARAMETER: return "parameter";
36 case ENTITY_COMPOUND_MEMBER: return "compound member";
37 case ENTITY_CLASS: return "class";
38 case ENTITY_STRUCT: return "struct";
39 case ENTITY_UNION: return "union";
40 case ENTITY_ENUM: return "enum";
41 case ENTITY_ENUM_VALUE: return "enum value";
42 case ENTITY_LABEL: return "label";
43 case ENTITY_LOCAL_LABEL: return "local label";
44 case ENTITY_TYPEDEF: return "typedef";
45 case ENTITY_NAMESPACE: return "namespace";
46 }
47
48 panic("invalid entity kind");
49 }
50
51 /**
52 * Returns the size of an entity node.
53 *
54 * @param kind the entity kind
55 */
get_entity_struct_size(entity_kind_t kind)56 static size_t get_entity_struct_size(entity_kind_t kind)
57 {
58 static const size_t sizes[] = {
59 [ENTITY_VARIABLE] = sizeof(variable_t),
60 [ENTITY_PARAMETER] = sizeof(variable_t),
61 [ENTITY_COMPOUND_MEMBER] = sizeof(compound_member_t),
62 [ENTITY_FUNCTION] = sizeof(function_t),
63 [ENTITY_TYPEDEF] = sizeof(typedef_t),
64 [ENTITY_STRUCT] = sizeof(compound_t),
65 [ENTITY_UNION] = sizeof(compound_t),
66 [ENTITY_ENUM] = sizeof(enum_t),
67 [ENTITY_ENUM_VALUE] = sizeof(enum_value_t),
68 [ENTITY_LABEL] = sizeof(label_t),
69 [ENTITY_LOCAL_LABEL] = sizeof(label_t),
70 [ENTITY_NAMESPACE] = sizeof(namespace_t)
71 };
72 assert(kind < lengthof(sizes));
73 assert(sizes[kind] != 0);
74 return sizes[kind];
75 }
76
77 /**
78 * Allocate an entity of given kind and initialize all
79 * fields with zero.
80 *
81 * @param kind the kind of the entity to allocate
82 */
allocate_entity_zero(entity_kind_t const kind,entity_namespace_t const namespc,symbol_t * const symbol,source_position_t const * const pos)83 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)
84 {
85 size_t const size = get_entity_struct_size(kind);
86 entity_t *const entity = allocate_ast_zero(size);
87 entity->kind = kind;
88 entity->base.namespc = namespc;
89 entity->base.symbol = symbol;
90 entity->base.source_position = *pos;
91 return entity;
92 }
93
get_elf_visibility_from_string(const char * string)94 elf_visibility_tag_t get_elf_visibility_from_string(const char *string)
95 {
96 if (streq(string, "default")) {
97 return ELF_VISIBILITY_DEFAULT;
98 } else if (streq(string, "hidden")) {
99 return ELF_VISIBILITY_HIDDEN;
100 } else if (streq(string, "internal")) {
101 return ELF_VISIBILITY_INTERNAL;
102 } else if (streq(string, "protected")) {
103 return ELF_VISIBILITY_PROTECTED;
104 } else {
105 return ELF_VISIBILITY_ERROR;
106 }
107 }
108
skip_unnamed_bitfields(entity_t * entry)109 entity_t *skip_unnamed_bitfields(entity_t *entry)
110 {
111 for (; entry != NULL; entry = entry->base.next) {
112 assert(entry->kind == ENTITY_COMPOUND_MEMBER);
113 if (!entry->compound_member.bitfield || entry->base.symbol != NULL)
114 break;
115 }
116 return entry;
117 }
118