Skip to content

Commit

Permalink
Add DIBuilder functions for OOP style (#125)
Browse files Browse the repository at this point in the history
* Add some OOP style functions for DIBuilder.

* pass pointers to avoid AccessViolation

* Last functions

* add test, remove erroneous &
  • Loading branch information
yowl authored and tannergooding committed Dec 16, 2019
1 parent 52b94ee commit 729d58e
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 2 deletions.
65 changes: 65 additions & 0 deletions Tests/LLVMSharp.UnitTests/DIBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System;
using System.IO;
using LLVMSharp.Interop;
using NUnit.Framework;

namespace LLVMSharp.UnitTests
{
public class DIBuilder
{
[Test(Description = "Exercises some DIBuilder functions, does not test the actual debug information is correct")]
public void CreateDebugLocation()
{
string fileName = Path.GetFileName("DIBuilder.c");
string directory = Path.GetDirectoryName(".");
LLVMModuleRef module = LLVMModuleRef.CreateWithName("netscripten");
module.Target = "asmjs-unknown-emscripten";
var dIBuilder = module.CreateDIBuilder();
var builder = module.Context.CreateBuilder();
LLVMMetadataRef fileMetadata = dIBuilder.CreateFile(fileName, directory);

LLVMMetadataRef compileUnitMetadata = dIBuilder.CreateCompileUnit(
LLVMDWARFSourceLanguage.LLVMDWARFSourceLanguageC,
fileMetadata, "ILC", 0 /* Optimized */, String.Empty, 1, String.Empty,
LLVMDWARFEmissionKind.LLVMDWARFEmissionFull, 0, 0, 0);
module.AddNamedMetadataOperand("llvm.dbg.cu", compileUnitMetadata);

LLVMMetadataRef functionMetaType = dIBuilder.CreateSubroutineType(fileMetadata,
ReadOnlySpan<LLVMMetadataRef>.Empty, LLVMDIFlags.LLVMDIFlagZero);

uint lineNumber = 1;
var debugFunction = dIBuilder.CreateFunction(fileMetadata, "CreateDebugLocation", "CreateDebugLocation",
fileMetadata,
lineNumber, functionMetaType, 1, 1, lineNumber, 0, 0);
LLVMMetadataRef currentLine =
module.Context.CreateDebugLocation(lineNumber, 0, debugFunction, default(LLVMMetadataRef));

LLVMTypeRef[] FooParamTys = {LLVMTypeRef.Int64, LLVMTypeRef.Int64,};
LLVMTypeRef FooFuncTy = LLVMTypeRef.CreateFunction(LLVMTypeRef.Int64, FooParamTys);
LLVMValueRef FooFunction = module.AddFunction("foo", FooFuncTy);

var funcBlock = module.Context.AppendBasicBlock(FooFunction, "foo");
builder.PositionAtEnd(funcBlock);
builder.BuildRet(LLVMValueRef.CreateConstInt(LLVMTypeRef.Int64, 0));
builder.CurrentDebugLocation = module.Context.MetadataAsValue(currentLine);
var dwarfVersion = LLVMValueRef.CreateMDNode(new[]
{
LLVMValueRef.CreateConstInt(LLVMTypeRef.Int32, 2), module.Context.GetMDString("Dwarf Version", 13),
LLVMValueRef.CreateConstInt(LLVMTypeRef.Int32, 4)
});
var dwarfSchemaVersion = LLVMValueRef.CreateMDNode(new[]
{
LLVMValueRef.CreateConstInt(LLVMTypeRef.Int32, 2),
module.Context.GetMDString("Debug Info Version", 18),
LLVMValueRef.CreateConstInt(LLVMTypeRef.Int32, 3)
});
module.AddNamedMetadataOperand("llvm.module.flags", dwarfVersion);
module.AddNamedMetadataOperand("llvm.module.flags", dwarfSchemaVersion);
dIBuilder.DIBuilderFinalize();

module.TryVerify(LLVMVerifierFailureAction.LLVMPrintMessageAction, out string message);

Assert.AreEqual("", message);
}
}
}
11 changes: 11 additions & 0 deletions sources/LLVMSharp/Interop.Extensions/LLVMContextRef.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,23 @@ public LLVMBuilderRef CreateBuilder()
return LLVM.CreateBuilderInContext(this);
}

public LLVMMetadataRef CreateDebugLocation(uint Line, uint Column, LLVMMetadataRef Scope, LLVMMetadataRef InlinedAt)
{
return LLVM.DIBuilderCreateDebugLocation(this, Line, Column, Scope, InlinedAt);
}

public LLVMModuleRef CreateModuleWithName(string ModuleID)
{
using var marshaledModuleID = new MarshaledString(ModuleID);
return LLVM.ModuleCreateWithNameInContext(marshaledModuleID, this);
}

public LLVMValueRef MetadataAsValue(LLVMMetadataRef MD)
{
return LLVM.MetadataAsValue(this, MD);
}


