From d4869193c8de21a896f6b91fbd3d3796222f22cd Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sat, 1 Nov 2025 22:31:15 -0400 Subject: [PATCH] IRGen: Only skip round-trip demangler check for types that involve C++ types Previously this was disabled entirely if C++ interop was enabled, which is too broad. --- lib/AST/Module.cpp | 13 ++++++++++- lib/IRGen/IRGenDebugInfo.cpp | 45 ++++++++++++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/lib/AST/Module.cpp b/lib/AST/Module.cpp index c1ee8ae8f5eed..2473495be2cfc 100644 --- a/lib/AST/Module.cpp +++ b/lib/AST/Module.cpp @@ -1011,7 +1011,18 @@ void ModuleDecl::lookupMember(SmallVectorImpl &results, } else if (privateDiscriminator.empty()) { auto newEnd = std::remove_if(results.begin()+oldSize, results.end(), [](const ValueDecl *VD) -> bool { - return VD->getFormalAccess() <= AccessLevel::FilePrivate; + // FIXME: The ClangImporter sometimes generates private declarations but + // doesn't give their file unit a private discriminator so they mangle + // incorrectly. + // + // The hasClangNode() carveout makes the ASTDemangler work properly in + // this case. + // + // We should fix things up so that such declarations also mangle with a + // a private discriminator, in which case this entry point will be called + // with the right parameters so that this isn't needed. + return (VD->getFormalAccess() <= AccessLevel::FilePrivate && + !VD->hasClangNode()); }); results.erase(newEnd, results.end()); diff --git a/lib/IRGen/IRGenDebugInfo.cpp b/lib/IRGen/IRGenDebugInfo.cpp index aa48bdea6b9a3..7a1d258e472f4 100644 --- a/lib/IRGen/IRGenDebugInfo.cpp +++ b/lib/IRGen/IRGenDebugInfo.cpp @@ -1075,12 +1075,11 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo { CanonicalName.clear(); } - bool IsTypeOriginallyDefinedIn = - containsOriginallyDefinedIn(DbgTy.getType()); - // TODO(https://github.com/apple/swift/issues/57699): We currently cannot round trip some C++ types. + bool IsTypeOriginallyDefinedIn = containsOriginallyDefinedIn(DbgTy.getType()); + bool IsCxxType = containsCxxType(DbgTy.getType()); // There's no way to round trip when respecting @_originallyDefinedIn for a type. - if (!Opts.DisableRoundTripDebugTypes && - !Ty->getASTContext().LangOpts.EnableCXXInterop && !IsTypeOriginallyDefinedIn) { + // TODO(https://github.com/apple/swift/issues/57699): We currently cannot round trip some C++ types. + if (!Opts.DisableRoundTripDebugTypes && !IsTypeOriginallyDefinedIn && !IsCxxType) { // Make sure we can reconstruct mangled types for the debugger. auto &Ctx = Ty->getASTContext(); Type Reconstructed = Demangle::getTypeForMangling(Ctx, SugaredName, Sig); @@ -2504,6 +2503,42 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo { return Walker.visitedOriginallyDefinedIn; } + /// Returns true if the type contains an imported C++ type. Due to + /// various unimplemented features these cannot round-trip through + /// the ASTDemangler. + /// + /// FIXME: Get these cases working with the ASTDemangler instead. + bool containsCxxType(Type T) { + return T.findIf([&](Type t) -> bool { + if (auto *decl = t->getAnyNominal()) { + if (auto *clangDecl = decl->getClangDecl()) { + // Lookup of template instantiations is not implemented. + if (isa(clangDecl)) + return true; + + // Lookup of types in weird contexts is not implemented. + if (isa(clangDecl) || + isa(clangDecl)) { + auto *dc = clangDecl->getDeclContext(); + while (!isa(dc)) { + // ... in namespaces, + if (isa(dc)) + return true; + + // ... or inside other types. + if (isa(dc)) + return true; + + dc = dc->getParent(); + } + } + } + } + + return false; + }); + } + /// Returns the decl of the type's parent chain annotated by /// @_originallyDefinedIn. Returns null if no type is annotated. NominalTypeDecl *getDeclAnnotatedByOriginallyDefinedIn(DebugTypeInfo DbgTy) {