~ubuntu-branches/ubuntu/breezy/ace/breezy

« back to all changes in this revision

Viewing changes to TAO/TAO_IDL/ast/ast_union.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad, Benjamin Montgomery, Adam Conrad
  • Date: 2005-09-18 22:51:38 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 sarge) (0.1.2 woody)
  • Revision ID: james.westby@ubuntu.com-20050918225138-seav22q6fyylb536
Tags: 5.4.7-3ubuntu1
[ Benjamin Montgomery ]
* Added a patch for amd64 and powerpc that disables the compiler
  option -fvisibility-inlines-hidden

[ Adam Conrad ]
* Added DPATCH_OPTION_CPP=1 to debian/patches/00options to make
  Benjamin's above changes work correctly with dpatch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// ast_union.cpp,v 1.31 2003/11/10 20:29:25 dhinton Exp
2
 
 
3
 
/*
4
 
 
5
 
COPYRIGHT
6
 
 
7
 
Copyright 1992, 1993, 1994 Sun Microsystems, Inc.  Printed in the United
8
 
States of America.  All Rights Reserved.
9
 
 
10
 
This product is protected by copyright and distributed under the following
11
 
license restricting its use.
12
 
 
13
 
The Interface Definition Language Compiler Front End (CFE) is made
14
 
available for your use provided that you include this license and copyright
15
 
notice on all media and documentation and the software program in which
16
 
this product is incorporated in whole or part. You may copy and extend
17
 
functionality (but may not remove functionality) of the Interface
18
 
Definition Language CFE without charge, but you are not authorized to
19
 
license or distribute it to anyone else except as part of a product or
20
 
program developed by you or with the express written consent of Sun
21
 
Microsystems, Inc. ("Sun").
22
 
 
23
 
The names of Sun Microsystems, Inc. and any of its subsidiaries or
24
 
affiliates may not be used in advertising or publicity pertaining to
25
 
distribution of Interface Definition Language CFE as permitted herein.
26
 
 
27
 
This license is effective until terminated by Sun for failure to comply
28
 
with this license.  Upon termination, you shall destroy or return all code
29
 
and documentation for the Interface Definition Language CFE.
30
 
 
31
 
INTERFACE DEFINITION LANGUAGE CFE IS PROVIDED AS IS WITH NO WARRANTIES OF
32
 
ANY KIND INCLUDING THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS
33
 
FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR ARISING FROM A COURSE OF
34
 
DEALING, USAGE OR TRADE PRACTICE.
35
 
 
36
 
INTERFACE DEFINITION LANGUAGE CFE IS PROVIDED WITH NO SUPPORT AND WITHOUT
37
 
ANY OBLIGATION ON THE PART OF Sun OR ANY OF ITS SUBSIDIARIES OR AFFILIATES
38
 
TO ASSIST IN ITS USE, CORRECTION, MODIFICATION OR ENHANCEMENT.
39
 
 
40
 
SUN OR ANY OF ITS SUBSIDIARIES OR AFFILIATES SHALL HAVE NO LIABILITY WITH
41
 
RESPECT TO THE INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY
42
 
INTERFACE DEFINITION LANGUAGE CFE OR ANY PART THEREOF.
43
 
 
44
 
IN NO EVENT WILL SUN OR ANY OF ITS SUBSIDIARIES OR AFFILIATES BE LIABLE FOR
45
 
ANY LOST REVENUE OR PROFITS OR OTHER SPECIAL, INDIRECT AND CONSEQUENTIAL
46
 
DAMAGES, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
47
 
 
48
 
Use, duplication, or disclosure by the government is subject to
49
 
restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
50
 
Technical Data and Computer Software clause at DFARS 252.227-7013 and FAR
51
 
52.227-19.
52
 
 
53
 
Sun, Sun Microsystems and the Sun logo are trademarks or registered
54
 
trademarks of Sun Microsystems, Inc.
55
 
 
56
 
SunSoft, Inc.
57
 
2550 Garcia Avenue
58
 
Mountain View, California  94043
59
 
 
60
 
NOTE:
61
 
 
62
 
SunOS, SunSoft, Sun, Solaris, Sun Microsystems or the Sun logo are
63
 
trademarks or registered trademarks of Sun Microsystems, Inc.
64
 
 
65
 
*/
66
 
 
67
 
// AST_Union nodes represent IDL union declarations.
68
 
// AST_Union is a subclass of AST_ConcreteType and of UTL_Scope (the
69
 
// union branches are managed in a scope).
70
 
// AST_Union nodes have a discriminator type (a subclass of AST_ConcreteType),
71
 
// a name (an UTL_ScopedName) and a field denoting the discriminator type if
72
 
// it is a primitive type (the value of this field is from the union
73
 
// AST_Expression::ExprType and serves as a cache). This field is used
74
 
// to compute coercions for labels based on the expected discriminator type.
75
 
 
76
 
#include "ast_union.h"
77
 
#include "ast_union_branch.h"
78
 
#include "ast_union_label.h"
79
 
#include "ast_field.h"
80
 
#include "ast_predefined_type.h"
81
 
#include "ast_enum.h"
82
 
#include "ast_enum_val.h"
83
 
#include "ast_visitor.h"
84
 
#include "utl_err.h"
85
 
#include "utl_identifier.h"
86
 
#include "utl_indenter.h"
87
 
#include "global_extern.h"
88
 
 
89
 
// FUZZ: disable check_for_streams_include
90
 
#include "ace/streams.h"
91
 
 
92
 
ACE_RCSID (ast, 
93
 
           ast_union, 
94
 
           "ast_union.cpp,v 1.31 2003/11/10 20:29:25 dhinton Exp")
95
 
 
96
 
AST_Union::AST_Union (void)
97
 
  : COMMON_Base (),
98
 
    AST_Decl (),
99
 
    AST_Type (),
100
 
    AST_ConcreteType (),
101
 
    UTL_Scope (),
102
 
    AST_Structure (),
103
 
    default_index_ (-2)
104
 
{
105
 
}
106
 
 
107
 
