Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add DIBuilder functions for OOP style #125

Merged
merged 4 commits into from
Dec 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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