Skip to content

Commit 729d58e

Browse files
yowltannergooding
authored andcommitted
Add DIBuilder functions for OOP style (#125)
* Add some OOP style functions for DIBuilder. * pass pointers to avoid AccessViolation * Last functions * add test, remove erroneous &
1 parent 52b94ee commit 729d58e

File tree

4 files changed

+140
-2
lines changed

4 files changed

+140
-2
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
using System;
2+
using System.IO;
3+
using LLVMSharp.Interop;
4+
using NUnit.Framework;
5+
6+
namespace LLVMSharp.UnitTests
7+
{
8+
public class DIBuilder
9+
{
10+
[Test(Description = "Exercises some DIBuilder functions, does not test the actual debug information is correct")]
11+
public void CreateDebugLocation()
12+
{
13+
string fileName = Path.GetFileName("DIBuilder.c");
14+
string directory = Path.GetDirectoryName(".");
15+
LLVMModuleRef module = LLVMModuleRef.CreateWithName("netscripten");
16+
module.Target = "asmjs-unknown-emscripten";
17+
var dIBuilder = module.CreateDIBuilder();
18+
var builder = module.Context.CreateBuilder();
19+
LLVMMetadataRef fileMetadata = dIBuilder.CreateFile(fileName, directory);
20+
21+
LLVMMetadataRef compileUnitMetadata = dIBuilder.CreateCompileUnit(
22+
LLVMDWARFSourceLanguage.LLVMDWARFSourceLanguageC,
23+
fileMetadata, "ILC", 0 /* Optimized */, String.Empty, 1, String.Empty,
24+
LLVMDWARFEmissionKind.LLVMDWARFEmissionFull, 0, 0, 0);
25+
module.AddNamedMetadataOperand("llvm.dbg.cu", compileUnitMetadata);
26+
27+
LLVMMetadataRef functionMetaType = dIBuilder.CreateSubroutineType(fileMetadata,
28+
ReadOnlySpan<LLVMMetadataRef>.Empty, LLVMDIFlags.LLVMDIFlagZero);
29+
30+
uint lineNumber = 1;
31+
var debugFunction = dIBuilder.CreateFunction(fileMetadata, "CreateDebugLocation", "CreateDebugLocation",
32+
fileMetadata,
33+
lineNumber, functionMetaType, 1, 1, lineNumber, 0, 0);
34+
LLVMMetadataRef currentLine =
35+
module.Context.CreateDebugLocation(lineNumber, 0, debugFunction, default(LLVMMetadataRef));
36+
37+
LLVMTypeRef[] FooParamTys = {LLVMTypeRef.Int64, LLVMTypeRef.Int64,};
38+
LLVMTypeRef FooFuncTy = LLVMTypeRef.CreateFunction(LLVMTypeRef.Int64, FooParamTys);
39+
LLVMValueRef FooFunction = module.AddFunction("foo", FooFuncTy);
40+
41+
var funcBlock = module.Context.AppendBasicBlock(FooFunction, "foo");
42+
builder.PositionAtEnd(funcBlock);
43+
builder.BuildRet(LLVMValueRef.CreateConstInt(LLVMTypeRef.Int64, 0));
44+
builder.CurrentDebugLocation = module.Context.MetadataAsValue(currentLine);
45+
var dwarfVersion = LLVMValueRef.CreateMDNode(new[]
46+
{
47+
LLVMValueRef.CreateConstInt(LLVMTypeRef.Int32, 2), module.Context.GetMDString("Dwarf Version", 13),
48+
LLVMValueRef.CreateConstInt(LLVMTypeRef.Int32, 4)
49+
});
50+
var dwarfSchemaVersion = LLVMValueRef.CreateMDNode(new[]
51+
{
52+
LLVMValueRef.CreateConstInt(LLVMTypeRef.Int32, 2),
53+
module.Context.GetMDString("Debug Info Version", 18),
54+
LLVMValueRef.CreateConstInt(LLVMTypeRef.Int32, 3)
55+
});
56+
module.AddNamedMetadataOperand("llvm.module.flags", dwarfVersion);
57+
module.AddNamedMetadataOperand("llvm.module.flags", dwarfSchemaVersion);
58+
dIBuilder.DIBuilderFinalize();
59+
60+
module.TryVerify(LLVMVerifierFailureAction.LLVMPrintMessageAction, out string message);
61+
62+
Assert.AreEqual("", message);
63+
}
64+
}
65+
}

sources/LLVMSharp/Interop.Extensions/LLVMContextRef.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,23 @@ public LLVMBuilderRef CreateBuilder()
7171
return LLVM.CreateBuilderInContext(this);
7272
}
7373

74+
public LLVMMetadataRef CreateDebugLocation(uint Line, uint Column, LLVMMetadataRef Scope, LLVMMetadataRef InlinedAt)
75+
{
76+
return LLVM.DIBuilderCreateDebugLocation(this, Line, Column, Scope, InlinedAt);
77+
}
78+
7479
public LLVMModuleRef CreateModuleWithName(string ModuleID)
7580
{
7681
using var marshaledModuleID = new MarshaledString(ModuleID);
7782
return LLVM.ModuleCreateWithNameInContext(marshaledModuleID, this);
7883
}
7984