AST_Union::AST_Union (AST_ConcreteType *dt,
108
 
                      UTL_ScopedName *n,
109
 
                      idl_bool local,
110
 
                      idl_bool abstract)
111
 
  : COMMON_Base (local,
112
 
                 abstract),
113
 
    AST_Decl (AST_Decl::NT_union,
114
 
              n),
115
 
    AST_Type (AST_Decl::NT_union,
116
 
              n),
117
 
    AST_ConcreteType (AST_Decl::NT_union,
118
 
                      n),
119
 
    UTL_Scope (AST_Decl::NT_union),
120
 
    AST_Structure (n,
121
 
                   local,
122
 
                   abstract),
123
 
    default_index_ (-2)
124
 
{
125
 
  this->default_value_.computed_ = -2;
126
 
 
127
 
  AST_PredefinedType *pdt = 0;
128
 
 
129
 
  if (dt == 0)
130
 
    {
131
 
      this->pd_disc_type = 0;
132
 
      this->pd_udisc_type = AST_Expression::EV_none;
133
 
      return;
134
 
    }
135
 
 
136
 
  // If the discriminator type is a predefined type
137
 
  // then install the equivalent coercion target type in
138
 
  // the pd_udisc_type field.
139
 
  if (dt->node_type () == AST_Decl::NT_pre_defined)
140
 
    {
141
 
      pdt = AST_PredefinedType::narrow_from_decl (dt);
142
 
 
143
 
      if (pdt == 0)
144
 
        {
145
 
          this->pd_disc_type = 0;
146
 
          this->pd_udisc_type = AST_Expression::EV_none;
147
 
          return;
148
 
        }
149
 
 
150
 
      pd_disc_type = dt;
151
 
 
152
 
      switch (pdt->pt ())
153
 
        {
154
 
        case AST_PredefinedType::PT_long:
155
 
          this->pd_udisc_type = AST_Expression::EV_long;
156
 
          break;
157
 
        case AST_PredefinedType::PT_ulong:
158
 
          this->pd_udisc_type = AST_Expression::EV_ulong;
159
 
          break;
160
 
        case AST_PredefinedType::PT_short:
161
 
          this->pd_udisc_type = AST_Expression::EV_short;
162
 
          break;
163
 
        case AST_PredefinedType::PT_ushort:
164
 
          this->pd_udisc_type = AST_Expression::EV_ushort;
165
 
          break;
166
 
        case AST_PredefinedType::PT_char:
167
 
          this->pd_udisc_type = AST_Expression::EV_char;
168
 
          break;
169
 
        case AST_PredefinedType::PT_wchar:
170
 
          this->pd_udisc_type = AST_Expression::EV_wchar;
171
 
          break;
172
 
        case AST_PredefinedType::PT_octet:
173
 
          this->pd_udisc_type = AST_Expression::EV_octet;
174
 
          break;
175
 
        case AST_PredefinedType::PT_boolean:
176
 
          this->pd_udisc_type = AST_Expression::EV_bool;
177
 
          break;
178
 
        default:
179
 
          this->pd_udisc_type = AST_Expression::EV_none;
180
 
          this->pd_disc_type = 0;
181
 
          break;
182
 
        }
183
 
    }
184
 
  else if (dt->node_type () == AST_Decl::NT_enum)
185
 
    {
186
 
      this->pd_udisc_type = AST_Expression::EV_enum;
187
 
      this->pd_disc_type = dt;
188
 
    }
189
 
  else
190
 
    {
191
 
      this->pd_udisc_type = AST_Expression::EV_none;
192
 
      this->pd_disc_type = 0;
193
 
    }
194
 
 
195
 
  if (this->pd_disc_type == 0)
196
 
    {
197
 
      idl_global->err ()->error2 (UTL_Error::EIDL_DISC_TYPE,
198
 
                                  this,
199
 
                                  dt);
200
 
    }
201
 
}
202
 
 
203
 
AST_Union::~AST_Union (void)
204
 
{
205
 
}
206
 
 
207
 
// Public operations.
208
 
 
209
 
void
210
 
AST_Union::redefine (AST_Structure *from)
211
 
{
212
 
  AST_Union *u = AST_Union::narrow_from_decl (from);
213
 
 
214
 
  if (u == 0)
215
 
    {
216
 
      idl_global->err ()->redef_error (from->local_name ()->get_string (),
217
 
                                       this->local_name ()->get_string ());
218
 
      return;
219
 
    }
220
 
 
221
 
  // Copy over all the base class members.
222
 
  this->AST_Structure::redefine (from);
223
 
 
224
 
  this->pd_disc_type = u->pd_disc_type;
225
 
  this->pd_udisc_type = u->pd_udisc_type;
226
 
  this->default_index_ = u->default_index_;
227
 
  this->default_value_ = u->default_value_;
228
 
}
229
 
 
230
 
// Return the default_index.
231
 
int
232
 
AST_Union::default_index (void)
233
 
{
234
 
  if (this->default_index_ == -2)
235
 
    {
236
 
      this->compute_default_index ();
237
 
    }
238
 
 
239
 
  return this->default_index_;
240
 
}
241
 
 
242
 
// Are we or the parameter node involved in any recursion?
243
 
idl_bool
244
 
AST_Union::in_recursion (AST_Type *node)
245
 
{
246
 
  if (node == 0)
247
 
    {
248
 
      // We are determining the recursive status for ourselves.
249
 
      node = this;
250
 
    }
251
 
 
252
 
  // Proceed if the number of members in our scope is greater than 0.
253
 
  if (this->nmembers () > 0)
254
 
    {
255
 
      // Initialize an iterator to iterate thru our scope.
256
 
      // Continue until each element is visited.
257
 
      for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls);
258
 
           !si.is_done ();
259
 
           si.next ())
