Changeset View
Changeset View
Standalone View
Standalone View
libcxxabi/src/demangle/ItaniumDemangle.h
Show First 20 Lines • Show All 215 Lines • ▼ Show 20 Lines | public: | ||||
Node(Kind K_, Cache RHSComponentCache_, Cache ArrayCache_ = Cache::No, | Node(Kind K_, Cache RHSComponentCache_, Cache ArrayCache_ = Cache::No, | ||||
Cache FunctionCache_ = Cache::No) | Cache FunctionCache_ = Cache::No) | ||||
: Node(K_, Prec::Primary, RHSComponentCache_, ArrayCache_, | : Node(K_, Prec::Primary, RHSComponentCache_, ArrayCache_, | ||||
FunctionCache_) {} | FunctionCache_) {} | ||||
/// Visit the most-derived object corresponding to this object. | /// Visit the most-derived object corresponding to this object. | ||||
template<typename Fn> void visit(Fn F) const; | template<typename Fn> 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: | // The following function is provided by all derived classes: | ||||
// | // | ||||
// Call F with arguments that, when passed to the constructor of this node, | // Call F with arguments that, when passed to the constructor of this node, | ||||
// would construct an equivalent node. | // would construct an equivalent node. | ||||
//template<typename Fn> void match(Fn F) const; | //template<typename Fn> void match(Fn F) const; | ||||
bool hasRHSComponent(OutputBuffer &OB) const { | bool hasRHSComponent(OutputBuffer &OB) const { | ||||
if (RHSComponentCache != Cache::Unknown) | if (RHSComponentCache != Cache::Unknown) | ||||
▲ Show 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | for (size_t Idx = 0; Idx != NumElements; ++Idx) { | ||||
if (AfterComma == OB.getCurrentPosition()) { | if (AfterComma == OB.getCurrentPosition()) { | ||||
OB.setCurrentPosition(BeforeComma); | OB.setCurrentPosition(BeforeComma); | ||||
continue; | continue; | ||||
} | } | ||||
FirstElement = false; | 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, ++IT2) | |||||
if (!(*IT1)->equals(*IT2)) | |||||
return false; | |||||
return true; | |||||
} | |||||
friend bool operator!=(NodeArray const &LHS, NodeArray const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
struct NodeArrayNode : Node { | struct NodeArrayNode : Node { | ||||
NodeArray Array; | NodeArray Array; | ||||
NodeArrayNode(NodeArray Array_) : Node(KNodeArrayNode), Array(Array_) {} | NodeArrayNode(NodeArray Array_) : Node(KNodeArrayNode), Array(Array_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Array); } | template<typename Fn> void match(Fn F) const { F(Array); } | ||||
void printLeft(OutputBuffer &OB) const override { Array.printWithComma(OB); } | 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 { | class DotSuffix final : public Node { | ||||
const Node *Prefix; | const Node *Prefix; | ||||
const StringView Suffix; | const StringView Suffix; | ||||
public: | public: | ||||
DotSuffix(const Node *Prefix_, StringView Suffix_) | DotSuffix(const Node *Prefix_, StringView Suffix_) | ||||
: Node(KDotSuffix), Prefix(Prefix_), Suffix(Suffix_) {} | : Node(KDotSuffix), Prefix(Prefix_), Suffix(Suffix_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Prefix, Suffix); } | template<typename Fn> void match(Fn F) const { F(Prefix, Suffix); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
Prefix->print(OB); | Prefix->print(OB); | ||||
OB += " ("; | OB += " ("; | ||||
OB += Suffix; | OB += Suffix; | ||||
OB += ")"; | OB += ")"; | ||||
} | } | ||||
friend bool operator==(DotSuffix const &LHS, DotSuffix const &RHS) { | |||||
assert(LHS.Prefix != nullptr); | |||||
assert(RHS.Prefix != nullptr); | |||||
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 { | class VendorExtQualType final : public Node { | ||||
const Node *Ty; | const Node *Ty; | ||||
StringView Ext; | StringView Ext; | ||||
const Node *TA; | const Node *TA; | ||||
public: | public: | ||||
VendorExtQualType(const Node *Ty_, StringView Ext_, const Node *TA_) | VendorExtQualType(const Node *Ty_, StringView Ext_, const Node *TA_) | ||||
: Node(KVendorExtQualType), Ty(Ty_), Ext(Ext_), TA(TA_) {} | : Node(KVendorExtQualType), Ty(Ty_), Ext(Ext_), TA(TA_) {} | ||||
const Node *getTy() const { return Ty; } | |||||
StringView getExt() const { return Ext; } | |||||
const Node *getTA() const { return TA; } | |||||
template <typename Fn> void match(Fn F) const { F(Ty, Ext, TA); } | template <typename Fn> void match(Fn F) const { F(Ty, Ext, TA); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
Ty->print(OB); | Ty->print(OB); | ||||
OB += " "; | OB += " "; | ||||
OB += Ext; | OB += Ext; | ||||
if (TA != nullptr) | if (TA != nullptr) | ||||
TA->print(OB); | TA->print(OB); | ||||
} | } | ||||
friend bool operator==(VendorExtQualType const &LHS, | |||||
VendorExtQualType const &RHS) { | |||||
assert(LHS.Ty != nullptr); | |||||
assert(RHS.Ty != nullptr); | |||||
if (!(LHS.Ext == RHS.Ext)) | |||||
return false; | |||||
if (!LHS.Ty->equals(RHS.Ty)) | |||||
return false; | |||||
if (LHS.TA != nullptr && RHS.TA != nullptr) | |||||
return LHS.TA->equals(RHS.TA); | |||||
return LHS.TA == nullptr && RHS.TA == nullptr; | |||||
} | |||||
friend bool operator!=(VendorExtQualType const &LHS, | |||||
VendorExtQualType const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
enum FunctionRefQual : unsigned char { | enum FunctionRefQual : unsigned char { | ||||
FrefQualNone, | FrefQualNone, | ||||
FrefQualLValue, | FrefQualLValue, | ||||
FrefQualRValue, | FrefQualRValue, | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | public: | ||||
} | } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
Child->printLeft(OB); | Child->printLeft(OB); | ||||
printQuals(OB); | printQuals(OB); | ||||
} | } | ||||
void printRight(OutputBuffer &OB) const override { Child->printRight(OB); } | void printRight(OutputBuffer &OB) const override { Child->printRight(OB); } | ||||
friend bool operator==(QualType const &LHS, QualType const &RHS) { | |||||
assert(LHS.Child != nullptr); | |||||
assert(RHS.Child != nullptr); | |||||
return LHS.Quals == RHS.Quals && LHS.Child->equals(RHS.Child); | |||||
} | |||||
friend bool operator!=(QualType const &LHS, QualType const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class ConversionOperatorType final : public Node { | class ConversionOperatorType final : public Node { | ||||
const Node *Ty; | const Node *Ty; | ||||
public: | public: | ||||
ConversionOperatorType(const Node *Ty_) | ConversionOperatorType(const Node *Ty_) | ||||
: Node(KConversionOperatorType), Ty(Ty_) {} | : Node(KConversionOperatorType), Ty(Ty_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Ty); } | template<typename Fn> void match(Fn F) const { F(Ty); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB += "operator "; | OB += "operator "; | ||||
Ty->print(OB); | Ty->print(OB); | ||||
} | } | ||||
friend bool operator==(ConversionOperatorType const &LHS, | |||||
ConversionOperatorType const &RHS) { | |||||
return LHS.Ty->equals(RHS.Ty); | |||||
} | |||||
friend bool operator!=(ConversionOperatorType const &LHS, | |||||
ConversionOperatorType const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class PostfixQualifiedType final : public Node { | class PostfixQualifiedType final : public Node { | ||||
const Node *Ty; | const Node *Ty; | ||||
const StringView Postfix; | const StringView Postfix; | ||||
public: | public: | ||||
PostfixQualifiedType(const Node *Ty_, StringView Postfix_) | PostfixQualifiedType(const Node *Ty_, StringView Postfix_) | ||||
: Node(KPostfixQualifiedType), Ty(Ty_), Postfix(Postfix_) {} | : Node(KPostfixQualifiedType), Ty(Ty_), Postfix(Postfix_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Ty, Postfix); } | template<typename Fn> void match(Fn F) const { F(Ty, Postfix); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
Ty->printLeft(OB); | Ty->printLeft(OB); | ||||
OB += Postfix; | OB += Postfix; | ||||
} | } | ||||
friend bool operator==(PostfixQualifiedType const &LHS, | |||||
PostfixQualifiedType const &RHS) { | |||||
return LHS.Postfix == RHS.Postfix && LHS.Ty->equals(RHS.Ty); | |||||
} | |||||
friend bool operator!=(PostfixQualifiedType const &LHS, | |||||
PostfixQualifiedType const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class NameType final : public Node { | class NameType final : public Node { | ||||
const StringView Name; | const StringView Name; | ||||
public: | public: | ||||
NameType(StringView Name_) : Node(KNameType), Name(Name_) {} | NameType(StringView Name_) : Node(KNameType), Name(Name_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Name); } | template<typename Fn> void match(Fn F) const { F(Name); } | ||||
StringView getName() const { return Name; } | StringView getName() const { return Name; } | ||||
StringView getBaseName() const override { return Name; } | StringView getBaseName() const override { return Name; } | ||||
void printLeft(OutputBuffer &OB) const override { OB += Name; } | void printLeft(OutputBuffer &OB) const override { OB += Name; } | ||||
friend bool operator==(NameType const &LHS, NameType const &RHS) { | |||||
return LHS.Name == RHS.Name; | |||||
} | |||||
friend bool operator!=(NameType const &LHS, NameType const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class BitIntType final : public Node { | class BitIntType final : public Node { | ||||
const Node *Size; | const Node *Size; | ||||
bool Signed; | bool Signed; | ||||
public: | public: | ||||
BitIntType(const Node *Size_, bool Signed_) | BitIntType(const Node *Size_, bool Signed_) | ||||
: Node(KBitIntType), Size(Size_), Signed(Signed_) {} | : Node(KBitIntType), Size(Size_), Signed(Signed_) {} | ||||
template <typename Fn> void match(Fn F) const { F(Size, Signed); } | template <typename Fn> void match(Fn F) const { F(Size, Signed); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
if (!Signed) | if (!Signed) | ||||
OB += "unsigned "; | OB += "unsigned "; | ||||
OB += "_BitInt"; | OB += "_BitInt"; | ||||
OB.printOpen(); | OB.printOpen(); | ||||
Size->printAsOperand(OB); | Size->printAsOperand(OB); | ||||
OB.printClose(); | OB.printClose(); | ||||
} | } | ||||
friend bool operator==(BitIntType const &LHS, BitIntType const &RHS) { | |||||
return LHS.Signed == RHS.Signed && LHS.Size->equals(RHS.Size); | |||||
} | |||||
friend bool operator!=(BitIntType const &LHS, BitIntType const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class ElaboratedTypeSpefType : public Node { | class ElaboratedTypeSpefType : public Node { | ||||
StringView Kind; | StringView Kind; | ||||
Node *Child; | Node *Child; | ||||
public: | public: | ||||
ElaboratedTypeSpefType(StringView Kind_, Node *Child_) | ElaboratedTypeSpefType(StringView Kind_, Node *Child_) | ||||
: Node(KElaboratedTypeSpefType), Kind(Kind_), Child(Child_) {} | : Node(KElaboratedTypeSpefType), Kind(Kind_), Child(Child_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Kind, Child); } | template<typename Fn> void match(Fn F) const { F(Kind, Child); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB += Kind; | OB += Kind; | ||||
OB += ' '; | OB += ' '; | ||||
Child->print(OB); | Child->print(OB); | ||||
} | } | ||||
friend bool operator==(ElaboratedTypeSpefType const &LHS, | |||||
ElaboratedTypeSpefType const &RHS) { | |||||
return LHS.Kind == RHS.Kind && LHS.Child->equals(RHS.Child); | |||||
} | |||||
friend bool operator!=(ElaboratedTypeSpefType const &LHS, | |||||
ElaboratedTypeSpefType const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
struct AbiTagAttr : Node { | struct AbiTagAttr : Node { | ||||
Node *Base; | Node *Base; | ||||
StringView Tag; | StringView Tag; | ||||
AbiTagAttr(Node* Base_, StringView Tag_) | AbiTagAttr(Node* Base_, StringView Tag_) | ||||
: Node(KAbiTagAttr, Base_->RHSComponentCache, | : Node(KAbiTagAttr, Base_->RHSComponentCache, | ||||
Base_->ArrayCache, Base_->FunctionCache), | Base_->ArrayCache, Base_->FunctionCache), | ||||
Base(Base_), Tag(Tag_) {} | Base(Base_), Tag(Tag_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Base, Tag); } | template<typename Fn> void match(Fn F) const { F(Base, Tag); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
Base->printLeft(OB); | Base->printLeft(OB); | ||||
OB += "[abi:"; | OB += "[abi:"; | ||||
OB += Tag; | OB += Tag; | ||||
OB += "]"; | OB += "]"; | ||||
} | } | ||||
friend bool operator==(AbiTagAttr const &LHS, AbiTagAttr const &RHS) { | |||||
return LHS.Tag == RHS.Tag && LHS.Base->equals(RHS.Base); | |||||
} | |||||
friend bool operator!=(AbiTagAttr const &LHS, AbiTagAttr const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class EnableIfAttr : public Node { | class EnableIfAttr : public Node { | ||||
NodeArray Conditions; | NodeArray Conditions; | ||||
public: | public: | ||||
EnableIfAttr(NodeArray Conditions_) | EnableIfAttr(NodeArray Conditions_) | ||||
: Node(KEnableIfAttr), Conditions(Conditions_) {} | : Node(KEnableIfAttr), Conditions(Conditions_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Conditions); } | template<typename Fn> void match(Fn F) const { F(Conditions); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB += " [enable_if:"; | OB += " [enable_if:"; | ||||
Conditions.printWithComma(OB); | Conditions.printWithComma(OB); | ||||
OB += ']'; | OB += ']'; | ||||
} | } | ||||
friend bool operator==(EnableIfAttr const &LHS, EnableIfAttr const &RHS) { | |||||
return LHS.Conditions == RHS.Conditions; | |||||
} | |||||
friend bool operator!=(EnableIfAttr const &LHS, EnableIfAttr const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class ObjCProtoName : public Node { | class ObjCProtoName : public Node { | ||||
const Node *Ty; | const Node *Ty; | ||||
StringView Protocol; | StringView Protocol; | ||||
friend class PointerType; | friend class PointerType; | ||||
Show All 9 Lines | public: | ||||
} | } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
Ty->print(OB); | Ty->print(OB); | ||||
OB += "<"; | OB += "<"; | ||||
OB += Protocol; | OB += Protocol; | ||||
OB += ">"; | OB += ">"; | ||||
} | } | ||||
friend bool operator==(ObjCProtoName const &LHS, ObjCProtoName const &RHS) { | |||||
return LHS.Protocol == RHS.Protocol && LHS.Ty->equals(RHS.Ty); | |||||
} | |||||
friend bool operator!=(ObjCProtoName const &LHS, ObjCProtoName const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class PointerType final : public Node { | class PointerType final : public Node { | ||||
const Node *Pointee; | const Node *Pointee; | ||||
public: | public: | ||||
PointerType(const Node *Pointee_) | PointerType(const Node *Pointee_) | ||||
: Node(KPointerType, Pointee_->RHSComponentCache), | : Node(KPointerType, Pointee_->RHSComponentCache), | ||||
Pointee(Pointee_) {} | Pointee(Pointee_) {} | ||||
const Node *getPointee() const { return Pointee; } | |||||
template<typename Fn> void match(Fn F) const { F(Pointee); } | template<typename Fn> void match(Fn F) const { F(Pointee); } | ||||
bool hasRHSComponentSlow(OutputBuffer &OB) const override { | bool hasRHSComponentSlow(OutputBuffer &OB) const override { | ||||
return Pointee->hasRHSComponent(OB); | return Pointee->hasRHSComponent(OB); | ||||
} | } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
// We rewrite objc_object<SomeProtocol>* into id<SomeProtocol>. | // We rewrite objc_object<SomeProtocol>* into id<SomeProtocol>. | ||||
Show All 16 Lines | public: | ||||
void printRight(OutputBuffer &OB) const override { | void printRight(OutputBuffer &OB) const override { | ||||
if (Pointee->getKind() != KObjCProtoName || | if (Pointee->getKind() != KObjCProtoName || | ||||
!static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) { | !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) { | ||||
if (Pointee->hasArray(OB) || Pointee->hasFunction(OB)) | if (Pointee->hasArray(OB) || Pointee->hasFunction(OB)) | ||||
OB += ")"; | OB += ")"; | ||||
Pointee->printRight(OB); | Pointee->printRight(OB); | ||||
} | } | ||||
} | } | ||||
friend bool operator==(PointerType const &LHS, PointerType const &RHS) { | |||||
return LHS.Pointee->equals(RHS.Pointee); | |||||
} | |||||
friend bool operator!=(PointerType const &LHS, PointerType const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
enum class ReferenceKind { | enum class ReferenceKind { | ||||
LValue, | LValue, | ||||
RValue, | RValue, | ||||
}; | }; | ||||
// Represents either a LValue or an RValue reference type. | // Represents either a LValue or an RValue reference type. | ||||
▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | void printRight(OutputBuffer &OB) const override { | ||||
ScopedOverride<bool> SavePrinting(Printing, true); | ScopedOverride<bool> SavePrinting(Printing, true); | ||||
std::pair<ReferenceKind, const Node *> Collapsed = collapse(OB); | std::pair<ReferenceKind, const Node *> Collapsed = collapse(OB); | ||||
if (!Collapsed.second) | if (!Collapsed.second) | ||||
return; | return; | ||||
if (Collapsed.second->hasArray(OB) || Collapsed.second->hasFunction(OB)) | if (Collapsed.second->hasArray(OB) || Collapsed.second->hasFunction(OB)) | ||||
OB += ")"; | OB += ")"; | ||||
Collapsed.second->printRight(OB); | Collapsed.second->printRight(OB); | ||||
} | } | ||||
friend bool operator==(ReferenceType const &LHS, ReferenceType const &RHS) { | |||||
return LHS.RK == RHS.RK && LHS.Pointee->equals(RHS.Pointee); | |||||
} | |||||
friend bool operator!=(ReferenceType const &LHS, ReferenceType const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class PointerToMemberType final : public Node { | class PointerToMemberType final : public Node { | ||||
const Node *ClassType; | const Node *ClassType; | ||||
const Node *MemberType; | const Node *MemberType; | ||||
public: | public: | ||||
PointerToMemberType(const Node *ClassType_, const Node *MemberType_) | PointerToMemberType(const Node *ClassType_, const Node *MemberType_) | ||||
Show All 16 Lines | void printLeft(OutputBuffer &OB) const override { | ||||
OB += "::*"; | OB += "::*"; | ||||
} | } | ||||
void printRight(OutputBuffer &OB) const override { | void printRight(OutputBuffer &OB) const override { | ||||
if (MemberType->hasArray(OB) || MemberType->hasFunction(OB)) | if (MemberType->hasArray(OB) || MemberType->hasFunction(OB)) | ||||
OB += ")"; | OB += ")"; | ||||
MemberType->printRight(OB); | MemberType->printRight(OB); | ||||
} | } | ||||
friend bool operator==(PointerToMemberType const &LHS, | |||||
PointerToMemberType const &RHS) { | |||||
return LHS.ClassType->equals(RHS.ClassType) && | |||||
LHS.MemberType->equals(RHS.MemberType); | |||||
} | |||||
friend bool operator!=(PointerToMemberType const &LHS, | |||||
PointerToMemberType const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class ArrayType final : public Node { | class ArrayType final : public Node { | ||||
const Node *Base; | const Node *Base; | ||||
Node *Dimension; | Node *Dimension; | ||||
public: | public: | ||||
ArrayType(const Node *Base_, Node *Dimension_) | ArrayType(const Node *Base_, Node *Dimension_) | ||||
Show All 13 Lines | void printRight(OutputBuffer &OB) const override { | ||||
if (OB.back() != ']') | if (OB.back() != ']') | ||||
OB += " "; | OB += " "; | ||||
OB += "["; | OB += "["; | ||||
if (Dimension) | if (Dimension) | ||||
Dimension->print(OB); | Dimension->print(OB); | ||||
OB += "]"; | OB += "]"; | ||||
Base->printRight(OB); | Base->printRight(OB); | ||||
} | } | ||||
friend bool operator==(ArrayType const &LHS, ArrayType const &RHS) { | |||||
return LHS.Base->equals(RHS.Base) && LHS.Dimension->equals(RHS.Dimension); | |||||
} | |||||
friend bool operator!=(ArrayType const &LHS, ArrayType const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class FunctionType final : public Node { | class FunctionType final : public Node { | ||||
const Node *Ret; | const Node *Ret; | ||||
NodeArray Params; | NodeArray Params; | ||||
Qualifiers CVQuals; | Qualifiers CVQuals; | ||||
FunctionRefQual RefQual; | FunctionRefQual RefQual; | ||||
const Node *ExceptionSpec; | const Node *ExceptionSpec; | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | void printRight(OutputBuffer &OB) const override { | ||||
else if (RefQual == FrefQualRValue) | else if (RefQual == FrefQualRValue) | ||||
OB += " &&"; | OB += " &&"; | ||||
if (ExceptionSpec != nullptr) { | if (ExceptionSpec != nullptr) { | ||||
OB += ' '; | OB += ' '; | ||||
ExceptionSpec->print(OB); | 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); | |||||
} | |||||
friend bool operator!=(FunctionType const &LHS, FunctionType const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class NoexceptSpec : public Node { | class NoexceptSpec : public Node { | ||||
const Node *E; | const Node *E; | ||||
public: | public: | ||||
NoexceptSpec(const Node *E_) : Node(KNoexceptSpec), E(E_) {} | NoexceptSpec(const Node *E_) : Node(KNoexceptSpec), E(E_) {} | ||||
template<typename Fn> void match(Fn F) const { F(E); } | template<typename Fn> void match(Fn F) const { F(E); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB += "noexcept"; | OB += "noexcept"; | ||||
OB.printOpen(); | OB.printOpen(); | ||||
E->printAsOperand(OB); | E->printAsOperand(OB); | ||||
OB.printClose(); | OB.printClose(); | ||||
} | } | ||||
friend bool operator==(NoexceptSpec const &LHS, NoexceptSpec const &RHS) { | |||||
return LHS.E->equals(RHS.E); | |||||
} | |||||
friend bool operator!=(NoexceptSpec const &LHS, NoexceptSpec const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class DynamicExceptionSpec : public Node { | class DynamicExceptionSpec : public Node { | ||||
NodeArray Types; | NodeArray Types; | ||||
public: | public: | ||||
DynamicExceptionSpec(NodeArray Types_) | DynamicExceptionSpec(NodeArray Types_) | ||||
: Node(KDynamicExceptionSpec), Types(Types_) {} | : Node(KDynamicExceptionSpec), Types(Types_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Types); } | template<typename Fn> void match(Fn F) const { F(Types); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB += "throw"; | OB += "throw"; | ||||
OB.printOpen(); | OB.printOpen(); | ||||
Types.printWithComma(OB); | Types.printWithComma(OB); | ||||
OB.printClose(); | OB.printClose(); | ||||
} | } | ||||
friend bool operator==(DynamicExceptionSpec const &LHS, | |||||
DynamicExceptionSpec const &RHS) { | |||||
return LHS.Types == RHS.Types; | |||||
} | |||||
friend bool operator!=(DynamicExceptionSpec const &LHS, | |||||
DynamicExceptionSpec const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class FunctionEncoding final : public Node { | class FunctionEncoding final : public Node { | ||||
const Node *Ret; | const Node *Ret; | ||||
const Node *Name; | const Node *Name; | ||||
NodeArray Params; | NodeArray Params; | ||||
const Node *Attrs; | const Node *Attrs; | ||||
Qualifiers CVQuals; | Qualifiers CVQuals; | ||||
▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | void printRight(OutputBuffer &OB) const override { | ||||
if (RefQual == FrefQualLValue) | if (RefQual == FrefQualLValue) | ||||
OB += " &"; | OB += " &"; | ||||
else if (RefQual == FrefQualRValue) | else if (RefQual == FrefQualRValue) | ||||
OB += " &&"; | OB += " &&"; | ||||
if (Attrs != nullptr) | if (Attrs != nullptr) | ||||
Attrs->print(OB); | Attrs->print(OB); | ||||
} | } | ||||
friend bool operator==(FunctionEncoding const &LHS, | |||||
FunctionEncoding const &RHS) { | |||||
assert(LHS.Name != nullptr); | |||||
assert(RHS.Name != nullptr); | |||||
if (LHS.CVQuals != RHS.CVQuals) | |||||
return false; | |||||
if (LHS.RefQual != RHS.RefQual) | |||||
return false; | |||||
if (!LHS.Name->equals(RHS.Name)) | |||||
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; | |||||
} | |||||
friend bool operator!=(FunctionEncoding const &LHS, | |||||
FunctionEncoding const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class LiteralOperator : public Node { | class LiteralOperator : public Node { | ||||
const Node *OpName; | const Node *OpName; | ||||
public: | public: | ||||
LiteralOperator(const Node *OpName_) | LiteralOperator(const Node *OpName_) | ||||
: Node(KLiteralOperator), OpName(OpName_) {} | : Node(KLiteralOperator), OpName(OpName_) {} | ||||
template<typename Fn> void match(Fn F) const { F(OpName); } | template<typename Fn> void match(Fn F) const { F(OpName); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB += "operator\"\" "; | OB += "operator\"\" "; | ||||
OpName->print(OB); | OpName->print(OB); | ||||
} | } | ||||
friend bool operator==(LiteralOperator const &LHS, | |||||
LiteralOperator const &RHS) { | |||||
assert(LHS.OpName != nullptr); | |||||
assert(RHS.OpName != nullptr); | |||||
return LHS.OpName->equals(RHS.OpName); | |||||
} | |||||
friend bool operator!=(LiteralOperator const &LHS, | |||||
LiteralOperator const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class SpecialName final : public Node { | class SpecialName final : public Node { | ||||
const StringView Special; | const StringView Special; | ||||
const Node *Child; | const Node *Child; | ||||
public: | public: | ||||
SpecialName(StringView Special_, const Node *Child_) | SpecialName(StringView Special_, const Node *Child_) | ||||
: Node(KSpecialName), Special(Special_), Child(Child_) {} | : Node(KSpecialName), Special(Special_), Child(Child_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Special, Child); } | template<typename Fn> void match(Fn F) const { F(Special, Child); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB += Special; | OB += Special; | ||||
Child->print(OB); | Child->print(OB); | ||||
} | } | ||||
friend bool operator==(SpecialName const &LHS, SpecialName const &RHS) { | |||||
assert(LHS.Child != nullptr); | |||||
assert(RHS.Child != nullptr); | |||||
return LHS.Special == RHS.Special && LHS.Child->equals(RHS.Child); | |||||
} | |||||
friend bool operator!=(SpecialName const &LHS, SpecialName const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class CtorVtableSpecialName final : public Node { | class CtorVtableSpecialName final : public Node { | ||||
const Node *FirstType; | const Node *FirstType; | ||||
const Node *SecondType; | const Node *SecondType; | ||||
public: | public: | ||||
CtorVtableSpecialName(const Node *FirstType_, const Node *SecondType_) | CtorVtableSpecialName(const Node *FirstType_, const Node *SecondType_) | ||||
: Node(KCtorVtableSpecialName), | : Node(KCtorVtableSpecialName), | ||||
FirstType(FirstType_), SecondType(SecondType_) {} | FirstType(FirstType_), SecondType(SecondType_) {} | ||||
template<typename Fn> void match(Fn F) const { F(FirstType, SecondType); } | template<typename Fn> void match(Fn F) const { F(FirstType, SecondType); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB += "construction vtable for "; | OB += "construction vtable for "; | ||||
FirstType->print(OB); | FirstType->print(OB); | ||||
OB += "-in-"; | OB += "-in-"; | ||||
SecondType->print(OB); | SecondType->print(OB); | ||||
} | } | ||||
friend bool operator==(CtorVtableSpecialName const &LHS, | |||||
CtorVtableSpecialName const &RHS) { | |||||
assert(LHS.FirstType != nullptr); | |||||
assert(RHS.FirstType != nullptr); | |||||
assert(LHS.SecondType != nullptr); | |||||
assert(RHS.SecondType != nullptr); | |||||
return LHS.FirstType->equals(RHS.FirstType) && | |||||
LHS.SecondType->equals(RHS.SecondType); | |||||
} | |||||
friend bool operator!=(CtorVtableSpecialName const &LHS, | |||||
CtorVtableSpecialName const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
struct NestedName : Node { | struct NestedName : Node { | ||||
Node *Qual; | Node *Qual; | ||||
Node *Name; | Node *Name; | ||||
NestedName(Node *Qual_, Node *Name_) | NestedName(Node *Qual_, Node *Name_) | ||||
: Node(KNestedName), Qual(Qual_), Name(Name_) {} | : Node(KNestedName), Qual(Qual_), Name(Name_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Qual, Name); } | template<typename Fn> void match(Fn F) const { F(Qual, Name); } | ||||
StringView getBaseName() const override { return Name->getBaseName(); } | StringView getBaseName() const override { return Name->getBaseName(); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
Qual->print(OB); | Qual->print(OB); | ||||
OB += "::"; | OB += "::"; | ||||
Name->print(OB); | Name->print(OB); | ||||
} | } | ||||
friend bool operator==(NestedName const &LHS, NestedName const &RHS) { | |||||
assert(LHS.Qual != nullptr); | |||||
assert(RHS.Qual != nullptr); | |||||
assert(LHS.Name != nullptr); | |||||
assert(RHS.Name != nullptr); | |||||
return LHS.Qual->equals(RHS.Qual) && LHS.Name->equals(RHS.Name); | |||||
} | |||||
friend bool operator!=(NestedName const &LHS, NestedName const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
struct ModuleName : Node { | struct ModuleName : Node { | ||||
ModuleName *Parent; | ModuleName *Parent; | ||||
Node *Name; | Node *Name; | ||||
bool IsPartition; | bool IsPartition; | ||||
ModuleName(ModuleName *Parent_, Node *Name_, bool IsPartition_ = false) | ModuleName(ModuleName *Parent_, Node *Name_, bool IsPartition_ = false) | ||||
: Node(KModuleName), Parent(Parent_), Name(Name_), | : Node(KModuleName), Parent(Parent_), Name(Name_), | ||||
IsPartition(IsPartition_) {} | IsPartition(IsPartition_) {} | ||||
template <typename Fn> void match(Fn F) const { | template <typename Fn> void match(Fn F) const { | ||||
F(Parent, Name, IsPartition); | F(Parent, Name, IsPartition); | ||||
} | } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
if (Parent) | if (Parent) | ||||
Parent->print(OB); | Parent->print(OB); | ||||
if (Parent || IsPartition) | if (Parent || IsPartition) | ||||
OB += IsPartition ? ':' : '.'; | OB += IsPartition ? ':' : '.'; | ||||
Name->print(OB); | Name->print(OB); | ||||
} | } | ||||
friend bool operator==(ModuleName const &LHS, ModuleName const &RHS) { | |||||
assert(LHS.Name != nullptr); | |||||
assert(RHS.Name != nullptr); | |||||
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); | |||||
} | |||||
friend bool operator!=(ModuleName const &LHS, ModuleName const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
struct ModuleEntity : Node { | struct ModuleEntity : Node { | ||||
ModuleName *Module; | ModuleName *Module; | ||||
Node *Name; | Node *Name; | ||||
ModuleEntity(ModuleName *Module_, Node *Name_) | ModuleEntity(ModuleName *Module_, Node *Name_) | ||||
: Node(KModuleEntity), Module(Module_), Name(Name_) {} | : Node(KModuleEntity), Module(Module_), Name(Name_) {} | ||||
template <typename Fn> void match(Fn F) const { F(Module, Name); } | template <typename Fn> void match(Fn F) const { F(Module, Name); } | ||||
StringView getBaseName() const override { return Name->getBaseName(); } | StringView getBaseName() const override { return Name->getBaseName(); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
Name->print(OB); | Name->print(OB); | ||||
OB += '@'; | OB += '@'; | ||||
Module->print(OB); | Module->print(OB); | ||||
} | } | ||||
friend bool operator==(ModuleEntity const &LHS, ModuleEntity const &RHS) { | |||||
return LHS.Module->equals(RHS.Module) && LHS.Name->equals(RHS.Name); | |||||
} | |||||
friend bool operator!=(ModuleEntity const &LHS, ModuleEntity const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
struct LocalName : Node { | struct LocalName : Node { | ||||
Node *Encoding; | Node *Encoding; | ||||
Node *Entity; | Node *Entity; | ||||
LocalName(Node *Encoding_, Node *Entity_) | LocalName(Node *Encoding_, Node *Entity_) | ||||
: Node(KLocalName), Encoding(Encoding_), Entity(Entity_) {} | : Node(KLocalName), Encoding(Encoding_), Entity(Entity_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Encoding, Entity); } | template<typename Fn> void match(Fn F) const { F(Encoding, Entity); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
Encoding->print(OB); | Encoding->print(OB); | ||||
OB += "::"; | OB += "::"; | ||||
Entity->print(OB); | Entity->print(OB); | ||||
} | } | ||||
friend bool operator==(LocalName const &LHS, LocalName const &RHS) { | |||||
assert(LHS.Encoding != nullptr); | |||||
assert(RHS.Encoding != nullptr); | |||||
assert(LHS.Entity != nullptr); | |||||
assert(RHS.Entity != nullptr); | |||||
return LHS.Encoding->equals(RHS.Encoding) && LHS.Entity->equals(RHS.Entity); | |||||
} | |||||
friend bool operator!=(LocalName const &LHS, LocalName const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class QualifiedName final : public Node { | class QualifiedName final : public Node { | ||||
// qualifier::name | // qualifier::name | ||||
const Node *Qualifier; | const Node *Qualifier; | ||||
const Node *Name; | const Node *Name; | ||||
public: | public: | ||||
QualifiedName(const Node *Qualifier_, const Node *Name_) | QualifiedName(const Node *Qualifier_, const Node *Name_) | ||||
: Node(KQualifiedName), Qualifier(Qualifier_), Name(Name_) {} | : Node(KQualifiedName), Qualifier(Qualifier_), Name(Name_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Qualifier, Name); } | template<typename Fn> void match(Fn F) const { F(Qualifier, Name); } | ||||
StringView getBaseName() const override { return Name->getBaseName(); } | StringView getBaseName() const override { return Name->getBaseName(); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
Qualifier->print(OB); | Qualifier->print(OB); | ||||
OB += "::"; | OB += "::"; | ||||
Name->print(OB); | Name->print(OB); | ||||
} | } | ||||
friend bool operator==(QualifiedName const &LHS, QualifiedName const &RHS) { | |||||
assert(LHS.Qualifier != nullptr); | |||||
assert(RHS.Qualifier != nullptr); | |||||
assert(LHS.Name != nullptr); | |||||
assert(RHS.Name != nullptr); | |||||
return LHS.Qualifier->equals(RHS.Qualifier) && LHS.Name->equals(RHS.Name); | |||||
} | |||||
friend bool operator!=(QualifiedName const &LHS, QualifiedName const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class VectorType final : public Node { | class VectorType final : public Node { | ||||
const Node *BaseType; | const Node *BaseType; | ||||
const Node *Dimension; | const Node *Dimension; | ||||
public: | public: | ||||
VectorType(const Node *BaseType_, const Node *Dimension_) | VectorType(const Node *BaseType_, const Node *Dimension_) | ||||
: Node(KVectorType), BaseType(BaseType_), Dimension(Dimension_) {} | : Node(KVectorType), BaseType(BaseType_), Dimension(Dimension_) {} | ||||
const Node *getBaseType() const { return BaseType; } | |||||
const Node *getDimension() const { return Dimension; } | |||||
template<typename Fn> void match(Fn F) const { F(BaseType, Dimension); } | template<typename Fn> void match(Fn F) const { F(BaseType, Dimension); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
BaseType->print(OB); | BaseType->print(OB); | ||||
OB += " vector["; | OB += " vector["; | ||||
if (Dimension) | if (Dimension) | ||||
Dimension->print(OB); | Dimension->print(OB); | ||||
OB += "]"; | OB += "]"; | ||||
} | } | ||||
friend bool operator==(VectorType const &LHS, VectorType const &RHS) { | |||||
return LHS.BaseType->equals(RHS.BaseType) && | |||||
LHS.Dimension->equals(RHS.Dimension); | |||||
} | |||||
friend bool operator!=(VectorType const &LHS, VectorType const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class PixelVectorType final : public Node { | class PixelVectorType final : public Node { | ||||
const Node *Dimension; | const Node *Dimension; | ||||
public: | public: | ||||
PixelVectorType(const Node *Dimension_) | PixelVectorType(const Node *Dimension_) | ||||
: Node(KPixelVectorType), Dimension(Dimension_) {} | : Node(KPixelVectorType), Dimension(Dimension_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Dimension); } | template<typename Fn> void match(Fn F) const { F(Dimension); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
// FIXME: This should demangle as "vector pixel". | // FIXME: This should demangle as "vector pixel". | ||||
OB += "pixel vector["; | OB += "pixel vector["; | ||||
Dimension->print(OB); | Dimension->print(OB); | ||||
OB += "]"; | OB += "]"; | ||||
} | } | ||||
friend bool operator==(PixelVectorType const &LHS, | |||||
PixelVectorType const &RHS) { | |||||
return LHS.Dimension->equals(RHS.Dimension); | |||||
} | |||||
friend bool operator!=(PixelVectorType const &LHS, | |||||
PixelVectorType const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class BinaryFPType final : public Node { | class BinaryFPType final : public Node { | ||||
const Node *Dimension; | const Node *Dimension; | ||||
public: | public: | ||||
BinaryFPType(const Node *Dimension_) | BinaryFPType(const Node *Dimension_) | ||||
: Node(KBinaryFPType), Dimension(Dimension_) {} | : Node(KBinaryFPType), Dimension(Dimension_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Dimension); } | template<typename Fn> void match(Fn F) const { F(Dimension); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB += "_Float"; | OB += "_Float"; | ||||
Dimension->print(OB); | Dimension->print(OB); | ||||
} | } | ||||
friend bool operator==(BinaryFPType const &LHS, BinaryFPType const &RHS) { | |||||
return LHS.Dimension->equals(RHS.Dimension); | |||||
} | |||||
friend bool operator!=(BinaryFPType const &LHS, BinaryFPType const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
enum class TemplateParamKind { Type, NonType, Template }; | enum class TemplateParamKind { Type, NonType, Template }; | ||||
/// An invented name for a template parameter for which we don't have a | /// An invented name for a template parameter for which we don't have a | ||||
/// corresponding template argument. | /// corresponding template argument. | ||||
/// | /// | ||||
/// This node is created when parsing the <lambda-sig> for a lambda with | /// This node is created when parsing the <lambda-sig> for a lambda with | ||||
Show All 19 Lines | case TemplateParamKind::NonType: | ||||
break; | break; | ||||
case TemplateParamKind::Template: | case TemplateParamKind::Template: | ||||
OB += "$TT"; | OB += "$TT"; | ||||
break; | break; | ||||
} | } | ||||
if (Index > 0) | if (Index > 0) | ||||
OB << Index - 1; | OB << Index - 1; | ||||
} | } | ||||
friend bool operator==(SyntheticTemplateParamName const &LHS, | |||||
SyntheticTemplateParamName const &RHS) { | |||||
return LHS.Kind == RHS.Kind && LHS.Index == RHS.Index; | |||||
} | |||||
friend bool operator!=(SyntheticTemplateParamName const &LHS, | |||||
SyntheticTemplateParamName const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
/// A template type parameter declaration, 'typename T'. | /// A template type parameter declaration, 'typename T'. | ||||
class TypeTemplateParamDecl final : public Node { | class TypeTemplateParamDecl final : public Node { | ||||
Node *Name; | Node *Name; | ||||
public: | public: | ||||
TypeTemplateParamDecl(Node *Name_) | TypeTemplateParamDecl(Node *Name_) | ||||
: Node(KTypeTemplateParamDecl, Cache::Yes), Name(Name_) {} | : Node(KTypeTemplateParamDecl, Cache::Yes), Name(Name_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Name); } | template<typename Fn> void match(Fn F) const { F(Name); } | ||||
void printLeft(OutputBuffer &OB) const override { OB += "typename "; } | void printLeft(OutputBuffer &OB) const override { OB += "typename "; } | ||||
void printRight(OutputBuffer &OB) const override { Name->print(OB); } | void printRight(OutputBuffer &OB) const override { Name->print(OB); } | ||||
friend bool operator==(TypeTemplateParamDecl const &LHS, | |||||
TypeTemplateParamDecl const &RHS) { | |||||
return LHS.Name->equals(RHS.Name); | |||||
} | |||||
friend bool operator!=(TypeTemplateParamDecl const &LHS, | |||||
TypeTemplateParamDecl const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
/// A non-type template parameter declaration, 'int N'. | /// A non-type template parameter declaration, 'int N'. | ||||
class NonTypeTemplateParamDecl final : public Node { | class NonTypeTemplateParamDecl final : public Node { | ||||
Node *Name; | Node *Name; | ||||
Node *Type; | Node *Type; | ||||
public: | public: | ||||
NonTypeTemplateParamDecl(Node *Name_, Node *Type_) | NonTypeTemplateParamDecl(Node *Name_, Node *Type_) | ||||
: Node(KNonTypeTemplateParamDecl, Cache::Yes), Name(Name_), Type(Type_) {} | : Node(KNonTypeTemplateParamDecl, Cache::Yes), Name(Name_), Type(Type_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Name, Type); } | template<typename Fn> void match(Fn F) const { F(Name, Type); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
Type->printLeft(OB); | Type->printLeft(OB); | ||||
if (!Type->hasRHSComponent(OB)) | if (!Type->hasRHSComponent(OB)) | ||||
OB += " "; | OB += " "; | ||||
} | } | ||||
void printRight(OutputBuffer &OB) const override { | void printRight(OutputBuffer &OB) const override { | ||||
Name->print(OB); | Name->print(OB); | ||||
Type->printRight(OB); | Type->printRight(OB); | ||||
} | } | ||||
friend bool operator==(NonTypeTemplateParamDecl const &LHS, | |||||
NonTypeTemplateParamDecl const &RHS) { | |||||
return LHS.Name->equals(RHS.Name) && LHS.Type->equals(RHS.Type); | |||||
} | |||||
friend bool operator!=(NonTypeTemplateParamDecl const &LHS, | |||||
NonTypeTemplateParamDecl const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
/// A template template parameter declaration, | /// A template template parameter declaration, | ||||
/// 'template<typename T> typename N'. | /// 'template<typename T> typename N'. | ||||
class TemplateTemplateParamDecl final : public Node { | class TemplateTemplateParamDecl final : public Node { | ||||
Node *Name; | Node *Name; | ||||
NodeArray Params; | NodeArray Params; | ||||
public: | public: | ||||
TemplateTemplateParamDecl(Node *Name_, NodeArray Params_) | TemplateTemplateParamDecl(Node *Name_, NodeArray Params_) | ||||
: Node(KTemplateTemplateParamDecl, Cache::Yes), Name(Name_), | : Node(KTemplateTemplateParamDecl, Cache::Yes), Name(Name_), | ||||
Params(Params_) {} | Params(Params_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Name, Params); } | template<typename Fn> void match(Fn F) const { F(Name, Params); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
ScopedOverride<unsigned> LT(OB.GtIsGt, 0); | ScopedOverride<unsigned> LT(OB.GtIsGt, 0); | ||||
OB += "template<"; | OB += "template<"; | ||||
Params.printWithComma(OB); | Params.printWithComma(OB); | ||||
OB += "> typename "; | OB += "> typename "; | ||||
} | } | ||||
void printRight(OutputBuffer &OB) const override { Name->print(OB); } | 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; | |||||
} | |||||
friend bool operator!=(TemplateTemplateParamDecl const &LHS, | |||||
TemplateTemplateParamDecl const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
/// A template parameter pack declaration, 'typename ...T'. | /// A template parameter pack declaration, 'typename ...T'. | ||||
class TemplateParamPackDecl final : public Node { | class TemplateParamPackDecl final : public Node { | ||||
Node *Param; | Node *Param; | ||||
public: | public: | ||||
TemplateParamPackDecl(Node *Param_) | TemplateParamPackDecl(Node *Param_) | ||||
: Node(KTemplateParamPackDecl, Cache::Yes), Param(Param_) {} | : Node(KTemplateParamPackDecl, Cache::Yes), Param(Param_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Param); } | template<typename Fn> void match(Fn F) const { F(Param); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
Param->printLeft(OB); | Param->printLeft(OB); | ||||
OB += "..."; | OB += "..."; | ||||
} | } | ||||
void printRight(OutputBuffer &OB) const override { Param->printRight(OB); } | void printRight(OutputBuffer &OB) const override { Param->printRight(OB); } | ||||
friend bool operator==(TemplateParamPackDecl const &LHS, | |||||
TemplateParamPackDecl const &RHS) { | |||||
return LHS.Param->equals(RHS.Param); | |||||
} | |||||
friend bool operator!=(TemplateParamPackDecl const &LHS, | |||||
TemplateParamPackDecl const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
/// An unexpanded parameter pack (either in the expression or type context). If | /// An unexpanded parameter pack (either in the expression or type context). If | ||||
/// this AST is correct, this node will have a ParameterPackExpansion node above | /// this AST is correct, this node will have a ParameterPackExpansion node above | ||||
/// it. | /// it. | ||||
/// | /// | ||||
/// This node is created when some <template-args> are found that apply to an | /// This node is created when some <template-args> are found that apply to an | ||||
/// <encoding>, and is stored in the TemplateParams table. In order for this to | /// <encoding>, and is stored in the TemplateParams table. In order for this to | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | if (Idx < Data.size()) | ||||
Data[Idx]->printLeft(OB); | Data[Idx]->printLeft(OB); | ||||
} | } | ||||
void printRight(OutputBuffer &OB) const override { | void printRight(OutputBuffer &OB) const override { | ||||
initializePackExpansion(OB); | initializePackExpansion(OB); | ||||
size_t Idx = OB.CurrentPackIndex; | size_t Idx = OB.CurrentPackIndex; | ||||
if (Idx < Data.size()) | if (Idx < Data.size()) | ||||
Data[Idx]->printRight(OB); | Data[Idx]->printRight(OB); | ||||
} | } | ||||
friend bool operator==(ParameterPack const &LHS, ParameterPack const &RHS) { | |||||
return LHS.Data == RHS.Data; | |||||
} | |||||
friend bool operator!=(ParameterPack const &LHS, ParameterPack const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
/// A variadic template argument. This node represents an occurrence of | /// A variadic template argument. This node represents an occurrence of | ||||
/// J<something>E in some <template-args>. It isn't itself unexpanded, unless | /// J<something>E in some <template-args>. It isn't itself unexpanded, unless | ||||
/// one of it's Elements is. The parser inserts a ParameterPack into the | /// one of it's Elements is. The parser inserts a ParameterPack into the | ||||
/// TemplateParams table if the <template-args> this pack belongs to apply to an | /// TemplateParams table if the <template-args> this pack belongs to apply to an | ||||
/// <encoding>. | /// <encoding>. | ||||
class TemplateArgumentPack final : public Node { | class TemplateArgumentPack final : public Node { | ||||
NodeArray Elements; | NodeArray Elements; | ||||
public: | public: | ||||
TemplateArgumentPack(NodeArray Elements_) | TemplateArgumentPack(NodeArray Elements_) | ||||
: Node(KTemplateArgumentPack), Elements(Elements_) {} | : Node(KTemplateArgumentPack), Elements(Elements_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Elements); } | template<typename Fn> void match(Fn F) const { F(Elements); } | ||||
NodeArray getElements() const { return Elements; } | NodeArray getElements() const { return Elements; } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
Elements.printWithComma(OB); | Elements.printWithComma(OB); | ||||
} | } | ||||
friend bool operator==(TemplateArgumentPack const &LHS, | |||||
TemplateArgumentPack const &RHS) { | |||||
return LHS.Elements == RHS.Elements; | |||||
} | |||||
friend bool operator!=(TemplateArgumentPack const &LHS, | |||||
TemplateArgumentPack const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
/// A pack expansion. Below this node, there are some unexpanded ParameterPacks | /// A pack expansion. Below this node, there are some unexpanded ParameterPacks | ||||
/// which each have Child->ParameterPackSize elements. | /// which each have Child->ParameterPackSize elements. | ||||
class ParameterPackExpansion final : public Node { | class ParameterPackExpansion final : public Node { | ||||
const Node *Child; | const Node *Child; | ||||
public: | public: | ||||
Show All 30 Lines | void printLeft(OutputBuffer &OB) const override { | ||||
// Else, iterate through the rest of the elements in the pack. | // Else, iterate through the rest of the elements in the pack. | ||||
for (unsigned I = 1, E = OB.CurrentPackMax; I < E; ++I) { | for (unsigned I = 1, E = OB.CurrentPackMax; I < E; ++I) { | ||||
OB += ", "; | OB += ", "; | ||||
OB.CurrentPackIndex = I; | OB.CurrentPackIndex = I; | ||||
Child->print(OB); | Child->print(OB); | ||||
} | } | ||||
} | } | ||||
friend bool operator==(ParameterPackExpansion const &LHS, | |||||
ParameterPackExpansion const &RHS) { | |||||
return LHS.Child->equals(RHS.Child); | |||||
} | |||||
friend bool operator!=(ParameterPackExpansion const &LHS, | |||||
ParameterPackExpansion const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class TemplateArgs final : public Node { | class TemplateArgs final : public Node { | ||||
NodeArray Params; | NodeArray Params; | ||||
public: | public: | ||||
TemplateArgs(NodeArray Params_) : Node(KTemplateArgs), Params(Params_) {} | TemplateArgs(NodeArray Params_) : Node(KTemplateArgs), Params(Params_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Params); } | template<typename Fn> void match(Fn F) const { F(Params); } | ||||
NodeArray getParams() { return Params; } | NodeArray getParams() { return Params; } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
ScopedOverride<unsigned> LT(OB.GtIsGt, 0); | ScopedOverride<unsigned> LT(OB.GtIsGt, 0); | ||||
OB += "<"; | OB += "<"; | ||||
Params.printWithComma(OB); | Params.printWithComma(OB); | ||||
OB += ">"; | OB += ">"; | ||||
} | } | ||||
friend bool operator==(TemplateArgs const &LHS, TemplateArgs const &RHS) { | |||||
return LHS.Params == RHS.Params; | |||||
} | |||||
friend bool operator!=(TemplateArgs const &LHS, TemplateArgs const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
/// A forward-reference to a template argument that was not known at the point | /// A forward-reference to a template argument that was not known at the point | ||||
/// where the template parameter name was parsed in a mangling. | /// where the template parameter name was parsed in a mangling. | ||||
/// | /// | ||||
/// This is created when demangling the name of a specialization of a | /// This is created when demangling the name of a specialization of a | ||||
/// conversion function template: | /// conversion function template: | ||||
/// | /// | ||||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | void printLeft(OutputBuffer &OB) const override { | ||||
Ref->printLeft(OB); | Ref->printLeft(OB); | ||||
} | } | ||||
void printRight(OutputBuffer &OB) const override { | void printRight(OutputBuffer &OB) const override { | ||||
if (Printing) | if (Printing) | ||||
return; | return; | ||||
ScopedOverride<bool> SavePrinting(Printing, true); | ScopedOverride<bool> SavePrinting(Printing, true); | ||||
Ref->printRight(OB); | Ref->printRight(OB); | ||||
} | } | ||||
friend bool operator==(ForwardTemplateReference const &LHS, | |||||
ForwardTemplateReference const &RHS) { | |||||
if (LHS.Index != RHS.Index) | |||||
return false; | |||||
// Ignore 'Printing' member | |||||
if (LHS.Ref != nullptr && RHS.Ref != nullptr) | |||||
return LHS.Ref->equals(RHS.Ref); | |||||
return LHS.Ref == nullptr && RHS.Ref == nullptr; | |||||
} | |||||
friend bool operator!=(ForwardTemplateReference const &LHS, | |||||
ForwardTemplateReference const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
struct NameWithTemplateArgs : Node { | struct NameWithTemplateArgs : Node { | ||||
// name<template_args> | // name<template_args> | ||||
Node *Name; | Node *Name; | ||||
Node *TemplateArgs; | Node *TemplateArgs; | ||||
NameWithTemplateArgs(Node *Name_, Node *TemplateArgs_) | NameWithTemplateArgs(Node *Name_, Node *TemplateArgs_) | ||||
: Node(KNameWithTemplateArgs), Name(Name_), TemplateArgs(TemplateArgs_) {} | : Node(KNameWithTemplateArgs), Name(Name_), TemplateArgs(TemplateArgs_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Name, TemplateArgs); } | template<typename Fn> void match(Fn F) const { F(Name, TemplateArgs); } | ||||
StringView getBaseName() const override { return Name->getBaseName(); } | StringView getBaseName() const override { return Name->getBaseName(); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
Name->print(OB); | Name->print(OB); | ||||
TemplateArgs->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); | |||||
} | |||||
friend bool operator!=(NameWithTemplateArgs const &LHS, | |||||
NameWithTemplateArgs const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class GlobalQualifiedName final : public Node { | class GlobalQualifiedName final : public Node { | ||||
Node *Child; | Node *Child; | ||||
public: | public: | ||||
GlobalQualifiedName(Node* Child_) | GlobalQualifiedName(Node* Child_) | ||||
: Node(KGlobalQualifiedName), Child(Child_) {} | : Node(KGlobalQualifiedName), Child(Child_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Child); } | template<typename Fn> void match(Fn F) const { F(Child); } | ||||
StringView getBaseName() const override { return Child->getBaseName(); } | StringView getBaseName() const override { return Child->getBaseName(); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB += "::"; | OB += "::"; | ||||
Child->print(OB); | Child->print(OB); | ||||
} | } | ||||
friend bool operator==(GlobalQualifiedName const &LHS, | |||||
GlobalQualifiedName const &RHS) { | |||||
return LHS.Child->equals(RHS.Child); | |||||
} | |||||
friend bool operator!=(GlobalQualifiedName const &LHS, | |||||
GlobalQualifiedName const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
enum class SpecialSubKind { | enum class SpecialSubKind { | ||||
allocator, | allocator, | ||||
basic_string, | basic_string, | ||||
string, | string, | ||||
istream, | istream, | ||||
ostream, | ostream, | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | void printLeft(OutputBuffer &OB) const override { | ||||
OB << "std::" << getBaseName(); | OB << "std::" << getBaseName(); | ||||
if (isInstantiation()) { | if (isInstantiation()) { | ||||
OB << "<char, std::char_traits<char>"; | OB << "<char, std::char_traits<char>"; | ||||
if (SSK == SpecialSubKind::string) | if (SSK == SpecialSubKind::string) | ||||
OB << ", std::allocator<char>"; | OB << ", std::allocator<char>"; | ||||
OB << ">"; | OB << ">"; | ||||
} | } | ||||
} | } | ||||
friend bool operator==(ExpandedSpecialSubstitution const &LHS, | |||||
ExpandedSpecialSubstitution const &RHS) { | |||||
return LHS.SSK == RHS.SSK; | |||||
} | |||||
friend bool operator!=(ExpandedSpecialSubstitution const &LHS, | |||||
ExpandedSpecialSubstitution const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class SpecialSubstitution final : public ExpandedSpecialSubstitution { | class SpecialSubstitution final : public ExpandedSpecialSubstitution { | ||||
public: | public: | ||||
SpecialSubstitution(SpecialSubKind SSK_) | SpecialSubstitution(SpecialSubKind SSK_) | ||||
: ExpandedSpecialSubstitution(SSK_, KSpecialSubstitution) {} | : ExpandedSpecialSubstitution(SSK_, KSpecialSubstitution) {} | ||||
template<typename Fn> void match(Fn F) const { F(SSK); } | template<typename Fn> void match(Fn F) const { F(SSK); } | ||||
Show All 29 Lines | public: | ||||
template<typename Fn> void match(Fn F) const { F(Basename, IsDtor, Variant); } | template<typename Fn> void match(Fn F) const { F(Basename, IsDtor, Variant); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
if (IsDtor) | if (IsDtor) | ||||
OB += "~"; | OB += "~"; | ||||
OB += Basename->getBaseName(); | OB += Basename->getBaseName(); | ||||
} | } | ||||
friend bool operator==(CtorDtorName const &LHS, CtorDtorName const &RHS) { | |||||
assert(LHS.Basename != nullptr); | |||||
assert(RHS.Basename != nullptr); | |||||
return LHS.IsDtor == RHS.IsDtor && LHS.Variant == RHS.Variant && | |||||
LHS.Basename->equals(RHS.Basename); | |||||
} | |||||
friend bool operator!=(CtorDtorName const &LHS, CtorDtorName const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class DtorName : public Node { | class DtorName : public Node { | ||||
const Node *Base; | const Node *Base; | ||||
public: | public: | ||||
DtorName(const Node *Base_) : Node(KDtorName), Base(Base_) {} | DtorName(const Node *Base_) : Node(KDtorName), Base(Base_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Base); } | template<typename Fn> void match(Fn F) const { F(Base); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB += "~"; | OB += "~"; | ||||
Base->printLeft(OB); | Base->printLeft(OB); | ||||
} | } | ||||
friend bool operator==(DtorName const &LHS, DtorName const &RHS) { | |||||
assert(LHS.Base != nullptr); | |||||
assert(RHS.Base != nullptr); | |||||
return LHS.Base->equals(RHS.Base); | |||||
} | |||||
friend bool operator!=(DtorName const &LHS, DtorName const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class UnnamedTypeName : public Node { | class UnnamedTypeName : public Node { | ||||
const StringView Count; | const StringView Count; | ||||
public: | public: | ||||
UnnamedTypeName(StringView Count_) : Node(KUnnamedTypeName), Count(Count_) {} | UnnamedTypeName(StringView Count_) : Node(KUnnamedTypeName), Count(Count_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Count); } | template<typename Fn> void match(Fn F) const { F(Count); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB += "'unnamed"; | OB += "'unnamed"; | ||||
OB += Count; | OB += Count; | ||||
OB += "\'"; | OB += "\'"; | ||||
} | } | ||||
friend bool operator==(UnnamedTypeName const &LHS, | |||||
UnnamedTypeName const &RHS) { | |||||
return LHS.Count == RHS.Count; | |||||
} | |||||
friend bool operator!=(UnnamedTypeName const &LHS, | |||||
UnnamedTypeName const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class ClosureTypeName : public Node { | class ClosureTypeName : public Node { | ||||
NodeArray TemplateParams; | NodeArray TemplateParams; | ||||
NodeArray Params; | NodeArray Params; | ||||
StringView Count; | StringView Count; | ||||
public: | public: | ||||
Show All 19 Lines | public: | ||||
} | } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB += "\'lambda"; | OB += "\'lambda"; | ||||
OB += Count; | OB += Count; | ||||
OB += "\'"; | OB += "\'"; | ||||
printDeclarator(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; | |||||
} | |||||
friend bool operator!=(ClosureTypeName const &LHS, | |||||
ClosureTypeName const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class StructuredBindingName : public Node { | class StructuredBindingName : public Node { | ||||
NodeArray Bindings; | NodeArray Bindings; | ||||
public: | public: | ||||
StructuredBindingName(NodeArray Bindings_) | StructuredBindingName(NodeArray Bindings_) | ||||
: Node(KStructuredBindingName), Bindings(Bindings_) {} | : Node(KStructuredBindingName), Bindings(Bindings_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Bindings); } | template<typename Fn> void match(Fn F) const { F(Bindings); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB.printOpen('['); | OB.printOpen('['); | ||||
Bindings.printWithComma(OB); | Bindings.printWithComma(OB); | ||||
OB.printClose(']'); | OB.printClose(']'); | ||||
} | } | ||||
friend bool operator==(StructuredBindingName const &LHS, | |||||
StructuredBindingName const &RHS) { | |||||
return LHS.Bindings == RHS.Bindings; | |||||
} | |||||
friend bool operator!=(StructuredBindingName const &LHS, | |||||
StructuredBindingName const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
// -- Expression Nodes -- | // -- Expression Nodes -- | ||||
class BinaryExpr : public Node { | class BinaryExpr : public Node { | ||||
const Node *LHS; | const Node *LHS; | ||||
const StringView InfixOperator; | const StringView InfixOperator; | ||||
const Node *RHS; | const Node *RHS; | ||||
Show All 20 Lines | void printLeft(OutputBuffer &OB) const override { | ||||
if (!(InfixOperator == ",")) | if (!(InfixOperator == ",")) | ||||
OB += " "; | OB += " "; | ||||
OB += InfixOperator; | OB += InfixOperator; | ||||
OB += " "; | OB += " "; | ||||
RHS->printAsOperand(OB, getPrecedence(), IsAssign); | RHS->printAsOperand(OB, getPrecedence(), IsAssign); | ||||
if (ParenAll) | if (ParenAll) | ||||
OB.printClose(); | OB.printClose(); | ||||
} | } | ||||
friend bool operator==(BinaryExpr const &Left, BinaryExpr const &Right) { | |||||
return Left.InfixOperator == Right.InfixOperator && | |||||
Left.LHS->equals(Right.LHS) && Left.RHS->equals(Right.RHS); | |||||
} | |||||
friend bool operator!=(BinaryExpr const &Left, BinaryExpr const &Right) { | |||||
return !(Left == Right); | |||||
} | |||||
}; | }; | ||||
class ArraySubscriptExpr : public Node { | class ArraySubscriptExpr : public Node { | ||||
const Node *Op1; | const Node *Op1; | ||||
const Node *Op2; | const Node *Op2; | ||||
public: | public: | ||||
ArraySubscriptExpr(const Node *Op1_, const Node *Op2_, Prec Prec_) | ArraySubscriptExpr(const Node *Op1_, const Node *Op2_, Prec Prec_) | ||||
: Node(KArraySubscriptExpr, Prec_), Op1(Op1_), Op2(Op2_) {} | : Node(KArraySubscriptExpr, Prec_), Op1(Op1_), Op2(Op2_) {} | ||||
template <typename Fn> void match(Fn F) const { | template <typename Fn> void match(Fn F) const { | ||||
F(Op1, Op2, getPrecedence()); | F(Op1, Op2, getPrecedence()); | ||||
} | } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
Op1->printAsOperand(OB, getPrecedence()); | Op1->printAsOperand(OB, getPrecedence()); | ||||
OB.printOpen('['); | OB.printOpen('['); | ||||
Op2->printAsOperand(OB); | Op2->printAsOperand(OB); | ||||
OB.printClose(']'); | OB.printClose(']'); | ||||
} | } | ||||
friend bool operator==(ArraySubscriptExpr const &LHS, | |||||
ArraySubscriptExpr const &RHS) { | |||||
return LHS.Op1->equals(RHS.Op1) && LHS.Op2->equals(RHS.Op2); | |||||
} | |||||
friend bool operator!=(ArraySubscriptExpr const &LHS, | |||||
ArraySubscriptExpr const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class PostfixExpr : public Node { | class PostfixExpr : public Node { | ||||
const Node *Child; | const Node *Child; | ||||
const StringView Operator; | const StringView Operator; | ||||
public: | public: | ||||
PostfixExpr(const Node *Child_, StringView Operator_, Prec Prec_) | PostfixExpr(const Node *Child_, StringView Operator_, Prec Prec_) | ||||
: Node(KPostfixExpr, Prec_), Child(Child_), Operator(Operator_) {} | : Node(KPostfixExpr, Prec_), Child(Child_), Operator(Operator_) {} | ||||
template <typename Fn> void match(Fn F) const { | template <typename Fn> void match(Fn F) const { | ||||
F(Child, Operator, getPrecedence()); | F(Child, Operator, getPrecedence()); | ||||
} | } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
Child->printAsOperand(OB, getPrecedence(), true); | Child->printAsOperand(OB, getPrecedence(), true); | ||||
OB += Operator; | OB += Operator; | ||||
} | } | ||||
friend bool operator==(PostfixExpr const &LHS, PostfixExpr const &RHS) { | |||||
return LHS.Operator == RHS.Operator && LHS.Child->equals(RHS.Child); | |||||
} | |||||
friend bool operator!=(PostfixExpr const &LHS, PostfixExpr const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class ConditionalExpr : public Node { | class ConditionalExpr : public Node { | ||||
const Node *Cond; | const Node *Cond; | ||||
const Node *Then; | const Node *Then; | ||||
const Node *Else; | const Node *Else; | ||||
public: | public: | ||||
ConditionalExpr(const Node *Cond_, const Node *Then_, const Node *Else_, | ConditionalExpr(const Node *Cond_, const Node *Then_, const Node *Else_, | ||||
Prec Prec_) | Prec Prec_) | ||||
: Node(KConditionalExpr, Prec_), Cond(Cond_), Then(Then_), Else(Else_) {} | : Node(KConditionalExpr, Prec_), Cond(Cond_), Then(Then_), Else(Else_) {} | ||||
template <typename Fn> void match(Fn F) const { | template <typename Fn> void match(Fn F) const { | ||||
F(Cond, Then, Else, getPrecedence()); | F(Cond, Then, Else, getPrecedence()); | ||||
} | } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
Cond->printAsOperand(OB, getPrecedence()); | Cond->printAsOperand(OB, getPrecedence()); | ||||
OB += " ? "; | OB += " ? "; | ||||
Then->printAsOperand(OB); | Then->printAsOperand(OB); | ||||
OB += " : "; | OB += " : "; | ||||
Else->printAsOperand(OB, Prec::Assign, true); | 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); | |||||
} | |||||
friend bool operator!=(ConditionalExpr const &LHS, | |||||
ConditionalExpr const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class MemberExpr : public Node { | class MemberExpr : public Node { | ||||
const Node *LHS; | const Node *LHS; | ||||
const StringView Kind; | const StringView Kind; | ||||
const Node *RHS; | const Node *RHS; | ||||
public: | public: | ||||
MemberExpr(const Node *LHS_, StringView Kind_, const Node *RHS_, Prec Prec_) | MemberExpr(const Node *LHS_, StringView Kind_, const Node *RHS_, Prec Prec_) | ||||
: Node(KMemberExpr, Prec_), LHS(LHS_), Kind(Kind_), RHS(RHS_) {} | : Node(KMemberExpr, Prec_), LHS(LHS_), Kind(Kind_), RHS(RHS_) {} | ||||
template <typename Fn> void match(Fn F) const { | template <typename Fn> void match(Fn F) const { | ||||
F(LHS, Kind, RHS, getPrecedence()); | F(LHS, Kind, RHS, getPrecedence()); | ||||
} | } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
LHS->printAsOperand(OB, getPrecedence(), true); | LHS->printAsOperand(OB, getPrecedence(), true); | ||||
OB += Kind; | OB += Kind; | ||||
RHS->printAsOperand(OB, getPrecedence(), false); | RHS->printAsOperand(OB, getPrecedence(), false); | ||||
} | } | ||||
friend bool operator==(MemberExpr const &Left, MemberExpr const &Right) { | |||||
return Left.Kind == Right.Kind && Left.LHS->equals(Right.LHS) && | |||||
Left.RHS->equals(Right.RHS); | |||||
} | |||||
friend bool operator!=(MemberExpr const &Left, MemberExpr const &Right) { | |||||
return !(Left == Right); | |||||
} | |||||
}; | }; | ||||
class SubobjectExpr : public Node { | class SubobjectExpr : public Node { | ||||
const Node *Type; | const Node *Type; | ||||
const Node *SubExpr; | const Node *SubExpr; | ||||
StringView Offset; | StringView Offset; | ||||
NodeArray UnionSelectors; | NodeArray UnionSelectors; | ||||
bool OnePastTheEnd; | bool OnePastTheEnd; | ||||
Show All 18 Lines | void printLeft(OutputBuffer &OB) const override { | ||||
} else if (Offset[0] == 'n') { | } else if (Offset[0] == 'n') { | ||||
OB += "-"; | OB += "-"; | ||||
OB += Offset.dropFront(); | OB += Offset.dropFront(); | ||||
} else { | } else { | ||||
OB += Offset; | OB += Offset; | ||||
} | } | ||||
OB += ">"; | 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; | |||||
} | |||||
friend bool operator!=(SubobjectExpr const &LHS, SubobjectExpr const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class EnclosingExpr : public Node { | class EnclosingExpr : public Node { | ||||
const StringView Prefix; | const StringView Prefix; | ||||
const Node *Infix; | const Node *Infix; | ||||
const StringView Postfix; | const StringView Postfix; | ||||
public: | public: | ||||
EnclosingExpr(StringView Prefix_, const Node *Infix_, | EnclosingExpr(StringView Prefix_, const Node *Infix_, | ||||
Prec Prec_ = Prec::Primary) | Prec Prec_ = Prec::Primary) | ||||
: Node(KEnclosingExpr, Prec_), Prefix(Prefix_), Infix(Infix_) {} | : Node(KEnclosingExpr, Prec_), Prefix(Prefix_), Infix(Infix_) {} | ||||
template <typename Fn> void match(Fn F) const { | template <typename Fn> void match(Fn F) const { | ||||
F(Prefix, Infix, getPrecedence()); | F(Prefix, Infix, getPrecedence()); | ||||
} | } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB += Prefix; | OB += Prefix; | ||||
OB.printOpen(); | OB.printOpen(); | ||||
Infix->print(OB); | Infix->print(OB); | ||||
OB.printClose(); | OB.printClose(); | ||||
OB += Postfix; | 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); | |||||
} | |||||
friend bool operator!=(EnclosingExpr const &LHS, EnclosingExpr const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class CastExpr : public Node { | class CastExpr : public Node { | ||||
// cast_kind<to>(from) | // cast_kind<to>(from) | ||||
const StringView CastKind; | const StringView CastKind; | ||||
const Node *To; | const Node *To; | ||||
const Node *From; | const Node *From; | ||||
Show All 12 Lines | OB += CastKind; | ||||
OB += "<"; | OB += "<"; | ||||
To->printLeft(OB); | To->printLeft(OB); | ||||
OB += ">"; | OB += ">"; | ||||
} | } | ||||
OB.printOpen(); | OB.printOpen(); | ||||
From->printAsOperand(OB); | From->printAsOperand(OB); | ||||
OB.printClose(); | 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); | |||||
} | |||||
friend bool operator!=(CastExpr const &LHS, CastExpr const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class SizeofParamPackExpr : public Node { | class SizeofParamPackExpr : public Node { | ||||
const Node *Pack; | const Node *Pack; | ||||
public: | public: | ||||
SizeofParamPackExpr(const Node *Pack_) | SizeofParamPackExpr(const Node *Pack_) | ||||
: Node(KSizeofParamPackExpr), Pack(Pack_) {} | : Node(KSizeofParamPackExpr), Pack(Pack_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Pack); } | template<typename Fn> void match(Fn F) const { F(Pack); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB += "sizeof..."; | OB += "sizeof..."; | ||||
OB.printOpen(); | OB.printOpen(); | ||||
ParameterPackExpansion PPE(Pack); | ParameterPackExpansion PPE(Pack); | ||||
PPE.printLeft(OB); | PPE.printLeft(OB); | ||||
OB.printClose(); | OB.printClose(); | ||||
} | } | ||||
friend bool operator==(SizeofParamPackExpr const &LHS, | |||||
SizeofParamPackExpr const &RHS) { | |||||
return LHS.Pack->equals(RHS.Pack); | |||||
} | |||||
friend bool operator!=(SizeofParamPackExpr const &LHS, | |||||
SizeofParamPackExpr const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class CallExpr : public Node { | class CallExpr : public Node { | ||||
const Node *Callee; | const Node *Callee; | ||||
NodeArray Args; | NodeArray Args; | ||||
public: | public: | ||||
CallExpr(const Node *Callee_, NodeArray Args_, Prec Prec_) | CallExpr(const Node *Callee_, NodeArray Args_, Prec Prec_) | ||||
: Node(KCallExpr, Prec_), Callee(Callee_), Args(Args_) {} | : Node(KCallExpr, Prec_), Callee(Callee_), Args(Args_) {} | ||||
template <typename Fn> void match(Fn F) const { | template <typename Fn> void match(Fn F) const { | ||||
F(Callee, Args, getPrecedence()); | F(Callee, Args, getPrecedence()); | ||||
} | } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
Callee->print(OB); | Callee->print(OB); | ||||
OB.printOpen(); | OB.printOpen(); | ||||
Args.printWithComma(OB); | Args.printWithComma(OB); | ||||
OB.printClose(); | OB.printClose(); | ||||
} | } | ||||
friend bool operator==(CallExpr const &LHS, CallExpr const &RHS) { | |||||
return LHS.Callee->equals(RHS.Callee) && LHS.Args == RHS.Args; | |||||
} | |||||
friend bool operator!=(CallExpr const &LHS, CallExpr const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class NewExpr : public Node { | class NewExpr : public Node { | ||||
// new (expr_list) type(init_list) | // new (expr_list) type(init_list) | ||||
NodeArray ExprList; | NodeArray ExprList; | ||||
Node *Type; | Node *Type; | ||||
NodeArray InitList; | NodeArray InitList; | ||||
bool IsGlobal; // ::operator new ? | bool IsGlobal; // ::operator new ? | ||||
Show All 22 Lines | void printLeft(OutputBuffer &OB) const override { | ||||
OB += " "; | OB += " "; | ||||
Type->print(OB); | Type->print(OB); | ||||
if (!InitList.empty()) { | if (!InitList.empty()) { | ||||
OB.printOpen(); | OB.printOpen(); | ||||
InitList.printWithComma(OB); | InitList.printWithComma(OB); | ||||
OB.printClose(); | 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; | |||||
} | |||||
friend bool operator!=(NewExpr const &LHS, NewExpr const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class DeleteExpr : public Node { | class DeleteExpr : public Node { | ||||
Node *Op; | Node *Op; | ||||
bool IsGlobal; | bool IsGlobal; | ||||
bool IsArray; | bool IsArray; | ||||
public: | public: | ||||
Show All 9 Lines | void printLeft(OutputBuffer &OB) const override { | ||||
if (IsGlobal) | if (IsGlobal) | ||||
OB += "::"; | OB += "::"; | ||||
OB += "delete"; | OB += "delete"; | ||||
if (IsArray) | if (IsArray) | ||||
OB += "[]"; | OB += "[]"; | ||||
OB += ' '; | OB += ' '; | ||||
Op->print(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); | |||||
} | |||||
friend bool operator!=(DeleteExpr const &LHS, DeleteExpr const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class PrefixExpr : public Node { | class PrefixExpr : public Node { | ||||
StringView Prefix; | StringView Prefix; | ||||
Node *Child; | Node *Child; | ||||
public: | public: | ||||
PrefixExpr(StringView Prefix_, Node *Child_, Prec Prec_) | PrefixExpr(StringView Prefix_, Node *Child_, Prec Prec_) | ||||
: Node(KPrefixExpr, Prec_), Prefix(Prefix_), Child(Child_) {} | : Node(KPrefixExpr, Prec_), Prefix(Prefix_), Child(Child_) {} | ||||
template <typename Fn> void match(Fn F) const { | template <typename Fn> void match(Fn F) const { | ||||
F(Prefix, Child, getPrecedence()); | F(Prefix, Child, getPrecedence()); | ||||
} | } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB += Prefix; | OB += Prefix; | ||||
Child->printAsOperand(OB, getPrecedence()); | Child->printAsOperand(OB, getPrecedence()); | ||||
} | } | ||||
friend bool operator==(PrefixExpr const &LHS, PrefixExpr const &RHS) { | |||||
return LHS.Prefix == RHS.Prefix && LHS.Child->equals(RHS.Child); | |||||
} | |||||
friend bool operator!=(PrefixExpr const &LHS, PrefixExpr const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class FunctionParam : public Node { | class FunctionParam : public Node { | ||||
StringView Number; | StringView Number; | ||||
public: | public: | ||||
FunctionParam(StringView Number_) : Node(KFunctionParam), Number(Number_) {} | FunctionParam(StringView Number_) : Node(KFunctionParam), Number(Number_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Number); } | template<typename Fn> void match(Fn F) const { F(Number); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB += "fp"; | OB += "fp"; | ||||
OB += Number; | OB += Number; | ||||
} | } | ||||
friend bool operator==(FunctionParam const &LHS, FunctionParam const &RHS) { | |||||
return LHS.Number == RHS.Number; | |||||
} | |||||
friend bool operator!=(FunctionParam const &LHS, FunctionParam const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class ConversionExpr : public Node { | class ConversionExpr : public Node { | ||||
const Node *Type; | const Node *Type; | ||||
NodeArray Expressions; | NodeArray Expressions; | ||||
public: | public: | ||||
ConversionExpr(const Node *Type_, NodeArray Expressions_, Prec Prec_) | ConversionExpr(const Node *Type_, NodeArray Expressions_, Prec Prec_) | ||||
: Node(KConversionExpr, Prec_), Type(Type_), Expressions(Expressions_) {} | : Node(KConversionExpr, Prec_), Type(Type_), Expressions(Expressions_) {} | ||||
template <typename Fn> void match(Fn F) const { | template <typename Fn> void match(Fn F) const { | ||||
F(Type, Expressions, getPrecedence()); | F(Type, Expressions, getPrecedence()); | ||||
} | } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB.printOpen(); | OB.printOpen(); | ||||
Type->print(OB); | Type->print(OB); | ||||
OB.printClose(); | OB.printClose(); | ||||
OB.printOpen(); | OB.printOpen(); | ||||
Expressions.printWithComma(OB); | Expressions.printWithComma(OB); | ||||
OB.printClose(); | OB.printClose(); | ||||
} | } | ||||
friend bool operator==(ConversionExpr const &LHS, ConversionExpr const &RHS) { | |||||
return LHS.Type->equals(RHS.Type) && LHS.Expressions == RHS.Expressions; | |||||
} | |||||
friend bool operator!=(ConversionExpr const &LHS, ConversionExpr const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class PointerToMemberConversionExpr : public Node { | class PointerToMemberConversionExpr : public Node { | ||||
const Node *Type; | const Node *Type; | ||||
const Node *SubExpr; | const Node *SubExpr; | ||||
StringView Offset; | StringView Offset; | ||||
public: | public: | ||||
Show All 9 Lines | public: | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB.printOpen(); | OB.printOpen(); | ||||
Type->print(OB); | Type->print(OB); | ||||
OB.printClose(); | OB.printClose(); | ||||
OB.printOpen(); | OB.printOpen(); | ||||
SubExpr->print(OB); | SubExpr->print(OB); | ||||
OB.printClose(); | 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); | |||||
} | |||||
friend bool operator!=(PointerToMemberConversionExpr const &LHS, | |||||
PointerToMemberConversionExpr const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class InitListExpr : public Node { | class InitListExpr : public Node { | ||||
const Node *Ty; | const Node *Ty; | ||||
NodeArray Inits; | NodeArray Inits; | ||||
public: | public: | ||||
InitListExpr(const Node *Ty_, NodeArray Inits_) | InitListExpr(const Node *Ty_, NodeArray Inits_) | ||||
: Node(KInitListExpr), Ty(Ty_), Inits(Inits_) {} | : Node(KInitListExpr), Ty(Ty_), Inits(Inits_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Ty, Inits); } | template<typename Fn> void match(Fn F) const { F(Ty, Inits); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
if (Ty) | if (Ty) | ||||
Ty->print(OB); | Ty->print(OB); | ||||
OB += '{'; | OB += '{'; | ||||
Inits.printWithComma(OB); | Inits.printWithComma(OB); | ||||
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; | |||||
} | |||||
friend bool operator!=(InitListExpr const &LHS, InitListExpr const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class BracedExpr : public Node { | class BracedExpr : public Node { | ||||
const Node *Elem; | const Node *Elem; | ||||
const Node *Init; | const Node *Init; | ||||
bool IsArray; | bool IsArray; | ||||
public: | public: | ||||
BracedExpr(const Node *Elem_, const Node *Init_, bool IsArray_) | BracedExpr(const Node *Elem_, const Node *Init_, bool IsArray_) | ||||
Show All 9 Lines | void printLeft(OutputBuffer &OB) const override { | ||||
} else { | } else { | ||||
OB += '.'; | OB += '.'; | ||||
Elem->print(OB); | Elem->print(OB); | ||||
} | } | ||||
if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr) | if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr) | ||||
OB += " = "; | OB += " = "; | ||||
Init->print(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); | |||||
} | |||||
friend bool operator!=(BracedExpr const &LHS, BracedExpr const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class BracedRangeExpr : public Node { | class BracedRangeExpr : public Node { | ||||
const Node *First; | const Node *First; | ||||
const Node *Last; | const Node *Last; | ||||
const Node *Init; | const Node *Init; | ||||
public: | public: | ||||
BracedRangeExpr(const Node *First_, const Node *Last_, const Node *Init_) | BracedRangeExpr(const Node *First_, const Node *Last_, const Node *Init_) | ||||
: Node(KBracedRangeExpr), First(First_), Last(Last_), Init(Init_) {} | : Node(KBracedRangeExpr), First(First_), Last(Last_), Init(Init_) {} | ||||
template<typename Fn> void match(Fn F) const { F(First, Last, Init); } | template<typename Fn> void match(Fn F) const { F(First, Last, Init); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB += '['; | OB += '['; | ||||
First->print(OB); | First->print(OB); | ||||
OB += " ... "; | OB += " ... "; | ||||
Last->print(OB); | Last->print(OB); | ||||
OB += ']'; | OB += ']'; | ||||
if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr) | if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr) | ||||
OB += " = "; | OB += " = "; | ||||
Init->print(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); | |||||
} | |||||
friend bool operator!=(BracedRangeExpr const &LHS, | |||||
BracedRangeExpr const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class FoldExpr : public Node { | class FoldExpr : public Node { | ||||
const Node *Pack, *Init; | const Node *Pack, *Init; | ||||
StringView OperatorName; | StringView OperatorName; | ||||
bool IsLeftFold; | bool IsLeftFold; | ||||
public: | public: | ||||
Show All 31 Lines | if (IsLeftFold || Init != nullptr) { | ||||
OB << " " << OperatorName << " "; | OB << " " << OperatorName << " "; | ||||
if (IsLeftFold) | if (IsLeftFold) | ||||
PrintPack(); | PrintPack(); | ||||
else | else | ||||
Init->printAsOperand(OB, Prec::Cast, true); | Init->printAsOperand(OB, Prec::Cast, true); | ||||
} | } | ||||
OB.printClose(); | 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; | |||||
if (LHS.Init != nullptr && RHS.Init != nullptr) | |||||
return LHS.Init->equals(RHS.Init); | |||||
return LHS.Init == nullptr && RHS.Init == nullptr; | |||||
} | |||||
friend bool operator!=(FoldExpr const &LHS, FoldExpr const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class ThrowExpr : public Node { | class ThrowExpr : public Node { | ||||
const Node *Op; | const Node *Op; | ||||
public: | public: | ||||
ThrowExpr(const Node *Op_) : Node(KThrowExpr), Op(Op_) {} | ThrowExpr(const Node *Op_) : Node(KThrowExpr), Op(Op_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Op); } | template<typename Fn> void match(Fn F) const { F(Op); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB += "throw "; | OB += "throw "; | ||||
Op->print(OB); | Op->print(OB); | ||||
} | } | ||||
friend bool operator==(ThrowExpr const &LHS, ThrowExpr const &RHS) { | |||||
return LHS.Op->equals(RHS.Op); | |||||
} | |||||
friend bool operator!=(ThrowExpr const &LHS, ThrowExpr const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class BoolExpr : public Node { | class BoolExpr : public Node { | ||||
bool Value; | bool Value; | ||||
public: | public: | ||||
BoolExpr(bool Value_) : Node(KBoolExpr), Value(Value_) {} | BoolExpr(bool Value_) : Node(KBoolExpr), Value(Value_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Value); } | template<typename Fn> void match(Fn F) const { F(Value); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB += Value ? StringView("true") : StringView("false"); | OB += Value ? StringView("true") : StringView("false"); | ||||
} | } | ||||
friend bool operator==(BoolExpr const &LHS, BoolExpr const &RHS) { | |||||
return LHS.Value == RHS.Value; | |||||
} | |||||
friend bool operator!=(BoolExpr const &LHS, BoolExpr const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class StringLiteral : public Node { | class StringLiteral : public Node { | ||||
const Node *Type; | const Node *Type; | ||||
public: | public: | ||||
StringLiteral(const Node *Type_) : Node(KStringLiteral), Type(Type_) {} | StringLiteral(const Node *Type_) : Node(KStringLiteral), Type(Type_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Type); } | template<typename Fn> void match(Fn F) const { F(Type); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB += "\"<"; | OB += "\"<"; | ||||
Type->print(OB); | Type->print(OB); | ||||
OB += ">\""; | OB += ">\""; | ||||
} | } | ||||
friend bool operator==(StringLiteral const &LHS, StringLiteral const &RHS) { | |||||
assert(LHS.Type != nullptr); | |||||
assert(RHS.Type != nullptr); | |||||
return LHS.Type->equals(RHS.Type); | |||||
} | |||||
friend bool operator!=(StringLiteral const &LHS, StringLiteral const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class LambdaExpr : public Node { | class LambdaExpr : public Node { | ||||
const Node *Type; | const Node *Type; | ||||
public: | public: | ||||
LambdaExpr(const Node *Type_) : Node(KLambdaExpr), Type(Type_) {} | LambdaExpr(const Node *Type_) : Node(KLambdaExpr), Type(Type_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Type); } | template<typename Fn> void match(Fn F) const { F(Type); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB += "[]"; | OB += "[]"; | ||||
if (Type->getKind() == KClosureTypeName) | if (Type->getKind() == KClosureTypeName) | ||||
static_cast<const ClosureTypeName *>(Type)->printDeclarator(OB); | static_cast<const ClosureTypeName *>(Type)->printDeclarator(OB); | ||||
OB += "{...}"; | OB += "{...}"; | ||||
} | } | ||||
friend bool operator==(LambdaExpr const &LHS, LambdaExpr const &RHS) { | |||||
return LHS.Type->equals(RHS.Type); | |||||
} | |||||
friend bool operator!=(LambdaExpr const &LHS, LambdaExpr const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class EnumLiteral : public Node { | class EnumLiteral : public Node { | ||||
// ty(integer) | // ty(integer) | ||||
const Node *Ty; | const Node *Ty; | ||||
StringView Integer; | StringView Integer; | ||||
public: | public: | ||||
EnumLiteral(const Node *Ty_, StringView Integer_) | EnumLiteral(const Node *Ty_, StringView Integer_) | ||||
: Node(KEnumLiteral), Ty(Ty_), Integer(Integer_) {} | : Node(KEnumLiteral), Ty(Ty_), Integer(Integer_) {} | ||||
template<typename Fn> void match(Fn F) const { F(Ty, Integer); } | template<typename Fn> void match(Fn F) const { F(Ty, Integer); } | ||||
void printLeft(OutputBuffer &OB) const override { | void printLeft(OutputBuffer &OB) const override { | ||||
OB.printOpen(); | OB.printOpen(); | ||||
Ty->print(OB); | Ty->print(OB); | ||||
OB.printClose(); | OB.printClose(); | ||||
if (Integer[0] == 'n') | if (Integer[0] == 'n') | ||||
OB << "-" << Integer.dropFront(1); | OB << "-" << Integer.dropFront(1); | ||||
else | else | ||||
OB << Integer; | OB << Integer; | ||||
} | } | ||||
friend bool operator==(EnumLiteral const &LHS, EnumLiteral const &RHS) { | |||||
assert(LHS.Ty != nullptr); | |||||
assert(RHS.Ty != nullptr); | |||||
return LHS.Integer == RHS.Integer && LHS.Ty->equals(RHS.Ty); | |||||
} | |||||
friend bool operator!=(EnumLiteral const &LHS, EnumLiteral const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
class IntegerLiteral : public Node { | class IntegerLiteral : public Node { | ||||
StringView Type; | StringView Type; | ||||
StringView Value; | StringView Value; | ||||
public: | public: | ||||
IntegerLiteral(StringView Type_, StringView Value_) | IntegerLiteral(StringView Type_, StringView Value_) | ||||
Show All 12 Lines | if (Value[0] == 'n') { | ||||
OB += '-'; | OB += '-'; | ||||
OB += Value.dropFront(1); | OB += Value.dropFront(1); | ||||
} else | } else | ||||
OB += Value; | OB += Value; | ||||
if (Type.size() <= 3) | if (Type.size() <= 3) | ||||
OB += Type; | OB += Type; | ||||
} | } | ||||
friend bool operator==(IntegerLiteral const &LHS, IntegerLiteral const &RHS) { | |||||
return LHS.Type == RHS.Type && LHS.Value == RHS.Value; | |||||
} | |||||
friend bool operator!=(IntegerLiteral const &LHS, IntegerLiteral const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
template <class Float> struct FloatData; | template <class Float> struct FloatData; | ||||
namespace float_literal_impl { | namespace float_literal_impl { | ||||
constexpr Node::Kind getFloatLiteralKind(float *) { | constexpr Node::Kind getFloatLiteralKind(float *) { | ||||
return Node::KFloatLiteral; | return Node::KFloatLiteral; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ | #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ | ||||
std::reverse(buf, e); | std::reverse(buf, e); | ||||
#endif | #endif | ||||
char num[FloatData<Float>::max_demangled_size] = {0}; | char num[FloatData<Float>::max_demangled_size] = {0}; | ||||
int n = snprintf(num, sizeof(num), FloatData<Float>::spec, value); | int n = snprintf(num, sizeof(num), FloatData<Float>::spec, value); | ||||
OB += StringView(num, num + n); | OB += StringView(num, num + n); | ||||
} | } | ||||
} | } | ||||
friend bool operator==(FloatLiteralImpl<Float> const &LHS, | |||||
FloatLiteralImpl<Float> const &RHS) { | |||||
return LHS.Contents == RHS.Contents; | |||||
} | |||||
friend bool operator!=(FloatLiteralImpl<Float> const &LHS, | |||||
FloatLiteralImpl<Float> const &RHS) { | |||||
return !(LHS == RHS); | |||||
} | |||||
}; | }; | ||||
using FloatLiteral = FloatLiteralImpl<float>; | using FloatLiteral = FloatLiteralImpl<float>; | ||||
using DoubleLiteral = FloatLiteralImpl<double>; | using DoubleLiteral = FloatLiteralImpl<double>; | ||||
using LongDoubleLiteral = FloatLiteralImpl<long double>; | using LongDoubleLiteral = FloatLiteralImpl<long double>; | ||||
/// Visit the node. Calls \c F(P), where \c P is the node cast to the | /// Visit the node. Calls \c F(P), where \c P is the node cast to the | ||||
/// appropriate derived class. | /// appropriate derived class. | ||||
▲ Show 20 Lines • Show All 3,133 Lines • Show Last 20 Lines |