Sync with 5.4.0
[deliverable/titan.core.git] / compiler2 / SigParam.cc
1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 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 #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 */
This page took 0.044893 seconds and 6 git commands to generate.