260
 
        {
261
 
          AST_UnionBranch *field = 
262
 
            AST_UnionBranch::narrow_from_decl (si.item ());
263
 
 
264
 
          if (field == 0)
265
 
            // This will be an enum value or other legitimate non-field
266
 
            // member - in any case, no recursion.
267
 
            {
268
 
              continue;
269
 
            }
270
 
 
271
 
          AST_Type *type = field->field_type ();
272
 
 
273
 
          if (type->node_type () == AST_Decl::NT_typedef)
274
 
            {
275
 
              AST_Typedef *td = AST_Typedef::narrow_from_decl (type);
276
 
              type = td->primitive_base_type ();
277
 
            }
278
 
 
279
 
          if (type == 0)
280
 
            {
281
 
              ACE_ERROR_RETURN ((LM_ERROR,
282
 
                                 ACE_TEXT ("(%N:%l) AST_Union::")
283
 
                                 ACE_TEXT ("in_recursion - ")
284
 
                                 ACE_TEXT ("bad field type\n")),
285
 
                                0);
286
 
            }
287
 
 
288
 
          if (type->in_recursion (node))
289
 
            {
290
 
              return 1;
291
 
            }
292
 
        }
293
 
    }
294
 
 
295
 
  // Not in recursion.
296
 
  return 0;
297
 
}
298
 
 
299
 
// Look up the default branch in union.
300
 
AST_UnionBranch *
301
 
AST_Union::lookup_default (void)
302
 
{
303
 
  AST_UnionBranch *b = 0;
304
 
  AST_Decl *d = 0;
305
 
 
306
 
  for (UTL_ScopeActiveIterator i (this, UTL_Scope::IK_both);
307
 
       !i.is_done();
308
 
       i.next ())
309
 
    {
310
 
      d = i.item ();
311
 
 
312
 
      if (d->node_type () == AST_Decl::NT_union_branch)
313
 
        {
314
 
          b = AST_UnionBranch::narrow_from_decl (d);
315
 
 
316
 
          if (b == 0)
317
 
            {
318
 
              continue;
319
 
            }
320
 
 
321
 
          if (b->label () != 0
322
 
              && b->label ()->label_kind () == AST_UnionLabel::UL_default)
323
 
            {
324
 
              idl_global->err ()->error2 (UTL_Error::EIDL_MULTIPLE_BRANCH,
325
 
                                          this,
326
 
                                          b);
327
 
              return b;
328
 
            }
329
 
        }
330
 
    }
331
 
 
332
 
  return 0;
333
 
}
334
 
 
335
 
// Look up a branch by label.
336
 
AST_UnionBranch *
337
 
AST_Union::lookup_label (AST_UnionBranch *b)
338
 
{
339
 
  AST_UnionLabel *label = b->label ();
340
 
  AST_Expression *lv = label->label_val ();
341
 
 
342
 
  if (label->label_val () == 0)
343
 
    {
344
 
      return b;
345
 
    }
346
 
 
347
 
  AST_Decl *d = 0;
348
 
  AST_UnionBranch       *fb = 0;
349
 
 
350
 
  lv->set_ev (lv->coerce (this->pd_udisc_type));
351
 
 
352
 
  if (lv->ev () == 0)
353
 
    {
354
 
      idl_global->err ()->eval_error (lv);
355
 
      return b;
356
 
    }
357
 
 
358
 
  for (UTL_ScopeActiveIterator i (this, UTL_Scope::IK_decls);
359
 
       !i.is_done();
360
 
       i.next ())
361
 
    {
362
 
      d = i.item ();
363
 
 
364
 
      if (d->node_type () == AST_Decl::NT_union_branch)
365
 
        {
366
 
          fb = AST_UnionBranch::narrow_from_decl (d);
367
 
 
368
 
          if (fb == 0)
369
 
            {
370
 
              continue;
371
 
            }
372
 
 
373
 
          if (fb->label() != 0
374
 
              && fb->label ()->label_kind () == AST_UnionLabel::UL_label
375
 
              && fb->label ()->label_val ()->compare (lv))
376
 
            {
377
 
              idl_global->err ()->error2  (UTL_Error::EIDL_MULTIPLE_BRANCH,
378
 
                                           this,
379
 
                                           b);
380
 
              return b;
381
 
            }
382
 
        }
383
 
    }
384
 
 
385
 
  return 0;
386
 
}
387
 
 
388
 
// Look up a branch in an enum which is the discriminator type for this
389
 
// union, based on the label value which must be an enumerator in that
390
 
// enum.
391
 
AST_UnionBranch *
392
 
AST_Union::lookup_enum (AST_UnionBranch *b)
393
 
{
394
 
  AST_UnionLabel *label = b->label();
395
 
  AST_Expression *lv = label->label_val ();
396
 
  AST_Enum *e = AST_Enum::narrow_from_decl (this->pd_disc_type);
397
 
  AST_Decl *d = 0;
398
 
  AST_UnionBranch       *fb = 0;
399
 
 
400
 
  if (e == 0)
401
 
    {
402
 
      return 0;
403
 
    }
404
 
 
405
 
  if (lv == 0)
406
 
    {
407
 
      return b;
408
 
    }
409
 
 
410
 
  // Expecting a symbol label.
411
 
  if (lv->ec () != AST_Expression::EC_symbol)
412
 
    {
413
 
      idl_global->err ()->enum_val_expected (this,
414
 
                                             label);
415
 
      return b;
416
 
    }
417
 
 
418
 
  // See if the symbol defines a constant in the discriminator enum.
419
 
  UTL_ScopedName *sn = lv->n ();
420
 
  d = e->lookup_by_name (sn,
421
 
                         I_TRUE);
422
 
 
423
 
  if (d == 0 || d->defined_in () != e)
424
 
    {
425
 
      idl_global->err ()->enum_val_lookup_failure (this,
426
 
                                                   e,
427
 
                                                   sn);
428
 
      return b;
429
 
    }
430
 
 
431
 
  // OK, now see if this symbol is already used as the label of
432
 
  // some other branch.
433
 
  for (UTL_ScopeActiveIterator i (this, UTL_Scope::IK_decls);
434
 
       !i.is_done();
435
 
       i.next ())
436
 
    {
437
 
      d = i.item ();
438
 
 
439
 
      if (d->node_type () == AST_Decl::NT_union_branch)
440
 
        {
441
 
          fb = AST_UnionBranch::narrow_from_decl (d);
442
 
 
443
 
          if (fb == 0)
444
 
            {
445
 
              continue;
446
 
            }
447
 
 
448
 
          if (fb->label() != 0
449
 
              && fb->label ()->label_kind () == AST_UnionLabel::UL_label
450
 
              && fb->label ()->label_val ()->compare (lv))
451
 
            {
452
 
              idl_global->err ()->error2 (UTL_Error::EIDL_MULTIPLE_BRANCH,
453
 
                                          this,
454
 
                                          b);
455
 
              return b;
456
 
            }
457
 
        }
458
 
    }
459
 
 
460
 
  return 0;
461
 
}
462
 
 
463
 
