28
28
#include " swift/Basic/SourceManager.h"
29
29
#include " swift/Basic/Version.h"
30
30
#include " swift/ClangImporter/ClangImporter.h"
31
+ #include " swift/ClangImporter/ClangModule.h"
31
32
#include " swift/Demangling/ManglingMacros.h"
33
+ #include " swift/Serialization/SerializedModuleLoader.h"
32
34
#include " swift/SIL/SILArgument.h"
33
35
#include " swift/SIL/SILBasicBlock.h"
34
36
#include " swift/SIL/SILDebugScope.h"
@@ -582,14 +584,18 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
582
584
}
583
585
584
586
StringRef Sysroot = IGM.Context .SearchPathOpts .SDKPath ;
585
- auto M =
587
+ llvm::DIModule * M =
586
588
DBuilder.createModule (Parent, Name, ConfigMacros, IncludePath, Sysroot);
587
589
DIModuleCache.insert ({Key, llvm::TrackingMDNodeRef (M)});
588
590
return M;
589
591
}
590
592
591
- llvm::DIModule *
592
- getOrCreateModule (clang::ExternalASTSource::ASTSourceDescriptor Desc) {
593
+ using ASTSourceDescriptor = clang::ExternalASTSource::ASTSourceDescriptor;
594
+ // / Create a DIModule from a clang module or PCH.
595
+ // / The clang::Module pointer is passed separately because the recursive case
596
+ // / needs to fudge the AST descriptor.
597
+ llvm::DIModule *getOrCreateModule (ASTSourceDescriptor Desc,
598
+ const clang::Module *ClangModule) {
593
599
// PCH files don't have a signature field in the control block,
594
600
// but LLVM detects skeleton CUs by looking for a non-zero DWO id.
595
601
// We use the lower 64 bits for debug info.
@@ -599,10 +605,24 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
599
605
: ~1ULL ;
600
606
601
607
// Handle Clang modules.
602
- if (const clang::Module * ClangModule = Desc. getModuleOrNull () ) {
608
+ if (ClangModule) {
603
609
llvm::DIModule *Parent = nullptr ;
604
- if (ClangModule->Parent )
605
- Parent = getOrCreateModule (*ClangModule->Parent );
610
+ if (ClangModule->Parent ) {
611
+ // The loading of additional modules by Sema may trigger an out-of-date
612
+ // PCM rebuild in the Clang module dependencies of the additional
613
+ // module. A PCM rebuild causes the ModuleManager to unload previously
614
+ // loaded ASTFiles. For this reason we must use the cached ASTFile
615
+ // information here instead of the potentially dangling pointer to the
616
+ // ASTFile that is stored in the clang::Module object.
617
+ //
618
+ // Note: The implementation here assumes that all clang submodules
619
+ // belong to the same PCM file.
620
+ ASTSourceDescriptor ParentDescriptor (*ClangModule->Parent );
621
+ Parent = getOrCreateModule ({ParentDescriptor.getModuleName (),
622
+ ParentDescriptor.getPath (),
623
+ Desc.getASTFile (), Desc.getSignature ()},
624
+ ClangModule->Parent );
625
+ }
606
626
return getOrCreateModule (ClangModule, Parent, Desc.getModuleName (),
607
627
Desc.getPath (), Signature, Desc.getASTFile ());
608
628
}
@@ -612,10 +632,18 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
612
632
Desc.getASTFile ());
613
633
};
614
634
635
+ static Optional<ASTSourceDescriptor> getClangModule (const ModuleDecl &M) {
636
+ for (auto *FU : M.getFiles ())
637
+ if (auto *CMU = dyn_cast_or_null<ClangModuleUnit>(FU))
638
+ if (auto Desc = CMU->getASTSourceDescriptor ())
639
+ return Desc;
640
+ return None;
641
+ }
642
+
615
643
llvm::DIModule *getOrCreateModule (ModuleDecl::ImportedModule IM) {
616
644
ModuleDecl *M = IM.second ;
617
- if (auto *ClangModule = M-> findUnderlyingClangModule ( ))
618
- return getOrCreateModule (*ClangModule );
645
+ if (Optional<ASTSourceDescriptor> ModuleDesc = getClangModule (*M ))
646
+ return getOrCreateModule (*ModuleDesc, ModuleDesc-> getModuleOrNull () );
619
647
620
648
StringRef Path = getFilenameFromDC (M);
621
649
StringRef Name = M->getName ().str ();
@@ -1457,8 +1485,18 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1457
1485
if (auto *ClangDecl = D->getClangDecl ()) {
1458
1486
clang::ASTReader &Reader = *CI.getClangInstance ().getModuleManager ();
1459
1487
auto Idx = ClangDecl->getOwningModuleID ();
1460
- if (auto Info = Reader.getSourceDescriptor (Idx))
1461
- Scope = getOrCreateModule (*Info);
1488
+ auto SubModuleDesc = Reader.getSourceDescriptor (Idx);
1489
+ auto TopLevelModuleDesc = getClangModule (*D->getModuleContext ());
1490
+ if (SubModuleDesc && TopLevelModuleDesc) {
1491
+ // Describe the submodule, but substitute the cached ASTFile from
1492
+ // the toplevel module. The ASTFile pointer in SubModule may be
1493
+ // dangling and cant be trusted.
1494
+ Scope = getOrCreateModule ({SubModuleDesc->getModuleName (),
1495
+ SubModuleDesc->getPath (),
1496
+ TopLevelModuleDesc->getASTFile (),
1497
+ TopLevelModuleDesc->getSignature ()},
1498
+ SubModuleDesc->getModuleOrNull ());
1499
+ }
1462
1500
}
1463
1501
Context = Context->getParent ();
1464
1502
}
0 commit comments