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;
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);
@@ -1506,7 +1514,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
1506
1514
// / anchor any typedefs that may appear in parameters so they can be
1507
1515
// / resolved in the debugger without needing to query the Swift module.
1508
1516
llvm::DINodeArray
1509
- collectGenericParams (NominalOrBoundGenericNominalType *BGT) {
1517
+ collectGenericParams (NominalOrBoundGenericNominalType *BGT, bool AsForwardDeclarations = false ) {
1510
1518
1511
1519
// Collect the generic args from the type and its parent.
1512
1520
std::vector<Type> GenericArgs;
@@ -1521,7 +1529,8 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
1521
1529
SmallVector<llvm::Metadata *, 16 > TemplateParams;
1522
1530
for (auto Arg : GenericArgs) {
1523
1531
DebugTypeInfo ParamDebugType;
1524
- if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
1532
+ if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes &&
1533
+ !AsForwardDeclarations)
1525
1534
// For the DwarfTypes level don't generate just a forward declaration
1526
1535
// for the generic type parameters.
1527
1536
ParamDebugType = DebugTypeInfo::getFromTypeInfo (
@@ -1789,39 +1798,19 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
1789
1798
}
1790
1799
1791
1800
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
- }
1812
1801
1813
1802
// Here goes!
1814
1803
switch (BaseTy->getKind ()) {
1815
1804
case TypeKind::BuiltinUnboundGeneric:
1816
1805
llvm_unreachable (" not a real type" );
1817
-
1806
+
1818
1807
case TypeKind::BuiltinFixedArray: {
1819
1808
// TODO: provide proper array debug info
1820
1809
unsigned FwdDeclLine = 0 ;
1821
1810
return createOpaqueStruct (Scope, " Builtin.FixedArray" , MainFile, FwdDeclLine,
1822
1811
SizeInBits, AlignInBits, Flags, MangledName);
1823
1812
}
1824
-
1813
+
1825
1814
case TypeKind::BuiltinPackIndex:
1826
1815
case TypeKind::BuiltinInteger: {
1827
1816
Encoding = llvm::dwarf::DW_ATE_unsigned;
@@ -1845,7 +1834,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
1845
1834
break ;
1846
1835
}
1847
1836
1848
- case TypeKind::BuiltinNativeObject:
1837
+ case TypeKind::BuiltinNativeObject:
1849
1838
case TypeKind::BuiltinBridgeObject:
1850
1839
case TypeKind::BuiltinRawPointer:
1851
1840
case TypeKind::BuiltinRawUnsafeContinuation:
@@ -1927,7 +1916,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
1927
1916
assert (SizeInBits ==
1928
1917
CI.getTargetInfo ().getPointerWidth (clang::LangAS::Default));
1929
1918
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes) {
1930
- if (ClassTy->isSpecialized ())
1919
+ if (ClassTy->isSpecialized ())
1931
1920
return createSpecializedStructOrClassType (
1932
1921
ClassTy, Decl, Scope, L.File , L.Line , SizeInBits, AlignInBits,
1933
1922
Flags, MangledName);
@@ -2010,7 +1999,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
2010
1999
auto L = getFileAndLocation (Decl);
2011
2000
unsigned FwdDeclLine = 0 ;
2012
2001
2013
- if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
2002
+ if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
2014
2003
return createSpecializedStructOrClassType (
2015
2004
ClassTy, Decl, Scope, L.File , L.Line , SizeInBits, AlignInBits,
2016
2005
Flags, MangledName);
@@ -2308,8 +2297,8 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
2308
2297
unsigned CachedSizeInBits = getSizeInBits (CachedType);
2309
2298
if ((SizeInBits && CachedSizeInBits != *SizeInBits) ||
2310
2299
(!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.
2313
2302
if (DbgTy.getType ()->isSpecialized () && SizeInBits && *SizeInBits > 0 &&
2314
2303
CachedSizeInBits == 0 )
2315
2304
return true ;
@@ -2329,7 +2318,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
2329
2318
// / needed to correctly calculate the layout of more complex types built on
2330
2319
// / top of them.
2331
2320
void createSpecialStlibBuiltinTypes () {
2332
- if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::ASTTypes)
2321
+ if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::ASTTypes)
2333
2322
return ;
2334
2323
for (auto BuiltinType: IGM.getOrCreateSpecialStlibBuiltinTypes ()) {
2335
2324
auto DbgTy = DebugTypeInfo::getFromTypeInfo (
@@ -2338,6 +2327,103 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
2338
2327
}
2339
2328
}
2340
2329
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
+
2341
2427
llvm::DIType *getOrCreateType (DebugTypeInfo DbgTy,
2342
2428
llvm::DIScope *Scope = nullptr ) {
2343
2429
// Is this an empty type?
@@ -2382,7 +2468,18 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
2382
2468
ClangDecl = AliasDecl->getClangDecl ();
2383
2469
} else if (auto *ND = DbgTy.getType ()->getNominalOrBoundGenericNominal ()) {
2384
2470
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
+ }
2386
2483
ClangDecl = ND->getClangDecl ();
2387
2484
} else if (auto BNO = dyn_cast<BuiltinType>(DbgTy.getType ())) {
2388
2485
Context = BNO->getASTContext ().TheBuiltinModule ;
@@ -2431,6 +2528,8 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
2431
2528
FwdDeclTypes.emplace_back (
2432
2529
std::piecewise_construct, std::make_tuple (MangledName),
2433
2530
std::make_tuple (static_cast <llvm::Metadata *>(FwdDecl)));
2531
+
2532
+ handleOriginallyDefinedIn (DbgTy, FwdDecl, MangledName, getFile (Scope));
2434
2533
return FwdDecl;
2435
2534
}
2436
2535
llvm::DIType *DITy = createType (DbgTy, MangledName, Scope, getFile (Scope));
@@ -2459,6 +2558,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
2459
2558
// Store it in the cache.
2460
2559
DITypeCache.insert ({DbgTy.getType (), llvm::TrackingMDNodeRef (DITy)});
2461
2560
2561
+ handleOriginallyDefinedIn (DbgTy, DITy, MangledName, getFile (Scope));
2462
2562
return DITy;
2463
2563
}
2464
2564
};
0 commit comments