Skip to content

AST: Fix debug info mangling of opaque result types with @_originallyDefinedIn #59234

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
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
17 changes: 14 additions & 3 deletions include/swift/AST/ASTMangler.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class ASTMangler : public Mangler {

/// If enabled, non-canonical types are allowed and type alias types get a
/// special mangling.
bool DWARFMangling;
bool DWARFMangling = false;

/// If enabled, entities that ought to have names but don't get a placeholder.
///
Expand Down Expand Up @@ -72,6 +72,12 @@ class ASTMangler : public Mangler {
/// function types.
bool Preconcurrency = false;

/// If enabled, declarations annotated with @_originallyDefinedIn are mangled
/// as if they're part of their original module. Disabled for debug mangling,
/// because lldb wants to find declarations in the modules they're currently
/// defined in.
bool RespectOriginallyDefinedIn = true;

public:
using SymbolicReferent = llvm::PointerUnion<const NominalTypeDecl *,
const OpaqueTypeDecl *>;
Expand Down Expand Up @@ -110,8 +116,13 @@ class ASTMangler : public Mangler {
BackDeploymentFallback,
};

ASTMangler(bool DWARFMangling = false)
: DWARFMangling(DWARFMangling) {}
/// lldb overrides the defaulted argument to 'true'.
ASTMangler(bool DWARFMangling = false) {
if (DWARFMangling) {
DWARFMangling = true;
RespectOriginallyDefinedIn = false;
}
}

void addTypeSubstitution(Type type, GenericSignature sig) {
type = dropProtocolsFromAssociatedTypes(type, sig);
Expand Down
27 changes: 20 additions & 7 deletions lib/AST/ASTMangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,7 @@ std::string ASTMangler::mangleTypeForDebugger(Type Ty, GenericSignature sig) {
"mangling type for debugger", Ty);

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

Expand All @@ -651,6 +652,7 @@ std::string ASTMangler::mangleTypeForTypeName(Type type) {

std::string ASTMangler::mangleDeclType(const ValueDecl *decl) {
DWARFMangling = true;
RespectOriginallyDefinedIn = false;
beginMangling();

appendDeclType(decl);
Expand Down Expand Up @@ -742,6 +744,7 @@ std::string ASTMangler::mangleTypeAsContextUSR(const NominalTypeDecl *type) {

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

Ty = getTypeForDWARFMangling(Ty);
Expand All @@ -758,6 +761,7 @@ std::string ASTMangler::mangleTypeAsUSR(Type Ty) {

std::string ASTMangler::mangleAnyDecl(const ValueDecl *Decl, bool prefix) {
DWARFMangling = true;
RespectOriginallyDefinedIn = false;
if (prefix) {
beginMangling();
} else {
Expand Down Expand Up @@ -1032,6 +1036,14 @@ void ASTMangler::appendOpaqueDeclName(const OpaqueTypeDecl *opaqueDecl) {
if (canSymbolicReference(opaqueDecl)) {
appendSymbolicReference(opaqueDecl);
} else if (auto namingDecl = opaqueDecl->getNamingDecl()) {
// Set this to true temporarily, even if we're doing DWARF
// mangling for debug info, where it is false. Otherwise,
// the mangled opaque result type name will not be able to
// be looked up, since we rely on an exact match with the
// ABI name.
llvm::SaveAndRestore<bool> savedRespectOriginallyDefinedIn(
RespectOriginallyDefinedIn, true);

appendEntity(namingDecl);
appendOperator("QO");
} else {
Expand Down Expand Up @@ -2269,10 +2281,11 @@ void ASTMangler::appendModule(const ModuleDecl *module,
// Use the module real name in mangling; this is the physical name
// of the module on-disk, which can be different if -module-alias is
// used.
//
// For example, if a module Foo has 'import Bar', and '-module-alias Bar=Baz'
// was passed, the name 'Baz' will be used for mangling besides loading.
StringRef ModName = module->getRealName().str();
if (!DWARFMangling &&
if (RespectOriginallyDefinedIn &&
module->getABIName() != module->getName()) { // check if the ABI name is set
ModName = module->getABIName().str();
}
Expand All @@ -2281,7 +2294,7 @@ void ASTMangler::appendModule(const ModuleDecl *module,
if (ModName == STDLIB_NAME) {
if (useModuleName.empty()) {
appendOperator("s");
} else if (DWARFMangling) {
} else if (!RespectOriginallyDefinedIn) {
appendOperator("s");
} else {
appendIdentifier(useModuleName);
Expand All @@ -2298,11 +2311,11 @@ void ASTMangler::appendModule(const ModuleDecl *module,
return appendOperator("SC");
}

// Enabling DWARFMangling indicate the mangled names are not part of the ABI,
// probably used by the debugger or IDE (USR). These mangled names will not be
// demangled successfully if we use the original module name instead of the
// actual module name.
if (!useModuleName.empty() && !DWARFMangling)
// Disabling RespectOriginallyDefinedIn indicate the mangled names are not part
// of the ABI, probably used by the debugger or IDE (USR). These mangled names
// will not be demangled successfully if we use the original module name instead
// of the actual module name.
if (!useModuleName.empty() && RespectOriginallyDefinedIn)
appendIdentifier(useModuleName);
else
appendIdentifier(ModName);
Expand Down
2 changes: 1 addition & 1 deletion lib/SIL/IR/SILType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ bool SILType::isNoReturnFunction(SILModule &M,
}

std::string SILType::getMangledName() const {
Mangle::ASTMangler mangler(false/*use dwarf mangling*/);
Mangle::ASTMangler mangler;
return mangler.mangleTypeWithoutPrefix(getASTType());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
// RUN: %target-swift-emit-module-interface(%t/CoreChef.swiftinterface) %s -module-name CoreChef -I %t -disable-availability-checking -DLIB
// RUN: %target-swift-typecheck-module-from-interface(%t/CoreChef.swiftinterface) -module-name CoreChef -I %t -disable-availability-checking

// Also build the module itself with -g to exercise debug info round tripping.
// RUN: %target-swift-frontend -emit-ir -g %s -I %t -disable-availability-checking

// RUN: %FileCheck %s < %t/CoreChef.swiftinterface

// REQUIRES: OS=macosx
Expand Down