summaryrefslogtreecommitdiff
path: root/TAO/TAO_IDL/be/be_state_structure.cpp
blob: 2226d3b131f742feb1d18ce03a5e000e5dadf16d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// ============================================================================
//
// = LIBRARY
//    TAO IDL
//
// = FILENAME
//    be_state_struct.cpp
//
// = DESCRIPTION
//    state based code generation for structs.
//
// = AUTHOR
//    Aniruddha Gokhale
//
// ============================================================================

#include	"idl.h"
#include	"idl_extern.h"
#include	"be.h"

be_state_struct_ch::be_state_struct_ch (void)
{
}

// generate code for structure member
int
be_state_struct_ch::gen_code (be_type *bt, be_decl *d, be_type *type)
{
  TAO_OutStream *os; // output stream
  TAO_NL  nl;        // end line
  TAO_CodeGen *cg = TAO_CODEGEN::instance ();
  be_field *f;       // field node
  be_structure *bs;  // enclosing structure node

  // Macro to avoid "warning: unused parameter" type warning.
  ACE_UNUSED_ARG (nl);

  os = cg->client_header (); // get client header stream
  f = be_field::narrow_from_decl (d); // downcast to field node
  if (!f)
    return -1;

  bs = be_structure::narrow_from_scope (f->defined_in ());
  if (bs == NULL)
    return -1;

  // pass the field node just incase it is needed
  cg->node (f);

  if (!type) // not a recursive call
    type = bt;
  else // recursively called thru a typedef. "type" will have the most primitive
       // base class of the typedef
    ACE_ASSERT (bt->node_type () == AST_Decl::NT_typedef);

  // generate code based on type. For every case, first downcast to the
  // appropriate type. If the downcast fails, return error, else proceed. In
  // some cases, the type itself may need code generation, e.g., anonymous
  // struct types.
  switch (type->node_type ())
    {
    case AST_Decl::NT_interface: // type is an obj reference
      {
        os->indent (); // start from current indentation
        *os << bt->nested_type_name (bs, "_var") << " " << f->local_name () <<
          ";\n\n";
      }
      break;
    case AST_Decl::NT_pre_defined: // type is predefined type
      {
        os->indent (); // start from current indentation
        *os << bt->nested_type_name (bs) << " " << f->local_name () << ";\n\n";
      }
      break;
    case AST_Decl::NT_string: // type is a string
      {
        os->indent (); // start from current indentation
        if (bt->node_type () == AST_Decl::NT_typedef)
          {
            *os << bt->nested_type_name (bs, "_var") << " " << f->local_name () << ";\n\n";
          }
        else
          {
            *os << "CORBA::String_var " << f->local_name () << ";\n\n";
          }
      }
      break;
      // these are all anonymous types
    case AST_Decl::NT_array: // type is an array
    case AST_Decl::NT_sequence: // type is a sequence
    case AST_Decl::NT_enum: // type is an enum
    case AST_Decl::NT_struct: // type is a struct
    case AST_Decl::NT_union: // type is a union
      {
        // We first need to generate code for this aggregate type. Check if we
        // are not called recursively thru a typedef
        if (bt->node_type () != AST_Decl::NT_typedef)
          if (bt->gen_client_header () == -1)
            return -1;

        os->indent ();
        *os << bt->nested_type_name (bs) << " " << f->local_name () << ";\n\n";
      }
      break;
    case AST_Decl::NT_except: // type is an exception
      {
        // XXXASG TODO: is this allowed ???
      }
      break;
    case AST_Decl::NT_typedef: // type is a typedef
      {
        be_type *temp;
        be_typedef *t = be_typedef::narrow_from_decl (bt);

        if (!t)
          return -1;

        temp = t->primitive_base_type ();
        // make a recursive call
        return this->gen_code (t, f, temp);
      } // end of switch
      //break;  unreachable statement!
    }
  // the enclosing structure will be variable length the field is variable
  // length
  bs->size_type (type->size_type ());
  return 0;
}