1 #include "fe_obv_header.h"
4 #include "utl_namelist.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
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
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:
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
59 FE_OBVHeader::FE_OBVHeader (UTL_ScopedName
*n
,
60 UTL_NameList
*inherits
,
61 UTL_NameList
*supports
,
64 : FE_InterfaceHeader (n
,
71 inherits_concrete_ (nullptr),
72 supports_concrete_ (nullptr),
73 truncatable_ (truncatable
)
75 this->compile_inheritance (inherits
,
78 if (idl_global
->err_count () == 0)
80 this->compile_supports (supports
);
84 FE_OBVHeader::~FE_OBVHeader ()
89 FE_OBVHeader::supports () const
91 return this->supports_
;
95 FE_OBVHeader::n_supports () const
97 return this->n_supports_
;
101 FE_OBVHeader::inherits_concrete () const
103 return this->inherits_concrete_
;
107 FE_OBVHeader::supports_concrete () const
109 return this->supports_concrete_
;
113 FE_OBVHeader::truncatable () const
115 return this->truncatable_
;
119 FE_OBVHeader::destroy ()
121 this->FE_InterfaceHeader::destroy ();
125 FE_OBVHeader::compile_inheritance (UTL_NameList
*vtypes
,
128 this->FE_InterfaceHeader::compile_inheritance (vtypes
,
131 if (this->n_inherits_
> 0)
133 AST_Type
*t
= this->inherits_
[0];
134 AST_ValueType
*vt
= dynamic_cast<AST_ValueType
*> (t
);
137 && vt
->is_abstract () == false)
139 this->inherits_concrete_
= vt
;
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
);
158 && t
->node_type () == AST_Decl::NT_eventtype
)
160 idl_global
->err ()->valuetype_expected (t
);
167 FE_OBVHeader::compile_supports (UTL_NameList
*supports
)
169 if (supports
== nullptr)
171 this->supports_
= nullptr;
172 this->n_supports_
= 0;
176 long length
= supports
->length ();
177 this->n_supports_
= length
;
179 ACE_NEW (this->supports_
,
182 AST_Decl
*d
= nullptr;
183 UTL_ScopedName
*item
= nullptr;
184 AST_Interface
*iface
= nullptr;
185 AST_Type
*t
= nullptr;
188 for (UTL_NamelistActiveIterator
l (supports
); !l
.is_done (); l
.next ())
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.
203 UTL_Scope
*s
= idl_global
->scopes ().top ();
205 d
= s
->lookup_by_name (item
, true);
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 ());
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.
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 ());
260 idl_global
->err ()->supports_error (this->interface_name_
,
265 // Forward declared interface?
266 if (iface
!= nullptr && !iface
->is_defined ())
268 idl_global
->err ()->supports_fwd_error (this->interface_name_
,
273 if (iface
!= nullptr && !iface
->is_abstract ())
277 this->supports_concrete_
= iface
;
279 if (!this->check_concrete_supported_inheritance (iface
))
281 idl_global
->err ()->concrete_supported_inheritance_error (
289 idl_global
->err ()->abstract_expected (iface
);
294 this->supports_
[i
++] = t
;
299 FE_OBVHeader::check_concrete_supported_inheritance (AST_Interface
*d
)
301 if (this->n_inherits_
== 0)
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
)
325 for (long j
= 0; j
< d
->n_inherits_flat (); ++j
)
327 ancestor
= d
->inherits_flat ()[j
];
329 if (ancestor
== concrete
)