Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 41 additions & 7 deletions demangler/gnu3/demangle_gnu3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,19 @@ namespace
}


bool IsStaticOnlyMemberFunction(BNNameType nameType)
{
return nameType == OperatorNewNameType || nameType == OperatorNewArrayNameType ||
nameType == OperatorDeleteNameType || nameType == OperatorDeleteArrayNameType;
}


bool IsDirectAnonymousNamespaceFunction(const DemangledQualifiedName& name)
{
return name.size() == 2 && name.front().GetBase() == "(anonymous namespace)";
}


// Decode a big-endian hex string into a float or double.
// Returns the decimal string representation, or the raw hex with a type
// prefix if decoding fails or the result is NaN/Inf.
Expand Down Expand Up @@ -2540,7 +2553,7 @@ DemangledTypeNode DemangleGNU3::DemangleLocalName()
}


DemangledTypeNode DemangleGNU3::DemangleName()
DemangledTypeNode DemangleGNU3::DemangleName(bool* mayHaveImplicitThis)
{
NestingGuard nestingGuard(m_nestingDepth);
LOG_INDENTATION_SCOPE;
Expand All @@ -2559,6 +2572,8 @@ DemangledTypeNode DemangleGNU3::DemangleName()
*/
DemangledTypeNode type;
bool substitute = false;
if (mayHaveImplicitThis)
*mayHaveImplicitThis = false;
switch (m_reader.Read())
{
case 'S':
Expand Down Expand Up @@ -2591,13 +2606,17 @@ DemangledTypeNode DemangleGNU3::DemangleName()
break;
case 'N': //<nested-name>
{
if (mayHaveImplicitThis)
*mayHaveImplicitThis = true;
bool allTypeArgs = false;
type = DemangleNestedName(&allTypeArgs);
if (!m_inLocalName && allTypeArgs)
PushType(type);
break;
}
case 'Z': //<local-name>
if (mayHaveImplicitThis)
*mayHaveImplicitThis = true;
type = DemangleLocalName();
break;
default: //<unscoped-name> | <substitution>
Expand All @@ -2624,7 +2643,8 @@ DemangledTypeNode DemangleGNU3::DemangleName()
}


DemangledTypeNode DemangleGNU3::DemangleSymbol(StringList& varName, bool simplifyTemplates)
DemangledTypeNode DemangleGNU3::DemangleSymbol(
StringList& varName, bool simplifyTemplates, bool recoverImplicitThis)
{
NestingGuard nestingGuard(m_nestingDepth);
LOG_INDENTATION_SCOPE;
Expand Down Expand Up @@ -3002,7 +3022,8 @@ DemangledTypeNode DemangleGNU3::DemangleSymbol(StringList& varName, bool simplif
}

//<function name> or <data name>
type = DemangleName();
bool mayHaveImplicitThis = false;
type = DemangleName(&mayHaveImplicitThis);
if (m_reader.Length() == 0)
{
return type;
Expand Down Expand Up @@ -3033,8 +3054,13 @@ DemangledTypeNode DemangleGNU3::DemangleSymbol(StringList& varName, bool simplif
const bool nameRequiresReturnType = m_isParameter || LastTypeNameSegmentHasTemplateArguments(type);
if (simplifyTemplates)
DemangledTemplateSimplifier::SimplifyTypeNodeInPlace(type);
DemangledQualifiedName enclosingName = type.GetName();
varName = type.RenderTypeNameSegments(m_platform);
BNNameType nameType = type.GetNameType();
mayHaveImplicitThis = recoverImplicitThis && mayHaveImplicitThis && !IsStaticOnlyMemberFunction(nameType) &&
!IsDirectAnonymousNamespaceFunction(enclosingName) && enclosingName.size() > 1;
if (mayHaveImplicitThis)
enclosingName.pop_back();
if (m_isOperatorOverload ||
nameType == ConstructorNameType ||
nameType == DestructorNameType ||
Expand Down Expand Up @@ -3115,6 +3141,12 @@ DemangledTypeNode DemangleGNU3::DemangleSymbol(StringList& varName, bool simplif
if (!returnTypeRef)
returnTypeRef = DemangledTypeNode::CreateShared(std::move(returnType));
type = DemangledTypeNode::FunctionType(returnTypeRef, nullptr, std::move(params));
if (mayHaveImplicitThis)
{
auto thisType = DemangledTypeNode::NamedType(StructNamedTypeClass, std::move(enclosingName));
type.SetImplicitThisParameter(DemangledTypeNode::PointerType(
std::move(thisType), false, false, PointerReferenceType));
}
if (isReturnTypeUnknown)
type.SetReturnTypeConfidence(BN_MINIMUM_CONFIDENCE);

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

namespace
{
std::optional<DemanglerResult> DemangleGNU3WithConfig(const DemanglerConfig& config, std::string_view name)
std::optional<DemanglerResult> DemangleGNU3WithConfig(
const DemanglerConfig& config, std::string_view name, bool recoverImplicitThis = true)
{
if (name.empty())
return std::nullopt;
Expand Down Expand Up @@ -3222,7 +3255,7 @@ namespace
{
string normalized = "_";
normalized.append(base.substr(zPos));
if (auto baseResult = DemangleGNU3WithConfig(config, normalized))
if (auto baseResult = DemangleGNU3WithConfig(config, normalized, false))
{
DemanglerResult result;
result.name = QualifiedName(StringList{
Expand All @@ -3241,7 +3274,7 @@ namespace
name.compare(name.size() - tlvInitSuffix.size(), tlvInitSuffix.size(), tlvInitSuffix) == 0)
{
std::string_view base = name.substr(0, name.size() - tlvInitSuffix.size());
if (auto result = DemangleGNU3WithConfig(config, base))
if (auto result = DemangleGNU3WithConfig(config, base, recoverImplicitThis))
{
if (result->name.size() > 0)
result->name[result->name.size() - 1] += "$tlv$init";
Expand Down Expand Up @@ -3276,7 +3309,8 @@ namespace
{
DemanglerResult result;
StringList nameSegments;
DemangledTypeNode type = demangle.DemangleSymbol(nameSegments, simplifyTemplates);
DemangledTypeNode type = demangle.DemangleSymbol(
nameSegments, simplifyTemplates, recoverImplicitThis && !foundHeader);
if (simplifyTemplates)
DemangledTemplateSimplifier::SimplifyTypeNodeInPlace(type);
result.type = type.Finalize(platform);
Expand Down
5 changes: 3 additions & 2 deletions demangler/gnu3/demangle_gnu3.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ class DemangleGNU3
_STD_STRING DemanglePrimaryExpression();
NodeRef DemangleTemplateSubstitutionEntry(NodeRef* outTypeRef = nullptr);
bool TryDemangleTemplateParamExpressionPackExpansion(_STD_STRING& expr, bool& emptyPack);
DemangledTypeNode DemangleName();
DemangledTypeNode DemangleName(bool* mayHaveImplicitThis = nullptr);
DemangledTypeNode DemangleLocalName();

void DemangleCVQualifiers(bool& cnst, bool& vltl, bool& rstrct);
Expand All @@ -167,7 +167,8 @@ class DemangleGNU3
public:
DemangleGNU3(BN::Platform& platform, _STD_STRING mangledName);
void Reset(BN::Platform& platform, _STD_STRING mangledName);
DemangledTypeNode DemangleSymbol(StringList& varName, bool simplifyTemplates = false);
DemangledTypeNode DemangleSymbol(
StringList& varName, bool simplifyTemplates = false, bool recoverImplicitThis = true);
};


Expand Down