// Look up a branch by value. This is the top level branch label resolution
464
 
// entry point. It dispatches to the right lookup function depending on the
465
 
// union discriminator type.
466
 
AST_UnionBranch *
467
 
AST_Union::lookup_branch (AST_UnionBranch *branch)
468
 
{
469
 
  AST_UnionLabel *label = 0;
470
 
 
471
 
  if (branch != 0)
472
 
    {
473
 
      label = branch->label ();
474
 
    }
475
 
 
476
 
  if (label != 0)
477
 
    {
478
 
      if (label->label_kind () == AST_UnionLabel::UL_default)
479
 
        {
480
 
          return this->lookup_default ();
481
 
        }
482
 
 
483
 
      if (this->pd_udisc_type == AST_Expression::EV_enum)
484
 
        {
485
 
          // CONVENTION: indicates enum discriminant.
486
 
          return this->lookup_enum (branch);
487
 
        }
488
 
 
489
 
      return this->lookup_label (branch);
490
 
    }
491
 
 
492
 
  return 0;
493
 
}
494
 
 
495
 
// Return the default value.
496
 
int
497
 
AST_Union::default_value (AST_Union::DefaultValue &dv)
498
 
{
499
 
  if (this->default_value_.computed_ == -2)
500
 
    {
501
 
      // We need to compute it.
502
 
      if (this->compute_default_value () == -1)
503
 
        {
504
 
          ACE_ERROR_RETURN ((LM_ERROR,
505
 
                             ACE_TEXT ("(%N:%l) AST_Union::")
506
 
                             ACE_TEXT ("default_value - ")
507
 
                             ACE_TEXT ("Error computing ")
508
 
                             ACE_TEXT ("default value\n")),
509
 
                            -1);
510
 
        }
511
 
    }
512
 
 
513
 
  dv = this->default_value_;
514
 
  return 0;
515
 
}
516
 
 
517
 
// Determine the default value (if any).
518
 
int
519
 
AST_Union::compute_default_value (void)
520
 
{
521
 
  // Check if we really need a default value. This will be true if there is an
522
 
  // explicit default case OR if an implicit default exists because not all
523
 
  // values of the discriminant type are covered by the cases.
524
 
 
525
 
  // Compute the total true "case" labels i.e., exclude the "default" case.
526
 
  int total_case_members = 0;
527
 
 
528
 
  // Instantiate a scope iterator.
529
 
  for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls);
530
 
       !si.is_done ();
531
 
       si.next ())
532
 
    {
533
 
      // Get the next AST decl node.
534
 
      AST_UnionBranch *ub =
535
 
        AST_UnionBranch::narrow_from_decl (si.item ());
536
 
 
537
 
      if (ub != 0)
538
 
        {
539
 
          // If the label is a case label, increment by 1.
540
 
          for (unsigned long i = 0; i < ub->label_list_length (); ++i)
541
 
            {
542
 
              if (ub->label (i)->label_kind () == AST_UnionLabel::UL_label)
543
 
                {
544
 
                  ++total_case_members;
545
 
                }
546
 
            }
547
 
        }
548
 
    }
549
 
 
550
 
  // Check if the total_case_members cover the entire
551
 
  // range of values that are permitted by the discriminant type. If they do,
552
 
  // then a default value is not necessary. However, if such an explicit
553
 
  // default case is provided, it must be flagged off as an error. Our
554
 
  // front-end is not able to handle such a case since it is a semantic error
555
 
  // and not a syntax error. Such an error is caught here.
556
 
 
557
 
  switch (this->udisc_type ())
