@@ -72,6 +72,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
72
72
const IRGenOptions &Opts;
73
73
ClangImporter &CI;
74
74
SourceManager &SM;
75
+ llvm::Module &M;
75
76
llvm::DIBuilder DBuilder;
76
77
IRGenModule &IGM;
77
78
const PathRemapper &DebugPrefixMap;
@@ -559,36 +560,55 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
559
560
560
561
llvm::DIModule *getOrCreateModule (const void *Key, llvm::DIScope *Parent,
561
562
StringRef Name, StringRef IncludePath,
562
- StringRef ConfigMacros = StringRef()) {
563
+ uint64_t Signature = ~1ULL ,
564
+ StringRef ASTFile = StringRef()) {
563
565
// Look in the cache first.
564
566
auto Val = DIModuleCache.find (Key);
565
567
if (Val != DIModuleCache.end ())
566
568
return cast<llvm::DIModule>(Val->second );
567
569
570
+ // For Clang modules / PCH, create a Skeleton CU pointing to the PCM/PCH.
571
+ bool CreateSkeletonCU = !ASTFile.empty ();
572
+ bool IsRootModule = !Parent;
573
+ if (CreateSkeletonCU && IsRootModule) {
574
+ llvm::DIBuilder DIB (M);
575
+ DIB.createCompileUnit (IGM.ObjCInterop ? llvm::dwarf::DW_LANG_ObjC
576
+ : llvm::dwarf::DW_LANG_C99,
577
+ DIB.createFile (Name, IncludePath),
578
+ TheCU->getProducer (), true , StringRef (), 0 , ASTFile,
579
+ llvm::DICompileUnit::FullDebug, Signature);
580
+ DIB.finalize ();
581
+ }
582
+
568
583
StringRef Sysroot = IGM.Context .SearchPathOpts .SDKPath ;
569
- auto M = DBuilder.createModule (
570
- Parent, Name, ConfigMacros, DebugPrefixMap.remapPath (IncludePath),
571
- Sysroot);
584
+ auto M =
585
+ DBuilder.createModule (Parent, Name, ConfigMacros, IncludePath, Sysroot);
572
586
DIModuleCache.insert ({Key, llvm::TrackingMDNodeRef (M)});
573
587
return M;
574
588
}
575
589
576
590
llvm::DIModule *
577
591
getOrCreateModule (clang::ExternalASTSource::ASTSourceDescriptor Desc) {
592
+ // PCH files don't have a signature field in the control block,
593
+ // but LLVM detects skeleton CUs by looking for a non-zero DWO id.
594
+ // We use the lower 64 bits for debug info.
595
+ uint64_t Signature =
596
+ Desc.getSignature ()
597
+ ? (uint64_t )Desc.getSignature ()[1 ] << 32 | Desc.getSignature ()[0 ]
598
+ : ~1ULL ;
599
+
578
600
// Handle Clang modules.
579
601
if (const clang::Module *ClangModule = Desc.getModuleOrNull ()) {
580
602
llvm::DIModule *Parent = nullptr ;
581
603
if (ClangModule->Parent )
582
604
Parent = getOrCreateModule (*ClangModule->Parent );
583
-
584
- return getOrCreateModule (ClangModule, Parent,
585
- Desc.getModuleName (), Desc.getPath (),
586
- ConfigMacros);
605
+ return getOrCreateModule (ClangModule, Parent, Desc.getModuleName (),
606
+ Desc.getPath (), Signature, Desc.getASTFile ());
587
607
}
588
608
// Handle PCH.
589
609
return getOrCreateModule (Desc.getASTFile ().bytes_begin (), nullptr ,
590
- Desc.getModuleName (), Desc.getPath (),
591
- ConfigMacros );
610
+ Desc.getModuleName (), Desc.getPath (), Signature,
611
+ Desc. getASTFile () );
592
612
};
593
613
594
614
llvm::DIModule *getOrCreateModule (ModuleDecl::ImportedModule IM) {
@@ -1480,7 +1500,7 @@ IRGenDebugInfoImpl::IRGenDebugInfoImpl(const IRGenOptions &Opts,
1480
1500
ClangImporter &CI, IRGenModule &IGM,
1481
1501
llvm::Module &M,
1482
1502
StringRef MainOutputFilenameForDebugInfo)
1483
- : Opts(Opts), CI(CI), SM(IGM.Context.SourceMgr), DBuilder(M),
1503
+ : Opts(Opts), CI(CI), SM(IGM.Context.SourceMgr), M(M), DBuilder(M),
1484
1504
IGM (IGM), DebugPrefixMap(Opts.DebugPrefixMap), MetadataTypeDecl(nullptr ),
1485
1505
InternalType(nullptr ), LastDebugLoc({}), LastScope(nullptr ) {
1486
1506
assert (Opts.DebugInfoLevel > IRGenDebugInfoLevel::None &&
0 commit comments