tree parse_signature_string (const unsigned char *sig_string, int sig_length) { tree result_type; const unsigned char *str = sig_string; const unsigned char *limit = str + sig_length; if (str < limit && str[0] == '(') { tree argtype_list = NULL_TREE; str++; while (str < limit && str[0] != ')') { tree argtype = parse_signature_type (&str, limit); argtype_list = tree_cons (NULL_TREE, argtype, argtype_list); } if (str++, str >= limit) abort (); result_type = parse_signature_type (&str, limit); argtype_list = chainon (nreverse (argtype_list), end_params_node); result_type = build_function_type (result_type, argtype_list); } else result_type = parse_signature_type (&str, limit); if (str != limit) error ("junk at end of signature string"); return result_type; }
static tree parse_signature_type (const unsigned char **ptr, const unsigned char *limit) { tree type; if (*ptr >= limit) abort (); switch (**ptr) { case 'B': (*ptr)++; return byte_type_node; case 'C': (*ptr)++; return char_type_node; case 'D': (*ptr)++; return double_type_node; case 'F': (*ptr)++; return float_type_node; case 'S': (*ptr)++; return short_type_node; case 'I': (*ptr)++; return int_type_node; case 'J': (*ptr)++; return long_type_node; case 'Z': (*ptr)++; return boolean_type_node; case 'V': (*ptr)++; return void_type_node; case '[': for ((*ptr)++; (*ptr) < limit && ISDIGIT (**ptr); ) (*ptr)++; type = parse_signature_type (ptr, limit); type = build_java_array_type (type, -1); break; case 'L': { const unsigned char *start = ++(*ptr); const unsigned char *str = start; for ( ; ; str++) { if (str >= limit) abort (); if (*str == ';') break; } *ptr = str+1; type = lookup_class (unmangle_classname ((const char *) start, str - start)); break; } default: abort (); } return promote_type (type); }