Skip to content

Commit 06e83a5

Browse files
authored
This implements #284 (#285)
* This implements #284 Removed `ref struct` restriction on DIBuilder * DIBuilders is now a class with an unowned alias interface `IDIBuilder` * Applied LazyEncodedString in some more places to enable use of utf8 literals to provide pre-encoded literal strings * Removed infinite recursion in implicit operator - VS IDE hides stack overflow errors and make it look like things all passed unless you look very carefully for it. - A crash in the tests should show up as a total fail of the tests, but it doesn't. It just shows up as a count of errors that is easily overlooked.
1 parent 73fb0d6 commit 06e83a5

33 files changed

+2559
-1615
lines changed

IgnoredWords.dic

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ malloc
8686
marshallers
8787
marshalling
8888
memcopy
89+
memcpy
8990
metadata
9091
Mips
9192
msbuild

src/Interop/Ubiquity.NET.Llvm.Interop/ABI/libllvm-c/MetadataBindings.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ public static partial class MetadataBindings
220220

221221
[MethodImpl( MethodImplOptions.AggressiveInlining )]
222222
public static LLVMMetadataRef LibLLVMDIBuilderCreateTempFunctionFwdDecl(
223-
LLVMDIBuilderRef D,
223+
LLVMDIBuilderRefAlias D,
224224
LLVMMetadataRef Scope,
225225
LazyEncodedString Name,
226226
LazyEncodedString LinkageName,
@@ -255,7 +255,7 @@ bool isOptimized
255255
[LibraryImport( LibraryName )]
256256
[UnmanagedCallConv( CallConvs = [ typeof( CallConvCdecl ) ] )]
257257
private static unsafe partial LLVMMetadataRef LibLLVMDIBuilderCreateTempFunctionFwdDecl(
258-
LLVMDIBuilderRef D,
258+
LLVMDIBuilderRefAlias D,
259259
LLVMMetadataRef Scope,
260260
LazyEncodedString Name, nuint NameLen,
261261
LazyEncodedString LinkageName, nuint LinkageNameLen,
@@ -271,7 +271,7 @@ private static unsafe partial LLVMMetadataRef LibLLVMDIBuilderCreateTempFunction
271271

272272
[LibraryImport( LibraryName )]
273273
[UnmanagedCallConv( CallConvs = [ typeof( CallConvCdecl ) ] )]
274-
public static unsafe partial void LibLLVMDIBuilderFinalizeSubProgram( LLVMDIBuilderRef dref, LLVMMetadataRef subProgram );
274+
public static unsafe partial void LibLLVMDIBuilderFinalizeSubProgram( LLVMDIBuilderRefAlias dref, LLVMMetadataRef subProgram );
275275

276276
[LibraryImport( LibraryName )]
277277
[UnmanagedCallConv( CallConvs = [ typeof( CallConvCdecl ) ] )]

src/Interop/Ubiquity.NET.Llvm.Interop/ABI/llvm-c/DebugInfo.cs

Lines changed: 91 additions & 91 deletions
Large diffs are not rendered by default.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// -----------------------------------------------------------------------
2+
// <copyright file="LLVMDiBuilderRefAlias.cs" company="Ubiquity.NET Contributors">
3+
// Copyright (c) Ubiquity.NET Contributors. All rights reserved.
4+
// </copyright>
5+
// -----------------------------------------------------------------------
6+
7+
namespace Ubiquity.NET.Llvm.Interop
8+
{
9+
/// <summary>Simple type safe handle to wrap an opaque pointer</summary>
10+
/// <remarks>
11+
/// This is a specialized form of an alias, it is NOT inherent in the LLVM APIs
12+
/// as no LLVM objects own a DIBuilder, but many consumers will. This allows for
13+
/// consistency in the ownership consideration of a given DIBuilder instance.
14+
/// </remarks>
15+
[NativeMarshalling(typeof(ContextHandleMarshaller<LLVMDIBuilderRefAlias>))]
16+
public readonly record struct LLVMDIBuilderRefAlias
17+
: IContextHandle<LLVMDIBuilderRefAlias>
18+
{
19+
/// <summary>Gets a value indicating whether this handle is a <see langword="null"/> value</summary>
20+
public bool IsNull => Handle == nint.Zero;
21+
22+
/// <summary>Gets the handle as an <see cref="nint"/> suitable for passing to native code</summary>
23+
/// <returns>The handle as an <see cref="nint"/></returns>
24+
public nint DangerousGetHandle() => Handle;
25+
26+
public IntPtr ToIntPtr() => Handle;
27+
28+
/// <summary>Interface defined factory for an instance of <see cref="LLVMDIBuilderRefAlias"/></summary>
29+
/// <param name="abiValue">Native ABI value of the handle</param>
30+
/// <returns>Type specific wrapper around the native ABI handle</returns>
31+
public static LLVMDIBuilderRefAlias FromABI(nint abiValue) => new(abiValue);
32+
33+
/// <summary>Gets a zero (<see langword="null"/>) value handle</summary>
34+
public static LLVMDIBuilderRefAlias Zero => FromABI(nint.Zero);
35+
36+
/// <summary>Gets the handle as an <see cref="nint"/> suitable for passing to native code</summary>
37+
/// <param name="value">Handle to convert</param>
38+
/// <returns>The handle as an <see cref="nint"/></returns>
39+
public static implicit operator nint(LLVMDIBuilderRefAlias value) => value.Handle;
40+
41+
public static LLVMDIBuilderRefAlias From( LLVMDIBuilderRefAlias self )
42+
{
43+
self.ThrowIfInvalid();
44+
return FromABI(self.DangerousGetHandle());
45+
}
46+
47+
// define implicit conversion from an OWNED value
48+
[SuppressMessage( "Usage", "CA2225:Operator overloads have named alternates", Justification = "Exists, tooling is too stupid to see it" )]
49+
public static implicit operator LLVMDIBuilderRefAlias( LLVMDIBuilderRef other ) => FromABI( other.DangerousGetHandle() );
50+
51+
private LLVMDIBuilderRefAlias( nint p )
52+
{
53+
Handle = p;
54+
}
55+
56+
private readonly nint Handle;
57+
}
58+
}

src/Samples/CodeGenWithDebugInfo/Program.cs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,10 @@ public static void Main( string[] args )
8989

9090
#region CreatingBasicTypesWithDebugInfo
9191
// Create basic types used in this compilation
92-
var i32 = new DebugBasicType( module.Context.Int32Type, in diBuilder, "int", DiTypeKind.Signed );
93-
var f32 = new DebugBasicType( module.Context.FloatType, in diBuilder, "float", DiTypeKind.Float );
92+
var i32 = new DebugBasicType( module.Context.Int32Type, diBuilder, "int", DiTypeKind.Signed );
93+
var f32 = new DebugBasicType( module.Context.FloatType, diBuilder, "float", DiTypeKind.Float );
9494
var voidType = DebugType.Create( module.Context.VoidType, (DIType?)null );
95-
var i32Array_0_32 = i32.CreateArrayType( in diBuilder, 0, 32 );
95+
var i32Array_0_32 = i32.CreateArrayType( diBuilder, 0, 32 );
9696
#endregion
9797

9898
#region CreatingStructureTypes
@@ -104,7 +104,7 @@ public static void Main( string[] args )
104104
new( 2, "c", diFile, 5, i32Array_0_32 ),
105105
};
106106

107-
var fooType = new DebugStructType( in diBuilder, "struct.foo", compilationUnit, "foo", diFile, 1, DebugInfoFlags.None, fooBody );
107+
var fooType = new DebugStructType( diBuilder, "struct.foo", compilationUnit, "foo", diFile, 1, DebugInfoFlags.None, fooBody );
108108
#endregion
109109

110110
#region CreatingGlobalsAndMetadata
@@ -133,17 +133,17 @@ public static void Main( string[] args )
133133
#region CreatingQualifiedTypes
134134
// create types for function args
135135
var constFoo = diBuilder.CreateQualifiedType( fooType.DebugInfoType, QualifiedTypeTag.Const );
136-
var fooPtr = new DebugPointerType( fooType, in diBuilder );
136+
var fooPtr = new DebugPointerType( fooType, diBuilder );
137137
#endregion
138138

139139
// Create the functions
140140
// NOTE: The declaration ordering is reversed from that of the sample code file (test.c)
141141
// However, this is what Clang ends up doing for some reason so it is
142142
// replicated here to aid in comparing the generated LL files.
143-
Function doCopyFunc = DeclareDoCopyFunc( in diBuilder, diFile, voidType, abiAttributes );
144-
Function copyFunc = DeclareCopyFunc(targetABI, in diBuilder, diFile, voidType, constFoo, fooPtr, abiAttributes );
143+
Function doCopyFunc = DeclareDoCopyFunc( diBuilder, diFile, voidType, abiAttributes );
144+
Function copyFunc = DeclareCopyFunc(targetABI, diBuilder, diFile, voidType, constFoo, fooPtr, abiAttributes );
145145

146-
CreateCopyFunctionBody( in diBuilder, copyFunc, diFile, fooType, fooPtr, constFoo );
146+
CreateCopyFunctionBody( diBuilder, copyFunc, diFile, fooType, fooPtr, constFoo );
147147
CreateDoCopyFunctionBody( module, doCopyFunc, fooType, bar, baz, copyFunc );
148148

149149
// finalize the debug information
@@ -185,16 +185,16 @@ private static void ShowUsage( )
185185

186186
#region FunctionDeclarations
187187
private static Function DeclareDoCopyFunc(
188-
ref readonly DIBuilder diBuilder,
188+
DIBuilder diBuilder,
189189
DIFile diFile,
190190
IDebugType<ITypeRef, DIType> voidType,
191191
IEnumerable<AttributeValue> abiAttributes
192192
)
193193
{
194194
var module = diBuilder.OwningModule;
195-
var doCopySig = module.Context.CreateFunctionType( in diBuilder, voidType );
195+
var doCopySig = module.Context.CreateFunctionType( diBuilder, voidType );
196196

197-
var doCopyFunc = module.CreateFunction( in diBuilder
197+
var doCopyFunc = module.CreateFunction( diBuilder
198198
, scope: diFile
199199
, name: "DoCopy"
200200
, linkageName: null
@@ -212,7 +212,7 @@ IEnumerable<AttributeValue> abiAttributes
212212
}
213213

214214
private static Function DeclareCopyFunc( ITargetABI abi
215-
, ref readonly DIBuilder diBuilder
215+
, DIBuilder diBuilder
216216
, DIFile diFile
217217
, IDebugType<ITypeRef, DIType> voidType
218218
, DIDerivedType constFoo
@@ -230,13 +230,13 @@ private static Function DeclareCopyFunc( ITargetABI abi
230230
// To get the correct debug info signature this inserts an
231231
// explicit DebugType<> that overrides the default behavior
232232
// to pair the LLVM pointer type with the original source type.
233-
var copySig = module.Context.CreateFunctionType( in diBuilder
233+
var copySig = module.Context.CreateFunctionType( diBuilder
234234
, voidType
235235
, DebugType.Create( fooPtr, constFoo )
236236
, fooPtr
237237
);
238238

239-
var copyFunc = module.CreateFunction( in diBuilder
239+
var copyFunc = module.CreateFunction( diBuilder
240240
, scope: diFile
241241
, name: "copy"
242242
, linkageName: null
@@ -268,7 +268,7 @@ private static void AddModuleFlags( ITargetABI abi, Module module, ILibLlvm libr
268268
}
269269
#endregion
270270

271-
private static void CreateCopyFunctionBody( ref readonly DIBuilder diBuilder
271+
private static void CreateCopyFunctionBody( DIBuilder diBuilder
272272
, Function copyFunc
273273
, DIFile diFile
274274
, ITypeRef foo

0 commit comments

Comments
 (0)