Skip to content

Commit dad4169

Browse files
committed
[AST] Make dumping for SubstitutionMap lisp-formatted and indent-aware.
This is much easier to read when part of a larger dump, where it now occurs in expressions and specialized conformances. Part of rdar://problem/40074968.
1 parent f2e2f83 commit dad4169

File tree

4 files changed

+92
-66
lines changed

4 files changed

+92
-66
lines changed

include/swift/AST/SubstitutionMap.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ class SubstitutionMap {
219219
void verify() const;
220220

221221
/// Dump the contents of this substitution map for debugging purposes.
222-
void dump(llvm::raw_ostream &out) const;
222+
void dump(llvm::raw_ostream &out, unsigned indent = 0) const;
223223

224224
LLVM_ATTRIBUTE_DEPRECATED(void dump() const, "only for use in the debugger");
225225

lib/AST/ASTDumper.cpp

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2905,7 +2905,8 @@ static void dumpProtocolConformanceRec(
29052905
break;
29062906

29072907
out << '\n';
2908-
conf->getSubstitutionMap().dump(out);
2908+
conf->getSubstitutionMap().dump(out, indent + 2);
2909+
out << '\n';
29092910
for (auto subReq : conf->getConditionalRequirements()) {
29102911
out.indent(indent + 2);
29112912
subReq.dump(out);
@@ -2938,6 +2939,64 @@ void ProtocolConformance::dump(llvm::raw_ostream &out, unsigned indent) const {
29382939
dumpProtocolConformanceRec(this, out, indent, visited);
29392940
}
29402941

2942+
void SubstitutionMap::dump(llvm::raw_ostream &out, unsigned indent) const {
2943+
auto *genericSig = getGenericSignature();
2944+
out.indent(indent);
2945+
2946+
auto printParen = [&](char p) {
2947+
PrintWithColorRAII(out, ParenthesisColor) << p;
2948+
};
2949+
printParen('(');
2950+
out << "substitution_map generic_signature=";
2951+
if (genericSig == nullptr) {
2952+
out << "<nullptr>";
2953+
printParen(')');
2954+
return;
2955+
}
2956+
2957+
genericSig->print(out);
2958+
auto genericParams = genericSig->getGenericParams();
2959+
auto replacementTypes = getReplacementTypesBuffer();
2960+
for (unsigned i : indices(genericParams)) {
2961+
out << "\n";
2962+
out.indent(indent + 2);
2963+
printParen('(');
2964+
out << "substitution ";
2965+
genericParams[i]->print(out);
2966+
out << " -> ";
2967+
if (replacementTypes[i])
2968+
replacementTypes[i]->print(out);
2969+
else
2970+
out << "<<unresolved concrete type>>";
2971+
printParen(')');
2972+
}
2973+
2974+
// We only really need to print a conformance once across this whole map.
2975+
llvm::SmallPtrSet<const ProtocolConformance *, 8> visited;
2976+
auto conformances = getConformances();
2977+
for (const auto &req : genericSig->getRequirements()) {
2978+
if (req.getKind() != RequirementKind::Conformance)
2979+
continue;
2980+
2981+
out << "\n";
2982+
out.indent(indent + 2);
2983+
printParen('(');
2984+
out << "conformance type=";
2985+
req.getFirstType()->print(out);
2986+
out << "\n";
2987+
dumpProtocolConformanceRefRec(conformances.front(), out, indent + 4,
2988+
visited);
2989+
2990+
printParen(')');
2991+
conformances = conformances.slice(1);
2992+
}
2993+
}
2994+
2995+
void SubstitutionMap::dump() const {
2996+
dump(llvm::errs());
2997+
llvm::errs() << "\n";
2998+
}
2999+
29413000
//===----------------------------------------------------------------------===//
29423001
// Dumping for Types.
29433002
//===----------------------------------------------------------------------===//

lib/AST/SubstitutionMap.cpp

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -609,48 +609,6 @@ void SubstitutionMap::verify() const {
609609
#endif
610610
}
611611

612-
void SubstitutionMap::dump(llvm::raw_ostream &out) const {
613-
auto *genericSig = getGenericSignature();
614-
if (genericSig == nullptr) {
615-
out << "Empty substitution map\n";
616-
return;
617-
}
618-
out << "Generic signature: ";
619-
genericSig->print(out);
620-
out << "\n";
621-
out << "Substitutions:\n";
622-
auto genericParams = genericSig->getGenericParams();
623-
auto replacementTypes = getReplacementTypesBuffer();
624-
for (unsigned i : indices(genericParams)) {
625-
out.indent(2);
626-
genericParams[i]->print(out);
627-
out << " -> ";
628-
if (replacementTypes[i])
629-
replacementTypes[i]->print(out);
630-
else
631-
out << "<<unresolved concrete type>>";
632-
out << "\n";
633-
}
634-
635-
out << "\nConformance map:\n";
636-
auto conformances = getConformances();
637-
for (const auto &req : genericSig->getRequirements()) {
638-
if (req.getKind() != RequirementKind::Conformance) continue;
639-
640-
out.indent(2);
641-
req.getFirstType()->print(out);
642-
out << " -> ";
643-
conformances.front().dump(out);
644-
out << "\n";
645-
646-
conformances = conformances.slice(1);
647-
}
648-
}
649-
650-
void SubstitutionMap::dump() const {
651-
return dump(llvm::errs());
652-
}
653-
654612
void SubstitutionMap::profile(llvm::FoldingSetNodeID &id) const {
655613
id.AddPointer(storage);
656614
}

test/Driver/debug-generic-signatures.swift

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -75,37 +75,46 @@ extension Generic: P1 where T: P1 {
7575

7676

7777
// Satisfying associated types with requirements with generic params
78-
class Super<T> {}
79-
// CHECK-LABEL: ExtensionDecl line={{.*}} base=Super<T>
80-
// CHECK-NEXT: (normal_conformance type=Super<T> protocol=P2
81-
// CHECK-NEXT: (assoc_type req=A type=Super<T>.A)
82-
// CHECK-NEXT: (assoc_type req=B type=Super<T>.B)
78+
class Super<T, U> {}
79+
// CHECK-LABEL: ExtensionDecl line={{.*}} base=Super<T, U>
80+
// CHECK-NEXT: (normal_conformance type=Super<T, U> protocol=P2
81+
// CHECK-NEXT: (assoc_type req=A type=Super<T, U>.A)
82+
// CHECK-NEXT: (assoc_type req=B type=Super<T, U>.B)
8383
// CHECK-NEXT: (abstract_conformance protocol=P2)
8484
// CHECK: (abstract_conformance protocol=P2)
85-
// CHECK: conforms_to: T P2)
86-
extension Super: P2 where T: P2 {
85+
// CHECK: conforms_to: T P2
86+
// CHECK: conforms_to: U P2)
87+
extension Super: P2 where T: P2, U: P2 {
8788
typealias A = T
8889
typealias B = T
8990
}
9091

9192
// Inherited/specialized conformances.
9293
// CHECK-LABEL: ClassDecl name=Sub
9394
// CHECK-NEXT: (inherited_conformance type=Sub protocol=P2
94-
// CHECK-NEXT: (specialized_conformance type=Super<Recur> protocol=P2
95-
// CHECK-NEXT: Generic signature: <T where T : P2>
96-
// CHECK-NEXT: Substitutions:
97-
// CHECK-NEXT: T -> Recur
98-
// CHECK: Conformance map:
99-
// CHECK-NEXT: T -> (normal_conformance type=Recur protocol=P2
100-
// CHECK-NEXT: (assoc_type req=A type=Recur.A)
101-
// CHECK-NEXT: (assoc_type req=B type=Recur.B)
102-
// CHECK-NEXT: (normal_conformance type=Recur protocol=P2 (details printed above))
103-
// CHECK-NEXT: (normal_conformance type=Recur protocol=P2 (details printed above)))
95+
// CHECK-NEXT: (specialized_conformance type=Super<NonRecur, Recur> protocol=P2
96+
// CHECK-NEXT: (substitution_map generic_signature=<T, U where T : P2, U : P2>
97+
// CHECK-NEXT: (substitution T -> NonRecur)
98+
// CHECK-NEXT: (substitution U -> Recur)
99+
// CHECK-NEXT: (conformance type=T
100+
// CHECK-NEXT: (normal_conformance type=NonRecur protocol=P2
101+
// CHECK-NEXT: (assoc_type req=A type=NonRecur.A)
102+
// CHECK-NEXT: (assoc_type req=B type=NonRecur.B)
103+
// CHECK-NEXT: (normal_conformance type=Recur protocol=P2
104+
// CHECK-NEXT: (assoc_type req=A type=Recur.A)
105+
// CHECK-NEXT: (assoc_type req=B type=Recur.B)
106+
// CHECK-NEXT: (normal_conformance type=Recur protocol=P2 (details printed above))
107+
// CHECK-NEXT: (normal_conformance type=Recur protocol=P2 (details printed above)))
108+
// CHECK-NEXT: (normal_conformance type=Recur protocol=P2 (details printed above))))
109+
// CHECK-NEXT: (conformance type=U
110+
// CHECK-NEXT: (normal_conformance type=Recur protocol=P2 (details printed above))))
111+
// CHECK-NEXT: conforms_to: NonRecur P2
104112
// CHECK-NEXT: conforms_to: Recur P2
105-
// CHECK-NEXT: (normal_conformance type=Super<T> protocol=P2
106-
// CHECK-NEXT: (assoc_type req=A type=Super<T>.A)
107-
// CHECK-NEXT: (assoc_type req=B type=Super<T>.B)
113+
// CHECK-NEXT: (normal_conformance type=Super<T, U> protocol=P2
114+
// CHECK-NEXT: (assoc_type req=A type=Super<T, U>.A)
115+
// CHECK-NEXT: (assoc_type req=B type=Super<T, U>.B)
108116
// CHECK-NEXT: (abstract_conformance protocol=P2)
109117
// CHECK: (abstract_conformance protocol=P2)
110-
// CHECK: conforms_to: T P2)))
111-
class Sub: Super<Recur> {}
118+
// CHECK: conforms_to: T P2
119+
// CHECK: conforms_to: U P2)))
120+
class Sub: Super<NonRecur, Recur> {}

0 commit comments

Comments
 (0)