diff --git a/llvm/include/llvm/Demangle/ItaniumDemangle.h b/llvm/include/llvm/Demangle/ItaniumDemangle.h --- a/llvm/include/llvm/Demangle/ItaniumDemangle.h +++ b/llvm/include/llvm/Demangle/ItaniumDemangle.h @@ -221,6 +221,17 @@ /// Visit the most-derived object corresponding to this object. template void visit(Fn F) const; + /// Returns true if the tree rooted at this node is equivalent to + /// the tree rooted at the specified 'Root' node. + /// + /// Equivalence of two nodes N1 and N2 is defined as: + /// 1. N1.getKind() == N2.getKind() + /// 2. N1 == N2 where '==' is defined by the + /// kind of N1 and N2. + /// + /// Behaviour is undefined if 'Root == nullptr'. + bool equals(Node const* Root) const; + // The following function is provided by all derived classes: // // Call F with arguments that, when passed to the constructor of this node, @@ -331,6 +342,19 @@ FirstElement = false; } } + + friend bool operator==(NodeArray const& LHS, NodeArray const& RHS) { + if (LHS.size() != RHS.size()) + return false; + + auto** IT1 = LHS.begin(); + auto** IT2 = RHS.begin(); + for (; IT1 != LHS.end(); ++IT1) + if (!(*IT1)->equals(*IT2)) + return false; + + return true; + } }; struct NodeArrayNode : Node { @@ -340,6 +364,10 @@ template void match(Fn F) const { F(Array); } void printLeft(OutputBuffer &OB) const override { Array.printWithComma(OB); } + + friend bool operator==(NodeArrayNode const& lhs, NodeArrayNode const& rhs) { + return lhs.Array == rhs.Array; + } }; class DotSuffix final : public Node { @@ -358,6 +386,10 @@ OB += Suffix; OB += ")"; } + + friend bool operator==(DotSuffix const& lhs, DotSuffix const& rhs) { + return lhs.Suffix == rhs.Suffix && lhs.Prefix->equals(rhs.Prefix); + } }; class VendorExtQualType final : public Node { @@ -378,6 +410,12 @@ if (TA != nullptr) TA->print(OB); } + + friend bool operator==(VendorExtQualType const& lhs, VendorExtQualType const& rhs) { + return lhs.Ext == rhs.Ext + && lhs.Ty->equals(rhs.Ty) + && lhs.TA->equals(rhs.TA); + } }; enum FunctionRefQual : unsigned char { @@ -435,6 +473,11 @@ } void printRight(OutputBuffer &OB) const override { Child->printRight(OB); } + + friend bool operator==(QualType const& lhs, QualType const& rhs) { + return lhs.Quals == rhs.Quals + && lhs.Child->equals(rhs.Child); + } }; class ConversionOperatorType final : public Node { @@ -450,6 +493,11 @@ OB += "operator "; Ty->print(OB); } + + friend bool operator==(ConversionOperatorType const& lhs, + ConversionOperatorType const& rhs) { + return lhs.Ty->equals(rhs.Ty); + } }; class PostfixQualifiedType final : public Node { @@ -466,6 +514,12 @@ Ty->printLeft(OB); OB += Postfix; } + + friend bool operator==(PostfixQualifiedType const& lhs, + PostfixQualifiedType const& rhs) { + return lhs.Postfix == rhs.Postfix + && lhs.Ty->equals(rhs.Ty); + } }; class NameType final : public Node { @@ -480,6 +534,10 @@ StringView getBaseName() const override { return Name; } void printLeft(OutputBuffer &OB) const override { OB += Name; } + + friend bool operator==(NameType const& lhs, NameType const& rhs) { + return lhs.Name == rhs.Name; + } }; class BitIntType final : public Node { @@ -500,6 +558,11 @@ Size->printAsOperand(OB); OB.printClose(); } + + friend bool operator==(BitIntType const& lhs, BitIntType const& rhs) { + return lhs.Signed == rhs.Signed + && lhs.Size->equals(rhs.Size); + } }; class ElaboratedTypeSpefType : public Node { @@ -516,6 +579,12 @@ OB += ' '; Child->print(OB); } + + friend bool operator==(ElaboratedTypeSpefType const& lhs, + ElaboratedTypeSpefType const& rhs) { + return lhs.Kind == rhs.Kind + && lhs.Child->equals(rhs.Child); + } }; struct AbiTagAttr : Node { @@ -535,6 +604,11 @@ OB += Tag; OB += "]"; } + + friend bool operator==(AbiTagAttr const& lhs, AbiTagAttr const& rhs) { + return lhs.Tag == rhs.Tag + && lhs.Base->equals(rhs.Base); + } }; class EnableIfAttr : public Node { @@ -550,6 +624,11 @@ Conditions.printWithComma(OB); OB += ']'; } + + friend bool operator==(EnableIfAttr const& lhs, + EnableIfAttr const& rhs) { + return lhs.Conditions == rhs.Conditions; + } }; class ObjCProtoName : public Node { @@ -575,6 +654,12 @@ OB += Protocol; OB += ">"; } + + friend bool operator==(ObjCProtoName const& lhs, + ObjCProtoName const& rhs) { + return lhs.Protocol == rhs.Protocol + && lhs.Ty->equals(rhs.Ty); + } }; class PointerType final : public Node { @@ -617,6 +702,10 @@ Pointee->printRight(OB); } } + + friend bool operator==(PointerType const& lhs, PointerType const& rhs) { + return lhs.Pointee->equals(rhs.Pointee); + } }; enum class ReferenceKind { @@ -699,6 +788,11 @@ OB += ")"; Collapsed.second->printRight(OB); } + + friend bool operator==(ReferenceType const& lhs, ReferenceType const& rhs) { + return lhs.RK == rhs.RK + && lhs.Pointee->equals(rhs.Pointee); + } }; class PointerToMemberType final : public Node { @@ -731,6 +825,11 @@ OB += ")"; MemberType->printRight(OB); } + + friend bool operator==(PointerToMemberType const& lhs, PointerToMemberType const& rhs) { + return lhs.ClassType->equals(rhs.ClassType) + && lhs.ClassType->equals(rhs.ClassType); + } }; class ArrayType final : public Node { @@ -760,6 +859,11 @@ OB += "]"; Base->printRight(OB); } + + friend bool operator==(ArrayType const& lhs, ArrayType const& rhs) { + return lhs.Base->equals(rhs.Base) + && lhs.Dimension->equals(rhs.Dimension); + } }; class FunctionType final : public Node { @@ -820,6 +924,14 @@ ExceptionSpec->print(OB); } } + + friend bool operator==(FunctionType const& lhs, FunctionType const& rhs) { + return lhs.CVQuals == rhs.CVQuals + && lhs.RefQual == rhs.RefQual + && lhs.Params == rhs.Params + && lhs.Ret->equals(rhs.Ret) + && lhs.ExceptionSpec->equals(rhs.ExceptionSpec); + } }; class NoexceptSpec : public Node { @@ -835,6 +947,10 @@ E->printAsOperand(OB); OB.printClose(); } + + friend bool operator==(NoexceptSpec const& lhs, NoexceptSpec const& rhs) { + return lhs.E->equals(rhs.E); + } }; class DynamicExceptionSpec : public Node { @@ -851,6 +967,11 @@ Types.printWithComma(OB); OB.printClose(); } + + friend bool operator==(DynamicExceptionSpec const& lhs, + DynamicExceptionSpec const& rhs) { + return lhs.Types == rhs.Types; + } }; class FunctionEncoding final : public Node { @@ -917,6 +1038,16 @@ if (Attrs != nullptr) Attrs->print(OB); } + + friend bool operator==(FunctionEncoding const& lhs, + FunctionEncoding const& rhs) { + return lhs.CVQuals == rhs.CVQuals + && lhs.RefQual == rhs.RefQual + && lhs.Ret->equals(rhs.Ret) + && lhs.Name->equals(rhs.Name) + && lhs.Params == rhs.Params + && lhs.Attrs->equals(rhs.Attrs); + } }; class LiteralOperator : public Node { @@ -932,6 +1063,11 @@ OB += "operator\"\" "; OpName->print(OB); } + + friend bool operator==(LiteralOperator const& lhs, + LiteralOperator const& rhs) { + return lhs.OpName == rhs.OpName; + } }; class SpecialName final : public Node { @@ -948,6 +1084,12 @@ OB += Special; Child->print(OB); } + + friend bool operator==(SpecialName const& lhs, + SpecialName const& rhs) { + return lhs.Special == rhs.Special + && lhs.Child->equals(rhs.Child); + } }; class CtorVtableSpecialName final : public Node { @@ -967,6 +1109,12 @@ OB += "-in-"; SecondType->print(OB); } + + friend bool operator==(CtorVtableSpecialName const& lhs, + CtorVtableSpecialName const& rhs) { + return lhs.FirstType->equals(rhs.FirstType) + && lhs.SecondType->equals(rhs.SecondType); + } }; struct NestedName : Node { @@ -985,6 +1133,12 @@ OB += "::"; Name->print(OB); } + + friend bool operator==(NestedName const& lhs, + NestedName const& rhs) { + return lhs.Qual->equals(rhs.Qual) + && lhs.Name->equals(rhs.Name); + } }; struct ModuleName : Node { @@ -1007,6 +1161,21 @@ OB += IsPartition ? ':' : '.'; Name->print(OB); } + + friend bool operator==(ModuleName const& lhs, + ModuleName const& rhs) { + if (lhs.IsPartition != rhs.IsPartition) + return false; + + if (!!lhs.Parent != !!rhs.Parent) + return false; + + if (lhs.Parent) + if (!(*lhs.Parent == *rhs.Parent)) + return false; + + return lhs.Name->equals(rhs.Name); + } }; struct ModuleEntity : Node { @@ -1025,6 +1194,12 @@ OB += '@'; Module->print(OB); } + + friend bool operator==(ModuleEntity const& lhs, + ModuleEntity const& rhs) { + return lhs.Module->equals(rhs.Module) + && lhs.Name->equals(rhs.Name); + } }; struct LocalName : Node { @@ -1041,6 +1216,11 @@ OB += "::"; Entity->print(OB); } + + friend bool operator==(LocalName const& lhs, LocalName const& rhs) { + return lhs.Encoding->equals(rhs.Encoding) + && lhs.Entity->equals(rhs.Entity); + } }; class QualifiedName final : public Node { @@ -1061,6 +1241,12 @@ OB += "::"; Name->print(OB); } + + friend bool operator==(QualifiedName const& lhs, + QualifiedName const& rhs) { + return lhs.Qualifier->equals(rhs.Qualifier) + && lhs.Name->equals(rhs.Name); + } }; class VectorType final : public Node { @@ -1080,6 +1266,12 @@ Dimension->print(OB); OB += "]"; } + + friend bool operator==(VectorType const& lhs, + VectorType const& rhs) { + return lhs.BaseType->equals(rhs.BaseType) + && lhs.Dimension->equals(rhs.Dimension); + } }; class PixelVectorType final : public Node { @@ -1097,6 +1289,11 @@ Dimension->print(OB); OB += "]"; } + + friend bool operator==(PixelVectorType const& lhs, + PixelVectorType const& rhs) { + return lhs.Dimension->equals(rhs.Dimension); + } }; class BinaryFPType final : public Node { @@ -1112,6 +1309,11 @@ OB += "_Float"; Dimension->print(OB); } + + friend bool operator==(BinaryFPType const& lhs, + BinaryFPType const& rhs) { + return lhs.Dimension->equals(rhs.Dimension); + } }; enum class TemplateParamKind { Type, NonType, Template }; @@ -1147,6 +1349,12 @@ if (Index > 0) OB << Index - 1; } + + friend bool operator==(SyntheticTemplateParamName const& lhs, + SyntheticTemplateParamName const& rhs) { + return lhs.Kind == rhs.Kind + && lhs.Index == rhs.Index; + } }; /// A template type parameter declaration, 'typename T'. @@ -1162,6 +1370,11 @@ void printLeft(OutputBuffer &OB) const override { OB += "typename "; } void printRight(OutputBuffer &OB) const override { Name->print(OB); } + + friend bool operator==(TypeTemplateParamDecl const& lhs, + TypeTemplateParamDecl const& rhs) { + return lhs.Name->equals(rhs.Name); + } }; /// A non-type template parameter declaration, 'int N'. @@ -1185,6 +1398,12 @@ Name->print(OB); Type->printRight(OB); } + + friend bool operator==(NonTypeTemplateParamDecl const& lhs, + NonTypeTemplateParamDecl const& rhs) { + return lhs.Name->equals(rhs.Name) + && lhs.Type->equals(rhs.Type); + } }; /// A template template parameter declaration, @@ -1208,6 +1427,12 @@ } void printRight(OutputBuffer &OB) const override { Name->print(OB); } + + friend bool operator==(TemplateTemplateParamDecl const& lhs, + TemplateTemplateParamDecl const& rhs) { + return lhs.Name->equals(rhs.Name) + && lhs.Params == rhs.Params; + } }; /// A template parameter pack declaration, 'typename ...T'. @@ -1226,6 +1451,11 @@ } void printRight(OutputBuffer &OB) const override { Param->printRight(OB); } + + friend bool operator==(TemplateParamPackDecl const& lhs, + TemplateParamPackDecl const& rhs) { + return lhs.Param->equals(rhs.Param); + } }; /// An unexpanded parameter pack (either in the expression or type context). If @@ -1300,6 +1530,11 @@ if (Idx < Data.size()) Data[Idx]->printRight(OB); } + + friend bool operator==(ParameterPack const& lhs, + ParameterPack const& rhs) { + return lhs.Data == rhs.Data; + } }; /// A variadic template argument. This node represents an occurrence of @@ -1320,6 +1555,11 @@ void printLeft(OutputBuffer &OB) const override { Elements.printWithComma(OB); } + + friend bool operator==(TemplateArgumentPack const& lhs, + TemplateArgumentPack const& rhs) { + return lhs.Elements == rhs.Elements; + } }; /// A pack expansion. Below this node, there are some unexpanded ParameterPacks @@ -1366,6 +1606,11 @@ Child->print(OB); } } + + friend bool operator==(ParameterPackExpansion const& lhs, + ParameterPackExpansion const& rhs) { + return lhs.Child->equals(rhs.Child); + } }; class TemplateArgs final : public Node { @@ -1384,6 +1629,11 @@ Params.printWithComma(OB); OB += ">"; } + + friend bool operator==(TemplateArgs const& lhs, + TemplateArgs const& rhs) { + return lhs.Params == rhs.Params; + } }; /// A forward-reference to a template argument that was not known at the point @@ -1414,6 +1664,22 @@ // out if more than one print* function is active. mutable bool Printing = false; + friend bool operator==(ForwardTemplateReference const& lhs, + ForwardTemplateReference const& rhs) { + if (lhs.Index != rhs.Index) + return false; + + if (!!lhs.Ref != !!rhs.Ref) + return false; + + if (lhs.Ref) + if (!lhs.Ref->equals(rhs.Ref)) + return false; + + // Ignore 'Printing' member + return true; + } + ForwardTemplateReference(size_t Index_) : Node(KForwardTemplateReference, Cache::Unknown, Cache::Unknown, Cache::Unknown), @@ -1479,6 +1745,12 @@ Name->print(OB); TemplateArgs->print(OB); } + + friend bool operator==(NameWithTemplateArgs const& lhs, + NameWithTemplateArgs const& rhs) { + return lhs.Name->equals(rhs.Name) + && lhs.TemplateArgs->equals(rhs.TemplateArgs); + } }; class GlobalQualifiedName final : public Node { @@ -1496,6 +1768,11 @@ OB += "::"; Child->print(OB); } + + friend bool operator==(GlobalQualifiedName const& lhs, + GlobalQualifiedName const& rhs) { + return lhs.Child->equals(rhs.Child); + } }; enum class SpecialSubKind { @@ -1554,6 +1831,11 @@ OB << ">"; } } + + friend bool operator==(ExpandedSpecialSubstitution const& lhs, + ExpandedSpecialSubstitution const& rhs) { + return lhs.SSK == rhs.SSK; + } }; class SpecialSubstitution final : public ExpandedSpecialSubstitution { @@ -1599,6 +1881,13 @@ OB += "~"; OB += Basename->getBaseName(); } + + friend bool operator==(CtorDtorName const& lhs, + CtorDtorName const& rhs) { + return lhs.IsDtor == rhs.IsDtor + && lhs.Variant == rhs.Variant + && lhs.Basename->equals(rhs.Basename); + } }; class DtorName : public Node { @@ -1613,6 +1902,11 @@ OB += "~"; Base->printLeft(OB); } + + friend bool operator==(DtorName const& lhs, + DtorName const& rhs) { + return lhs.Base->equals(rhs.Base); + } }; class UnnamedTypeName : public Node { @@ -1628,6 +1922,11 @@ OB += Count; OB += "\'"; } + + friend bool operator==(UnnamedTypeName const& lhs, + UnnamedTypeName const& rhs) { + return lhs.Count == rhs.Count; + } }; class ClosureTypeName : public Node { @@ -1663,6 +1962,13 @@ OB += "\'"; printDeclarator(OB); } + + friend bool operator==(ClosureTypeName const& lhs, + ClosureTypeName const& rhs) { + return lhs.TemplateParams == rhs.TemplateParams + && lhs.Params == rhs.Params + && lhs.Count == rhs.Count; + } }; class StructuredBindingName : public Node { @@ -1678,6 +1984,11 @@ Bindings.printWithComma(OB); OB.printClose(']'); } + + friend bool operator==(StructuredBindingName const& lhs, + StructuredBindingName const& rhs) { + return lhs.Bindings == rhs.Bindings; + } }; // -- Expression Nodes -- @@ -1714,6 +2025,13 @@ if (ParenAll) OB.printClose(); } + + friend bool operator==(BinaryExpr const& lhs, + BinaryExpr const& rhs) { + return lhs.InfixOperator == rhs.InfixOperator + && lhs.LHS->equals(rhs.LHS) + && lhs.RHS->equals(rhs.RHS); + } }; class ArraySubscriptExpr : public Node { @@ -1734,6 +2052,12 @@ Op2->printAsOperand(OB); OB.printClose(']'); } + + friend bool operator==(ArraySubscriptExpr const& lhs, + ArraySubscriptExpr const& rhs) { + return lhs.Op1->equals(rhs.Op1) + && lhs.Op2->equals(rhs.Op2); + } }; class PostfixExpr : public Node { @@ -1752,6 +2076,12 @@ Child->printAsOperand(OB, getPrecedence(), true); OB += Operator; } + + friend bool operator==(PostfixExpr const& lhs, + PostfixExpr const& rhs) { + return lhs.Operator == rhs.Operator + && lhs.Child->equals(rhs.Child); + } }; class ConditionalExpr : public Node { @@ -1775,6 +2105,13 @@ OB += " : "; Else->printAsOperand(OB, Prec::Assign, true); } + + friend bool operator==(ConditionalExpr const& lhs, + ConditionalExpr const& rhs) { + return lhs.Cond->equals(rhs.Cond) + && lhs.Then->equals(rhs.Then) + && lhs.Else->equals(rhs.Else); + } }; class MemberExpr : public Node { @@ -1795,6 +2132,13 @@ OB += Kind; RHS->printAsOperand(OB, getPrecedence(), false); } + + friend bool operator==(MemberExpr const& lhs, + MemberExpr const& rhs) { + return lhs.Kind == rhs.Kind + && lhs.LHS->equals(rhs.LHS) + && lhs.RHS->equals(rhs.RHS); + } }; class SubobjectExpr : public Node { @@ -1829,6 +2173,15 @@ } OB += ">"; } + + friend bool operator==(SubobjectExpr const& lhs, + SubobjectExpr const& rhs) { + return lhs.Offset == rhs.Offset + && lhs.OnePastTheEnd == rhs.OnePastTheEnd + && lhs.Type->equals(rhs.Type) + && lhs.SubExpr->equals(rhs.SubExpr) + && lhs.UnionSelectors == rhs.UnionSelectors; + } }; class EnclosingExpr : public Node { @@ -1852,6 +2205,13 @@ OB.printClose(); OB += Postfix; } + + friend bool operator==(EnclosingExpr const& lhs, + EnclosingExpr const& rhs) { + return lhs.Prefix == rhs.Prefix + && lhs.Postfix == rhs.Postfix + && lhs.Infix->equals(rhs.Infix); + } }; class CastExpr : public Node { @@ -1880,6 +2240,13 @@ From->printAsOperand(OB); OB.printClose(); } + + friend bool operator==(CastExpr const& lhs, + CastExpr const& rhs) { + return lhs.CastKind == rhs.CastKind + && lhs.To->equals(rhs.To) + && lhs.From->equals(rhs.From); + } }; class SizeofParamPackExpr : public Node { @@ -1898,6 +2265,11 @@ PPE.printLeft(OB); OB.printClose(); } + + friend bool operator==(SizeofParamPackExpr const& lhs, + SizeofParamPackExpr const& rhs) { + return lhs.Pack->equals(rhs.Pack); + } }; class CallExpr : public Node { @@ -1918,6 +2290,12 @@ Args.printWithComma(OB); OB.printClose(); } + + friend bool operator==(CallExpr const& lhs, + CallExpr const& rhs) { + return lhs.Callee->equals(rhs.Callee) + && lhs.Args == rhs.Args; + } }; class NewExpr : public Node { @@ -1956,6 +2334,15 @@ OB.printClose(); } } + + friend bool operator==(NewExpr const& lhs, + NewExpr const& rhs) { + return lhs.IsGlobal == rhs.IsGlobal + && lhs.IsArray == rhs.IsArray + && lhs.Type->equals(rhs.Type) + && lhs.ExprList == rhs.ExprList + && lhs.InitList == rhs.InitList; + } }; class DeleteExpr : public Node { @@ -1981,6 +2368,13 @@ OB += ' '; Op->print(OB); } + + friend bool operator==(DeleteExpr const& lhs, + DeleteExpr const& rhs) { + return lhs.IsGlobal == rhs.IsGlobal + && lhs.IsArray == rhs.IsArray + && lhs.Op->equals(rhs.Op); + } }; class PrefixExpr : public Node { @@ -1999,6 +2393,12 @@ OB += Prefix; Child->printAsOperand(OB, getPrecedence()); } + + friend bool operator==(PrefixExpr const& lhs, + PrefixExpr const& rhs) { + return lhs.Prefix == rhs.Prefix + && lhs.Child->equals(rhs.Child); + } }; class FunctionParam : public Node { @@ -2013,6 +2413,11 @@ OB += "fp"; OB += Number; } + + friend bool operator==(FunctionParam const& lhs, + FunctionParam const& rhs) { + return lhs.Number == rhs.Number; + } }; class ConversionExpr : public Node { @@ -2035,6 +2440,12 @@ Expressions.printWithComma(OB); OB.printClose(); } + + friend bool operator==(ConversionExpr const& lhs, + ConversionExpr const& rhs) { + return lhs.Type->equals(rhs.Type) + && lhs.Expressions == rhs.Expressions; + } }; class PointerToMemberConversionExpr : public Node { @@ -2060,6 +2471,13 @@ SubExpr->print(OB); OB.printClose(); } + + friend bool operator==(PointerToMemberConversionExpr const& lhs, + PointerToMemberConversionExpr const& rhs) { + return lhs.Offset == rhs.Offset + && lhs.Type->equals(rhs.Type) + && lhs.SubExpr->equals(rhs.SubExpr); + } }; class InitListExpr : public Node { @@ -2078,6 +2496,12 @@ Inits.printWithComma(OB); OB += '}'; } + + friend bool operator==(InitListExpr const& lhs, + InitListExpr const& rhs) { + return lhs.Ty->equals(rhs.Ty) + && lhs.Inits == rhs.Inits; + } }; class BracedExpr : public Node { @@ -2103,6 +2527,13 @@ OB += " = "; Init->print(OB); } + + friend bool operator==(BracedExpr const& lhs, + BracedExpr const& rhs) { + return lhs.IsArray == rhs.IsArray + && lhs.Elem->equals(rhs.Elem) + && lhs.Init->equals(rhs.Init); + } }; class BracedRangeExpr : public Node { @@ -2125,6 +2556,13 @@ OB += " = "; Init->print(OB); } + + friend bool operator==(BracedRangeExpr const& lhs, + BracedRangeExpr const& rhs) { + return lhs.First->equals(rhs.First) + && lhs.Last->equals(rhs.Last) + && lhs.Init->equals(rhs.Init); + } }; class FoldExpr : public Node { @@ -2172,6 +2610,14 @@ } OB.printClose(); } + + friend bool operator==(FoldExpr const& lhs, + FoldExpr const& rhs) { + return lhs.IsLeftFold == rhs.IsLeftFold + && lhs.OperatorName == rhs.OperatorName + && lhs.Pack->equals(rhs.Pack) + && lhs.Init->equals(rhs.Init); + } }; class ThrowExpr : public Node { @@ -2186,6 +2632,11 @@ OB += "throw "; Op->print(OB); } + + friend bool operator==(ThrowExpr const& lhs, + ThrowExpr const& rhs) { + return lhs.Op->equals(rhs.Op); + } }; class BoolExpr : public Node { @@ -2199,6 +2650,11 @@ void printLeft(OutputBuffer &OB) const override { OB += Value ? StringView("true") : StringView("false"); } + + friend bool operator==(BoolExpr const& lhs, + BoolExpr const& rhs) { + return lhs.Value == rhs.Value; + } }; class StringLiteral : public Node { @@ -2214,6 +2670,11 @@ Type->print(OB); OB += ">\""; } + + friend bool operator==(StringLiteral const& lhs, + StringLiteral const& rhs) { + return lhs.Type->equals(rhs.Type); + } }; class LambdaExpr : public Node { @@ -2230,6 +2691,11 @@ static_cast(Type)->printDeclarator(OB); OB += "{...}"; } + + friend bool operator==(LambdaExpr const& lhs, + LambdaExpr const& rhs) { + return lhs.Type->equals(rhs.Type); + } }; class EnumLiteral : public Node { @@ -2253,6 +2719,12 @@ else OB << Integer; } + + friend bool operator==(EnumLiteral const& lhs, + EnumLiteral const& rhs) { + return lhs.Integer == rhs.Integer + && lhs.Ty->equals(rhs.Ty); + } }; class IntegerLiteral : public Node { @@ -2281,6 +2753,12 @@ if (Type.size() <= 3) OB += Type; } + + friend bool operator==(IntegerLiteral const& lhs, + IntegerLiteral const& rhs) { + return lhs.Type == rhs.Type + && lhs.Value == rhs.Value; + } }; template struct FloatData; @@ -2338,6 +2816,11 @@ OB += StringView(num, num + n); } } + + friend bool operator==(FloatLiteralImpl const& lhs, + FloatLiteralImpl const& rhs) { + return lhs.Contents == rhs.Contents; + } }; using FloatLiteral = FloatLiteralImpl; diff --git a/llvm/lib/Demangle/ItaniumDemangle.cpp b/llvm/lib/Demangle/ItaniumDemangle.cpp --- a/llvm/lib/Demangle/ItaniumDemangle.cpp +++ b/llvm/lib/Demangle/ItaniumDemangle.cpp @@ -58,6 +58,22 @@ return first; } +bool Node::equals(Node const* Other) const { + assert(Other != nullptr); + + if (K != Other->getKind()) + return false; + + switch (K) { +#define NODE(X) \ + case K##X: \ + return *static_cast(this) == *static_cast(Other); +#include "llvm/Demangle/ItaniumNodes.def" + } + assert(0 && "unknown mangling node kind"); +} + + #ifndef NDEBUG namespace { struct DumpVisitor {