+/* Produce an unsigned hash value from STRING0 that is consistent
+ with strcmp_iw, strcmp, and, at least on Ada symbols, wild_match.
+ That is, two identifiers equivalent according to any of those three
+ comparison operators hash to the same value. */
+
+static unsigned int
+dict_hash (const char *string0)
+{
+ /* The Ada-encoded version of a name P1.P2...Pn has either the form
+ P1__P2__...Pn<suffix> or _ada_P1__P2__...Pn<suffix> (where the Pi
+ are lower-cased identifiers). The <suffix> (which can be empty)
+ encodes additional information about the denoted entity. This
+ routine hashes such names to msymbol_hash_iw(Pn). It actually
+ does this for a superset of both valid Pi and of <suffix>, but
+ in other cases it simply returns msymbol_hash_iw(STRING0). */
+
+ const char *string;
+ unsigned int hash;
+
+ string = string0;
+ if (*string == '_')
+ {
+ if (strncmp (string, "_ada_", 5) == 0)
+ string += 5;
+ else
+ return msymbol_hash_iw (string0);
+ }
+
+ hash = 0;
+ while (*string)
+ {
+ switch (*string)
+ {
+ case '$':
+ case '.':
+ case 'X':
+ if (string0 == string)
+ return msymbol_hash_iw (string0);
+ else
+ return hash;
+ case ' ':
+ case '(':
+ return msymbol_hash_iw (string0);
+ case '_':
+ if (string[1] == '_' && string != string0)
+ {
+ int c = string[2];
+
+ if ((c < 'a' || c > 'z') && c != 'O')
+ return hash;
+ hash = 0;
+ string += 2;
+ break;
+ }
+ /* FALL THROUGH */
+ default:
+ hash = SYMBOL_HASH_NEXT (hash, *string);
+ string += 1;
+ break;
+ }
+ }
+ return hash;
+}
+