/// <summary>Create a constant array of values of a given type</summary> /// <param name="elementType">Type of elements in the array</param> /// <param name="values">Values to initialize the array</param> /// <returns>Constant representing the array</returns> public static Constant From(ITypeRef elementType, IList <Constant> values) { if (values.Any(v => v.NativeType.GetTypeRef() != elementType.GetTypeRef( ))) { throw new ArgumentException("One or more value(s) types do not match specified array element type"); } var valueHandles = values.Select(v => v.ValueHandle).ToArray( ); var handle = LLVMConstArray(elementType.GetTypeRef(), valueHandles, (uint)valueHandles.Length); return(FromHandle <Constant>(handle)); }
/// <summary>Create a constant array of values of a given type</summary> /// <param name="elementType">Type of elements in the array</param> /// <param name="values">Values to initialize the array</param> /// <returns>Constant representing the array</returns> public static unsafe Constant From(ITypeRef elementType, IList <Constant> values) { if (values.Any(v => v.NativeType.GetTypeRef( ) != elementType.GetTypeRef( ))) { throw new ArgumentException("One or more value(s) types do not match specified array element type"); } var valueHandles = values.Select(v => v.ValueHandle).ToArray( ); fixed(LLVMValueRef *pValueHandles = valueHandles.AsSpan( )) { var handle = LLVM.ConstArray(elementType.GetTypeRef(), (LLVMOpaqueValue **)pValueHandles, (uint)valueHandles.Length); return(FromHandle <Constant>(handle) !); } }
/// <summary>Get an LLVM Function type (e.g. signature)</summary> /// <param name="returnType">Return type of the function</param> /// <param name="args">Potentially empty set of function argument types</param> /// <param name="isVarArgs">Flag to indicate if the method supports C/C++ style VarArgs</param> /// <returns>Signature type for the specified signature</returns> public IFunctionType GetFunctionType(ITypeRef returnType, IEnumerable <ITypeRef> args, bool isVarArgs) { if (returnType == null) { throw new ArgumentNullException(nameof(returnType)); } if (ContextHandle.Pointer != returnType.Context.ContextHandle.Pointer) { throw new ArgumentException("Mismatched context", nameof(returnType)); } LLVMTypeRef[] llvmArgs = args.Select(a => a.GetTypeRef( )).ToArray( ); int argCount = llvmArgs.Length; // have to pass a valid addressable object to native interop // so allocate space for a single value but tell LLVM the length is 0 if (llvmArgs.Length == 0) { llvmArgs = new LLVMTypeRef[1]; } var signature = NativeMethods.FunctionType(returnType.GetTypeRef( ), out llvmArgs[0], ( uint )argCount, isVarArgs); return(TypeRef.FromHandle <IFunctionType>(signature)); }
public static Constant BitCast(Constant value, ITypeRef toType) { value.ValidateNotNull(nameof(value)); var handle = LLVMConstBitCast(value.ValueHandle, toType.GetTypeRef( )); return(FromHandle <Constant>(handle)); }
/// <summary>Adds a global to this module with a specific address space</summary> /// <param name="addressSpace">Address space to add the global to</param> /// <param name="typeRef">Type of the value</param> /// <param name="name">Name of the global</param> /// <returns>The new <see cref="GlobalVariable"/></returns> /// <openissues> /// - What does LLVM do if creating a second Global with the same name (return null, throw, crash??,...) /// </openissues> public GlobalVariable AddGlobalInAddressSpace(uint addressSpace, ITypeRef typeRef, string name) { ThrowIfDisposed( ); var handle = ModuleHandle.AddGlobalInAddressSpace(typeRef.GetTypeRef( ), name, addressSpace); return(Value.FromHandle <GlobalVariable>(handle) !); }
/// <summary>Adds a global to this module</summary> /// <param name="typeRef">Type of the value</param> /// <param name="name">Name of the global</param> /// <returns>The new <see cref="GlobalVariable"/></returns> /// <openissues> /// - What does LLVM do if creating a second Global with the same name (return null, throw, crash??,...) /// </openissues> public GlobalVariable AddGlobal(ITypeRef typeRef, string name) { ThrowIfDisposed( ); var handle = ModuleHandle.AddGlobal(typeRef.GetTypeRef( ), name); return(Value.FromHandle <GlobalVariable>(handle) !); }
/// <summary>Get a type that is a pointer to a value of a given type</summary> /// <param name="elementType">Type of value the pointer points to</param> /// <returns><see cref="IPointerType"/> for a pointer that references a value of type <paramref name="elementType"/></returns> public IPointerType GetPointerTypeFor(ITypeRef elementType) { if (elementType.Context != this) { throw new ArgumentException( ); } return(TypeRef.FromHandle <IPointerType>(LLVM.PointerType(elementType.GetTypeRef( ), 0))); }
/// <summary>Initializes a new instance of the <see cref="GenericValue"/> class with a floating point value</summary> /// <param name="t">LLVM type describing the floating point format</param> /// <param name="value">floating point value</param> public GenericValue(ITypeRef t, double value) { if (!t.ValidateNotNull(nameof(t)).IsFloatingPoint) { throw new ArgumentException(Resources.Type_must_be_a_floating_point_data_type, nameof(t)); } Handle = LLVMCreateGenericValueOfFloat(t.GetTypeRef( ), value); }
/// <summary>Creates a new <see cref="ConstantInt"/> with a bit length of 1</summary> /// <param name="constValue">Value for the constant</param> /// <returns><see cref="ConstantInt"/> representing the value</returns> public Constant CreateConstant(bool constValue) { var handle = NativeMethods.ConstInt(BoolType.GetTypeRef( ) , ( ulong )(constValue ? 1 : 0) , false ); return(Value.FromHandle <Constant>(handle)); }
/// <summary>Initializes a new instance of the <see cref="GenericValue"/> class with an integer value</summary> /// <param name="t">LLVM type describing the integer bit width</param> /// <param name="value">integer value</param> /// <param name="isSigned">Indicates if the value is signed</param> public GenericValue(ITypeRef t, UInt64 value, bool isSigned) { if (!t.ValidateNotNull(nameof(t)).IsInteger) { throw new ArgumentException(Resources.Type_must_be_an_integral_data_type, nameof(t)); } Handle = LLVMCreateGenericValueOfInt(t.GetTypeRef( ), value, isSigned); }
/// <summary>Adds a global to this module with a specific address space</summary> /// <param name="addressSpace">Address space to add the global to</param> /// <param name="typeRef">Type of the global's value</param> /// <param name="name">Name of the global</param> /// <returns>The new <see cref="GlobalVariable"/></returns> /// <openissues> /// - What does LLVM do if creating a second Global with the same name (return null, throw, crash??,...) /// </openissues> public GlobalVariable AddGlobalInAddressSpace(uint addressSpace, ITypeRef typeRef, string name) { ValidateHandle( ); typeRef.ValidateNotNull(nameof(typeRef)); name.ValidateNotNullOrWhiteSpace(nameof(name)); var handle = LLVMAddGlobalInAddressSpace(ModuleHandle, typeRef.GetTypeRef( ), name, addressSpace); return(Value.FromHandle <GlobalVariable>(handle)); }
/// <summary>Create a constant array of values of a given type</summary> /// <param name="elementType">Type of elements in the array</param> /// <param name="values">Values to initialize the array</param> /// <returns>Constant representing the array</returns> public static Constant From(ITypeRef elementType, IList <Constant> values) { if (values.Any(v => v.NativeType.GetTypeRef() != elementType.GetTypeRef( ))) { throw new ArgumentException("One or more value(s) types do not match specified array element type"); } var valueHandles = values.Select(v => v.ValueHandle).ToArray( ); int argCount = valueHandles.Length; if (argCount == 0) { valueHandles = new LLVMValueRef[1]; } var handle = NativeMethods.LLVMConstArray(elementType.GetTypeRef(), out valueHandles[0], (uint)argCount); return(FromHandle <Constant>(handle)); }
/// <summary>Initializes a new instance of the <see cref="GenericValue"/> class with a floating point value</summary> /// <param name="t">LLVM type describing the floating point format</param> /// <param name="value">floating point value</param> public GenericValue(ITypeRef t, double value) { t.ValidateNotNull(nameof(t)); if (!t.IsFloatingPoint) { throw new ArgumentException("Type must be a floating point data type", nameof(t)); } Handle = LLVMCreateGenericValueOfFloat(t.GetTypeRef( ), value); }
/// <summary>Initializes a new instance of the <see cref="GenericValue"/> class with an integer value</summary> /// <param name="t">LLVM type describing the integer bit width</param> /// <param name="value">integer value</param> /// <param name="isSigned">Indicates if the value is signed</param> public GenericValue(ITypeRef t, UInt64 value, bool isSigned) { t.ValidateNotNull(nameof(t)); if (!t.IsInteger) { throw new ArgumentException("Type must be an integral data type", nameof(t)); } Handle = LLVMCreateGenericValueOfInt(t.GetTypeRef( ), value, isSigned); }
/// <summary>Adds a global to this module</summary> /// <param name="typeRef">Type of the global's value</param> /// <param name="name">Name of the global</param> /// <returns>The new <see cref="GlobalVariable"/></returns> /// <openissues> /// - What does LLVM do if creating a second Global with the same name (return null, throw, crash??,...) /// </openissues> public GlobalVariable AddGlobal(ITypeRef typeRef, string name) { ValidateHandle( ); typeRef.ValidateNotNull(nameof(typeRef)); name.ValidateNotNull(nameof(name)); var handle = LLVMAddGlobal(ModuleHandle, typeRef.GetTypeRef( ), name); return(Value.FromHandle <GlobalVariable>(handle)); }
public static Constant BitCast(Constant value, ITypeRef toType) { if (value == null) { throw new ArgumentNullException(nameof(value)); } var handle = NativeMethods.ConstBitCast(value.ValueHandle, toType.GetTypeRef( )); return(FromHandle <Constant>(handle)); }
/// <summary>Get a type that is a pointer to a value of a given type</summary> /// <param name="elementType">Type of value the pointer points to</param> /// <returns><see cref="IPointerType"/> for a pointer that references a value of type <paramref name="elementType"/></returns> public IPointerType GetPointerTypeFor(ITypeRef elementType) { elementType.ValidateNotNull(nameof(elementType)); if (elementType.Context != this) { throw new ArgumentException(Resources.Cannot_mix_types_from_different_contexts, nameof(elementType)); } return(TypeRef.FromHandle <IPointerType>(LLVMPointerType(elementType.GetTypeRef( ), 0).ThrowIfInvalid( )) !); }
/// <summary>Get a type that is a pointer to a value of a given type</summary> /// <param name="elementType">Type of value the pointer points to</param> /// <returns><see cref="IPointerType"/> for a pointer that references a value of type <paramref name="elementType"/></returns> public IPointerType GetPointerTypeFor(ITypeRef elementType) { elementType.ValidateNotNull(nameof(elementType)); if (elementType.Context != this) { throw new ArgumentException("Cannot mix types from different contexts", nameof(elementType)); } return(TypeRef.FromHandle <IPointerType>(LLVMPointerType(elementType.GetTypeRef( ), 0))); }
/// <summary>Get a type that is a pointer to a value of a given type</summary> /// <param name="elementType">Type of value the pointer points to</param> /// <returns><see cref="IPointerType"/> for a pointer that references a value of type <paramref name="elementType"/></returns> public IPointerType GetPointerTypeFor(ITypeRef elementType) { if (elementType == null) { throw new ArgumentNullException(nameof(elementType)); } if (elementType.Context != this) { throw new ArgumentException("Cannot mix types from different contexts", nameof(elementType)); } return(TypeRef.FromHandle <IPointerType>(NativeMethods.PointerType(elementType.GetTypeRef( ), 0))); }
/// <summary>Get an LLVM Function type (e.g. signature)</summary> /// <param name="returnType">Return type of the function</param> /// <param name="args">Potentially empty set of function argument types</param> /// <param name="isVarArgs">Flag to indicate if the method supports C/C++ style VarArgs</param> /// <returns>Signature type for the specified signature</returns> public IFunctionType GetFunctionType(ITypeRef returnType, IEnumerable <ITypeRef> args, bool isVarArgs) { returnType.ValidateNotNull(nameof(returnType)); args.ValidateNotNull(nameof(args)); if (ContextHandle != returnType.Context.ContextHandle) { throw new ArgumentException(Resources.Mismatched_context, nameof(returnType)); } LLVMTypeRef[] llvmArgs = args.Select(a => a.GetTypeRef( )).ToArray( ); var signature = LLVMFunctionType(returnType.GetTypeRef( ), llvmArgs, ( uint )llvmArgs.Length, isVarArgs); return(TypeRef.FromHandle <IFunctionType>(signature)); }
/// <summary>Create a NULL pointer for a given type.</summary> /// <param name="typeRef">Type of pointer to create a null vale for.</param> /// <returns>Constant NULL pointer of the specified type.</returns> public static Constant NullValueFor(ITypeRef typeRef) { if (typeRef == default) { throw new ArgumentNullException(nameof(typeRef)); } var kind = typeRef.Kind; if (kind == TypeKind.Label || kind == TypeKind.Function || (typeRef is StructType structType && structType.IsOpaque)) { throw new ArgumentException(); } return(FromHandle <Constant>(LLVM.ConstNull(typeRef.GetTypeRef())) !); }
public static Constant IntToPtrExpression(Constant value, ITypeRef type) { value.ValidateNotNull(nameof(value)); if (value.NativeType.Kind != TypeKind.Integer) { throw new ArgumentException(Resources.Integer_type_expected, nameof(value)); } if (!(type is IPointerType)) { throw new ArgumentException(Resources.Pointer_type_expected, nameof(type)); } return(FromHandle <Constant>(LLVMConstIntToPtr(value.ValueHandle, type.GetTypeRef( )))); }
/// <summary>Create an anonymous structure type (e.g. Tuple)</summary> /// <param name="packed">Flag to indicate if the structure is "packed"</param> /// <param name="element0">Type of the first field of the structure</param> /// <param name="elements">Types of any additional fields of the structure</param> /// <returns> /// <see cref="IStructType"/> with the specified body defined. /// </returns> public IStructType CreateStructType(bool packed, [ValidatedNotNull] ITypeRef element0, params ITypeRef[] elements) { element0.ValidateNotNull(nameof(element0)); elements.ValidateNotNull(nameof(elements)); LLVMTypeRef[] llvmArgs = new LLVMTypeRef[elements.Length + 1]; llvmArgs[0] = element0.GetTypeRef( ); for (int i = 1; i < llvmArgs.Length; ++i) { llvmArgs[i] = elements[i - 1].GetTypeRef( ); } var handle = LLVMStructTypeInContext(ContextHandle, out llvmArgs[0], ( uint )llvmArgs.Length, packed); return(TypeRef.FromHandle <IStructType>(handle)); }
/// <summary>Create a constant value of the specified integer type</summary> /// <param name="intType">Integer type</param> /// <param name="constValue">value</param> /// <param name="signExtend">flag to indicate if <paramref name="constValue"/> is sign extended</param> /// <returns>Constant for the specified value</returns> public Constant CreateConstant(ITypeRef intType, UInt64 constValue, bool signExtend) { intType.ValidateNotNull(nameof(intType)); if (intType.Context != this) { throw new ArgumentException("Cannot mix types from different contexts", nameof(intType)); } if (intType.Kind != TypeKind.Integer) { throw new ArgumentException("Integer type required", nameof(intType)); } return(Value.FromHandle <Constant>(LLVMConstInt(intType.GetTypeRef( ), constValue, signExtend))); }
/// <summary>Create a constant value of the specified integer type</summary> /// <param name="intType">Integer type</param> /// <param name="constValue">value</param> /// <param name="signExtend">flag to indicate if <paramref name="constValue"/> is sign extended</param> /// <returns>Constant for the specified value</returns> public Constant CreateConstant(ITypeRef intType, UInt64 constValue, bool signExtend) { intType.ValidateNotNull(nameof(intType)); if (intType.Context != this) { throw new ArgumentException(Resources.Cannot_mix_types_from_different_contexts, nameof(intType)); } if (intType.Kind != TypeKind.Integer) { throw new ArgumentException(Resources.Integer_type_required, nameof(intType)); } return(Value.FromHandle <Constant>(LLVMConstInt(intType.GetTypeRef( ), constValue, signExtend))); }
/// <summary>Create a NULL pointer for a given type</summary> /// <param name="typeRef">Type of pointer to create a null vale for</param> /// <returns>Constant NULL pointer of the specified type</returns> public static Constant NullValueFor(ITypeRef typeRef) { if (typeRef == null) { throw new ArgumentNullException(nameof(typeRef)); } var kind = typeRef.Kind; if (kind == TypeKind.Label || kind == TypeKind.Function || (typeRef is StructType structType && structType.IsOpaque)) { throw new ArgumentException(Resources.Cannot_get_null_for_labels_and_opaque_types); } return(FromHandle <Constant>(LLVMConstNull(typeRef.GetTypeRef( )).ThrowIfInvalid( )) !); }
/// <summary>Create a NULL pointer for a given type</summary> /// <param name="typeRef">Type of pointer to create a null vale for</param> /// <returns>Constant NULL pointer of the specified type</returns> public static Constant NullValueFor(ITypeRef typeRef) { if (typeRef == null) { throw new ArgumentNullException(nameof(typeRef)); } var kind = typeRef.Kind; var structType = typeRef as StructType; if (kind == TypeKind.Label || kind == TypeKind.Function || (structType != null && structType.IsOpaque)) { throw new ArgumentException("Cannot get a Null value for labels, functions and opaque types"); } return(FromHandle <Constant>(NativeMethods.LLVMConstNull(typeRef.GetTypeRef( )))); }
/// <summary>Create an anonymous structure type (e.g. Tuple)</summary> /// <param name="packed">Flag to indicate if the structure is "packed"</param> /// <param name="element0">Type of the first field of the structure</param> /// <param name="elements">Types of any additional fields of the structure</param> /// <returns> /// <see cref="IStructType"/> with the specified body defined. /// </returns> public IStructType CreateStructType(bool packed, ITypeRef element0, params ITypeRef[] elements) { if (elements == null) { throw new ArgumentNullException(nameof(elements)); } LLVMTypeRef[] llvmArgs = new LLVMTypeRef[elements.Length + 1]; llvmArgs[0] = element0.GetTypeRef( ); for (int i = 1; i < llvmArgs.Length; ++i) { llvmArgs[i] = elements[i - 1].GetTypeRef( ); } var handle = NativeMethods.StructTypeInContext(ContextHandle, out llvmArgs[0], ( uint )llvmArgs.Length, packed); return(TypeRef.FromHandle <IStructType>(handle)); }
/// <summary>Gets the preferred alignment for an LLVM type</summary> /// <param name="typeRef">Type to get the alignment of</param> /// <returns>Preferred alignment</returns> public uint PreferredAlignmentOf(ITypeRef typeRef) { VerifySized(typeRef, nameof(typeRef)); return(LLVMPreferredAlignmentOfType(DataLayoutHandle, typeRef.GetTypeRef( ))); }
/// <summary>Retrieves the ABI specified size of the given type</summary> /// <param name="typeRef">Type to get the size from</param> /// <returns>Size of the type</returns> /// <remarks> /// Returns the offset in bytes between successive objects of the /// specified type, including alignment padding /// </remarks> public ulong AbiSizeOf(ITypeRef typeRef) { VerifySized(typeRef, nameof(typeRef)); return(LLVMABISizeOfType(DataLayoutHandle, typeRef.GetTypeRef( ))); }