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 (IGM.Context );
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);
@@ -1507,7 +1515,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
15071515 // / anchor any typedefs that may appear in parameters so they can be
15081516 // / resolved in the debugger without needing to query the Swift module.
15091517 llvm::DINodeArray
1510- collectGenericParams (NominalOrBoundGenericNominalType *BGT) {
1518+ collectGenericParams (NominalOrBoundGenericNominalType *BGT, bool AsForwardDeclarations = false ) {
15111519
15121520 // Collect the generic args from the type and its parent.
15131521 std::vector<Type> GenericArgs;
@@ -1522,7 +1530,8 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
15221530 SmallVector<llvm::Metadata *, 16 > TemplateParams;
15231531 for (auto Arg : GenericArgs) {
15241532 DebugTypeInfo ParamDebugType;
1525- if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
1533+ if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes &&
1534+ !AsForwardDeclarations)
15261535 // For the DwarfTypes level don't generate just a forward declaration
15271536 // for the generic type parameters.
15281537 ParamDebugType = DebugTypeInfo::getFromTypeInfo (
@@ -1790,39 +1799,19 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
17901799 }
17911800
17921801 llvm::DIType *SpecificationOf = nullptr ;
1793- if (auto *TypeDecl = DbgTy.getType ()->getNominalOrBoundGenericNominal ()) {
1794- // If this is a nominal type that has the @_originallyDefinedIn attribute,
1795- // IRGenDebugInfo emits a forward declaration of the type as a child
1796- // of the original module, and the type with a specification pointing to
1797- // the forward declaraation. We do this so LLDB has enough information to
1798- // both find the type in reflection metadata (the parent module name) and
1799- // find it in the swiftmodule (the module name in the type mangled name).
1800- if (auto Attribute =
1801- TypeDecl->getAttrs ().getAttribute <OriginallyDefinedInAttr>()) {
1802- auto Identifier = IGM.getSILModule ().getASTContext ().getIdentifier (
1803- Attribute->OriginalModuleName );
1804-
1805- void *Key = (void *)Identifier.get ();
1806- auto InnerScope =
1807- getOrCreateModule (Key, TheCU, Attribute->OriginalModuleName , {});
1808- SpecificationOf = DBuilder.createForwardDecl (
1809- llvm::dwarf::DW_TAG_structure_type, TypeDecl->getNameStr (),
1810- InnerScope, File, 0 , llvm::dwarf::DW_LANG_Swift, 0 , 0 );
1811- }
1812- }
18131802
18141803 // Here goes!
18151804 switch (BaseTy->getKind ()) {
18161805 case TypeKind::BuiltinUnboundGeneric:
18171806 llvm_unreachable (" not a real type" );
1818-
1807+
18191808 case TypeKind::BuiltinFixedArray: {
18201809 // TODO: provide proper array debug info
18211810 unsigned FwdDeclLine = 0 ;
18221811 return createOpaqueStruct (Scope, " Builtin.FixedArray" , MainFile, FwdDeclLine,
18231812 SizeInBits, AlignInBits, Flags, MangledName);
18241813 }
1825-
1814+
18261815 case TypeKind::BuiltinPackIndex:
18271816 case TypeKind::BuiltinInteger: {
18281817 Encoding = llvm::dwarf::DW_ATE_unsigned;
@@ -1846,7 +1835,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
18461835 break ;
18471836 }
18481837
1849- case TypeKind::BuiltinNativeObject:
1838+ case TypeKind::BuiltinNativeObject:
18501839 case TypeKind::BuiltinBridgeObject:
18511840 case TypeKind::BuiltinRawPointer:
18521841 case TypeKind::BuiltinRawUnsafeContinuation:
@@ -1928,7 +1917,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
19281917 assert (SizeInBits ==
19291918 CI.getTargetInfo ().getPointerWidth (clang::LangAS::Default));
19301919 if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes) {
1931- if (ClassTy->isSpecialized ())
1920+ if (ClassTy->isSpecialized ())
19321921 return createSpecializedStructOrClassType (
19331922 ClassTy, Decl, Scope, L.File , L.Line , SizeInBits, AlignInBits,
19341923 Flags, MangledName);
@@ -2011,7 +2000,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
20112000 auto L = getFileAndLocation (Decl);
20122001 unsigned FwdDeclLine = 0 ;
20132002
2014- if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
2003+ if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
20152004 return createSpecializedStructOrClassType (
20162005 ClassTy, Decl, Scope, L.File , L.Line , SizeInBits, AlignInBits,
20172006 Flags, MangledName);
@@ -2315,8 +2304,8 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
23152304 unsigned CachedSizeInBits = getSizeInBits (CachedType);
23162305 if ((SizeInBits && CachedSizeInBits != *SizeInBits) ||
23172306 (!SizeInBits && CachedSizeInBits)) {
2318- // In some situation a specialized type is emitted with size 0, even if the real
2319- // type has a size.
2307+ // In some situation a specialized type is emitted with size 0, even if
2308+ // the real type has a size.
23202309 if (DbgTy.getType ()->isSpecialized () && SizeInBits && *SizeInBits > 0 &&
23212310 CachedSizeInBits == 0 )
23222311 return true ;
@@ -2336,7 +2325,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
23362325 // / needed to correctly calculate the layout of more complex types built on
23372326 // / top of them.
23382327 void createSpecialStlibBuiltinTypes () {
2339- if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::ASTTypes)
2328+ if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::ASTTypes)
23402329 return ;
23412330 for (auto BuiltinType: IGM.getOrCreateSpecialStlibBuiltinTypes ()) {
23422331 auto DbgTy = DebugTypeInfo::getFromTypeInfo (
@@ -2345,6 +2334,103 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
23452334 }
23462335 }
23472336
2337+ // / A TypeWalker that finds if a given type's mangling is affected by an
2338+ // / @_originallyDefinedIn annotation.
2339+ struct OriginallyDefinedInFinder : public TypeWalker {
2340+ bool visitedOriginallyDefinedIn = false ;
2341+
2342+ TypeWalker::Action walkToTypePre (Type T) override {
2343+ if (visitedOriginallyDefinedIn)
2344+ return TypeWalker::Action::Stop;
2345+
2346+ // A typealias inside a function used that function's signature as part of
2347+ // its mangling, so check if any types in the generic signature are
2348+ // annotated with @_originallyDefinedIn.
2349+ if (auto *TAT = llvm::dyn_cast<TypeAliasType>(T)) {
2350+ auto D = TAT->getDecl ()->getDeclContext ();
2351+ if (auto AFD = llvm::dyn_cast<AbstractFunctionDecl>(D)) {
2352+ OriginallyDefinedInFinder InnerWalker;
2353+ AFD->getInterfaceType ().walk (InnerWalker);
2354+ if (InnerWalker.visitedOriginallyDefinedIn ) {
2355+ visitedOriginallyDefinedIn = true ;
2356+ return TypeWalker::Action::Stop;
2357+ }
2358+ }
2359+ }
2360+
2361+ auto *TypeDecl = T->getNominalOrBoundGenericNominal ();
2362+ if (!TypeDecl)
2363+ return TypeWalker::Action::Continue;
2364+
2365+ NominalTypeDecl *ParentDecl = TypeDecl;
2366+ while (llvm::isa_and_nonnull<NominalTypeDecl>(ParentDecl->getParent ()))
2367+ ParentDecl = llvm::cast<NominalTypeDecl>(ParentDecl->getParent ());
2368+
2369+ if (ParentDecl->getAttrs ().hasAttribute <OriginallyDefinedInAttr>()) {
2370+ visitedOriginallyDefinedIn = true ;
2371+ return TypeWalker::Action::Stop;
2372+ }
2373+
2374+ return TypeWalker::Action::Continue;
2375+ }
2376+ };
2377+
2378+ // / Returns true if the type's mangled name is affected by an
2379+ // / @_originallyDefinedIn annotation. This annotation can be on the type
2380+ // / itself, one of its generic arguments, etc.
2381+ bool containsOriginallyDefinedIn (Type T) {
2382+ OriginallyDefinedInFinder Walker;
2383+ T.walk (Walker);
2384+ return Walker.visitedOriginallyDefinedIn ;
2385+ }
2386+
2387+ // / Returns the decl of the type's parent chain annotated by
2388+ // / @_originallyDefinedIn. Returns null if no type is annotated.
2389+ NominalTypeDecl *getDeclAnnotatedByOriginallyDefinedIn (DebugTypeInfo DbgTy) {
2390+ auto Type = DbgTy.getType ();
2391+ auto *TypeDecl = Type->getNominalOrBoundGenericNominal ();
2392+ if (!TypeDecl)
2393+ return nullptr ;
2394+
2395+ // Find the outermost type, since only those can have @_originallyDefinedIn
2396+ // attached to them.
2397+ NominalTypeDecl *ParentDecl = TypeDecl;
2398+ while (llvm::isa_and_nonnull<NominalTypeDecl>(ParentDecl->getParent ()))
2399+ ParentDecl = llvm::cast<NominalTypeDecl>(ParentDecl->getParent ());
2400+
2401+ if (ParentDecl->getAttrs ().hasAttribute <OriginallyDefinedInAttr>())
2402+ return ParentDecl;;
2403+
2404+ return nullptr ;
2405+ }
2406+
2407+ // / If this is a nominal type that has the @_originallyDefinedIn
2408+ // / attribute, IRGenDebugInfo emits an imported declaration of the type as
2409+ // / a child of the real module. We do this so LLDB has enough
2410+ // / information to both find the type in reflection metadata (the module name
2411+ // / in the type's mangled name), and find it in the swiftmodule (the type's
2412+ // / imported declaration's parent module name).
2413+ void handleOriginallyDefinedIn (DebugTypeInfo DbgTy, llvm::DIType *DITy,
2414+ StringRef MangledName, llvm::DIFile *File) {
2415+ if (OriginallyDefinedInTypes.contains (MangledName))
2416+ return ;
2417+
2418+ // Force the generation of the generic type parameters as forward
2419+ // declarations, as those types might be annotated with
2420+ // @_originallyDefinedIn.
2421+ if (auto *BoundDecl = llvm::dyn_cast<BoundGenericType>(DbgTy.getType ()))
2422+ collectGenericParams (BoundDecl, /* AsForwardDeclarations=*/ true );
2423+
2424+ NominalTypeDecl *OriginallyDefinedInDecl = getDeclAnnotatedByOriginallyDefinedIn (DbgTy);
2425+ if (!OriginallyDefinedInDecl)
2426+ return ;
2427+
2428+ // Emit the imported declaration under the real swiftmodule the type lives on.
2429+ auto RealModule = getOrCreateContext (OriginallyDefinedInDecl->getParent ());
2430+ DBuilder.createImportedDeclaration (RealModule, DITy, File, 0 , MangledName);
2431+ OriginallyDefinedInTypes.insert (MangledName);
2432+ }
2433+
23482434 llvm::DIType *getOrCreateType (DebugTypeInfo DbgTy,
23492435 llvm::DIScope *Scope = nullptr ) {
23502436 // Is this an empty type?
@@ -2389,7 +2475,18 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
23892475 ClangDecl = AliasDecl->getClangDecl ();
23902476 } else if (auto *ND = DbgTy.getType ()->getNominalOrBoundGenericNominal ()) {
23912477 TypeDecl = ND;
2392- Context = ND->getParent ();
2478+ // If this is an originally defined in type, we want to emit this type's
2479+ // scope to be the ABI module.
2480+ if (auto Attribute =
2481+ ND->getAttrs ().getAttribute <OriginallyDefinedInAttr>()) {
2482+ auto Identifier = IGM.getSILModule ().getASTContext ().getIdentifier (
2483+ Attribute->OriginalModuleName );
2484+ void *Key = (void *)Identifier.get ();
2485+ Scope =
2486+ getOrCreateModule (Key, TheCU, Attribute->OriginalModuleName , {});
2487+ } else {
2488+ Context = ND->getParent ();
2489+ }
23932490 ClangDecl = ND->getClangDecl ();
23942491 } else if (auto BNO = dyn_cast<BuiltinType>(DbgTy.getType ())) {
23952492 Context = BNO->getASTContext ().TheBuiltinModule ;
@@ -2438,6 +2535,8 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
24382535 FwdDeclTypes.emplace_back (
24392536 std::piecewise_construct, std::make_tuple (MangledName),
24402537 std::make_tuple (static_cast <llvm::Metadata *>(FwdDecl)));
2538+
2539+ handleOriginallyDefinedIn (DbgTy, FwdDecl, MangledName, getFile (Scope));
24412540 return FwdDecl;
24422541 }
24432542 llvm::DIType *DITy = createType (DbgTy, MangledName, Scope, getFile (Scope));
@@ -2466,6 +2565,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
24662565 // Store it in the cache.
24672566 DITypeCache.insert ({DbgTy.getType (), llvm::TrackingMDNodeRef (DITy)});
24682567
2568+ handleOriginallyDefinedIn (DbgTy, DITy, MangledName, getFile (Scope));
24692569 return DITy;
24702570 }
24712571};
0 commit comments