Skip to content

Commit 9c10151

Browse files
authored
Merge pull request #37733 from DougGregor/concurrency-standard-substitutions
2 parents 21a25c8 + b57a73a commit 9c10151

File tree

16 files changed

+125
-30
lines changed

16 files changed

+125
-30
lines changed

docs/ABI/Mangling.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@ Types
466466
KNOWN-TYPE-KIND ::= 'a' // Swift.Array
467467
KNOWN-TYPE-KIND ::= 'B' // Swift.BinaryFloatingPoint
468468
KNOWN-TYPE-KIND ::= 'b' // Swift.Bool
469+
KNOWN-TYPE-KIND ::= 'c' KNOWN-TYPE-KIND-2 // Second set of standard types
469470
KNOWN-TYPE-KIND ::= 'D' // Swift.Dictionary
470471
KNOWN-TYPE-KIND ::= 'd' // Swift.Float64
471472
KNOWN-TYPE-KIND ::= 'E' // Swift.Encodable
@@ -511,6 +512,25 @@ Types
511512
KNOWN-TYPE-KIND ::= 'Z' // Swift.SignedInteger
512513
KNOWN-TYPE-KIND ::= 'z' // Swift.BinaryInteger
513514

515+
KNOWN-TYPE-KIND-2 ::= 'A' // Swift.Actor
516+
KNOWN-TYPE-KIND-2 ::= 'C' // Swift.CheckedContinuation
517+
KNOWN-TYPE-KIND-2 ::= 'c' // Swift.UnsafeContinuation
518+
KNOWN-TYPE-KIND-2 ::= 'E' // Swift.CancellationError
519+
KNOWN-TYPE-KIND-2 ::= 'e' // Swift.UnownedSerialExecutor
520+
KNOWN-TYPE-KIND-2 ::= 'F' // Swift.Executor
521+
KNOWN-TYPE-KIND-2 ::= 'f' // Swift.SerialExecutor
522+
KNOWN-TYPE-KIND-2 ::= 'G' // Swift.TaskGroup
523+
KNOWN-TYPE-KIND-2 ::= 'g' // Swift.ThrowingTaskGroup
524+
KNOWN-TYPE-KIND-2 ::= 'I' // Swift.AsyncIteratorProtocol
525+
KNOWN-TYPE-KIND-2 ::= 'i' // Swift.AsyncSequence
526+
KNOWN-TYPE-KIND-2 ::= 'J' // Swift.UnownedJob
527+
KNOWN-TYPE-KIND-2 ::= 'M' // Swift.MainActor
528+
KNOWN-TYPE-KIND-2 ::= 'P' // Swift.TaskPriority
529+
KNOWN-TYPE-KIND-2 ::= 'S' // Swift.AsyncStream
530+
KNOWN-TYPE-KIND-2 ::= 's' // Swift.AsyncThrowingStream
531+
KNOWN-TYPE-KIND-2 ::= 'T' // Swift.Task
532+
KNOWN-TYPE-KIND-2 ::= 't' // Swift.UnsafeCurrentTask
533+
514534
protocol ::= context decl-name
515535
protocol ::= standard-substitutions
516536

