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