2323#include " IRBuilder.h"
2424#include " swift/AST/ASTDemangler.h"
2525#include " swift/AST/ASTMangler.h"
26+ #include " swift/AST/Attr.h"
27+ #include " swift/AST/Decl.h"
2628#include " swift/AST/Expr.h"
2729#include " swift/AST/GenericEnvironment.h"
2830#include " swift/AST/IRGenOptions.h"
2931#include " swift/AST/Module.h"
3032#include " swift/AST/ModuleLoader.h"
33+ #include " swift/AST/ParameterList.h"
3134#include " swift/AST/Pattern.h"
3235#include " swift/AST/TypeDifferenceVisitor.h"
36+ #include " swift/AST/TypeWalker.h"
3337#include " swift/Basic/Assertions.h"
3438#include " swift/Basic/Compiler.h"
3539#include " swift/Basic/SourceManager.h"
@@ -137,7 +141,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
137141 return Line == other.Line && Column == other.Column && File == other.File ;
138142 }
139143 };
140-
144+
141145 // / Various caches.
142146 // / \{
143147 llvm::StringSet<> VarNames;
@@ -150,6 +154,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
150154 llvm::DenseMap<const void *, llvm::TrackingMDNodeRef> DIModuleCache;
151155 llvm::StringMap<llvm::TrackingMDNodeRef> DIFileCache;
152156 llvm::StringMap<llvm::TrackingMDNodeRef> RuntimeErrorFnCache;
157+ llvm::StringSet<> OriginallyDefinedInTypes;
153158 TrackingDIRefMap DIRefMap;
154159 TrackingDIRefMap InnerTypeCache;
155160 // / \}
@@ -1026,9 +1031,12 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
10261031 Mangle::ASTMangler Mangler;
10271032 std::string Result = Mangler.mangleTypeForDebugger (Ty, Sig);
10281033
1034+ bool IsTypeOriginallyDefinedIn =
1035+ containsOriginallyDefinedIn (DbgTy.getType ());
10291036 // TODO(https://github.com/apple/swift/issues/57699): We currently cannot round trip some C++ types.
1037+ // There's no way to round trip when respecting @_originallyDefinedIn for a type.
10301038 if (!Opts.DisableRoundTripDebugTypes &&
1031- !Ty->getASTContext ().LangOpts .EnableCXXInterop ) {
1039+ !Ty->getASTContext ().LangOpts .EnableCXXInterop && !IsTypeOriginallyDefinedIn ) {
10321040 // Make sure we can reconstruct mangled types for the debugger.
10331041 auto &Ctx = Ty->getASTContext ();
10341042 Type Reconstructed = Demangle::getTypeForMangling (Ctx, Result, Sig);
@@ -1506,7 +1514,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
15061514 // / anchor any typedefs that may appear in parameters so they can be
15071515 // / resolved in the debugger without needing to query the Swift module.
15081516 llvm::DINodeArray
1509- collectGenericParams (NominalOrBoundGenericNominalType *BGT) {
1517+ collectGenericParams (NominalOrBoundGenericNominalType *BGT, bool AsForwardDeclarations = false ) {
15101518
15111519 // Collect the generic args from the type and its parent.
15121520 std::vector<Type> GenericArgs;
@@ -1521,7 +1529,8 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
15211529 SmallVector<llvm::Metadata *, 16 > TemplateParams;
15221530 for (auto Arg : GenericArgs) {
15231531 DebugTypeInfo ParamDebugType;
1524- if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
1532+ if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes &&
1533+ !AsForwardDeclarations)
15251534 // For the DwarfTypes level don't generate just a forward declaration
15261535 // for the generic type parameters.
15271536 ParamDebugType = DebugTypeInfo::getFromTypeInfo (
@@ -1789,39 +1798,19 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
17891798 }
17901799
17911800 llvm::DIType *SpecificationOf = nullptr ;
1792- if (auto *TypeDecl = DbgTy.getType ()->getNominalOrBoundGenericNominal ()) {
1793- // If this is a nominal type that has the @_originallyDefinedIn attribute,
1794- // IRGenDebugInfo emits a forward declaration of the type as a child
1795- // of the original module, and the type with a specification pointing to
1796- // the forward declaraation. We do this so LLDB has enough information to
1797- // both find the type in reflection metadata (the parent module name) and
1798- // find it in the swiftmodule (the module name in the type mangled name).
1799- if (auto Attribute =
1800- TypeDecl->getAttrs ().getAttribute <OriginallyDefinedInAttr>()) {
1801- auto Identifier = IGM.getSILModule ().getASTContext ().getIdentifier (
1802- Attribute->OriginalModuleName );
1803-
1804- void *Key = (void *)Identifier.get ();
1805- auto InnerScope =
1806- getOrCreateModule (Key, TheCU, Attribute->OriginalModuleName , {});
1807- SpecificationOf = DBuilder.createForwardDecl (
1808- llvm::dwarf::DW_TAG_structure_type, TypeDecl->getNameStr (),
1809- InnerScope, File, 0 , llvm::dwarf::DW_LANG_Swift, 0 , 0 );
1810- }
1811- }
18121801
18131802 // Here goes!
18141803 switch (BaseTy->getKind ()) {
18151804 case TypeKind::BuiltinUnboundGeneric:
18161805 llvm_unreachable (" not a real type" );
1817-
1806+
18181807 case TypeKind::BuiltinFixedArray: {
18191808 // TODO: provide proper array debug info
18201809 unsigned FwdDeclLine = 0 ;
18211810 return createOpaqueStruct (Scope, " Builtin.FixedArray" , MainFile, FwdDeclLine,
18221811 SizeInBits, AlignInBits, Flags, MangledName);
18231812 }
1824-
1813+
18251814 case TypeKind::BuiltinPackIndex:
18261815 case TypeKind::BuiltinInteger: {
18271816 Encoding = llvm::dwarf::DW_ATE_unsigned;
@@ -1845,7 +1834,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
18451834 break ;
18461835 }
18471836
1848- case TypeKind::BuiltinNativeObject:
1837+ case TypeKind::BuiltinNativeObject:
18491838 case TypeKind::BuiltinBridgeObject:
18501839 case TypeKind::BuiltinRawPointer:
18511840 case TypeKind::BuiltinRawUnsafeContinuation:
@@ -1927,7 +1916,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
19271916 assert (SizeInBits ==
19281917 CI.getTargetInfo ().getPointerWidth (clang::LangAS::Default));
19291918 if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes) {
1930- if (ClassTy->isSpecialized ())
1919+ if (ClassTy->isSpecialized ())
19311920 return createSpecializedStructOrClassType (
19321921 ClassTy, Decl, Scope, L.File , L.Line , SizeInBits, AlignInBits,
19331922 Flags, MangledName);
@@ -2010,7 +1999,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
20101999 auto L = getFileAndLocation (Decl);
20112000 unsigned FwdDeclLine = 0 ;
20122001
2013- if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
2002+ if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
20142003 return createSpecializedStructOrClassType (
20152004 ClassTy, Decl, Scope, L.File , L.Line , SizeInBits, AlignInBits,
20162005 Flags, MangledName);
@@ -2308,8 +2297,8 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
23082297 unsigned CachedSizeInBits = getSizeInBits (CachedType);
23092298 if ((SizeInBits && CachedSizeInBits != *SizeInBits) ||
23102299 (!SizeInBits && CachedSizeInBits)) {
2311- // In some situation a specialized type is emitted with size 0, even if the real
2312- // type has a size.
2300+ // In some situation a specialized type is emitted with size 0, even if
2301+ // the real type has a size.
23132302 if (DbgTy.getType ()->isSpecialized () && SizeInBits && *SizeInBits > 0 &&
23142303 CachedSizeInBits == 0 )
23152304 return true ;
@@ -2329,7 +2318,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
23292318 // / needed to correctly calculate the layout of more complex types built on
23302319 // / top of them.
23312320 void createSpecialStlibBuiltinTypes () {
2332- if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::ASTTypes)
2321+ if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::ASTTypes)
23332322 return ;
23342323 for (auto BuiltinType: IGM.getOrCreateSpecialStlibBuiltinTypes ()) {
23352324 auto DbgTy = DebugTypeInfo::getFromTypeInfo (
@@ -2338,6 +2327,103 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
23382327 }
23392328 }
23402329
2330+ // / A TypeWalker that finds if a given type's mangling is affected by an
2331+ // / @_originallyDefinedIn annotation.
2332+ struct OriginallyDefinedInFinder : public TypeWalker {
2333+ bool visitedOriginallyDefinedIn = false ;
2334+
2335+ TypeWalker::Action walkToTypePre (Type T) override {
2336+ if (visitedOriginallyDefinedIn)
2337+ return TypeWalker::Action::Stop;
2338+
2339+ // A typealias inside a function used that function's signature as part of
2340+ // its mangling, so check if any types in the generic signature are
2341+ // annotated with @_originallyDefinedIn.
2342+ if (auto *TAT = llvm::dyn_cast<TypeAliasType>(T)) {
2343+ auto D = TAT->getDecl ()->getDeclContext ();
2344+ if (auto AFD = llvm::dyn_cast<AbstractFunctionDecl>(D)) {
2345+ OriginallyDefinedInFinder InnerWalker;
2346+ AFD->getInterfaceType ().walk (InnerWalker);
2347+ if (InnerWalker.visitedOriginallyDefinedIn ) {
2348+ visitedOriginallyDefinedIn = true ;
2349+ return TypeWalker::Action::Stop;
2350+ }
2351+ }
2352+ }
2353+
2354+ auto *TypeDecl = T->getNominalOrBoundGenericNominal ();
2355+ if (!TypeDecl)
2356+ return TypeWalker::Action::Continue;
2357+
2358+ NominalTypeDecl *ParentDecl = TypeDecl;
2359+ while (llvm::isa_and_nonnull<NominalTypeDecl>(ParentDecl->getParent ()))
2360+ ParentDecl = llvm::cast<NominalTypeDecl>(ParentDecl->getParent ());
2361+
2362+ if (ParentDecl->getAttrs ().hasAttribute <OriginallyDefinedInAttr>()) {
2363+ visitedOriginallyDefinedIn = true ;
2364+ return TypeWalker::Action::Stop;
2365+ }
2366+
2367+ return TypeWalker::Action::Continue;
2368+ }
2369+ };
2370+
2371+ // / Returns true if the type's mangled name is affected by an
2372+ // / @_originallyDefinedIn annotation. This annotation can be on the type
2373+ // / itself, one of its generic arguments, etc.
2374+ bool containsOriginallyDefinedIn (Type T) {
2375+ OriginallyDefinedInFinder Walker;
2376+ T.walk (Walker);
2377+ return Walker.visitedOriginallyDefinedIn ;
2378+ }
2379+
2380+ // / Returns the decl of the type's parent chain annotated by
2381+ // / @_originallyDefinedIn. Returns null if no type is annotated.
2382+ NominalTypeDecl *getDeclAnnotatedByOriginallyDefinedIn (DebugTypeInfo DbgTy) {
2383+ auto Type = DbgTy.getType ();
2384+ auto *TypeDecl = Type->getNominalOrBoundGenericNominal ();
2385+ if (!TypeDecl)
2386+ return nullptr ;
2387+
2388+ // Find the outermost type, since only those can have @_originallyDefinedIn
2389+ // attached to them.
2390+ NominalTypeDecl *ParentDecl = TypeDecl;
2391+ while (llvm::isa_and_nonnull<NominalTypeDecl>(ParentDecl->getParent ()))
2392+ ParentDecl = llvm::cast<NominalTypeDecl>(ParentDecl->getParent ());
2393+
2394+ if (ParentDecl->getAttrs ().hasAttribute <OriginallyDefinedInAttr>())
2395+ return ParentDecl;;
2396+
2397+ return nullptr ;
2398+ }
2399+
2400+ // / If this is a nominal type that has the @_originallyDefinedIn
2401+ // / attribute, IRGenDebugInfo emits an imported declaration of the type as
2402+ // / a child of the real module. We do this so LLDB has enough
2403+ // / information to both find the type in reflection metadata (the module name
2404+ // / in the type's mangled name), and find it in the swiftmodule (the type's
2405+ // / imported declaration's parent module name).
2406+ void handleOriginallyDefinedIn (DebugTypeInfo DbgTy, llvm::DIType *DITy,
2407+ StringRef MangledName, llvm::DIFile *File) {
2408+ if (OriginallyDefinedInTypes.contains (MangledName))
2409+ return ;
2410+
2411+ // Force the generation of the generic type parameters as forward
2412+ // declarations, as those types might be annotated with
2413+ // @_originallyDefinedIn.
2414+ if (auto *BoundDecl = llvm::dyn_cast<BoundGenericType>(DbgTy.getType ()))
2415+ collectGenericParams (BoundDecl, /* AsForwardDeclarations=*/ true );
2416+
2417+ NominalTypeDecl *OriginallyDefinedInDecl = getDeclAnnotatedByOriginallyDefinedIn (DbgTy);
2418+ if (!OriginallyDefinedInDecl)
2419+ return ;
2420+
2421+ // Emit the imported declaration under the real swiftmodule the type lives on.
2422+ auto RealModule = getOrCreateContext (OriginallyDefinedInDecl->getParent ());
2423+ DBuilder.createImportedDeclaration (RealModule, DITy, File, 0 , MangledName);
2424+ OriginallyDefinedInTypes.insert (MangledName);
2425+ }
2426+
23412427 llvm::DIType *getOrCreateType (DebugTypeInfo DbgTy,
23422428 llvm::DIScope *Scope = nullptr ) {
23432429 // Is this an empty type?
@@ -2382,7 +2468,18 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
23822468 ClangDecl = AliasDecl->getClangDecl ();
23832469 } else if (auto *ND = DbgTy.getType ()->getNominalOrBoundGenericNominal ()) {
23842470 TypeDecl = ND;
2385- Context = ND->getParent ();
2471+ // If this is an originally defined in type, we want to emit this type's
2472+ // scope to be the ABI module.
2473+ if (auto Attribute =
2474+ ND->getAttrs ().getAttribute <OriginallyDefinedInAttr>()) {
2475+ auto Identifier = IGM.getSILModule ().getASTContext ().getIdentifier (
2476+ Attribute->OriginalModuleName );
2477+ void *Key = (void *)Identifier.get ();
2478+ Scope =
2479+ getOrCreateModule (Key, TheCU, Attribute->OriginalModuleName , {});
2480+ } else {
2481+ Context = ND->getParent ();
2482+ }
23862483 ClangDecl = ND->getClangDecl ();
23872484 } else if (auto BNO = dyn_cast<BuiltinType>(DbgTy.getType ())) {
23882485 Context = BNO->getASTContext ().TheBuiltinModule ;
@@ -2431,6 +2528,8 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
24312528 FwdDeclTypes.emplace_back (
24322529 std::piecewise_construct, std::make_tuple (MangledName),
24332530 std::make_tuple (static_cast <llvm::Metadata *>(FwdDecl)));
2531+
2532+ handleOriginallyDefinedIn (DbgTy, FwdDecl, MangledName, getFile (Scope));
24342533 return FwdDecl;
24352534 }
24362535 llvm::DIType *DITy = createType (DbgTy, MangledName, Scope, getFile (Scope));
@@ -2459,6 +2558,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
24592558 // Store it in the cache.
24602559 DITypeCache.insert ({DbgTy.getType (), llvm::TrackingMDNodeRef (DITy)});
24612560
2561+ handleOriginallyDefinedIn (DbgTy, DITy, MangledName, getFile (Scope));
24622562 return DITy;
24632563 }
24642564};
0 commit comments