Skip to content

Commit c2b14dc

Browse files
committed
Debug info: Represent clang-imported submodules.
Previously an import of a submodule would emit debug info for importing the root module. <rdar://problem/17260802>
1 parent 9545af6 commit c2b14dc

File tree

7 files changed

+63
-38
lines changed

7 files changed

+63
-38
lines changed

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,14 @@
3434
#include "swift/SIL/SILDebugScope.h"
3535
#include "swift/SIL/SILModule.h"
3636
#include "clang/AST/ASTContext.h"
37+
#include "clang/AST/ExternalASTSource.h"
3738
#include "clang/AST/Decl.h"
3839
#include "clang/Basic/Module.h"
3940
#include "clang/Basic/SourceLocation.h"
4041
#include "clang/Basic/SourceManager.h"
4142
#include "clang/Basic/TargetInfo.h"
43+
#include "clang/Frontend/CompilerInstance.h"
44+
#include "clang/Serialization/ASTReader.h"
4245
#include "llvm/Config/config.h"
4346
#include "llvm/IR/DebugInfo.h"
4447
#include "llvm/IR/Module.h"
@@ -190,7 +193,7 @@ SILLocation::DebugLoc getDeserializedLoc(Decl *D) {
190193
/// Use the SM to figure out the actual line/column of a SourceLoc.
191194
template <typename WithLoc>
192195
SILLocation::DebugLoc getDebugLoc(IRGenDebugInfo &DI, WithLoc *S,
193-
bool End = false) {
196+
bool End = false) {
194197
SILLocation::DebugLoc L;
195198
if (S == nullptr)
196199
return L;
@@ -814,6 +817,23 @@ llvm::DIModule *IRGenDebugInfo::getOrCreateModule(StringRef Key,
814817
return M;
815818
}
816819

820+
llvm::DIModule *IRGenDebugInfo::getOrCreateModule(
821+
clang::ExternalASTSource::ASTSourceDescriptor Desc) {
822+
// Handle Clang modules.
823+
if (const clang::Module *ClangModule = Desc.getModuleOrNull()) {
824+
llvm::DIModule *Parent = nullptr;
825+
if (ClangModule->Parent) {
826+
clang::ExternalASTSource::ASTSourceDescriptor PM(*ClangModule->Parent);
827+
Parent = getOrCreateModule(PM);
828+
}
829+
return getOrCreateModule(ClangModule->getFullModuleName(), Parent,
830+
Desc.getModuleName(), Desc.getPath());
831+
}
832+
// Handle PCH.
833+
return getOrCreateModule(Desc.getASTFile(), nullptr, Desc.getModuleName(),
834+
Desc.getPath());
835+
};
836+
817837
llvm::DISubprogram *IRGenDebugInfo::emitFunction(SILFunction &SILFn,
818838
llvm::Function *Fn) {
819839
auto *DS = SILFn.getDebugScope();
@@ -1491,6 +1511,13 @@ llvm::DIType *IRGenDebugInfo::createType(DebugTypeInfo DbgTy,
14911511
auto *StructTy = BaseTy->castTo<StructType>();
14921512
auto *Decl = StructTy->getDecl();
14931513
auto L = getDebugLoc(*this, Decl);
1514+
if (auto *ClangDecl = Decl->getClangDecl()) {
1515+
auto ClangSrcLoc = ClangDecl->getLocStart();
1516+
clang::SourceManager &ClangSM =
1517+
CI.getClangASTContext().getSourceManager();
1518+
L.Line = ClangSM.getPresumedLineNumber(ClangSrcLoc);
1519+
L.Filename = ClangSM.getBufferName(ClangSrcLoc);
1520+
}
14941521
auto *File = getOrCreateFile(L.Filename);
14951522
if (Opts.DebugInfoKind > IRGenDebugInfoKind::ASTTypes)
14961523
return createStructType(DbgTy, Decl, StructTy, Scope, File, L.Line,
@@ -1515,28 +1542,6 @@ llvm::DIType *IRGenDebugInfo::createType(DebugTypeInfo DbgTy,
15151542
CI.getClangASTContext().getSourceManager();
15161543
L.Line = ClangSM.getPresumedLineNumber(ClangSrcLoc);
15171544
L.Filename = ClangSM.getBufferName(ClangSrcLoc);
1518-
1519-
// Use "__ObjC" as default for implicit decls.
1520-
// FIXME: Do something more clever based on the decl's mangled name.
1521-
std::string FullModuleNameBuffer;
1522-
StringRef ModulePath;
1523-
StringRef ModuleName = "__ObjC";
1524-
if (auto *OwningModule = ClangDecl->getImportedOwningModule())
1525-
ModuleName = OwningModule->getTopLevelModuleName();
1526-
1527-
if (auto *SwiftModule = Decl->getParentModule())
1528-
if (auto *ClangModule = SwiftModule->findUnderlyingClangModule()) {
1529-
// FIXME: Clang submodules are not handled here.
1530-
// FIXME: Clang module config macros are not handled here.
1531-
FullModuleNameBuffer = ClangModule->getFullModuleName();
1532-
ModuleName = FullModuleNameBuffer;
1533-
// FIXME: A clang module's Directory is supposed to be the
1534-
// directory containing the module map, but ClangImporter
1535-
// sets it to the module cache directory.
1536-
if (ClangModule->Directory)
1537-
ModulePath = ClangModule->Directory->getName();
1538-
}
1539-
Scope = getOrCreateModule(ModuleName, TheCU, ModuleName, ModulePath);
15401545
}
15411546
assert(SizeInBits == CI.getTargetInfo().getPointerWidth(0));
15421547
return createPointerSizedStruct(Scope, Decl->getNameStr(),
@@ -1856,10 +1861,20 @@ llvm::DIType *IRGenDebugInfo::getOrCreateType(DebugTypeInfo DbgTy) {
18561861
//
18571862
// FIXME: Builtin and qualified types in LLVM have no parent
18581863
// scope. TODO: This can be fixed by extending DIBuilder.
1864+
llvm::DIScope *Scope = nullptr;
18591865
DeclContext *Context = DbgTy.getType()->getNominalOrBoundGenericNominal();
1860-
if (Context)
1866+
if (Context) {
1867+
if (auto *D = Context->getAsNominalTypeOrNominalTypeExtensionContext())
1868+
if (auto *ClangDecl = D->getClangDecl()) {
1869+
clang::ASTReader &Reader = *CI.getClangInstance().getModuleManager();
1870+
auto Idx = ClangDecl->getOwningModuleID();
1871+
if (auto Info = Reader.getSourceDescriptor(Idx))
1872+
Scope = getOrCreateModule(*Info);
1873+
}
18611874
Context = Context->getParent();
1862-
llvm::DIScope *Scope = getOrCreateContext(Context);
1875+
}
1876+
if (!Scope)
1877+
Scope = getOrCreateContext(Context);
18631878
llvm::DIType *DITy = createType(DbgTy, MangledName, Scope, getFile(Scope));
18641879

18651880
// Incrementally build the DIRefMap.

lib/IRGen/IRGenDebugInfo.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "IRBuilder.h"
2222
#include "IRGenFunction.h"
2323
#include "IRGenModule.h"
24+
#include "clang/AST/ExternalASTSource.h"
2425
#include "swift/SIL/SILLocation.h"
2526
#include "llvm/IR/DIBuilder.h"
2627
#include "llvm/Support/Allocator.h"
@@ -296,6 +297,9 @@ class IRGenDebugInfo {
296297
/// Return a cached module for an access path or create a new one.
297298
llvm::DIModule *getOrCreateModule(StringRef Key, llvm::DIScope *Parent,
298299
StringRef Name, StringRef IncludePath);
300+
llvm::DIModule *
301+
getOrCreateModule(clang::ExternalASTSource::ASTSourceDescriptor M);
302+
299303
llvm::DIScope *getModule(StringRef MangledName);
300304
/// Return an array with the DITypes for each of a struct's elements.
301305
llvm::DINodeArray getStructMembers(NominalTypeDecl *D, Type BaseTy,

lib/IRGen/IRGenModule.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,8 @@ static clang::CodeGenerator *createClangCodeGenerator(ASTContext &Context,
9797
CGO.setDebugInfo(clang::codegenoptions::DebugInfoKind::DebugLineTablesOnly);
9898
break;
9999
case IRGenDebugInfoKind::ASTTypes:
100-
// TODO: Enable -gmodules for the clang code generator.
101100
case IRGenDebugInfoKind::DwarfTypes:
101+
CGO.DebugTypeExtRefs = true;
102102
CGO.setDebugInfo(clang::codegenoptions::DebugInfoKind::FullDebugInfo);
103103
break;
104104
}
Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
// RUN: rm -rf %t && mkdir -p %t
2-
// REQUIRES: OS=macosx
1+
// RUN: %target-swift-frontend -emit-ir %s -g -I %S/Inputs -o - | %FileCheck %s
32

4-
// RUN: %target-swift-frontend -emit-ir %s -g -o - | %FileCheck %s
3+
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Bar",
4+
// CHECK-SAME: scope: ![[SUBMODULE:[0-9]+]]
55

6-
// CHECK: !DIImportedEntity(
7-
// CHECK: tag: DW_TAG_imported_module{{.*}}entity: ![[C:.*]], line: [[@LINE+1]])
8-
import Darwin.C
6+
// CHECK: ![[SUBMODULE]] = !DIModule(scope: ![[CLANGMODULE:[0-9]+]],
7+
// CHECK-SAME: name: "SubModule",
8+
// CHECK: ![[CLANGMODULE]] = !DIModule(scope: null, name: "ClangModule",
9+
// CHECK: !DIImportedEntity({{.*}}, entity: ![[SUBMODULE]], line: [[@LINE+1]])
10+
import ClangModule.SubModule
911

10-
let irrational = sqrt(2 as Double)
11-
12-
// CHECK: ![[C]] = !DIModule(scope: ![[Darwin:.*]], name: "C",
13-
// CHECK: ![[Darwin]] = !DIModule(scope: null, name: "Darwin",
12+
let bar = Bar()

test/DebugInfo/Inputs/SubModule.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
struct Bar {};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
module ClangModule {
22
header "ClangModule.h"
3+
export *
4+
module SubModule {
5+
header "SubModule.h"
6+
export *
7+
}
38
}

test/DebugInfo/test-foundation.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ class MyObject : NSObject {
1818
var MyArr = NSArray()
1919
// IMPORT-CHECK: filename: "test-foundation.swift"
2020
// IMPORT-CHECK-DAG: [[FOUNDATION:[0-9]+]] = !DIModule({{.*}} name: "Foundation",{{.*}} includePath:
21-
// IMPORT-CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "NSArray", scope: ![[FOUNDATION]]
22-
// IMPORT-CHECK-DAG: !DIImportedEntity(tag: DW_TAG_imported_module, {{.*}}entity: ![[FOUNDATION]]
21+
// IMPORT-CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "NSArray", scope: ![[NSARRAY:[0-9]+]]
22+
// IMPORT-CHECK-DAG: ![[NSARRAY]] = !DIModule(scope: ![[FOUNDATION:[0-9]+]], name: "NSArray"
23+
// IMPORT-CHECK-DAG: !DIImportedEntity(tag: DW_TAG_imported_module, {{.*}}entity: ![[FOUNDATION]]
2324

2425
func foo(_ obj: MyObject) {
2526
return obj.foo(obj)

0 commit comments

Comments
 (0)