// <summary> // This routine will attempt to simplify the unary expression when the // argument is a constant. // </summary> Constant TryReduceConstant (ResolveContext ec, Constant e) { if (e is EmptyConstantCast) return TryReduceConstant (ec, ((EmptyConstantCast) e).child); if (e is SideEffectConstant) { Constant r = TryReduceConstant (ec, ((SideEffectConstant) e).value); return r == null ? null : new SideEffectConstant (r, e, r.Location); } Type expr_type = e.Type; switch (Oper){ case Operator.UnaryPlus: // Unary numeric promotions if (expr_type == TypeManager.byte_type) return new IntConstant (((ByteConstant)e).Value, e.Location); if (expr_type == TypeManager.sbyte_type) return new IntConstant (((SByteConstant)e).Value, e.Location); if (expr_type == TypeManager.short_type) return new IntConstant (((ShortConstant)e).Value, e.Location); if (expr_type == TypeManager.ushort_type) return new IntConstant (((UShortConstant)e).Value, e.Location); if (expr_type == TypeManager.char_type) return new IntConstant (((CharConstant)e).Value, e.Location); // Predefined operators if (expr_type == TypeManager.int32_type || expr_type == TypeManager.uint32_type || expr_type == TypeManager.int64_type || expr_type == TypeManager.uint64_type || expr_type == TypeManager.float_type || expr_type == TypeManager.double_type || expr_type == TypeManager.decimal_type) { return e; } return null; case Operator.UnaryNegation: // Unary numeric promotions if (expr_type == TypeManager.byte_type) return new IntConstant (-((ByteConstant)e).Value, e.Location); if (expr_type == TypeManager.sbyte_type) return new IntConstant (-((SByteConstant)e).Value, e.Location); if (expr_type == TypeManager.short_type) return new IntConstant (-((ShortConstant)e).Value, e.Location); if (expr_type == TypeManager.ushort_type) return new IntConstant (-((UShortConstant)e).Value, e.Location); if (expr_type == TypeManager.char_type) return new IntConstant (-((CharConstant)e).Value, e.Location); // Predefined operators if (expr_type == TypeManager.int32_type) { int value = ((IntConstant)e).Value; if (value == int.MinValue) { if (ec.ConstantCheckState) { ConstantFold.Error_CompileTimeOverflow (ec, loc); return null; } return e; } return new IntConstant (-value, e.Location); } if (expr_type == TypeManager.int64_type) { long value = ((LongConstant)e).Value; if (value == long.MinValue) { if (ec.ConstantCheckState) { ConstantFold.Error_CompileTimeOverflow (ec, loc); return null; } return e; } return new LongConstant (-value, e.Location); } if (expr_type == TypeManager.uint32_type) { UIntLiteral uil = e as UIntLiteral; if (uil != null) { if (uil.Value == 2147483648) return new IntLiteral (int.MinValue, e.Location); return new LongLiteral (-uil.Value, e.Location); } return new LongConstant (-((UIntConstant)e).Value, e.Location); } if (expr_type == TypeManager.uint64_type) { ULongLiteral ull = e as ULongLiteral; if (ull != null && ull.Value == 9223372036854775808) return new LongLiteral (long.MinValue, e.Location); return null; } if (expr_type == TypeManager.float_type) { FloatLiteral fl = e as FloatLiteral; // For better error reporting if (fl != null) return new FloatLiteral (-fl.Value, e.Location); return new FloatConstant (-((FloatConstant)e).Value, e.Location); } if (expr_type == TypeManager.double_type) { DoubleLiteral dl = e as DoubleLiteral; // For better error reporting if (dl != null) return new DoubleLiteral (-dl.Value, e.Location); return new DoubleConstant (-((DoubleConstant)e).Value, e.Location); } if (expr_type == TypeManager.decimal_type) return new DecimalConstant (-((DecimalConstant)e).Value, e.Location); return null; case Operator.LogicalNot: if (expr_type != TypeManager.bool_type) return null; bool b = (bool)e.GetValue (); return new BoolConstant (!b, e.Location); case Operator.OnesComplement: // Unary numeric promotions if (expr_type == TypeManager.byte_type) return new IntConstant (~((ByteConstant)e).Value, e.Location); if (expr_type == TypeManager.sbyte_type) return new IntConstant (~((SByteConstant)e).Value, e.Location); if (expr_type == TypeManager.short_type) return new IntConstant (~((ShortConstant)e).Value, e.Location); if (expr_type == TypeManager.ushort_type) return new IntConstant (~((UShortConstant)e).Value, e.Location); if (expr_type == TypeManager.char_type) return new IntConstant (~((CharConstant)e).Value, e.Location); // Predefined operators if (expr_type == TypeManager.int32_type) return new IntConstant (~((IntConstant)e).Value, e.Location); if (expr_type == TypeManager.uint32_type) return new UIntConstant (~((UIntConstant)e).Value, e.Location); if (expr_type == TypeManager.int64_type) return new LongConstant (~((LongConstant)e).Value, e.Location); if (expr_type == TypeManager.uint64_type){ return new ULongConstant (~((ULongConstant)e).Value, e.Location); } if (e is EnumConstant) { e = TryReduceConstant (ec, ((EnumConstant)e).Child); if (e != null) e = new EnumConstant (e, expr_type); return e; } return null; } throw new Exception ("Can not constant fold: " + Oper.ToString()); }
// // Imports System.Reflection parameters // AParametersCollection CreateParameters (TypeSpec parent, ParameterInfo[] pi, MethodBase method) { int varargs = method != null && (method.CallingConvention & CallingConventions.VarArgs) != 0 ? 1 : 0; if (pi.Length == 0 && varargs == 0) return ParametersCompiled.EmptyReadOnlyParameters; TypeSpec[] types = new TypeSpec[pi.Length + varargs]; IParameterData[] par = new IParameterData[pi.Length + varargs]; bool is_params = false; for (int i = 0; i < pi.Length; i++) { ParameterInfo p = pi[i]; Parameter.Modifier mod = 0; Expression default_value = null; if (p.ParameterType.IsByRef) { if ((p.Attributes & (ParameterAttributes.Out | ParameterAttributes.In)) == ParameterAttributes.Out) mod = Parameter.Modifier.OUT; else mod = Parameter.Modifier.REF; // // Strip reference wrapping // var el = p.ParameterType.GetElementType (); types[i] = ImportType (el, new DynamicTypeReader (p)); // TODO: 1-based positio to be csc compatible } else if (i == 0 && method.IsStatic && parent.IsStatic && parent.MemberDefinition.DeclaringAssembly.HasExtensionMethod && HasAttribute (CustomAttributeData.GetCustomAttributes (method), "ExtensionAttribute", CompilerServicesNamespace)) { mod = Parameter.Modifier.This; types[i] = ImportType (p.ParameterType); } else { types[i] = ImportType (p.ParameterType, new DynamicTypeReader (p)); if (i >= pi.Length - 2 && types[i] is ArrayContainer) { if (HasAttribute (CustomAttributeData.GetCustomAttributes (p), "ParamArrayAttribute", "System")) { mod = Parameter.Modifier.PARAMS; is_params = true; } } if (!is_params && p.IsOptional) { object value = p.RawDefaultValue; var ptype = types[i]; if ((p.Attributes & ParameterAttributes.HasDefault) != 0 && ptype.Kind != MemberKind.TypeParameter && (value != null || TypeSpec.IsReferenceType (ptype))) { if (value == null) { default_value = Constant.CreateConstant (ptype, null, Location.Null); } else { default_value = ImportParameterConstant (value); if (ptype.IsEnum) { default_value = new EnumConstant ((Constant) default_value, ptype); } } } else if (value == Missing.Value) { default_value = EmptyExpression.MissingValue; } else if (value == null) { default_value = new DefaultValueExpression (new TypeExpression (ptype, Location.Null), Location.Null); } else if (ptype.BuiltinType == BuiltinTypeSpec.Type.Decimal) { default_value = ImportParameterConstant (value); } } } par[i] = new ParameterData (p.Name, mod, default_value); } if (varargs != 0) { par[par.Length - 1] = new ArglistParameter (Location.Null); types[types.Length - 1] = InternalType.Arglist; } return method != null ? new ParametersImported (par, types, varargs != 0, is_params) : new ParametersImported (par, types, is_params); }
// <summary> // This routine will attempt to simplify the unary expression when the // argument is a constant. The result is returned in `result' and the // function returns true or false depending on whether a reduction // was performed or not // </summary> bool Reduce (EmitContext ec, Constant e, out Expression result) { Type expr_type = e.Type; switch (Oper){ case Operator.UnaryPlus: result = e; return true; case Operator.UnaryNegation: result = TryReduceNegative (e); return true; case Operator.LogicalNot: if (expr_type != TypeManager.bool_type) { result = null; Error23 (expr_type); return false; } BoolConstant b = (BoolConstant) e; result = new BoolConstant (!(b.Value)); return true; case Operator.OnesComplement: if (!((expr_type == TypeManager.int32_type) || (expr_type == TypeManager.uint32_type) || (expr_type == TypeManager.int64_type) || (expr_type == TypeManager.uint64_type) || (expr_type.IsSubclassOf (TypeManager.enum_type)))){ result = null; if (ImplicitConversionExists (ec, e, TypeManager.int32_type)){ result = new Cast (new TypeExpr (TypeManager.int32_type, loc), e, loc); result = result.Resolve (ec); } else if (ImplicitConversionExists (ec, e, TypeManager.uint32_type)){ result = new Cast (new TypeExpr (TypeManager.uint32_type, loc), e, loc); result = result.Resolve (ec); } else if (ImplicitConversionExists (ec, e, TypeManager.int64_type)){ result = new Cast (new TypeExpr (TypeManager.int64_type, loc), e, loc); result = result.Resolve (ec); } else if (ImplicitConversionExists (ec, e, TypeManager.uint64_type)){ result = new Cast (new TypeExpr (TypeManager.uint64_type, loc), e, loc); result = result.Resolve (ec); } if (result == null || !(result is Constant)){ result = null; Error23 (expr_type); return false; } expr_type = result.Type; e = (Constant) result; } if (e is EnumConstant){ EnumConstant enum_constant = (EnumConstant) e; Expression reduced; if (Reduce (ec, enum_constant.Child, out reduced)){ result = new EnumConstant ((Constant) reduced, enum_constant.Type); return true; } else { result = null; return false; } } if (expr_type == TypeManager.int32_type){ result = new IntConstant (~ ((IntConstant) e).Value); } else if (expr_type == TypeManager.uint32_type){ result = new UIntConstant (~ ((UIntConstant) e).Value); } else if (expr_type == TypeManager.int64_type){ result = new LongConstant (~ ((LongConstant) e).Value); } else if (expr_type == TypeManager.uint64_type){ result = new ULongConstant (~ ((ULongConstant) e).Value); } else { result = null; Error23 (expr_type); return false; } return true; case Operator.AddressOf: result = this; return false; case Operator.Indirection: result = this; return false; } throw new Exception ("Can not constant fold: " + Oper.ToString()); }