Skip to content

Demangler: fix the function specialization de-mangling #7651

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 21, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions include/swift/Basic/Demangler.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,6 @@ class Demangler {
NodePointer demangleGenericSpecialization(Node::Kind SpecKind);
NodePointer demangleFunctionSpecialization();
NodePointer demangleFuncSpecParam(Node::IndexType ParamIdx);
NodePointer addFuncSpecParamIdentifier(NodePointer Param,
FunctionSigSpecializationParamKind Kind,
StringRef FirstParam = StringRef());
NodePointer addFuncSpecParamNumber(NodePointer Param,
FunctionSigSpecializationParamKind Kind);

Expand Down
109 changes: 65 additions & 44 deletions lib/Basic/Demangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1184,6 +1184,53 @@ NodePointer Demangler::demangleFunctionSpecialization() {
}
if (!nextIf('n'))
Spec = addChild(Spec, demangleFuncSpecParam(Node::IndexType(~0)));

if (!Spec)
return nullptr;

// Add the required parameters in reverse order.
for (size_t Idx = 0, Num = Spec->getNumChildren(); Idx < Num; ++Idx) {
NodePointer Param = Spec->getChild(Num - Idx - 1);
if (Param->getKind() != Node::Kind::FunctionSignatureSpecializationParam)
continue;

if (Param->getNumChildren() == 0)
continue;
NodePointer KindNd = Param->getFirstChild();
assert(KindNd->getKind() ==
Node::Kind::FunctionSignatureSpecializationParamKind);
auto ParamKind = (FunctionSigSpecializationParamKind)KindNd->getIndex();
switch (ParamKind) {
case FunctionSigSpecializationParamKind::ConstantPropFunction:
case FunctionSigSpecializationParamKind::ConstantPropGlobal:
case FunctionSigSpecializationParamKind::ConstantPropString:
case FunctionSigSpecializationParamKind::ClosureProp: {
std::vector<NodePointer> Types;
while (NodePointer Ty = popNode(Node::Kind::Type)) {
assert(ParamKind == FunctionSigSpecializationParamKind::ClosureProp);
Types.push_back(Ty);
}
NodePointer Name = popNode(Node::Kind::Identifier);
if (!Name)
return nullptr;
StringRef Text = Name->getText();
if (ParamKind ==
FunctionSigSpecializationParamKind::ConstantPropString &&
Text.size() > 0 && Text[0] == '_') {
// A '_' escapes a leading digit or '_' of a string constant.
Text = Text.drop_front(1);
}
addChild(Param, NodeFactory::create(
Node::Kind::FunctionSignatureSpecializationParamPayload, Text));
while (NodePointer Ty = pop_back_val(Types)) {
Param = addChild(Param, Ty);
}
break;
}
default:
break;
}
}
return Spec;
}

