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 "SigParam.hh" |
14 | ||
15 | #include "Type.hh" | |
16 | #include "CompilerError.hh" | |
17 | ||
18 | namespace Common { | |
19 | ||
20 | // ================================= | |
21 | // ===== SignatureParam | |
22 | // ================================= | |
23 | ||
24 | SignatureParam::SignatureParam(param_direction_t p_d, Type *p_t, | |
25 | Identifier *p_i) | |
26 | : param_direction(p_d), param_type(p_t), param_id(p_i) | |
27 | { | |
28 | if (!p_t || !p_i) FATAL_ERROR("SignatureParam::SignatureParam()"); | |
29 | param_type->set_ownertype(Type::OT_SIG_PAR, this); | |
30 | } | |
31 | ||
32 | SignatureParam::~SignatureParam() | |
33 | { | |
34 | delete param_type; | |
35 | delete param_id; | |
36 | } | |
37 | ||
38 | SignatureParam *SignatureParam::clone() const | |
39 | { | |
40 | FATAL_ERROR("SignatureParam::clone"); | |
41 | } | |
42 | ||
43 | void SignatureParam::set_fullname(const string& p_fullname) | |
44 | { | |
45 | Node::set_fullname(p_fullname); | |
46 | param_type->set_fullname(p_fullname); | |
47 | } | |
48 | ||
49 | void SignatureParam::set_my_scope(Scope *p_scope) | |
50 | { | |
51 | param_type->set_my_scope(p_scope); | |
52 | } | |
53 | ||
54 | void SignatureParam::dump(unsigned level) const | |
55 | { | |
56 | switch(param_direction) { | |
57 | case PARAM_IN: DEBUG(level,"in"); break; | |
58 | case PARAM_OUT: DEBUG(level,"out"); break; | |
59 | case PARAM_INOUT: DEBUG(level,"inout");break; | |
60 | default: FATAL_ERROR("SignatureParam::dump()"); break; | |
61 | } | |
62 | param_type->dump(level+1); | |
63 | param_id->dump(level+2); | |
64 | } | |
65 | ||
66 | // ================================= | |
67 | // ===== SignatureParamList | |
68 | // ================================= | |
69 | ||
70 | SignatureParamList::~SignatureParamList() | |
71 | { | |
72 | for (size_t i = 0; i < params_v.size(); i++) delete params_v[i]; | |
73 | params_v.clear(); | |
74 | params_m.clear(); | |
75 | in_params_v.clear(); | |
76 | out_params_v.clear(); | |
77 | } | |
78 | ||
79 | SignatureParamList *SignatureParamList::clone() const | |
80 | { | |
81 | FATAL_ERROR("SignatureParam::clone"); | |
82 | } | |
83 | ||
84 | void SignatureParamList::set_fullname(const string& p_fullname) | |
85 | { | |
86 | Node::set_fullname(p_fullname); | |
87 | for (size_t i = 0; i < params_v.size(); i++) { | |
88 | SignatureParam *param = params_v[i]; | |
89 | param->set_fullname(p_fullname + "." + param->get_id().get_dispname()); | |
90 | } | |
91 | } | |
92 | ||
93 | void SignatureParamList::set_my_scope(Scope *p_scope) | |
94 | { | |
95 | for (size_t i = 0; i < params_v.size(); i++) | |
96 | params_v[i]->set_my_scope(p_scope); | |
97 | } | |
98 | ||
99 | void SignatureParamList::add_param(SignatureParam *p_param) | |
100 | { | |
101 | if (!p_param || checked) FATAL_ERROR("SignatureParamList::add_param()"); | |
102 | params_v.add(p_param); | |
103 | } | |
104 | ||
105 | size_t SignatureParamList::get_nof_in_params() const | |
106 | { | |
107 | if (!checked) FATAL_ERROR("SignatureParamList::get_nof_in_params()"); | |
108 | return in_params_v.size(); | |
109 | } | |
110 | ||
111 | SignatureParam *SignatureParamList::get_in_param_byIndex(size_t n) const | |
112 | { | |
113 | if (!checked) FATAL_ERROR("SignatureParamList::get_in_param_byIndex()"); | |
114 | return in_params_v[n]; | |
115 | } | |
116 | ||
117 | size_t SignatureParamList::get_nof_out_params() const | |
118 | { | |
119 | if (!checked) FATAL_ERROR("SignatureParamList::get_nof_out_params()"); | |
120 | return out_params_v.size(); | |
121 | } | |
122 | ||
123 | SignatureParam *SignatureParamList::get_out_param_byIndex(size_t n) const | |
124 | { | |
125 | if (!checked) FATAL_ERROR("SignatureParamList::get_out_param_byIndex()"); | |
126 | return out_params_v[n]; | |
127 | } | |
128 | ||
129 | bool SignatureParamList::has_param_withName(const Identifier& p_name) const | |
130 | { | |
131 | if (!checked) FATAL_ERROR("SignatureParamList::has_param_withName()"); | |
132 | return params_m.has_key(p_name.get_name()); | |
133 | } | |
134 | ||
135 | const SignatureParam *SignatureParamList::get_param_byName | |
136 | (const Identifier& p_name) const | |
137 | { | |
138 | if (!checked) FATAL_ERROR("SignatureParamList::get_param_byName()"); | |
139 | return params_m[p_name.get_name()]; | |
140 | } | |
141 | ||
142 | void SignatureParamList::chk(Type *p_signature) | |
143 | { | |
144 | if (checked) return; | |
145 | checked = true; | |
146 | for (size_t i = 0; i < params_v.size(); i++) { | |
147 | SignatureParam *param = params_v[i]; | |
148 | const Identifier& id = param->get_id(); | |
149 | const string& name = id.get_name(); | |
150 | const char *dispname_str = id.get_dispname().c_str(); | |
151 | if (params_m.has_key(name)) { | |
152 | param->error("Duplicate parameter identifier: `%s'", dispname_str); | |
153 | params_m[name]->note("Parameter `%s' is already defined here", | |
154 | dispname_str); | |
155 | } else params_m.add(name, param); | |
156 | Error_Context cntxt(param, "In parameter `%s'", dispname_str); | |
157 | bool is_nonblock = p_signature->is_nonblocking_signature(); | |
158 | switch (param->get_direction()) { | |
159 | case SignatureParam::PARAM_IN: | |
160 | in_params_v.add(param); | |
161 | break; | |
162 | case SignatureParam::PARAM_OUT: | |
163 | if (is_nonblock) param->error("A non-blocking signature cannot have " | |
164 | "`out' parameter"); | |
165 | out_params_v.add(param); | |
166 | break; | |
167 | case SignatureParam::PARAM_INOUT: | |
168 | if (is_nonblock) param->error("A non-blocking signature cannot have " | |
169 | "`inout' parameter"); | |
170 | in_params_v.add(param); | |
171 | out_params_v.add(param); | |
172 | break; | |
173 | default: | |
174 | FATAL_ERROR("SignatureParamList::chk()"); | |
175 | } | |
176 | Type *param_type = param->get_type(); | |
177 | param_type->set_genname(p_signature->get_genname_own(), name); | |
178 | param_type->set_parent_type(p_signature); | |
179 | param_type->chk(); | |
180 | param_type->chk_embedded(false, "the type of a signature parameter"); | |
181 | } | |
182 | } | |
183 | ||
184 | void SignatureParamList::dump(unsigned level) const | |
185 | { | |
186 | for (size_t i = 0; i < params_v.size(); i++) params_v[i]->dump(level); | |
187 | } | |
188 | ||
189 | // ================================= | |
190 | // ===== SignatureExceptions | |
191 | // ================================= | |
192 | ||
193 | SignatureExceptions::~SignatureExceptions() | |
194 | { | |
195 | for (size_t i = 0; i < exc_v.size(); i++) delete exc_v[i]; | |
196 | exc_v.clear(); | |
197 | exc_m.clear(); | |
198 | } | |
199 | ||
200 | SignatureExceptions *SignatureExceptions::clone() const | |
201 | { | |
202 | FATAL_ERROR("SignatureExceptions::clone"); | |
203 | } | |
204 | ||
205 | void SignatureExceptions::add_type(Type *p_type) | |
206 | { | |
207 | if (!p_type) FATAL_ERROR("SignatureExceptions::add_type()"); | |
208 | exc_v.add(p_type); | |
209 | } | |
210 | ||
211 | bool SignatureExceptions::has_type(Type *p_type) | |
212 | { | |
213 | if (!p_type) FATAL_ERROR("SignatureExceptions::has_type()"); | |
214 | if (p_type->get_type_refd_last()->get_typetype() == Type::T_ERROR) | |
215 | return true; | |
216 | else return exc_m.has_key(p_type->get_typename()); | |
217 | } | |
218 | ||
219 | size_t SignatureExceptions::get_nof_compatible_types(Type *p_type) | |
220 | { | |
221 | if (!p_type) FATAL_ERROR("SignatureExceptions::get_nof_compatible_types()"); | |
222 | if (p_type->get_type_refd_last()->get_typetype() == Type::T_ERROR) { | |
223 | // Return a positive answer for erroneous types. | |
224 | return 1; | |
225 | } else { | |
226 | size_t ret_val = 0; | |
227 | for (size_t i = 0; i < exc_v.size(); i++) | |
228 | // Don't allow type compatibility. The types must match exactly. | |
229 | if (exc_v[i]->is_compatible(p_type, NULL)) | |
230 | ret_val++; | |
231 | return ret_val; | |
232 | } | |
233 | } | |
234 | ||
235 | void SignatureExceptions::chk(Type *p_signature) | |
236 | { | |
237 | Error_Context cntxt(this, "In exception list"); | |
238 | for (size_t i = 0; i < exc_v.size(); i++) { | |
239 | Type *type = exc_v[i]; | |
240 | type->set_genname(p_signature->get_genname_own(), Int2string(i + 1)); | |
241 | type->set_parent_type(p_signature); | |
242 | type->chk(); | |
243 | if (type->get_typetype() == Type::T_ERROR) continue; | |
244 | type->chk_embedded(false, "on the exception list of a signature"); | |
245 | const string& type_name = type->get_typename(); | |
246 | if (exc_m.has_key(type_name)) { | |
247 | type->error("Duplicate type in exception list"); | |
248 | exc_m[type_name]->note("Type `%s' is already given here", | |
249 | type_name.c_str()); | |
250 | } else exc_m.add(type_name, type); | |
251 | } | |
252 | } | |
253 | ||
254 | void SignatureExceptions::set_fullname(const string& p_fullname) | |
255 | { | |
256 | Node::set_fullname(p_fullname); | |
257 | for (size_t i = 0; i < exc_v.size(); i++) | |
258 | exc_v[i]->set_fullname(p_fullname + ".<type" + Int2string(i + 1) + ">"); | |
259 | } | |
260 | ||
261 | void SignatureExceptions::set_my_scope(Scope *p_scope) | |
262 | { | |
263 | for (size_t i = 0; i < exc_v.size(); i++) | |
264 | exc_v[i]->set_my_scope(p_scope); | |
265 | } | |
266 | ||
267 | void SignatureExceptions::dump(unsigned level) const | |
268 | { | |
269 | for (size_t i=0; i < exc_v.size(); i++) exc_v[i]->dump(level); | |
270 | } | |
271 | ||
272 | } /* namespace Common */ |