23
23
#include " IRBuilder.h"
24
24
#include " swift/AST/ASTDemangler.h"
25
25
#include " swift/AST/ASTMangler.h"
26
+ #include " swift/AST/Attr.h"
27
+ #include " swift/AST/Decl.h"
26
28
#include " swift/AST/Expr.h"
27
29
#include " swift/AST/GenericEnvironment.h"
28
30
#include " swift/AST/IRGenOptions.h"
29
31
#include " swift/AST/Module.h"
30
32
#include " swift/AST/ModuleLoader.h"
31
33
#include " swift/AST/Pattern.h"
32
34
#include " swift/AST/TypeDifferenceVisitor.h"
35
+ #include " swift/AST/TypeWalker.h"
33
36
#include " swift/Basic/Assertions.h"
34
37
#include " swift/Basic/Compiler.h"
35
38
#include " swift/Basic/SourceManager.h"
@@ -137,7 +140,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
137
140
return Line == other.Line && Column == other.Column && File == other.File ;
138
141
}
139
142
};
140
-
143
+
141
144
// / Various caches.
142
145
// / \{
143
146
llvm::StringSet<> VarNames;
@@ -150,6 +153,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
150
153
llvm::DenseMap<const void *, llvm::TrackingMDNodeRef> DIModuleCache;
151
154
llvm::StringMap<llvm::TrackingMDNodeRef> DIFileCache;
152
155
llvm::StringMap<llvm::TrackingMDNodeRef> RuntimeErrorFnCache;
156
+ llvm::StringSet<> OriginallyDefinedInTypes;
153
157
TrackingDIRefMap DIRefMap;
154
158
TrackingDIRefMap InnerTypeCache;
155
159
// / \}
@@ -1026,9 +1030,12 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1026
1030
Mangle::ASTMangler Mangler (IGM.Context );
1027
1031
std::string Result = Mangler.mangleTypeForDebugger (Ty, Sig);
1028
1032
1033
+ bool IsTypeOriginallyDefinedIn =
1034
+ containsOriginallyDefinedIn (DbgTy.getType ());
1029
1035
// TODO(https://github.com/apple/swift/issues/57699): We currently cannot round trip some C++ types.
1036
+ // There's no way to round trip when respecting @_originallyDefinedIn for a type.
1030
1037
if (!Opts.DisableRoundTripDebugTypes &&
1031
- !Ty->getASTContext ().LangOpts .EnableCXXInterop ) {
1038
+ !Ty->getASTContext ().LangOpts .EnableCXXInterop && !IsTypeOriginallyDefinedIn ) {
1032
1039
// Make sure we can reconstruct mangled types for the debugger.
1033
1040
auto &Ctx = Ty->getASTContext ();
1034
1041
Type Reconstructed = Demangle::getTypeForMangling (Ctx, Result, Sig);
@@ -1507,7 +1514,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
1507
1514
// / anchor any typedefs that may appear in parameters so they can be
1508
1515
// / resolved in the debugger without needing to query the Swift module.
1509
1516
llvm::DINodeArray
1510
- collectGenericParams (NominalOrBoundGenericNominalType *BGT) {
1517
+ collectGenericParams (NominalOrBoundGenericNominalType *BGT, bool AsForwardDeclarations = false ) {
1511
1518
1512
1519
// Collect the generic args from the type and its parent.
1513
1520
std::vector<Type> GenericArgs;
@@ -1522,7 +1529,8 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
1522
1529
SmallVector<llvm::Metadata *, 16 > TemplateParams;
1523
1530
for (auto Arg : GenericArgs) {
1524
1531
DebugTypeInfo ParamDebugType;
1525
- if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
1532
+ if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes &&
1533
+ !AsForwardDeclarations)
1526
1534
// For the DwarfTypes level don't generate just a forward declaration
1527
1535
// for the generic type parameters.
1528
1536
ParamDebugType = DebugTypeInfo::getFromTypeInfo (
@@ -1790,39 +1798,19 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
1790
1798
}
1791
1799
1792
1800
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
- }
1813
1801
1814
1802
// Here goes!
1815
1803
switch (BaseTy->getKind ()) {
1816
1804
case TypeKind::BuiltinUnboundGeneric:
1817
1805
llvm_unreachable (" not a real type" );
1818
-
1806
+
1819
1807
case TypeKind::BuiltinFixedArray: {
1820
1808
// TODO: provide proper array debug info
1821
1809
unsigned FwdDeclLine = 0 ;
1822
1810
return createOpaqueStruct (Scope, " Builtin.FixedArray" , MainFile, FwdDeclLine,
1823
1811
SizeInBits, AlignInBits, Flags, MangledName);
1824
1812
}
1825
-
1813
+
1826
1814
case TypeKind::BuiltinPackIndex:
1827
1815
case TypeKind::BuiltinInteger: {
1828
1816
Encoding = llvm::dwarf::DW_ATE_unsigned;
@@ -1846,7 +1834,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
1846
1834
break ;
1847
1835
}
1848
1836
1849
- case TypeKind::BuiltinNativeObject:
1837
+ case TypeKind::BuiltinNativeObject:
1850
1838
case TypeKind::BuiltinBridgeObject:
1851
1839
case TypeKind::BuiltinRawPointer:
1852
1840
case TypeKind::BuiltinRawUnsafeContinuation:
@@ -1928,7 +1916,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
1928
1916
assert (SizeInBits ==
1929
1917
CI.getTargetInfo ().getPointerWidth (clang::LangAS::Default));
1930
1918
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes) {
1931
- if (ClassTy->isSpecialized ())
1919
+ if (ClassTy->isSpecialized ())
1932
1920
return createSpecializedStructOrClassType (
1933
1921
ClassTy, Decl, Scope, L.File , L.Line , SizeInBits, AlignInBits,
1934
1922
Flags, MangledName);
@@ -2011,7 +1999,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
2011
1999
auto L = getFileAndLocation (Decl);
2012
2000
unsigned FwdDeclLine = 0 ;
2013
2001
2014
- if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
2002
+ if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
2015
2003
return createSpecializedStructOrClassType (
2016
2004
ClassTy, Decl, Scope, L.File , L.Line , SizeInBits, AlignInBits,
2017
2005
Flags, MangledName);
@@ -2315,8 +2303,8 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
2315
2303
unsigned CachedSizeInBits = getSizeInBits (CachedType);
2316
2304
if ((SizeInBits && CachedSizeInBits != *SizeInBits) ||
2317
2305
(!SizeInBits && CachedSizeInBits)) {
2318
- // In some situation a specialized type is emitted with size 0, even if the real
2319
- // type has a size.
2306
+ // In some situation a specialized type is emitted with size 0, even if
2307
+ // the real type has a size.
2320
2308
if (DbgTy.getType ()->isSpecialized () && SizeInBits && *SizeInBits > 0 &&
2321
2309
CachedSizeInBits == 0 )
2322
2310
return true ;
@@ -2336,7 +2324,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
2336
2324
// / needed to correctly calculate the layout of more complex types built on
2337
2325
// / top of them.
2338
2326
void createSpecialStlibBuiltinTypes () {
2339
- if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::ASTTypes)
2327
+ if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::ASTTypes)
2340
2328
return ;
2341
2329
for (auto BuiltinType: IGM.getOrCreateSpecialStlibBuiltinTypes ()) {
2342
2330
auto DbgTy = DebugTypeInfo::getFromTypeInfo (
@@ -2345,6 +2333,86 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
2345
2333
}
2346
2334
}
2347
2335
2336
+ struct OriginallyDefinedInFinder : public TypeWalker {
2337
+ bool visitedOriginallyDefinedIn = false ;
2338
+
2339
+ TypeWalker::Action walkToTypePre (Type T) override {
2340
+ if (visitedOriginallyDefinedIn)
2341
+ return TypeWalker::Action::Stop;
2342
+
2343
+ auto *TypeDecl = T->getNominalOrBoundGenericNominal ();
2344
+ if (!TypeDecl)
2345
+ return TypeWalker::Action::Continue;
2346
+
2347
+ NominalTypeDecl *ParentDecl = TypeDecl;
2348
+ while (llvm::isa_and_nonnull<NominalTypeDecl>(ParentDecl->getParent ()))
2349
+ ParentDecl = llvm::cast<NominalTypeDecl>(ParentDecl->getParent ());
2350
+
2351
+ if (ParentDecl->getAttrs ().hasAttribute <OriginallyDefinedInAttr>()) {
2352
+ visitedOriginallyDefinedIn = true ;
2353
+ return TypeWalker::Action::Stop;
2354
+ }
2355
+
2356
+ return TypeWalker::Action::Continue;
2357
+ }
2358
+ };
2359
+
2360
+ // / Returns true if the type's mangled name is affected by an
2361
+ // / @_originallyDefinedIn annotation. This annotation can be on the type
2362
+ // / itself, one of its generic arguments, etc.
2363
+ bool containsOriginallyDefinedIn (Type T) {
2364
+ OriginallyDefinedInFinder Walker;
2365
+ T.walk (Walker);
2366
+ return Walker.visitedOriginallyDefinedIn ;
2367
+ }
2368
+
2369
+ // / Returns the decl of the type's parent chain annotated by
2370
+ // / @_originallyDefinedIn. Returns null if no type is annotated.
2371
+ NominalTypeDecl *getDeclAnnotatedByOriginallyDefinedIn (DebugTypeInfo DbgTy) {
2372
+ auto Type = DbgTy.getType ();
2373
+ auto *TypeDecl = Type->getNominalOrBoundGenericNominal ();
2374
+ if (!TypeDecl)
2375
+ return nullptr ;
2376
+
2377
+ // Find the outermost type, since only those can have @_originallyDefinedIn
2378
+ // attached to them.
2379
+ NominalTypeDecl *ParentDecl = TypeDecl;
2380
+ while (llvm::isa_and_nonnull<NominalTypeDecl>(ParentDecl->getParent ()))
2381
+ ParentDecl = llvm::cast<NominalTypeDecl>(ParentDecl->getParent ());
2382
+
2383
+ if (ParentDecl->getAttrs ().hasAttribute <OriginallyDefinedInAttr>())
2384
+ return ParentDecl;;
2385
+
2386
+ return nullptr ;
2387
+ }
2388
+
2389
+ // / If this is a nominal type that has the @_originallyDefinedIn
2390
+ // / attribute, IRGenDebugInfo emits an imported declaration of the type as
2391
+ // / a child of the real module. We do this so LLDB has enough
2392
+ // / information to both find the type in reflection metadata (the module name
2393
+ // / in the type's mangled name), and find it in the swiftmodule (the type's
2394
+ // / imported declaration's parent module name).
2395
+ void handleOriginallyDefinedIn (DebugTypeInfo DbgTy, llvm::DIType *DITy,
2396
+ StringRef MangledName, llvm::DIFile *File) {
2397
+ if (OriginallyDefinedInTypes.contains (MangledName))
2398
+ return ;
2399
+
2400
+ // Force the generation of the generic type parameters as forward
2401
+ // declarations, as those types might be annotated with
2402
+ // @_originallyDefinedIn.
2403
+ if (auto *BoundDecl = llvm::dyn_cast<BoundGenericType>(DbgTy.getType ()))
2404
+ collectGenericParams (BoundDecl, /* AsForwardDeclarations=*/ true );
2405
+
2406
+ NominalTypeDecl *OriginallyDefinedInDecl = getDeclAnnotatedByOriginallyDefinedIn (DbgTy);
2407
+ if (!OriginallyDefinedInDecl)
2408
+ return ;
2409
+
2410
+ // Emit the imported declaration under the real swiftmodule the type lives on.
2411
+ auto RealModule = getOrCreateContext (OriginallyDefinedInDecl->getParent ());
2412
+ DBuilder.createImportedDeclaration (RealModule, DITy, File, 0 , MangledName);
2413
+ OriginallyDefinedInTypes.insert (MangledName);
2414
+ }
2415
+
2348
2416
llvm::DIType *getOrCreateType (DebugTypeInfo DbgTy,
2349
2417
llvm::DIScope *Scope = nullptr ) {
2350
2418
// Is this an empty type?
@@ -2389,7 +2457,18 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
2389
2457
ClangDecl = AliasDecl->getClangDecl ();
2390
2458
} else if (auto *ND = DbgTy.getType ()->getNominalOrBoundGenericNominal ()) {
2391
2459
TypeDecl = ND;
2392
- Context = ND->getParent ();
2460
+ // If this is an originally defined in type, we want to emit this type's
2461
+ // scope to be the ABI module.
2462
+ if (auto Attribute =
2463
+ ND->getAttrs ().getAttribute <OriginallyDefinedInAttr>()) {
2464
+ auto Identifier = IGM.getSILModule ().getASTContext ().getIdentifier (
2465
+ Attribute->OriginalModuleName );
2466
+ void *Key = (void *)Identifier.get ();
2467
+ Scope =
2468
+ getOrCreateModule (Key, TheCU, Attribute->OriginalModuleName , {});
2469
+ } else {
2470
+ Context = ND->getParent ();
2471
+ }
2393
2472
ClangDecl = ND->getClangDecl ();
2394
2473
} else if (auto BNO = dyn_cast<BuiltinType>(DbgTy.getType ())) {
2395
2474
Context = BNO->getASTContext ().TheBuiltinModule ;
@@ -2438,6 +2517,8 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
2438
2517
FwdDeclTypes.emplace_back (
2439
2518
std::piecewise_construct, std::make_tuple (MangledName),
2440
2519
std::make_tuple (static_cast <llvm::Metadata *>(FwdDecl)));
2520
+
2521
+ handleOriginallyDefinedIn (DbgTy, FwdDecl, MangledName, getFile (Scope));
2441
2522
return FwdDecl;
2442
2523
}
2443
2524
llvm::DIType *DITy = createType (DbgTy, MangledName, Scope, getFile (Scope));
@@ -2466,6 +2547,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
2466
2547
// Store it in the cache.
2467
2548
DITypeCache.insert ({DbgTy.getType (), llvm::TrackingMDNodeRef (DITy)});
2468
2549
2550
+ handleOriginallyDefinedIn (DbgTy, DITy, MangledName, getFile (Scope));
2469
2551
return DITy;
2470
2552
}
2471
2553
};
0 commit comments