public LLVMTypeRef CreateNamedStruct(string Name)
{
using var marshaledName = new MarshaledString(Name);
Expand Down
44 changes: 44 additions & 0 deletions sources/LLVMSharp/Interop.Extensions/LLVMDIBuilderRef.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,50 @@ public LLVMDIBuilderRef(IntPtr handle)

public IntPtr Handle;

public LLVMMetadataRef CreateCompileUnit(LLVMDWARFSourceLanguage SourceLanguage, LLVMMetadataRef FileMetadata, string Producer, int IsOptimized, string Flags, uint RuntimeVersion,
string SplitName, LLVMDWARFEmissionKind DwarfEmissionKind, uint DWOld, int SplitDebugInlining, int DebugInfoForProfiling)
{
using var marshaledProducer= new MarshaledString(Producer);
using var marshaledFlags = new MarshaledString(Flags);
using var marshaledSplitNameFlags = new MarshaledString(SplitName);

return LLVM.DIBuilderCreateCompileUnit(this, SourceLanguage, FileMetadata, marshaledProducer, (UIntPtr)marshaledProducer.Length, IsOptimized, marshaledFlags, (UIntPtr)marshaledFlags.Length,
RuntimeVersion, marshaledSplitNameFlags, (UIntPtr)marshaledSplitNameFlags.Length, DwarfEmissionKind, DWOld, SplitDebugInlining, DebugInfoForProfiling);
}

public LLVMMetadataRef CreateFile(string FullPath, string Directory)
{
using var marshaledFullPath = new MarshaledString(FullPath);
using var marshaledDirectory = new MarshaledString(Directory);
return LLVM.DIBuilderCreateFile(this, marshaledFullPath, (UIntPtr)marshaledFullPath.Length, marshaledDirectory, (UIntPtr)marshaledDirectory.Length);
}

public LLVMMetadataRef CreateFunction(LLVMMetadataRef Scope, string Name, string LinkageName, LLVMMetadataRef File, uint LineNo, LLVMMetadataRef Type, int IsLocalToUnit, int IsDefinition,
uint ScopeLine, LLVMDIFlags Flags, int IsOptimized)
{
using var marshaledName = new MarshaledString(Name);
using var marshaledLinkageName = new MarshaledString(LinkageName);
var methodNameLength = (uint)marshaledName.Length;
var linkageNameLength = (uint)marshaledLinkageName.Length;

return LLVM.DIBuilderCreateFunction(this, Scope, marshaledName, (UIntPtr)(methodNameLength), marshaledLinkageName, (UIntPtr)(linkageNameLength), File,
LineNo, Type, IsLocalToUnit, IsDefinition, ScopeLine, Flags, IsOptimized);
}

public LLVMMetadataRef CreateSubroutineType(LLVMMetadataRef File, ReadOnlySpan<LLVMMetadataRef> ParameterTypes, LLVMDIFlags Flags)
{
fixed (LLVMMetadataRef* pParameterTypes = ParameterTypes)
{
return LLVM.DIBuilderCreateSubroutineType(this, File, (LLVMOpaqueMetadata**)pParameterTypes, (uint)ParameterTypes.Length, Flags);
}
}

public void DIBuilderFinalize()
{
LLVM.DIBuilderFinalize(this);
}


public static implicit operator LLVMDIBuilderRef(LLVMOpaqueDIBuilder* value)
{
return new LLVMDIBuilderRef((IntPtr)value);
Expand Down
22 changes: 20 additions & 2 deletions sources/LLVMSharp/Interop.Extensions/LLVMModuleRef.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ public void AddNamedMetadataOperand(string Name, LLVMValueRef Val)
LLVM.AddNamedMetadataOperand(this, marshaledName, Val);
}

public LLVMDIBuilderRef CreateDIBuilder()
{
return new LLVMDIBuilderRef((IntPtr)LLVM.CreateDIBuilder(this));
}

public LLVMExecutionEngineRef CreateExecutionEngine()
{
if (!TryCreateExecutionEngine(out LLVMExecutionEngineRef EE, out string Error))
Expand Down Expand Up @@ -174,6 +179,12 @@ public LLVMExecutionEngineRef CreateMCJITCompiler(ref LLVMMCJITCompilerOptions O

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

public void AddNamedMetadataOperand(string Name, LLVMMetadataRef CompileUnitMetadata)
{
using var marshaledName = new MarshaledString(Name);
LLVM.AddNamedMetadataOperand(this, marshaledName, LLVM.MetadataAsValue(Context, CompileUnitMetadata));
}

public void Dispose()
{
if (Handle != IntPtr.Zero)
Expand Down Expand Up @@ -333,9 +344,16 @@ public bool TryPrintToFile(string Filename, out string ErrorMessage)
{
using var marshaledFilename = new MarshaledString(Filename);

sbyte* pErrorMessage;
var result = LLVM.PrintModuleToFile(this, marshaledFilename, &pErrorMessage);
sbyte* pErrorMessage = null;
int result = 0;
try
{
result = LLVM.PrintModuleToFile(this, marshaledFilename, &pErrorMessage);
}
catch (Exception)
{

}

if (pErrorMessage is null)
{
Expand Down

0 comments on commit 729d58e

Please sign in to comment.