public void GetFunctionTypeTest1( ) { using (var context = new Context()) { Assert.IsNotNull(context); Assert.IsNotNull(context.Int32Type); Assert.IsNotNull(context.FloatType); Assert.IsNotNull(context.Int16Type); // i16 ( i32, float ) var argTypes = new ITypeRef[] { context.Int32Type, context.FloatType }; var funcSig = context.GetFunctionType(context.Int16Type, argTypes); Assert.IsNotNull(funcSig); Assert.AreSame(context, funcSig.Context); Assert.AreEqual(TypeKind.Function, funcSig.Kind); Assert.AreSame(context.Int16Type, funcSig.ReturnType); Assert.AreEqual(2, funcSig.ParameterTypes.Count); // verify additional properties created properly Assert.AreEqual(0U, funcSig.IntegerBitWidth); Assert.IsFalse(funcSig.IsDouble); Assert.IsFalse(funcSig.IsFloat); Assert.IsFalse(funcSig.IsFloatingPoint); Assert.IsFalse(funcSig.IsInteger); Assert.IsFalse(funcSig.IsPointer); Assert.IsFalse(funcSig.IsPointerPointer); Assert.IsFalse(funcSig.IsSequence); Assert.IsFalse(funcSig.IsSized); Assert.IsFalse(funcSig.IsStruct); Assert.IsFalse(funcSig.IsVarArg); Assert.IsFalse(funcSig.IsVoid); } }
/// <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 IMethodBuilder NewPublicMethod(string methodName, ITypeRef returnType, ITypeRef[] parameterTypes) { MethodDefinition method = NewMethod(methodName, parameterTypes, returnType); _type.Methods.Add(method); return(new CecilMethodBuilder(method)); }
private ITypeRef ArithmeticType(IComparisonOperand operand) { if (operand is ConstValue) { return(PrimitiveType(((ConstValue)operand).Value().GetType())); } if (operand is FieldValue) { return(((FieldValue)operand).Field.Type); } if (operand is ArithmeticExpression) { ArithmeticExpression expr = (ArithmeticExpression)operand; ITypeRef left = ArithmeticType(expr.Left()); ITypeRef right = ArithmeticType(expr.Right()); if (left == DoubleType() || right == DoubleType()) { return(DoubleType()); } if (left == FloatType() || right == FloatType()) { return(FloatType()); } if (left == LongType() || right == LongType()) { return(LongType()); } return(IntType()); } return(null); }
/// <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)); }
private static void VerifySized(ITypeRef type, string name) { if (!type.IsSized) { throw new ArgumentException("Type must be sized to get target size information", name); } }
/// <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) !); }
// FIXME: need to map dX,fX,... private void Box(ITypeRef boxedType, bool canApply) { if (!canApply) { return; } _methodBuilder.Box(boxedType); }
public StaticFieldRoot(ITypeRef type) { if (null == type) { throw new ArgumentNullException(); } _type = type; }
public static Constant BitCast(Constant value, ITypeRef toType) { value.ValidateNotNull(nameof(value)); var handle = LLVMConstBitCast(value.ValueHandle, toType.GetTypeRef( )); return(FromHandle <Constant>(handle)); }
/// <summary> /// Creates a new array value of the given length. Expects a value of type i64 for the length of the array. /// Registers the value with the scope manager, unless registerWithScopeManager is set to false. /// </summary> /// <param name="length">Value of type i64 indicating the number of elements in the array</param> /// <param name="elementType">Q# type of the array elements</param> /// <param name="context">Generation context where constants are defined and generated if needed</param> internal ArrayValue(Value length, ResolvedType elementType, GenerationContext context, bool registerWithScopeManager = true) { this.sharedState = context; this.QSharpElementType = elementType; this.LlvmElementType = context.LlvmTypeFromQsharpType(elementType); this.length = this.CreateLengthCache(length); this.OpaquePointer = this.AllocateArray(registerWithScopeManager); }
/// <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>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>Constructs a new <see cref="DebugPointerType"/></summary> /// <param name="llvmElementType">Native type of the pointee</param> /// <param name="module"><see cref="NativeModule"/> 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, NativeModule module, DIType elementType, uint addressSpace = 0, string name = null, uint alignment = 0) : this(llvmElementType.VerifyArgNotNull(nameof(llvmElementType)).CreatePointerType(addressSpace) , module , elementType , name , alignment ) { }
/// <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="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="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="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="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 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); }
public void Box(ITypeRef boxedType) { TypeReference type = CecilTypeRef.GetReference(boxedType); if (!type.IsValueType) { return; } _il.Emit(OpCodes.Box, type); }
/// <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); }
public override bool Equals(object obj) { if (!(obj is ITypeRef)) { return(false); } ITypeRef other = (ITypeRef)obj; return(IsPrimitive == other.IsPrimitive && Name.Equals(other.Name)); }
/// <summary> /// Creates a new array value from the given opaque array of elements of the given type. /// </summary> /// <param name="array">The opaque pointer to the array data structure</param> /// <param name="length">Value of type i64 indicating the number of elements in the array; will be computed on demand if the given value is null</param> /// <param name="elementType">Q# type of the array elements</param> /// <param name="context">Generation context where constants are defined and generated if needed</param> internal ArrayValue(Value array, Value?length, ResolvedType elementType, GenerationContext context) { this.sharedState = context; this.QSharpElementType = elementType; this.LlvmElementType = context.LlvmTypeFromQsharpType(elementType); this.OpaquePointer = Types.IsArray(array.NativeType) ? array : throw new ArgumentException("expecting an opaque array"); this.length = length == null ? new IValue.Cached <Value>(context, this.GetLength) : this.CreateLengthCache(length); }
/// <summary> /// Gets string representation of types contained in given type mask. /// </summary> public string ToString(TypeRefMask mask) { if (!mask.IsVoid) { if (mask.IsAnyType) { return(TypeRefMask.MixedTypeName); } // var types = new List <string>(1); // handle arrays separately var arrmask = mask & _isArrayMask; if (arrmask != 0) { mask &= ~_isArrayMask; ITypeRef elementtype = null; var elementmask = GetElementType(arrmask); if (elementmask.IsSingleType) { elementtype = GetTypes(elementmask).FirstOrDefault(); } if (elementtype != null) { types.Add(elementtype.QualifiedName.ToString() + "[]"); } else { types.Add(TypeRefFactory.ArrayTypeRef.QualifiedName.ToString()); } } //// int|double => number //var isNumber = (_isIntMask != 0 && _isDoubleMask != 0 && (mask & IsNumberMask) == IsNumberMask); //if (isNumber) // mask &= ~IsNumberMask; // types.AddRange(GetTypes(mask).Select(t => t.QualifiedName.ToString())); //if (isNumber) // types.Add("number"); // if (types.Count != 0) { types.Sort(); return(string.Join(PHPDocBlock.TypeVarDescTag.TypeNamesSeparator.ToString(), types.Distinct())); } } return(TypeRefMask.VoidTypeName); }
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)); }
public virtual void InjectOptimization(IExpression expr) { _editor.AddInterface(TypeRef(typeof(IDb4oEnhancedFilter))); _builder = _editor.NewPublicMethod(PlatformName(OptimizeQueryMethodName), TypeRef (typeof(void)), new ITypeRef[] { TypeRef(typeof(IQuery)) }); ITypeRef predicateClass = _editor.Type; expr.Accept(new SODAMethodBuilder.SODAExpressionBuilder(this, predicateClass)); _builder.Pop(); _builder.EndMethod(); }
/// <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( )) !); }
private static MethodDefinition NewMethod(string methodName, ITypeRef[] parameterTypes, ITypeRef returnType) { var method = new MethodDefinition(methodName, MethodAttributes.Virtual | MethodAttributes.Public, GetTypeReference(returnType)); foreach (var paramType in parameterTypes) { method.Parameters.Add(new ParameterDefinition(GetTypeReference(paramType))); } return method; }
/// <summary>Adds a global to this module</summary> /// <param name="typeRef">Type of the 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) { ThrowIfDisposed( ); var retVal = AddGlobal(typeRef, name); retVal.IsConstant = isConst; retVal.Linkage = linkage; retVal.Initializer = constVal; return(retVal); }
public MockFieldRef(string name, ITypeRef typeRef) { if (null == name) { throw new ArgumentNullException(); } if (null == typeRef) { throw new ArgumentNullException(); } _name = name; _type = typeRef; }
public virtual void Visit(ConstValue operand) { var value = operand.Value(); if (value != null) { _opClass = TypeRef(value.GetType()); } _methodBuilder.Ldc(value); if (value != null) { Box(_opClass, !_inArithmetic); } }
public virtual void Visit(FieldValue fieldValue) { var lastFieldClass = fieldValue.Field.Type; var needConversion = lastFieldClass.IsPrimitive; fieldValue.Parent().Accept(this); if (_staticRoot != null) { _methodBuilder.LoadStaticField(fieldValue.Field); _staticRoot = null; return; } _methodBuilder.LoadField(fieldValue.Field); Box(lastFieldClass, !_inArithmetic && needConversion); }
public IMethodBuilder NewPublicMethod(string methodName, ITypeRef returnType, ITypeRef[] parameterTypes) { var method = NewMethod(methodName, parameterTypes, returnType); _type.Methods.Add(method); return new CecilMethodBuilder(method); }
/// <summary> /// Helper method that builds <see cref="TypeRefMask"/> for given type in this context. /// </summary> public TypeRefMask GetTypeMask(ITypeRef/*!*/typeref, bool includesSubclasses) { var index = AddToContext(typeref); var mask = TypeRefMask.CreateFromTypeIndex(index); if (includesSubclasses && typeref.IsObject) mask.SetIncludesSubclasses(); return mask; }
/// <summary> /// Updates internal masks for newly added type. /// </summary> /// <param name="typeRef">Type.</param> /// <param name="index">Type index.</param> private void UpdateMasks(ITypeRef/*!*/typeRef, int index) { Debug.Assert(index >= 0 && index < TypeRefMask.IndicesCount); ulong mask = (ulong)1 << index; if (typeRef.IsObject) _isObjectMask |= mask; if (typeRef.IsArray) _isArrayMask |= mask; if (typeRef.IsLambda) _isLambdaMask |= mask; if (typeRef.IsPrimitiveType) { _isPrimitiveMask |= mask; switch (typeRef.TypeCode) { case PhpTypeCode.Boolean: _isBoolMask = mask; break; case PhpTypeCode.Long: _isLongMask |= mask; break; case PhpTypeCode.Double: _isDoubleMask = mask; break; case PhpTypeCode.String: _isStringMask = mask; break; case PhpTypeCode.WritableString: _isWritableStringMask = mask; break; } } }
public void AddInterface(ITypeRef type) { _type.Interfaces.Add(GetTypeReference(type)); }
/// <summary> /// Ensures given type is in the context. /// </summary> /// <param name="typeRef">Type reference to be in the context.</param> /// <returns>Index of the type within the context. Can return <c>-1</c> if there is too many types in the context already.</returns> public int AddToContext(ITypeRef/*!*/typeRef) { Contract.ThrowIfNull(typeRef); var types = _typeRefs; var index = this.GetTypeIndex(typeRef); if (index < 0 && this.Types.Count < TypeRefMask.IndicesCount) index = this.AddToContextNoCheck(typeRef); // return index; }
private int AddToContextNoCheck(ITypeRef/*!*/typeRef) { Contract.ThrowIfNull(typeRef); Debug.Assert(_typeRefs.IndexOf(typeRef) == -1); int index = _typeRefs.Count; this.UpdateMasks(typeRef, index); _typeRefs.Add(typeRef); // return index; }
public SODAExpressionBuilder(SODAMethodBuilder _enclosing, ITypeRef predicateClass ) { this._enclosing = _enclosing; this.predicateClass = predicateClass; }
public void Modulo(ITypeRef operandType) { throw new NotImplementedException(); }
public void LoadArrayElement(ITypeRef elementType) { throw new NotImplementedException(); }
public void Multiply(ITypeRef operandType) { throw new NotImplementedException(); }
public virtual void Visit(ConstValue operand) { _clazz = _referenceProvider.ForType(operand.Value().GetType()); }
public ComparisonBytecodeGeneratingVisitor(IMethodBuilder methodBuilder, ITypeRef predicateClass) { _methodBuilder = methodBuilder; _predicateClass = predicateClass; }
private static TypeReference GetTypeReference(ITypeRef type) { return CecilTypeRef.GetReference(type); }
public virtual void Visit(FieldValue operand) { _clazz = operand.Field.Type; }
public static TypeRefMask CreateMask(TypeRefContext ctx, ITypeRef tref) { Contract.ThrowIfNull(tref); TypeRefMask result = 0; result.AddType(ctx.AddToContext(tref)); if (!tref.IsPrimitiveType && !tref.IsArray) { result.IncludesSubclasses = true; } return result; }
public virtual void Visit(MethodCallValue operand) { _clazz = operand.Method.ReturnType; }
// _clazz=_candidateClass; public virtual void Visit(StaticFieldRoot root) { _clazz = root.Type; }
public virtual void Visit(StaticFieldRoot root) { _staticRoot = root.Type; }
public void Divide(ITypeRef operandType) { throw new NotImplementedException(); }
public IMethodRef ForMethod(ITypeRef declaringType, string methodName, ITypeRef[] parameterTypes, ITypeRef returnType) { throw new NotImplementedException(); }
public void Box(ITypeRef boxedType) { var type = CecilTypeRef.GetReference(boxedType); if (!type.IsValueType) return; _il.Emit(OpCodes.Box, type); }
public virtual void Visit(ArrayAccessValue operand) { operand.Parent().Accept(this); _clazz = _clazz.ElementType; }
public void Subtract(ITypeRef operandType) { throw new NotImplementedException(); }
/// <summary> /// Gets index of the given type within the context. Returns <c>-1</c> if such type is not present. /// </summary> public int GetTypeIndex(ITypeRef/*!*/typeref) { return _typeRefs.IndexOf(typeref); }