From 230d863ab1b48376ad1ca18b2fced7552dd9d98d Mon Sep 17 00:00:00 2001 From: DJ Delorie Date: Thu, 4 Apr 2013 01:02:59 +0000 Subject: merge from gcc --- libiberty/ChangeLog | 3 ++ libiberty/cp-demangle.c | 71 ++++++++++++++--------------------- libiberty/testsuite/demangle-expected | 4 +- 3 files changed, 34 insertions(+), 44 deletions(-) (limited to 'libiberty') diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 5e4473255e..717221dd89 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,5 +1,8 @@ 2013-04-03 Jason Merrill + * cp-demangle.c (cplus_demangle_type): Fix function quals. + (d_pointer_to_member_type): Simplify. + Demangle C++11 ref-qualifier. * cp-demangle.c (d_ref_qualifier): New. (d_nested_name, d_function_type): Use it. diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index 271d3d324d..70f54389c8 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -2198,8 +2198,16 @@ cplus_demangle_type (struct d_info *di) pret = d_cv_qualifiers (di, &ret, 0); if (pret == NULL) return NULL; - *pret = cplus_demangle_type (di); - if (! *pret) + if (d_peek_char (di) == 'F') + { + /* cv-qualifiers before a function type apply to 'this', + so avoid adding the unqualified function type to + the substitution list. */ + *pret = d_function_type (di); + } + else + *pret = cplus_demangle_type (di); + if (!*pret) return NULL; if ((*pret)->type == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS || (*pret)->type == DEMANGLE_COMPONENT_REFERENCE_THIS) @@ -2739,53 +2747,32 @@ d_pointer_to_member_type (struct d_info *di) { struct demangle_component *cl; struct demangle_component *mem; - struct demangle_component **pmem; if (! d_check_char (di, 'M')) return NULL; cl = cplus_demangle_type (di); - - /* The ABI specifies that any type can be a substitution source, and - that M is followed by two types, and that when a CV-qualified - type is seen both the base type and the CV-qualified types are - substitution sources. The ABI also specifies that for a pointer - to a CV-qualified member function, the qualifiers are attached to - the second type. Given the grammar, a plain reading of the ABI - suggests that both the CV-qualified member function and the - non-qualified member function are substitution sources. However, - g++ does not work that way. g++ treats only the CV-qualified - member function as a substitution source. FIXME. So to work - with g++, we need to pull off the CV-qualifiers here, in order to - avoid calling add_substitution() in cplus_demangle_type(). But - for a CV-qualified member which is not a function, g++ does - follow the ABI, so we need to handle that case here by calling - d_add_substitution ourselves. */ - - pmem = d_cv_qualifiers (di, &mem, 1); - if (pmem == NULL) - return NULL; - *pmem = cplus_demangle_type (di); - if (*pmem == NULL) + if (cl == NULL) return NULL; - if (pmem != &mem - && ((*pmem)->type == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS - || (*pmem)->type == DEMANGLE_COMPONENT_REFERENCE_THIS)) - { - /* Move the ref-qualifier outside the cv-qualifiers so that - they are printed in the right order. */ - struct demangle_component *fn = d_left (*pmem); - d_left (*pmem) = mem; - mem = *pmem; - *pmem = fn; - } - - if (pmem != &mem && (*pmem)->type != DEMANGLE_COMPONENT_FUNCTION_TYPE) - { - if (! d_add_substitution (di, mem)) - return NULL; - } + /* The ABI says, "The type of a non-static member function is considered + to be different, for the purposes of substitution, from the type of a + namespace-scope or static member function whose type appears + similar. The types of two non-static member functions are considered + to be different, for the purposes of substitution, if the functions + are members of different classes. In other words, for the purposes of + substitution, the class of which the function is a member is + considered part of the type of function." + + For a pointer to member function, this call to cplus_demangle_type + will end up adding a (possibly qualified) non-member function type to + the substitution table, which is not correct; however, the member + function type will never be used in a substitution, so putting the + wrong type in the substitution table is harmless. */ + + mem = cplus_demangle_type (di); + if (mem == NULL) + return NULL; return d_make_comp (di, DEMANGLE_COMPONENT_PTRMEM_TYPE, cl, mem); } diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected index ed73245206..1259e4a9f4 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -4273,8 +4273,8 @@ foo # --format=gnu-v3 --no-params _Z1fIKFvvES0_Evv -void f() -f +void f() +f # --format=gnu-v3 _ZN4modc6parser8sequenceINS_9astParser13LocatedParserINS0_9ParserRefINS2_UlRNS2_16TokenParserInputEE_EEEEEINS0_14OptionalParserINS2_18ListParserTemplateILNS_6tokens5Token4TypeE4EXadL_ZNSD_Ut_13parenthesizedEEEE6ParserINS4_INS0_6ParserIS5_NS_3ast10ExpressionEEEEEEEEENSA_INS4_INS2_22OneOfKeywordsToTParserINSJ_5StyleEEEEEEENS0_14SequenceParserIS5_INS0_18ExactElementParserIS5_EENSA_ISM_EEEEENS0_14RepeatedParserINS4_INS0_15TransformParserINSU_IS5_INS4_INSP_INSJ_10Annotation12RelationshipEEEEESX_EEENS2_UlNS2_3LocES12_ONS_5MaybeISK_EEE19_EEEEELb0EEEEEENSU_INS0_17ExtractParserTypeIT_E9InputTypeEINS0_8MaybeRefIS1F_E4TypeEDpNS1I_IT0_E4TypeEEEEOS1F_DpOS1L_ -- cgit v1.2.1