Skip to content

Commit cbfc477

Browse files
committed
Recover implicit this parameters in GNU3 symbols
1 parent e4f60d2 commit cbfc477

2 files changed

Lines changed: 44 additions & 9 deletions

File tree

demangler/gnu3/demangle_gnu3.cpp

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,19 @@ namespace
288288
}
289289

290290

291+
bool IsStaticOnlyMemberFunction(BNNameType nameType)
292+
{
293+
return nameType == OperatorNewNameType || nameType == OperatorNewArrayNameType ||
294+
nameType == OperatorDeleteNameType || nameType == OperatorDeleteArrayNameType;
295+
}
296+
297+
298+
bool IsDirectAnonymousNamespaceFunction(const DemangledQualifiedName& name)
299+
{
300+
return name.size() == 2 && name.front().GetBase() == "(anonymous namespace)";
301+
}
302+
303+
291304
// Decode a big-endian hex string into a float or double.
292305
// Returns the decimal string representation, or the raw hex with a type
293306
// prefix if decoding fails or the result is NaN/Inf.
@@ -2540,7 +2553,7 @@ DemangledTypeNode DemangleGNU3::DemangleLocalName()
25402553
}
25412554

25422555

2543-
DemangledTypeNode DemangleGNU3::DemangleName()
2556+
DemangledTypeNode DemangleGNU3::DemangleName(bool* mayHaveImplicitThis)
25442557
{
25452558
NestingGuard nestingGuard(m_nestingDepth);
25462559
LOG_INDENTATION_SCOPE;
@@ -2559,6 +2572,8 @@ DemangledTypeNode DemangleGNU3::DemangleName()
25592572
*/
25602573
DemangledTypeNode type;
25612574
bool substitute = false;
2575+
if (mayHaveImplicitThis)
2576+
*mayHaveImplicitThis = false;
25622577
switch (m_reader.Read())
25632578
{
25642579
case 'S':
@@ -2591,13 +2606,17 @@ DemangledTypeNode DemangleGNU3::DemangleName()
25912606
break;
25922607
case 'N': //<nested-name>
25932608
{
2609+
if (mayHaveImplicitThis)
2610+
*mayHaveImplicitThis = true;
25942611
bool allTypeArgs = false;
25952612
type = DemangleNestedName(&allTypeArgs);
25962613
if (!m_inLocalName && allTypeArgs)
25972614
PushType(type);
25982615
break;
25992616
}
26002617
case 'Z': //<local-name>
2618+
if (mayHaveImplicitThis)
2619+
*mayHaveImplicitThis = true;
26012620
type = DemangleLocalName();
26022621
break;
26032622
default: //<unscoped-name> | <substitution>
@@ -2624,7 +2643,8 @@ DemangledTypeNode DemangleGNU3::DemangleName()
26242643
}
26252644

26262645

2627-
DemangledTypeNode DemangleGNU3::DemangleSymbol(StringList& varName, bool simplifyTemplates)
2646+
DemangledTypeNode DemangleGNU3::DemangleSymbol(
2647+
StringList& varName, bool simplifyTemplates, bool recoverImplicitThis)
26282648
{
26292649
NestingGuard nestingGuard(m_nestingDepth);
26302650
LOG_INDENTATION_SCOPE;
@@ -3002,7 +3022,8 @@ DemangledTypeNode DemangleGNU3::DemangleSymbol(StringList& varName, bool simplif
30023022
}
30033023

30043024
//<function name> or <data name>
3005-
type = DemangleName();
3025+
bool mayHaveImplicitThis = false;
3026+
type = DemangleName(&mayHaveImplicitThis);
30063027
if (m_reader.Length() == 0)
30073028
{
30083029
return type;
@@ -3033,8 +3054,13 @@ DemangledTypeNode DemangleGNU3::DemangleSymbol(StringList& varName, bool simplif
30333054
const bool nameRequiresReturnType = m_isParameter || LastTypeNameSegmentHasTemplateArguments(type);
30343055
if (simplifyTemplates)
30353056
DemangledTemplateSimplifier::SimplifyTypeNodeInPlace(type);
3057+
DemangledQualifiedName enclosingName = type.GetName();
30363058
varName = type.RenderTypeNameSegments(m_platform);
30373059
BNNameType nameType = type.GetNameType();
3060+
mayHaveImplicitThis = recoverImplicitThis && mayHaveImplicitThis && !IsStaticOnlyMemberFunction(nameType) &&
3061+
!IsDirectAnonymousNamespaceFunction(enclosingName) && enclosingName.size() > 1;
3062+
if (mayHaveImplicitThis)
3063+
enclosingName.pop_back();
30383064
if (m_isOperatorOverload ||
30393065
nameType == ConstructorNameType ||
30403066
nameType == DestructorNameType ||
@@ -3115,6 +3141,12 @@ DemangledTypeNode DemangleGNU3::DemangleSymbol(StringList& varName, bool simplif
31153141
if (!returnTypeRef)
31163142
returnTypeRef = DemangledTypeNode::CreateShared(std::move(returnType));
31173143
type = DemangledTypeNode::FunctionType(returnTypeRef, nullptr, std::move(params));
3144+
if (mayHaveImplicitThis)
3145+
{
3146+
auto thisType = DemangledTypeNode::NamedType(StructNamedTypeClass, std::move(enclosingName));
3147+
type.SetImplicitThisParameter(DemangledTypeNode::PointerType(
3148+
std::move(thisType), false, false, PointerReferenceType));
3149+
}
31183150
if (isReturnTypeUnknown)
31193151
type.SetReturnTypeConfidence(BN_MINIMUM_CONFIDENCE);
31203152

@@ -3187,7 +3219,8 @@ bool DemangleGNU3Static::DemangleGlobalHeader(string& name, string& header)
31873219

31883220
namespace
31893221
{
3190-
std::optional<DemanglerResult> DemangleGNU3WithConfig(const DemanglerConfig& config, std::string_view name)
3222+
std::optional<DemanglerResult> DemangleGNU3WithConfig(
3223+
const DemanglerConfig& config, std::string_view name, bool recoverImplicitThis = true)
31913224
{
31923225
if (name.empty())
31933226
return std::nullopt;
@@ -3222,7 +3255,7 @@ namespace
32223255
{
32233256
string normalized = "_";
32243257
normalized.append(base.substr(zPos));
3225-
if (auto baseResult = DemangleGNU3WithConfig(config, normalized))
3258+
if (auto baseResult = DemangleGNU3WithConfig(config, normalized, false))
32263259
{
32273260
DemanglerResult result;
32283261
result.name = QualifiedName(StringList{
@@ -3241,7 +3274,7 @@ namespace
32413274
name.compare(name.size() - tlvInitSuffix.size(), tlvInitSuffix.size(), tlvInitSuffix) == 0)
32423275
{
32433276
std::string_view base = name.substr(0, name.size() - tlvInitSuffix.size());
3244-
if (auto result = DemangleGNU3WithConfig(config, base))
3277+
if (auto result = DemangleGNU3WithConfig(config, base, recoverImplicitThis))
32453278
{
32463279
if (result->name.size() > 0)
32473280
result->name[result->name.size() - 1] += "$tlv$init";
@@ -3276,7 +3309,8 @@ namespace
32763309
{
32773310
DemanglerResult result;
32783311
StringList nameSegments;
3279-
DemangledTypeNode type = demangle.DemangleSymbol(nameSegments, simplifyTemplates);
3312+
DemangledTypeNode type = demangle.DemangleSymbol(
3313+
nameSegments, simplifyTemplates, recoverImplicitThis && !foundHeader);
32803314
if (simplifyTemplates)
32813315
DemangledTemplateSimplifier::SimplifyTypeNodeInPlace(type);
32823316
result.type = type.Finalize(platform);

demangler/gnu3/demangle_gnu3.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ class DemangleGNU3
140140
_STD_STRING DemanglePrimaryExpression();
141141
NodeRef DemangleTemplateSubstitutionEntry(NodeRef* outTypeRef = nullptr);
142142
bool TryDemangleTemplateParamExpressionPackExpansion(_STD_STRING& expr, bool& emptyPack);
143-
DemangledTypeNode DemangleName();
143+
DemangledTypeNode DemangleName(bool* mayHaveImplicitThis = nullptr);
144144
DemangledTypeNode DemangleLocalName();
145145

146146
void DemangleCVQualifiers(bool& cnst, bool& vltl, bool& rstrct);
@@ -167,7 +167,8 @@ class DemangleGNU3
167167
public:
168168
DemangleGNU3(BN::Platform& platform, _STD_STRING mangledName);
169169
void Reset(BN::Platform& platform, _STD_STRING mangledName);
170-
DemangledTypeNode DemangleSymbol(StringList& varName, bool simplifyTemplates = false);
170+
DemangledTypeNode DemangleSymbol(
171+
StringList& varName, bool simplifyTemplates = false, bool recoverImplicitThis = true);
171172
};
172173

173174

0 commit comments

Comments
 (0)