/// <summary>Create a constant array of values of a given type with a fixed size, zero filling any unspecified values</summary> /// <param name="elementType">Type of elements in the array</param> /// <param name="len">Length of the array</param> /// <param name="values">Values to initialize the array</param> /// <returns>Constant representing the array</returns> /// <remarks> /// If the number of arguments provided for the values is less than <paramref name="len"/> /// then the remaining elements of the array are set with the null value for the <paramref name="elementType"/> /// </remarks> public static Constant From(ITypeRef elementType, int len, params Constant[] values) { elementType.ValidateNotNull(nameof(elementType)); var zeroFilledValues = ZeroFill(elementType, len, values).ToList( ); return(From(elementType, zeroFilledValues)); }
/// <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>Initializes a new instance of the <see cref="DebugPointerType"/> class.</summary> /// <param name="llvmElementType">Native type of the pointee</param> /// <param name="module"><see cref="BitcodeModule"/> used for creating the pointer type and debug information</param> /// <param name="elementType">Debug type of the pointee</param> /// <param name="addressSpace">Target address space for the pointer [Default: 0]</param> /// <param name="name">Name of the type [Default: null]</param> /// <param name="alignment">Alignment of pointer</param> public DebugPointerType(ITypeRef llvmElementType, BitcodeModule module, DIType elementType, uint addressSpace = 0, string name = null, uint alignment = 0) : this(llvmElementType.ValidateNotNull(nameof(llvmElementType)).CreatePointerType(addressSpace) , module , elementType , name , alignment ) { }
/// <summary>Adds a global to this module</summary> /// <param name="typeRef">Type of the global's value</param> /// <param name="isConst">Flag to indicate if this global is a constant</param> /// <param name="linkage">Linkage type for this global</param> /// <param name="constVal">Initial value for the global</param> /// <returns>New global variable</returns> public GlobalVariable AddGlobal(ITypeRef typeRef, bool isConst, Linkage linkage, Constant constVal) { ValidateHandle( ); typeRef.ValidateNotNull(nameof(typeRef)); linkage.ValidateDefined(nameof(linkage)); constVal.ValidateNotNull(nameof(constVal)); return(AddGlobal(typeRef, isConst, linkage, constVal, string.Empty)); }
/// <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</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)); }
/// <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>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>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>Adds a global to this module</summary> /// <param name="typeRef">Type of the global's value</param> /// <param name="isConst">Flag to indicate if this global is a constant</param> /// <param name="linkage">Linkage type for this global</param> /// <param name="constVal">Initial value for the global</param> /// <param name="name">Name of the variable</param> /// <returns>New global variable</returns> public GlobalVariable AddGlobal(ITypeRef typeRef, bool isConst, Linkage linkage, Constant constVal, string name) { ValidateHandle( ); typeRef.ValidateNotNull(nameof(typeRef)); linkage.ValidateDefined(nameof(linkage)); constVal.ValidateNotNull(nameof(constVal)); name.ValidateNotNull(nameof(name)); var retVal = AddGlobal(typeRef, name); retVal.IsConstant = isConst; retVal.Linkage = linkage; retVal.Initializer = constVal; return(retVal); }
/// <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 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 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 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>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("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 = LLVMFunctionType(returnType.GetTypeRef( ), out llvmArgs[0], ( uint )argCount, isVarArgs); return(TypeRef.FromHandle <IFunctionType>(signature)); }
internal static LLVMTypeRef GetTypeRef([ValidatedNotNull] this ITypeRef self) { self.ValidateNotNull(nameof(self)); return((( ITypeHandleOwner )self).TypeHandle); }