2727
2828DEMANGLE_NAMESPACE_BEGIN
2929
30+ template <class T > class ScopedOverride {
31+ T &Loc;
32+ T Original;
33+
34+ public:
35+ ScopedOverride (T &Loc_) : ScopedOverride(Loc_, Loc_) {}
36+
37+ ScopedOverride (T &Loc_, T NewVal) : Loc(Loc_), Original(Loc_) {
38+ Loc_ = std::move (NewVal);
39+ }
40+ ~ScopedOverride () { Loc = std::move (Original); }
41+
42+ ScopedOverride (const ScopedOverride &) = delete ;
43+ ScopedOverride &operator =(const ScopedOverride &) = delete ;
44+ };
45+
3046// Stream that AST nodes write their string representation into after the AST
3147// has been parsed.
3248class OutputBuffer {
@@ -83,6 +99,127 @@ class OutputBuffer {
8399 return std::string_view (Buffer, CurrentPosition);
84100 }
85101
102+ // Stores information about parts of a demangled function name.
103+ struct FunctionNameInfo {
104+ // /< A [start, end) pair for the function basename.
105+ // /< The basename is the name without scope qualifiers
106+ // /< and without template parameters. E.g.,
107+ // /< \code{.cpp}
108+ // /< void foo::bar<int>::someFunc<float>(int) const &&
109+ // /< ^ ^
110+ // /< Start End
111+ // /< \endcode
112+ std::pair<size_t , size_t > BasenameLocs;
113+
114+ // /< A [start, end) pair for the function scope qualifiers.
115+ // /< E.g., for
116+ // /< \code{.cpp}
117+ // /< void foo::bar<int>::qux<float>(int) const &&
118+ // /< ^ ^
119+ // /< Start End
120+ // /< \endcode
121+ std::pair<size_t , size_t > ScopeLocs;
122+
123+ // /< Indicates the [start, end) of the function argument lits.
124+ // /< E.g.,
125+ // /< \code{.cpp}
126+ // /< int (*getFunc<float>(float, double))(int, int)
127+ // /< ^ ^
128+ // /< start end
129+ // /< \endcode
130+ std::pair<size_t , size_t > ArgumentLocs;
131+
132+ bool startedPrintingArguments () const { return ArgumentLocs.first > 0 ; }
133+
134+ bool shouldTrack (OutputBuffer &OB) const {
135+ if (OB.isPrintingNestedFunctionType ())
136+ return false ;
137+
138+ if (OB.isGtInsideTemplateArgs ())
139+ return false ;
140+
141+ if (startedPrintingArguments ())
142+ return false ;
143+
144+ return true ;
145+ }
146+
147+ bool canFinalize (OutputBuffer &OB) const {
148+ if (OB.isPrintingNestedFunctionType ())
149+ return false ;
150+
151+ if (OB.isGtInsideTemplateArgs ())
152+ return false ;
153+
154+ if (!startedPrintingArguments ())
155+ return false ;
156+
157+ return true ;
158+ }
159+
160+ void updateBasenameEnd (OutputBuffer &OB) {
161+ if (!shouldTrack (OB))
162+ return ;
163+
164+ BasenameLocs.second = OB.getCurrentPosition ();
165+ }
166+
167+ void updateScopeStart (OutputBuffer &OB) {
168+ if (!shouldTrack (OB))
169+ return ;
170+
171+ ScopeLocs.first = OB.getCurrentPosition ();
172+ }
173+
174+ void updateScopeEnd (OutputBuffer &OB) {
175+ if (!shouldTrack (OB))
176+ return ;
177+
178+ ScopeLocs.second = OB.getCurrentPosition ();
179+ }
180+
181+ void finalizeArgumentEnd (OutputBuffer &OB) {
182+ if (!canFinalize (OB))
183+ return ;
184+
185+ OB.FunctionInfo .ArgumentLocs .second = OB.getCurrentPosition ();
186+ }
187+
188+ void finalizeStart (OutputBuffer &OB) {
189+ if (!shouldTrack (OB))
190+ return ;
191+
192+ OB.FunctionInfo .ArgumentLocs .first = OB.getCurrentPosition ();
193+
194+ // If nothing has set the end of the basename yet (for example when
195+ // printing templates), then the beginning of the arguments is the end of
196+ // the basename.
197+ if (BasenameLocs.second == 0 )
198+ OB.FunctionInfo .BasenameLocs .second = OB.getCurrentPosition ();
199+
200+ DEMANGLE_ASSERT (!shouldTrack (OB), " " );
201+ DEMANGLE_ASSERT (canFinalize (OB), " " );
202+ }
203+
204+ void finalizeEnd (OutputBuffer &OB) {
205+ if (!canFinalize (OB))
206+ return ;
207+
208+ if (ScopeLocs.first > OB.FunctionInfo .ScopeLocs .second )
209+ ScopeLocs.second = OB.FunctionInfo .ScopeLocs .first ;
210+ BasenameLocs.first = OB.FunctionInfo .ScopeLocs .second ;
211+ }
212+
213+ ScopedOverride<unsigned > enterFunctionTypePrinting (OutputBuffer &OB) {
214+ return {OB.FunctionPrintingDepth , OB.FunctionPrintingDepth + 1 };
215+ }
216+
217+ bool hasBasename () const {
218+ return BasenameLocs.first != BasenameLocs.second &&
219+ BasenameLocs.second > 0 ;
220+ }
221+ };
222+
86223 // / If a ParameterPackExpansion (or similar type) is encountered, the offset
87224 // / into the pack that we're currently printing.
88225 unsigned CurrentPackIndex = std::numeric_limits<unsigned >::max();
@@ -92,8 +229,18 @@ class OutputBuffer {
92229 // / Use a counter so we can simply increment inside parentheses.
93230 unsigned GtIsGt = 1 ;
94231
232+ // /< When a function type is being printed this value is incremented.
233+ // /< When printing of the type is finished the value is decremented.
234+ unsigned FunctionPrintingDepth = 0 ;
235+
236+ FunctionNameInfo FunctionInfo;
237+
95238 bool isGtInsideTemplateArgs () const { return GtIsGt == 0 ; }
96239
240+ bool isPrintingNestedFunctionType () const {
241+ return FunctionPrintingDepth != 1 ;
242+ }
243+
97244 void printOpen (char Open = ' (' ) {
98245 GtIsGt++;
99246 *this += Open;
@@ -182,22 +329,6 @@ class OutputBuffer {
182329 size_t getBufferCapacity () const { return BufferCapacity; }
183330};
184331
185- template <class T > class ScopedOverride {
186- T &Loc;
187- T Original;
188-
189- public:
190- ScopedOverride (T &Loc_) : ScopedOverride(Loc_, Loc_) {}
191-
192- ScopedOverride (T &Loc_, T NewVal) : Loc(Loc_), Original(Loc_) {
193- Loc_ = std::move (NewVal);
194- }
195- ~ScopedOverride () { Loc = std::move (Original); }
196-
197- ScopedOverride (const ScopedOverride &) = delete ;
198- ScopedOverride &operator =(const ScopedOverride &) = delete ;
199- };
200-
201332DEMANGLE_NAMESPACE_END
202333
203334#endif
0 commit comments