td->prefix.flags |= XPT_TDP_REFERENCE;
td->prefix.flags |= XPT_TDP_POINTER | XPT_TDP_REFERENCE; else if (IDL_tree_property_get(type,"ptr")) td->prefix.flags |= XPT_TDP_POINTER;
fill_td_from_type(TreeState *state, XPTTypeDescriptor *td, IDL_tree type){    IDL_tree up;    int16 size_is_argnum;    int16 length_is_argnum;    gboolean has_size_is;    gboolean has_length_is;    gboolean is_array = FALSE;    if (type) {        /* deal with array */        if (IDL_NODE_TYPE(state->tree) == IDLN_PARAM_DCL) {            IDL_tree sd = IDL_PARAM_DCL(state->tree).simple_declarator;            if (IDL_tree_property_get(sd, "array")) {                is_array = TRUE;                /* size_is is required! */                if (!get_size_and_length(state, type,                                          &size_is_argnum, &length_is_argnum,                                         &has_size_is, &has_length_is)) {                    /* error was reported by helper function */                    return FALSE;                }                if (!has_size_is) {                   IDL_tree_error(state->tree, "[array] requires [size_is()]\n");                    return FALSE;                }                td->prefix.flags = TD_ARRAY | XPT_TDP_POINTER;                td->argnum = size_is_argnum;                if (has_length_is)                    td->argnum2 = length_is_argnum;                else                    td->argnum2 = size_is_argnum;                /*                 * XXX - NOTE - this will be broken for multidimensional                 * arrays because of the realloc XPT_InterfaceDescriptorAddTypes                * uses. The underlying 'td' can change as we recurse in to get                * additional dimensions. Luckily, we don't yet support more                * than on dimension in the arrays                */                /* setup the additional_type */                                if (!XPT_InterfaceDescriptorAddTypes(ARENA(state),                                                      CURRENT(state), 1)) {                    g_error("out of memory\n");                    return FALSE;                }                td->type.additional_type = NEXT_TYPE(state);                td = &CURRENT(state)->additional_types[NEXT_TYPE(state)];                NEXT_TYPE(state)++ ;            }        }handle_typedef:        switch (IDL_NODE_TYPE(type)) {          case IDLN_TYPE_INTEGER: {              gboolean sign = IDL_TYPE_INTEGER(type).f_signed;              switch(IDL_TYPE_INTEGER(type).f_type) {                case IDL_INTEGER_TYPE_SHORT:                  td->prefix.flags = sign ? TD_INT16 : TD_UINT16;                  break;                case IDL_INTEGER_TYPE_LONG:                  td->prefix.flags = sign ? TD_INT32 : TD_UINT32;                  break;                case IDL_INTEGER_TYPE_LONGLONG:                  td->prefix.flags = sign ? TD_INT64 : TD_UINT64;                  break;              }              break;          }          case IDLN_TYPE_CHAR:            td->prefix.flags = TD_CHAR;            break;          case IDLN_TYPE_WIDE_CHAR:            td->prefix.flags = TD_WCHAR;            break;          case IDLN_TYPE_STRING:            if (is_array) {                td->prefix.flags = TD_PSTRING | XPT_TDP_POINTER;            } else {                if (!get_size_and_length(state, type,                                          &size_is_argnum, &length_is_argnum,                                         &has_size_is, &has_length_is)) {                    /* error was reported by helper function */                    return FALSE;                }                if (has_size_is) {                    td->prefix.flags = TD_PSTRING_SIZE_IS | XPT_TDP_POINTER;                    td->argnum = size_is_argnum;                    if (has_length_is)                        td->argnum2 = length_is_argnum;                    else                        td->argnum2 = size_is_argnum;                } else {                    td->prefix.flags = TD_PSTRING | XPT_TDP_POINTER;                }            }            break;          case IDLN_TYPE_WIDE_STRING:            if (is_array) {                td->prefix.flags = TD_PWSTRING | XPT_TDP_POINTER;            } else {                if (!get_size_and_length(state, type,                                          &size_is_argnum, &length_is_argnum,                                         &has_size_is, &has_length_is)) {                    /* error was reported by helper function */                    return FALSE;                }                if (has_size_is) {                    td->prefix.flags = TD_PWSTRING_SIZE_IS | XPT_TDP_POINTER;                    td->argnum = size_is_argnum;                    if (has_length_is)                        td->argnum2 = length_is_argnum;                    else                        td->argnum2 = size_is_argnum;                } else {                    td->prefix.flags = TD_PWSTRING | XPT_TDP_POINTER;                }            }            break;          case IDLN_TYPE_BOOLEAN:            td->prefix.flags = TD_BOOL;            break;          case IDLN_TYPE_OCTET:            td->prefix.flags = TD_UINT8;            break;          case IDLN_TYPE_FLOAT:            switch (IDL_TYPE_FLOAT (type).f_type) {              case IDL_FLOAT_TYPE_FLOAT:                td->prefix.flags = TD_FLOAT;                break;              case IDL_FLOAT_TYPE_DOUBLE:                td->prefix.flags = TD_DOUBLE;                break;              /* XXX 'long double' just ignored, or what? */              default: break;            }            break;          case IDLN_IDENT:            if (!(up = IDL_NODE_UP(type))) {                IDL_tree_error(state->tree,                               "ERROR: orphan ident %s in param list\n",                               IDL_IDENT(type).str);                return FALSE;            }            switch (IDL_NODE_TYPE(up)) {                /* This whole section is abominably ugly */              case IDLN_FORWARD_DCL:              case IDLN_INTERFACE: {                XPTInterfaceDirectoryEntry *ide, *ides;                uint16 num_ifaces;                char *className;                const char *iid_is;handle_iid_is:                ides = HEADER(state)->interface_directory;                num_ifaces = HEADER(state)->num_interfaces;                /* might get here via the goto, so re-check type */                if (IDL_NODE_TYPE(up) == IDLN_INTERFACE)                    className = IDL_IDENT(IDL_INTERFACE(up).ident).str;                else if (IDL_NODE_TYPE(up) == IDLN_FORWARD_DCL)                    className = IDL_IDENT(IDL_FORWARD_DCL(up).ident).str;                else                    className = IDL_IDENT(IDL_NATIVE(up).ident).str;                iid_is = NULL;                if (IDL_NODE_TYPE(state->tree) == IDLN_PARAM_DCL) {                    iid_is =                        IDL_tree_property_get(IDL_PARAM_DCL(state->tree).simple_declarator,                                              "iid_is");                }                if (iid_is) {                    int16 argnum;                    if (!find_arg_with_name(state, iid_is, &argnum)) {                        IDL_tree_error(state->tree,                                       "can't find matching argument for "                                       "[iid_is(%s)]\n", iid_is);                        return FALSE;                    }                    td->prefix.flags = TD_INTERFACE_IS_TYPE | XPT_TDP_POINTER;                    td->argnum = argnum;                } else {                    td->prefix.flags = TD_INTERFACE_TYPE | XPT_TDP_POINTER;                    ide = FindInterfaceByName(ides, num_ifaces, className);                    if (!ide || ide < ides || ide > ides + num_ifaces) {                        IDL_tree_error(state->tree,                                       "unknown iface %s in param\n",                                       className);                        return FALSE;                    }                    td->type.iface = ide - ides + 1;#ifdef DEBUG_shaver_index                    fprintf(stderr, "DBG: index %d for %s\n",                            td->type.iface, className);#endif                }                break;              }              case IDLN_NATIVE: {                  char *ident;                  /* jband - adding goto for iid_is when type is native */                  if (IDL_NODE_TYPE(state->tree) == IDLN_PARAM_DCL &&                      IDL_tree_property_get(IDL_PARAM_DCL(state->tree).simple_declarator,                                              "iid_is"))                      goto handle_iid_is;                  ident = IDL_IDENT(type).str;                  if (IDL_tree_property_get(type, "nsid")) {                      td->prefix.flags = TD_PNSIID | XPT_TDP_POINTER;                      if (IDL_tree_property_get(type, "ref"))                          td->prefix.flags |= XPT_TDP_REFERENCE;                  } else if (IDL_tree_property_get(type, "domstring")) {                      td->prefix.flags = TD_DOMSTRING | XPT_TDP_POINTER;                      if (IDL_tree_property_get(type, "ref"))                          td->prefix.flags |= XPT_TDP_REFERENCE;                  } else {                      td->prefix.flags = TD_VOID | XPT_TDP_POINTER;                  }                  break;                }              default:                if (IDL_NODE_TYPE(IDL_NODE_UP(up)) == IDLN_TYPE_DCL) {                    /* restart with the underlying type */                    IDL_tree new_type;                    new_type = IDL_TYPE_DCL(IDL_NODE_UP(up)).type_spec;#ifdef DEBUG_shaver_misc                    fprintf(stderr, "following %s typedef to %s\n",                            IDL_IDENT(type).str, IDL_NODE_TYPE_NAME(new_type));#endif                    /*                     *  Do a nice messy goto rather than recursion so that                    *  we can avoid screwing up the *array* information.                    *//*                    return fill_td_from_type(state, td, new_type); */                    if (new_type) {                        type = new_type;                        goto handle_typedef;                    } else {                        /* do what we would do in recursion if !type */                        td->prefix.flags = TD_VOID;                        return TRUE;                    }                }                IDL_tree_error(state->tree,                               "can't handle %s ident in param list\n",#ifdef DEBUG_shaver                               /* XXX is this safe to use on Win now? */                               IDL_NODE_TYPE_NAME(IDL_NODE_UP(type))#else                               "that type of"#endif                               );#ifdef DEBUG_shaver                XPT_ASSERT(0);#endif                return FALSE;            }            break;          default:            IDL_tree_error(state->tree, "can't handle %s in param list\n",#ifdef DEBUG_shaver                           /* XXX is this safe to use on Win now? */                           IDL_NODE_TYPE_NAME(IDL_NODE_UP(type))#else                        "that type"#endif            );            return FALSE;        }    } else {        td->prefix.flags = TD_VOID;    }    return TRUE;}