Expand All @@ -1193,57 +1240,47 @@ NodePointer Demangler::demangleFuncSpecParam(Node::IndexType ParamIdx) {
switch (nextChar()) {
case 'n':
return Param;
case 'c': {
std::vector<NodePointer> Types;
while (NodePointer Ty = popNode(Node::Kind::Type)) {
Types.push_back(Ty);
}
Param = addFuncSpecParamIdentifier(Param,
swift::Demangle::FunctionSigSpecializationParamKind::ClosureProp);
while (NodePointer Ty = pop_back_val(Types)) {
Param = addChild(Param, Ty);
}
return Param;
}
case 'c':
// Consumes an identifier and multiple type parameters.
// The parameters will be added later.
return addChild(Param, NodeFactory::create(
Node::Kind::FunctionSignatureSpecializationParamKind,
unsigned(FunctionSigSpecializationParamKind::ClosureProp)));
case 'p': {
switch (nextChar()) {
case 'f':
return addFuncSpecParamIdentifier(Param,
FunctionSigSpecializationParamKind::ConstantPropFunction);
// Consumes an identifier parameter, which will be added later.
return addChild(Param, NodeFactory::create(
Node::Kind::FunctionSignatureSpecializationParamKind,
unsigned(FunctionSigSpecializationParamKind::ConstantPropFunction)));
case 'g':
return addFuncSpecParamIdentifier(Param,
FunctionSigSpecializationParamKind::ConstantPropGlobal);
// Consumes an identifier parameter, which will be added later.
return addChild(Param, NodeFactory::create(
Node::Kind::FunctionSignatureSpecializationParamKind,
unsigned(FunctionSigSpecializationParamKind::ConstantPropGlobal)));
case 'i':
return addFuncSpecParamNumber(Param,
FunctionSigSpecializationParamKind::ConstantPropInteger);
case 'd':
return addFuncSpecParamNumber(Param,
FunctionSigSpecializationParamKind::ConstantPropFloat);
case 's': {
// Consumes an identifier parameter (the string constant),
// which will be added later.
StringRef Encoding;
switch (nextChar()) {
case 'b': Encoding = "u8"; break;
case 'w': Encoding = "u16"; break;
case 'c': Encoding = "objc"; break;
default: return nullptr;
}
NodePointer Str = popNode(Node::Kind::Identifier);
if (!Str)
return nullptr;
StringRef Text = Str->getText();
if (Text.size() > 0 && Text[0] == '_')
Text = Text.drop_front(1);

Param->addChild(NodeFactory::create(
addChild(Param, NodeFactory::create(
Node::Kind::FunctionSignatureSpecializationParamKind,
unsigned(swift::Demangle::FunctionSigSpecializationParamKind::
ConstantPropString)));
Param->addChild(NodeFactory::create(
Node::Kind::FunctionSignatureSpecializationParamPayload,
Encoding));
return addChild(Param, NodeFactory::create(
Node::Kind::FunctionSignatureSpecializationParamPayload,
Text));
Encoding));
}
default:
return nullptr;
Expand Down Expand Up @@ -1283,22 +1320,6 @@ NodePointer Demangler::demangleFuncSpecParam(Node::IndexType ParamIdx) {
}
}

NodePointer Demangler::addFuncSpecParamIdentifier(NodePointer Param,
FunctionSigSpecializationParamKind Kind,
StringRef FirstParam) {
NodePointer Name = popNode(Node::Kind::Identifier);
if (!Name)
return nullptr;
Param->addChild(NodeFactory::create(
Node::Kind::FunctionSignatureSpecializationParamKind, unsigned(Kind)));
if (!FirstParam.empty()) {
Param->addChild(NodeFactory::create(
Node::Kind::FunctionSignatureSpecializationParamPayload, FirstParam));
}
return addChild(Param, NodeFactory::create(
Node::Kind::FunctionSignatureSpecializationParamPayload, Name->getText()));
}

NodePointer Demangler::addFuncSpecParamNumber(NodePointer Param,
FunctionSigSpecializationParamKind Kind) {
Param->addChild(NodeFactory::create(
Expand Down
4 changes: 0 additions & 4 deletions lib/Basic/Mangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,16 +235,12 @@ std::string NewMangling::selectMangling(const std::string &Old,
NodePointer RemangledNode = demangleSymbolAsNode(Remangled);
isEqual = areTreesEqual(NewNode, RemangledNode);
}

// TODO: Check disabled until rdar://problem/30592808 is fixed.
#if 0
if (!isEqual) {
llvm::errs() << "Remangling failed at #" << numCmp << ":\n"
"original: " << New << "\n"
"remangled: " << Remangled << "\n";
assert(false);
}
#endif
}
}
}
Expand Down
12 changes: 10 additions & 2 deletions lib/Basic/Remangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -830,9 +830,17 @@ void Remangler::mangleFunctionSignatureSpecialization(Node *node) {
case FunctionSigSpecializationParamKind::ConstantPropGlobal:
mangleIdentifier(Param->getChild(1).get());
break;
case FunctionSigSpecializationParamKind::ConstantPropString:
mangleIdentifier(Param->getChild(2).get());
case FunctionSigSpecializationParamKind::ConstantPropString: {
NodePointer TextNd = Param->getChild(2);
StringRef Text = TextNd->getText();
if (Text.size() > 0 && (isDigit(Text[0]) || Text[0] == '_')) {
std::string Buffer = "_";
Buffer.append(Text.data(), Text.size());
TextNd = NodeFactory::create(Node::Kind::Identifier, Buffer);
}
mangleIdentifier(TextNd.get());
break;
}
case FunctionSigSpecializationParamKind::ClosureProp:
mangleIdentifier(Param->getChild(1).get());
for (unsigned i = 2, e = Param->getNumChildren(); i != e; ++i) {
Expand Down
2 changes: 2 additions & 0 deletions test/Demangle/Inputs/manglings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -239,5 +239,7 @@ _TFVFE15nested_genericsSS3fooFT_T_L_6CheeseCfT8materialx_GS0_x_ ---> (extension
_TTWOE5imojiCSo5Imoji14ImojiMatchRankS_9RankValueS_FS2_g9rankValueqq_Ss16RawRepresentable8RawValue ---> _TTWOE5imojiCSo5Imoji14ImojiMatchRankS_9RankValueS_FS2_g9rankValueqq_Ss16RawRepresentable8RawValue
_TtFzas4VoidGC16FusionXBaseUtils6FutureQq_ZFVS_7Futures6futureurFFzT_GS0_x_GS0_x__ ---> _TtFzas4VoidGC16FusionXBaseUtils6FutureQq_ZFVS_7Futures6futureurFFzT_GS0_x_GS0_x__
_T0s17MutableCollectionP1asAARzs012RandomAccessB0RzsAA11SubSequences013BidirectionalB0PRpzsAdHRQlE06rotatecD05Indexs01_A9IndexablePQzAM15shiftingToStart_tFAJs01_J4BasePQzAQcfU_ ---> (extension in a):Swift.MutableCollection<A where A: Swift.MutableCollection, A: Swift.RandomAccessCollection, A.SubSequence: Swift.MutableCollection, A.SubSequence: Swift.RandomAccessCollection>.(rotateRandomAccess (shiftingToStart : A.Index) -> A.Index).(closure #1)
_T03foo4_123ABTf3psbpsb_n ---> function signature specialization <Arg[0] = [Constant Propagated String : u8'123'], Arg[1] = [Constant Propagated String : u8'123']> of foo
_T04main5innerys5Int32Vz_yADctF25closure_with_box_argumentxz_Bi32__lXXTf1nc_n ---> function signature specialization <Arg[1] = [Closure Propagated : closure_with_box_argument, Argument Types : [<A> { var A } <Builtin.Int32>]> of main.inner (inout Swift.Int32, (Swift.Int32) -> ()) -> ()
_T03foo6testityyyc_yyctF1a1bTf3pfpf_n ---> function signature specialization <Arg[0] = [Constant Propagated Function : a], Arg[1] = [Constant Propagated Function : b]> of foo.testit (() -> (), () -> ()) -> ()