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 @@ -28,6 +28,8 @@ #include #include +#include "llvm/Support/raw_ostream.h" + DEMANGLE_NAMESPACE_BEGIN template class PODSmallVector { @@ -221,6 +223,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 +344,25 @@ FirstElement = false; } } + + friend bool operator==(NodeArray const& LHS, NodeArray const& RHS) { + if (LHS.size() != RHS.size()) + return false; + + llvm::errs() << LHS.size() << " " << RHS.size() << '\n'; + + auto** IT1 = LHS.begin(); + auto** IT2 = RHS.begin(); + for (; IT1 != LHS.end(); ++IT1, ++IT2) + if (!(*IT1)->equals(*IT2)) + return false; + + return true; + } + + friend bool operator!=(NodeArray const& LHS, NodeArray const& RHS) { + return !(LHS == RHS); + } }; struct NodeArrayNode : Node { @@ -340,6 +372,14 @@ 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; + } + + friend bool operator!=(NodeArrayNode const& LHS, NodeArrayNode const& RHS) { + return !(LHS == RHS); + } }; class DotSuffix final : public Node { @@ -358,6 +398,14 @@ OB += Suffix; OB += ")"; } + + friend bool operator==(DotSuffix const& LHS, DotSuffix const& RHS) { + return LHS.Suffix == RHS.Suffix && LHS.Prefix->equals(RHS.Prefix); + } + + friend bool operator!=(DotSuffix const& LHS, DotSuffix const& RHS) { + return !(LHS == RHS); + } }; class VendorExtQualType final : public Node { @@ -382,6 +430,16 @@ 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); + } + + friend bool operator!=(VendorExtQualType const& LHS, VendorExtQualType const& RHS) { + return !(LHS == RHS); + } }; enum FunctionRefQual : unsigned char { @@ -442,6 +500,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 { @@ -457,6 +520,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 { @@ -473,6 +541,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 { @@ -487,6 +561,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 { @@ -507,6 +585,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 { @@ -523,6 +606,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 { @@ -542,6 +631,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 { @@ -557,6 +651,11 @@ Conditions.printWithComma(OB); OB += ']'; } + + friend bool operator==(EnableIfAttr const& LHS, + EnableIfAttr const& RHS) { + return LHS.Conditions == RHS.Conditions; + } }; class ObjCProtoName : public Node { @@ -582,6 +681,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 { @@ -626,6 +731,10 @@ Pointee->printRight(OB); } } + + friend bool operator==(PointerType const& LHS, PointerType const& RHS) { + return LHS.Pointee->equals(RHS.Pointee); + } }; enum class ReferenceKind { @@ -708,6 +817,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 { @@ -740,6 +854,11 @@ OB += ")"; MemberType->printRight(OB); } + + friend bool operator==(PointerToMemberType const& LHS, PointerToMemberType const& RHS) { + return LHS.ClassType->equals(RHS.ClassType) + && LHS.MemberType->equals(RHS.MemberType); + } }; class ArrayType final : public Node { @@ -769,6 +888,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 { @@ -829,6 +953,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 { @@ -844,6 +976,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 { @@ -860,6 +996,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 { @@ -926,6 +1067,31 @@ if (Attrs != nullptr) Attrs->print(OB); } + + friend bool operator==(FunctionEncoding const& LHS, + FunctionEncoding const& RHS) { + if (LHS.CVQuals != RHS.CVQuals) + return false; + + if (LHS.RefQual != RHS.RefQual) + return false; + + if (!!LHS.Ret != !!RHS.Ret) + return false; + + if (LHS.Ret) + if (!LHS.Ret->equals(RHS.Ret)) + return false; + + if (!!LHS.Attrs != !!RHS.Attrs) + return false; + + if (LHS.Attrs) + if (!LHS.Attrs->equals(RHS.Attrs)) + return false; + + return LHS.Params == RHS.Params; + } }; class LiteralOperator : public Node { @@ -941,6 +1107,11 @@ OB += "operator\"\" "; OpName->print(OB); } + + friend bool operator==(LiteralOperator const& LHS, + LiteralOperator const& RHS) { + return LHS.OpName->equals(RHS.OpName); + } }; class SpecialName final : public Node { @@ -957,6 +1128,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 { @@ -976,6 +1153,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 { @@ -994,6 +1177,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 { @@ -1016,6 +1205,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->equals(RHS.Parent)) + return false; + + return LHS.Name->equals(RHS.Name); + } }; struct ModuleEntity : Node { @@ -1034,6 +1238,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 { @@ -1050,6 +1260,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 { @@ -1070,6 +1285,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 { @@ -1092,6 +1313,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 { @@ -1109,6 +1336,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 { @@ -1124,6 +1356,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 }; @@ -1159,6 +1396,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'. @@ -1174,6 +1417,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'. @@ -1197,6 +1445,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, @@ -1220,6 +1474,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'. @@ -1238,6 +1498,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 @@ -1312,6 +1577,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 @@ -1332,6 +1602,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 @@ -1378,6 +1653,11 @@ Child->print(OB); } } + + friend bool operator==(ParameterPackExpansion const& LHS, + ParameterPackExpansion const& RHS) { + return LHS.Child->equals(RHS.Child); + } }; class TemplateArgs final : public Node { @@ -1396,6 +1676,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 @@ -1426,6 +1711,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), @@ -1491,6 +1792,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 { @@ -1508,6 +1815,11 @@ OB += "::"; Child->print(OB); } + + friend bool operator==(GlobalQualifiedName const& LHS, + GlobalQualifiedName const& RHS) { + return LHS.Child->equals(RHS.Child); + } }; enum class SpecialSubKind { @@ -1566,6 +1878,11 @@ OB << ">"; } } + + friend bool operator==(ExpandedSpecialSubstitution const& LHS, + ExpandedSpecialSubstitution const& RHS) { + return LHS.SSK == RHS.SSK; + } }; class SpecialSubstitution final : public ExpandedSpecialSubstitution { @@ -1611,6 +1928,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 { @@ -1625,6 +1949,11 @@ OB += "~"; Base->printLeft(OB); } + + friend bool operator==(DtorName const& LHS, + DtorName const& RHS) { + return LHS.Base->equals(RHS.Base); + } }; class UnnamedTypeName : public Node { @@ -1640,6 +1969,11 @@ OB += Count; OB += "\'"; } + + friend bool operator==(UnnamedTypeName const& LHS, + UnnamedTypeName const& RHS) { + return LHS.Count == RHS.Count; + } }; class ClosureTypeName : public Node { @@ -1675,6 +2009,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 { @@ -1690,6 +2031,11 @@ Bindings.printWithComma(OB); OB.printClose(']'); } + + friend bool operator==(StructuredBindingName const& LHS, + StructuredBindingName const& RHS) { + return LHS.Bindings == RHS.Bindings; + } }; // -- Expression Nodes -- @@ -1726,6 +2072,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 { @@ -1746,6 +2099,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 { @@ -1764,6 +2123,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 { @@ -1787,6 +2152,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 { @@ -1807,6 +2179,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 { @@ -1841,6 +2220,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 { @@ -1864,6 +2252,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 { @@ -1892,6 +2287,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 { @@ -1910,6 +2312,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 { @@ -1930,6 +2337,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 { @@ -1968,6 +2381,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 { @@ -1993,6 +2415,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 { @@ -2011,6 +2440,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 { @@ -2025,6 +2460,11 @@ OB += "fp"; OB += Number; } + + friend bool operator==(FunctionParam const& LHS, + FunctionParam const& RHS) { + return LHS.Number == RHS.Number; + } }; class ConversionExpr : public Node { @@ -2047,6 +2487,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 { @@ -2072,6 +2518,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 { @@ -2090,6 +2543,18 @@ Inits.printWithComma(OB); OB += '}'; } + + friend bool operator==(InitListExpr const& LHS, + InitListExpr const& RHS) { + if (!!LHS.Ty != !!RHS.Ty) + return false; + + if (LHS.Ty) + if (!LHS.Ty->equals(RHS.Ty)) + return false; + + return LHS.Inits == RHS.Inits; + } }; class BracedExpr : public Node { @@ -2115,6 +2580,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 { @@ -2137,6 +2609,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 { @@ -2184,6 +2663,22 @@ } OB.printClose(); } + + friend bool operator==(FoldExpr const& LHS, + FoldExpr const& RHS) { + if (LHS.IsLeftFold != RHS.IsLeftFold + || LHS.OperatorName == RHS.OperatorName) + return false; + + if (!!LHS.Pack != !!RHS.Pack) + return false; + + if (LHS.Pack) + if (!LHS.Pack->equals(RHS.Pack)) + return false; + + return LHS.Init->equals(RHS.Init); + } }; class ThrowExpr : public Node { @@ -2198,6 +2693,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 { @@ -2211,6 +2711,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 { @@ -2226,6 +2731,11 @@ Type->print(OB); OB += ">\""; } + + friend bool operator==(StringLiteral const& LHS, + StringLiteral const& RHS) { + return LHS.Type->equals(RHS.Type); + } }; class LambdaExpr : public Node { @@ -2242,6 +2752,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 { @@ -2265,6 +2780,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 { @@ -2293,6 +2814,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; @@ -2350,6 +2877,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 @@ -12,6 +12,7 @@ #include "llvm/Demangle/Demangle.h" #include "llvm/Demangle/ItaniumDemangle.h" +#include "llvm/Support/raw_ostream.h" #include #include @@ -58,6 +59,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 {