558
 
    {
559
 
    case AST_Expression::EV_short:
560
 
    case AST_Expression::EV_ushort:
561
 
      if (total_case_members == ACE_UINT16_MAX + 1)
562
 
        {
563
 
          this->default_value_.computed_ = 0;
564
 
        }
565
 
 
566
 
      break;
567
 
    case AST_Expression::EV_long:
568
 
    case AST_Expression::EV_ulong:
569
 
      if ((unsigned int) total_case_members > ACE_UINT32_MAX)
570
 
        {
571
 
          this->default_value_.computed_ = 0;
572
 
        }
573
 
 
574
 
      break;
575
 
    case AST_Expression::EV_longlong:
576
 
    case AST_Expression::EV_ulonglong:
577
 
      // Error for now.
578
 
      this->default_value_.computed_ = -1;
579
 
      ACE_ERROR_RETURN ((
580
 
          LM_ERROR,
581
 
          ACE_TEXT ("(%N:%l) AST_Union::compute_default_value ")
582
 
          ACE_TEXT ("- unimplemented discriminant type ")
583
 
          ACE_TEXT ("(longlong or ulonglong)\n")
584
 
        ),
585
 
        -1
586
 
      );
587
 
      ACE_NOTREACHED (break;)
588
 
    case AST_Expression::EV_char:
589
 
      if (total_case_members == ACE_OCTET_MAX + 1)
590
 
        {
591
 
          this->default_value_.computed_ = 0;
592
 
        }
593
 
 
594
 
      break;
595
 
    case AST_Expression::EV_wchar:
596
 
      if (total_case_members == ACE_WCHAR_MAX + 1)
597
 
        {
598
 
          this->default_value_.computed_ = 0;
599
 
        }
600
 
 
601
 
      break;
602
 
    case AST_Expression::EV_bool:
603
 
      if (total_case_members == 2)
604
 
        {
605
 
          this->default_value_.computed_ = 0;
606
 
        }
607
 
 
608
 
      break;
609
 
    case AST_Expression::EV_enum:
610
 
      // Has to be enum.
611
 
      {
612
 
        AST_Decl *d = AST_Decl::narrow_from_decl (this->disc_type ());
613
 
 
614
 
        if (d->node_type () == AST_Decl::NT_typedef)
615
 
          {
616
 
            AST_Typedef *bt = AST_Typedef::narrow_from_decl (d);
617
 
            d = bt->primitive_base_type ();
618
 
          }
619
 
 
620
 
        AST_Enum *en = AST_Enum::narrow_from_decl (d);
621
 
 
622
 
        if (en != 0)
623
 
          {
624
 
            if (total_case_members == en->member_count ())
625
 
              {
626
 
                this->default_value_.computed_ = 0;
627
 
              }
628
 
          }
629
 
        else
630
 
          {
631
 
            // Error.
632
 
            this->default_value_.computed_ = -1;
633
 
            ACE_ERROR_RETURN ((LM_ERROR,
634
 
                               ACE_TEXT ("(%N:%l) AST_Union::")
635
 
                               ACE_TEXT ("compute_default_value ")
636
 
                               ACE_TEXT ("- disc type not an ENUM\n")),
637
 
                              -1);
638
 
          }
639
 
      }
640
 
      break;
641
 
    default:
642
 
      // Error.
643
 
      this->default_value_.computed_ = -1;
644
 
      ACE_ERROR_RETURN ((LM_ERROR,
645
 
                         ACE_TEXT ("(%N:%l) AST_Union::compute_default_value")
646
 
                         ACE_TEXT (" - Bad discriminant type\n")),
647
 
                        -1);
648
 
      ACE_NOTREACHED (break;)
649
 
    } // End of switch
650
 
 
651
 
  // If we have determined that we don't need a default case and even then a
652
 
  // default case was provided, flag this off as error.
653
 
  if ((this->default_value_.computed_ == 0)
654
 
      && (this->default_index () != -1))
655
 
    {
656
 
      // Error.
657
 
      this->default_value_.computed_ = -1;
658
 
      ACE_ERROR_RETURN ((LM_ERROR,
659
 
                         ACE_TEXT ("(%N:%l) AST_Union::compute_default_value")
660
 
                         ACE_TEXT (" - default clause is invalid here\n")),
661
 
                        -1);
662
 
    }
663
 
 
664
 
  // Proceed only if necessary.
665
 
  switch (this->default_value_.computed_)
666
 
    {
667
 
    case -1:
668
 
      // Error. We should never be here because errors
669
 
      // have already been caught
670
 
      // above.
671
 
      return -1;
672
 
    case 0:
673
 
      // Nothing more to do.
674
 
      return 0;
675
 
    default:
676
 
      // Proceed further down.
677
 
      break;
678
 
    }
679
 
 
680
 
  // Initialization of the default value data member.
681
 
  switch (this->udisc_type ())
682
 
    {
683
 
    case AST_Expression::EV_short:
684
 
      this->default_value_.u.short_val = ACE_INT16_MIN;
685
 
      break;
686
 
    case AST_Expression::EV_ushort:
687
 
      this->default_value_.u.ushort_val = 0;
688
 
      break;
689
 
    case AST_Expression::EV_long:
690
 
      // The +1 is to avert a warning on many compilers.
691
 
      this->default_value_.u.long_val = ACE_INT32_MIN + 1;
692
 
      break;
693
 
    case AST_Expression::EV_ulong:
694
 
      this->default_value_.u.ulong_val = 0;
695
 
      break;
696
 
    case AST_Expression::EV_char:
697
 
      this->default_value_.u.char_val = 0;
698
 
      break;
699
 
    case AST_Expression::EV_wchar:
700
 
      this->default_value_.u.wchar_val = 0;
701
 
      break;
702
 
    case AST_Expression::EV_bool:
703
 
      this->default_value_.u.bool_val = 0;
704
 
      break;
705
 
    case AST_Expression::EV_enum:
706
 
      this->default_value_.u.enum_val = 0;
707
 
      break;
708
 
    case AST_Expression::EV_longlong:
709
 
    case AST_Expression::EV_ulonglong:
710
 
      // Unimplemented.
711
 
    default:
712
 
      // Error caught earlier.
713
 
      break;
714
 
    }
715
 
 
716
 
  // Proceed until we have found the appropriate default value.
717
 
  while (this->default_value_.computed_ == -2)
718
 
    {
719
 
      int break_loop = 0;
720
 
 
721
 
      // Instantiate a scope iterator.
722
 
      for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls);
723
 
           !si.is_done () && break_loop == 0;
724
 
           si.next ())
