//===--- ItaniumDemangle.h -----------*- mode:c++;eval:(read-only-mode) -*-===// // Do not edit! See README.txt. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Generic itanium demangler library. // There are two copies of this file in the source tree. The one under // libcxxabi is the original and the one under llvm is the copy. Use // cp-to-llvm.sh to update the copy. See README.txt for more details. // //===----------------------------------------------------------------------===// #ifndef DEMANGLE_ITANIUMDEMANGLE_H #define DEMANGLE_ITANIUMDEMANGLE_H #include "DemangleConfig.h" #include "StringViewExtras.h" #include "Utility.h" #include <algorithm> #include <cctype> #include <cstdio> #include <cstdlib> #include <cstring> #include <limits> #include <new> #include <string_view> #include <type_traits> #include <utility> #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-template" #endif DEMANGLE_NAMESPACE_BEGIN template <class T, size_t N> class PODSmallVector { … }; class NodeArray; // Base class of all AST nodes. The AST is built by the parser, then is // traversed by the printLeft/Right functions to produce a demangled string. class Node { … }; class NodeArray { … }; struct NodeArrayNode : Node { … }; class DotSuffix final : public Node { … }; class VendorExtQualType final : public Node { … }; enum FunctionRefQual : unsigned char { … }; enum Qualifiers { … }; inline Qualifiers operator|=(Qualifiers &Q1, Qualifiers Q2) { … } class QualType final : public Node { … }; class ConversionOperatorType final : public Node { … }; class PostfixQualifiedType final : public Node { … }; class NameType final : public Node { … }; class BitIntType final : public Node { … }; class ElaboratedTypeSpefType : public Node { … }; class TransformedType : public Node { … }; struct AbiTagAttr : Node { … }; class EnableIfAttr : public Node { … }; class ObjCProtoName : public Node { … }; class PointerType final : public Node { … }; enum class ReferenceKind { … }; // Represents either a LValue or an RValue reference type. class ReferenceType : public Node { … }; class PointerToMemberType final : public Node { … }; class ArrayType final : public Node { … }; class FunctionType final : public Node { … }; class NoexceptSpec : public Node { … }; class DynamicExceptionSpec : public Node { … }; /// Represents the explicitly named object parameter. /// E.g., /// \code{.cpp} /// struct Foo { /// void bar(this Foo && self); /// }; /// \endcode class ExplicitObjectParameter final : public Node { … }; class FunctionEncoding final : public Node { … }; class LiteralOperator : public Node { … }; class SpecialName final : public Node { … }; class CtorVtableSpecialName final : public Node { … }; struct NestedName : Node { … }; struct MemberLikeFriendName : Node { … }; struct ModuleName : Node { … }; struct ModuleEntity : Node { … }; struct LocalName : Node { … }; class QualifiedName final : public Node { … }; class VectorType final : public Node { … }; class PixelVectorType final : public Node { … }; class BinaryFPType final : public Node { … }; enum class TemplateParamKind { … }; /// An invented name for a template parameter for which we don't have a /// corresponding template argument. /// /// This node is created when parsing the <lambda-sig> for a lambda with /// explicit template arguments, which might be referenced in the parameter /// types appearing later in the <lambda-sig>. class SyntheticTemplateParamName final : public Node { … }; class TemplateParamQualifiedArg final : public Node { … }; /// A template type parameter declaration, 'typename T'. class TypeTemplateParamDecl final : public Node { … }; /// A constrained template type parameter declaration, 'C<U> T'. class ConstrainedTypeTemplateParamDecl final : public Node { … }; /// A non-type template parameter declaration, 'int N'. class NonTypeTemplateParamDecl final : public Node { … }; /// A template template parameter declaration, /// 'template<typename T> typename N'. class TemplateTemplateParamDecl final : public Node { … }; /// A template parameter pack declaration, 'typename ...T'. class TemplateParamPackDecl final : public Node { … }; /// An unexpanded parameter pack (either in the expression or type context). If /// this AST is correct, this node will have a ParameterPackExpansion node above /// it. /// /// 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 /// appear in the final AST, it has to referenced via a <template-param> (ie, /// T_). class ParameterPack final : public Node { … }; /// A variadic template argument. This node represents an occurrence of /// J<something>E in some <template-args>. It isn't itself unexpanded, unless /// one of its Elements is. The parser inserts a ParameterPack into the /// TemplateParams table if the <template-args> this pack belongs to apply to an /// <encoding>. class TemplateArgumentPack final : public Node { … }; /// A pack expansion. Below this node, there are some unexpanded ParameterPacks /// which each have Child->ParameterPackSize elements. class ParameterPackExpansion final : public Node { … }; class TemplateArgs final : public Node { … }; /// A forward-reference to a template argument that was not known at the point /// where the template parameter name was parsed in a mangling. /// /// This is created when demangling the name of a specialization of a /// conversion function template: /// /// \code /// struct A { /// template<typename T> operator T*(); /// }; /// \endcode /// /// When demangling a specialization of the conversion function template, we /// encounter the name of the template (including the \c T) before we reach /// the template argument list, so we cannot substitute the parameter name /// for the corresponding argument while parsing. Instead, we create a /// \c ForwardTemplateReference node that is resolved after we parse the /// template arguments. struct ForwardTemplateReference : Node { … }; struct NameWithTemplateArgs : Node { … }; class GlobalQualifiedName final : public Node { … }; enum class SpecialSubKind { … }; class SpecialSubstitution; class ExpandedSpecialSubstitution : public Node { … }; class SpecialSubstitution final : public ExpandedSpecialSubstitution { … }; inline ExpandedSpecialSubstitution::ExpandedSpecialSubstitution( SpecialSubstitution const *SS) : … { … } class CtorDtorName final : public Node { … }; class DtorName : public Node { … }; class UnnamedTypeName : public Node { … }; class ClosureTypeName : public Node { … }; class StructuredBindingName : public Node { … }; // -- Expression Nodes -- class BinaryExpr : public Node { … }; class ArraySubscriptExpr : public Node { … }; class PostfixExpr : public Node { … }; class ConditionalExpr : public Node { … }; class MemberExpr : public Node { … }; class SubobjectExpr : public Node { … }; class EnclosingExpr : public Node { … }; class CastExpr : public Node { … }; class SizeofParamPackExpr : public Node { … }; class CallExpr : public Node { … }; class NewExpr : public Node { … }; class DeleteExpr : public Node { … }; class PrefixExpr : public Node { … }; class FunctionParam : public Node { … }; class ConversionExpr : public Node { … }; class PointerToMemberConversionExpr : public Node { … }; class InitListExpr : public Node { … }; class BracedExpr : public Node { … }; class BracedRangeExpr : public Node { … }; class FoldExpr : public Node { … }; class ThrowExpr : public Node { … }; class BoolExpr : public Node { … }; class StringLiteral : public Node { … }; class LambdaExpr : public Node { … }; class EnumLiteral : public Node { … }; class IntegerLiteral : public Node { … }; class RequiresExpr : public Node { … }; class ExprRequirement : public Node { … }; class TypeRequirement : public Node { … }; class NestedRequirement : public Node { … }; template <class Float> struct FloatData; namespace float_literal_impl { constexpr Node::Kind getFloatLiteralKind(float *) { … } constexpr Node::Kind getFloatLiteralKind(double *) { … } constexpr Node::Kind getFloatLiteralKind(long double *) { … } } template <class Float> class FloatLiteralImpl : public Node { … }; FloatLiteral; DoubleLiteral; LongDoubleLiteral; /// Visit the node. Calls \c F(P), where \c P is the node cast to the /// appropriate derived class. template<typename Fn> void Node::visit(Fn F) const { … } /// Determine the kind of a node from its type. template<typename NodeT> struct NodeKind; #define NODE … #include "ItaniumNodes.def" inline bool NodeArray::printAsString(OutputBuffer &OB) const { … } template <typename Derived, typename Alloc> struct AbstractManglingParser { … }; const char* parse_discriminator(const char* first, const char* last); // <name> ::= <nested-name> // N // ::= <local-name> # See Scope Encoding below // Z // ::= <unscoped-template-name> <template-args> // ::= <unscoped-name> // // <unscoped-template-name> ::= <unscoped-name> // ::= <substitution> template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseName(NameState *State) { … } // <local-name> := Z <function encoding> E <entity name> [<discriminator>] // := Z <function encoding> E s [<discriminator>] // := Z <function encoding> Ed [ <parameter number> ] _ <entity name> template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseLocalName(NameState *State) { … } // <unscoped-name> ::= <unqualified-name> // ::= St <unqualified-name> # ::std:: // [*] extension template <typename Derived, typename Alloc> Node * AbstractManglingParser<Derived, Alloc>::parseUnscopedName(NameState *State, bool *IsSubst) { … } // <unqualified-name> ::= [<module-name>] F? L? <operator-name> [<abi-tags>] // ::= [<module-name>] <ctor-dtor-name> [<abi-tags>] // ::= [<module-name>] F? L? <source-name> [<abi-tags>] // ::= [<module-name>] L? <unnamed-type-name> [<abi-tags>] // # structured binding declaration // ::= [<module-name>] L? DC <source-name>+ E template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseUnqualifiedName( NameState *State, Node *Scope, ModuleName *Module) { … } // <module-name> ::= <module-subname> // ::= <module-name> <module-subname> // ::= <substitution> # passed in by caller // <module-subname> ::= W <source-name> // ::= W P <source-name> template <typename Derived, typename Alloc> bool AbstractManglingParser<Derived, Alloc>::parseModuleNameOpt( ModuleName *&Module) { … } // <unnamed-type-name> ::= Ut [<nonnegative number>] _ // ::= <closure-type-name> // // <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _ // // <lambda-sig> ::= <template-param-decl>* [Q <requires-clause expression>] // <parameter type>+ # or "v" if the lambda has no parameters template <typename Derived, typename Alloc> Node * AbstractManglingParser<Derived, Alloc>::parseUnnamedTypeName(NameState *State) { … } // <source-name> ::= <positive length number> <identifier> template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseSourceName(NameState *) { … } // Operator encodings template <typename Derived, typename Alloc> const typename AbstractManglingParser< Derived, Alloc>::OperatorInfo AbstractManglingParser<Derived, Alloc>::Ops[] = …; template <typename Derived, typename Alloc> const size_t AbstractManglingParser<Derived, Alloc>::NumOps = …; // If the next 2 chars are an operator encoding, consume them and return their // OperatorInfo. Otherwise return nullptr. template <typename Derived, typename Alloc> const typename AbstractManglingParser<Derived, Alloc>::OperatorInfo * AbstractManglingParser<Derived, Alloc>::parseOperatorEncoding() { … } // <operator-name> ::= See parseOperatorEncoding() // ::= li <source-name> # operator "" // ::= v <digit> <source-name> # vendor extended operator template <typename Derived, typename Alloc> Node * AbstractManglingParser<Derived, Alloc>::parseOperatorName(NameState *State) { … } // <ctor-dtor-name> ::= C1 # complete object constructor // ::= C2 # base object constructor // ::= C3 # complete object allocating constructor // extension ::= C4 # gcc old-style "[unified]" constructor // extension ::= C5 # the COMDAT used for ctors // ::= D0 # deleting destructor // ::= D1 # complete object destructor // ::= D2 # base object destructor // extension ::= D4 # gcc old-style "[unified]" destructor // extension ::= D5 # the COMDAT used for dtors template <typename Derived, typename Alloc> Node * AbstractManglingParser<Derived, Alloc>::parseCtorDtorName(Node *&SoFar, NameState *State) { … } // <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix> // <unqualified-name> E // ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix> // <template-args> E // // <prefix> ::= <prefix> <unqualified-name> // ::= <template-prefix> <template-args> // ::= <template-param> // ::= <decltype> // ::= # empty // ::= <substitution> // ::= <prefix> <data-member-prefix> // [*] extension // // <data-member-prefix> := <member source-name> [<template-args>] M // // <template-prefix> ::= <prefix> <template unqualified-name> // ::= <template-param> // ::= <substitution> template <typename Derived, typename Alloc> Node * AbstractManglingParser<Derived, Alloc>::parseNestedName(NameState *State) { … } // <simple-id> ::= <source-name> [ <template-args> ] template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseSimpleId() { … } // <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f()) // ::= <simple-id> # e.g., ~A<2*N> template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseDestructorName() { … } // <unresolved-type> ::= <template-param> // ::= <decltype> // ::= <substitution> template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedType() { … } // <base-unresolved-name> ::= <simple-id> # unresolved name // extension ::= <operator-name> # unresolved operator-function-id // extension ::= <operator-name> <template-args> # unresolved operator template-id // ::= on <operator-name> # unresolved operator-function-id // ::= on <operator-name> <template-args> # unresolved operator template-id // ::= dn <destructor-name> # destructor or pseudo-destructor; // # e.g. ~X or ~X<N-1> template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseBaseUnresolvedName() { … } // <unresolved-name> // extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name> // ::= [gs] <base-unresolved-name> # x or (with "gs") ::x // ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name> // # A::x, N::y, A<T>::z; "gs" means leading "::" // [gs] has been parsed by caller. // ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x // extension ::= sr <unresolved-type> <template-args> <base-unresolved-name> // # T::N::x /decltype(p)::N::x // (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name> // // <unresolved-qualifier-level> ::= <simple-id> template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedName(bool Global) { … } // <abi-tags> ::= <abi-tag> [<abi-tags>] // <abi-tag> ::= B <source-name> template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseAbiTags(Node *N) { … } // <number> ::= [n] <non-negative decimal integer> template <typename Alloc, typename Derived> std::string_view AbstractManglingParser<Alloc, Derived>::parseNumber(bool AllowNegative) { … } // <positive length number> ::= [0-9]* template <typename Alloc, typename Derived> bool AbstractManglingParser<Alloc, Derived>::parsePositiveInteger(size_t *Out) { … } template <typename Alloc, typename Derived> std::string_view AbstractManglingParser<Alloc, Derived>::parseBareSourceName() { … } // <function-type> ::= [<CV-qualifiers>] [<exception-spec>] [Dx] F [Y] <bare-function-type> [<ref-qualifier>] E // // <exception-spec> ::= Do # non-throwing exception-specification (e.g., noexcept, throw()) // ::= DO <expression> E # computed (instantiation-dependent) noexcept // ::= Dw <type>+ E # dynamic exception specification with instantiation-dependent types // // <ref-qualifier> ::= R # & ref-qualifier // <ref-qualifier> ::= O # && ref-qualifier template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseFunctionType() { … } // extension: // <vector-type> ::= Dv <positive dimension number> _ <extended element type> // ::= Dv [<dimension expression>] _ <element type> // <extended element type> ::= <element type> // ::= p # AltiVec vector pixel template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseVectorType() { … } // <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x) // ::= DT <expression> E # decltype of an expression (C++0x) template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseDecltype() { … } // <array-type> ::= A <positive dimension number> _ <element type> // ::= A [<dimension expression>] _ <element type> template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseArrayType() { … } // <pointer-to-member-type> ::= M <class type> <member type> template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parsePointerToMemberType() { … } // <class-enum-type> ::= <name> # non-dependent type name, dependent type name, or dependent typename-specifier // ::= Ts <name> # dependent elaborated type specifier using 'struct' or 'class' // ::= Tu <name> # dependent elaborated type specifier using 'union' // ::= Te <name> # dependent elaborated type specifier using 'enum' template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseClassEnumType() { … } // <qualified-type> ::= <qualifiers> <type> // <qualifiers> ::= <extended-qualifier>* <CV-qualifiers> // <extended-qualifier> ::= U <source-name> [<template-args>] # vendor extended type qualifier template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseQualifiedType() { … } // <type> ::= <builtin-type> // ::= <qualified-type> // ::= <function-type> // ::= <class-enum-type> // ::= <array-type> // ::= <pointer-to-member-type> // ::= <template-param> // ::= <template-template-param> <template-args> // ::= <decltype> // ::= P <type> # pointer // ::= R <type> # l-value reference // ::= O <type> # r-value reference (C++11) // ::= C <type> # complex pair (C99) // ::= G <type> # imaginary (C99) // ::= <substitution> # See Compression below // extension ::= U <objc-name> <objc-type> # objc-type<identifier> // extension ::= <vector-type> # <vector-type> starts with Dv // // <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + <number of digits in k1> + k1 // <objc-type> ::= <source-name> # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name> template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseType() { … } template <typename Derived, typename Alloc> Node * AbstractManglingParser<Derived, Alloc>::parsePrefixExpr(std::string_view Kind, Node::Prec Prec) { … } template <typename Derived, typename Alloc> Node * AbstractManglingParser<Derived, Alloc>::parseBinaryExpr(std::string_view Kind, Node::Prec Prec) { … } template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseIntegerLiteral( std::string_view Lit) { … } // <CV-Qualifiers> ::= [r] [V] [K] template <typename Alloc, typename Derived> Qualifiers AbstractManglingParser<Alloc, Derived>::parseCVQualifiers() { … } // <function-param> ::= fp <top-level CV-Qualifiers> _ # L == 0, first parameter // ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters // ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _ # L > 0, first parameter // ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters // ::= fpT # 'this' expression (not part of standard?) template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseFunctionParam() { … } // cv <type> <expression> # conversion with one argument // cv <type> _ <expression>* E # conversion with a different number of arguments template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseConversionExpr() { … } // <expr-primary> ::= L <type> <value number> E # integer literal // ::= L <type> <value float> E # floating literal // ::= L <string type> E # string literal // ::= L <nullptr type> E # nullptr literal (i.e., "LDnE") // ::= L <lambda type> E # lambda expression // FIXME: ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000) // ::= L <mangled-name> E # external name template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseExprPrimary() { … } // <braced-expression> ::= <expression> // ::= di <field source-name> <braced-expression> # .name = expr // ::= dx <index expression> <braced-expression> # [expr] = expr // ::= dX <range begin expression> <range end expression> <braced-expression> template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseBracedExpr() { … } // (not yet in the spec) // <fold-expr> ::= fL <binary-operator-name> <expression> <expression> // ::= fR <binary-operator-name> <expression> <expression> // ::= fl <binary-operator-name> <expression> // ::= fr <binary-operator-name> <expression> template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseFoldExpr() { … } // <expression> ::= mc <parameter type> <expr> [<offset number>] E // // Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47 template <typename Derived, typename Alloc> Node * AbstractManglingParser<Derived, Alloc>::parsePointerToMemberConversionExpr( Node::Prec Prec) { … } // <expression> ::= so <referent type> <expr> [<offset number>] <union-selector>* [p] E // <union-selector> ::= _ [<number>] // // Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47 template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseSubobjectExpr() { … } template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseConstraintExpr() { … } template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseRequiresExpr() { … } // <expression> ::= <unary operator-name> <expression> // ::= <binary operator-name> <expression> <expression> // ::= <ternary operator-name> <expression> <expression> <expression> // ::= cl <expression>+ E # call // ::= cv <type> <expression> # conversion with one argument // ::= cv <type> _ <expression>* E # conversion with a different number of arguments // ::= [gs] nw <expression>* _ <type> E # new (expr-list) type // ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init) // ::= [gs] na <expression>* _ <type> E # new[] (expr-list) type // ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init) // ::= [gs] dl <expression> # delete expression // ::= [gs] da <expression> # delete[] expression // ::= pp_ <expression> # prefix ++ // ::= mm_ <expression> # prefix -- // ::= ti <type> # typeid (type) // ::= te <expression> # typeid (expression) // ::= dc <type> <expression> # dynamic_cast<type> (expression) // ::= sc <type> <expression> # static_cast<type> (expression) // ::= cc <type> <expression> # const_cast<type> (expression) // ::= rc <type> <expression> # reinterpret_cast<type> (expression) // ::= st <type> # sizeof (a type) // ::= sz <expression> # sizeof (an expression) // ::= at <type> # alignof (a type) // ::= az <expression> # alignof (an expression) // ::= nx <expression> # noexcept (expression) // ::= <template-param> // ::= <function-param> // ::= dt <expression> <unresolved-name> # expr.name // ::= pt <expression> <unresolved-name> # expr->name // ::= ds <expression> <expression> # expr.*expr // ::= sZ <template-param> # size of a parameter pack // ::= sZ <function-param> # size of a function parameter pack // ::= sP <template-arg>* E # sizeof...(T), size of a captured template parameter pack from an alias template // ::= sp <expression> # pack expansion // ::= tw <expression> # throw expression // ::= tr # throw with no operand (rethrow) // ::= <unresolved-name> # f(p), N::f(p), ::f(p), // # freestanding dependent name (e.g., T::x), // # objectless nonstatic member reference // ::= fL <binary-operator-name> <expression> <expression> // ::= fR <binary-operator-name> <expression> <expression> // ::= fl <binary-operator-name> <expression> // ::= fr <binary-operator-name> <expression> // ::= <expr-primary> template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseExpr() { … } // <call-offset> ::= h <nv-offset> _ // ::= v <v-offset> _ // // <nv-offset> ::= <offset number> // # non-virtual base override // // <v-offset> ::= <offset number> _ <virtual offset number> // # virtual base override, with vcall offset template <typename Alloc, typename Derived> bool AbstractManglingParser<Alloc, Derived>::parseCallOffset() { … } // <special-name> ::= TV <type> # virtual table // ::= TT <type> # VTT structure (construction vtable index) // ::= TI <type> # typeinfo structure // ::= TS <type> # typeinfo name (null-terminated byte string) // ::= Tc <call-offset> <call-offset> <base encoding> // # base is the nominal target function of thunk // # first call-offset is 'this' adjustment // # second call-offset is result adjustment // ::= T <call-offset> <base encoding> // # base is the nominal target function of thunk // # Guard variable for one-time initialization // ::= GV <object name> // # No <type> // ::= TW <object name> # Thread-local wrapper // ::= TH <object name> # Thread-local initialization // ::= GR <object name> _ # First temporary // ::= GR <object name> <seq-id> _ # Subsequent temporaries // # construction vtable for second-in-first // extension ::= TC <first type> <number> _ <second type> // extension ::= GR <object name> # reference temporary for object // extension ::= GI <module name> # module global initializer template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseSpecialName() { … } // <encoding> ::= <function name> <bare-function-type> // [`Q` <requires-clause expr>] // ::= <data name> // ::= <special-name> template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseEncoding(bool ParseParams) { … } template <class Float> struct FloatData; template <> struct FloatData<float> { … }; template <> struct FloatData<double> { … }; template <> struct FloatData<long double> { … }; template <typename Alloc, typename Derived> template <class Float> Node *AbstractManglingParser<Alloc, Derived>::parseFloatingLiteral() { … } // <seq-id> ::= <0-9A-Z>+ template <typename Alloc, typename Derived> bool AbstractManglingParser<Alloc, Derived>::parseSeqId(size_t *Out) { … } // <substitution> ::= S <seq-id> _ // ::= S_ // <substitution> ::= Sa # ::std::allocator // <substitution> ::= Sb # ::std::basic_string // <substitution> ::= Ss # ::std::basic_string < char, // ::std::char_traits<char>, // ::std::allocator<char> > // <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> > // <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> > // <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> > // The St case is handled specially in parseNestedName. template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseSubstitution() { … } // <template-param> ::= T_ # first template parameter // ::= T <parameter-2 non-negative number> _ // ::= TL <level-1> __ // ::= TL <level-1> _ <parameter-2 non-negative number> _ template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParam() { … } // <template-param-decl> ::= Ty # type parameter // ::= Tk <concept name> [<template-args>] # constrained type parameter // ::= Tn <type> # non-type parameter // ::= Tt <template-param-decl>* E # template parameter // ::= Tp <template-param-decl> # parameter pack template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParamDecl( TemplateParamList *Params) { … } // <template-arg> ::= <type> # type or template // ::= X <expression> E # expression // ::= <expr-primary> # simple expressions // ::= J <template-arg>* E # argument pack // ::= LZ <encoding> E # extension // ::= <template-param-decl> <template-arg> template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parseTemplateArg() { … } // <template-args> ::= I <template-arg>* [Q <requires-clause expr>] E // extension, the abi says <template-arg>+ template <typename Derived, typename Alloc> Node * AbstractManglingParser<Derived, Alloc>::parseTemplateArgs(bool TagTemplates) { … } // <mangled-name> ::= _Z <encoding> // ::= <type> // extension ::= ___Z <encoding> _block_invoke // extension ::= ___Z <encoding> _block_invoke<decimal-digit>+ // extension ::= ___Z <encoding> _block_invoke_<decimal-digit>+ template <typename Derived, typename Alloc> Node *AbstractManglingParser<Derived, Alloc>::parse(bool ParseParams) { … } template <typename Alloc> struct ManglingParser : AbstractManglingParser<ManglingParser<Alloc>, Alloc> { … }; DEMANGLE_NAMESPACE_END #if defined(__clang__) #pragma clang diagnostic pop #endif #endif // DEMANGLE_ITANIUMDEMANGLE_H