@@ -604,126 +604,6 @@ bool CPlusPlusLanguage::ExtractContextAndIdentifier(
604604 return false ;
605605}
606606
607- namespace {
608- class NodeAllocator {
609- llvm::BumpPtrAllocator Alloc;
610-
611- public:
612- void reset () { Alloc.Reset (); }
613-
614- template <typename T, typename ... Args> T *makeNode (Args &&...args) {
615- return new (Alloc.Allocate (sizeof (T), alignof (T)))
616- T (std::forward<Args>(args)...);
617- }
618-
619- void *allocateNodeArray (size_t sz) {
620- return Alloc.Allocate (sizeof (llvm::itanium_demangle::Node *) * sz,
621- alignof (llvm::itanium_demangle::Node *));
622- }
623- };
624-
625- template <typename Derived>
626- class ManglingSubstitutor
627- : public llvm::itanium_demangle::AbstractManglingParser<Derived,
628- NodeAllocator> {
629- using Base =
630- llvm::itanium_demangle::AbstractManglingParser<Derived, NodeAllocator>;
631-
632- public:
633- ManglingSubstitutor () : Base(nullptr , nullptr ) {}
634-
635- template <typename ... Ts>
636- ConstString substitute (llvm::StringRef Mangled, Ts &&...Vals) {
637- this ->getDerived ().reset (Mangled, std::forward<Ts>(Vals)...);
638- return substituteImpl (Mangled);
639- }
640-
641- protected:
642- void reset (llvm::StringRef Mangled) {
643- Base::reset (Mangled.begin (), Mangled.end ());
644- Written = Mangled.begin ();
645- Result.clear ();
646- Substituted = false ;
647- }
648-
649- ConstString substituteImpl (llvm::StringRef Mangled) {
650- Log *log = GetLog (LLDBLog::Language);
651- if (this ->parse () == nullptr ) {
652- LLDB_LOG (log, " Failed to substitute mangling in {0}" , Mangled);
653- return ConstString ();
654- }
655- if (!Substituted)
656- return ConstString ();
657-
658- // Append any trailing unmodified input.
659- appendUnchangedInput ();
660- LLDB_LOG (log, " Substituted mangling {0} -> {1}" , Mangled, Result);
661- return ConstString (Result);
662- }
663-
664- void trySubstitute (llvm::StringRef From, llvm::StringRef To) {
665- if (!llvm::StringRef (currentParserPos (), this ->numLeft ()).starts_with (From))
666- return ;
667-
668- // We found a match. Append unmodified input up to this point.
669- appendUnchangedInput ();
670-
671- // And then perform the replacement.
672- Result += To;
673- Written += From.size ();
674- Substituted = true ;
675- }
676-
677- private:
678- // / Input character until which we have constructed the respective output
679- // / already.
680- const char *Written = " " ;
681-
682- llvm::SmallString<128 > Result;
683-
684- // / Whether we have performed any substitutions.
685- bool Substituted = false ;
686-
687- const char *currentParserPos () const { return this ->First ; }
688-
689- void appendUnchangedInput () {
690- Result +=
691- llvm::StringRef (Written, std::distance (Written, currentParserPos ()));
692- Written = currentParserPos ();
693- }
694- };
695-
696- // / Given a mangled function `Mangled`, replace all the primitive function type
697- // / arguments of `Search` with type `Replace`.
698- class TypeSubstitutor : public ManglingSubstitutor <TypeSubstitutor> {
699- llvm::StringRef Search;
700- llvm::StringRef Replace;
701-
702- public:
703- void reset (llvm::StringRef Mangled, llvm::StringRef Search,
704- llvm::StringRef Replace) {
705- ManglingSubstitutor::reset (Mangled);
706- this ->Search = Search;
707- this ->Replace = Replace;
708- }
709-
710- llvm::itanium_demangle::Node *parseType () {
711- trySubstitute (Search, Replace);
712- return ManglingSubstitutor::parseType ();
713- }
714- };
715-
716- class CtorDtorSubstitutor : public ManglingSubstitutor <CtorDtorSubstitutor> {
717- public:
718- llvm::itanium_demangle::Node *
719- parseCtorDtorName (llvm::itanium_demangle::Node *&SoFar, NameState *State) {
720- trySubstitute (" C1" , " C2" );
721- trySubstitute (" D1" , " D2" );
722- return ManglingSubstitutor::parseCtorDtorName (SoFar, State);
723- }
724- };
725- } // namespace
726-
727607std::vector<ConstString> CPlusPlusLanguage::GenerateAlternateFunctionManglings (
728608 const ConstString mangled_name) const {
729609 std::vector<ConstString> alternates;
@@ -751,29 +631,49 @@ std::vector<ConstString> CPlusPlusLanguage::GenerateAlternateFunctionManglings(
751631 alternates.push_back (ConstString (fixed_scratch));
752632 }
753633
754- TypeSubstitutor TS;
634+ auto *log = GetLog (LLDBLog::Language);
635+
755636 // `char` is implementation defined as either `signed` or `unsigned`. As a
756637 // result a char parameter has 3 possible manglings: 'c'-char, 'a'-signed
757638 // char, 'h'-unsigned char. If we're looking for symbols with a signed char
758639 // parameter, try finding matches which have the general case 'c'.
759- if (ConstString char_fixup =
760- TS.substitute (mangled_name.GetStringRef (), " a" , " c" ))
761- alternates.push_back (char_fixup);
640+ if (auto char_fixup_or_err =
641+ SubstituteType_ItaniumMangle (mangled_name.GetStringRef (), " a" , " c" )) {
642+ // LLDB_LOG(log, "Substituted mangling {0} -> {1}", Mangled, Result);
643+ if (*char_fixup_or_err)
644+ alternates.push_back (*char_fixup_or_err);
645+ } else
646+ LLDB_LOG_ERROR (log, char_fixup_or_err.takeError (),
647+ " Failed to substitute 'char' type mangling: {0}" );
762648
763649 // long long parameter mangling 'x', may actually just be a long 'l' argument
764- if (ConstString long_fixup =
765- TS.substitute (mangled_name.GetStringRef (), " x" , " l" ))
766- alternates.push_back (long_fixup);
650+ if (auto long_fixup_or_err =
651+ SubstituteType_ItaniumMangle (mangled_name.GetStringRef (), " x" , " l" )) {
652+ if (*long_fixup_or_err)
653+ alternates.push_back (*long_fixup_or_err);
654+ } else
655+ LLDB_LOG_ERROR (log, long_fixup_or_err.takeError (),
656+ " Failed to substitute 'long long' type mangling: {0}" );
767657
768658 // unsigned long long parameter mangling 'y', may actually just be unsigned
769659 // long 'm' argument
770- if (ConstString ulong_fixup =
771- TS.substitute (mangled_name.GetStringRef (), " y" , " m" ))
772- alternates.push_back (ulong_fixup);
773-
774- if (ConstString ctor_fixup =
775- CtorDtorSubstitutor ().substitute (mangled_name.GetStringRef ()))
776- alternates.push_back (ctor_fixup);
660+ if (auto ulong_fixup_or_err =
661+ SubstituteType_ItaniumMangle (mangled_name.GetStringRef (), " y" , " m" )) {
662+ if (*ulong_fixup_or_err)
663+ alternates.push_back (*ulong_fixup_or_err);
664+ } else
665+ LLDB_LOG_ERROR (
666+ log, ulong_fixup_or_err.takeError (),
667+ " Failed to substitute 'unsigned long long' type mangling: {0}" );
668+
669+ if (auto ctor_fixup_or_err = SubstituteStructorAliases_ItaniumMangle (
670+ mangled_name.GetStringRef ())) {
671+ if (*ctor_fixup_or_err) {
672+ alternates.push_back (*ctor_fixup_or_err);
673+ }
674+ } else
675+ LLDB_LOG_ERROR (log, ctor_fixup_or_err.takeError (),
676+ " Failed to substitute structor alias manglings: {0}" );
777677
778678 return alternates;
779679}
@@ -2442,6 +2342,160 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
24422342 }
24432343}
24442344
2345+ namespace {
2346+ class NodeAllocator {
2347+ llvm::BumpPtrAllocator Alloc;
2348+
2349+ public:
2350+ void reset () { Alloc.Reset (); }
2351+
2352+ template <typename T, typename ... Args> T *makeNode (Args &&...args) {
2353+ return new (Alloc.Allocate (sizeof (T), alignof (T)))
2354+ T (std::forward<Args>(args)...);
2355+ }
2356+
2357+ void *allocateNodeArray (size_t sz) {
2358+ return Alloc.Allocate (sizeof (llvm::itanium_demangle::Node *) * sz,
2359+ alignof (llvm::itanium_demangle::Node *));
2360+ }
2361+ };
2362+
2363+ template <typename Derived>
2364+ class ManglingSubstitutor
2365+ : public llvm::itanium_demangle::AbstractManglingParser<Derived,
2366+ NodeAllocator> {
2367+ using Base =
2368+ llvm::itanium_demangle::AbstractManglingParser<Derived, NodeAllocator>;
2369+
2370+ public:
2371+ ManglingSubstitutor () : Base(nullptr , nullptr ) {}
2372+
2373+ template <typename ... Ts>
2374+ llvm::Expected<ConstString> substitute (llvm::StringRef Mangled,
2375+ Ts &&...Vals) {
2376+ this ->getDerived ().reset (Mangled, std::forward<Ts>(Vals)...);
2377+ return substituteImpl (Mangled);
2378+ }
2379+
2380+ protected:
2381+ void reset (llvm::StringRef Mangled) {
2382+ Base::reset (Mangled.begin (), Mangled.end ());
2383+ Written = Mangled.begin ();
2384+ Result.clear ();
2385+ Substituted = false ;
2386+ }
2387+
2388+ llvm::Expected<ConstString> substituteImpl (llvm::StringRef Mangled) {
2389+ if (this ->parse () == nullptr )
2390+ return llvm::createStringError (
2391+ llvm::formatv (" Failed to substitute mangling in '{0}'" , Mangled));
2392+
2393+ if (!Substituted)
2394+ return ConstString ();
2395+
2396+ // Append any trailing unmodified input.
2397+ appendUnchangedInput ();
2398+ return ConstString (Result);
2399+ }
2400+
2401+ void trySubstitute (llvm::StringRef From, llvm::StringRef To) {
2402+ if (!llvm::StringRef (currentParserPos (), this ->numLeft ()).starts_with (From))
2403+ return ;
2404+
2405+ // We found a match. Append unmodified input up to this point.
2406+ appendUnchangedInput ();
2407+
2408+ // And then perform the replacement.
2409+ Result += To;
2410+ Written += From.size ();
2411+ Substituted = true ;
2412+ }
2413+
2414+ private:
2415+ // / Input character until which we have constructed the respective output
2416+ // / already.
2417+ const char *Written = " " ;
2418+
2419+ llvm::SmallString<128 > Result;
2420+
2421+ // / Whether we have performed any substitutions.
2422+ bool Substituted = false ;
2423+
2424+ const char *currentParserPos () const { return this ->First ; }
2425+
2426+ void appendUnchangedInput () {
2427+ Result +=
2428+ llvm::StringRef (Written, std::distance (Written, currentParserPos ()));
2429+ Written = currentParserPos ();
2430+ }
2431+ };
2432+
2433+ // / Given a mangled function `Mangled`, replace all the primitive function type
2434+ // / arguments of `Search` with type `Replace`.
2435+ class TypeSubstitutor : public ManglingSubstitutor <TypeSubstitutor> {
2436+ llvm::StringRef Search;
2437+ llvm::StringRef Replace;
2438+
2439+ public:
2440+ void reset (llvm::StringRef Mangled, llvm::StringRef Search,
2441+ llvm::StringRef Replace) {
2442+ ManglingSubstitutor::reset (Mangled);
2443+ this ->Search = Search;
2444+ this ->Replace = Replace;
2445+ }
2446+
2447+ llvm::itanium_demangle::Node *parseType () {
2448+ trySubstitute (Search, Replace);
2449+ return ManglingSubstitutor::parseType ();
2450+ }
2451+ };
2452+
2453+ class CtorDtorSubstitutor : public ManglingSubstitutor <CtorDtorSubstitutor> {
2454+ llvm::StringRef Search;
2455+ llvm::StringRef Replace;
2456+
2457+ public:
2458+ void reset (llvm::StringRef Mangled, llvm::StringRef Search,
2459+ llvm::StringRef Replace) {
2460+ ManglingSubstitutor::reset (Mangled);
2461+ this ->Search = Search;
2462+ this ->Replace = Replace;
2463+ }
2464+
2465+ void reset (llvm::StringRef Mangled) { ManglingSubstitutor::reset (Mangled); }
2466+
2467+ llvm::itanium_demangle::Node *
2468+ parseCtorDtorName (llvm::itanium_demangle::Node *&SoFar, NameState *State) {
2469+ if (!Search.empty () && !Replace.empty ()) {
2470+ trySubstitute (Search, Replace);
2471+ } else {
2472+ trySubstitute (" D1" , " D2" );
2473+ trySubstitute (" C1" , " C2" );
2474+ }
2475+ return ManglingSubstitutor::parseCtorDtorName (SoFar, State);
2476+ }
2477+ };
2478+ } // namespace
2479+
2480+ llvm::Expected<ConstString>
2481+ CPlusPlusLanguage::SubstituteType_ItaniumMangle (llvm::StringRef mangled_name,
2482+ llvm::StringRef subst_from,
2483+ llvm::StringRef subst_to) {
2484+ return TypeSubstitutor ().substitute (mangled_name, subst_from, subst_to);
2485+ }
2486+
2487+ llvm::Expected<ConstString> CPlusPlusLanguage::SubstituteStructor_ItaniumMangle (
2488+ llvm::StringRef mangled_name, llvm::StringRef subst_from,
2489+ llvm::StringRef subst_to) {
2490+ return CtorDtorSubstitutor ().substitute (mangled_name, subst_from, subst_to);
2491+ }
2492+
2493+ llvm::Expected<ConstString>
2494+ CPlusPlusLanguage::SubstituteStructorAliases_ItaniumMangle (
2495+ llvm::StringRef mangled_name) {
2496+ return CtorDtorSubstitutor ().substitute (mangled_name);
2497+ }
2498+
24452499#define LLDB_PROPERTIES_language_cplusplus
24462500#include " LanguageCPlusPlusProperties.inc"
24472501
0 commit comments