Author: epilk Date: Tue Feb 13 17:08:17 2018 New Revision: 325092 URL: http://llvm.org/viewvc/llvm-project?rev=325092&view=rev Log: [demangler] Simplify the AST for function types, NFC.
Modified: libcxxabi/trunk/src/cxa_demangle.cpp Modified: libcxxabi/trunk/src/cxa_demangle.cpp URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_demangle.cpp?rev=325092&r1=325091&r2=325092&view=diff ============================================================================== --- libcxxabi/trunk/src/cxa_demangle.cpp (original) +++ libcxxabi/trunk/src/cxa_demangle.cpp Tue Feb 13 17:08:17 2018 @@ -176,8 +176,6 @@ public: KArrayType, KFunctionType, KFunctionEncoding, - KFunctionQualType, - KFunctionRefQualType, KLiteralOperator, KSpecialName, KCtorVtableSpecialName, @@ -357,6 +355,12 @@ public: } }; +enum FunctionRefQual : unsigned char { + FrefQualNone, + FrefQualLValue, + FrefQualRValue, +}; + enum Qualifiers { QualNone = 0, QualConst = 0x1, @@ -714,13 +718,16 @@ public: class FunctionType final : public Node { Node *Ret; NodeArray Params; + Qualifiers CVQuals; + FunctionRefQual RefQual; public: - FunctionType(Node *Ret_, NodeArray Params_) + FunctionType(Node *Ret_, NodeArray Params_, Qualifiers CVQuals_, + FunctionRefQual RefQual_) : Node(KFunctionType, Ret_->ParameterPackSize, /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No, /*FunctionCache=*/Cache::Yes), - Ret(Ret_), Params(Params_) { + Ret(Ret_), Params(Params_), CVQuals(CVQuals_), RefQual(RefQual_) { for (Node *P : Params) ParameterPackSize = std::min(ParameterPackSize, P->ParameterPackSize); } @@ -745,6 +752,18 @@ public: Params.printWithComma(S); S += ")"; Ret->printRight(S); + + if (CVQuals & QualConst) + S += " const"; + if (CVQuals & QualVolatile) + S += " volatile"; + if (CVQuals & QualRestrict) + S += " restrict"; + + if (RefQual == FrefQualLValue) + S += " &"; + else if (RefQual == FrefQualRValue) + S += " &&"; } }; @@ -752,13 +771,17 @@ class FunctionEncoding final : public No const Node *Ret; const Node *Name; NodeArray Params; + Qualifiers CVQuals; + FunctionRefQual RefQual; public: - FunctionEncoding(Node *Ret_, Node *Name_, NodeArray Params_) + FunctionEncoding(Node *Ret_, Node *Name_, NodeArray Params_, + Qualifiers CVQuals_, FunctionRefQual RefQual_) : Node(KFunctionEncoding, NoParameterPack, /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No, /*FunctionCache=*/Cache::Yes), - Ret(Ret_), Name(Name_), Params(Params_) { + Ret(Ret_), Name(Name_), Params(Params_), CVQuals(CVQuals_), + RefQual(RefQual_) { for (Node *P : Params) ParameterPackSize = std::min(ParameterPackSize, P->ParameterPackSize); if (Ret) @@ -785,66 +808,19 @@ public: S += ")"; if (Ret) Ret->printRight(S); - } -}; - -enum FunctionRefQual : unsigned char { - FrefQualNone, - FrefQualLValue, - FrefQualRValue, -}; -class FunctionRefQualType : public Node { - Node *Fn; - FunctionRefQual Quals; - - friend class FunctionQualType; - -public: - FunctionRefQualType(Node *Fn_, FunctionRefQual Quals_) - : Node(KFunctionRefQualType, Fn_->ParameterPackSize, - /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No, - /*FunctionCache=*/Cache::Yes), - Fn(Fn_), Quals(Quals_) {} - - bool hasFunctionSlow(OutputStream &) const override { return true; } - bool hasRHSComponentSlow(OutputStream &) const override { return true; } + if (CVQuals & QualConst) + S += " const"; + if (CVQuals & QualVolatile) + S += " volatile"; + if (CVQuals & QualRestrict) + S += " restrict"; - void printQuals(OutputStream &S) const { - if (Quals == FrefQualLValue) + if (RefQual == FrefQualLValue) S += " &"; - else + else if (RefQual == FrefQualRValue) S += " &&"; } - - void printLeft(OutputStream &S) const override { Fn->printLeft(S); } - - void printRight(OutputStream &S) const override { - Fn->printRight(S); - printQuals(S); - } -}; - -class FunctionQualType final : public QualType { -public: - FunctionQualType(Node *Child_, Qualifiers Quals_) - : QualType(Child_, Quals_) { - K = KFunctionQualType; - } - - void printLeft(OutputStream &S) const override { Child->printLeft(S); } - - void printRight(OutputStream &S) const override { - if (Child->getKind() == KFunctionRefQualType) { - auto *RefQuals = static_cast<const FunctionRefQualType *>(Child); - RefQuals->Fn->printRight(S); - printQuals(S); - RefQuals->printQuals(S); - } else { - Child->printRight(S); - printQuals(S); - } - } }; class LiteralOperator : public Node { @@ -2077,7 +2053,7 @@ struct Db { Node *parseArrayType(); Node *parsePointerToMemberType(); Node *parseClassEnumType(); - Node *parseQualifiedType(bool &AppliesToFunction); + Node *parseQualifiedType(); Node *parseNestedName(); Node *parseCtorDtorName(Node *&SoFar); @@ -2384,11 +2360,16 @@ StringView Db::parseBareSourceName() { return R; } -// <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E +// <function-type> ::= [<CV-qualifiers>] [<exception-spec>] [Dx] F [Y] <bare-function-type> [<ref-qualifier>] E // -// <ref-qualifier> ::= R # & ref-qualifier -// <ref-qualifier> ::= O # && ref-qualifier +// <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 Node *Db::parseFunctionType() { + Qualifiers CVQuals = parseCVQualifiers(); if (!consumeIf('F')) return nullptr; consumeIf('Y'); // extern "C" @@ -2418,10 +2399,7 @@ Node *Db::parseFunctionType() { } NodeArray Params = popTrailingNodeArray(ParamsBegin); - Node *Fn = make<FunctionType>(ReturnType, Params); - if (ReferenceQualifier != FrefQualNone) - Fn = make<FunctionRefQualType>(Fn, ReferenceQualifier); - return Fn; + return make<FunctionType>(ReturnType, Params, CVQuals, ReferenceQualifier); } // extension: @@ -2549,7 +2527,7 @@ Node *Db::parseClassEnumType() { // <qualified-type> ::= <qualifiers> <type> // <qualifiers> ::= <extended-qualifier>* <CV-qualifiers> // <extended-qualifier> ::= U <source-name> [<template-args>] # vendor extended type qualifier -Node *Db::parseQualifiedType(bool &AppliesToFunction) { +Node *Db::parseQualifiedType() { if (consumeIf('U')) { StringView Qual = parseBareSourceName(); if (Qual.empty()) @@ -2568,27 +2546,24 @@ Node *Db::parseQualifiedType(bool &Appli } if (Proto.empty()) return nullptr; - Node *Child = parseQualifiedType(AppliesToFunction); + Node *Child = parseQualifiedType(); if (Child == nullptr) return nullptr; return make<ObjCProtoName>(Child, Proto); } - Node *Child = parseQualifiedType(AppliesToFunction); + Node *Child = parseQualifiedType(); if (Child == nullptr) return nullptr; return make<VendorExtQualType>(Child, Qual); } Qualifiers Quals = parseCVQualifiers(); - AppliesToFunction = look() == 'F'; Node *Ty = parseType(); if (Ty == nullptr) return nullptr; - if (Quals != QualNone) { - return AppliesToFunction ? - make<FunctionQualType>(Ty, Quals) : make<QualType>(Ty, Quals); - } + if (Quals != QualNone) + Ty = make<QualType>(Ty, Quals); return Ty; } @@ -2619,16 +2594,19 @@ Node *Db::parseType() { // ::= <qualified-type> case 'r': case 'V': - case 'K': + case 'K': { + unsigned AfterQuals = 0; + if (look(AfterQuals) == 'r') ++AfterQuals; + if (look(AfterQuals) == 'V') ++AfterQuals; + if (look(AfterQuals) == 'K') ++AfterQuals; + if (look(AfterQuals) == 'F') { + Result = parseFunctionType(); + break; + } + _LIBCPP_FALLTHROUGH(); + } case 'U': { - bool AppliesToFunction = false; - Result = parseQualifiedType(AppliesToFunction); - - // Itanium C++ ABI 5.1.5.3: - // For the purposes of substitution, the CV-qualifiers and ref-qualifier - // of a function type are an indivisible part of the type. - if (AppliesToFunction) - return Result; + Result = parseQualifiedType(); break; } // <builtin-type> ::= v # void @@ -5506,7 +5484,7 @@ parse_encoding(const char* first, const Node* name = db.Names.back(); db.Names.pop_back(); result = db.make<FunctionEncoding>( - return_type, name, NodeArray()); + return_type, name, NodeArray(), cv, ref); } else { @@ -5527,12 +5505,8 @@ parse_encoding(const char* first, const Node* name = db.Names.back(); db.Names.pop_back(); result = db.make<FunctionEncoding>( - return_type, name, params); + return_type, name, params, cv, ref); } - if (ref != FrefQualNone) - result = db.make<FunctionRefQualType>(result, ref); - if (cv != QualNone) - result = db.make<FunctionQualType>(result, cv); db.Names.push_back(result); first = t; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits