Skip to content

Commit 9033198

Browse files
committed
ASTDemangler: Round-trip @isolated @sil_implicit_leading_param parameter attributes
We sometimes mangle SILFunctionTypes when generating debug info for reabstraction thunks, and these can have various exotic parameter and result attributes. Two recent additions were never plumbed through the mangler, causing assertion failures when emitting debug info. Fixes rdar://153730847.
1 parent c2d9d67 commit 9033198

File tree

14 files changed

+238
-76
lines changed

14 files changed

+238
-76
lines changed

docs/ABI/Mangling.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,15 @@ mangled in to disambiguate.
902902
PARAM-CONVENTION ::= 'p' // pack guaranteed
903903
PARAM-CONVENTION ::= 'm' // pack inout
904904

905+
#if SWIFT_RUNTIME_VERSION >= 6.0
906+
SENDING-PARAM ::= 'T' // sending parameter
907+
#endif
908+
909+
#if SWIFT_RUNTIME_VERSION >= 6.2
910+
ISOLATED-PARAM ::= 'I' // @isolated parameter
911+
IMPLICIT-LEADING-PARAM ::= 'L' // @implicit_leading parameter
912+
#endif
913+
905914
PARAM-DIFFERENTIABILITY ::= 'w' // @noDerivative
906915

907916
RESULT-CONVENTION ::= 'r' // indirect

