Skip to content

Revert "[DebugInfo] Fix handling of @_originallyDefinedIn types" #78324

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

Closed
wants to merge 1 commit into from
Closed
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: 1 addition & 1 deletion lib/AST/ASTMangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,7 @@ std::string ASTMangler::mangleTypeForDebugger(Type Ty, GenericSignature sig) {
Ty);

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

Expand Down
2 changes: 1 addition & 1 deletion lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -979,7 +979,7 @@ const ExternalSourceLocs *Decl::getSerializedLocs() const {
StringRef Decl::getAlternateModuleName() const {
for (auto *Att: Attrs) {
if (auto *OD = dyn_cast<OriginallyDefinedInAttr>(Att)) {
if (!OD->isInvalid() && OD->isActivePlatform(getASTContext())) {
if (OD->isActivePlatform(getASTContext())) {
return OD->OriginalModuleName;
}
}
Expand Down
166 changes: 33 additions & 133 deletions lib/IRGen/IRGenDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,13 @@
#include "IRBuilder.h"
#include "swift/AST/ASTDemangler.h"
#include "swift/AST/ASTMangler.h"
#include "swift/AST/Attr.h"
#include "swift/AST/Decl.h"
#include "swift/AST/Expr.h"
#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/IRGenOptions.h"
#include "swift/AST/Module.h"
#include "swift/AST/ModuleLoader.h"
#include "swift/AST/ParameterList.h"
#include "swift/AST/Pattern.h"
#include "swift/AST/TypeDifferenceVisitor.h"
#include "swift/AST/TypeWalker.h"
#include "swift/Basic/Assertions.h"
#include "swift/Basic/Compiler.h"
#include "swift/Basic/SourceManager.h"
Expand Down Expand Up @@ -141,7 +137,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
return Line == other.Line && Column == other.Column && File == other.File;
}
};

/// Various caches.
/// \{
llvm::StringSet<> VarNames;
Expand All @@ -154,7 +150,6 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
llvm::DenseMap<const void *, llvm::TrackingMDNodeRef> DIModuleCache;
llvm::StringMap<llvm::TrackingMDNodeRef> DIFileCache;
llvm::StringMap<llvm::TrackingMDNodeRef> RuntimeErrorFnCache;
llvm::StringSet<> OriginallyDefinedInTypes;
TrackingDIRefMap DIRefMap;
TrackingDIRefMap InnerTypeCache;
/// \}
Expand Down Expand Up @@ -1031,12 +1026,9 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
Mangle::ASTMangler Mangler(IGM.Context);
std::string Result = Mangler.mangleTypeForDebugger(Ty, Sig);

bool IsTypeOriginallyDefinedIn =
containsOriginallyDefinedIn(DbgTy.getType());
// TODO(https://github.com/apple/swift/issues/57699): We currently cannot round trip some C++ types.
// There's no way to round trip when respecting @_originallyDefinedIn for a type.
if (!Opts.DisableRoundTripDebugTypes &&
!Ty->getASTContext().LangOpts.EnableCXXInterop && !IsTypeOriginallyDefinedIn) {
!Ty->getASTContext().LangOpts.EnableCXXInterop) {
// Make sure we can reconstruct mangled types for the debugger.
auto &Ctx = Ty->getASTContext();
Type Reconstructed = Demangle::getTypeForMangling(Ctx, Result, Sig);
Expand Down Expand Up @@ -1515,7 +1507,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
/// anchor any typedefs that may appear in parameters so they can be
/// resolved in the debugger without needing to query the Swift module.
llvm::DINodeArray
collectGenericParams(NominalOrBoundGenericNominalType *BGT, bool AsForwardDeclarations = false) {
collectGenericParams(NominalOrBoundGenericNominalType *BGT) {

// Collect the generic args from the type and its parent.
std::vector<Type> GenericArgs;
Expand All @@ -1530,8 +1522,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
SmallVector<llvm::Metadata *, 16> TemplateParams;
for (auto Arg : GenericArgs) {
DebugTypeInfo ParamDebugType;
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes &&
!AsForwardDeclarations)
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
// For the DwarfTypes level don't generate just a forward declaration
// for the generic type parameters.
ParamDebugType = DebugTypeInfo::getFromTypeInfo(
Expand Down Expand Up @@ -1799,19 +1790,39 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
}

llvm::DIType *SpecificationOf = nullptr;
if (auto *TypeDecl = DbgTy.getType()->getNominalOrBoundGenericNominal()) {
// If this is a nominal type that has the @_originallyDefinedIn attribute,
// IRGenDebugInfo emits a forward declaration of the type as a child
// of the original module, and the type with a specification pointing to
// the forward declaraation. We do this so LLDB has enough information to
// both find the type in reflection metadata (the parent module name) and
// find it in the swiftmodule (the module name in the type mangled name).
if (auto Attribute =
TypeDecl->getAttrs().getAttribute<OriginallyDefinedInAttr>()) {
auto Identifier = IGM.getSILModule().getASTContext().getIdentifier(
Attribute->OriginalModuleName);

void *Key = (void *)Identifier.get();
auto InnerScope =
getOrCreateModule(Key, TheCU, Attribute->OriginalModuleName, {});
SpecificationOf = DBuilder.createForwardDecl(
llvm::dwarf::DW_TAG_structure_type, TypeDecl->getNameStr(),
InnerScope, File, 0, llvm::dwarf::DW_LANG_Swift, 0, 0);
}
}

// Here goes!
switch (BaseTy->getKind()) {
case TypeKind::BuiltinUnboundGeneric:
llvm_unreachable("not a real type");

case TypeKind::BuiltinFixedArray: {
// TODO: provide proper array debug info
unsigned FwdDeclLine = 0;
return createOpaqueStruct(Scope, "Builtin.FixedArray", MainFile, FwdDeclLine,
SizeInBits, AlignInBits, Flags, MangledName);
}

case TypeKind::BuiltinPackIndex:
case TypeKind::BuiltinInteger: {
Encoding = llvm::dwarf::DW_ATE_unsigned;
Expand All @@ -1835,7 +1846,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
break;
}

case TypeKind::BuiltinNativeObject:
case TypeKind::BuiltinNativeObject:
case TypeKind::BuiltinBridgeObject:
case TypeKind::BuiltinRawPointer:
case TypeKind::BuiltinRawUnsafeContinuation:
Expand Down Expand Up @@ -1917,7 +1928,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
assert(SizeInBits ==
CI.getTargetInfo().getPointerWidth(clang::LangAS::Default));
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes) {
if (ClassTy->isSpecialized())
if (ClassTy->isSpecialized())
return createSpecializedStructOrClassType(
ClassTy, Decl, Scope, L.File, L.Line, SizeInBits, AlignInBits,
Flags, MangledName);
Expand Down Expand Up @@ -2000,7 +2011,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
auto L = getFileAndLocation(Decl);
unsigned FwdDeclLine = 0;

if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
return createSpecializedStructOrClassType(
ClassTy, Decl, Scope, L.File, L.Line, SizeInBits, AlignInBits,
Flags, MangledName);
Expand Down Expand Up @@ -2304,8 +2315,8 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
unsigned CachedSizeInBits = getSizeInBits(CachedType);
if ((SizeInBits && CachedSizeInBits != *SizeInBits) ||
(!SizeInBits && CachedSizeInBits)) {
// In some situation a specialized type is emitted with size 0, even if
// the real type has a size.
// In some situation a specialized type is emitted with size 0, even if the real
// type has a size.
if (DbgTy.getType()->isSpecialized() && SizeInBits && *SizeInBits > 0 &&
CachedSizeInBits == 0)
return true;
Expand All @@ -2325,7 +2336,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
/// needed to correctly calculate the layout of more complex types built on
/// top of them.
void createSpecialStlibBuiltinTypes() {
if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::ASTTypes)
if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::ASTTypes)
return;
for (auto BuiltinType: IGM.getOrCreateSpecialStlibBuiltinTypes()) {
auto DbgTy = DebugTypeInfo::getFromTypeInfo(
Expand All @@ -2334,103 +2345,6 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
}
}

/// A TypeWalker that finds if a given type's mangling is affected by an
/// @_originallyDefinedIn annotation.
struct OriginallyDefinedInFinder : public TypeWalker {
bool visitedOriginallyDefinedIn = false;

TypeWalker::Action walkToTypePre(Type T) override {
if (visitedOriginallyDefinedIn)
return TypeWalker::Action::Stop;

// A typealias inside a function used that function's signature as part of
// its mangling, so check if any types in the generic signature are
// annotated with @_originallyDefinedIn.
if (auto *TAT = llvm::dyn_cast<TypeAliasType>(T)) {
auto D = TAT->getDecl()->getDeclContext();
if (auto AFD = llvm::dyn_cast<AbstractFunctionDecl>(D)) {
OriginallyDefinedInFinder InnerWalker;
AFD->getInterfaceType().walk(InnerWalker);
if (InnerWalker.visitedOriginallyDefinedIn) {
visitedOriginallyDefinedIn = true;
return TypeWalker::Action::Stop;
}
}
}

auto *TypeDecl = T->getNominalOrBoundGenericNominal();
if (!TypeDecl)
return TypeWalker::Action::Continue;

NominalTypeDecl *ParentDecl = TypeDecl;
while (llvm::isa_and_nonnull<NominalTypeDecl>(ParentDecl->getParent()))
ParentDecl = llvm::cast<NominalTypeDecl>(ParentDecl->getParent());

if (ParentDecl->getAttrs().hasAttribute<OriginallyDefinedInAttr>()) {
visitedOriginallyDefinedIn = true;
return TypeWalker::Action::Stop;
}

return TypeWalker::Action::Continue;
}
};

/// Returns true if the type's mangled name is affected by an
/// @_originallyDefinedIn annotation. This annotation can be on the type
/// itself, one of its generic arguments, etc.
bool containsOriginallyDefinedIn(Type T) {
OriginallyDefinedInFinder Walker;
T.walk(Walker);
return Walker.visitedOriginallyDefinedIn;
}

/// Returns the decl of the type's parent chain annotated by
/// @_originallyDefinedIn. Returns null if no type is annotated.
NominalTypeDecl *getDeclAnnotatedByOriginallyDefinedIn(DebugTypeInfo DbgTy) {
auto Type = DbgTy.getType();
auto *TypeDecl = Type->getNominalOrBoundGenericNominal();
if (!TypeDecl)
return nullptr;

// Find the outermost type, since only those can have @_originallyDefinedIn
// attached to them.
NominalTypeDecl *ParentDecl = TypeDecl;
while (llvm::isa_and_nonnull<NominalTypeDecl>(ParentDecl->getParent()))
ParentDecl = llvm::cast<NominalTypeDecl>(ParentDecl->getParent());

if (ParentDecl->getAttrs().hasAttribute<OriginallyDefinedInAttr>())
return ParentDecl;;

return nullptr;
}

/// If this is a nominal type that has the @_originallyDefinedIn
/// attribute, IRGenDebugInfo emits an imported declaration of the type as
/// a child of the real module. We do this so LLDB has enough
/// information to both find the type in reflection metadata (the module name
/// in the type's mangled name), and find it in the swiftmodule (the type's
/// imported declaration's parent module name).
void handleOriginallyDefinedIn(DebugTypeInfo DbgTy, llvm::DIType *DITy,
StringRef MangledName, llvm::DIFile *File) {
if (OriginallyDefinedInTypes.contains(MangledName))
return;

// Force the generation of the generic type parameters as forward
// declarations, as those types might be annotated with
// @_originallyDefinedIn.
if (auto *BoundDecl = llvm::dyn_cast<BoundGenericType>(DbgTy.getType()))
collectGenericParams(BoundDecl, /*AsForwardDeclarations=*/true);

NominalTypeDecl *OriginallyDefinedInDecl = getDeclAnnotatedByOriginallyDefinedIn(DbgTy);
if (!OriginallyDefinedInDecl)
return;

// Emit the imported declaration under the real swiftmodule the type lives on.
auto RealModule = getOrCreateContext(OriginallyDefinedInDecl->getParent());
DBuilder.createImportedDeclaration(RealModule, DITy, File, 0, MangledName);
OriginallyDefinedInTypes.insert(MangledName);
}

llvm::DIType *getOrCreateType(DebugTypeInfo DbgTy,
llvm::DIScope *Scope = nullptr) {
// Is this an empty type?
Expand Down Expand Up @@ -2475,18 +2389,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
ClangDecl = AliasDecl->getClangDecl();
} else if (auto *ND = DbgTy.getType()->getNominalOrBoundGenericNominal()) {
TypeDecl = ND;
// If this is an originally defined in type, we want to emit this type's
// scope to be the ABI module.
if (auto Attribute =
ND->getAttrs().getAttribute<OriginallyDefinedInAttr>()) {
auto Identifier = IGM.getSILModule().getASTContext().getIdentifier(
Attribute->OriginalModuleName);
void *Key = (void *)Identifier.get();
Scope =
getOrCreateModule(Key, TheCU, Attribute->OriginalModuleName, {});
} else {
Context = ND->getParent();
}
Context = ND->getParent();
ClangDecl = ND->getClangDecl();
} else if (auto BNO = dyn_cast<BuiltinType>(DbgTy.getType())) {
Context = BNO->getASTContext().TheBuiltinModule;
Expand Down Expand Up @@ -2535,8 +2438,6 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
FwdDeclTypes.emplace_back(
std::piecewise_construct, std::make_tuple(MangledName),
std::make_tuple(static_cast<llvm::Metadata *>(FwdDecl)));

handleOriginallyDefinedIn(DbgTy, FwdDecl, MangledName, getFile(Scope));
return FwdDecl;
}
llvm::DIType *DITy = createType(DbgTy, MangledName, Scope, getFile(Scope));
Expand Down Expand Up @@ -2565,7 +2466,6 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
// Store it in the cache.
DITypeCache.insert({DbgTy.getType(), llvm::TrackingMDNodeRef(DITy)});

handleOriginallyDefinedIn(DbgTy, DITy, MangledName, getFile(Scope));
return DITy;
}
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,2 @@
@_originallyDefinedIn(
module: "Barn", iOS 2.0, macOS 2.0, tvOS 2.0, watchOS 2.0)
@available(iOS 1.0, macOS 1.0, tvOS 1.0, watchOS 1.0, *)
public struct Horse {
public init() {}
}

@_originallyDefinedIn(
module: "Barn", iOS 2.0, macOS 2.0, tvOS 2.0, watchOS 2.0)
@available(iOS 1.0, macOS 1.0, tvOS 1.0, watchOS 1.0, *)
public class Cow {
public init() {}
}


@_originallyDefinedIn(
module: "Barn", iOS 2.0, macOS 2.0, tvOS 2.0, watchOS 2.0)
@available(iOS 1.0, macOS 1.0, tvOS 1.0, watchOS 1.0, *)
public class Sheep {
public init() {}
}

@available(macOS 10, *)
@_originallyDefinedIn(module: "Barn", macOS 10.1) public struct Horse {}
26 changes: 2 additions & 24 deletions test/DebugInfo/local_type_originally_defined_in.swift
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/local_type_originally_defined_in_other.swiftmodule %S/Inputs/local_type_originally_defined_in_other.swift
// RUN: %target-swift-frontend -I%t -g -emit-ir %s -o - | %FileCheck %s
// REQUIRES: OS=macosx
// RUN: %target-swift-frontend -I%t -g -emit-ir %s

import local_type_originally_defined_in_other

public func definedInOtherModule() {
let s = Sheep()
// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "Sheep"{{.*}}identifier: "$s4Barn5SheepCD
}
public func localTypeAliasTest(horse: Horse) {
// The local type mangling for 'A' mentions 'Horse', which must
// be mangled using it's current module name, and not the
Expand All @@ -18,21 +13,4 @@ public func localTypeAliasTest(horse: Horse) {

let info = UnsafeMutablePointer<A>.allocate(capacity: 1)
_ = info
// CHECK: DIDerivedType(tag: DW_TAG_typedef, name: "$s32local_type_originally_defined_in0A13TypeAliasTest5horsey4Barn5HorseV_tF1AL_aD"
}

public func localTypeAliasTest() -> Horse {
typealias B = Int

let info = UnsafeMutablePointer<B>.allocate(capacity: 1)
_ = info
return Horse()
// CHECK: DIDerivedType(tag: DW_TAG_typedef, name: "$s32local_type_originally_defined_in0A13TypeAliasTest4Barn5HorseVyF1BL_aD"
}

public func localTypeAliasTestGeneric<T: Cow>(cow: T) {
typealias C = Int

let info = UnsafeMutablePointer<C>.allocate(capacity: 1)
_ = info
}
}
6 changes: 6 additions & 0 deletions test/DebugInfo/module_abi_name.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,11 @@
class SomeClass {}
// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "SomeClass",{{.*}}runtimeLang: DW_LANG_Swift, identifier: "$s7Goodbye9SomeClassCD"

@available(macOS 10.13, *)
@_originallyDefinedIn(module: "ThirdModule", OSX 10.12)
class DefinedElsewhere {}
// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "DefinedElsewhere",{{.*}}runtimeLang: DW_LANG_Swift, identifier: "$s7Goodbye16DefinedElsewhereCD")

let v1 = SomeClass()
let v2 = DefinedElsewhere()

Loading