Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
63 changes: 61 additions & 2 deletions sources/LLVMSharp.Interop/Extensions/LLVMAttributeRef.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,68 @@ public unsafe partial struct LLVMAttributeRef(IntPtr handle) : IEquatable<LLVMAt
{
public IntPtr Handle = handle;

public readonly uint Kind => LLVM.GetEnumAttributeKind(this);
/// <summary>
/// <see href="https://github.com/llvm/llvm-project/blob/a64e6f49284a7ffd5401183d0e94a94a7de39cfb/llvm/include/llvm/IR/Attributes.h#L233"/>
Comment thread
ds5678 marked this conversation as resolved.
Outdated
/// </summary>
public readonly bool HasKindAsEnum => Handle != IntPtr.Zero && LLVM.IsStringAttribute(this) == 0;
Comment thread
ds5678 marked this conversation as resolved.
Outdated

public readonly ulong Value => LLVM.GetEnumAttributeValue(this);
/// <summary>
/// <see href="https://github.com/llvm/llvm-project/blob/de7bac6426e7f544189dfba7ae658dcf3d7be5f6/llvm/lib/IR/Core.cpp#L231">This returns true for enum attributes and int attributes.</see>
/// </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();
}
}

/// <summary>
/// <see href="https://github.com/llvm/llvm-project/blob/a64e6f49284a7ffd5401183d0e94a94a7de39cfb/llvm/lib/IR/Core.cpp#L175"/>
/// </summary>
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,34 @@
// 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 record struct LLVMBasicBlockInstructionsEnumerable(LLVMBasicBlockRef BasicBlock) : IEnumerable<LLVMValueRef>
{
public Enumerator GetEnumerator() => new(BasicBlock);
Comment thread
ds5678 marked this conversation as resolved.
Outdated
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;
}
Comment thread
ds5678 marked this conversation as resolved.
}
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
93 changes: 93 additions & 0 deletions sources/LLVMSharp.Interop/Extensions/LLVMMetadataRef.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,99 @@ 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 IsType => Kind switch {
LLVMMetadataKind.LLVMDICompositeTypeMetadataKind => true,
LLVMMetadataKind.LLVMDIDerivedTypeMetadataKind => true,
LLVMMetadataKind.LLVMDIStringTypeMetadataKind => true,
LLVMMetadataKind.LLVMDIBasicTypeMetadataKind => true,
LLVMMetadataKind.LLVMDISubroutineTypeMetadataKind => true,
LLVMMetadataKind.LLVMDITemplateTypeParameterMetadataKind => 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 Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// 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 record struct LLVMModuleFunctionsEnumerable(LLVMModuleRef Module) : IEnumerable<LLVMValueRef>
Comment thread
ds5678 marked this conversation as resolved.
Outdated
{
public Enumerator GetEnumerator() => new(Module);
Comment thread
ds5678 marked this conversation as resolved.
Outdated
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,34 @@
// 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 record struct LLVMModuleGlobalAliasesEnumerable(LLVMModuleRef Module) : IEnumerable<LLVMValueRef>
{
public Enumerator GetEnumerator() => new(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,34 @@
// 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 record struct LLVMModuleGlobalIFuncsEnumerable(LLVMModuleRef Module) : IEnumerable<LLVMValueRef>
{
public Enumerator GetEnumerator() => new(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;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// 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 record struct LLVMModuleGlobalsEnumerable(LLVMModuleRef Module) : IEnumerable<LLVMValueRef>
{
public Enumerator GetEnumerator() => new(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.FirstGlobal;
}
else
{
Current = Current.NextGlobal;
}
return Current.Handle != 0;
}
public void Reset() => Current = default;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// 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 record struct LLVMModuleNamedMetadataEnumerable(LLVMModuleRef Module) : IEnumerable<LLVMNamedMDNodeRef>
{
public Enumerator GetEnumerator() => new(Module);
IEnumerator<LLVMNamedMDNodeRef> IEnumerable<LLVMNamedMDNodeRef>.GetEnumerator() => GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

public struct Enumerator(LLVMModuleRef module) : IEnumerator<LLVMNamedMDNodeRef>
{
public LLVMNamedMDNodeRef Current { get; private set; }
readonly object IEnumerator.Current => Current;
readonly void IDisposable.Dispose() { }
public bool MoveNext()
{
if (Current.Handle == 0)
{
Current = module.FirstNamedMetadata;
}
else
{
Current = Current.NextNamedMetadata;
}
return Current.Handle != 0;
}
public void Reset() => Current = default;
}
}
Loading
Loading