[demangler] Support for clang's enable_if attribute.

Fixes PR33569.

llvm-svn: 328462
This commit is contained in:
Erik Pilkington 2018-03-25 22:49:16 +00:00
parent 93e64dd9a1
commit c728786b1d
3 changed files with 75 additions and 13 deletions

View File

@ -9,7 +9,6 @@
// FIXME: (possibly) incomplete list of features that clang mangles that this
// file does not yet support:
// - enable_if attribute
// - C++ modules TS
// - All C++14 and C++17 features
@ -168,6 +167,7 @@ public:
KElaboratedTypeSpefType,
KNameType,
KAbiTagAttr,
KEnableIfAttr,
KObjCProtoName,
KPointerType,
KLValueReferenceType,
@ -486,6 +486,19 @@ public:
}
};
class EnableIfAttr : public Node {
NodeArray Conditions;
public:
EnableIfAttr(NodeArray Conditions_)
: Node(KEnableIfAttr), Conditions(Conditions_) {}
void printLeft(OutputStream &S) const override {
S += " [enable_if:";
Conditions.printWithComma(S);
S += ']';
}
};
class ObjCProtoName : public Node {
Node *Ty;
StringView Protocol;
@ -812,17 +825,18 @@ class FunctionEncoding final : public Node {
const Node *Ret;
const Node *Name;
NodeArray Params;
Node *Attrs;
Qualifiers CVQuals;
FunctionRefQual RefQual;
public:
FunctionEncoding(Node *Ret_, Node *Name_, NodeArray Params_,
Qualifiers CVQuals_, FunctionRefQual RefQual_)
Node *Attrs_, Qualifiers CVQuals_, FunctionRefQual RefQual_)
: Node(KFunctionEncoding, NoParameterPack,
/*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No,
/*FunctionCache=*/Cache::Yes),
Ret(Ret_), Name(Name_), Params(Params_), CVQuals(CVQuals_),
RefQual(RefQual_) {
Ret(Ret_), Name(Name_), Params(Params_), Attrs(Attrs_),
CVQuals(CVQuals_), RefQual(RefQual_) {
for (Node *P : Params)
ParameterPackSize = std::min(ParameterPackSize, P->ParameterPackSize);
if (Ret)
@ -861,6 +875,9 @@ public:
S += " &";
else if (RefQual == FrefQualRValue)
S += " &&";
if (Attrs != nullptr)
Attrs->print(S);
}
};
@ -4480,6 +4497,18 @@ Node *Db::parseEncoding() {
TagTemplates = false;
Node *Attrs = nullptr;
if (consumeIf("Ua9enable_ifI")) {
size_t BeforeArgs = Names.size();
while (!consumeIf('E')) {
Node *Arg = parseTemplateArg();
if (Arg == nullptr)
return nullptr;
Names.push_back(Arg);
}
Attrs = make<EnableIfAttr>(popTrailingNodeArray(BeforeArgs));
}
Node *ReturnType = nullptr;
if (!NameInfo.CtorDtorConversion && NameInfo.EndsWithTemplateArgs) {
ReturnType = parseType();
@ -4489,7 +4518,7 @@ Node *Db::parseEncoding() {
if (consumeIf('v'))
return make<FunctionEncoding>(ReturnType, Name, NodeArray(),
NameInfo.CVQualifiers,
Attrs, NameInfo.CVQualifiers,
NameInfo.ReferenceQualifier);
size_t ParamsBegin = Names.size();
@ -4502,7 +4531,7 @@ Node *Db::parseEncoding() {
return make<FunctionEncoding>(ReturnType, Name,
popTrailingNodeArray(ParamsBegin),
NameInfo.CVQualifiers,
Attrs, NameInfo.CVQualifiers,
NameInfo.ReferenceQualifier);
}

View File

@ -29727,6 +29727,11 @@ const char* cases[][2] =
{"_ZGR1bIvE2_", "reference temporary for b<void>"},
{"_ZZ18test_assign_throwsI20small_throws_on_copyLb0EEvvENKUlRNSt3__13anyEOT_E_clIRS0_EEDaS3_S5_", "auto void test_assign_throws<small_throws_on_copy, false>()::'lambda'(std::__1::any&, auto&&)::operator()<small_throws_on_copy&>(std::__1::any&, auto&&) const"},
// enable_if attributes:
{"_Z1fUa9enable_ifIXLi1EEEv", "f() [enable_if:1]"},
{"_ZN5test4IdE1fEUa9enable_ifIXeqfL0p_Li1EEXeqfL0p0_Li2EEEi", "test4<double>::f(int) [enable_if:(fp) == (1), (fp0) == (2)]"},
{"_Z3quxUa9enable_ifIXLi1EEXL_Z9TRUEFACTSEEEi", "qux(int) [enable_if:1, TRUEFACTS]"},
};
const unsigned N = sizeof(cases) / sizeof(cases[0]);
@ -29856,7 +29861,6 @@ void test_invalid_cases()
}
const char *xfail_cases[] = {
"_Z1fUa9enable_ifIXLi1EEEv", // enable_if attribute
"_ZW6FooBarE2f3v", // C++ modules TS
// FIXME: Why does clang generate the "cp" expr?

View File

@ -9,7 +9,6 @@
// FIXME: (possibly) incomplete list of features that clang mangles that this
// file does not yet support:
// - enable_if attribute
// - C++ modules TS
// - All C++14 and C++17 features
@ -160,6 +159,7 @@ public:
KElaboratedTypeSpefType,
KNameType,
KAbiTagAttr,
KEnableIfAttr,
KObjCProtoName,
KPointerType,
KLValueReferenceType,
@ -478,6 +478,19 @@ public:
}
};
class EnableIfAttr : public Node {
NodeArray Conditions;
public:
EnableIfAttr(NodeArray Conditions_)
: Node(KEnableIfAttr), Conditions(Conditions_) {}
void printLeft(OutputStream &S) const override {
S += " [enable_if:";
Conditions.printWithComma(S);
S += ']';
}
};
class ObjCProtoName : public Node {
Node *Ty;
StringView Protocol;
@ -804,17 +817,18 @@ class FunctionEncoding final : public Node {
const Node *Ret;
const Node *Name;
NodeArray Params;
Node *Attrs;
Qualifiers CVQuals;
FunctionRefQual RefQual;
public:
FunctionEncoding(Node *Ret_, Node *Name_, NodeArray Params_,
Qualifiers CVQuals_, FunctionRefQual RefQual_)
Node *Attrs_, Qualifiers CVQuals_, FunctionRefQual RefQual_)
: Node(KFunctionEncoding, NoParameterPack,
/*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No,
/*FunctionCache=*/Cache::Yes),
Ret(Ret_), Name(Name_), Params(Params_), CVQuals(CVQuals_),
RefQual(RefQual_) {
Ret(Ret_), Name(Name_), Params(Params_), Attrs(Attrs_),
CVQuals(CVQuals_), RefQual(RefQual_) {
for (Node *P : Params)
ParameterPackSize = std::min(ParameterPackSize, P->ParameterPackSize);
if (Ret)
@ -853,6 +867,9 @@ public:
S += " &";
else if (RefQual == FrefQualRValue)
S += " &&";
if (Attrs != nullptr)
Attrs->print(S);
}
};
@ -4472,6 +4489,18 @@ Node *Db::parseEncoding() {
TagTemplates = false;
Node *Attrs = nullptr;
if (consumeIf("Ua9enable_ifI")) {
size_t BeforeArgs = Names.size();
while (!consumeIf('E')) {
Node *Arg = parseTemplateArg();
if (Arg == nullptr)
return nullptr;
Names.push_back(Arg);
}
Attrs = make<EnableIfAttr>(popTrailingNodeArray(BeforeArgs));
}
Node *ReturnType = nullptr;
if (!NameInfo.CtorDtorConversion && NameInfo.EndsWithTemplateArgs) {
ReturnType = parseType();
@ -4481,7 +4510,7 @@ Node *Db::parseEncoding() {
if (consumeIf('v'))
return make<FunctionEncoding>(ReturnType, Name, NodeArray(),
NameInfo.CVQualifiers,
Attrs, NameInfo.CVQualifiers,
NameInfo.ReferenceQualifier);
size_t ParamsBegin = Names.size();
@ -4494,7 +4523,7 @@ Node *Db::parseEncoding() {
return make<FunctionEncoding>(ReturnType, Name,
popTrailingNodeArray(ParamsBegin),
NameInfo.CVQualifiers,
Attrs, NameInfo.CVQualifiers,
NameInfo.ReferenceQualifier);
}