diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index fd7f555ee4e..597e840e0dc 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,9 @@ +2000-09-06 Alex Samuel + + * cp-demangle.c (status_allocation_failed): Rearrange whitespace. + (demangle_type): Handle substitution candidates correctly in the + face of special substitutions. + 2000-09-05 Alex Samuel * cp-demangle.c (demangle_encoding): Rename variable. diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index 48325e66d9f..5b16c4e3507 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -170,7 +170,7 @@ typedef const char *status_t; #define STATUS_INTERNAL_ERROR "Internal error." /* This status code indicates a failure in malloc or realloc. */ -static const char* const status_allocation_failed = "Allocation failed."; +static const char *const status_allocation_failed = "Allocation failed."; #define STATUS_ALLOCATION_FAILED status_allocation_failed /* Non-zero if STATUS indicates that no error has occurred. */ @@ -2284,10 +2284,31 @@ demangle_type (dm) is_substitution_candidate = 0; } else - /* While the special substitution token itself is not a - substitution candidate, the is, so - don't clear is_substitution_candidate. */ - RETURN_IF_ERROR (demangle_class_enum_type (dm, &encode_return_type)); + { + /* Now some trickiness. We have a special substitution + here. Often, the special substitution provides the + name of a template that's subsequently instantiated, + for instance `SaIcE' => std::allocator. In these + cases we need to add a substitution candidate for the + entire and thus don't want to clear + the is_substitution_candidate flag. + + However, it's possible that what we have here is a + substitution token representing an entire type, such as + `Ss' => std::string. In this case, we mustn't add a + new substitution candidate for this substitution token. + To detect this case, remember where the start of the + substitution token is. */ + const char *next = dm->next; + /* Now demangle the . */ + RETURN_IF_ERROR + (demangle_class_enum_type (dm, &encode_return_type)); + /* If all that was just demangled is the two-character + special substitution token, supress the addition of a + new candidate for it. */ + if (dm->next == next + 2) + is_substitution_candidate = 0; + } break;