Skip to content

Commit 1fb77e6

Browse files
authored
Merge pull request #198 from CodaFi/file-format
Add accessors for DIFile
2 parents baaa266 + f9d78d7 commit 1fb77e6

File tree

4 files changed

+84
-1
lines changed

4 files changed

+84
-1
lines changed

Sources/LLVM/IRMetadata.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#if SWIFT_PACKAGE
22
import cllvm
3+
import llvmshims
34
#endif
45

56
/// An unfortunate artifact of the design of the metadata class hierarchy is
@@ -79,6 +80,13 @@ extension IRMetadata {
7980
/// Denotes a scope in which child metadata nodes can be inserted.
8081
public protocol DIScope: IRMetadata {}
8182

83+
extension DIScope {
84+
/// Retrieves the file metadata associated with this scope, if any.
85+
public var file: FileMetadata? {
86+
return LLVMDIScopeGetFile(self.asMetadata()).map(FileMetadata.init(llvm:))
87+
}
88+
}
89+
8290
/// Denotes metadata for a type.
8391
public protocol DIType: DIScope {}
8492

@@ -206,6 +214,27 @@ public struct FileMetadata: DIScope {
206214
public init(llvm: LLVMMetadataRef) {
207215
self.llvm = llvm
208216
}
217+
218+
/// Retrieves the name of this file
219+
public var name: String {
220+
var length: UInt32 = 0
221+
let cstring = LLVMDIFileGetFilename(self.asMetadata(), &length)
222+
return String(cString: cstring!)
223+
}
224+
225+
/// Retrieves the directory of this file
226+
public var directory: String {
227+
var length: UInt32 = 0
228+
let cstring = LLVMDIFileGetDirectory(self.asMetadata(), &length)
229+
return String(cString: cstring!)
230+
}
231+
232+
/// Retrieves the source text of this file.
233+
public var source: String {
234+
var length: UInt32 = 0
235+
let cstring = LLVMDIFileGetSource(self.asMetadata(), &length)
236+
return String(cString: cstring!)
237+
}
209238
}
210239

211240
/// `DIBasicType` nodes represent primitive types, such as `int`, `bool` and

Sources/llvmshims/include/shim.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,9 @@ void LLVMInstructionSetDebugLoc(LLVMValueRef Inst, LLVMMetadataRef Loc);
7777
LLVMMetadataRef LLVMGetCurrentDebugLocation2(LLVMBuilderRef Builder);
7878
void LLVMSetCurrentDebugLocation2(LLVMBuilderRef Builder, LLVMMetadataRef Loc);
7979

80+
LLVMMetadataRef LLVMDIScopeGetFile(LLVMMetadataRef Scope);
81+
const char *LLVMDIFileGetDirectory(LLVMMetadataRef File, unsigned *Len);
82+
const char *LLVMDIFileGetFilename(LLVMMetadataRef File, unsigned *Len);
83+
const char *LLVMDIFileGetSource(LLVMMetadataRef File, unsigned *Len);
84+
8085
#endif /* LLVMSWIFT_LLVM_SHIM_H */

Sources/llvmshims/src/shim.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#include "llvm-c/Object.h"
2+
#include "llvm/IR/DebugInfo.h"
3+
#include "llvm/IR/DIBuilder.h"
24
#include "llvm/IR/Intrinsics.h"
35
#include "llvm/IR/Function.h"
46
#include "llvm/IR/IRBuilder.h"
@@ -94,6 +96,12 @@ extern "C" {
9496
// https://reviews.llvm.org/D60484
9597
LLVMMetadataRef LLVMGetCurrentDebugLocation2(LLVMBuilderRef Builder);
9698
void LLVMSetCurrentDebugLocation2(LLVMBuilderRef Builder, LLVMMetadataRef Loc);
99+
100+
// https://reviews.llvm.org/D60489
101+
LLVMMetadataRef LLVMDIScopeGetFile(LLVMMetadataRef Scope);
102+
const char *LLVMDIFileGetDirectory(LLVMMetadataRef File, unsigned *Len);
103+
const char *LLVMDIFileGetFilename(LLVMMetadataRef File, unsigned *Len);
104+
const char *LLVMDIFileGetSource(LLVMMetadataRef File, unsigned *Len);
97105
}
98106

99107
using namespace llvm;
@@ -277,3 +285,28 @@ void LLVMSetCurrentDebugLocation2(LLVMBuilderRef Builder, LLVMMetadataRef Loc) {
277285
else
278286
unwrap(Builder)->SetCurrentDebugLocation(DebugLoc());
279287
}
288+
289+
const char *LLVMDIFileGetDirectory(LLVMMetadataRef File, unsigned *Len) {
290+
auto Dir = unwrap<DIFile>(File)->getDirectory();
291+
*Len = Dir.size();
292+
return Dir.data();
293+
}
294+
295+
const char *LLVMDIFileGetFilename(LLVMMetadataRef File, unsigned *Len) {
296+
auto Dir = unwrap<DIFile>(File)->getFilename();
297+
*Len = Dir.size();
298+
return Dir.data();
299+
}
300+
301+
const char *LLVMDIFileGetSource(LLVMMetadataRef File, unsigned *Len) {
302+
if (auto Dir = unwrap<DIFile>(File)->getSource()) {
303+
*Len = Dir->size();
304+
return Dir->data();
305+
}
306+
*Len = 0;
307+
return "";
308+
}
309+
310+
LLVMMetadataRef LLVMDIScopeGetFile(LLVMMetadataRef Scope) {
311+
return wrap(unwrap<DIScope>(Scope)->getFile());
312+
}

Tests/LLVMTests/DIBuilderSpec.swift

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ class DIBuilderSpec : XCTestCase {
2121
let file = debugBuilder.buildFile(named: "test.trill", in: "/")
2222
// DIBUILDER-DAG: !{{[0-9]+}} = distinct !DICompileUnit(language: DW_LANG_Swift, file: !{{[0-9]+}}, isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !{{[0-9]+}}, splitDebugInlining: false)
2323
_ = debugBuilder.buildCompileUnit(for: .swift, in: file, kind: .full, optimized: false, runtimeVersion: 0)
24-
2524
debugBuilder.finalize()
2625
module.dump()
2726
})
@@ -78,9 +77,26 @@ class DIBuilderSpec : XCTestCase {
7877
})
7978
}
8079

80+
func testDIScopeAccessors() {
81+
let module = Module(name: "DISCope")
82+
let debugBuilder = DIBuilder(module: module)
83+
84+
let directory = "/some/long/directory/name"
85+
let fileName = "test.trill"
86+
let file = debugBuilder.buildFile(named: fileName, in: directory)
87+
let cu = debugBuilder.buildCompileUnit(for: .swift, in: file, kind: .full, optimized: false, runtimeVersion: 0)
88+
89+
XCTAssertEqual(cu.file?.name, fileName)
90+
XCTAssertEqual(cu.file?.directory, directory)
91+
// FIXME: Empty, for now. Need hashing and DWARF 5 source text bindings.
92+
XCTAssertEqual(cu.file?.source, "")
93+
}
94+
8195
#if !os(macOS)
8296
static var allTests = testCase([
8397
("testDIBuilder", testDIBuilder),
98+
("testDIExpression", testDIExpression),
99+
("testDIScopeAccessors", testDIScopeAccessors),
84100
])
85101
#endif
86102
}

0 commit comments

Comments
 (0)