Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
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
60 changes: 58 additions & 2 deletions sources/LLVMSharp.Interop/Extensions/LLVMAttributeRef.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,65 @@ public unsafe partial struct LLVMAttributeRef(IntPtr handle) : IEquatable<LLVMAt
{
public IntPtr Handle = handle;

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

public readonly ulong Value => LLVM.GetEnumAttributeValue(this);
/// <summary>
/// This returns true for enum attributes and int attributes.
/// </summary>
public readonly bool IsEnumAttribute => (Handle != IntPtr.Zero) && LLVM.IsEnumAttribute(this) != 0;

public readonly bool IsStringAttribute => (Handle != IntPtr.Zero) && LLVM.IsStringAttribute(this) != 0;

public readonly bool IsTypeAttribute => (Handle != IntPtr.Zero) && LLVM.IsTypeAttribute(this) != 0;

public readonly uint KindAsEnum => HasKindAsEnum ? LLVM.GetEnumAttributeKind(this) : default;

public readonly string KindAsString
{
get
{
if (!IsStringAttribute)
{
return string.Empty;
}

uint length = 0;
var kindPtr = LLVM.GetStringAttributeKind(this, &length);
if (kindPtr == null)
{
return string.Empty;
}

return new ReadOnlySpan<byte>(kindPtr, (int)length).AsString();
}
}

public readonly ulong ValueAsInt => IsEnumAttribute ? LLVM.GetEnumAttributeValue(this) : default;

public readonly string ValueAsString
{
get
{
if (!IsStringAttribute)
{
return string.Empty;
}

uint length = 0;
var valuePtr = LLVM.GetStringAttributeValue(this, &length);
if (valuePtr == null)
{
return string.Empty;
}

return new ReadOnlySpan<byte>(valuePtr, (int)length).AsString();
}
}

public readonly LLVMTypeRef ValueAsType => IsTypeAttribute ? LLVM.GetTypeAttributeValue(this) : default;

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

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// 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.

using System;
using System.Collections;
using System.Collections.Generic;

namespace LLVMSharp.Interop;

public readonly struct LLVMBasicBlockInstructionsEnumerable(LLVMBasicBlockRef basicBlock) : IEnumerable<LLVMValueRef>
{
public Enumerator GetEnumerator() => new Enumerator(basicBlock);

IEnumerator<LLVMValueRef> IEnumerable<LLVMValueRef>.GetEnumerator() => GetEnumerator();

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

public struct Enumerator(LLVMBasicBlockRef basicBlock) : IEnumerator<LLVMValueRef>
{
public LLVMValueRef Current { get; private set; }

readonly object IEnumerator.Current => Current;

readonly void IDisposable.Dispose()
{
}

public bool MoveNext()
{
if (Current.Handle == 0)
{
Current = basicBlock.FirstInstruction;
}
else
{
Current = Current.NextInstruction;
}
return Current.Handle != 0;
}

public void Reset() => Current = default;
}
}
2 changes: 2 additions & 0 deletions sources/LLVMSharp.Interop/Extensions/LLVMBasicBlockRef.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ public unsafe partial struct LLVMBasicBlockRef(IntPtr handle) : IEquatable<LLVMB

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

public readonly LLVMBasicBlockInstructionsEnumerable Instructions => new LLVMBasicBlockInstructionsEnumerable(this);

public readonly LLVMValueRef LastInstruction => (Handle != IntPtr.Zero) ? LLVM.GetLastInstruction(this) : default;

public readonly LLVMBasicBlockRef Next => (Handle != IntPtr.Zero) ? LLVM.GetNextBasicBlock(this) : default;
Expand Down
106 changes: 106 additions & 0 deletions sources/LLVMSharp.Interop/Extensions/LLVMMetadataRef.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,104 @@ public unsafe partial struct LLVMMetadataRef(IntPtr handle) : IEquatable<LLVMMet
{
public IntPtr Handle = handle;

public readonly uint AlignInBits => IsType ? LLVM.DITypeGetAlignInBits(this) : default;

public readonly uint Column => Kind switch {
LLVMMetadataKind.LLVMDILocationMetadataKind => LLVM.DILocationGetColumn(this),
_ => default,
};

public readonly LLVMMetadataRef Expression => Kind switch {
LLVMMetadataKind.LLVMDIGlobalVariableExpressionMetadataKind => LLVM.DIGlobalVariableExpressionGetExpression(this),
_ => default,
};

public readonly LLVMMetadataRef File => Kind switch {
LLVMMetadataKind.LLVMDIFileMetadataKind => this,
LLVMMetadataKind.LLVMDISubprogramMetadataKind => LLVM.DIScopeGetFile(this),
_ when IsVariable => LLVM.DIVariableGetFile(this),
_ => default,
};

public readonly LLVMDIFlags Flags => IsType ? LLVM.DITypeGetFlags(this) : default;

public readonly LLVMMetadataRef InlinedAt => Kind switch {
LLVMMetadataKind.LLVMDILocationMetadataKind => LLVM.DILocationGetInlinedAt(this),
_ => default,
};

public readonly bool IsDINode => Kind is >= LLVMMetadataKind.LLVMDILocationMetadataKind and <= LLVMMetadataKind.LLVMDIAssignIDMetadataKind;

public readonly bool IsTemplateParameter => Kind switch {
LLVMMetadataKind.LLVMDITemplateTypeParameterMetadataKind => true,
LLVMMetadataKind.LLVMDITemplateValueParameterMetadataKind => true,
_ => false,
};

public readonly bool IsType => Kind switch {
LLVMMetadataKind.LLVMDICompositeTypeMetadataKind => true,
LLVMMetadataKind.LLVMDIDerivedTypeMetadataKind => true,
LLVMMetadataKind.LLVMDIStringTypeMetadataKind => true,
LLVMMetadataKind.LLVMDIBasicTypeMetadataKind => true,
LLVMMetadataKind.LLVMDISubroutineTypeMetadataKind => true,
_ => false,
};

public readonly bool IsVariable => Kind switch {
LLVMMetadataKind.LLVMDILocalVariableMetadataKind => true,
LLVMMetadataKind.LLVMDIGlobalVariableMetadataKind => true,
_ => false,
};

public readonly LLVMMetadataKind Kind => Handle == default
? (LLVMMetadataKind)(-1) // 0 is a valid kind, so we use -1 to indicate a null metadata reference
: (LLVMMetadataKind)LLVM.GetMetadataKind(this);

public readonly uint Line => Kind switch {
LLVMMetadataKind.LLVMDISubprogramMetadataKind => LLVM.DISubprogramGetLine(this),
LLVMMetadataKind.LLVMDILocationMetadataKind => LLVM.DILocationGetLine(this),
_ when IsType => LLVM.DITypeGetLine(this),
_ when IsVariable => LLVM.DIVariableGetLine(this),
_ => default,
};

public readonly string Name
{
get
{
if (!IsType)
{
return "";
}

nuint nameLength = 0;
sbyte* namePtr = LLVM.DITypeGetName(this, &nameLength);
if (namePtr == null)
{
return "";
}

return new ReadOnlySpan<byte>(namePtr, (int)nameLength).AsString();
}
}

public readonly ulong OffsetInBits => IsType ? LLVM.DITypeGetOffsetInBits(this) : default;

public readonly LLVMMetadataRef Scope => Kind switch {
LLVMMetadataKind.LLVMDILocationMetadataKind => LLVM.DILocationGetScope(this),
_ when IsVariable => LLVM.DIVariableGetScope(this),
_ => default,
};

public readonly ulong SizeInBits => IsType ? LLVM.DITypeGetSizeInBits(this) : default;

public readonly ushort Tag => IsDINode ? LLVM.GetDINodeTag(this) : default;

public readonly LLVMMetadataRef Variable => Kind switch {
LLVMMetadataKind.LLVMDIGlobalVariableExpressionMetadataKind => LLVM.DIGlobalVariableExpressionGetVariable(this),
_ => default,
};

public static implicit operator LLVMMetadataRef(LLVMOpaqueMetadata* value) => new LLVMMetadataRef((IntPtr)value);

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

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

public readonly LLVMValueRef AsValue(LLVMContextRef context) => context.MetadataAsValue(this);

public override readonly bool Equals(object? obj) => (obj is LLVMMetadataRef other) && Equals(other);

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

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

public readonly string GetMDString(LLVMContextRef context, out uint length)
{
var value = context.MetadataAsValue(this);
return value.GetMDString(out length);
}

public override readonly string ToString() => $"{nameof(LLVMMetadataRef)}: {Handle:X}";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// 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.

using System;
using System.Collections;
using System.Collections.Generic;

namespace LLVMSharp.Interop;

public readonly struct LLVMModuleFunctionsEnumerable(LLVMModuleRef module) : IEnumerable<LLVMValueRef>
{
public Enumerator GetEnumerator() => new Enumerator(module);

IEnumerator<LLVMValueRef> IEnumerable<LLVMValueRef>.GetEnumerator() => GetEnumerator();

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

public struct Enumerator(LLVMModuleRef module) : IEnumerator<LLVMValueRef>
{
public LLVMValueRef Current { get; private set; }

readonly object IEnumerator.Current => Current;

readonly void IDisposable.Dispose()
{
}

public bool MoveNext()
{
if (Current.Handle == 0)
{
Current = module.FirstFunction;
}
else
{
Current = Current.NextFunction;
}
return Current.Handle != 0;
}

public void Reset() => Current = default;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// 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.

using System;
using System.Collections;
using System.Collections.Generic;

namespace LLVMSharp.Interop;

public readonly struct LLVMModuleGlobalAliasesEnumerable(LLVMModuleRef module) : IEnumerable<LLVMValueRef>
{
public Enumerator GetEnumerator() => new Enumerator(module);

IEnumerator<LLVMValueRef> IEnumerable<LLVMValueRef>.GetEnumerator() => GetEnumerator();

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

public struct Enumerator(LLVMModuleRef module) : IEnumerator<LLVMValueRef>
{
public LLVMValueRef Current { get; private set; }

readonly object IEnumerator.Current => Current;

readonly void IDisposable.Dispose()
{
}

public bool MoveNext()
{
if (Current.Handle == 0)
{
Current = module.FirstGlobalAlias;
}
else
{
Current = Current.NextGlobalAlias;
}
return Current.Handle != 0;
}

public void Reset() => Current = default;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// 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.

using System;
using System.Collections;
using System.Collections.Generic;

namespace LLVMSharp.Interop;

public readonly struct LLVMModuleGlobalIFuncsEnumerable(LLVMModuleRef module) : IEnumerable<LLVMValueRef>
{
public Enumerator GetEnumerator() => new Enumerator(module);

IEnumerator<LLVMValueRef> IEnumerable<LLVMValueRef>.GetEnumerator() => GetEnumerator();

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

public struct Enumerator(LLVMModuleRef module) : IEnumerator<LLVMValueRef>
{
public LLVMValueRef Current { get; private set; }

readonly object IEnumerator.Current => Current;

readonly void IDisposable.Dispose()
{
}

public bool MoveNext()
{
if (Current.Handle == 0)
{
Current = module.FirstGlobalIFunc;
}
else
{
Current = Current.NextGlobalIFunc;
}
return Current.Handle != 0;
}

public void Reset() => Current = default;
}
}
Loading
Loading