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