@@ -547,126 +547,6 @@ bool CPlusPlusLanguage::ExtractContextAndIdentifier(
547547 return false ;
548548}
549549
550- namespace {
551- class NodeAllocator {
552- llvm::BumpPtrAllocator Alloc;
553-
554- public:
555- void reset () { Alloc.Reset (); }
556-
557- template <typename T, typename ... Args> T *makeNode (Args &&...args) {
558- return new (Alloc.Allocate (sizeof (T), alignof (T)))
559- T (std::forward<Args>(args)...);
560- }
561-
562- void *allocateNodeArray (size_t sz) {
563- return Alloc.Allocate (sizeof (llvm::itanium_demangle::Node *) * sz,
564- alignof (llvm::itanium_demangle::Node *));
565- }
566- };
567-
568- template <typename Derived>
569- class ManglingSubstitutor
570- : public llvm::itanium_demangle::AbstractManglingParser<Derived,
571- NodeAllocator> {
572- using Base =
573- llvm::itanium_demangle::AbstractManglingParser<Derived, NodeAllocator>;
574-
575- public:
576- ManglingSubstitutor () : Base(nullptr , nullptr ) {}
577-
578- template <typename ... Ts>
579- ConstString substitute (llvm::StringRef Mangled, Ts &&...Vals) {
580- this ->getDerived ().reset (Mangled, std::forward<Ts>(Vals)...);
581- return substituteImpl (Mangled);
582- }
583-
584- protected:
585- void reset (llvm::StringRef Mangled) {
586- Base::reset (Mangled.begin (), Mangled.end ());
587- Written = Mangled.begin ();
588- Result.clear ();
589- Substituted = false ;
590- }
591-
592- ConstString substituteImpl (llvm::StringRef Mangled) {
593- Log *log = GetLog (LLDBLog::Language);
594- if (this ->parse () == nullptr ) {
595- LLDB_LOG (log, " Failed to substitute mangling in {0}" , Mangled);
596- return ConstString ();
597- }
598- if (!Substituted)
599- return ConstString ();
600-
601- // Append any trailing unmodified input.
602- appendUnchangedInput ();
603- LLDB_LOG (log, " Substituted mangling {0} -> {1}" , Mangled, Result);
604- return ConstString (Result);
605- }
606-
607- void trySubstitute (llvm::StringRef From, llvm::StringRef To) {
608- if (!llvm::StringRef (currentParserPos (), this ->numLeft ()).starts_with (From))
609- return ;
610-
611- // We found a match. Append unmodified input up to this point.
612- appendUnchangedInput ();
613-
614- // And then perform the replacement.
615- Result += To;
616- Written += From.size ();
617- Substituted = true ;
618- }
619-
620- private:
621- // / Input character until which we have constructed the respective output
622- // / already.
623- const char *Written = " " ;
624-
625- llvm::SmallString<128 > Result;
626-
627- // / Whether we have performed any substitutions.
628- bool Substituted = false ;
629-
630- const char *currentParserPos () const { return this ->First ; }
631-
632- void appendUnchangedInput () {
633- Result +=
634- llvm::StringRef (Written, std::distance (Written, currentParserPos ()));
635- Written = currentParserPos ();
636- }
637- };
638-
639- // / Given a mangled function `Mangled`, replace all the primitive function type
640- // / arguments of `Search` with type `Replace`.
641- class TypeSubstitutor : public ManglingSubstitutor <TypeSubstitutor> {
642- llvm::StringRef Search;
643- llvm::StringRef Replace;
644-
645- public:
646- void reset (llvm::StringRef Mangled, llvm::StringRef Search,
647- llvm::StringRef Replace) {
648- ManglingSubstitutor::reset (Mangled);
649- this ->Search = Search;
650- this ->Replace = Replace;
651- }
652-
653- llvm::itanium_demangle::Node *parseType () {
654- trySubstitute (Search, Replace);
655- return ManglingSubstitutor::parseType ();
656- }
657- };
658-
659- class CtorDtorSubstitutor : public ManglingSubstitutor <CtorDtorSubstitutor> {
660- public:
661- llvm::itanium_demangle::Node *
662- parseCtorDtorName (llvm::itanium_demangle::Node *&SoFar, NameState *State) {
663- trySubstitute (" C1" , " C2" );
664- trySubstitute (" D1" , " D2" );
665- return ManglingSubstitutor::parseCtorDtorName (SoFar, State);
666- }
667- };
668- } // namespace
669-
670550std::vector<ConstString> CPlusPlusLanguage::GenerateAlternateFunctionManglings (
671551 const ConstString mangled_name) const {
672552 std::vector<ConstString> alternates;
@@ -694,29 +574,49 @@ std::vector<ConstString> CPlusPlusLanguage::GenerateAlternateFunctionManglings(
694574 alternates.push_back (ConstString (fixed_scratch));
695575 }
696576
697- TypeSubstitutor TS;
577+ auto *log = GetLog (LLDBLog::Language);
578+
698579 // `char` is implementation defined as either `signed` or `unsigned`. As a
699580 // result a char parameter has 3 possible manglings: 'c'-char, 'a'-signed
700581 // char, 'h'-unsigned char. If we're looking for symbols with a signed char
701582 // parameter, try finding matches which have the general case 'c'.
702- if (ConstString char_fixup =
703- TS.substitute (mangled_name.GetStringRef (), " a" , " c" ))
704- alternates.push_back (char_fixup);
583+ if (auto char_fixup_or_err =
584+ SubstituteType_ItaniumMangle (mangled_name.GetStringRef (), " a" , " c" )) {
585+ // LLDB_LOG(log, "Substituted mangling {0} -> {1}", Mangled, Result);
586+ if (*char_fixup_or_err)
587+ alternates.push_back (*char_fixup_or_err);
588+ } else
589+ LLDB_LOG_ERROR (log, char_fixup_or_err.takeError (),
590+ " Failed to substitute 'char' type mangling: {0}" );
705591
706592 // long long parameter mangling 'x', may actually just be a long 'l' argument
707- if (ConstString long_fixup =
708- TS.substitute (mangled_name.GetStringRef (), " x" , " l" ))
709- alternates.push_back (long_fixup);
593+ if (auto long_fixup_or_err =
594+ SubstituteType_ItaniumMangle (mangled_name.GetStringRef (), " x" , " l" )) {
595+ if (*long_fixup_or_err)
596+ alternates.push_back (*long_fixup_or_err);
597+ } else
598+ LLDB_LOG_ERROR (log, long_fixup_or_err.takeError (),
599+ " Failed to substitute 'long long' type mangling: {0}" );
710600
711601 // unsigned long long parameter mangling 'y', may actually just be unsigned
712602 // long 'm' argument
713- if (ConstString ulong_fixup =
714- TS.substitute (mangled_name.GetStringRef (), " y" , " m" ))
715- alternates.push_back (ulong_fixup);
716-
717- if (ConstString ctor_fixup =
718- CtorDtorSubstitutor ().substitute (mangled_name.GetStringRef ()))
719- alternates.push_back (ctor_fixup);
603+ if (auto ulong_fixup_or_err =
604+ SubstituteType_ItaniumMangle (mangled_name.GetStringRef (), " y" , " m" )) {
605+ if (*ulong_fixup_or_err)
606+ alternates.push_back (*ulong_fixup_or_err);
607+ } else
608+ LLDB_LOG_ERROR (
609+ log, ulong_fixup_or_err.takeError (),
610+ " Failed to substitute 'unsigned long long' type mangling: {0}" );
611+
612+ if (auto ctor_fixup_or_err = SubstituteStructorAliases_ItaniumMangle (
613+ mangled_name.GetStringRef ())) {
614+ if (*ctor_fixup_or_err) {
615+ alternates.push_back (*ctor_fixup_or_err);
616+ }
617+ } else
618+ LLDB_LOG_ERROR (log, ctor_fixup_or_err.takeError (),
619+ " Failed to substitute structor alias manglings: {0}" );
720620
721621 return alternates;
722622}
@@ -2150,6 +2050,160 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
21502050 }
21512051}
21522052
2053+ namespace {
2054+ class NodeAllocator {
2055+ llvm::BumpPtrAllocator Alloc;
2056+
2057+ public:
2058+ void reset () { Alloc.Reset (); }
2059+
2060+ template <typename T, typename ... Args> T *makeNode (Args &&...args) {
2061+ return new (Alloc.Allocate (sizeof (T), alignof (T)))
2062+ T (std::forward<Args>(args)...);
2063+ }
2064+
2065+ void *allocateNodeArray (size_t sz) {
2066+ return Alloc.Allocate (sizeof (llvm::itanium_demangle::Node *) * sz,
2067+ alignof (llvm::itanium_demangle::Node *));
2068+ }
2069+ };
2070+
2071+ template <typename Derived>
2072+ class ManglingSubstitutor
2073+ : public llvm::itanium_demangle::AbstractManglingParser<Derived,
2074+ NodeAllocator> {
2075+ using Base =
2076+ llvm::itanium_demangle::AbstractManglingParser<Derived, NodeAllocator>;
2077+
2078+ public:
2079+ ManglingSubstitutor () : Base(nullptr , nullptr ) {}
2080+
2081+ template <typename ... Ts>
2082+ llvm::Expected<ConstString> substitute (llvm::StringRef Mangled,
2083+ Ts &&...Vals) {
2084+ this ->getDerived ().reset (Mangled, std::forward<Ts>(Vals)...);
2085+ return substituteImpl (Mangled);
2086+ }
2087+
2088+ protected:
2089+ void reset (llvm::StringRef Mangled) {
2090+ Base::reset (Mangled.begin (), Mangled.end ());
2091+ Written = Mangled.begin ();
2092+ Result.clear ();
2093+ Substituted = false ;
2094+ }
2095+
2096+ llvm::Expected<ConstString> substituteImpl (llvm::StringRef Mangled) {
2097+ if (this ->parse () == nullptr )
2098+ return llvm::createStringError (
2099+ llvm::formatv (" Failed to substitute mangling in '{0}'" , Mangled));
2100+
2101+ if (!Substituted)
2102+ return ConstString ();
2103+
2104+ // Append any trailing unmodified input.
2105+ appendUnchangedInput ();
2106+ return ConstString (Result);
2107+ }
2108+
2109+ void trySubstitute (llvm::StringRef From, llvm::StringRef To) {
2110+ if (!llvm::StringRef (currentParserPos (), this ->numLeft ()).starts_with (From))
2111+ return ;
2112+
2113+ // We found a match. Append unmodified input up to this point.
2114+ appendUnchangedInput ();
2115+
2116+ // And then perform the replacement.
2117+ Result += To;
2118+ Written += From.size ();
2119+ Substituted = true ;
2120+ }
2121+
2122+ private:
2123+ // / Input character until which we have constructed the respective output
2124+ // / already.
2125+ const char *Written = " " ;
2126+
2127+ llvm::SmallString<128 > Result;
2128+
2129+ // / Whether we have performed any substitutions.
2130+ bool Substituted = false ;
2131+
2132+ const char *currentParserPos () const { return this ->First ; }
2133+
2134+ void appendUnchangedInput () {
2135+ Result +=
2136+ llvm::StringRef (Written, std::distance (Written, currentParserPos ()));
2137+ Written = currentParserPos ();
2138+ }
2139+ };
2140+
2141+ // / Given a mangled function `Mangled`, replace all the primitive function type
2142+ // / arguments of `Search` with type `Replace`.
2143+ class TypeSubstitutor : public ManglingSubstitutor <TypeSubstitutor> {
2144+ llvm::StringRef Search;
2145+ llvm::StringRef Replace;
2146+
2147+ public:
2148+ void reset (llvm::StringRef Mangled, llvm::StringRef Search,
2149+ llvm::StringRef Replace) {
2150+ ManglingSubstitutor::reset (Mangled);
2151+ this ->Search = Search;
2152+ this ->Replace = Replace;
2153+ }
2154+
2155+ llvm::itanium_demangle::Node *parseType () {
2156+ trySubstitute (Search, Replace);
2157+ return ManglingSubstitutor::parseType ();
2158+ }
2159+ };
2160+
2161+ class CtorDtorSubstitutor : public ManglingSubstitutor <CtorDtorSubstitutor> {
2162+ llvm::StringRef Search;
2163+ llvm::StringRef Replace;
2164+
2165+ public:
2166+ void reset (llvm::StringRef Mangled, llvm::StringRef Search,
2167+ llvm::StringRef Replace) {
2168+ ManglingSubstitutor::reset (Mangled);
2169+ this ->Search = Search;
2170+ this ->Replace = Replace;
2171+ }
2172+
2173+ void reset (llvm::StringRef Mangled) { ManglingSubstitutor::reset (Mangled); }
2174+
2175+ llvm::itanium_demangle::Node *
2176+ parseCtorDtorName (llvm::itanium_demangle::Node *&SoFar, NameState *State) {
2177+ if (!Search.empty () && !Replace.empty ()) {
2178+ trySubstitute (Search, Replace);
2179+ } else {
2180+ trySubstitute (" D1" , " D2" );
2181+ trySubstitute (" C1" , " C2" );
2182+ }
2183+ return ManglingSubstitutor::parseCtorDtorName (SoFar, State);
2184+ }
2185+ };
2186+ } // namespace
2187+
2188+ llvm::Expected<ConstString>
2189+ CPlusPlusLanguage::SubstituteType_ItaniumMangle (llvm::StringRef mangled_name,
2190+ llvm::StringRef subst_from,
2191+ llvm::StringRef subst_to) {
2192+ return TypeSubstitutor ().substitute (mangled_name, subst_from, subst_to);
2193+ }
2194+
2195+ llvm::Expected<ConstString> CPlusPlusLanguage::SubstituteStructor_ItaniumMangle (
2196+ llvm::StringRef mangled_name, llvm::StringRef subst_from,
2197+ llvm::StringRef subst_to) {
2198+ return CtorDtorSubstitutor ().substitute (mangled_name, subst_from, subst_to);
2199+ }
2200+
2201+ llvm::Expected<ConstString>
2202+ CPlusPlusLanguage::SubstituteStructorAliases_ItaniumMangle (
2203+ llvm::StringRef mangled_name) {
2204+ return CtorDtorSubstitutor ().substitute (mangled_name);
2205+ }
2206+
21532207#define LLDB_PROPERTIES_language_cplusplus
21542208#include " LanguageCPlusPlusProperties.inc"
21552209
0 commit comments