Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / TAO / TAO_IDL / fe / fe_obv_header.cpp
blob0532f2eb9afd402ea564029e44f1cc33765f2c77
1 #include "fe_obv_header.h"
3 #include "utl_err.h"
4 #include "utl_namelist.h"
6 #include "fe_extern.h"
7 #include "nr_extern.h"
8 #include "global_extern.h"
10 #include "ast_valuetype.h"
11 #include "ast_module.h"
12 #include "ast_param_holder.h"
14 // @@@ (JP) Here are the rules for interface inheritance and
15 // value type inheritance and supports, straight from Jonathan
16 // Biggar <jon@floorboard.com> as of 3/28/02. The following was
17 // resolved by the OMG, but is not yet part of an official spec.
20 An interface can inherit from any number of other interfaces, abstract
21 or not.
23 An abstract interface can only inherit from other abstract interfaces.
25 An abstract valuetype can inherit from any number of abstract
26 valuetypes. It may support one interface, and in addition, any number
27 of abstract interfaces.
29 A concrete valuetype can inherit from only one concrete valuetype. It
30 may inherit from any number of abstract valuetypes. It may support one
31 interface, and any number of abstract interfaces.
33 The single concrete inherited valuetype must be the first one in the
34 inheritance list.
36 The single supported interface (for valuetypes) must also be the first
37 in the "supports" list.
39 And one more important clarification, if a base valuetype supports an
40 interface, a derived valuetype may also be declared to support an
41 interface, as long as it is derived from all interfaces that are
42 supported by any base valuetypes. Here is an example:
44 interface I1 { };
45 interface I2 { };
46 interface I3: I1, I2 { };
48 abstract valuetype V1 supports I1 { };
49 abstract valuetype V2 supports I2 { };
50 valuetype V3: V1, V2 supports I3 { }; // legal
51 valuetype V4: V1 supports I2 { }; // illegal
53 This last rule was made to guarantee that any given valuetype supported
54 at most one most-derived interface. We didn't want valuetypes to extend
55 the OMG model through the backdoor by providing multiple non-related
56 interfaces.
59 FE_OBVHeader::FE_OBVHeader (UTL_ScopedName *n,
60 UTL_NameList *inherits,
61 UTL_NameList *supports,
62 bool truncatable,
63 bool is_eventtype)
64 : FE_InterfaceHeader (n,
65 inherits,
66 false,
67 false,
68 false),
69 supports_ (nullptr),
70 n_supports_ (0),
71 inherits_concrete_ (nullptr),
72 supports_concrete_ (nullptr),
73 truncatable_ (truncatable)
75 this->compile_inheritance (inherits,
76 is_eventtype);
78 if (idl_global->err_count () == 0)
80 this->compile_supports (supports);
84 FE_OBVHeader::~FE_OBVHeader ()
88 AST_Type **
89 FE_OBVHeader::supports () const
91 return this->supports_;
94 long
95 FE_OBVHeader::n_supports () const
97 return this->n_supports_;
100 AST_Type *
101 FE_OBVHeader::inherits_concrete () const
103 return this->inherits_concrete_;
106 AST_Type *
107 FE_OBVHeader::supports_concrete () const
109 return this->supports_concrete_;
112 bool
113 FE_OBVHeader::truncatable () const
115 return this->truncatable_;
118 void
119 FE_OBVHeader::destroy ()
121 this->FE_InterfaceHeader::destroy ();
124 void
125 FE_OBVHeader::compile_inheritance (UTL_NameList *vtypes,
126 bool is_eventtype)
128 this->FE_InterfaceHeader::compile_inheritance (vtypes,
129 true);
131 if (this->n_inherits_ > 0)
133 AST_Type *t = this->inherits_[0];
134 AST_ValueType *vt = dynamic_cast<AST_ValueType*> (t);
136 if (vt != nullptr
137 && vt->is_abstract () == false)
139 this->inherits_concrete_ = vt;
142 if (! is_eventtype
143 && this->inherits_[0]->node_type () == AST_Decl::NT_eventtype)
145 idl_global->err ()->valuetype_expected (this->inherits_[0]);
148 for (long i = 1; i < this->n_inherits_; ++i)
150 t = this->inherits_[i];
152 if (!t->is_abstract ())
154 idl_global->err ()->abstract_expected (t);
157 if (! is_eventtype
158 && t->node_type () == AST_Decl::NT_eventtype)
160 idl_global->err ()->valuetype_expected (t);
166 void
167 FE_OBVHeader::compile_supports (UTL_NameList *supports)
169 if (supports == nullptr)
171 this->supports_ = nullptr;
172 this->n_supports_ = 0;
173 return;
176 long length = supports->length ();
177 this->n_supports_ = length;
179 ACE_NEW (this->supports_,
180 AST_Type *[length]);
182 AST_Decl *d = nullptr;
183 UTL_ScopedName *item = nullptr;
184 AST_Interface *iface = nullptr;
185 AST_Type *t = nullptr;
186 int i = 0;
188 for (UTL_NamelistActiveIterator l (supports); !l.is_done (); l.next ())
190 item = l.item ();
192 // Check that scope stack is valid.
193 if (idl_global->scopes ().top () == nullptr)
195 idl_global->err ()->lookup_error (item);
197 // This is probably the result of bad IDL.
198 // We will crash if we continue from here.
199 throw Bailout ();
202 // Look it up.
203 UTL_Scope *s = idl_global->scopes ().top ();
205 d = s->lookup_by_name (item, true);
207 if (d == nullptr)
209 AST_Decl *sad = ScopeAsDecl (s);
211 if (sad->node_type () == AST_Decl::NT_module)
213 AST_Module *m = dynamic_cast<AST_Module*> (sad);
215 d = m->look_in_prev_mods_local (item->last_component ());
219 // Not found?
220 if (d == nullptr)
222 idl_global->err ()->lookup_error (item);
224 // This is probably the result of bad IDL.
225 // We will crash if we continue from here.
226 throw Bailout ();
229 // Remove typedefs, if any.
230 if (d->node_type () == AST_Decl::NT_typedef)
232 d = dynamic_cast<AST_Typedef*> (d)->primitive_base_type ();
235 AST_Decl::NodeType nt = d->node_type ();
236 t = dynamic_cast<AST_Type*> (d);
238 if (nt == AST_Decl::NT_interface)
240 iface = dynamic_cast<AST_Interface*> (d);
242 else if (nt == AST_Decl::NT_param_holder)
244 AST_Param_Holder *ph =
245 dynamic_cast<AST_Param_Holder*> (d);
247 nt = ph->info ()->type_;
249 if (nt != AST_Decl::NT_type
250 && nt != AST_Decl::NT_interface)
252 idl_global->err ()->mismatched_template_param (
253 ph->info ()->name_.c_str ());
255 continue;
258 else
260 idl_global->err ()->supports_error (this->interface_name_,
262 continue;
265 // Forward declared interface?
266 if (iface != nullptr && !iface->is_defined ())
268 idl_global->err ()->supports_fwd_error (this->interface_name_,
269 iface);
270 continue;
273 if (iface != nullptr && !iface->is_abstract ())
275 if (i == 0)
277 this->supports_concrete_ = iface;
279 if (!this->check_concrete_supported_inheritance (iface))
281 idl_global->err ()->concrete_supported_inheritance_error (
282 this->name (),
283 iface->name ()
287 else
289 idl_global->err ()->abstract_expected (iface);
290 continue;
294 this->supports_[i++] = t;
298 bool
299 FE_OBVHeader::check_concrete_supported_inheritance (AST_Interface *d)
301 if (this->n_inherits_ == 0)
303 return true;
306 AST_ValueType *vt = nullptr;
307 AST_Type *concrete = nullptr;
308 AST_Interface *ancestor = nullptr;
310 for (long i = 0; i < this->n_inherits_; ++i)
312 vt = dynamic_cast<AST_ValueType*> (this->inherits_[i]);
313 concrete = vt->supports_concrete ();
315 if (nullptr == concrete)
317 return true;
320 if (d == concrete)
322 return true;
325 for (long j = 0; j < d->n_inherits_flat (); ++j)
327 ancestor = d->inherits_flat ()[j];
329 if (ancestor == concrete)
331 return true;
336 return false;