mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-10-10 12:55:00 +00:00
[demangler] Simplify the AST for function types, NFC.
llvm-svn: 325092
This commit is contained in:
parent
56f6352354
commit
bb0e34558f
@ -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 Node {
|
||||
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,
|
||||
};
|
||||
if (CVQuals & QualConst)
|
||||
S += " const";
|
||||
if (CVQuals & QualVolatile)
|
||||
S += " volatile";
|
||||
if (CVQuals & QualRestrict)
|
||||
S += " restrict";
|
||||
|
||||
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; }
|
||||
|
||||
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 &AppliesToFunction) {
|
||||
}
|
||||
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 char* last, Db& db)
|
||||
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 char* last, Db& db)
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user