Skip to content

Type reconstruction rework, part 3 #22237

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jan 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/swift/AST/ASTDemangler.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ class ASTBuilder {

Type createObjCClassType(StringRef name);

Type createBoundGenericObjCClassType(StringRef name, ArrayRef<Type> args);

ProtocolDecl *createObjCProtocolDecl(StringRef name);

Type createDynamicSelfType(Type selfType);
Expand Down
14 changes: 7 additions & 7 deletions include/swift/AST/ASTMangler.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,13 @@ class ASTMangler : public Mangler {

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

std::string mangleTypeAsUSR(Type type) {
return mangleTypeWithoutPrefix(type);
std::string mangleTypeWithoutPrefix(Type type) {
appendType(type);
return finalize();
}

std::string mangleTypeAsUSR(Type decl);

std::string mangleTypeAsContextUSR(const NominalTypeDecl *type);

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

std::string mangleLocalTypeDecl(const TypeDecl *type);

enum SpecialContext {
ObjCContext,
ClangImporterContext,
Expand Down Expand Up @@ -317,11 +322,6 @@ class ASTMangler : public Mangler {
void appendOpParamForLayoutConstraint(LayoutConstraint Layout);

void appendSymbolicReference(SymbolicReferent referent);

std::string mangleTypeWithoutPrefix(Type type) {
appendType(type);
return finalize();
}
};

} // end namespace Mangle
Expand Down
27 changes: 26 additions & 1 deletion include/swift/AST/TypeCheckRequests.h
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,32 @@ class USRGenerationRequest :
friend SimpleRequest;

// Evaluation.
llvm::Expected<std::string> evaluate(Evaluator &eval, const ValueDecl* d) const;
llvm::Expected<std::string> evaluate(Evaluator &eval, const ValueDecl *d) const;

public:
// Cycle handling
void diagnoseCycle(DiagnosticEngine &diags) const;
void noteCycleStep(DiagnosticEngine &diags) const;

// Caching
bool isCached() const { return true; }
};

/// Generate the mangling for the given local type declaration.
class MangleLocalTypeDeclRequest :
public SimpleRequest<MangleLocalTypeDeclRequest,
CacheKind::Cached,
std::string,
const TypeDecl*>
{
public:
using SimpleRequest::SimpleRequest;

private:
friend SimpleRequest;

// Evaluation.
llvm::Expected<std::string> evaluate(Evaluator &eval, const TypeDecl *d) const;

public:
// Cycle handling
Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/TypeCheckerTypeIDZone.def
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ SWIFT_TYPEID(IsDynamicRequest)
SWIFT_TYPEID(RequirementRequest)
SWIFT_TYPEID(USRGenerationRequest)
SWIFT_TYPEID(DefaultTypeRequest)
SWIFT_TYPEID(MangleLocalTypeDeclRequest)
42 changes: 20 additions & 22 deletions include/swift/Demangling/TypeDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class ImplFunctionParam {
getConventionFromString(StringRef conventionString) {
if (conventionString == "@in")
return ConventionType::Indirect_In;
if (conventionString == "@indirect_in_constant")
if (conventionString == "@in_constant")
return ConventionType::Indirect_In_Constant;
if (conventionString == "@in_guaranteed")
return ConventionType::Indirect_In_Guaranteed;
Expand Down Expand Up @@ -306,35 +306,15 @@ class TypeDecoder {

return Builder.createNominalType(typeDecl, parent);
}
case NodeKind::BoundGenericClass:
{
#if SWIFT_OBJC_INTEROP
if (Node->getNumChildren() >= 2) {
auto ChildNode = Node->getChild(0);
if (ChildNode->getKind() == NodeKind::Type &&
ChildNode->getNumChildren() > 0)
ChildNode = ChildNode->getChild(0);

if (auto mangledName = getObjCClassOrProtocolName(ChildNode))
return Builder.createObjCClassType(mangledName->str());
}
#endif
LLVM_FALLTHROUGH;
}
case NodeKind::BoundGenericEnum:
case NodeKind::BoundGenericStructure:
case NodeKind::BoundGenericClass:
case NodeKind::BoundGenericTypeAlias:
case NodeKind::BoundGenericOtherNominalType: {
if (Node->getNumChildren() < 2)
return BuiltType();

BuiltTypeDecl typeDecl = BuiltTypeDecl();
BuiltType parent = BuiltType();
bool typeAlias = false;
if (!decodeMangledTypeDecl(Node->getChild(0), typeDecl,
parent, typeAlias))
return BuiltType();

std::vector<BuiltType> args;

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

auto ChildNode = Node->getChild(0);
if (ChildNode->getKind() == NodeKind::Type &&
ChildNode->getNumChildren() > 0)
ChildNode = ChildNode->getChild(0);

#if SWIFT_OBJC_INTEROP
if (auto mangledName = getObjCClassOrProtocolName(ChildNode))
return Builder.createBoundGenericObjCClassType(mangledName->str(),
args);
#endif

BuiltTypeDecl typeDecl = BuiltTypeDecl();
BuiltType parent = BuiltType();
bool typeAlias = false;
if (!decodeMangledTypeDecl(ChildNode, typeDecl,
parent, typeAlias))
return BuiltType();

return Builder.createBoundGenericType(typeDecl, args, parent);
}
case NodeKind::BoundGenericProtocol: {
Expand Down
8 changes: 8 additions & 0 deletions include/swift/Reflection/TypeRefBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,14 @@ class TypeRefBuilder {
return ObjCClassTypeRef::create(*this, name);
}

const ObjCClassTypeRef *
createBoundGenericObjCClassType(const std::string &name,
std::vector<const TypeRef *> &args) {
// Remote reflection just ignores generic arguments for Objective-C
// lightweight generic types, since they don't affect layout.
return createObjCClassType(name);
}

const ObjCProtocolTypeRef *
createObjCProtocolType(const std::string &name) {
return ObjCProtocolTypeRef::create(*this, name);
Expand Down
24 changes: 24 additions & 0 deletions lib/AST/ASTDemangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,30 @@ Type ASTBuilder::createObjCClassType(StringRef name) {
return typeDecl->getDeclaredInterfaceType();
}

Type ASTBuilder::createBoundGenericObjCClassType(StringRef name,
ArrayRef<Type> args) {
auto typeDecl =
findForeignTypeDecl(name, /*relatedEntityKind*/{},
ForeignModuleKind::Imported,
Demangle::Node::Kind::Class);
if (!typeDecl ||
!isa<ClassDecl>(typeDecl)) return Type();
if (!typeDecl->getGenericParams() ||
typeDecl->getGenericParams()->size() != args.size())
return Type();

Type parent;
auto *dc = typeDecl->getDeclContext();
if (dc->isTypeContext()) {
if (dc->isGenericContext())
return Type();
parent = dc->getDeclaredInterfaceType();
}

return BoundGenericClassType::get(cast<ClassDecl>(typeDecl),
parent, args);
}

ProtocolDecl *ASTBuilder::createObjCProtocolDecl(StringRef name) {
auto typeDecl =
findForeignTypeDecl(name, /*relatedEntityKind*/{},
Expand Down
38 changes: 32 additions & 6 deletions lib/AST/ASTMangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,17 +365,13 @@ std::string ASTMangler::mangleTypeForDebugger(Type Ty, const DeclContext *DC) {
"mangling type for debugger", Ty);

DWARFMangling = true;
OptimizeProtocolNames = false;
beginMangling();

if (DC)
bindGenericParameters(DC);

if (auto *fnType = Ty->getAs<AnyFunctionType>()) {
appendFunction(fnType, false);
} else {
appendType(Ty);
}

appendType(Ty);
appendOperator("D");
return finalize();
}
Expand Down Expand Up @@ -468,6 +464,20 @@ std::string ASTMangler::mangleTypeAsContextUSR(const NominalTypeDecl *type) {
return finalize();
}

std::string ASTMangler::mangleTypeAsUSR(Type Ty) {
DWARFMangling = true;
beginMangling();

if (auto *fnType = Ty->getAs<AnyFunctionType>()) {
appendFunction(fnType, false);
} else {
appendType(Ty);
}

appendOperator("D");
return finalize();
}

std::string ASTMangler::mangleDeclAsUSR(const ValueDecl *Decl,
StringRef USRPrefix) {
beginManglingWithoutPrefix();
Expand Down Expand Up @@ -506,6 +516,22 @@ std::string ASTMangler::mangleAccessorEntityAsUSR(AccessorKind kind,
return finalize();
}

std::string ASTMangler::mangleLocalTypeDecl(const TypeDecl *type) {
beginManglingWithoutPrefix();
AllowNamelessEntities = true;
OptimizeProtocolNames = false;

if (auto GTD = dyn_cast<GenericTypeDecl>(type)) {
appendAnyGenericType(GTD);
} else {
assert(isa<AssociatedTypeDecl>(type));
appendContextOf(type);
appendDeclName(type);
appendOperator("Qa");
}

return finalize();
}

void ASTMangler::appendSymbolKind(SymbolKind SKind) {
switch (SKind) {
Expand Down
5 changes: 1 addition & 4 deletions lib/AST/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -570,11 +570,8 @@ TypeDecl *SourceFile::lookupLocalType(llvm::StringRef mangledName) const {
ASTContext &ctx = getASTContext();
for (auto typeDecl : LocalTypeDecls) {
auto typeMangledName = evaluateOrDefault(ctx.evaluator,
USRGenerationRequest { typeDecl },
MangleLocalTypeDeclRequest { typeDecl },
std::string());
if (typeMangledName.find("s:") == 0)
typeMangledName = typeMangledName.substr(2);

if (mangledName == typeMangledName)
return typeDecl;
}
Expand Down
16 changes: 16 additions & 0 deletions lib/AST/TypeCheckRequests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,22 @@ void USRGenerationRequest::noteCycleStep(DiagnosticEngine &diags) const {
diags.diagnose(d, diag::circular_reference);
}

//----------------------------------------------------------------------------//
// Mangled local type name computation.
//----------------------------------------------------------------------------//

void MangleLocalTypeDeclRequest::diagnoseCycle(DiagnosticEngine &diags) const {
const auto &storage = getStorage();
auto &d = std::get<0>(storage);
diags.diagnose(d, diag::circular_reference);
}

void MangleLocalTypeDeclRequest::noteCycleStep(DiagnosticEngine &diags) const {
const auto &storage = getStorage();
auto &d = std::get<0>(storage);
diags.diagnose(d, diag::circular_reference);
}

//----------------------------------------------------------------------------//
// DefaultTypeRequest.
//----------------------------------------------------------------------------//
Expand Down
18 changes: 16 additions & 2 deletions lib/AST/USRGeneration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ static inline StringRef getUSRSpacePrefix() {
bool ide::printTypeUSR(Type Ty, raw_ostream &OS) {
assert(!Ty->hasArchetype() && "cannot have contextless archetypes mangled.");
Mangle::ASTMangler Mangler;
OS << Mangler.mangleTypeForDebugger(Ty->getRValueType(), nullptr);
OS << Mangler.mangleTypeAsUSR(Ty->getRValueType());
return false;
}

Expand Down Expand Up @@ -165,7 +165,8 @@ static bool shouldUseObjCUSR(const Decl *D) {
}

llvm::Expected<std::string>
swift::USRGenerationRequest::evaluate(Evaluator &evaluator, const ValueDecl* D) const {
swift::USRGenerationRequest::evaluate(Evaluator &evaluator,
const ValueDecl *D) const {
if (!D->hasName() && !isa<ParamDecl>(D) && !isa<AccessorDecl>(D))
return std::string(); // Ignore.
if (D->getModuleContext()->isBuiltinModule())
Expand Down Expand Up @@ -249,6 +250,19 @@ swift::USRGenerationRequest::evaluate(Evaluator &evaluator, const ValueDecl* D)
return NewMangler.mangleDeclAsUSR(D, getUSRSpacePrefix());
}

llvm::Expected<std::string>
swift::MangleLocalTypeDeclRequest::evaluate(Evaluator &evaluator,
const TypeDecl *D) const {
if (!D->hasInterfaceType())
return std::string();

if (isa<ModuleDecl>(D))
return std::string(); // Ignore.

Mangle::ASTMangler NewMangler;
return NewMangler.mangleLocalTypeDecl(D);
}

bool ide::printModuleUSR(ModuleEntity Mod, raw_ostream &OS) {
if (auto *D = Mod.getAsSwiftModule()) {
StringRef moduleName = D->getName().str();
Expand Down
2 changes: 1 addition & 1 deletion lib/SIL/SILDefaultWitnessTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ convertToDefinition(ArrayRef<Entry> entries) {

std::string SILDefaultWitnessTable::getUniqueName() const {
Mangle::ASTMangler Mangler;
return Mangler.mangleTypeAsUSR(getProtocol()->getDeclaredType());
return Mangler.mangleTypeWithoutPrefix(getProtocol()->getDeclaredType());
}

SILDefaultWitnessTable::~SILDefaultWitnessTable() {
Expand Down
6 changes: 5 additions & 1 deletion lib/Serialization/Serialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "swift/AST/PrettyStackTrace.h"
#include "swift/AST/ProtocolConformance.h"
#include "swift/AST/RawComment.h"
#include "swift/AST/TypeCheckRequests.h"
#include "swift/Basic/Dwarf.h"
#include "swift/Basic/FileSystem.h"
#include "swift/Basic/STLExtras.h"
Expand Down Expand Up @@ -4638,7 +4639,10 @@ void Serializer::writeAST(ModuleOrSourceFile DC,
for (auto TD : localTypeDecls) {
hasLocalTypes = true;
Mangle::ASTMangler Mangler;
std::string MangledName = Mangler.mangleDeclAsUSR(TD, /*USRPrefix*/"");
std::string MangledName =
evaluateOrDefault(M->getASTContext().evaluator,
MangleLocalTypeDeclRequest { TD },
std::string());
assert(!MangledName.empty() && "Mangled type came back empty!");
localTypeGenerator.insert(MangledName, addDeclRef(TD));

Expand Down
7 changes: 7 additions & 0 deletions stdlib/public/runtime/MetadataLookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -987,6 +987,13 @@ class DecodedMetadataBuilder {
#endif
}

BuiltType createBoundGenericObjCClassType(const std::string &mangledName,
ArrayRef<BuiltType> args) const {
// Generic arguments of lightweight Objective-C generic classes are not
// reified in the metadata.
return createObjCClassType(mangledName);
}

BuiltType createNominalType(BuiltTypeDecl metadataOrTypeDecl,
BuiltType parent) const {
// Treat nominal type creation the same way as generic type creation,
Expand Down
2 changes: 1 addition & 1 deletion test/DebugInfo/archetype.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ func ExistentialTuple<T: RandomAccessIndex>(_ x: T, y: T) -> T.Distance {
return _overflowChecked((tmp.0, tmp.1))
}
// CHECK: ![[TT]] = !DICompositeType(tag: DW_TAG_structure_type,
// CHECK-SAME: name: "$s8DistanceQz_SbtD"
// CHECK-SAME: name: "$s8Distance9archetype17RandomAccessIndexPQz_SbtD"

Loading