85+
public LLVMValueRef MetadataAsValue(LLVMMetadataRef MD)
86+
{
87+
return LLVM.MetadataAsValue(this, MD);
88+
}
89+
90+
8091
public LLVMTypeRef CreateNamedStruct(string Name)
8192
{
8293
using var marshaledName = new MarshaledString(Name);

sources/LLVMSharp/Interop.Extensions/LLVMDIBuilderRef.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,50 @@ public LLVMDIBuilderRef(IntPtr handle)
1313

1414
public IntPtr Handle;
1515

16+
public LLVMMetadataRef CreateCompileUnit(LLVMDWARFSourceLanguage SourceLanguage, LLVMMetadataRef FileMetadata, string Producer, int IsOptimized, string Flags, uint RuntimeVersion,
17+
string SplitName, LLVMDWARFEmissionKind DwarfEmissionKind, uint DWOld, int SplitDebugInlining, int DebugInfoForProfiling)
18+
{
19+
using var marshaledProducer= new MarshaledString(Producer);
20+
using var marshaledFlags = new MarshaledString(Flags);
21+
using var marshaledSplitNameFlags = new MarshaledString(SplitName);
22+
23+
return LLVM.DIBuilderCreateCompileUnit(this, SourceLanguage, FileMetadata, marshaledProducer, (UIntPtr)marshaledProducer.Length, IsOptimized, marshaledFlags, (UIntPtr)marshaledFlags.Length,
24+
RuntimeVersion, marshaledSplitNameFlags, (UIntPtr)marshaledSplitNameFlags.Length, DwarfEmissionKind, DWOld, SplitDebugInlining, DebugInfoForProfiling);
25+
}
26+
27+
public LLVMMetadataRef CreateFile(string FullPath, string Directory)
28+
{
29+
using var marshaledFullPath = new MarshaledString(FullPath);
30+
using var marshaledDirectory = new MarshaledString(Directory);
31+
return LLVM.DIBuilderCreateFile(this, marshaledFullPath, (UIntPtr)marshaledFullPath.Length, marshaledDirectory, (UIntPtr)marshaledDirectory.Length);
32+
}
33+
34+
public LLVMMetadataRef CreateFunction(LLVMMetadataRef Scope, string Name, string LinkageName, LLVMMetadataRef File, uint LineNo, LLVMMetadataRef Type, int IsLocalToUnit, int IsDefinition,
35+
uint ScopeLine, LLVMDIFlags Flags, int IsOptimized)
36+
{
37+
using var marshaledName = new MarshaledString(Name);
38+
using var marshaledLinkageName = new MarshaledString(LinkageName);
39+
var methodNameLength = (uint)marshaledName.Length;
40+
var linkageNameLength = (uint)marshaledLinkageName.Length;
41+
42+
return LLVM.DIBuilderCreateFunction(this, Scope, marshaledName, (UIntPtr)(methodNameLength), marshaledLinkageName, (UIntPtr)(linkageNameLength), File,
43+
LineNo, Type, IsLocalToUnit, IsDefinition, ScopeLine, Flags, IsOptimized);
44+
}
45+
46+
public LLVMMetadataRef CreateSubroutineType(LLVMMetadataRef File, ReadOnlySpan<LLVMMetadataRef> ParameterTypes, LLVMDIFlags Flags)
47+
{
48+
fixed (LLVMMetadataRef* pParameterTypes = ParameterTypes)
49+
{
50+
return LLVM.DIBuilderCreateSubroutineType(this, File, (LLVMOpaqueMetadata**)pParameterTypes, (uint)ParameterTypes.Length, Flags);
51+
}
52+
}
53+
54+
public void DIBuilderFinalize()
55+
{
56+
LLVM.DIBuilderFinalize(this);
57+
}
58+
59+
1660
public static implicit operator LLVMDIBuilderRef(LLVMOpaqueDIBuilder* value)
1761
{
1862
return new LLVMDIBuilderRef((IntPtr)value);

sources/LLVMSharp/Interop.Extensions/LLVMModuleRef.cs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ public void AddNamedMetadataOperand(string Name, LLVMValueRef Val)
128128
LLVM.AddNamedMetadataOperand(this, marshaledName, Val);
129129
}
130130

131+
public LLVMDIBuilderRef CreateDIBuilder()
132+
{
133+
return new LLVMDIBuilderRef((IntPtr)LLVM.CreateDIBuilder(this));
134+
}
135+
131136
public LLVMExecutionEngineRef CreateExecutionEngine()
132137
{
133138
if (!TryCreateExecutionEngine(out LLVMExecutionEngineRef EE, out string Error))
@@ -174,6 +179,12 @@ public LLVMExecutionEngineRef CreateMCJITCompiler(ref LLVMMCJITCompilerOptions O
174179

175180
public LLVMModuleProviderRef CreateModuleProvider() => LLVM.CreateModuleProviderForExistingModule(this);
176181

182+
public void AddNamedMetadataOperand(string Name, LLVMMetadataRef CompileUnitMetadata)
183+
{
184+
using var marshaledName = new MarshaledString(Name);
185+
LLVM.AddNamedMetadataOperand(this, marshaledName, LLVM.MetadataAsValue(Context, CompileUnitMetadata));
186+
}
187+
177188
public void Dispose()
178189
{
179190
if (Handle != IntPtr.Zero)
@@ -333,9 +344,16 @@ public bool TryPrintToFile(string Filename, out string ErrorMessage)
333344
{
334345
using var marshaledFilename = new MarshaledString(Filename);
335346

336-
sbyte* pErrorMessage;
337-
var result = LLVM.PrintModuleToFile(this, marshaledFilename, &pErrorMessage);
347+
sbyte* pErrorMessage = null;
348+
int result = 0;
349+
try
350+
{
351+
result = LLVM.PrintModuleToFile(this, marshaledFilename, &pErrorMessage);
352+
}
353+
catch (Exception)
354+
{
338355

356+
}
339357

340358
if (pErrorMessage is null)
341359
{

0 commit comments

Comments
 (0)