725
 
        {
726
 
          // Get the next AST decl node
727
 
          AST_UnionBranch *ub =
728
 
            AST_UnionBranch::narrow_from_decl (si.item ());
729
 
 
730
 
          if (ub != 0)
731
 
            {
732
 
              for (unsigned long i = 0;
733
 
                   i < ub->label_list_length () && !break_loop;
734
 
                   ++i)
735
 
                {
736
 
                  if (ub->label (i)->label_kind () == AST_UnionLabel::UL_label)
737
 
                    {
738
 
                      // Not a default.
739
 
                      AST_Expression *expr = ub->label (i)->label_val ();
740
 
 
741
 
                      if (expr == 0)
742
 
                        {
743
 
                          // Error.
744
 
                          this->default_value_.computed_ = -1;
745
 
                          ACE_ERROR_RETURN ((
746
 
                              LM_ERROR,
747
 
                              ACE_TEXT ("(%N:%l) AST_Union::")
748
 
                              ACE_TEXT ("compute_default_value - ")
749
 
                              ACE_TEXT ("Bad case label value\n")
750
 
                            ),
751
 
                            -1
752
 
                          );
753
 
                        }
754
 
 
755
 
                      switch (expr->ev ()->et)
756
 
                        {
757
 
                          // Check if they match in which case this
758
 
                          // cannot be the implicit default value. So
759
 
                          // start with a new value and try the whole loop
760
 
                          // again because our case labels may not be sorted.
761
 
                        case AST_Expression::EV_short:
762
 
                          if (this->default_value_.u.short_val
763
 
                                == expr->ev ()->u.sval)
764
 
                            {
765
 
                              this->default_value_.u.short_val++;
766
 
                              break_loop = 1;
767
 
                            }
768
 
 
769
 
                          break;
770
 
                        case AST_Expression::EV_ushort:
771
 
                          if (this->default_value_.u.ushort_val
772
 
                                == expr->ev ()->u.usval)
773
 
                            {
774
 
                              this->default_value_.u.ushort_val++;
775
 
                              break_loop = 1;
776
 
                            }
777
 
 
778
 
                          break;
779
 
                        case AST_Expression::EV_long:
780
 
                          if (this->default_value_.u.long_val
781
 
                                == expr->ev ()->u.lval)
782
 
                            {
783
 
                              this->default_value_.u.long_val++;
784
 
                              break_loop = 1;
785
 
                            }
786
 
 
787
 
                          break;
788
 
                        case AST_Expression::EV_ulong:
789
 
                          if (this->default_value_.u.ulong_val
790
 
                                == expr->ev ()->u.ulval)
791
 
                            {
792
 
                              this->default_value_.u.ulong_val++;
793
 
                              break_loop = 1;
794
 
                            }
795
 
 
796
 
                          break;
797
 
                        case AST_Expression::EV_char:
798
 
                          if (this->default_value_.u.char_val
799
 
                                == expr->ev ()->u.cval)
800
 
                            {
801
 
                              this->default_value_.u.char_val++;
802
 
                              break_loop = 1;
803
 
                            }
804
 
 
805
 
                          break;
806
 
                        case AST_Expression::EV_wchar:
807
 
                          if (this->default_value_.u.wchar_val
808
 
                                == expr->ev ()->u.wcval)
809
 
                            {
810
 
                              this->default_value_.u.wchar_val++;
811
 
                              break_loop = 1;
812
 
                            }
813
 
 
814
 
                          break;
815
 
                        case AST_Expression::EV_bool:
816
 
                          if (this->default_value_.u.bool_val
817
 
                                == expr->ev ()->u.bval)
818
 
                            {
819
 
                              this->default_value_.u.bool_val++;
820
 
                              break_loop = 1;
821
 
                            }
822
 
 
823
 
                          break;
824
 
                        case AST_Expression::EV_enum:
825
 
                          // this is the case of enums. We maintain
826
 
                          // evaluated values which always start with 0
827
 
                          if (this->default_value_.u.enum_val
828
 
                                == expr->ev ()->u.eval)
829
 
                            {
830
 
                              this->default_value_.u.enum_val++;
831
 
                              break_loop = 1;
832
 
                            }
833
 
 
834
 
                          break;
835
 
                        case AST_Expression::EV_longlong:
836
 
                        case AST_Expression::EV_ulonglong:
837
 
                          // Unimplemented. right now - flag as error.
838
 
                        default:
839
 
                          // Error.
840
 
                          break;
841
 
                        } // End of switch.
842
 
                    } // if label_Kind == label
843
 
                } // End of for loop going thru all labels.
844
 
            } // If valid union branch.
845
 
        } // End of while scope iterator loop.
846
 
 
847
 
      // We have not aborted the inner loops which means we have found the
848
 
      // default value.
849
 
      if (break_loop == 0)
850
 
        {
851
 
          this->default_value_.computed_ = 1;
852
 
        }
853
 
 
854
 
    } // End of outer while (default_value.computed == -2).
855
 
 
856
 
  return 0;
857
 
}
858
 
 
859
 
// Private  operations.
860
 
 
861
 
// Compute the default index.
862
 
int
863
 
AST_Union::compute_default_index (void)
864
 
{
865
 
  AST_Decl *d = 0;
866
 
  AST_UnionBranch *ub = 0;
867
 
  int i = 0;
868
 
 
869
 
  // If default case does not exist, it will have a value of -1 according to
870
 
  // the spec.
871
 
  this->default_index_ = -1;
872
 
 
873
 
  // If there are elements in this scope...
874
 
  if (this->nmembers () > 0)
875
 
    {
876
 
      // Instantiate a scope iterator.
877
 
      for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls);
878
 
           !si.is_done ();
879
 
           si.next ())
880
 
        {
881
 
          // Get the next AST decl node.
882
 
          d = si.item ();
883
 
 
884
 
          // If an enum is declared in our scope, its members are
885
 
          // added to our scope as well, to detect clashes.
886
 
          if (d->node_type () == AST_Decl::NT_enum_val)
887
 
            {
888
 
              continue;
889
 
            }
890
 
 
891
 
          if (!d->imported ())
892
 
            {
893
 
              ub = AST_UnionBranch::narrow_from_decl (d);
894
 
 
895
 
              for (unsigned long j = 0; j < ub->label_list_length (); ++j)
896
 
                {
897
 
                  // Check if we are printing the default case.
898
 
                  AST_UnionLabel::UnionLabel ulk = ub->label ()->label_kind ();
899
 
                  if (ulk == AST_UnionLabel::UL_default)
900
 
                    {
901
 
                      // Zero based indexing.
902
 
                      this->default_index_ = i;
903
 
                    }
904
 
                }
905
 
 
906
 
              // TAO's Typecode class keeps only a member count (not
907
 
              // a label count) so this increment has been moved
908
 
              // out of the inner loop.
909
 
              ++i;
910
 
            }
911
 
        }
912
 
    }
913
 
 
914
 
  return 0;
915
 
}
916
 
 
917
 
// Redefinition of inherited virtual operations
918
 
 
919
 
