15
15
// ===----------------------------------------------------------------------===//
16
16
17
17
#include " IRGenDebugInfo.h"
18
+ #include " DebugTypeInfo.h"
18
19
#include " GenEnum.h"
19
20
#include " GenOpaque.h"
20
21
#include " GenStruct.h"
23
24
#include " IRBuilder.h"
24
25
#include " swift/AST/ASTDemangler.h"
25
26
#include " swift/AST/ASTMangler.h"
27
+ #include " swift/AST/Attr.h"
28
+ #include " swift/AST/Decl.h"
26
29
#include " swift/AST/Expr.h"
27
30
#include " swift/AST/GenericEnvironment.h"
28
31
#include " swift/AST/IRGenOptions.h"
29
32
#include " swift/AST/Module.h"
30
33
#include " swift/AST/ModuleLoader.h"
34
+ #include " swift/AST/ParameterList.h"
31
35
#include " swift/AST/Pattern.h"
32
36
#include " swift/AST/TypeDifferenceVisitor.h"
37
+ #include " swift/AST/Types.h"
33
38
#include " swift/Basic/Assertions.h"
34
39
#include " swift/Basic/Compiler.h"
35
40
#include " swift/Basic/SourceManager.h"
61
66
#include " llvm/IR/DebugInfo.h"
62
67
#include " llvm/IR/IntrinsicInst.h"
63
68
#include " llvm/IR/Module.h"
69
+ #include " llvm/Support/Casting.h"
64
70
#include " llvm/Support/CommandLine.h"
65
71
#include " llvm/Support/Debug.h"
66
72
#include " llvm/Support/FileSystem.h"
67
73
#include " llvm/Support/MemoryBuffer.h"
68
74
#include " llvm/Support/Path.h"
69
75
#include " llvm/Support/raw_ostream.h"
70
76
#include " llvm/Transforms/Utils/Local.h"
77
+ #include < cstddef>
71
78
72
79
#define DEBUG_TYPE " debug-info"
73
80
@@ -150,6 +157,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
150
157
llvm::DenseMap<const void *, llvm::TrackingMDNodeRef> DIModuleCache;
151
158
llvm::StringMap<llvm::TrackingMDNodeRef> DIFileCache;
152
159
llvm::StringMap<llvm::TrackingMDNodeRef> RuntimeErrorFnCache;
160
+ llvm::StringSet<> OriginallyDefinedInTypes;
153
161
TrackingDIRefMap DIRefMap;
154
162
TrackingDIRefMap InnerTypeCache;
155
163
// / \}
@@ -1026,9 +1034,12 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1026
1034
Mangle::ASTMangler Mangler;
1027
1035
std::string Result = Mangler.mangleTypeForDebugger (Ty, Sig);
1028
1036
1037
+ bool IsTypeOriginallyDefinedIn =
1038
+ containsOriginallyDefinedIn (DbgTy.getType ());
1029
1039
// TODO(https://github.com/apple/swift/issues/57699): We currently cannot round trip some C++ types.
1040
+ // There's no way to round trip when respecting @_originallyDefinedIn for a type.
1030
1041
if (!Opts.DisableRoundTripDebugTypes &&
1031
- !Ty->getASTContext ().LangOpts .EnableCXXInterop ) {
1042
+ !Ty->getASTContext ().LangOpts .EnableCXXInterop && !IsTypeOriginallyDefinedIn ) {
1032
1043
// Make sure we can reconstruct mangled types for the debugger.
1033
1044
auto &Ctx = Ty->getASTContext ();
1034
1045
Type Reconstructed = Demangle::getTypeForMangling (Ctx, Result, Sig);
@@ -1506,7 +1517,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
1506
1517
// / anchor any typedefs that may appear in parameters so they can be
1507
1518
// / resolved in the debugger without needing to query the Swift module.
1508
1519
llvm::DINodeArray
1509
- collectGenericParams (NominalOrBoundGenericNominalType *BGT) {
1520
+ collectGenericParams (NominalOrBoundGenericNominalType *BGT, bool AsForwardDeclarations = false ) {
1510
1521
1511
1522
// Collect the generic args from the type and its parent.
1512
1523
std::vector<Type> GenericArgs;
@@ -1521,7 +1532,8 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
1521
1532
SmallVector<llvm::Metadata *, 16 > TemplateParams;
1522
1533
for (auto Arg : GenericArgs) {
1523
1534
DebugTypeInfo ParamDebugType;
1524
- if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
1535
+ if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes &&
1536
+ !AsForwardDeclarations)
1525
1537
// For the DwarfTypes level don't generate just a forward declaration
1526
1538
// for the generic type parameters.
1527
1539
ParamDebugType = DebugTypeInfo::getFromTypeInfo (
@@ -1789,26 +1801,6 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
1789
1801
}
1790
1802
1791
1803
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
1804
1813
1805
// Here goes!
1814
1806
switch (BaseTy->getKind ()) {
@@ -2338,6 +2330,106 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
2338
2330
}
2339
2331
}
2340
2332
2333
+ // / Returns true if the type's mangled name is affected by an
2334
+ // / @_originallyDefinedIn annotation. This annotation can be on the type
2335
+ // / itself, one of its generic arguments, etc.
2336
+ bool containsOriginallyDefinedIn (Type T) {
2337
+ if (auto *MT = llvm::dyn_cast<MetatypeType>(T))
2338
+ if (containsOriginallyDefinedIn (MT->getInstanceType ()))
2339
+ return true ;
2340
+ ;
2341
+
2342
+ auto *TypeDecl = T->getNominalOrBoundGenericNominal ();
2343
+ if (!TypeDecl)
2344
+ return false ;
2345
+
2346
+ // Find the outermost type, since only those can be annotated with
2347
+ // @_originallyDefinedIn.
2348
+ NominalTypeDecl *ParentDecl = TypeDecl;
2349
+ while (llvm::isa_and_nonnull<NominalTypeDecl>(ParentDecl->getParent ()))
2350
+ ParentDecl = llvm::cast<NominalTypeDecl>(ParentDecl->getParent ());
2351
+
2352
+ if (ParentDecl->getAttrs ().hasAttribute <OriginallyDefinedInAttr>())
2353
+ return true ;
2354
+
2355
+ // If the type is a bound generic, the type of the substituted generic
2356
+ // arguments might be annotated with @_originallyDefinedIn.
2357
+ if (auto *BGT = llvm::dyn_cast<BoundGenericType>(T))
2358
+ for (auto &Arg : BGT->getGenericArgs ())
2359
+ if (containsOriginallyDefinedIn (Arg))
2360
+ return true ;
2361
+
2362
+ // A typealias inside a function mentions the function's signature, so check
2363
+ // if any types in the generic signature are annotated with
2364
+ // @_originallyDefinedIn.
2365
+ if (auto *TAT = llvm::dyn_cast<TypeAliasType>(T)) {
2366
+ auto D = TAT->getDecl ()->getDeclContext ();
2367
+ if (auto AFD = llvm::dyn_cast<AbstractFunctionDecl>(D)) {
2368
+ for (auto &Param : *AFD->getParameters ())
2369
+ if (containsOriginallyDefinedIn (Param->getInterfaceType ()))
2370
+ return true ;
2371
+
2372
+ for (auto &Req : AFD->getGenericSignature ().getRequirements ())
2373
+ if (containsOriginallyDefinedIn (Req.getFirstType ()) ||
2374
+ containsOriginallyDefinedIn (Req.getSecondType ()))
2375
+ return true ;
2376
+
2377
+ if (auto FD = llvm::dyn_cast<FuncDecl>(D))
2378
+ if (containsOriginallyDefinedIn (FD->getResultInterfaceType ()))
2379
+ return true ;
2380
+ }
2381
+ }
2382
+
2383
+ return false ;
2384
+ }
2385
+
2386
+ // / Returns the decl of the type's parent chain annotated by
2387
+ // / @_originallyDefinedIn. Returns null if no type is annotated.
2388
+ NominalTypeDecl *getDeclAnnotatedByOriginallyDefinedIn (DebugTypeInfo DbgTy) {
2389
+ auto Type = DbgTy.getType ();
2390
+ auto *TypeDecl = Type->getNominalOrBoundGenericNominal ();
2391
+ if (!TypeDecl)
2392
+ return nullptr ;
2393
+
2394
+ // Find the outermost type, since only those can have @_originallyDefinedIn
2395
+ // attached to them.
2396
+ NominalTypeDecl *ParentDecl = TypeDecl;
2397
+ while (llvm::isa_and_nonnull<NominalTypeDecl>(ParentDecl->getParent ()))
2398
+ ParentDecl = llvm::cast<NominalTypeDecl>(ParentDecl->getParent ());
2399
+
2400
+ if (ParentDecl->getAttrs ().hasAttribute <OriginallyDefinedInAttr>())
2401
+ return ParentDecl;;
2402
+
2403
+ return nullptr ;
2404
+ }
2405
+
2406
+ // / If this is a nominal type that has the @_originallyDefinedIn
2407
+ // / attribute, IRGenDebugInfo emits an imported declaration of the type as
2408
+ // / a child of the real module. We do this so LLDB has enough
2409
+ // / information to both find the type in reflection metadata (the module name
2410
+ // / in the type's mangled name), and find it in the swiftmodule (the type's
2411
+ // / imported declaration's parent module name).
2412
+ void handleOriginallyDefinedIn (DebugTypeInfo DbgTy, llvm::DIType *DITy,
2413
+ StringRef MangledName, llvm::DIFile *File) {
2414
+ if (OriginallyDefinedInTypes.contains (MangledName))
2415
+ return ;
2416
+
2417
+ // Force the generation of the generic type parameters as forward
2418
+ // declarations, as those types might be annotated with
2419
+ // @_originallyDefinedIn.
2420
+ if (auto *BoundDecl = llvm::dyn_cast<BoundGenericType>(DbgTy.getType ()))
2421
+ collectGenericParams (BoundDecl, /* AsForwardDeclarations=*/ true );
2422
+
2423
+ NominalTypeDecl *OriginallyDefinedInDecl = getDeclAnnotatedByOriginallyDefinedIn (DbgTy);
2424
+ if (!OriginallyDefinedInDecl)
2425
+ return ;
2426
+
2427
+ // Emit the imported declaration under the real swiftmodule the type lives on.
2428
+ auto RealModule = getOrCreateContext (OriginallyDefinedInDecl->getParent ());
2429
+ DBuilder.createImportedDeclaration (RealModule, DITy, File, 0 , MangledName);
2430
+ OriginallyDefinedInTypes.insert (MangledName);
2431
+ }
2432
+
2341
2433
llvm::DIType *getOrCreateType (DebugTypeInfo DbgTy,
2342
2434
llvm::DIScope *Scope = nullptr ) {
2343
2435
// Is this an empty type?
@@ -2382,7 +2474,18 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
2382
2474
ClangDecl = AliasDecl->getClangDecl ();
2383
2475
} else if (auto *ND = DbgTy.getType ()->getNominalOrBoundGenericNominal ()) {
2384
2476
TypeDecl = ND;
2385
- Context = ND->getParent ();
2477
+ // If this is an originally defined in type, we want to emit this type's scope
2478
+ // to be the ABI module.
2479
+ if (auto Attribute =
2480
+ ND->getAttrs ().getAttribute <OriginallyDefinedInAttr>()) {
2481
+ auto Identifier = IGM.getSILModule ().getASTContext ().getIdentifier (
2482
+ Attribute->OriginalModuleName );
2483
+ void *Key = (void *)Identifier.get ();
2484
+ Scope =
2485
+ getOrCreateModule (Key, TheCU, Attribute->OriginalModuleName , {});
2486
+ } else {
2487
+ Context = ND->getParent ();
2488
+ }
2386
2489
ClangDecl = ND->getClangDecl ();
2387
2490
} else if (auto BNO = dyn_cast<BuiltinType>(DbgTy.getType ())) {
2388
2491
Context = BNO->getASTContext ().TheBuiltinModule ;
@@ -2431,6 +2534,8 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
2431
2534
FwdDeclTypes.emplace_back (
2432
2535
std::piecewise_construct, std::make_tuple (MangledName),
2433
2536
std::make_tuple (static_cast <llvm::Metadata *>(FwdDecl)));
2537
+
2538
+ handleOriginallyDefinedIn (DbgTy, FwdDecl, MangledName, getFile (Scope));
2434
2539
return FwdDecl;
2435
2540
}
2436
2541
llvm::DIType *DITy = createType (DbgTy, MangledName, Scope, getFile (Scope));
@@ -2459,6 +2564,7 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
2459
2564
// Store it in the cache.
2460
2565
DITypeCache.insert ({DbgTy.getType (), llvm::TrackingMDNodeRef (DITy)});
2461
2566
2567
+ handleOriginallyDefinedIn (DbgTy, DITy, MangledName, getFile (Scope));
2462
2568
return DITy;
2463
2569
}
2464
2570
};
0 commit comments