include/swift/Demangling/Demangle.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@ struct [[nodiscard]] ManglingError {
649649
InvalidImplCoroutineKind,
650650
InvalidImplFunctionAttribute,
651651
InvalidImplParameterConvention,
652-
InvalidImplParameterSending,
652+
InvalidImplParameterAttr,
653653
InvalidMetatypeRepresentation,
654654
MultiByteRelatedEntity,
655655
BadValueWitnessKind,

include/swift/Demangling/DemangleNodes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ NODE(ImplErasedIsolation)
138138
NODE(ImplSendingResult)
139139
NODE(ImplParameterResultDifferentiability)
140140
NODE(ImplParameterSending)
141+
NODE(ImplParameterIsolated)
142+
NODE(ImplParameterImplicitLeading)
141143
NODE(ImplFunctionAttribute)
142144
NODE(ImplFunctionConvention)
143145
NODE(ImplFunctionConventionName)

include/swift/Demangling/Demangler.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,8 @@ class Demangler : public NodeFactory {
570570
NodePointer demangleImplParamConvention(Node::Kind ConvKind);
571571
NodePointer demangleImplResultConvention(Node::Kind ConvKind);
572572
NodePointer demangleImplParameterSending();
573+
NodePointer demangleImplParameterIsolated();
574+
NodePointer demangleImplParameterImplicitLeading();
573575
NodePointer demangleImplParameterResultDifferentiability();
574576
NodePointer demangleImplFunctionType();
575577
NodePointer demangleClangType();

include/swift/Demangling/TypeDecoder.h

Lines changed: 83 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ enum class ImplParameterConvention {
118118
enum class ImplParameterInfoFlags : uint8_t {
119119
NotDifferentiable = 0x1,
120120
Sending = 0x2,
121+
Isolated = 0x4,
122+
ImplicitLeading = 0x8
121123
};
122124

123125
using ImplParameterInfoOptions = OptionSet<ImplParameterInfoFlags>;
@@ -192,6 +194,22 @@ class ImplFunctionParam {
192194
return result;
193195
}
194196

197+
static OptionsType getIsolated() {
198+
OptionsType result;
199+
200+
result |= ImplParameterInfoFlags::Isolated;
201+
202+
return result;
203+
}
204+
205+
static OptionsType getImplicitLeading() {
206+
OptionsType result;
207+
208+
result |= ImplParameterInfoFlags::ImplicitLeading;
209+
210+
return result;
211+
}
212+
195213
ImplFunctionParam(BuiltType type, ImplParameterConvention convention,
196214
OptionsType options)
197215
: Type(type), Convention(convention), Options(options) {}
@@ -1143,11 +1161,11 @@ class TypeDecoder {
11431161
return MAKE_NODE_TYPE_ERROR0(child,
11441162
"failed to decode function yields");
11451163
} else if (child->getKind() == NodeKind::ImplResult) {
1146-
if (decodeImplFunctionParam(child, depth + 1, results))
1164+
if (decodeImplFunctionResult(child, depth + 1, results))
11471165
return MAKE_NODE_TYPE_ERROR0(child,
11481166
"failed to decode function results");
11491167
} else if (child->getKind() == NodeKind::ImplErrorResult) {
1150-
if (decodeImplFunctionPart(child, depth + 1, errorResults))
1168+
if (decodeImplFunctionResult(child, depth + 1, errorResults))
11511169
return MAKE_NODE_TYPE_ERROR0(child,
11521170
"failed to decode function part");
11531171
} else {
@@ -1638,40 +1656,70 @@ class TypeDecoder {
16381656
}
16391657

16401658
template <typename T>
1641-
bool decodeImplFunctionPart(Demangle::NodePointer node, unsigned depth,
1642-
llvm::SmallVectorImpl<T> &results) {
1659+
bool decodeImplFunctionParam(Demangle::NodePointer node, unsigned depth,
1660+
llvm::SmallVectorImpl<T> &results) {
16431661
if (depth > TypeDecoder::MaxDepth)
16441662
return true;
16451663

1646-
if (node->getNumChildren() != 2)
1664+
// Children: `convention, attrs, type`
1665+
// attrs: `differentiability?, sending?, isolated?, implicit_leading?`
1666+
if (node->getNumChildren() < 2)
16471667
return true;
1648-
1649-
if (node->getChild(0)->getKind() != Node::Kind::ImplConvention ||
1650-
node->getChild(1)->getKind() != Node::Kind::Type)
1668+
1669+
auto *conventionNode = node->getChild(0);
1670+
auto *typeNode = node->getLastChild();
1671+
if (conventionNode->getKind() != Node::Kind::ImplConvention ||
1672+
typeNode->getKind() != Node::Kind::Type)
16511673
return true;
16521674

1653-
StringRef conventionString = node->getChild(0)->getText();
1654-
std::optional<typename T::ConventionType> convention =
1655-
T::getConventionFromString(conventionString);
1675+
StringRef conventionString = conventionNode->getText();
1676+
auto convention = T::getConventionFromString(conventionString);
16561677
if (!convention)
16571678
return true;
1658-
auto type = decodeMangledType(node->getChild(1), depth + 1);
1659-
if (type.isError())
1679+
auto result = decodeMangledType(typeNode, depth + 1);
1680+
if (result.isError())
16601681
return true;
16611682

1662-
results.emplace_back(type.getType(), *convention);
1683+
typename T::OptionsType options;
1684+
for (unsigned i = 1; i < node->getNumChildren() - 1; ++i) {
1685+
auto child = node->getChild(i);
1686+
switch (child->getKind()) {
1687+
case Node::Kind::ImplParameterResultDifferentiability: {
1688+
auto optDiffOptions =
1689+
T::getDifferentiabilityFromString(child->getText());
1690+
if (!optDiffOptions)
1691+
return true;
1692+
options |= *optDiffOptions;
1693+
break;
1694+
}
1695+
case Node::Kind::ImplParameterSending:
1696+
options |= T::getSending();
1697+
break;
1698+
case Node::Kind::ImplParameterIsolated:
1699+
options |= T::getIsolated();
1700+
break;
1701+
case Node::Kind::ImplParameterImplicitLeading:
1702+
options |= T::getImplicitLeading();
1703+
break;
1704+
default:
1705+
return true;
1706+
}
1707+
}
1708+
1709+
results.emplace_back(result.getType(), *convention, options);
1710+
16631711
return false;
16641712
}
16651713

16661714
template <typename T>
1667-
bool decodeImplFunctionParam(Demangle::NodePointer node, unsigned depth,
1668-
llvm::SmallVectorImpl<T> &results) {
1715+
bool decodeImplFunctionResult(Demangle::NodePointer node, unsigned depth,
1716+
llvm::SmallVectorImpl<T> &results) {
16691717
if (depth > TypeDecoder::MaxDepth)
16701718
return true;
16711719

1672-
// Children: `convention, differentiability?, sending?, type`
1673-
if (node->getNumChildren() != 2 && node->getNumChildren() != 3 &&
1674-
node->getNumChildren() != 4)
1720+
// Children: `convention, attrs, type`
1721+
// attrs: `differentiability?, sending?, isolated?, implicit_leading?`
1722+
if (node->getNumChildren() < 2)
16751723
return true;
16761724

16771725
auto *conventionNode = node->getChild(0);
@@ -1689,23 +1737,23 @@ class TypeDecoder {
16891737
return true;
16901738

16911739
typename T::OptionsType options;
1692-
if (node->getNumChildren() == 3 || node->getNumChildren() == 4) {
1693-
auto diffKindNode = node->getChild(1);
1694-
if (diffKindNode->getKind() !=
1695-
Node::Kind::ImplParameterResultDifferentiability)
1696-
return true;
1697-
auto optDiffOptions =
1698-
T::getDifferentiabilityFromString(diffKindNode->getText());
1699-
if (!optDiffOptions)
1700-
return true;
1701-
options |= *optDiffOptions;
1702-
}
1703-
1704-
if (node->getNumChildren() == 4) {
1705-
auto sendingKindNode = node->getChild(2);
1706-
if (sendingKindNode->getKind() != Node::Kind::ImplParameterSending)
1740+
for (unsigned i = 1; i < node->getNumChildren() - 1; ++i) {
1741+
auto child = node->getChild(i);
1742+
switch (child->getKind()) {
1743+
case Node::Kind::ImplParameterResultDifferentiability: {
1744+
auto optDiffOptions =
1745+
T::getDifferentiabilityFromString(child->getText());
1746+
if (!optDiffOptions)
1747+
return true;
1748+
options |= *optDiffOptions;
1749+
break;
1750+
}
1751+
case Node::Kind::ImplParameterSending:
1752+
options |= T::getSending();
1753+
break;
1754+
default:
17071755
return true;
1708-
options |= T::getSending();
1756+
}
17091757
}
17101758

17111759
results.emplace_back(result.getType(), *convention, options);

lib/AST/ASTDemangler.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,16 @@ getParameterOptions(ImplParameterInfoOptions implOptions) {
528528
result |= SILParameterInfo::Sending;
529529
}
530530

531+
if (implOptions.contains(ImplParameterInfoFlags::Isolated)) {
532+
implOptions -= ImplParameterInfoFlags::Isolated;
533+
result |= SILParameterInfo::Isolated;
534+
}
535+
536+
if (implOptions.contains(ImplParameterInfoFlags::ImplicitLeading)) {
537+
implOptions -= ImplParameterInfoFlags::ImplicitLeading;
538+
result |= SILParameterInfo::ImplicitLeading;
539+
}
540+
531541
// If we did not handle all flags in implOptions, this code was not updated
532542
// appropriately. Return None to signal error.
533543
if (bool(implOptions))

lib/AST/ASTMangler.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2412,6 +2412,10 @@ void ASTMangler::appendImplFunctionType(SILFunctionType *fn,
24122412
OpArgs.push_back(getParamConvention(param.getConvention()));
24132413
if (param.hasOption(SILParameterInfo::Sending))
24142414
OpArgs.push_back('T');
2415+
if (param.hasOption(SILParameterInfo::Isolated))
2416+
OpArgs.push_back('I');
2417+
if (param.hasOption(SILParameterInfo::ImplicitLeading))
2418+
OpArgs.push_back('L');
24152419
if (auto diffKind = getParamDifferentiability(param.getOptions()))
24162420
OpArgs.push_back(*diffKind);
24172421
appendType(param.getInterfaceType(), sig, forDecl);

lib/Demangling/Demangler.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2301,6 +2301,22 @@ NodePointer Demangler::demangleImplParameterSending() {
23012301
return createNode(Node::Kind::ImplParameterSending, attr);
23022302
}
23032303

2304+
NodePointer Demangler::demangleImplParameterIsolated() {
2305+
// Empty string represents default differentiability.
2306+
if (!nextIf('I'))
2307+
return nullptr;
2308+
const char *attr = "isolated";
2309+
return createNode(Node::Kind::ImplParameterIsolated, attr);
2310+
}
2311+
2312+
NodePointer Demangler::demangleImplParameterImplicitLeading() {
2313+
// Empty string represents default differentiability.
2314+
if (!nextIf('L'))
2315+
return nullptr;
2316+
const char *attr = "sil_implicit_leading_param";
2317+
return createNode(Node::Kind::ImplParameterImplicitLeading, attr);
2318+
}
2319+
23042320
NodePointer Demangler::demangleImplParameterResultDifferentiability() {
23052321
// Empty string represents default differentiability.
23062322
const char *attr = "";
@@ -2452,6 +2468,10 @@ NodePointer Demangler::demangleImplFunctionType() {
24522468
Param = addChild(Param, Diff);
24532469
if (auto Sending = demangleImplParameterSending())
24542470
Param = addChild(Param, Sending);
2471+
if (auto Sending = demangleImplParameterIsolated())
2472+
Param = addChild(Param, Sending);
2473+
if (auto Sending = demangleImplParameterImplicitLeading())
2474+
Param = addChild(Param, Sending);
24552475
++NumTypesToAdd;
24562476
}
24572477

lib/Demangling/NodePrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,8 @@ bool NodePrinter::isSimpleType(NodePointer Node) {
390390
case Node::Kind::ImplConvention:
391391
case Node::Kind::ImplParameterResultDifferentiability:
392392
case Node::Kind::ImplParameterSending:
393+
case Node::Kind::ImplParameterIsolated:
394+
case Node::Kind::ImplParameterImplicitLeading:
393395
case Node::Kind::ImplFunctionAttribute:
394396
case Node::Kind::ImplFunctionConvention:
395397
case Node::Kind::ImplFunctionConventionName:
@@ -2803,6 +2805,8 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
28032805
Printer << Node->getText() << ' ';
28042806
return nullptr;
28052807
case Node::Kind::ImplParameterSending:
2808+
case Node::Kind::ImplParameterIsolated:
2809+
case Node::Kind::ImplParameterImplicitLeading:
28062810
// Skip if text is empty.
28072811
if (Node->getText().empty())
28082812
return nullptr;

lib/Demangling/OldRemangler.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1868,7 +1868,17 @@ ManglingError Remangler::mangleImplParameterSending(Node *node,
18681868
Buffer << 'T';
18691869
return ManglingError::Success;
18701870
}
1871-
return MANGLING_ERROR(ManglingError::InvalidImplParameterSending, node);
1871+
return MANGLING_ERROR(ManglingError::InvalidImplParameterAttr, node);
1872+
}
1873+
1874+
ManglingError Remangler::mangleImplParameterIsolated(Node *node,
1875+
unsigned depth) {
1876+
return ManglingError::Success;
1877+
}
1878+
1879+
ManglingError Remangler::mangleImplParameterImplicitLeading(Node *node,
1880+
unsigned depth) {
1881+
return ManglingError::Success;
18721882
}
18731883

18741884
ManglingError Remangler::mangleDynamicSelf(Node *node, unsigned depth) {

0 commit comments

Comments
 (0)