Commit | Line | Data |
---|---|---|
d44e3c4f | 1 | /****************************************************************************** |
2 | * Copyright (c) 2000-2016 Ericsson Telecom AB | |
3 | * All rights reserved. This program and the accompanying materials | |
4 | * are made available under the terms of the Eclipse Public License v1.0 | |
5 | * which accompanies this distribution, and is available at | |
6 | * http://www.eclipse.org/legal/epl-v10.html | |
7 | * | |
8 | * Contributors: | |
9 | * Balasko, Jeno | |
10 | * Raduly, Csaba | |
11 | * | |
12 | ******************************************************************************/ | |
970ed795 EL |
13 | #include "CompField.hh" |
14 | #include "Type.hh" | |
15 | #include "Value.hh" | |
16 | #include "CompilerError.hh" | |
17 | ||
18 | namespace Common { | |
19 | ||
20 | // ================================= | |
21 | // ===== CompField | |
22 | // ================================= | |
23 | ||
24 | CompField::CompField(Identifier *p_name, Type *p_type, bool p_is_optional, | |
25 | Value *p_defval) | |
26 | : Node(), Location(), name(p_name), type(p_type), | |
27 | is_optional(p_is_optional), defval(p_defval), rawattrib(0) | |
28 | { | |
29 | if(!p_name || !p_type) | |
30 | FATAL_ERROR("NULL parameter: Common::CompField::CompField()"); | |
31 | type->set_ownertype(Type::OT_COMP_FIELD, this); | |
32 | } | |
33 | ||
34 | CompField::CompField(const CompField& p) | |
35 | : Node(p), Location(p), is_optional(p.is_optional), rawattrib(0) | |
36 | { | |
37 | name=p.name->clone(); | |
38 | type=p.type->clone(); | |
39 | type->set_ownertype(Type::OT_COMP_FIELD, this); | |
40 | defval=p.defval?p.defval->clone():0; | |
41 | } | |
42 | ||
43 | CompField::~CompField() | |
44 | { | |
45 | delete name; | |
46 | delete type; | |
47 | delete defval; | |
48 | delete rawattrib; | |
49 | } | |
50 | ||
51 | CompField *CompField::clone() const | |
52 | { | |
53 | return new CompField(*this); | |
54 | } | |
55 | ||
56 | void CompField::set_fullname(const string& p_fullname) | |
57 | { | |
58 | string base_name(p_fullname + "." + name->get_dispname()); | |
59 | Node::set_fullname(base_name); | |
60 | type->set_fullname(base_name); | |
61 | if (defval) defval->set_fullname(base_name + ".<defval>"); | |
62 | } | |
63 | ||
64 | void CompField::set_my_scope(Scope *p_scope) | |
65 | { | |
66 | type->set_my_scope(p_scope); | |
67 | if (defval) defval->set_my_scope(p_scope); | |
68 | } | |
69 | ||
70 | void CompField::set_raw_attrib(RawAST* r_attr) | |
71 | { | |
72 | delete rawattrib; | |
73 | rawattrib=r_attr; | |
74 | } | |
75 | ||
76 | void CompField::dump(unsigned level) const | |
77 | { | |
78 | name->dump(level); | |
79 | type->dump(level + 1); | |
80 | if(is_optional) | |
81 | DEBUG(level + 1, "optional"); | |
82 | if(defval) { | |
83 | DEBUG(level + 1, "with default value"); | |
84 | defval->dump(level + 2); | |
85 | } | |
86 | } | |
87 | ||
88 | // ================================= | |
89 | // ===== CompFieldMap | |
90 | // ================================= | |
91 | ||
92 | CompFieldMap::CompFieldMap(const CompFieldMap& p) | |
93 | : Node(p), my_type(0), checked(false) | |
94 | { | |
95 | size_t nof_comps = p.v.size(); | |
96 | for (size_t i = 0; i < nof_comps; i++) v.add(p.v[i]->clone()); | |
97 | } | |
98 | ||
99 | CompFieldMap::~CompFieldMap() | |
100 | { | |
101 | size_t nof_comps = v.size(); | |
102 | for (size_t i = 0; i < nof_comps; i++) delete v[i]; | |
103 | v.clear(); | |
104 | m.clear(); | |
105 | } | |
106 | ||
107 | CompFieldMap *CompFieldMap::clone() const | |
108 | { | |
109 | return new CompFieldMap(*this); | |
110 | } | |
111 | ||
112 | void CompFieldMap::set_fullname(const string& p_fullname) | |
113 | { | |
114 | Node::set_fullname(p_fullname); | |
115 | size_t nof_comps = v.size(); | |
116 | for (size_t i = 0; i < nof_comps; i++) v[i]->set_fullname(p_fullname); | |
117 | } | |
118 | ||
119 | void CompFieldMap::set_my_scope(Scope *p_scope) | |
120 | { | |
121 | size_t nof_comps = v.size(); | |
122 | for (size_t i = 0; i < nof_comps; i++) v[i]->set_my_scope(p_scope); | |
123 | } | |
124 | ||
125 | void CompFieldMap::add_comp(CompField *comp) | |
126 | { | |
127 | v.add(comp); | |
128 | if (checked) { | |
129 | const string& name = comp->get_name().get_name(); | |
130 | if (m.has_key(name)) FATAL_ERROR("CompFieldMap::add_comp(%s)", name.c_str()); | |
131 | m.add(name, comp); | |
132 | } | |
133 | } | |
134 | ||
135 | bool CompFieldMap::has_comp_withName(const Identifier& p_name) | |
136 | { | |
137 | if (!checked) chk_uniq(); | |
138 | return m.has_key(p_name.get_name()); | |
139 | } | |
140 | ||
141 | CompField* CompFieldMap::get_comp_byName(const Identifier& p_name) | |
142 | { | |
143 | if (!checked) chk_uniq(); | |
144 | return m[p_name.get_name()]; | |
145 | } | |
146 | ||
147 | const char *CompFieldMap::get_typetype_name() const | |
148 | { | |
149 | if (!my_type) FATAL_ERROR("CompFieldMap::get_typetype_name()"); | |
150 | switch (my_type->get_typetype()) { | |
151 | case Type::T_ANYTYPE: | |
152 | return "anytype"; | |
153 | case Type::T_CHOICE_T: | |
154 | return "union"; | |
155 | case Type::T_SEQ_T: | |
156 | return "record"; | |
157 | case Type::T_SET_T: | |
158 | return "set"; | |
159 | case Type::T_OPENTYPE: | |
160 | return "open type"; | |
161 | default: | |
162 | return "<unknown>"; | |
163 | } | |
164 | } | |
165 | ||
166 | void CompFieldMap::chk_uniq() | |
167 | { | |
168 | if (checked) return; | |
169 | const char *typetype_name = get_typetype_name(); | |
170 | size_t nof_comps = v.size(); | |
171 | for (size_t i = 0; i < nof_comps; i++) { | |
172 | CompField *comp = v[i]; | |
173 | const Identifier& id = comp->get_name(); | |
174 | const string& name = id.get_name(); | |
175 | if (m.has_key(name)) { | |
176 | const char *dispname = id.get_dispname().c_str(); | |
177 | comp->error("Duplicate %s field name `%s'", typetype_name, dispname); | |
178 | m[name]->note("Field `%s' is already defined here", dispname); | |
179 | } else m.add(name, comp); | |
180 | } | |
181 | checked = true; | |
182 | } | |
183 | ||
184 | void CompFieldMap::chk() | |
185 | { | |
186 | if (!checked) chk_uniq(); | |
187 | const char *typetype_name = get_typetype_name(); | |
188 | size_t nof_comps = v.size(); | |
189 | for (size_t i = 0; i < nof_comps; i++) { | |
190 | CompField *comp = v[i]; | |
191 | const Identifier& id = comp->get_name(); | |
192 | Error_Context cntxt(comp, "In %s field `%s'", typetype_name, | |
193 | id.get_dispname().c_str()); | |
194 | Type *t = comp->get_type(); | |
195 | t->set_genname(my_type->get_genname_own(), id.get_name()); | |
196 | t->set_parent_type(my_type); | |
197 | t->chk(); | |
198 | t->chk_embedded(true, "embedded into another type"); | |
199 | } | |
200 | } | |
201 | ||
202 | void CompFieldMap::dump(unsigned level) const | |
203 | { | |
204 | size_t nof_comps = v.size(); | |
205 | DEBUG(level, "component fields: (%lu pcs.) @ %p", | |
206 | (unsigned long) nof_comps, (const void*)this); | |
207 | for (size_t i = 0; i < nof_comps; i++) v[i]->dump(level + 1); | |
208 | } | |
209 | ||
210 | } /* namespace Common */ |