Skip to content

Commit 2733902

Browse files
Merge pull request #241 from ds5678/more-properties
Add more properties to the wrapper structs
2 parents d589f5e + bb4ee2e commit 2733902

15 files changed

+614
-3
lines changed

sources/LLVMSharp.Interop/Extensions/LLVMAttributeRef.cs

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,65 @@ public unsafe partial struct LLVMAttributeRef(IntPtr handle) : IEquatable<LLVMAt
88
{
99
public IntPtr Handle = handle;
1010

11-
public readonly uint Kind => LLVM.GetEnumAttributeKind(this);
11+
/// <summary>
12+
/// This returns true for all attributes except string attributes.
13+
/// </summary>
14+
public readonly bool HasKindAsEnum => (Handle != IntPtr.Zero) && (LLVM.IsStringAttribute(this) == 0);
1215

13-
public readonly ulong Value => LLVM.GetEnumAttributeValue(this);
16+
/// <summary>
17+
/// This returns true for enum attributes and int attributes.
18+
/// </summary>
19+
public readonly bool IsEnumAttribute => (Handle != IntPtr.Zero) && LLVM.IsEnumAttribute(this) != 0;
20+
21+
public readonly bool IsStringAttribute => (Handle != IntPtr.Zero) && LLVM.IsStringAttribute(this) != 0;
22+
23+
public readonly bool IsTypeAttribute => (Handle != IntPtr.Zero) && LLVM.IsTypeAttribute(this) != 0;
24+
25+
public readonly uint KindAsEnum => HasKindAsEnum ? LLVM.GetEnumAttributeKind(this) : default;
26+
27+
public readonly string KindAsString
28+
{
29+
get
30+
{
31+
if (!IsStringAttribute)
32+
{
33+
return string.Empty;
34+
}
35+
36+
uint length = 0;
37+
var kindPtr = LLVM.GetStringAttributeKind(this, &length);
38+
if (kindPtr == null)
39+
{
40+
return string.Empty;
41+
}
42+
43+
return new ReadOnlySpan<byte>(kindPtr, (int)length).AsString();
44+
}
45+
}
46+
47+
public readonly ulong ValueAsInt => IsEnumAttribute ? LLVM.GetEnumAttributeValue(this) : default;
48+
49+
public readonly string ValueAsString
50+
{
51+
get
52+
{
53+
if (!IsStringAttribute)
54+
{
55+
return string.Empty;
56+
}
57+
58+
uint length = 0;
59+
var valuePtr = LLVM.GetStringAttributeValue(this, &length);
60+
if (valuePtr == null)
61+
{
62+
return string.Empty;
63+
}
64+
65+
return new ReadOnlySpan<byte>(valuePtr, (int)length).AsString();
66+
}
67+
}
68+
69+
public readonly LLVMTypeRef ValueAsType => IsTypeAttribute ? LLVM.GetTypeAttributeValue(this) : default;
1470

1571
public static implicit operator LLVMAttributeRef(LLVMOpaqueAttributeRef* value) => new LLVMAttributeRef((IntPtr)value);
1672

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information.
2+
3+
using System;
4+
using System.Collections;
5+
using System.Collections.Generic;
6+
7+
namespace LLVMSharp.Interop;
8+
9+
public readonly struct LLVMBasicBlockInstructionsEnumerable(LLVMBasicBlockRef basicBlock) : IEnumerable<LLVMValueRef>
10+
{
11+
public Enumerator GetEnumerator() => new Enumerator(basicBlock);
12+
13+
IEnumerator<LLVMValueRef> IEnumerable<LLVMValueRef>.GetEnumerator() => GetEnumerator();
14+
15+
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
16+
17+
public struct Enumerator(LLVMBasicBlockRef basicBlock) : IEnumerator<LLVMValueRef>
18+
{
19+
public LLVMValueRef Current { get; private set; }
20+
21+
readonly object IEnumerator.Current => Current;
22+
23+
readonly void IDisposable.Dispose()
24+
{
25+
}
26+
27+
public bool MoveNext()
28+
{
29+
if (Current.Handle == 0)
30+
{
31+
Current = basicBlock.FirstInstruction;
32+
}
33+
else
34+
{
35+
Current = Current.NextInstruction;
36+
}
37+
return Current.Handle != 0;
38+
}
39+
40+
public void Reset() => Current = default;
41+
}
42+
}

sources/LLVMSharp.Interop/Extensions/LLVMBasicBlockRef.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ public unsafe partial struct LLVMBasicBlockRef(IntPtr handle) : IEquatable<LLVMB
1010

1111
public readonly LLVMValueRef FirstInstruction => (Handle != IntPtr.Zero) ? LLVM.GetFirstInstruction(this) : default;
1212

13+
public readonly LLVMBasicBlockInstructionsEnumerable Instructions => new LLVMBasicBlockInstructionsEnumerable(this);
14+
1315
public readonly LLVMValueRef LastInstruction => (Handle != IntPtr.Zero) ? LLVM.GetLastInstruction(this) : default;
1416

1517
public readonly LLVMBasicBlockRef Next => (Handle != IntPtr.Zero) ? LLVM.GetNextBasicBlock(this) : default;

sources/LLVMSharp.Interop/Extensions/LLVMMetadataRef.cs

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,104 @@ public unsafe partial struct LLVMMetadataRef(IntPtr handle) : IEquatable<LLVMMet
88
{
99
public IntPtr Handle = handle;
1010

11+
public readonly uint AlignInBits => IsType ? LLVM.DITypeGetAlignInBits(this) : default;
12+
13+
public readonly uint Column => Kind switch {
14+
LLVMMetadataKind.LLVMDILocationMetadataKind => LLVM.DILocationGetColumn(this),
15+
_ => default,
16+
};
17+
18+
public readonly LLVMMetadataRef Expression => Kind switch {
19+
LLVMMetadataKind.LLVMDIGlobalVariableExpressionMetadataKind => LLVM.DIGlobalVariableExpressionGetExpression(this),
20+
_ => default,
21+
};
22+
23+
public readonly LLVMMetadataRef File => Kind switch {
24+
LLVMMetadataKind.LLVMDIFileMetadataKind => this,
25+
LLVMMetadataKind.LLVMDISubprogramMetadataKind => LLVM.DIScopeGetFile(this),
26+
_ when IsVariable => LLVM.DIVariableGetFile(this),
27+
_ => default,
28+
};
29+
30+
public readonly LLVMDIFlags Flags => IsType ? LLVM.DITypeGetFlags(this) : default;
31+
32+
public readonly LLVMMetadataRef InlinedAt => Kind switch {
33+
LLVMMetadataKind.LLVMDILocationMetadataKind => LLVM.DILocationGetInlinedAt(this),
34+
_ => default,
35+
};
36+
37+
public readonly bool IsDINode => Kind is >= LLVMMetadataKind.LLVMDILocationMetadataKind and <= LLVMMetadataKind.LLVMDIAssignIDMetadataKind;
38+
39+
public readonly bool IsTemplateParameter => Kind switch {
40+
LLVMMetadataKind.LLVMDITemplateTypeParameterMetadataKind => true,
41+
LLVMMetadataKind.LLVMDITemplateValueParameterMetadataKind => true,
42+
_ => false,
43+
};
44+
45+
public readonly bool IsType => Kind switch {
46+
LLVMMetadataKind.LLVMDICompositeTypeMetadataKind => true,
47+
LLVMMetadataKind.LLVMDIDerivedTypeMetadataKind => true,
48+
LLVMMetadataKind.LLVMDIStringTypeMetadataKind => true,
49+
LLVMMetadataKind.LLVMDIBasicTypeMetadataKind => true,
50+
LLVMMetadataKind.LLVMDISubroutineTypeMetadataKind => true,
51+
_ => false,
52+
};
53+
54+
public readonly bool IsVariable => Kind switch {
55+
LLVMMetadataKind.LLVMDILocalVariableMetadataKind => true,
56+
LLVMMetadataKind.LLVMDIGlobalVariableMetadataKind => true,
57+
_ => false,
58+
};
59+
60+
public readonly LLVMMetadataKind Kind => Handle == default
61+
? (LLVMMetadataKind)(-1) // 0 is a valid kind, so we use -1 to indicate a null metadata reference
62+
: (LLVMMetadataKind)LLVM.GetMetadataKind(this);
63+
64+
public readonly uint Line => Kind switch {
65+
LLVMMetadataKind.LLVMDISubprogramMetadataKind => LLVM.DISubprogramGetLine(this),
66+
LLVMMetadataKind.LLVMDILocationMetadataKind => LLVM.DILocationGetLine(this),
67+
_ when IsType => LLVM.DITypeGetLine(this),
68+
_ when IsVariable => LLVM.DIVariableGetLine(this),
69+
_ => default,
70+
};
71+
72+
public readonly string Name
73+
{
74+
get
75+
{
76+
if (!IsType)
77+
{
78+
return "";
79+
}
80+
81+
nuint nameLength = 0;
82+
sbyte* namePtr = LLVM.DITypeGetName(this, &nameLength);
83+
if (namePtr == null)
84+
{
85+
return "";
86+
}
87+
88+
return new ReadOnlySpan<byte>(namePtr, (int)nameLength).AsString();
89+
}
90+
}
91+
92+
public readonly ulong OffsetInBits => IsType ? LLVM.DITypeGetOffsetInBits(this) : default;
93+
94+
public readonly LLVMMetadataRef Scope => Kind switch {
95+
LLVMMetadataKind.LLVMDILocationMetadataKind => LLVM.DILocationGetScope(this),
96+
_ when IsVariable => LLVM.DIVariableGetScope(this),
97+
_ => default,
98+
};
99+
100+
public readonly ulong SizeInBits => IsType ? LLVM.DITypeGetSizeInBits(this) : default;
101+
102+
public readonly ushort Tag => IsDINode ? LLVM.GetDINodeTag(this) : default;
103+
104+
public readonly LLVMMetadataRef Variable => Kind switch {
105+
LLVMMetadataKind.LLVMDIGlobalVariableExpressionMetadataKind => LLVM.DIGlobalVariableExpressionGetVariable(this),
106+
_ => default,
107+
};
108+
11109
public static implicit operator LLVMMetadataRef(LLVMOpaqueMetadata* value) => new LLVMMetadataRef((IntPtr)value);
12110

13111
public static implicit operator LLVMOpaqueMetadata*(LLVMMetadataRef value) => (LLVMOpaqueMetadata*)value.Handle;
@@ -16,11 +114,19 @@ public unsafe partial struct LLVMMetadataRef(IntPtr handle) : IEquatable<LLVMMet
16114

17115
public static bool operator !=(LLVMMetadataRef left, LLVMMetadataRef right) => !(left == right);
18116

117+
public readonly LLVMValueRef AsValue(LLVMContextRef context) => context.MetadataAsValue(this);
118+
19119
public override readonly bool Equals(object? obj) => (obj is LLVMMetadataRef other) && Equals(other);
20120

21121
public readonly bool Equals(LLVMMetadataRef other) => this == other;
22122

23123
public override readonly int GetHashCode() => Handle.GetHashCode();
24124

125+
public readonly string GetMDString(LLVMContextRef context, out uint length)
126+
{
127+
var value = context.MetadataAsValue(this);
128+
return value.GetMDString(out length);
129+
}
130+
25131
public override readonly string ToString() => $"{nameof(LLVMMetadataRef)}: {Handle:X}";
26132
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information.
2+
3+
using System;
4+
using System.Collections;
5+
using System.Collections.Generic;
6+
7+
namespace LLVMSharp.Interop;
8+
9+
public readonly struct LLVMModuleFunctionsEnumerable(LLVMModuleRef module) : IEnumerable<LLVMValueRef>
10+
{
11+
public Enumerator GetEnumerator() => new Enumerator(module);
12+
13+
IEnumerator<LLVMValueRef> IEnumerable<LLVMValueRef>.GetEnumerator() => GetEnumerator();
14+
15+
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
16+
17+
public struct Enumerator(LLVMModuleRef module) : IEnumerator<LLVMValueRef>
18+
{
19+
public LLVMValueRef Current { get; private set; }
20+
21+
readonly object IEnumerator.Current => Current;
22+
23+
readonly void IDisposable.Dispose()
24+
{
25+
}
26+
27+
public bool MoveNext()
28+
{
29+
if (Current.Handle == 0)
30+
{
31+
Current = module.FirstFunction;
32+
}
33+
else
34+
{
35+
Current = Current.NextFunction;
36+
}
37+
return Current.Handle != 0;
38+
}
39+
40+
public void Reset() => Current = default;
41+
}
42+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information.
2+
3+
using System;
4+
using System.Collections;
5+
using System.Collections.Generic;
6+
7+
namespace LLVMSharp.Interop;
8+
9+
public readonly struct LLVMModuleGlobalAliasesEnumerable(LLVMModuleRef module) : IEnumerable<LLVMValueRef>
10+
{
11+
public Enumerator GetEnumerator() => new Enumerator(module);
12+
13+
IEnumerator<LLVMValueRef> IEnumerable<LLVMValueRef>.GetEnumerator() => GetEnumerator();
14+
15+
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
16+
17+
public struct Enumerator(LLVMModuleRef module) : IEnumerator<LLVMValueRef>
18+
{
19+
public LLVMValueRef Current { get; private set; }
20+
21+
readonly object IEnumerator.Current => Current;
22+
23+
readonly void IDisposable.Dispose()
24+
{
25+
}
26+
27+
public bool MoveNext()
28+
{
29+
if (Current.Handle == 0)
30+
{
31+
Current = module.FirstGlobalAlias;
32+
}
33+
else
34+
{
35+
Current = Current.NextGlobalAlias;
36+
}
37+
return Current.Handle != 0;
38+
}
39+
40+
public void Reset() => Current = default;
41+
}
42+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information.
2+
3+
using System;
4+
using System.Collections;
5+
using System.Collections.Generic;
6+
7+
namespace LLVMSharp.Interop;
8+
9+
public readonly struct LLVMModuleGlobalIFuncsEnumerable(LLVMModuleRef module) : IEnumerable<LLVMValueRef>
10+
{
11+
public Enumerator GetEnumerator() => new Enumerator(module);
12+
13+
IEnumerator<LLVMValueRef> IEnumerable<LLVMValueRef>.GetEnumerator() => GetEnumerator();
14+
15+
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
16+
17+
public struct Enumerator(LLVMModuleRef module) : IEnumerator<LLVMValueRef>
18+
{
19+
public LLVMValueRef Current { get; private set; }
20+
21+
readonly object IEnumerator.Current => Current;
22+
23+
readonly void IDisposable.Dispose()
24+
{
25+
}
26+
27+
public bool MoveNext()
28+
{
29+
if (Current.Handle == 0)
30+
{
31+
Current = module.FirstGlobalIFunc;
32+
}
33+
else
34+
{
35+
Current = Current.NextGlobalIFunc;
36+
}
37+
return Current.Handle != 0;
38+
}
39+
40+
public void Reset() => Current = default;
41+
}
42+
}

0 commit comments

Comments
 (0)