예제 #1
0
        /// <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));
        }
예제 #2
0
        /// <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) !);
            }
        }
예제 #3
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)
        {
            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));
        }
예제 #4
0
        public static Constant BitCast(Constant value, ITypeRef toType)
        {
            value.ValidateNotNull(nameof(value));

            var handle = LLVMConstBitCast(value.ValueHandle, toType.GetTypeRef( ));

            return(FromHandle <Constant>(handle));
        }
예제 #5
0
        /// <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) !);
        }
예제 #6
0
        /// <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) !);
        }
예제 #7
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.Context != this)
            {
                throw new ArgumentException( );
            }

            return(TypeRef.FromHandle <IPointerType>(LLVM.PointerType(elementType.GetTypeRef( ), 0)));
        }
예제 #8
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);
        }
예제 #9
0
        /// <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));
        }
예제 #10
0
        /// <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);
        }
예제 #11
0
        /// <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));
        }
예제 #12
0
        /// <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));
        }
예제 #13
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)
        {
            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);
        }
예제 #14
0
        /// <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);
        }
예제 #15
0
        /// <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));
        }
예제 #16
0
        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));
        }
예제 #17
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)
        {
            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( )) !);
        }
예제 #18
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)
        {
            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)));
        }
예제 #19
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)));
        }
예제 #20
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));
        }
예제 #21
0
        /// <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())) !);
        }
예제 #22
0
        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( ))));
        }
예제 #23
0
        /// <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));
        }
예제 #24
0
        /// <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)));
        }
예제 #25
0
        /// <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)));
        }
예제 #26
0
        /// <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( )) !);
        }
예제 #27
0
        /// <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( ))));
        }
예제 #28
0
        /// <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));
        }
예제 #29
0
 /// <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( )));
 }
예제 #30
0
 /// <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( )));
 }