Merge pull request #2309 from mitza-oci/warnings
[ACE_TAO.git] / TAO / TAO_IDL / ast / ast_interface.cpp
blob0ded8e138f02c44c0da92c91eb290bb5dacca67a
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 // AST_Interfaces denote IDL interface definitions
66 // AST_Interfaces are subclasses of AST_Type and UTL_Scope
67 // AST_Interfaces have an array of inherited interfaces and
68 // a count of the number of inherited interfaces. This count
69 // represents the total number of unique (recursively) inherited
70 // interfaces.
72 #include "ast_interface.h"
73 #include "ast_interface_fwd.h"
74 #include "ast_valuetype.h"
75 #include "ast_component.h"
76 #include "ast_template_module.h"
77 #include "ast_constant.h"
78 #include "ast_exception.h"
79 #include "ast_attribute.h"
80 #include "ast_operation.h"
81 #include "ast_field.h"
82 #include "ast_enum.h"
83 #include "ast_enum_val.h"
84 #include "ast_union.h"
85 #include "ast_union_fwd.h"
86 #include "ast_structure_fwd.h"
87 #include "ast_typedef.h"
88 #include "ast_native.h"
89 #include "ast_visitor.h"
90 #include "ast_extern.h"
92 #include "utl_err.h"
93 #include "utl_identifier.h"
94 #include "utl_indenter.h"
95 #include "utl_string.h"
97 #include "global_extern.h"
98 #include "nr_extern.h"
100 #include "ace/streams.h"
102 AST_Decl::NodeType const
103 AST_Interface::NT = AST_Decl::NT_interface;
105 AST_Interface::AST_Interface (UTL_ScopedName *n,
106 AST_Type **ih,
107 long nih,
108 AST_Interface **ih_flat,
109 long nih_flat,
110 bool local,
111 bool abstract)
112 : COMMON_Base (local,
113 abstract),
114 AST_Decl (AST_Decl::NT_interface,
116 AST_Type (AST_Decl::NT_interface,
118 UTL_Scope (AST_Decl::NT_interface),
119 pd_inherits (ih),
120 pd_n_inherits (nih),
121 pd_inherits_flat (ih_flat),
122 pd_n_inherits_flat (nih_flat),
123 home_equiv_ (false),
124 fwd_decl_ (nullptr),
125 has_mixed_parentage_ (-1),
126 ami_handler_ (nullptr),
127 ami4ccm_uses_ (nullptr)
129 this->size_type (AST_Type::VARIABLE); // always the case
130 this->has_constructor (true); // always the case
132 // Enqueue the param holders (if any) for later destruction.
133 // By the time our destroy() is called, it will be too late
134 // to iterate over pd_inherits.
135 // Also check for illegal reference to a template module
136 // scope item.
137 for (long i = 0; i < nih; ++i)
139 if (ih[i]->node_type () == AST_Decl::NT_param_holder)
141 this->param_holders_.enqueue_tail (ih[i]);
144 FE_Utils::tmpl_mod_ref_check (this, ih[i]);
148 AST_Interface::~AST_Interface ()
152 void
153 AST_Interface::be_replace_operation (AST_Decl *old_op,
154 AST_Decl *new_op)
156 this->replace_scope (old_op,
157 new_op);
159 this->replace_referenced (old_op,
160 new_op);
163 AST_Operation *
164 AST_Interface::be_add_operation (AST_Operation *op)
166 return this->fe_add_operation (op);
169 bool
170 AST_Interface::is_defined ()
172 // Each instance of a forward declared interface no
173 // longer has a redefined full definition, so we
174 // have to backtrack to the fwd decl is_defined(),
175 // which searches for the one that does. If one
176 // is found, then we are defined for code generation
177 // purposes. See AST_InterfaceFwd::destroy() to
178 // see the difference for cleanup purposes.
179 return (nullptr == this->fwd_decl_
180 ? this->pd_n_inherits >= 0
181 : this->fwd_decl_->is_defined ());
184 AST_Constant *
185 AST_Interface::fe_add_constant (AST_Constant *t)
187 return dynamic_cast<AST_Constant*> (this->fe_add_decl (t));
190 AST_Exception *
191 AST_Interface::fe_add_exception (AST_Exception *t)
193 return dynamic_cast<AST_Exception*> (this->fe_add_decl (t));
196 AST_Attribute *
197 AST_Interface::fe_add_attribute (AST_Attribute *t)
199 return dynamic_cast<AST_Attribute*> (this->fe_add_decl (t));
202 AST_Operation *
203 AST_Interface::fe_add_operation (AST_Operation *t)
205 return dynamic_cast<AST_Operation*> (this->fe_add_decl (t));
208 AST_Structure *
209 AST_Interface::fe_add_structure (AST_Structure *t)
211 return this->fe_add_full_struct_type (t);
214 AST_StructureFwd *
215 AST_Interface::fe_add_structure_fwd (AST_StructureFwd *t)
217 return this->fe_add_fwd_struct_type (t);
220 AST_Enum *
221 AST_Interface::fe_add_enum (AST_Enum *t)
223 return dynamic_cast<AST_Enum*> (this->fe_add_decl (t));
226 AST_Union *
227 AST_Interface::fe_add_union (AST_Union *t)
229 return dynamic_cast<AST_Union*> (this->fe_add_full_struct_type (t));
232 AST_UnionFwd *
233 AST_Interface::fe_add_union_fwd (AST_UnionFwd *t)
235 return dynamic_cast<AST_UnionFwd*> (this->fe_add_fwd_struct_type (t));
238 // Add an AST_EnumVal node (an enumerator) to this scope.
239 // This is done to conform to the C++ scoping rules which declare
240 // enumerators in the enclosing scope (in addition to declaring them
241 // in the enum itself).
242 AST_EnumVal *
243 AST_Interface::fe_add_enum_val (AST_EnumVal *t)
245 return dynamic_cast<AST_EnumVal*> (this->fe_add_decl (t));
248 // Add an AST_Typedef (a typedef) to the current scope.
249 AST_Typedef *
250 AST_Interface::fe_add_typedef (AST_Typedef *t)
252 return dynamic_cast<AST_Typedef*> (this->fe_add_ref_decl (t));
255 AST_Native *
256 AST_Interface::fe_add_native (AST_Native *t)
258 return dynamic_cast<AST_Native*> (this->fe_add_decl (t));
261 // Dump this AST_Interface node to the ostream o.
262 void
263 AST_Interface::dump (ACE_OSTREAM_TYPE &o)
265 if (this->is_abstract ())
267 this->dump_i (o, "abstract ");
269 else if (this->is_local ())
271 this->dump_i (o, "local ");
274 this->dump_i (o, "interface ");
276 this->local_name ()->dump (o);
277 this->dump_i (o, " ");
279 if (this->pd_n_inherits > 0)
281 this->dump_i (o, ": ");
283 for (long i = 0; i < this->pd_n_inherits; ++i)
285 this->pd_inherits[i]->local_name ()->dump (o);
287 if (i < this->pd_n_inherits - 1)
289 this->dump_i (o, ", ");
294 this->dump_i (o, " {\n");
296 UTL_Scope::dump (o);
297 idl_global->indent ()->skip_to (o);
299 this->dump_i (o, "}");
302 // This serves for interfaces, valuetypes, components and eventtypes.
303 void
304 AST_Interface::fwd_redefinition_helper (AST_Interface *&i,
305 UTL_Scope *s)
307 if (i == nullptr)
309 return;
312 UTL_Scope *scope = i->defined_in ();
313 const char *prefix_holder = nullptr;
315 // If our prefix is empty, we check to see if an ancestor has one.
316 while (ACE_OS::strcmp (i->prefix (), "") == 0 && scope != nullptr)
318 AST_Decl *parent = ScopeAsDecl (scope);
319 prefix_holder = parent->prefix ();
321 // We have reached global scope.
322 if (prefix_holder == nullptr)
324 break;
327 i->prefix (const_cast<char *> (prefix_holder));
328 scope = parent->defined_in ();
331 // Fwd redefinition should be in the same scope, so local
332 // lookup is all that's needed.
333 AST_Decl *d = s->lookup_by_name_local (i->local_name (), false);
334 if (d != nullptr)
336 scope = d->defined_in ();
338 // If the lookup prefix is empty, we check to see if an ancestor has one.
339 while (ACE_OS::strcmp (d->prefix (), "") == 0 && scope != nullptr)
341 AST_Decl *parent = ScopeAsDecl (scope);
342 prefix_holder = parent->prefix ();
344 // We have reached global scope.
345 if (prefix_holder == nullptr)
347 break;
350 d->prefix (const_cast<char *> (prefix_holder));
351 scope = parent->defined_in ();
354 AST_Interface *fd = dynamic_cast<AST_Interface *> (d);
355 if (fd == nullptr)
357 AST_Decl::NodeType nt = d->node_type ();
359 if (nt == AST_Decl::NT_struct_fwd || nt == AST_Decl::NT_union_fwd)
361 idl_global->err ()->redef_error (i->full_name (),
362 d->full_name ());
365 // If it is a forward declared interface..
366 else if (!fd->is_defined ())
368 // Check if redefining in same scope. If a module is reopened,
369 // a new pointer in created, and the first term below will be
370 // true. In that case, the scoped names must be compared.
371 if (fd->defined_in () != s
372 && i->name ()->compare (fd->name ()) != 0)
374 idl_global->err ()->error2 (UTL_Error::EIDL_SCOPE_CONFLICT,
376 fd);
378 // All OK, do the redefinition.
379 else
381 AST_Decl::NodeType fd_nt = fd->node_type ();
382 AST_Decl::NodeType i_nt = i->node_type ();
384 // Only redefinition of the same kind.
385 if (i->is_local () != fd->is_local ()
386 || i_nt != fd_nt
387 || i->is_abstract () != fd->is_abstract ())
389 idl_global->err ()->error2 (UTL_Error::EIDL_REDEF,
391 fd);
392 return;
395 fd->redefine (i);
397 AST_InterfaceFwd *fwd = fd->fwd_decl ();
398 if (fwd != nullptr)
400 fwd->set_as_defined ();
403 // Use full definition node.
404 i->destroy ();
405 delete i;
406 i = fd;
412 void
413 AST_Interface::redef_clash_populate_r (AST_Type *t)
415 if (this->insert_non_dup (t, false) == 0)
417 return;
420 AST_Decl::NodeType nt = t->node_type ();
421 long n = 0;
423 if (nt != AST_Decl::NT_param_holder)
425 AST_Interface *i = dynamic_cast<AST_Interface*> (t);
427 AST_Type **parents = i->inherits ();
428 long n_parents = i->n_inherits ();
430 for (n = 0; n < n_parents; ++n)
432 this->redef_clash_populate_r (parents[n]);
436 if (nt == AST_Decl::NT_valuetype || nt == AST_Decl::NT_eventtype)
438 AST_ValueType *v = dynamic_cast<AST_ValueType*> (t);
439 AST_Type **supports = v->supports ();
440 long n_supports = v->n_supports ();
442 for (n = 0; n < n_supports; ++n)
444 this->redef_clash_populate_r (supports[n]);
447 else if (nt == AST_Decl::NT_component)
449 AST_Component *c = dynamic_cast<AST_Component*> (t);
450 AST_Type **supports = c->supports ();
451 long n_supports = c->n_supports ();
453 for (n = 0; n < n_supports; ++n)
455 this->redef_clash_populate_r (supports[n]);
460 bool
461 AST_Interface::home_equiv () const
463 return this->home_equiv_;
466 void
467 AST_Interface::home_equiv (bool val)
469 this->home_equiv_ = val;
472 AST_InterfaceFwd *
473 AST_Interface::fwd_decl () const
475 return this->fwd_decl_;
478 void
479 AST_Interface::fwd_decl (AST_InterfaceFwd *node)
481 this->fwd_decl_ = node;
485 AST_Interface::insert_non_dup (AST_Type *t,
486 bool abstract_paths_only)
488 AST_Interface *f = dynamic_cast<AST_Interface*> (t);
490 // Now check if the dequeued element has any ancestors. If yes, insert
491 // them inside the queue making sure that there are no duplicates.
492 // If we are doing a component, the inheritance list is actually a
493 // supports list.
494 if (f != nullptr)
496 for (long i = 0; i < f->n_inherits (); ++i)
498 // Retrieve the next parent from which
499 // the dequeued element inherits.
500 AST_Type *parent = f->inherits ()[i];
502 if (abstract_paths_only && ! parent->is_abstract ())
504 continue;
507 (void) this->insert_non_dup (parent,
508 abstract_paths_only);
512 const char *full_name = t->full_name ();
514 // Initialize an iterator to search the queue for duplicates.
515 for (ACE_Unbounded_Queue_Iterator<AST_Type *> q_iter (
516 this->insert_queue
518 !q_iter.done ();
519 (void) q_iter.advance ())
521 // Queue element.
522 AST_Type **temp = nullptr;
524 (void) q_iter.next (temp);
526 if (!ACE_OS::strcmp (full_name,
527 (*temp)->full_name ()))
529 // We exist in this queue and cannot be inserted.
530 return 0;
534 // Initialize an iterator to search the del_queue for duplicates.
535 for (ACE_Unbounded_Queue_Iterator<AST_Type *> del_q_iter (
536 this->del_queue
538 !del_q_iter.done ();
539 (void) del_q_iter.advance ())
541 // Queue element.
542 AST_Type **temp = nullptr;
544 (void) del_q_iter.next (temp);
546 if (!ACE_OS::strcmp (full_name,
547 (*temp)->full_name ()))
549 // We exist in this del_queue and cannot be inserted.
550 return 0;
554 // Insert the parent in the queue.
555 if (this->insert_queue.enqueue_tail (t) == -1)
557 ACE_ERROR_RETURN ((LM_ERROR,
558 "(%N:%l) be_interface::insert_non_dup - "
559 "enqueue failed\n"),
563 return 1;
566 // This serves only for interfaces. It is overridden for valuetypes,
567 // components and eventtypes.
568 void
569 AST_Interface::redefine (AST_Interface *from)
571 // 'this' is the full_definition member of a forward
572 // declared interface. 'from' is the actual full
573 // definition, which may be in a different scope.
574 // Since 'this' will replace 'from' upon returning
575 // from here, we have to update the scope now.
576 this->pd_n_inherits = from->pd_n_inherits;
577 unsigned long i = 0;
579 unsigned long array_size =
580 static_cast<unsigned long> (from->pd_n_inherits);
581 ACE_NEW (this->pd_inherits,
582 AST_Type *[array_size]);
584 for (i = 0; i < array_size; ++i)
586 this->pd_inherits[i] = from->pd_inherits[i];
589 this->pd_n_inherits_flat = from->pd_n_inherits_flat;
590 array_size =
591 static_cast<unsigned long> (from->pd_n_inherits_flat);
592 ACE_NEW (this->pd_inherits_flat,
593 AST_Interface *[array_size]);
595 for (i = 0; i < array_size; ++i)
597 this->pd_inherits_flat[i] = from->pd_inherits_flat[i];
600 // We've already checked for inconsistent prefixes.
601 this->prefix (from->prefix ());
603 this->set_defined_in (from->defined_in ());
604 this->set_imported (idl_global->imported ());
605 this->set_in_main_file (idl_global->in_main_file ());
606 this->set_line (idl_global->lineno ());
607 this->set_file_name (idl_global->filename ()->get_string ());
608 this->ifr_added_ = from->ifr_added_;
609 this->ifr_fwd_added_ = from->ifr_fwd_added_;
612 // Data accessors.
614 AST_Type **
615 AST_Interface::inherits () const
617 return this->pd_inherits;
620 long
621 AST_Interface::n_inherits () const
623 return this->pd_n_inherits;
626 AST_Interface **
627 AST_Interface::inherits_flat () const
629 return this->pd_inherits_flat;
632 long
633 AST_Interface::n_inherits_flat () const
635 return pd_n_inherits_flat;
638 ACE_Unbounded_Queue<AST_Type *> &
639 AST_Interface::get_insert_queue ()
641 return this->insert_queue;
644 ACE_Unbounded_Queue<AST_Type *> &
645 AST_Interface::get_del_queue ()
647 return this->del_queue;
650 bool
651 AST_Interface::redef_clash ()
653 this->insert_queue.reset ();
654 this->redef_clash_populate_r (this);
656 AST_Type **group1_member = nullptr;
657 AST_Type **group2_member = nullptr;
658 AST_Decl *group1_member_item = nullptr;
659 AST_Decl *group2_member_item = nullptr;
661 int i = 1;
663 // Now compare all pairs.
664 for (ACE_Unbounded_Queue_Iterator<AST_Type *> group1_iter (
665 this->insert_queue
667 !group1_iter.done ();
668 (void) group1_iter.advance (), ++i)
670 // Queue element.
671 (void) group1_iter.next (group1_member);
672 UTL_Scope *s = DeclAsScope (*group1_member);
674 if (s != nullptr)
676 for (UTL_ScopeActiveIterator group1_member_items (
678 UTL_Scope::IK_decls);
679 !group1_member_items.is_done ();
680 group1_member_items.next ())
682 group1_member_item = group1_member_items.item ();
683 AST_Decl::NodeType nt1 =
684 group1_member_item->node_type ();
686 // Only these member types may cause a clash because
687 // they can't be redefined.
688 if (nt1 != AST_Decl::NT_op
689 && nt1 != AST_Decl::NT_attr)
691 continue;
694 Identifier *pid1 = group1_member_item->local_name ();
695 int j = 0;
697 for (ACE_Unbounded_Queue_Iterator<AST_Type *> group2_iter (
698 this->insert_queue);
699 !group2_iter.done ();
700 (void) group2_iter.advance ())
702 // Since group1 and group2 are the same list, we can start this
703 // iterator from where the outer one is.
704 while (j++ < i)
706 group2_iter.advance ();
709 if (group2_iter.done ())
711 break;
714 // Queue element.
715 (void) group2_iter.next (group2_member);
716 UTL_Scope *ss = DeclAsScope (*group2_member);
718 if (ss != nullptr)
720 for (UTL_ScopeActiveIterator group2_member_items (
722 UTL_Scope::IK_decls);
723 !group2_member_items.is_done ();
724 group2_member_items.next ())
726 group2_member_item =
727 group2_member_items.item ();
729 AST_Decl::NodeType nt2 =
730 group2_member_item->node_type ();
732 // Only these member types may cause a clash
733 // with other parents' member of the same type.
734 if (nt2 != AST_Decl::NT_op
735 && nt2 != AST_Decl::NT_attr)
737 continue;
740 Identifier *pid2 =
741 group2_member_item->local_name ();
743 if (pid1->compare (pid2) == true)
745 idl_global->err ()->error3 (
746 UTL_Error::EIDL_REDEF,
747 *group1_member,
748 *group2_member,
749 group2_member_item);
751 return true;
753 else if (pid1->case_compare_quiet (pid2))
755 if (idl_global->case_diff_error ())
757 idl_global->err ()->error3 (
758 UTL_Error::EIDL_NAME_CASE_ERROR,
759 *group1_member,
760 group1_member_item,
761 group2_member_item);
763 return true;
765 else
767 idl_global->err ()->warning3 (
768 UTL_Error::EIDL_NAME_CASE_WARNING,
769 *group1_member,
770 group1_member_item,
771 group2_member_item);
774 } // end of FOR (group2_member_items)
775 } // end of IF ss != 0
776 } // end of FOR (group2_iter)
777 } // end of FOR (group1_member_items)
778 } // end of IF s != 0
779 } // end of FOR (group1_iter)
781 return false;
784 // Look through inherited interfaces.
785 AST_Decl *
786 AST_Interface::look_in_inherited (UTL_ScopedName *e,
787 bool full_def_only)
789 AST_Decl *d = nullptr;
790 AST_Decl *d_before = nullptr;
791 AST_Type **is = nullptr;
792 long nis = -1;
794 // Can't look in an interface which was not yet defined.
795 if (!this->is_defined ())
797 return nullptr;
800 // OK, loop through inherited interfaces.
802 // (Don't leave the inheritance hierarchy, no module or global ...)
803 // Find all and report ambiguous results as error.
805 for (nis = this->n_inherits (), is = this->inherits ();
806 nis > 0;
807 nis--, is++)
809 AST_Interface *i = dynamic_cast<AST_Interface*> (*is);
811 if (i == nullptr)
813 continue;
816 d = (i)->lookup_by_name_r (e, full_def_only);
817 if (d != nullptr)
819 if (d_before == nullptr)
821 // First result found.
822 d_before = d;
824 else
826 // Conflict against further results?
827 if (d != d_before)
829 ACE_ERROR ((LM_ERROR,
830 "warning in %C line %d: ",
831 idl_global->filename ()->get_string (),
832 idl_global->lineno ()));
834 e->dump (*ACE_DEFAULT_LOG_STREAM);
836 ACE_ERROR ((LM_ERROR,
837 " is ambiguous in scope.\n"
838 "Found "));
840 d->name ()->dump (*ACE_DEFAULT_LOG_STREAM);
842 ACE_ERROR ((LM_ERROR,
843 " and "));
845 d_before->name ()->dump (*ACE_DEFAULT_LOG_STREAM);
847 ACE_ERROR ((LM_ERROR,
848 ".\n"));
854 return d_before;
857 AST_Decl *
858 AST_Interface::look_in_inherited_local (Identifier *e,
859 bool full_def_only)
861 // Can't look in an interface which was not yet defined.
862 if (!this->is_defined ())
864 return nullptr;
867 AST_Decl *d = nullptr;
868 AST_Type **is = nullptr;
869 long nis = -1;
871 /// OK, loop through inherited interfaces.
872 for (nis = this->n_inherits (), is = this->inherits ();
873 nis > 0;
874 nis--, is++)
876 AST_Interface *i = dynamic_cast<AST_Interface*> (*is);
878 if (i == nullptr)
880 continue;
883 d = i->lookup_by_name_local (e, full_def_only);
885 if (d != nullptr)
887 break;
891 return d;
894 AST_Decl *
895 AST_Interface::lookup_for_add (AST_Decl *d)
897 if (d == nullptr)
899 return nullptr;
902 Identifier *id = d->local_name ();
903 AST_Decl *prev = nullptr;
904 AST_Decl::NodeType nt = NT_root;
905 long nis = -1;
906 AST_Interface **is = nullptr;
908 if (this->idl_keyword_clash (id) != 0)
910 return nullptr;
913 prev = this->lookup_by_name_local (id, false);
915 if (prev != nullptr)
917 nt = prev->node_type ();
919 if (nt == AST_Decl::NT_op || nt == AST_Decl::NT_attr)
921 return prev;
925 for (nis = this->n_inherits_flat (), is = this->inherits_flat ();
926 nis > 0;
927 nis--, is++)
929 prev = (*is)->lookup_by_name_local (id, false);
931 if (prev != nullptr)
933 nt = prev->node_type ();
935 if (nt == AST_Decl::NT_op || nt == AST_Decl::NT_attr)
937 return prev;
942 return nullptr;
946 AST_Interface::has_mixed_parentage ()
948 if (this->is_abstract_)
950 return 0;
953 AST_Decl::NodeType nt = this->node_type ();
955 if (AST_Decl::NT_component == nt
956 || AST_Decl::NT_home == nt
957 || AST_Decl::NT_connector == nt)
959 return 0;
962 if (this->has_mixed_parentage_ == -1)
964 this->analyze_parentage ();
967 return this->has_mixed_parentage_;
970 void
971 AST_Interface::analyze_parentage ()
973 if (this->has_mixed_parentage_ != -1)
975 return;
978 this->has_mixed_parentage_ = 0;
980 // Only interfaces may have mixed parentage.
981 if (this->node_type () != AST_Decl::NT_interface)
983 return;
986 for (long i = 0; i < this->pd_n_inherits; ++i)
988 AST_Interface *parent = dynamic_cast<AST_Interface*> (this->pd_inherits[i]);
990 if (parent == nullptr)
992 // The item is a template param holder.
993 continue;
996 if (parent->is_abstract ()
997 || parent->has_mixed_parentage ())
999 this->has_mixed_parentage_ = 1;
1000 break;
1004 // Must check if we are declared in a template module, in
1005 // which case no code will be generated, so we should not
1006 // be enqueued.
1007 bool in_tmpl_module = false;
1008 UTL_Scope *s = this->defined_in ();
1010 while (s != nullptr)
1012 AST_Template_Module *m = dynamic_cast<AST_Template_Module*> (s);
1014 if (m != nullptr)
1016 in_tmpl_module = true;
1017 break;
1020 s = ScopeAsDecl (s)->defined_in ();
1023 if (this->has_mixed_parentage_ == 1
1024 && this->is_defined ()
1025 && !this->imported ()
1026 && !in_tmpl_module)
1028 idl_global->mixed_parentage_interfaces ().enqueue_tail (this);
1032 bool
1033 AST_Interface::legal_for_primary_key () const
1035 return false;
1038 AST_Decl *
1039 AST_Interface::special_lookup (UTL_ScopedName *e,
1040 bool full_def_only,
1041 AST_Decl *&final_parent_decl)
1043 AST_Decl *d = this->look_in_inherited_local (e->head (),
1044 full_def_only);
1046 if (d != nullptr)
1048 UTL_Scope *s = DeclAsScope (d);
1049 UTL_ScopedName *sn =
1050 static_cast<UTL_ScopedName *> (e->tail ());
1052 return (s != nullptr && sn != nullptr
1053 ? s->lookup_by_name_r (sn, full_def_only, final_parent_decl)
1054 : d);
1057 return nullptr;
1060 AST_Interface *
1061 AST_Interface::ami_handler () const
1063 return this->ami_handler_;
1066 void
1067 AST_Interface::ami_handler (AST_Interface *handler)
1069 this->ami_handler_ = handler;
1072 AST_Interface *
1073 AST_Interface::ami4ccm_uses () const
1075 return this->ami4ccm_uses_;
1078 void
1079 AST_Interface::ami4ccm_uses (AST_Interface *implied)
1081 this->ami4ccm_uses_ = implied;
1084 void
1085 AST_Interface::destroy ()
1087 for (ACE_Unbounded_Queue_Iterator<AST_Type *> i (
1088 this->param_holders_);
1089 !i.done ();
1090 (void) i.advance ())
1092 AST_Type **tt = nullptr;
1093 i.next (tt);
1094 AST_Type *t = *tt;
1095 t->destroy ();
1096 delete t;
1097 t = nullptr;
1100 // The destroy() we are in gets called twice if we start from
1101 // be_valuetype or be_eventtype. This line keeps us from
1102 // iterating over null pointers the 2nd time.
1103 this->param_holders_.reset ();
1105 delete [] this->pd_inherits;
1106 this->pd_inherits = nullptr;
1107 this->pd_n_inherits = 0;
1109 delete [] this->pd_inherits_flat;
1110 this->pd_inherits_flat = nullptr;
1111 this->pd_n_inherits_flat = 0;
1113 this->UTL_Scope::destroy ();
1114 this->AST_Type::destroy ();
1118 AST_Interface::ast_accept (ast_visitor *visitor)
1120 return visitor->visit_interface (this);
1123 bool
1124 AST_Interface::annotatable () const
1126 return true;