// Add this AST_UnionBranch node (a node representing one branch in a
920
 
// union declaration) to this scope
921
 
AST_UnionBranch *
922
 
AST_Union::fe_add_union_branch (AST_UnionBranch *t)
923
 
{
924
 
  AST_Decl *d = 0;
925
 
 
926
 
  // If this is a malformed branch, don't do anything with it.
927
 
  if (t == 0 || t->label() == 0)
928
 
    {
929
 
      return 0;
930
 
    }
931
 
 
932
 
  // If branch with that label already exists, complain.
933
 
  if (lookup_branch (t) != 0)
934
 
    {
935
 
      idl_global->err ()->error2 (UTL_Error::EIDL_MULTIPLE_BRANCH,
936
 
                                  this,
937
 
                                  t);
938
 
      return 0;
939
 
    }
940
 
 
941
 
  // If branch with same field name exists, complain.
942
 
  if ((d = this->lookup_for_add (t, I_FALSE)) != 0)
943
 
    {
944
 
      if (!can_be_redefined (d))
945
 
        {
946
 
          idl_global->err ()->error3 (UTL_Error::EIDL_REDEF,
947
 
                                      t,
948
 
                                      this,
949
 
                                      d);
950
 
          return 0;
951
 
        }
952
 
 
953
 
      if (this->referenced (d, t->local_name ()))
954
 
        {
955
 
          idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE,
956
 
                                      t,
957
 
                                      this,
958
 
                                      d);
959
 
          return 0;
960
 
        }
961
 
 
962
 
      if (t->has_ancestor (d))
963
 
        {
964
 
          idl_global->err ()->redefinition_in_scope (t,
965
 
                                                     d);
966
 
          return 0;
967
 
        }
968
 
    }
969
 
 
970
 
  // Add it to scope.
971
 
  this->add_to_scope (t);
972
 
 
973
 
  // Add it to set of locally referenced symbols.
974
 
  this->add_to_referenced (t,
975
 
                           I_FALSE,
976
 
                           t->local_name ());
977
 
 
978
 
  AST_Type *ft = t->field_type ();
979
 
  UTL_ScopedName *mru = ft->last_referenced_as ();
980
 
 
981
 
  if (mru != 0)
982
 
    {
983
 
      this->add_to_referenced (ft,
984
 
                               I_FALSE,
985
 
                               mru->first_component ());
986
 
    }
987
 
 
988
 
  this->fields_.enqueue_tail (t);
989
 
 
990
 
  return t;
991
 
}
992
 
 
993
 
// Add this AST_Union (manifest union type) to this scope.
994
 
AST_Union *
995
 
AST_Union::fe_add_union (AST_Union *t)
996
 
{
997
 
  AST_Decl *d = 0;
998
 
 
999
 
  // Already defined and cannot be redefined? Or already used?
1000
 
  if ((d = this->lookup_for_add (t, I_FALSE)) != 0)
1001
 
    {
1002
 
      if (!can_be_redefined (d))
1003
 
        {
1004
 
          idl_global->err ()->error3 (UTL_Error::EIDL_REDEF,
1005
 
                                      t,
1006
 
                                      this,
1007
 
                                      d);
1008
 
          return 0;
1009
 
        }
1010
 
 
1011
 
      if (this->referenced (d, t->local_name ()))
1012
 
        {
1013
 
          idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE,
1014
 
                                      t,
1015
 
                                      this,
1016
 
                                      d);
1017
 
          return 0;
1018
 
        }
1019
 
 
1020
 
      if (t->has_ancestor (d))
1021
 
        {
1022
 
          idl_global->err ()->redefinition_in_scope (t,
1023
 
                                                     d);
1024
 
          return 0;
1025
 
        }
1026
 
    }
1027
 
 
1028
 
  // Add it to local types.
1029
 
  this->add_to_local_types (t);
1030
 
 
1031
 
  // Add it to set of locally referenced symbols.
1032
 
  this->add_to_referenced (t,
1033
 
                           I_FALSE,
1034
 
                           t->local_name ());
1035
 
 
1036
 
  return t;
1037
 
}
1038
 
 
1039
 
// Add this AST_Structure node (manifest struct type) to this scope.
1040
 
AST_Structure *
1041
 
AST_Union::fe_add_structure (AST_Structure *t)
1042
 
{
1043
 
  AST_Decl *d = 0;
1044
 
 
1045
 
  // Already defined and cannot be redefined? Or already used?
1046
 
  if ((d = this->lookup_for_add (t, I_FALSE)) != 0)
1047
 
    {
1048
 
      if (!can_be_redefined (d))
1049
 
        {
1050
 
          idl_global->err ()->error3 (UTL_Error::EIDL_REDEF,
1051
 
                                      t,
1052
 
                                      this,
1053
 
                                      d);
1054
 
          return 0;
1055
 
        }
1056
 
 
1057
 
      if (this->referenced (d, t->local_name ()))
1058
 
        {
1059
 
          idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE,
1060
 
                                      t,
1061
 
                                      this,
1062
 
                                      d);
1063
 
          return 0;
1064
 
        }
1065
 
 
1066
 
      if (t->has_ancestor (d))
1067
 
        {
1068
 
          idl_global->err ()->redefinition_in_scope (t,
1069
 
                                                     d);
1070
 
          return 0;
1071
 
        }
1072
 
    }
1073
 
 
1074
 
  // Add it to local types.
1075
 
  this->add_to_local_types (t);
1076
 
 
1077
 
  // Add it to set of locally referenced symbols.
1078
 
  this->add_to_referenced (t,
1079
 
                           I_FALSE,
1080
 
                           t->local_name ());
1081
 
 
1082
 
  return t;
1083
 
}
1084
 
 
1085
 
// Add this AST_Enum node (manifest enum type) to this scope.
1086
 
AST_Enum *
1087
 
AST_Union::fe_add_enum (AST_Enum *t)
1088
 
