Remove redundant void from tao_idl
[ACE_TAO.git] / TAO / TAO_IDL / fe / fe_interface_header.cpp
blob012262fc770f5de18121418ce22d3796766eee9e
1 /*
3 COPYRIGHT
5 Copyright 1992, 1993, 1994 Sun Microsystems, Inc. Printed in the United
6 States of America. All Rights Reserved.
8 This product is protected by copyright and distributed under the following
9 license restricting its use.
11 The Interface Definition Language Compiler Front End (CFE) is made
12 available for your use provided that you include this license and copyright
13 notice on all media and documentation and the software program in which
14 this product is incorporated in whole or part. You may copy and extend
15 functionality (but may not remove functionality) of the Interface
16 Definition Language CFE without charge, but you are not authorized to
17 license or distribute it to anyone else except as part of a product or
18 program developed by you or with the express written consent of Sun
19 Microsystems, Inc. ("Sun").
21 The names of Sun Microsystems, Inc. and any of its subsidiaries or
22 affiliates may not be used in advertising or publicity pertaining to
23 distribution of Interface Definition Language CFE as permitted herein.
25 This license is effective until terminated by Sun for failure to comply
26 with this license. Upon termination, you shall destroy or return all code
27 and documentation for the Interface Definition Language CFE.
29 INTERFACE DEFINITION LANGUAGE CFE IS PROVIDED AS IS WITH NO WARRANTIES OF
30 ANY KIND INCLUDING THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS
31 FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR ARISING FROM A COURSE OF
32 DEALING, USAGE OR TRADE PRACTICE.
34 INTERFACE DEFINITION LANGUAGE CFE IS PROVIDED WITH NO SUPPORT AND WITHOUT
35 ANY OBLIGATION ON THE PART OF Sun OR ANY OF ITS SUBSIDIARIES OR AFFILIATES
36 TO ASSIST IN ITS USE, CORRECTION, MODIFICATION OR ENHANCEMENT.
38 SUN OR ANY OF ITS SUBSIDIARIES OR AFFILIATES SHALL HAVE NO LIABILITY WITH
39 RESPECT TO THE INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY
40 INTERFACE DEFINITION LANGUAGE CFE OR ANY PART THEREOF.
42 IN NO EVENT WILL SUN OR ANY OF ITS SUBSIDIARIES OR AFFILIATES BE LIABLE FOR
43 ANY LOST REVENUE OR PROFITS OR OTHER SPECIAL, INDIRECT AND CONSEQUENTIAL
44 DAMAGES, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
46 Use, duplication, or disclosure by the government is subject to
47 restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
48 Technical Data and Computer Software clause at DFARS 252.227-7013 and FAR
49 52.227-19.
51 Sun, Sun Microsystems and the Sun logo are trademarks or registered
52 trademarks of Sun Microsystems, Inc.
54 SunSoft, Inc.
55 2550 Garcia Avenue
56 Mountain View, California 94043
58 NOTE:
60 SunOS, SunSoft, Sun, Solaris, Sun Microsystems or the Sun logo are
61 trademarks or registered trademarks of Sun Microsystems, Inc.
65 // These utility classes are used to store information about a
66 // node type as the node type is being parsed and before the
67 // node itself is created.
69 #include "fe_interface_header.h"
71 #include "ace/streams.h"
73 #include "utl_namelist.h"
74 #include "utl_err.h"
76 #include "fe_extern.h"
77 #include "global_extern.h"
78 #include "nr_extern.h"
80 #include "ast_interface_fwd.h"
81 #include "ast_valuetype.h"
82 #include "ast_component.h"
83 #include "ast_home.h"
84 #include "ast_module.h"
85 #include "ast_param_holder.h"
87 #undef INCREMENT
88 #define INCREMENT 512
90 // @@@ (JP) Here are the rules for interface inheritance and
91 // value type inheritance and supports, straight from Jonathan
92 // Biggar <jon@floorboard.com> as of 3/28/02. The following was
93 // resolved by the OMG, but is not yet part of an official spec.
96 An interface can inherit from any number of other interfaces, abstract
97 or not.
99 An abstract interface can only inherit from other abstract interfaces.
101 An abstract valuetype can inherit from any number of abstract
102 valuetypes. It may support one interface, and in addition, any number
103 of abstract interfaces.
105 A concrete valuetype can inherit from only one concrete valuetype. It
106 may inherit from any number of abstract valuetypes. It may support one
107 interface, and any number of abstract interfaces.
109 The single concrete inherited valuetype must be the first one in the
110 inheritance list.
112 The single supported interface (for valuetypes) must also be the first
113 in the "supports" list.
115 And one more important clarification, if a base valuetype supports an
116 interface, a derived valuetype may also be declared to support an
117 interface, as long as it is derived from all interfaces that are
118 supported by any base valuetypes. Here is an example:
120 interface I1 { };
121 interface I2 { };
122 interface I3: I1, I2 { };
124 abstract valuetype V1 supports I1 { };
125 abstract valuetype V2 supports I2 { };
126 valuetype V3: V1, V2 supports I3 { }; // legal
127 valuetype V4: V1 supports I2 { }; // illegal
129 This last rule was made to guarantee that any given valuetype supported
130 at most one most-derived interface. We didn't want valuetypes to extend
131 the OMG model through the backdoor by providing multiple non-related
132 interfaces.
135 FE_InterfaceHeader::FE_InterfaceHeader (UTL_ScopedName *n,
136 UTL_NameList *inherits,
137 bool is_local,
138 bool is_abstract,
139 bool compile_now)
140 : interface_name_ (n),
141 has_template_parent_ (false),
142 inherits_ (0),
143 n_inherits_ (0),
144 inherits_flat_ (0),
145 n_inherits_flat_ (0),
146 is_local_ (is_local),
147 is_abstract_ (is_abstract),
148 iseen_ (0),
149 iseen_flat_ (0),
150 iallocated_ (0),
151 iused_ (0),
152 iallocated_flat_ (0),
153 iused_flat_ (0)
155 if (compile_now)
157 this->compile_inheritance (inherits,
158 false);
162 FE_InterfaceHeader::~FE_InterfaceHeader ()
166 bool
167 FE_InterfaceHeader::is_local () const
169 return this->is_local_;
172 bool
173 FE_InterfaceHeader::is_abstract () const
175 return this->is_abstract_;
178 void
179 FE_InterfaceHeader::destroy ()
181 if (0 != this->interface_name_)
183 this->interface_name_->destroy ();
184 delete this->interface_name_;
185 this->interface_name_ = 0;
188 delete [] this->iseen_;
189 delete [] this->iseen_flat_;
192 // Add this interface to the list of inherited if not already there.
193 void
194 FE_InterfaceHeader::compile_one_inheritance (AST_Type *i)
196 // Check for badly formed interface.
197 if (i == 0)
199 return;
202 // If we've seen it already then don't expand again.
203 if (this->already_seen (i))
205 return;
208 // OK, add i to the list of inherited interfaces.
209 this->add_inheritance (i);
211 AST_Interface *iface =
212 dynamic_cast<AST_Interface*> (i);
214 if (iface == 0)
216 // If a template parameter as parent appears at any time,
217 // we bag the flat list until instantiation time.
218 this->has_template_parent_ = true;
219 this->destroy_flat_arrays ();
221 else if (! this->has_template_parent_)
223 // And add i to the flat list as well.
224 if (!this->already_seen_flat (iface))
226 this->add_inheritance_flat (iface);
229 // Add i's parents to the flat list.
230 AST_Interface **parents = iface->inherits_flat ();
231 long num_parents = iface->n_inherits_flat ();
233 for (long j = 0; j < num_parents; ++j)
235 AST_Interface *tmp =
236 dynamic_cast<AST_Interface*> (parents[j]);
238 if (tmp == 0)
240 // If a template parameter as parent appears at any time,
241 // we bag the flat list until instantiation time.
242 this->has_template_parent_ = true;
243 this->destroy_flat_arrays ();
244 break;
246 else if (! this->has_template_parent_)
248 if (this->already_seen_flat (tmp))
250 continue;
253 this->add_inheritance_flat (tmp);
259 // Compute the list of top-level interfaces this one inherits from.
260 void
261 FE_InterfaceHeader::compile_inheritance (UTL_NameList *ifaces,
262 bool for_valuetype)
264 if (ifaces == 0)
266 return;
269 AST_Decl *d = 0;
270 UTL_ScopedName *item = 0;
271 AST_Interface *i = 0;
273 // Compute expanded flattened non-repeating list of interfaces
274 // which this one inherits from.
276 for (UTL_NamelistActiveIterator l (ifaces);
277 !l.is_done ();
278 l.next ())
280 item = l.item ();
282 UTL_Scope *s = idl_global->scopes ().top ();
284 // Check that scope stack is valid.
285 if (s == 0)
287 idl_global->err ()->lookup_error (item);
289 // This is probably the result of bad IDL.
290 // We will crash if we continue from here.
291 throw Bailout ();
294 // Look it up.
295 d = s->lookup_by_name (item,
296 true); // full_def_only
298 // Undefined interface?
299 if (0 == d)
301 // If the lookup now succeeds, without the full_def_only
302 // constraint, it's an error.
303 d = s->lookup_by_name (item, false);
305 if (0 != d)
307 idl_global->err ()->inheritance_fwd_error (
308 this->interface_name_,
309 dynamic_cast<AST_Interface*> (d)
311 break;
315 if (0 == d)
317 AST_Decl *sad = ScopeAsDecl (s);
319 if (sad->node_type () == AST_Decl::NT_module)
321 AST_Module *m = dynamic_cast<AST_Module*> (sad);
323 d = m->look_in_prev_mods_local (item->last_component ());
327 // Not found?
328 if (0 == d)
330 idl_global->err ()->lookup_error (item);
332 // This is probably the result of bad IDL.
333 // We will crash if we continue from here.
334 throw Bailout ();
337 AST_Decl::NodeType nt = d->node_type ();
339 // Not an appropriate interface?
340 if (nt == AST_Decl::NT_typedef)
342 d = dynamic_cast<AST_Typedef*> (d)->primitive_base_type ();
345 i = dynamic_cast<AST_Interface*> (d);
347 if (i != 0)
349 if (this->check_inherit (i, for_valuetype) == -1)
351 idl_global->err ()->interface_expected (d);
352 break;
354 else if (!for_valuetype
355 && this->is_abstract_
356 && !i->is_abstract ())
358 idl_global->err ()->abstract_inheritance_error (
359 this->name (),
360 i->name ());
361 break;
364 else if (nt == AST_Decl::NT_param_holder)
366 AST_Param_Holder *ph =
367 dynamic_cast<AST_Param_Holder*> (d);
369 nt = ph->info ()->type_;
371 bool ok_param =
372 nt == AST_Decl::NT_type
373 || (nt == AST_Decl::NT_interface && !for_valuetype)
374 || (nt == AST_Decl::NT_valuetype && for_valuetype);
376 if (!ok_param)
378 idl_global->err ()->mismatched_template_param (
379 ph->info ()->name_.c_str ());
381 break;
384 else
386 idl_global->err ()->interface_expected (d);
387 break;
390 // OK, see if we have to add this to the list of interfaces
391 // inherited from.
392 this->compile_one_inheritance (
393 dynamic_cast<AST_Type*> (d));
396 // OK, install in interface header.
397 this->install_in_header ();
401 FE_InterfaceHeader::check_inherit (AST_Interface *i,
402 bool for_valuetype)
404 // We use the narrow instead of node_type() here so we can get a
405 // match with both valuetypes and eventtypes.
406 bool is_valuetype = (dynamic_cast<AST_ValueType*> (i) != 0);
408 if (
409 // Non-local interfaces may not inherit from local ones.
410 (! this->is_local_ && i->is_local ())
411 // Both valuetype or both interface.
412 || (for_valuetype ^ is_valuetype)
415 return -1;
417 else
419 return 0;
423 // Add an interface to an inheritance spec.
424 void
425 FE_InterfaceHeader::add_inheritance (AST_Type *i)
427 AST_Type **oiseen = 0;
429 // Make sure there's space for one more.
430 if (this->iallocated_ == this->iused_)
432 if (this->iallocated_ == 0)
434 this->iallocated_ = INCREMENT;
436 ACE_NEW (this->iseen_,
437 AST_Type *[this->iallocated_]);
439 else
441 oiseen = this->iseen_;
442 this->iallocated_ += INCREMENT;
444 ACE_NEW (this->iseen_,
445 AST_Type *[this->iallocated_]);
447 for (long k = 0; k < this->iused_; ++k)
449 this->iseen_[k] = oiseen[k];
452 delete [] oiseen;
456 // OK, now insert it.
457 this->iseen_[this->iused_++] = i;
460 // Add an interface to the flat list.
461 void
462 FE_InterfaceHeader::add_inheritance_flat (AST_Interface *i)
464 AST_Interface **oiseen_flat = 0;
466 // Make sure there's space for one more.
467 if (this->iallocated_flat_ == this->iused_flat_)
469 if (this->iallocated_flat_ == 0)
471 this->iallocated_flat_ = INCREMENT;
473 ACE_NEW (this->iseen_flat_,
474 AST_Interface *[this->iallocated_flat_]);
476 else
478 oiseen_flat = this->iseen_flat_;
479 this->iallocated_flat_ += INCREMENT;
481 ACE_NEW (this->iseen_flat_,
482 AST_Interface *[this->iallocated_flat_]);
484 for (long k = 0; k < this->iused_flat_; k++)
486 this->iseen_flat_[k] = oiseen_flat[k];
489 delete [] oiseen_flat;
493 // OK, now insert it.
494 this->iseen_flat_[this->iused_flat_++] = i;
497 // Have we already seen this interface?
498 bool
499 FE_InterfaceHeader::already_seen (AST_Type *ip)
501 AST_Param_Holder *ph =
502 dynamic_cast<AST_Param_Holder*> (ip);
504 for (long i = 0; i < this->iused_; ++i)
506 AST_Param_Holder *tmp =
507 dynamic_cast<AST_Param_Holder*> (this->iseen_[i]);
509 if (ph != 0 && tmp != 0)
511 if (ph->info ()->name_ == tmp->info ()->name_)
513 idl_global->err ()->duplicate_param_id (ph->name ());
514 ph->destroy ();
515 delete ph;
516 ph = 0;
517 return true;
520 else if (this->iseen_[i] == ip)
522 return true;
526 return false;
529 // Have we already seen this interface in the flat list?
530 bool
531 FE_InterfaceHeader::already_seen_flat (AST_Interface *ip)
533 for (long i = 0; i < this->iused_flat_; ++i)
535 if (this->iseen_flat_[i] == ip)
537 return true;
541 return false;
544 void
545 FE_InterfaceHeader::install_in_header ()
547 long j = 0;
548 long k = 0;
550 // First the flat list (all ancestors).
551 if (this->iused_flat_ > 0)
553 ACE_NEW (this->inherits_flat_,
554 AST_Interface *[this->iused_flat_]);
556 for (j = 0; j < this->iused_flat_; ++j)
558 this->inherits_flat_[j] = this->iseen_flat_[j];
561 this->n_inherits_flat_ = iused_flat_;
564 // Then the list of immediate ancestors.
565 if (this->iused_ > 0)
567 ACE_NEW (this->inherits_,
568 AST_Type *[this->iused_]);
570 for (k = 0; k < this->iused_; ++k)
572 this->inherits_[k] = this->iseen_[k];
575 this->n_inherits_ = this->iused_;
579 // Data accessors.
581 UTL_ScopedName *
582 FE_InterfaceHeader::name () const
584 return this->interface_name_;
587 AST_Type **
588 FE_InterfaceHeader::inherits () const
590 return this->inherits_;
593 long
594 FE_InterfaceHeader::n_inherits () const
596 return this->n_inherits_;
599 AST_Interface **
600 FE_InterfaceHeader::inherits_flat () const
602 return this->inherits_flat_;
605 long
606 FE_InterfaceHeader::n_inherits_flat () const
608 return this->n_inherits_flat_;
611 void
612 FE_InterfaceHeader::destroy_flat_arrays ()
614 delete [] this->inherits_flat_;
615 this->inherits_flat_ = 0;
616 delete [] this->iseen_flat_;
617 this->iseen_flat_ = 0;
618 this->n_inherits_flat_ = 0;
619 this->iallocated_flat_ = 0;
620 this->iused_flat_ = 0;