Skip to content

Commit 1e5155d

Browse files
authored
Merge pull request #17509 from DougGregor/mangle-generic-typealias
2 parents 2c297a6 + 5350d45 commit 1e5155d

File tree

13 files changed

+153
-27
lines changed

13 files changed

+153
-27
lines changed

include/swift/AST/ASTMangler.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,15 @@ class ASTMangler : public Mangler {
197197

198198
void appendBoundGenericArgs(Type type, bool &isFirstArgList);
199199

200+
/// Append the bound generics arguments for the given declaration context
201+
/// based on a complete substitution map.
202+
///
203+
/// \returns the number of generic parameters that were emitted
204+
/// thus far.
205+
unsigned appendBoundGenericArgs(DeclContext *dc,
206+
SubstitutionMap subs,
207+
bool &isFirstArgList);
208+
200209
/// Append any retroactive conformances.
201210
void appendRetroactiveConformances(Type type);
202211

lib/AST/ASTMangler.cpp

Lines changed: 69 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "swift/AST/Initializer.h"
2323
#include "swift/AST/Module.h"
2424
#include "swift/AST/ParameterList.h"
25+
#include "swift/AST/PrettyStackTrace.h"
2526
#include "swift/AST/ProtocolConformance.h"
2627
#include "swift/AST/ProtocolConformanceRef.h"
2728
#include "swift/Basic/Defer.h"
@@ -380,6 +381,9 @@ std::string ASTMangler::mangleReabstractionThunkHelper(
380381

381382
std::string ASTMangler::mangleTypeForDebugger(Type Ty, const DeclContext *DC,
382383
GenericEnvironment *GE) {
384+
PrettyStackTraceType prettyStackTrace(Ty->getASTContext(),
385+
"mangling type for debugger", Ty);
386+
383387
GenericEnv = GE;
384388
DWARFMangling = true;
385389
beginMangling();
@@ -746,17 +750,13 @@ void ASTMangler::appendType(Type type) {
746750
return appendType(aliasTy->getSinglyDesugaredType());
747751
}
748752

749-
if (type->isSpecialized()) {
753+
if (aliasTy->getSubstitutionMap().hasAnySubstitutableParams()) {
750754
// Try to mangle the entire name as a substitution.
751755
if (tryMangleSubstitution(tybase))
752756
return;
753757

754758
appendAnyGenericType(decl);
755759
bool isFirstArgList = true;
756-
if (auto *nominalType = type->getAs<NominalType>()) {
757-
if (nominalType->getParent())
758-
type = nominalType->getParent();
759-
}
760760
appendBoundGenericArgs(type, isFirstArgList);
761761
appendRetroactiveConformances(type);
762762
appendOperator("G");
@@ -1039,16 +1039,74 @@ void ASTMangler::bindGenericParameters(const DeclContext *DC) {
10391039
bindGenericParameters(sig->getCanonicalSignature());
10401040
}
10411041

1042+
unsigned ASTMangler::appendBoundGenericArgs(DeclContext *dc,
1043+
SubstitutionMap subs,
1044+
bool &isFirstArgList) {
1045+
auto decl = dc->getInnermostDeclarationDeclContext();
1046+
if (!decl) return 0;
1047+
1048+
// For an extension declaration, use the nominal type declaration instead.
1049+
// This is important when extending a nested type, because the generic
1050+
// parameters will line up with the (semantic) nesting of the nominal type.
1051+
if (auto ext = dyn_cast<ExtensionDecl>(decl))
1052+
decl = ext->getAsNominalTypeOrNominalTypeExtensionContext();
1053+
1054+
// Handle the generic arguments of the parent.
1055+
unsigned currentGenericParamIdx =
1056+
appendBoundGenericArgs(decl->getDeclContext(), subs, isFirstArgList);
1057+
1058+
// If this is potentially a generic context, emit a generic argument list.
1059+
if (auto genericContext = decl->getAsGenericContext()) {
1060+
if (isFirstArgList) {
1061+
appendOperator("y");
1062+
isFirstArgList = false;
1063+
} else {
1064+
appendOperator("_");
1065+
}
1066+
1067+
// If we are generic at this level, emit all of the replacements at
1068+
// this level.
1069+
if (genericContext->isGeneric()) {
1070+
auto genericParams = subs.getGenericSignature()->getGenericParams();
1071+
unsigned depth = genericParams[currentGenericParamIdx]->getDepth();
1072+
assert(genericContext->getGenericParams()->getDepth() == depth &&
1073+
"Depth mismatch mangling substitution map");
1074+
auto replacements = subs.getReplacementTypes();
1075+
for (unsigned lastGenericParamIdx = genericParams.size();
1076+
(currentGenericParamIdx != lastGenericParamIdx &&
1077+
genericParams[currentGenericParamIdx]->getDepth() == depth);
1078+
++currentGenericParamIdx) {
1079+
Type replacementType = replacements[currentGenericParamIdx];
1080+
if (replacementType->hasArchetype())
1081+
replacementType = replacementType->mapTypeOutOfContext();
1082+
1083+
appendType(replacementType);
1084+
}
1085+
}
1086+
}
1087+
1088+
return currentGenericParamIdx;
1089+
}
1090+
10421091
void ASTMangler::appendBoundGenericArgs(Type type, bool &isFirstArgList) {
1043-
BoundGenericType *boundType = nullptr;
1044-
if (auto *unboundType = type->getAs<UnboundGenericType>()) {
1092+
TypeBase *typePtr = type.getPointer();
1093+
ArrayRef<Type> genericArgs;
1094+
if (auto *typeAlias = dyn_cast<NameAliasType>(typePtr)) {
1095+
appendBoundGenericArgs(typeAlias->getDecl(),
1096+
typeAlias->getSubstitutionMap(),
1097+
isFirstArgList);
1098+
return;
1099+
}
1100+
1101+
if (auto *unboundType = dyn_cast<UnboundGenericType>(typePtr)) {
10451102
if (Type parent = unboundType->getParent())
10461103
appendBoundGenericArgs(parent, isFirstArgList);
1047-
} else if (auto *nominalType = type->getAs<NominalType>()) {
1104+
} else if (auto *nominalType = dyn_cast<NominalType>(typePtr)) {
10481105
if (Type parent = nominalType->getParent())
10491106
appendBoundGenericArgs(parent, isFirstArgList);
10501107
} else {
1051-
boundType = type->castTo<BoundGenericType>();
1108+
auto boundType = cast<BoundGenericType>(typePtr);
1109+
genericArgs = boundType->getGenericArgs();
10521110
if (Type parent = boundType->getParent())
10531111
appendBoundGenericArgs(parent, isFirstArgList);
10541112
}
@@ -1058,10 +1116,8 @@ void ASTMangler::appendBoundGenericArgs(Type type, bool &isFirstArgList) {
10581116
} else {
10591117
appendOperator("_");
10601118
}
1061-
if (boundType) {
1062-
for (Type arg : boundType->getGenericArgs()) {
1063-
appendType(arg);
1064-
}
1119+
for (Type arg : genericArgs) {
1120+
appendType(arg);
10651121
}
10661122
}
10671123

lib/Demangling/OldRemangler.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,11 +1243,7 @@ void Remangler::mangleBuiltinTypeName(Node *node) {
12431243
}
12441244

12451245
void Remangler::mangleTypeAlias(Node *node, EntityContext &ctx) {
1246-
SubstitutionEntry entry;
1247-
if (trySubstitution(node, entry)) return;
1248-
Out << 'a';
1249-
mangleChildNodes(node); // context, identifier
1250-
addSubstitution(entry);
1246+
mangleAnyNominalType(node, ctx);
12511247
}
12521248

12531249
void Remangler::mangleFunctionType(Node *node) {
@@ -1824,6 +1820,9 @@ void Remangler::mangleAnyNominalType(Node *node, EntityContext &ctx) {
18241820
case Node::Kind::Class:
18251821
mangleNominalType(node, 'C', ctx);
18261822
break;
1823+
case Node::Kind::TypeAlias:
1824+
mangleNominalType(node, 'a', ctx);
1825+
break;
18271826
default:
18281827
unreachable("bad nominal type kind");
18291828
}

lib/Demangling/Remangler.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,10 +248,10 @@ class Remangler {
248248
}
249249

250250
void manglePureProtocol(Node *Proto) {
251+
Proto = skipType(Proto);
251252
if (mangleStandardSubstitution(Proto))
252253
return;
253254

254-
Proto = skipType(Proto);
255255
mangleChildNodes(Proto);
256256
}
257257

@@ -474,6 +474,7 @@ void Remangler::mangleGenericArgs(Node *node, char &Separator) {
474474
case Node::Kind::Structure:
475475
case Node::Kind::Enum:
476476
case Node::Kind::Class:
477+
case Node::Kind::TypeAlias:
477478
mangleGenericArgs(node->getChild(0), Separator);
478479
Buffer << Separator;
479480
Separator = '_';
@@ -1712,7 +1713,7 @@ void Remangler::mangleType(Node *node) {
17121713
}
17131714

17141715
void Remangler::mangleTypeAlias(Node *node) {
1715-
mangleAnyGenericType(node, "a");
1716+
mangleAnyNominalType(node);
17161717
}
17171718

17181719
void Remangler::mangleTypeList(Node *node) {
@@ -2057,6 +2058,7 @@ bool Demangle::isSpecialized(Node *node) {
20572058
case Node::Kind::Structure:
20582059
case Node::Kind::Enum:
20592060
case Node::Kind::Class:
2061+
case Node::Kind::TypeAlias:
20602062
case Node::Kind::OtherNominalType:
20612063
return isSpecialized(node->getChild(0));
20622064

@@ -2073,6 +2075,7 @@ NodePointer Demangle::getUnspecialized(Node *node, NodeFactory &Factory) {
20732075
case Node::Kind::Structure:
20742076
case Node::Kind::Enum:
20752077
case Node::Kind::Class:
2078+
case Node::Kind::TypeAlias:
20762079
case Node::Kind::OtherNominalType: {
20772080
NodePointer result = Factory.createNode(node->getKind());
20782081
NodePointer parentOrModule = node->getChild(0);

lib/IDE/TypeReconstruction.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -772,13 +772,31 @@ static void VisitNodeGenericTypealias(ASTContext *ast,
772772
}
773773

774774
if (generic_type_result._decls.size() != 1 ||
775-
generic_type_result._types.size() != 1 ||
776-
template_types_result._types.empty())
775+
generic_type_result._types.size() != 1)
777776
return;
778777

779778
auto *genericTypeAlias =
780779
cast<TypeAliasDecl>(generic_type_result._decls.front());
781780
GenericSignature *signature = genericTypeAlias->getGenericSignature();
781+
if (signature &&
782+
template_types_result._types.size() !=
783+
signature->getGenericParams().size()) {
784+
result._error = stringWithFormat(
785+
"wrong number of generic arguments (%d) for generic typealias %s; "
786+
"expected %d",
787+
template_types_result._types.size(),
788+
genericTypeAlias->getBaseName().userFacingName(),
789+
signature->getGenericParams().size());
790+
791+
return;
792+
}
793+
794+
if (signature && signature->getNumConformanceRequirements() != 0) {
795+
result._error =
796+
"cannot handle generic typealias with conformance requirements";
797+
return;
798+
}
799+
782800
// FIXME: handle conformances.
783801
SubstitutionMap subMap;
784802
if (signature)

test/DebugInfo/DumpDeclFromMangledName.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,25 @@ class Foo<T> {
4949

5050
typealias Patatino<T> = Foo<T>
5151

52+
public struct Outer<T> {
53+
public struct Inner { }
54+
public struct GenericInner<U> { }
55+
56+
public typealias Foo<U> = Outer<U>.Inner
57+
58+
public func blah() {
59+
let foo: Foo<Int> = Outer<Int>.Inner()
60+
}
61+
}
62+
63+
extension Outer.GenericInner {
64+
public typealias Bar = Int
65+
66+
public func useBar() {
67+
let bar: Bar = 7
68+
}
69+
}
70+
5271
func main() -> Int {
5372
var p : Patatino<Int> = Patatino(23);
5473
return 0

test/DebugInfo/DumpTypeFromMangledName.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@ class Foo<T> {
3232

3333
typealias Patatino<T> = Foo<T>
3434

35+
public struct Outer<T> {
36+
public struct Inner { }
37+
38+
public typealias Foo<U> = Outer<U>.Inner
39+
40+
public func blah() {
41+
let foo: Foo<Int> = Outer<Int>.Inner()
42+
}
43+
}
44+
3545
func main() -> Int {
3646
struct patatino {}
3747
var p : Patatino<Int> = Patatino(23);
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
$S12DeclReconstr8patatinoSiyF ---> func patatino() -> Int
22
$S12DeclReconstr1SVACycfC ---> init()
33
$S12DeclReconstr8PatatinoaySiGD ---> typealias Patatino<T> = Foo<T>
4+
$S12DeclReconstr5OuterV3Fooayx_SiGD ---> Can't resolve decl of $S12DeclReconstr5OuterV3Fooayx_SiGD
5+
$S12DeclReconstr5OuterV12GenericInnerV3Barayx_qd___GD ---> typealias Bar = Int

test/DebugInfo/Inputs/type-reconstr-names.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ $SSayypXpG ---> Array<Any.Type>
1111
$S12EyeCandyCore11XPCListenerC14messageHandleryyAA13XPCConnectionV_AA10XPCMessageVxtcvpfiyAF_AHxtcfU_TA.4 ---> Can't resolve type of $S12EyeCandyCore11XPCListenerC14messageHandleryyAA13XPCConnectionV_AA10XPCMessageVxtcvpfiyAF_AHxtcfU_TA.4
1212
$Ss10CollectionP7ElementQa ---> Can't resolve type of $Ss10CollectionP7ElementQa
1313
$S12TypeReconstr8patatinoayAA5tinkyVGSgD ---> Optional<patatino>
14+
$S12TypeReconstr5OuterV3Fooayx_SiGD ---> Can't resolve type of $S12TypeReconstr5OuterV3Fooayx_SiGD

test/Demangle/Inputs/manglings.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,5 +313,7 @@ _$S3BBBBf0602365061_ ---> _$S3BBBBf0602365061_
313313
_$S3BBBBi0602365061_ ---> _$S3BBBBi0602365061_
314314
_$S3BBBBv0602365061_ ---> _$S3BBBBv0602365061_
315315
_T0lxxxmmmTk ---> _T0lxxxmmmTk
316-
$S4blah8PatatinoaySiGD -> blah.Patatino<Swift.Int>
317-
316+
$S4blah8PatatinoaySiGD ---> blah.Patatino<Swift.Int>
317+
$SSiSHsWP ---> protocol witness table for Swift.Int : Swift.Hashable in Swift
318+
$S7TestMod5OuterV3Fooayx_SiGD ---> TestMod.Outer<A>.Foo<Swift.Int>
319+
$Ss17_VariantSetBufferO05CocoaC0ayx_GD ---> Swift._VariantSetBuffer<A>.CocoaBuffer

test/SILOptimizer/array_contentof_opt.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public func testThreeInts(_ a: inout [Int]) {
3232

3333
// CHECK-LABEL: sil @{{.*}}testTooManyInts
3434
// CHECK-NOT: apply
35-
// CHECK: [[F:%[0-9]+]] = function_ref @$SSa6append10contentsOfyqd___t7ElementQyd__Rszs8SequenceRd__lFSi_SaySiGTg5
35+
// CHECK: [[F:%[0-9]+]] = function_ref @$SSa6append10contentsOfyqd___t7ElementQyd__RszSTRd__lFSi_SaySiGTg5
3636
// CHECK-NOT: apply
3737
// CHECK: apply [[F]]
3838
// CHECK-NOT: apply

test/SILOptimizer/eager_specialize.sil

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ bb2:
182182
}
183183

184184
// specialized divideNum<A where ...> (A, den : A) throws -> A
185-
// CHECK-LABEL: sil shared @$S16eager_specialize9divideNum_3denxx_xtKs13SignedIntegerRzlFSi_Tg5 : $@convention(thin) (Int, Int) -> (Int, @error Error) {
185+
// CHECK-LABEL: sil shared @$S16eager_specialize9divideNum_3denxx_xtKSZRzlFSi_Tg5 : $@convention(thin) (Int, Int) -> (Int, @error Error) {
186186
// CHECK: bb0(%0 : $Int, %1 : $Int):
187187
// CHECK: return %{{.*}}
188188
// CHECK: throw %{{.*}}
@@ -224,7 +224,7 @@ bb2:
224224
// CHECK: %{{.*}} = unchecked_addr_cast %2 : $*T to $*Int
225225
// CHECK: %{{.*}} = load %{{.*}} : $*Int
226226
// CHECK: // function_ref specialized divideNum<A>(_:den:)
227-
// CHECK: %{{.*}} = function_ref @$S16eager_specialize9divideNum_3denxx_xtKs13SignedIntegerRzlFSi_Tg5 : $@convention(thin) (Int, Int) -> (Int, @error Error)
227+
// CHECK: %{{.*}} = function_ref @$S16eager_specialize9divideNum_3denxx_xtKSZRzlFSi_Tg5 : $@convention(thin) (Int, Int) -> (Int, @error Error)
228228
// CHECK: try_apply %{{.*}}(%{{.*}}, %{{.*}}) : $@convention(thin) (Int, Int) -> (Int, @error Error), normal bb8, error bb7
229229

230230
// CHECK: bb7(%{{.*}} : $Error):

tools/lldb-moduleimport-test/lldb-moduleimport-test.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,9 @@ int main(int argc, char **argv) {
192192
llvm::cl::opt<std::string> DumpTypeFromMangled(
193193
"type-from-mangled", llvm::cl::desc("dump type from mangled names list"));
194194

195+
llvm::cl::opt<std::string> ResourceDir("resource-dir",
196+
llvm::cl::desc("The directory that holds the compiler resource files"));
197+
195198
llvm::cl::ParseCommandLineOptions(argc, argv);
196199
// Unregister our options so they don't interfere with the command line
197200
// parsing in CodeGen/BackendUtil.cpp.
@@ -254,6 +257,10 @@ int main(int argc, char **argv) {
254257
Invocation.setModuleName("lldbtest");
255258
Invocation.getClangImporterOptions().ModuleCachePath = ModuleCachePath;
256259

260+
if (!ResourceDir.empty()) {
261+
Invocation.setRuntimeResourcePath(ResourceDir);
262+
}
263+
257264
if (CI.setup(Invocation))
258265
return 1;
259266

0 commit comments

Comments
 (0)