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
51 Sun, Sun Microsystems and the Sun logo are trademarks or registered
52 trademarks of Sun Microsystems, Inc.
56 Mountain View, California 94043
60 SunOS, SunSoft, Sun, Solaris, Sun Microsystems or the Sun logo are
61 trademarks or registered trademarks of Sun Microsystems, Inc.
65 // AST_Structure nodes denote IDL struct declarations.
66 // AST_Structure is a subclass of AST_ConcreteType and of UTL_Scope (the
67 // structure's fields are managed in a scope).
69 #include "ast_union.h"
70 #include "ast_structure_fwd.h"
71 #include "ast_field.h"
73 #include "ast_enum_val.h"
74 #include "ast_typedef.h"
75 #include "ast_visitor.h"
77 #include "utl_string.h"
79 #include "utl_indenter.h"
80 #include "utl_identifier.h"
82 #include "ace/Truncate.h"
84 AST_Structure::AST_Structure (UTL_ScopedName
*n
,
89 AST_Decl (AST_Decl::NT_struct
,
91 AST_Type (AST_Decl::NT_struct
,
93 AST_ConcreteType (AST_Decl::NT_struct
,
95 UTL_Scope (AST_Decl::NT_struct
),
102 AST_Structure::AST_Structure (AST_Decl::NodeType nt
,
106 : COMMON_Base (local
,
112 AST_ConcreteType (nt
,
121 AST_Structure::~AST_Structure (void)
126 // Are we or the parameter node involved in any recursion?
128 AST_Structure::in_recursion (ACE_Unbounded_Queue
<AST_Type
*> &list
)
130 bool self_test
= (list
.size () == 0);
132 // We should calculate this only once. If it has already been
133 // done, just return it.
134 if (self_test
&& this->in_recursion_
!= -1)
136 return (this->in_recursion_
== 1);
139 if (list
.size () > 1)
141 if (match_names (this, list
))
143 // We've found ourselves outside of a sequence.
144 // This happens when we are not recursed ourselves but instead
145 // are part of another recursed type which is part of us.
146 // f.i. union containing sequence of struct containing the union as member.
151 list
.enqueue_tail(this);
153 // Proceed if the number of members in our scope is greater than 0.
154 if (this->nmembers () > 0)
156 // Initialize an iterator to iterate over our scope.
157 // Continue until each element is visited.
158 for (UTL_ScopeActiveIterator
si (this, UTL_Scope::IK_decls
);
162 AST_Field
*field
= dynamic_cast<AST_Field
*> (si
.item ());
165 // This will be an enum value or other legitimate non-field
166 // member - in any case, no recursion.
171 AST_Type
*type
= field
->field_type ();
173 if (type
->node_type () == AST_Decl::NT_typedef
)
175 AST_Typedef
*td
= dynamic_cast<AST_Typedef
*> (type
);
176 type
= td
->primitive_base_type ();
181 ACE_ERROR_RETURN ((LM_ERROR
,
182 ACE_TEXT ("(%N:%l) AST_Structure::")
183 ACE_TEXT ("in_recursion - ")
184 ACE_TEXT ("bad field type\n")),
188 if (type
->in_recursion (list
))
191 this->in_recursion_
= 1;
192 idl_global
->recursive_type_seen_
= true;
200 this->in_recursion_
= 0;
205 AST_Structure::member_count (void)
207 if (this->member_count_
== -1)
209 this->compute_member_count ();
212 return this->member_count_
;
216 AST_Structure::nfields (void) const
218 return ACE_Utils::truncate_cast
<ACE_CDR::ULong
> (this->fields_
.size ());
222 AST_Structure::field (AST_Field
**&result
,
223 ACE_CDR::ULong slot
) const
225 return this->fields_
.get (result
, slot
);
229 AST_Structure::is_local (void)
231 if (this->local_struct_
== -1)
235 this->local_struct_
= this->is_local_
;
239 this->local_struct_
= 0;
241 if (this->nmembers () > 0)
243 // Instantiate a scope iterator.
244 for (UTL_ScopeActiveIterator
si (this, UTL_Scope::IK_decls
);
248 if (si
.item ()->is_local ())
250 this->local_struct_
= true;
258 return this->local_struct_
;
262 AST_Structure::contains_wstring (void)
264 if (this->contains_wstring_
== -1)
266 for (UTL_ScopeActiveIterator
si (this, UTL_Scope::IK_decls
);
270 if (si
.item ()->contains_wstring () == 1)
272 this->contains_wstring_
= 1;
273 return this->contains_wstring_
;
277 this->contains_wstring_
= 0;
280 return this->contains_wstring_
;
284 AST_Structure::is_defined (void)
286 return 0 == this->fwd_decl_
|| this->fwd_decl_
->is_defined ();
290 AST_Structure::legal_for_primary_key (void) const
294 if (!this->recursing_in_legal_pk_
)
296 this->recursing_in_legal_pk_
= true;
298 for (UTL_ScopeActiveIterator
si (const_cast<AST_Structure
*> (this),
299 UTL_Scope::IK_decls
);
303 AST_Field
*f
= dynamic_cast<AST_Field
*> (si
.item ());
305 if (f
!= 0 && !f
->field_type ()->legal_for_primary_key ())
312 this->recursing_in_legal_pk_
= false;
319 AST_Structure::fwd_decl (void) const
321 return this->fwd_decl_
;
325 AST_Structure::fwd_decl (AST_StructureFwd
*node
)
327 this->fwd_decl_
= node
;
330 ACE_Unbounded_Queue
<AST_Field
*> &
331 AST_Structure::fields (void)
333 return this->fields_
;
336 // Private operations.
339 AST_Structure::fe_add_field (AST_Field
*t
)
341 return this->fe_add_ref_decl (t
);
345 AST_Structure::fe_add_structure (AST_Structure
*t
)
347 return this->fe_add_full_struct_type (t
);
351 AST_Structure::fe_add_union (AST_Union
*t
)
353 return dynamic_cast<AST_Union
*> (this->fe_add_full_struct_type (t
));
357 AST_Structure::fe_add_enum (AST_Enum
*t
)
359 return dynamic_cast<AST_Enum
*> (this->fe_add_decl (t
));
362 // Add this AST_EnumVal node (an enumerator declaration) to this scope.
363 // This is done to conform to the C++ scoping rules which declare
364 // enumerators in the enclosing scope (in addition to declaring them
365 // in the enum itself).
367 AST_Structure::fe_add_enum_val (AST_EnumVal
*t
)
369 return dynamic_cast<AST_EnumVal
*> (this->fe_add_decl (t
));
372 // Compute total number of members.
374 AST_Structure::compute_member_count (void)
376 this->member_count_
= 0;
378 // If there are elements in this scope.
379 if (this->nmembers () > 0)
381 // Instantiate a scope iterator.
382 for (UTL_ScopeActiveIterator
si (this, UTL_Scope::IK_decls
);
386 ++this->member_count_
;
393 // Dump this AST_Structure node to the ostream o.
395 AST_Structure::dump (ACE_OSTREAM_TYPE
&o
)
397 if (this->is_local ())
399 this->dump_i (o
, "(local) ");
402 this->dump_i (o
, "struct ");
404 this->dump_i (o
, " {\n");
406 idl_global
->indent ()->skip_to (o
);
407 this->dump_i (o
, "}");
410 // This serves for structs and unions.
412 AST_Structure::fwd_redefinition_helper (AST_Structure
*&i
,
420 // Fwd redefinition should be in the same scope, so local
421 // lookup is all that's needed.
423 s
->lookup_by_name_local (i
->local_name (), false);
425 AST_Structure
*fd
= 0;
429 // Full definition must have the same prefix as the forward declaration.
430 if (ACE_OS::strcmp (i
->prefix (), d
->prefix ()) != 0)
432 idl_global
->err ()->error1 (UTL_Error::EIDL_PREFIX_CONFLICT
,
438 AST_Decl::NodeType nt
= d
->node_type ();
440 // If this interface has been forward declared in a previous opening
441 // of the module it's defined in, the lookup will find the
442 // forward declaration.
443 if (nt
== AST_Decl::NT_struct_fwd
444 || nt
== AST_Decl::NT_union_fwd
)
446 AST_StructureFwd
*fwd_def
=
447 dynamic_cast<AST_StructureFwd
*> (d
);
449 fd
= fwd_def
->full_definition ();
451 // In all other cases, the lookup will find an interface node.
452 else if (nt
== AST_Decl::NT_struct
453 || nt
== AST_Decl::NT_union
)
455 fd
= dynamic_cast<AST_Structure
*> (d
);
461 // Should we give an error here?
462 // No, look in fe_add_interface.
464 // If it is a forward declared interface..
465 else if (!fd
->is_defined ())
467 // Check if redefining in same scope. If a module is reopened,
468 // a new pointer in created, and the first term below will be
469 // true. In that case, the scoped names must be compared.
470 if (fd
->defined_in () != s
471 && i
->name ()->compare (fd
->name ()) != 0)
473 idl_global
->err ()->error2 (UTL_Error::EIDL_SCOPE_CONFLICT
,
477 // All OK, do the redefinition.
480 AST_Decl::NodeType fd_nt
= fd
->node_type ();
481 AST_Decl::NodeType i_nt
= i
->node_type ();
483 // Only redefinition of the same kind.
486 idl_global
->err ()->error2 (UTL_Error::EIDL_REDEF
,
493 AST_StructureFwd
*fwd
= fd
->fwd_decl ();
497 // So the fwd decl won't destroy us at cleanup time.
498 // Unlike interfaces, valuetypes and components, it's
499 // ok to do this here, since fwd declared structs
500 // and unions must be defined in the same translation
502 fwd
->set_as_defined ();
505 // Use full definition node.
514 // This serves only for structs. It is overridden for unions.
516 AST_Structure::redefine (AST_Structure
*from
)
518 // We've already checked for inconsistent prefixes.
519 this->prefix (from
->prefix ());
521 this->set_defined_in (from
->defined_in ());
522 this->set_imported (idl_global
->imported ());
523 this->set_in_main_file (idl_global
->in_main_file ());
524 this->set_line (idl_global
->lineno ());
525 this->set_file_name (idl_global
->filename ()->get_string ());
526 this->ifr_added_
= from
->ifr_added_
;
527 this->ifr_fwd_added_
= from
->ifr_fwd_added_
;
528 this->fields_
= from
->fields_
;
529 this->member_count_
= from
->member_count_
;
530 this->local_struct_
= from
->local_struct_
;
533 // Compute the size type of the node in question.
535 AST_Structure::compute_size_type (void)
537 for (UTL_ScopeActiveIterator
si (this, UTL_Scope::IK_decls
);
541 // Get the next AST decl node.
542 AST_Decl
*d
= si
.item ();
544 if (d
->node_type () == AST_Decl::NT_enum_val
)
549 AST_Field
*f
= dynamic_cast<AST_Field
*> (d
);
550 AST_Type
*t
= f
->field_type ();
554 this->size_type (t
->size_type ());
556 // While we're iterating, we might as well do this one too.
557 this->has_constructor (t
->has_constructor ());
561 ACE_DEBUG ((LM_DEBUG
,
562 "WARNING (%N:%l) be_structure::compute_size_type - "
563 "dynamic_cast returned 0\n"));
571 AST_Structure::ast_accept (ast_visitor
*visitor
)
573 return visitor
->visit_structure (this);
577 AST_Structure::destroy (void)
579 this->AST_ConcreteType::destroy ();
580 this->UTL_Scope::destroy ();
583 IMPL_NARROW_FROM_DECL(AST_Structure
)
584 IMPL_NARROW_FROM_SCOPE(AST_Structure
)
586 bool AST_Structure::annotatable () const
592 AST_Structure::operator[] (const size_t index
)
594 size_t count
= member_count_
<= 0 ? 0 : member_count_
;
600 for (UTL_ScopeActiveIterator
si (this, UTL_Scope::IK_decls
);
614 AST_Structure::operator[] (const char* name
)
616 for (UTL_ScopeActiveIterator
si (this, UTL_Scope::IK_decls
);
620 AST_Decl
*field
= si
.item ();
621 const char *field_name
= field
->local_name ()->get_string ();
622 if (!ACE_OS::strcmp (name
, field_name
)) {