+ c_type = self.c_type
+
+ # special case: switch
+ # in case of switch, 2 params have to be supplied to certain accessor functions:
+ # 1. the anchestor object (request or reply)
+ # 2. the (anchestor) switch object
+ # the reason is that switch is either a child of a request/reply or nested in another switch,
+ # so whenever we need to access a length field, we might need to refer to some anchestor type
+ switch_obj = self if self.is_switch else None
+ if self.is_bitcase:
+ switch_obj = self.parents[-1]
+ if switch_obj is not None:
+ c_type = switch_obj.c_type
+
+ params = []
+ fields = {}
+ parents = self.parents if hasattr(self, 'parents') else [self]
+ # 'R': parents[0] is always the 'toplevel' container type
+ params.append(('const %s *R' % parents[0].c_type, parents[0]))
+ fields.update(_c_helper_field_mapping(parents[0], [('R', '->', parents[0])], flat=True))
+ # auxiliary object for 'R' parameters
+ R_obj = parents[0]
+
+ if switch_obj is not None:
+ # now look where the fields are defined that are needed to evaluate
+ # the switch expr, and store the parent objects in accessor_params and
+ # the fields in switch_fields
+
+ # 'S': name for the 'toplevel' switch
+ toplevel_switch = parents[1]
+ params.append(('const %s *S' % toplevel_switch.c_type, toplevel_switch))
+ fields.update(_c_helper_field_mapping(toplevel_switch, [('S', '->', toplevel_switch)], flat=True))
+
+ # initialize prefix for everything "below" S
+ prefix_str = '/* %s */ S' % toplevel_switch.name[-1]
+ prefix = [(prefix_str, '->', toplevel_switch)]
+
+ # look for fields in the remaining containers
+ for p in parents[2:] + [self]:
+ # the separator between parent and child is always '.' here,
+ # because of nested switch statements
+ if not p.is_bitcase or (p.is_bitcase and p.has_name):
+ prefix.append((p.name[-1], '.', p))
+ fields.update(_c_helper_field_mapping(p, prefix, flat=True))
+
+ # auxiliary object for 'S' parameter
+ S_obj = parents[1]