{
1089
 
  AST_Decl *d = 0;
1090
 
 
1091
 
  // Already defined and cannot be redefined? Or already used?
1092
 
  if ((d = this->lookup_for_add (t, I_FALSE)) != 0)
1093
 
    {
1094
 
      if (!can_be_redefined (d))
1095
 
        {
1096
 
          idl_global->err ()->error3 (UTL_Error::EIDL_REDEF,
1097
 
                                      t,
1098
 
                                      this,
1099
 
                                      d);
1100
 
          return 0;
1101
 
        }
1102
 
 
1103
 
      if (this->referenced (d, t->local_name ()))
1104
 
        {
1105
 
          idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE,
1106
 
                                      t,
1107
 
                                      this,
1108
 
                                      d);
1109
 
          return 0;
1110
 
        }
1111
 
 
1112
 
      if (t->has_ancestor (d))
1113
 
        {
1114
 
          idl_global->err ()->redefinition_in_scope (t,
1115
 
                                                     d);
1116
 
          return 0;
1117
 
        }
1118
 
    }
1119
 
 
1120
 
  // Add it to local types.
1121
 
  this->add_to_local_types (t);
1122
 
 
1123
 
  // Add it to set of locally referenced symbols.
1124
 
  this->add_to_referenced (t,
1125
 
                           I_FALSE,
1126
 
                           t->local_name ());
1127
 
 
1128
 
  return t;
1129
 
}
1130
 
 
1131
 
// Add this AST_EnumVal node (enumerator declaration) to this scope.
1132
 
// This is done to conform to the C++ scoping rules which declare
1133
 
// enumerators in the enclosing scope (in addition to declaring them
1134
 
// in the enum itself).
1135
 
AST_EnumVal *
1136
 
AST_Union::fe_add_enum_val (AST_EnumVal *t)
1137
 
{
1138
 
  AST_Decl *d = 0;
1139
 
 
1140
 
  // Already defined and cannot be redefined? Or already used?
1141
 
  if ((d = this->lookup_for_add (t, I_FALSE)) != 0)
1142
 
    {
1143
 
      if (!can_be_redefined (d))
1144
 
        {
1145
 
          idl_global->err ()->error3 (UTL_Error::EIDL_REDEF,
1146
 
                                      t,
1147
 
                                      this,
1148
 
                                      d);
1149
 
          return 0;
1150
 
        }
1151
 
 
1152
 
      if (this->referenced (d, t->local_name ()))
1153
 
        {
1154
 
          idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE,
1155
 
                                      t,
1156
 
                                      this,
1157
 
                                      d);
1158
 
          return 0;
1159
 
        }
1160
 
 
1161
 
      if (t->has_ancestor (d))
1162
 
        {
1163
 
          idl_global->err ()->redefinition_in_scope (t,
1164
 
                                                     d);
1165
 
          return 0;
1166
 
        }
1167
 
    }
1168
 
 
1169
 
  // Add it to scope.
1170
 
  this->add_to_scope (t);
1171
 
 
1172
 
  // Add it to set of locally referenced symbols.
1173
 
  this->add_to_referenced (t,
1174
 
                           I_FALSE,
1175
 
                           t->local_name ());
1176
 
 
1177
 
  return t;
1178
 
}
1179
 
 
1180
 
// Dump this AST_Union node to the ostream o.
1181
 
void
1182
 
AST_Union::dump (ACE_OSTREAM_TYPE &o)
1183
 
{
1184
 
  o << "union ";
1185
 
  this->local_name ()->dump (o);
1186
 
  o << " switch (";
1187
 
  this->pd_disc_type->local_name ()->dump (o);
1188
 
  o << ") {\n";
1189
 
  UTL_Scope::dump (o);
1190
 
  idl_global->indent ()->skip_to (o);
1191
 
  o << "}";
1192
 
}
1193
 
 
1194
 
// Compute the size type of the node in question.
1195
 
int
1196
 
AST_Union::compute_size_type (void)
1197
 
{
1198
 
  for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls);
1199
 
       !si.is_done ();
1200
 
       si.next ())
1201
 
    {
1202
 
      // Get the next AST decl node.
1203
 
      AST_Decl *d = si.item ();
1204
 
 
1205
 
      if (d->node_type () == AST_Decl::NT_enum_val)
1206
 
        {
1207
 
          continue;
1208
 
        }
1209
 
 
1210
 
      AST_Field *f = AST_Field::narrow_from_decl (d);
1211
 
 
1212
 
      if (f != 0)
1213
 
        {
1214
 
          AST_Type *t = f->field_type ();
1215
 
          // Our sizetype depends on the sizetype of our members. Although
1216
 
          // previous value of sizetype may get overwritten, we are
1217
 
          // guaranteed by the "size_type" call that once the value reached
1218
 
          // be_decl::VARIABLE, nothing else can overwrite it.
1219
 
          this->size_type (t->size_type ());
1220
 
        }
1221
 
      else
1222
 
        {
1223
 
          ACE_DEBUG ((LM_DEBUG,
1224
 
                      "WARNING (%N:%l) be_union::compute_size_type - "
1225
 
                      "narrow_from_decl returned 0\n"));
1226
 
        }
1227
 
    }
1228
 
 
1229
 
  return 0;
1230
 
}
1231
 
 
1232
 
int
1233
 
AST_Union::ast_accept (ast_visitor *visitor)
1234
 
{
1235
 
  return visitor->visit_union (this);
1236
 
}
1237
 
 
1238
 
// Data accessors.
1239
 
 
1240
 
AST_ConcreteType *
1241
 
AST_Union::disc_type (void)
1242
 
{
1243
 
  return this->pd_disc_type;
1244
 
}
1245
 
 
1246
 
AST_Expression::ExprType
1247
 
AST_Union::udisc_type (void)
1248
 
{
1249
 
  return this->pd_udisc_type;
1250
 
}
1251
 
 
1252
 
// Narrowing.
1253
 
IMPL_NARROW_METHODS1(AST_Union, AST_Structure)
1254
 
IMPL_NARROW_FROM_DECL(AST_Union)
1255
 
IMPL_NARROW_FROM_SCOPE(AST_Union)