Skip to content

Commit bcdc9e7

Browse files
authored
Merge pull request #22237 from slavapestov/type-reconstruction-part-3
Type reconstruction rework, part 3
2 parents 14760dd + 2b90ad1 commit bcdc9e7

17 files changed

+179
-48
lines changed

include/swift/AST/ASTDemangler.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ class ASTBuilder {
114114

115115
Type createObjCClassType(StringRef name);
116116

117+
Type createBoundGenericObjCClassType(StringRef name, ArrayRef<Type> args);
118+
117119
ProtocolDecl *createObjCProtocolDecl(StringRef name);
118120

119121
Type createDynamicSelfType(Type selfType);

include/swift/AST/ASTMangler.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,13 @@ class ASTMangler : public Mangler {
164164

165165
std::string mangleObjCRuntimeName(const NominalTypeDecl *Nominal);
166166

167-
std::string mangleTypeAsUSR(Type type) {
168-
return mangleTypeWithoutPrefix(type);
167+
std::string mangleTypeWithoutPrefix(Type type) {
168+
appendType(type);
169+
return finalize();
169170
}
170171

172+
std::string mangleTypeAsUSR(Type decl);
173+
171174
std::string mangleTypeAsContextUSR(const NominalTypeDecl *type);
172175

173176
std::string mangleDeclAsUSR(const ValueDecl *Decl, StringRef USRPrefix);
@@ -176,6 +179,8 @@ class ASTMangler : public Mangler {
176179
const AbstractStorageDecl *decl,
177180
StringRef USRPrefix);
178181

182+
std::string mangleLocalTypeDecl(const TypeDecl *type);
183+
179184
enum SpecialContext {
180185
ObjCContext,
181186
ClangImporterContext,
@@ -317,11 +322,6 @@ class ASTMangler : public Mangler {
317322
void appendOpParamForLayoutConstraint(LayoutConstraint Layout);
318323

319324
void appendSymbolicReference(SymbolicReferent referent);
320-
321-
std::string mangleTypeWithoutPrefix(Type type) {
322-
appendType(type);
323-
return finalize();
324-
}
325325
};
326326

327327
} // end namespace Mangle

include/swift/AST/TypeCheckRequests.h

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,32 @@ class USRGenerationRequest :
311311
friend SimpleRequest;
312312

313313
// Evaluation.
314-
llvm::Expected<std::string> evaluate(Evaluator &eval, const ValueDecl* d) const;
314+
llvm::Expected<std::string> evaluate(Evaluator &eval, const ValueDecl *d) const;
315+
316+
public:
317+
// Cycle handling
318+
void diagnoseCycle(DiagnosticEngine &diags) const;
319+
void noteCycleStep(DiagnosticEngine &diags) const;
320+
321+
// Caching
322+
bool isCached() const { return true; }
323+
};
324+
325+
/// Generate the mangling for the given local type declaration.
326+
class MangleLocalTypeDeclRequest :
327+
public SimpleRequest<MangleLocalTypeDeclRequest,
328+
CacheKind::Cached,
329+
std::string,
330+
const TypeDecl*>
331+
{
332+
public:
333+
using SimpleRequest::SimpleRequest;
334+
335+
private:
336+
friend SimpleRequest;
337+
338+
// Evaluation.
339+
llvm::Expected<std::string> evaluate(Evaluator &eval, const TypeDecl *d) const;
315340

316341
public:
317342
// Cycle handling

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,4 @@ SWIFT_TYPEID(IsDynamicRequest)
2323
SWIFT_TYPEID(RequirementRequest)
2424
SWIFT_TYPEID(USRGenerationRequest)
2525
SWIFT_TYPEID(DefaultTypeRequest)
26+
SWIFT_TYPEID(MangleLocalTypeDeclRequest)

include/swift/Demangling/TypeDecoder.h

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ class ImplFunctionParam {
102102
getConventionFromString(StringRef conventionString) {
103103
if (conventionString == "@in")
104104
return ConventionType::Indirect_In;
105-
if (conventionString == "@indirect_in_constant")
105+
if (conventionString == "@in_constant")
106106
return ConventionType::Indirect_In_Constant;
107107
if (conventionString == "@in_guaranteed")
108108
return ConventionType::Indirect_In_Guaranteed;
@@ -306,35 +306,15 @@ class TypeDecoder {
306306

307307
return Builder.createNominalType(typeDecl, parent);
308308
}
309-
case NodeKind::BoundGenericClass:
310-
{
311-
#if SWIFT_OBJC_INTEROP
312-
if (Node->getNumChildren() >= 2) {
313-
auto ChildNode = Node->getChild(0);
314-
if (ChildNode->getKind() == NodeKind::Type &&
315-
ChildNode->getNumChildren() > 0)
316-
ChildNode = ChildNode->getChild(0);
317309

318-
if (auto mangledName = getObjCClassOrProtocolName(ChildNode))
319-
return Builder.createObjCClassType(mangledName->str());
320-
}
321-
#endif
322-
LLVM_FALLTHROUGH;
323-
}
324310
case NodeKind::BoundGenericEnum:
325311
case NodeKind::BoundGenericStructure:
312+
case NodeKind::BoundGenericClass:
326313
case NodeKind::BoundGenericTypeAlias:
327314
case NodeKind::BoundGenericOtherNominalType: {
328315
if (Node->getNumChildren() < 2)
329316
return BuiltType();
330317

331-
BuiltTypeDecl typeDecl = BuiltTypeDecl();
332-
BuiltType parent = BuiltType();
333-
bool typeAlias = false;
334-
if (!decodeMangledTypeDecl(Node->getChild(0), typeDecl,
335-
parent, typeAlias))
336-
return BuiltType();
337-
338318
std::vector<BuiltType> args;
339319

340320
const auto &genericArgs = Node->getChild(1);
@@ -347,6 +327,24 @@ class TypeDecoder {
347327
args.push_back(paramType);
348328
}
349329

330+
auto ChildNode = Node->getChild(0);
331+
if (ChildNode->getKind() == NodeKind::Type &&
332+
ChildNode->getNumChildren() > 0)
333+
ChildNode = ChildNode->getChild(0);
334+
335+
#if SWIFT_OBJC_INTEROP
336+
if (auto mangledName = getObjCClassOrProtocolName(ChildNode))
337+
return Builder.createBoundGenericObjCClassType(mangledName->str(),
338+
args);
339+
#endif
340+
341+
BuiltTypeDecl typeDecl = BuiltTypeDecl();
342+
BuiltType parent = BuiltType();
343+
bool typeAlias = false;
344+
if (!decodeMangledTypeDecl(ChildNode, typeDecl,
345+
parent, typeAlias))
346+
return BuiltType();
347+
350348
return Builder.createBoundGenericType(typeDecl, args, parent);
351349
}
352350
case NodeKind::BoundGenericProtocol: {

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,14 @@ class TypeRefBuilder {
386386
return ObjCClassTypeRef::create(*this, name);
387387
}
388388

389+
const ObjCClassTypeRef *
390+
createBoundGenericObjCClassType(const std::string &name,
391+
std::vector<const TypeRef *> &args) {
392+
// Remote reflection just ignores generic arguments for Objective-C
393+
// lightweight generic types, since they don't affect layout.
394+
return createObjCClassType(name);
395+
}
396+
389397
const ObjCProtocolTypeRef *
390398
createObjCProtocolType(const std::string &name) {
391399
return ObjCProtocolTypeRef::create(*this, name);

lib/AST/ASTDemangler.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,30 @@ Type ASTBuilder::createObjCClassType(StringRef name) {
514514
return typeDecl->getDeclaredInterfaceType();
515515
}
516516

517+
Type ASTBuilder::createBoundGenericObjCClassType(StringRef name,
518+
ArrayRef<Type> args) {
519+
auto typeDecl =
520+
findForeignTypeDecl(name, /*relatedEntityKind*/{},
521+
ForeignModuleKind::Imported,
522+
Demangle::Node::Kind::Class);
523+
if (!typeDecl ||
524+
!isa<ClassDecl>(typeDecl)) return Type();
525+
if (!typeDecl->getGenericParams() ||
526+
typeDecl->getGenericParams()->size() != args.size())
527+
return Type();
528+
529+
Type parent;
530+
auto *dc = typeDecl->getDeclContext();
531+
if (dc->isTypeContext()) {
532+
if (dc->isGenericContext())
533+
return Type();
534+
parent = dc->getDeclaredInterfaceType();
535+
}
536+
537+
return BoundGenericClassType::get(cast<ClassDecl>(typeDecl),
538+
parent, args);
539+
}
540+
517541
ProtocolDecl *ASTBuilder::createObjCProtocolDecl(StringRef name) {
518542
auto typeDecl =
519543
findForeignTypeDecl(name, /*relatedEntityKind*/{},

lib/AST/ASTMangler.cpp

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -365,17 +365,13 @@ std::string ASTMangler::mangleTypeForDebugger(Type Ty, const DeclContext *DC) {
365365
"mangling type for debugger", Ty);
366366

367367
DWARFMangling = true;
368+
OptimizeProtocolNames = false;
368369
beginMangling();
369370

370371
if (DC)
371372
bindGenericParameters(DC);
372373

373-
if (auto *fnType = Ty->getAs<AnyFunctionType>()) {
374-
appendFunction(fnType, false);
375-
} else {
376-
appendType(Ty);
377-
}
378-
374+
appendType(Ty);
379375
appendOperator("D");
380376
return finalize();
381377
}
@@ -468,6 +464,20 @@ std::string ASTMangler::mangleTypeAsContextUSR(const NominalTypeDecl *type) {
468464
return finalize();
469465
}
470466

467+
std::string ASTMangler::mangleTypeAsUSR(Type Ty) {
468+
DWARFMangling = true;
469+
beginMangling();
470+
471+
if (auto *fnType = Ty->getAs<AnyFunctionType>()) {
472+
appendFunction(fnType, false);
473+
} else {
474+
appendType(Ty);
475+
}
476+
477+
appendOperator("D");
478+
return finalize();
479+
}
480+
471481
std::string ASTMangler::mangleDeclAsUSR(const ValueDecl *Decl,
472482
StringRef USRPrefix) {
473483
beginManglingWithoutPrefix();
@@ -506,6 +516,22 @@ std::string ASTMangler::mangleAccessorEntityAsUSR(AccessorKind kind,
506516
return finalize();
507517
}
508518

519+
std::string ASTMangler::mangleLocalTypeDecl(const TypeDecl *type) {
520+
beginManglingWithoutPrefix();
521+
AllowNamelessEntities = true;
522+
OptimizeProtocolNames = false;
523+
524+
if (auto GTD = dyn_cast<GenericTypeDecl>(type)) {
525+
appendAnyGenericType(GTD);
526+
} else {
527+
assert(isa<AssociatedTypeDecl>(type));
528+
appendContextOf(type);
529+
appendDeclName(type);
530+
appendOperator("Qa");
531+
}
532+
533+
return finalize();
534+
}
509535

510536
void ASTMangler::appendSymbolKind(SymbolKind SKind) {
511537
switch (SKind) {

lib/AST/Module.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -570,11 +570,8 @@ TypeDecl *SourceFile::lookupLocalType(llvm::StringRef mangledName) const {
570570
ASTContext &ctx = getASTContext();
571571
for (auto typeDecl : LocalTypeDecls) {
572572
auto typeMangledName = evaluateOrDefault(ctx.evaluator,
573-
USRGenerationRequest { typeDecl },
573+
MangleLocalTypeDeclRequest { typeDecl },
574574
std::string());
575-
if (typeMangledName.find("s:") == 0)
576-
typeMangledName = typeMangledName.substr(2);
577-
578575
if (mangledName == typeMangledName)
579576
return typeDecl;
580577
}

lib/AST/TypeCheckRequests.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,22 @@ void USRGenerationRequest::noteCycleStep(DiagnosticEngine &diags) const {
431431
diags.diagnose(d, diag::circular_reference);
432432
}
433433

434+
//----------------------------------------------------------------------------//
435+
// Mangled local type name computation.
436+
//----------------------------------------------------------------------------//
437+
438+
void MangleLocalTypeDeclRequest::diagnoseCycle(DiagnosticEngine &diags) const {
439+
const auto &storage = getStorage();
440+
auto &d = std::get<0>(storage);
441+
diags.diagnose(d, diag::circular_reference);
442+
}
443+
444+
void MangleLocalTypeDeclRequest::noteCycleStep(DiagnosticEngine &diags) const {
445+
const auto &storage = getStorage();
446+
auto &d = std::get<0>(storage);
447+
diags.diagnose(d, diag::circular_reference);
448+
}
449+
434450
//----------------------------------------------------------------------------//
435451
// DefaultTypeRequest.
436452
//----------------------------------------------------------------------------//

lib/AST/USRGeneration.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ static inline StringRef getUSRSpacePrefix() {
3535
bool ide::printTypeUSR(Type Ty, raw_ostream &OS) {
3636
assert(!Ty->hasArchetype() && "cannot have contextless archetypes mangled.");
3737
Mangle::ASTMangler Mangler;
38-
OS << Mangler.mangleTypeForDebugger(Ty->getRValueType(), nullptr);
38+
OS << Mangler.mangleTypeAsUSR(Ty->getRValueType());
3939
return false;
4040
}
4141

@@ -165,7 +165,8 @@ static bool shouldUseObjCUSR(const Decl *D) {
165165
}
166166

167167
llvm::Expected<std::string>
168-
swift::USRGenerationRequest::evaluate(Evaluator &evaluator, const ValueDecl* D) const {
168+
swift::USRGenerationRequest::evaluate(Evaluator &evaluator,
169+
const ValueDecl *D) const {
169170
if (!D->hasName() && !isa<ParamDecl>(D) && !isa<AccessorDecl>(D))
170171
return std::string(); // Ignore.
171172
if (D->getModuleContext()->isBuiltinModule())
@@ -249,6 +250,19 @@ swift::USRGenerationRequest::evaluate(Evaluator &evaluator, const ValueDecl* D)
249250
return NewMangler.mangleDeclAsUSR(D, getUSRSpacePrefix());
250251
}
251252

253+
llvm::Expected<std::string>
254+
swift::MangleLocalTypeDeclRequest::evaluate(Evaluator &evaluator,
255+
const TypeDecl *D) const {
256+
if (!D->hasInterfaceType())
257+
return std::string();
258+
259+
if (isa<ModuleDecl>(D))
260+
return std::string(); // Ignore.
261+
262+
Mangle::ASTMangler NewMangler;
263+
return NewMangler.mangleLocalTypeDecl(D);
264+
}
265+
252266
bool ide::printModuleUSR(ModuleEntity Mod, raw_ostream &OS) {
253267
if (auto *D = Mod.getAsSwiftModule()) {
254268
StringRef moduleName = D->getName().str();

lib/SIL/SILDefaultWitnessTable.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ convertToDefinition(ArrayRef<Entry> entries) {
9797

9898
std::string SILDefaultWitnessTable::getUniqueName() const {
9999
Mangle::ASTMangler Mangler;
100-
return Mangler.mangleTypeAsUSR(getProtocol()->getDeclaredType());
100+
return Mangler.mangleTypeWithoutPrefix(getProtocol()->getDeclaredType());
101101
}
102102

103103
SILDefaultWitnessTable::~SILDefaultWitnessTable() {

lib/Serialization/Serialization.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "swift/AST/PrettyStackTrace.h"
2727
#include "swift/AST/ProtocolConformance.h"
2828
#include "swift/AST/RawComment.h"
29+
#include "swift/AST/TypeCheckRequests.h"
2930
#include "swift/Basic/Dwarf.h"
3031
#include "swift/Basic/FileSystem.h"
3132
#include "swift/Basic/STLExtras.h"
@@ -4638,7 +4639,10 @@ void Serializer::writeAST(ModuleOrSourceFile DC,
46384639
for (auto TD : localTypeDecls) {
46394640
hasLocalTypes = true;
46404641
Mangle::ASTMangler Mangler;
4641-
std::string MangledName = Mangler.mangleDeclAsUSR(TD, /*USRPrefix*/"");
4642+
std::string MangledName =
4643+
evaluateOrDefault(M->getASTContext().evaluator,
4644+
MangleLocalTypeDeclRequest { TD },
4645+
std::string());
46424646
assert(!MangledName.empty() && "Mangled type came back empty!");
46434647
localTypeGenerator.insert(MangledName, addDeclRef(TD));
46444648

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -987,6 +987,13 @@ class DecodedMetadataBuilder {
987987
#endif
988988
}
989989

990+
BuiltType createBoundGenericObjCClassType(const std::string &mangledName,
991+
ArrayRef<BuiltType> args) const {
992+
// Generic arguments of lightweight Objective-C generic classes are not
993+
// reified in the metadata.
994+
return createObjCClassType(mangledName);
995+
}
996+
990997
BuiltType createNominalType(BuiltTypeDecl metadataOrTypeDecl,
991998
BuiltType parent) const {
992999
// Treat nominal type creation the same way as generic type creation,

test/DebugInfo/archetype.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,5 @@ func ExistentialTuple<T: RandomAccessIndex>(_ x: T, y: T) -> T.Distance {
2222
return _overflowChecked((tmp.0, tmp.1))
2323
}
2424
// CHECK: ![[TT]] = !DICompositeType(tag: DW_TAG_structure_type,
25-
// CHECK-SAME: name: "$s8DistanceQz_SbtD"
25+
// CHECK-SAME: name: "$s8Distance9archetype17RandomAccessIndexPQz_SbtD"
2626

0 commit comments

Comments
 (0)