include/swift/AST/Module.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,9 @@ class ModuleDecl : public DeclContext, public TypeDecl {
729729
/// \returns true if this module is the "swift" standard library module.
730730
bool isStdlibModule() const;
731731

732+
/// \returns true if this module has standard substitutions for mangling.
733+
bool hasStandardSubstitutions() const;
734+
732735
/// \returns true if this module is the "SwiftShims" module;
733736
bool isSwiftShimsModule() const;
734737

include/swift/Demangling/Demangler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ class Demangler : public NodeFactory {
494494
NodePointer pushMultiSubstitutions(int RepeatCount, size_t SubstIdx);
495495
NodePointer createSwiftType(Node::Kind typeKind, const char *name);
496496
NodePointer demangleStandardSubstitution();
497-
NodePointer createStandardSubstitution(char Subst);
497+
NodePointer createStandardSubstitution(char Subst, bool SecondLevel);
498498
NodePointer demangleLocalIdentifier();
499499

500500
NodePointer popModule();

include/swift/Demangling/ManglingUtils.h

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ char translateOperatorChar(char op);
9999
std::string translateOperator(StringRef Op);
100100

101101
/// Returns the standard type kind for an 'S' substitution, e.g. 'i' for "Int".
102-
char getStandardTypeSubst(StringRef TypeName);
102+
llvm::Optional<StringRef> getStandardTypeSubst(StringRef TypeName);
103103

104104
/// Mangles an identifier using a generic Mangler class.
105105
///
@@ -274,8 +274,9 @@ class SubstitutionMerging {
274274
/// *) getBufferStr(): Returns a StringRef of the current content of Buffer.
275275
/// *) resetBuffer(size_t): Resets the buffer to an old position.
276276
template <typename Mangler>
277-
bool tryMergeSubst(Mangler &M, char Subst, bool isStandardSubst) {
278-
assert(isUpperLetter(Subst) || (isStandardSubst && isLowerLetter(Subst)));
277+
bool tryMergeSubst(Mangler &M, StringRef Subst, bool isStandardSubst) {
278+
assert(isUpperLetter(Subst.back()) ||
279+
(isStandardSubst && isLowerLetter(Subst.back())));
279280
StringRef BufferStr = M.getBufferStr();
280281
if (lastNumSubsts > 0 && lastNumSubsts < MaxRepeatCount
281282
&& BufferStr.size() == lastSubstPosition + lastSubstSize
@@ -284,17 +285,20 @@ class SubstitutionMerging {
284285
// The last mangled thing is a substitution.
285286
assert(lastSubstPosition > 0 && lastSubstPosition < BufferStr.size());
286287
assert(lastSubstSize > 0);
287-
char lastSubst = BufferStr.back();
288-
assert(isUpperLetter(lastSubst)
289-
|| (isStandardSubst && isLowerLetter(lastSubst)));
288+
StringRef lastSubst = BufferStr.take_back(lastSubstSize)
289+
.drop_while([](char c) {
290+
return isDigit(c);
291+
});
292+
assert(isUpperLetter(lastSubst.back())
293+
|| (isStandardSubst && isLowerLetter(lastSubst.back())));
290294
if (lastSubst != Subst && !isStandardSubst) {
291295
// We can merge with a different 'A' substitution,
292296
// e.g. 'AB' -> 'AbC'.
293297
lastSubstPosition = BufferStr.size();
294298
lastNumSubsts = 1;
295299
M.resetBuffer(BufferStr.size() - 1);
296-
assert(isUpperLetter(lastSubst));
297-
M.Buffer << (char)(lastSubst - 'A' + 'a') << Subst;
300+
assert(isUpperLetter(lastSubst.back()));
301+
M.Buffer << (char)(lastSubst.back() - 'A' + 'a') << Subst;
298302
lastSubstSize = 1;
299303
return true;
300304
}
@@ -312,7 +316,7 @@ class SubstitutionMerging {
312316
// We can't merge with the previous substitution, but let's remember this
313317
// substitution which will be mangled by the caller.
314318
lastSubstPosition = BufferStr.size() + 1;
315-
lastSubstSize = 1;
319+
lastSubstSize = Subst.size();
316320
lastNumSubsts = 1;
317321
lastSubstIsStandardSubst = isStandardSubst;
318322
return false;

include/swift/Demangling/StandardTypesMangling.def

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@
1212

1313
/// STANDARD_TYPE(KIND, MANGLING, TYPENAME)
1414
/// The 1-character MANGLING for a known TYPENAME of KIND.
15-
15+
///
16+
/// STANDARD_TYPE_2(KIND, MANGLING, TYPENAME)
17+
/// The 1-character MANGLING for a known TYPENAME of KIND that is in the
18+
/// second level of standard types, all of which are mangled with the form
19+
/// Sc<MANGLING>.
20+
///
1621
/// OBJC_INTEROP_STANDARD_TYPE(KIND, MANGLING, TYPENAME)
1722
/// The 1-character MANGLING for a known TYPENAME of KIND, for a type that's
1823
/// only available with ObjC interop enabled.
@@ -22,6 +27,7 @@
2227
STANDARD_TYPE(KIND, MANGLING, TYPENAME)
2328
#endif
2429

30+
2531
OBJC_INTEROP_STANDARD_TYPE(Structure, A, AutoreleasingUnsafeMutablePointer)
2632
STANDARD_TYPE(Structure, a, Array)
2733
STANDARD_TYPE(Structure, b, Bool)
@@ -73,5 +79,25 @@ STANDARD_TYPE(Protocol, y, StringProtocol)
7379
STANDARD_TYPE(Protocol, Z, SignedInteger)
7480
STANDARD_TYPE(Protocol, z, BinaryInteger)
7581

82+
STANDARD_TYPE_2(Protocol, A, Actor)
83+
STANDARD_TYPE_2(Structure, C, CheckedContinuation)
84+
STANDARD_TYPE_2(Structure, c, UnsafeContinuation)
85+
STANDARD_TYPE_2(Structure, E, CancellationError)
86+
STANDARD_TYPE_2(Structure, e, UnownedSerialExecutor)
87+
STANDARD_TYPE_2(Protocol, F, Executor)
88+
STANDARD_TYPE_2(Protocol, f, SerialExecutor)
89+
STANDARD_TYPE_2(Structure, G, TaskGroup)
90+
STANDARD_TYPE_2(Structure, g, ThrowingTaskGroup)
91+
STANDARD_TYPE_2(Protocol, I, AsyncIteratorProtocol)
92+
STANDARD_TYPE_2(Protocol, i, AsyncSequence)
93+
STANDARD_TYPE_2(Structure, J, UnownedJob)
94+
STANDARD_TYPE_2(Class, M, MainActor)
95+
STANDARD_TYPE_2(Structure, P, TaskPriority)
96+
STANDARD_TYPE_2(Structure, S, AsyncStream)
97+
STANDARD_TYPE_2(Structure, s, AsyncThrowingStream)
98+
STANDARD_TYPE_2(Structure, T, Task)
99+
STANDARD_TYPE_2(Structure, t, UnsafeCurrentTask)
100+
76101
#undef STANDARD_TYPE
77102
#undef OBJC_INTEROP_STANDARD_TYPE
103+
#undef STANDARD_TYPE_2

lib/AST/ASTDemangler.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,15 @@ ASTBuilder::findTypeDecl(DeclContext *dc,
10601060
result = candidate;
10611061
}
10621062

1063+
// If we looked into the standard library module, but didn't find anything,
1064+
// try the _Concurrency module, which is also mangled into the Swift module.
1065+
if (!result && !dc->getParent() && module->isStdlibModule()) {
1066+
ASTContext &ctx = module->getASTContext();
1067+
if (auto concurrencyModule = ctx.getLoadedModule(ctx.Id_Concurrency)) {
1068+
return findTypeDecl(concurrencyModule, name, privateDiscriminator, kind);
1069+
}
1070+
}
1071+
10631072
return result;
10641073
}
10651074

lib/AST/ASTMangler.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2935,13 +2935,15 @@ void ASTMangler::appendDeclType(const ValueDecl *decl,
29352935

29362936
bool ASTMangler::tryAppendStandardSubstitution(const GenericTypeDecl *decl) {
29372937
// Bail out if our parent isn't the swift standard library.
2938-
if (!decl->isStdlibDecl())
2938+
auto dc = decl->getDeclContext();
2939+
if (!dc->isModuleScopeContext() ||
2940+
!dc->getParentModule()->hasStandardSubstitutions())
29392941
return false;
29402942

29412943
if (isa<NominalTypeDecl>(decl)) {
2942-
if (char Subst = getStandardTypeSubst(decl->getName().str())) {
2943-
if (!SubstMerging.tryMergeSubst(*this, Subst, /*isStandardSubst*/ true)) {
2944-
appendOperator("S", StringRef(&Subst, 1));
2944+
if (auto Subst = getStandardTypeSubst(decl->getName().str())) {
2945+
if (!SubstMerging.tryMergeSubst(*this, *Subst, /*isStandardSubst*/ true)){
2946+
appendOperator("S", *Subst);
29452947
}
29462948
return true;
29472949
}

lib/AST/Module.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,6 +1407,12 @@ bool ModuleDecl::isStdlibModule() const {
14071407
return !getParent() && getName() == getASTContext().StdlibModuleName;
14081408
}
14091409

1410+
bool ModuleDecl::hasStandardSubstitutions() const {
1411+
return !getParent() &&
1412+
(getName() == getASTContext().StdlibModuleName ||
1413+
getName() == getASTContext().Id_Concurrency);
1414+
}
1415+
14101416
bool ModuleDecl::isSwiftShimsModule() const {
14111417
return !getParent() && getName() == getASTContext().SwiftShimsModuleName;
14121418
}

lib/Basic/Mangler.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,13 +223,14 @@ void Mangler::mangleSubstitution(unsigned Idx) {
223223
return appendOperator("A", Index(Idx - 26));
224224
}
225225

226-
char Subst = Idx + 'A';
226+
char SubstChar = Idx + 'A';
227+
StringRef Subst(&SubstChar, 1);
227228
if (SubstMerging.tryMergeSubst(*this, Subst, /*isStandardSubst*/ false)) {
228229
#ifndef NDEBUG
229230
++mergedSubsts;
230231
#endif
231232
} else {
232-
appendOperator("A", StringRef(&Subst, 1));
233+
appendOperator("A", Subst);
233234
}
234235
}
235236

lib/Demangling/Demangler.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -949,7 +949,9 @@ NodePointer Demangler::demangleStandardSubstitution() {
949949
int RepeatCount = demangleNatural();
950950
if (RepeatCount > SubstitutionMerging::MaxRepeatCount)
951951
return nullptr;
952-
if (NodePointer Nd = createStandardSubstitution(nextChar())) {
952+
bool secondLevelSubstitution = nextIf('c');
953+
if (NodePointer Nd = createStandardSubstitution(
954+
nextChar(), secondLevelSubstitution)) {
953955
while (RepeatCount-- > 1) {
954956
pushNode(Nd);
955957
}
@@ -960,10 +962,16 @@ NodePointer Demangler::demangleStandardSubstitution() {
960962
}
961963
}
962964

963-
NodePointer Demangler::createStandardSubstitution(char Subst) {
965+
NodePointer Demangler::createStandardSubstitution(
966+
char Subst, bool SecondLevel) {
964967
#define STANDARD_TYPE(KIND, MANGLING, TYPENAME) \
965-
if (Subst == #MANGLING[0]) { \
966-
return createSwiftType(Node::Kind::KIND, #TYPENAME); \
968+
if (!SecondLevel && Subst == #MANGLING[0]) { \
969+
return createSwiftType(Node::Kind::KIND, #TYPENAME); \
970+
}
971+
972+
#define STANDARD_TYPE_2(KIND, MANGLING, TYPENAME) \
973+
if (SecondLevel && Subst == #MANGLING[0]) { \
974+
return createSwiftType(Node::Kind::KIND, #TYPENAME); \
967975
}
968976

969977
#include "swift/Demangling/StandardTypesMangling.def"

0 commit comments

Comments
 (0)