Ejemplo n.º 1
0
        public override void VisitAddressDereference(AddressDereference dereference)
        {
            if (dereference?.Address is UnaryExpression expression)
            {
                if ((expression.Type as Reference)?.ConstructorName.Name.Contains("Guid@") == true)
                {
                    AddProblem(expression);
                }
            }

            base.VisitAddressDereference(dereference);
        }
Ejemplo n.º 2
0
        public override Expression VisitAddressDereference(AddressDereference addr)
        {
            if (this._string == null)
            {
                this._string = new StringBuilder();
            }
            this._string.Append("::$Deref{");
            Expression e = base.VisitAddressDereference(addr);

            this._string.Append("}");
            return(e);
        }
Ejemplo n.º 3
0
        public static string GetVariableName(Expression expression)
        {
            ArgumentUtility.CheckNotNull("expression", expression);

            string variableName = null;

            if (expression is Parameter)
            {
                Parameter operand = (Parameter)expression;
                variableName = operand.Name.Name;
            }
            else if (expression is Local)
            {
                Local operand = (Local)expression;
                variableName = operand.Name.Name;
            }
            else if (expression.NodeType == NodeType.AddressOf)
            {
                Local operand = ((UnaryExpression)expression).Operand as Local;
                if (operand != null)
                {
                    variableName = operand.Name.Name;
                }
            }
            else if (expression.NodeType == NodeType.AddressDereference)
            {
                AddressDereference addressDereference = (AddressDereference)expression;
                variableName = GetVariableName(addressDereference.Address);
            }
            else if (expression is MemberBinding)
            {
                MemberBinding memberBinding = (MemberBinding)expression;
                if (memberBinding.BoundMember is Field)
                {
                    Field field = (Field)memberBinding.BoundMember;
                    variableName = field.Name.Name;
                }
            }
            else if (expression.NodeType == NodeType.Indexer)
            {
                Indexer indexer = (Indexer)expression;
                variableName = GetVariableName(indexer.Object);
            }

            return(variableName);
        }
Ejemplo n.º 4
0
 public override Expression VisitAddressDereference(AddressDereference addr){
   if (addr == null) return null;
   bool unboxDeref = addr.Address != null && addr.Address.NodeType == NodeType.Unbox;
   addr.Address = this.VisitExpression(addr.Address);
   if (addr.Address == null) return null;
   if (unboxDeref && addr.Address.NodeType != NodeType.Unbox) return addr.Address;
   Reference reference = addr.Address.Type as Reference;
   if (reference != null) addr.Type = reference.ElementType;
   return addr;
 }
Ejemplo n.º 5
0
    public override Expression VisitMethodCall(MethodCall call) {
      if (call == null) return null;
      NameBinding nb = call.Callee as NameBinding;
      if (nb != null) {      
        if (nb.Identifier != Looker.NotFound) {
          this.VisitNameBinding(nb); //Reports the error
          return null;
        }
        int numPars = call.Operands == null ? 0 : call.Operands.Count;
        bool callOperandsAlreadyNull = (call.Operands == null);
        ExpressionList operands = call.Operands = this.VisitExpressionList(call.Operands);
        if (operands == null && !callOperandsAlreadyNull || operands != null && operands.Count != numPars) return null;
        for (int i = 0; i < numPars; i++)
          if (call.Operands[i] == null) return null; //The error could have been caused by the bad argument.
        bool hasArglist = false;
        int arglistIndex = -1;

        for (int i = 0; i < numPars; i++) {
          if (call.Operands[i] is ArglistArgumentExpression) {
            hasArglist = true;
            arglistIndex = i;
            break;
          }
        }

        MemberList members = nb.BoundMembers;
        int n = members == null ? 0 : members.Count;
        MethodList ambiguousMethods = new MethodList(n);
        Method inaccessibleMethod = null;
        Method templateMethodWithFailedInference = null;
        Method objectMatchArglistMethod = null;
        for (int i = 0; i < n; i++) {
          Method meth = members[i] as Method;
          if (meth == null) continue;
          if ((meth.Parameters == null ? 0 : meth.Parameters.Count) != numPars) continue;
          if (this.NotAccessible(meth)) {
            inaccessibleMethod = meth;
            continue;
          } else {
            string mname = meth.Name != null ? meth.Name.ToString() :
        "";
            if (this.insideMethodContract  || this.insideInvariant) {
              if (!this.AsAccessible(meth, currentMethod) && !this.insideInvariant) {
                this.HandleError(meth, Error.MemberNotVisible, this.GetTypeName(meth.DeclaringType)+"."+mname); // WS better error message
                return null;
              }
              if ((this.insideMethodContract || this.insideAssertOrAssume) && !this.IsTransparentForMethodContract(meth, currentMethod)) {
                this.HandleError(meth, Error.MemberMustBePureForMethodContract, this.GetTypeName(meth.DeclaringType)+"."+mname);
                return null;
              }
              if (this.insideInvariant && !this.IsTransparentForInvariant(meth, currentMethod)) {
                this.HandleError(meth, Error.MemberMustBePureForInvariant, this.GetTypeName(meth.DeclaringType)+"."+mname);
                return null;
              }
            } else if (!this.IsModelUseOk(meth, currentMethod)) {
              this.HandleError(meth, Error.ModelMemberUseNotAllowedInContext, this.GetTypeName(meth.DeclaringType)+"."+mname);
              return null;
            }
          }
          if (meth.TemplateParameters != null && meth.TemplateParameters.Count > 0) {
            templateMethodWithFailedInference = meth;
            continue;
          }
          if (hasArglist && arglistIndex < meth.Parameters.Count && meth.Parameters[arglistIndex].Type == SystemTypes.Object) {
            objectMatchArglistMethod = meth;
          }
          ambiguousMethods.Add(meth);
        }
        if (ambiguousMethods.Count >= 2) {
          this.HandleError(call, Error.AmbiguousCall, this.GetMethodSignature(ambiguousMethods[0]), this.GetMethodSignature(ambiguousMethods[1]));
          return null;
        }
        if (inaccessibleMethod != null) {
          this.HandleError(call, Error.MemberNotVisible, this.GetMethodSignature(inaccessibleMethod));
          return null;
        }
        if (templateMethodWithFailedInference != null) {
          this.HandleError(call, Error.CannotInferMethTypeArgs, this.GetMethodSignature(templateMethodWithFailedInference));
          return null;
        }
        if (objectMatchArglistMethod != null) {
          this.HandleError(call, Error.CannotMatchArglist, objectMatchArglistMethod.Name.Name);
          this.HandleRelatedError(objectMatchArglistMethod);
          return null;
        }
        Identifier id = null;
        for (int i = 0; i < n; i++) {
          Member mem = members[i];
          if (!(mem is Method)) continue;
          if (id == null && mem.Name != null) {
            id = mem.Name;
            string name = id.Name;
            if (mem is InstanceInitializer && mem.DeclaringType != null && mem.DeclaringType.Name != null)
              name = mem.DeclaringType.Name.Name;
            else if (mem.IsSpecialName)
              name = this.GetMemberName(mem);
            this.HandleError(nb, Error.NoOverloadWithMatchingArgumentCount, name, (call.Operands == null ? 0 : call.Operands.Count).ToString());
          }
          this.HandleRelatedError(mem);
        }
        return null;
      }
      MemberBinding mb = call.Callee as MemberBinding;
      if (mb == null) {
        Expression e = this.VisitExpression(call.Callee);
        if (e != null) {
          if (e is Literal && e.Type == SystemTypes.Type)
            this.HandleError(e, Error.TypeInBadContext, this.GetTypeName((TypeNode)((Literal)e).Value));
          else {
            TemplateInstance templInst = e as TemplateInstance;
            if (templInst != null) {
              if (templInst.Expression == null || templInst.TypeArguments == null) return null;
              this.VisitExpression(templInst.Expression);
              return null;
            }
            //HS D
            if (call.Callee is Hole)
               return null;
            this.HandleError(e, Error.NoSuchMethod);
          }
        }
        return null;
      }
      Method method = mb.BoundMember as Method;
      if (method == null) {
        if (mb.BoundMember != null) {
          if (mb.BoundMember is Event)
            this.HandleError(mb, Error.BadCallToEventHandler, this.GetMemberSignature(mb.BoundMember));
          else
            this.HandleNonMethodWhereMethodExpectedError(mb, mb.BoundMember);
        }
        return null;
      }
      bool initialMayReferenceThisAndBase = this.MayReferenceThisAndBase;
      if (mb.TargetObject is ImplicitThis || mb.TargetObject is This || mb.TargetObject is Base) {
        if (method is InstanceInitializer) {
          this.MayReferenceThisAndBase = true;  //Base class constructor has been called
        } else if ((this.currentMethod == null && !this.insideModelfield // this is true when it is visited as part of a field initializer
                    || !this.MayReferenceThisAndBase) // this is true when it is visited as part of a ctor with an explicit call to base in the body
                   && !this.AllowThisTarget(method) && !this.insideInvariant) {
          if (mb.TargetObject is ImplicitThis) {
            this.HandleError(mb, Error.ObjectRequired, this.GetMethodSignature(method, true));
          } else if (mb.TargetObject is Base) {
            this.HandleError(mb.TargetObject, Error.BaseInBadContext);
          } else {
            this.HandleError(mb.TargetObject, Error.ThisInBadContext);
          }
          return null;
        }
      }
      if (method == Resolver.IndexerNotFound) {
        if (mb.TargetObject == null) return null;
        if (this.TypeInVariableContext(mb.TargetObject as Literal)) return null;
        Expression tgtObj = this.VisitExpression(mb.TargetObject);
        if (tgtObj == null) return null;
        this.HandleError(tgtObj, Error.NotIndexable, this.GetTypeName(mb.TargetObject.Type));
        return null;
      }
      if (method.Name == Looker.NotFound) {
        //TODO: report the error
        return null;
      }
      TypeNode obType = mb.TargetObject == null ? null : mb.TargetObject.Type;
      if (mb.TargetObject is Base) obType = this.currentType;
      obType = TypeNode.StripModifiers(obType);
      if (this.NotAccessible(method, ref obType)) {
        if (method.IsSpecialName && method.Parameters != null && method.Parameters.Count > 0 && method.Name.ToString().StartsWith("get_"))
          this.HandleError(call, Error.NotIndexable, this.GetTypeName(mb.TargetObject.Type));
        else if (mb.TargetObject == null || mb.TargetObject.Type == null || this.NotAccessible(method))
          this.HandleError(call, Error.MemberNotVisible, this.GetMethodSignature(method));
        else
          this.HandleError(mb.BoundMemberExpression == null ? mb : mb.BoundMemberExpression, Error.NotVisibleViaBaseType, this.GetMethodSignature(method),
            this.GetTypeName(mb.TargetObject.Type), this.GetTypeName(this.currentType));
        return null;
      } else {
        if (this.insideMethodContract || this.insideInvariant || this.insideAssertOrAssume) {
          string mname = method.Name == null ? "" : method.Name.ToString();
          if (!this.AsAccessible(method, currentMethod) && !this.insideInvariant && !this.insideMethodContract && !this.insideAssertOrAssume) {
            this.HandleError(mb, Error.MemberNotVisible, this.GetTypeName(method.DeclaringType)+"."+mname);
            return null;
          }
          if ((this.insideMethodContract || this.insideAssertOrAssume) && !this.IsTransparentForMethodContract(method, currentMethod)) {
            this.HandleError(mb, Error.MemberMustBePureForMethodContract, this.GetTypeName(method.DeclaringType)+"."+mname);
            return null;
          }
          if (this.insideInvariant && !this.IsTransparentForInvariant(method, currentMethod)) {
            this.HandleError(mb, Error.MemberMustBePureForInvariant, this.GetTypeName(method.DeclaringType)+"."+mname);
            return null;
          }
        } else if (!this.IsModelUseOk(method, currentMethod)) {
          string mname = method.Name == null ? "" : method.Name.ToString();
          this.HandleError(mb, Error.ModelMemberUseNotAllowedInContext, this.GetTypeName(method.DeclaringType)+"."+mname);
          return null;
        }
      }
      this.CheckDirectCallOfFinalize(method, call);
      if (method == this.currentMethod && method is InstanceInitializer)
      {
        this.HandleError(call, Error.RecursiveConstructorCall, this.GetMethodSignature(method));
        return null;
      }
      if (method.IsStatic) {
        Expression targetOb = mb.TargetObject;
        if (targetOb != null) {
          MemberBinding memb = targetOb as MemberBinding;
          if (memb == null || memb.BoundMember == null || memb.Type == null || memb.Type.Name == null ||
            memb.BoundMember.Name.UniqueIdKey != memb.Type.Name.UniqueIdKey) {
            MethodCall mcall = targetOb as MethodCall;
            memb = mcall == null ? null : mcall.Callee as MemberBinding;
            TypeNode mcallType = mcall == null ? null : TypeNode.StripModifiers(mcall.Type);
            if (memb == null || memb.BoundMember == null || !memb.BoundMember.IsSpecialName || mcallType == null ||
              mcallType.Name == null || memb.BoundMember.Name.ToString() != "get_"+mcallType.Name.ToString()) {
              targetOb = this.VisitExpression(targetOb);
              if (targetOb != null)
                this.HandleError(targetOb, Error.TypeNameRequired, this.GetMethodSignature(method));
            }
          }
          mb.TargetObject = targetOb = null;
        }
      } else {
        bool targetObIsNonNull = false;
        bool outerMayReferenceThisAndBase = this.MayReferenceThisAndBase;
        if (this.AllowThisTarget(method)) this.MayReferenceThisAndBase = true;
        Expression targetOb = mb.TargetObject = this.VisitExpression(mb.TargetObject);
        this.MayReferenceThisAndBase = outerMayReferenceThisAndBase;
        if (targetOb != null)
          targetObIsNonNull = this.typeSystem.IsNonNullType(targetOb.Type);
        if (targetOb is Literal && targetOb.Type == SystemTypes.Type) {
          this.HandleError(mb, Error.ObjectRequired, this.GetMethodSignature(method, true));
          return null;
        }
        if (this.currentMethod != null && this.currentMethod.IsStatic) {
          if (targetOb is ImplicitThis || targetOb is This || targetOb is Base) {
            ImplicitThis ithis = targetOb as ImplicitThis;
            if (ithis != null) {
              bool callToNestedFunction = false;
              if (this.currentMethod.Scope.CapturedForClosure) {
                TypeNode t = this.currentMethod.Scope.ClosureClass;
                while (t != null && !callToNestedFunction) {
                  callToNestedFunction = t == method.DeclaringType;
                  t = t.BaseType;
                }
              }
              if (!callToNestedFunction) ithis = null;
            }
            if (ithis == null) {
              this.HandleError(mb, Error.ObjectRequired, this.GetMethodSignature(method));
              return null;
            }
            targetOb = new CurrentClosure(this.currentMethod, this.currentMethod.DeclaringType);
          }
        }
        TypeNode tObType = method.DeclaringType;
        if (tObType == null) return null;
        if (tObType.TemplateParameters != null && tObType.Template == null)
          tObType = tObType.GetTemplateInstance(tObType, tObType.TemplateParameters);
        if ((method.CallingConvention & CallingConventionFlags.ExplicitThis) != 0) {
          if (method.Parameters == null || method.Parameters.Count < 1 || method.Parameters[0] == null)
            Debug.Assert(false);
          else
            tObType = method.Parameters[0].Type;
        }
        if (tObType != null) {
          if (targetOb == null) return null;
          if (tObType.IsValueType) {
            targetOb = this.ConvertValueTypeCallTarget(targetOb, method, tObType);
            if (targetOb == null) return null;
            mb.TargetObject = this.GetAddressOf(targetOb, tObType);
          } else if (targetOb is Base && this.currentType != null && this.currentType.IsValueType) {
            targetOb = new AddressDereference(targetOb, this.currentType);
            mb.TargetObject = new BinaryExpression(targetOb, new MemberBinding(null, this.currentType), NodeType.Box, tObType);
          } else {
            if (tObType != targetOb.Type && !(targetOb is CurrentClosure && tObType is ClosureClass) && !(targetOb is This || targetOb is ImplicitThis)) {
              if (this.useGenerics && targetOb.Type is ITypeParameter && method.IsVirtual) {
                call.Constraint = targetOb.Type;
                if (targetOb.NodeType == NodeType.Indexer)
                  targetOb = mb.TargetObject = new UnaryExpression(targetOb, NodeType.ReadOnlyAddressOf, targetOb.Type.GetReferenceType());
                else
                  targetOb = mb.TargetObject = this.GetAddressOf(targetOb, targetOb.Type);
              } else {
                Reference refType = targetOb.Type as Reference;
                if (this.useGenerics && refType != null && refType.ElementType is ITypeParameter)
                  call.Constraint = refType.ElementType;
                else
                  targetOb = mb.TargetObject = this.typeSystem.ExplicitCoercion(targetOb, tObType, this.TypeViewer);
              }
              if (targetOb == null) return null;
            } else if (targetOb.Type != null && !this.GetTypeView(targetOb.Type).IsAssignableTo(tObType) && targetOb.Type.IsNestedIn(tObType)) {
              this.HandleError(mb, Error.AccessToNonStaticOuterMember, this.GetTypeName(tObType), this.GetTypeName(targetOb.Type));
              return null;
            }
          }
        }
      }
      bool savedMayReferenceThisAndBase = this.MayReferenceThisAndBase;
      this.MayReferenceThisAndBase = initialMayReferenceThisAndBase;
      this.CoerceArguments(method.Parameters, ref call.Operands, this.DoNotVisitArguments(method), method.CallingConvention);
      this.MayReferenceThisAndBase = savedMayReferenceThisAndBase;
      this.CheckForObsolesence(call, method);
      if (call.GiveErrorIfSpecialNameMethod && method.IsSpecialName) {
        string mname = method.Name == null ? null : method.Name.Name;
        if (mname != null && (mname.StartsWith(".") || mname.StartsWith("get_") || mname.StartsWith("set_") || mname.StartsWith("add_") || mname.StartsWith("remove_")))
          this.HandleError(call, Error.CannotCallSpecialMethod, this.GetMethodSignature(method));
      }
      if (method.IsAbstract && call.NodeType != NodeType.Callvirt) {
        Debug.Assert(mb.TargetObject is Base);
        this.HandleError(call, Error.AbstractBaseCall, this.GetMethodSignature(method));
      }
      if (mb != null) {
        if (method != null && method.Contract != null && method.Contract.Ensures != null) {
          // Look at any checked exceptions listed in m's contract and make sure they
          // are covered by the list of allowedExceptions
          for (int i = 0, n = method.Contract.Ensures.Count; i < n; i++) {
            EnsuresExceptional ee = method.Contract.Ensures[i] as EnsuresExceptional;
            if (ee == null)
              continue;
            TypeNode thrownType = ee.Type;
            if (thrownType == null) continue;
            if (!this.GetTypeView(thrownType).IsAssignableTo(SystemTypes.ICheckedException))
              continue;
            int j = 0;
            int p = this.allowedExceptions.Count;
            while (j < p) {
              TypeNode t = this.allowedExceptions[j];
              if (this.GetTypeView(thrownType).IsAssignableTo(t))
                break;
              j++;
            }
            if (j == p) { // no allowed exception covers this one
              this.HandleError(call, Error.CheckedExceptionNotInThrowsClause, this.GetTypeName(thrownType), this.GetMethodSignature(this.currentMethod));
            }
          }
        }
      }
      int numTemplArgs = method.TemplateArguments == null ? 0 : method.TemplateArguments.Count;
      if (method != null && numTemplArgs > 0) {
        // check instantiation constraints
        int len = method.Template.TemplateParameters == null ? 0 : method.Template.TemplateParameters.Count;
        if (numTemplArgs != len) {
          this.HandleError(call, Error.TemplateTypeRequiresArgs, this.GetMethodSignature(method.Template), len.ToString(), "method");
          return call;
        }
        Specializer specializer = len == 0 ? null : new Specializer(method.DeclaringType.DeclaringModule, method.Template.TemplateParameters, method.TemplateArguments);
        if (specializer != null) specializer.CurrentType = this.currentType;
        for (int i=0; i < len; i++) {
          TypeNode formal = method.Template.TemplateParameters[i];
          ITypeParameter formaltp = (ITypeParameter)formal;
          TypeNode actual = method.TemplateArguments[i];
          if (formal == null || actual == null) continue;
          // make sure actual is assignable to base of formal and to each interface
          TypeNode fbaseType = specializer == null ? formal.BaseType : specializer.VisitTypeReference(formal.BaseType);
          if (fbaseType != null && (
                ((formaltp.TypeParameterFlags & TypeParameterFlags.ReferenceTypeConstraint) == TypeParameterFlags.ReferenceTypeConstraint && !actual.IsObjectReferenceType)
                || ((formaltp.TypeParameterFlags & TypeParameterFlags.ValueTypeConstraint) == TypeParameterFlags.ValueTypeConstraint && !actual.IsValueType)
                || !this.typeSystem.AssignmentCompatible(TypeNode.StripModifiers(actual), fbaseType, this.TypeViewer))) {
            Node offNode = call.CalleeExpression is TemplateInstance ? (Node)((TemplateInstance)call.CalleeExpression).TypeArgumentExpressions[i] : (Node)call.CalleeExpression;
            this.HandleError(offNode,
              Error.TypeParameterNotCompatibleWithConstraint, this.GetTypeName(actual),
              this.GetTypeName(fbaseType),
              this.GetTypeName(formal),
              this.GetMethodSignature(method.Template));
            return call;
          }
          InterfaceList formal_ifaces = this.GetTypeView(formal).Interfaces;
          if (formal_ifaces != null) {
            for (int j = 0, n = formal_ifaces.Count; j < n; j++) {
              TypeNode intf = specializer == null ? formal_ifaces[j] : specializer.VisitTypeReference(formal_ifaces[j]);
              intf = TypeNode.StripModifiers(intf);
              if (intf == null) continue;
              if (intf != SystemTypes.ITemplateParameter && !this.typeSystem.AssignmentCompatible(TypeNode.StripModifiers(actual), intf, this.TypeViewer)) {
                Node offNode = call.CalleeExpression is TemplateInstance ? (Node)((TemplateInstance)call.CalleeExpression).TypeArgumentExpressions[i] : (Node)call.CalleeExpression;
                this.HandleError(offNode,
                  Error.TypeParameterNotCompatibleWithConstraint, this.GetTypeName(actual),
                  this.GetTypeName(intf),
                  this.GetTypeName(formal),
                  this.GetMethodSignature(method.Template));
                return call;
              }
            }
          }
        }
        this.CheckGenericMethodSpecialConstraints(method, call);
      }

      return call;
    }
Ejemplo n.º 6
0
 public override Expression VisitAddressDereference(AddressDereference addr){
   if (addr == null) return null;
   addr.Type = SystemTypes.Object; //TODO: arrange for an error if the type is not determined below
   Expression aExpr = addr.Address = this.VisitExpression(addr.Address);
   if (aExpr != null && aExpr.Type != null){
     TypeNode aExprType = TypeNode.StripModifiers(aExpr.Type);
     Reference refType = aExprType as Reference;
     if (refType != null) aExprType = TypeNode.StripModifiers(refType.ElementType); 
     switch(aExprType.NodeType){
       case NodeType.Pointer: addr.Type = ((Pointer)aExprType).ElementType; break;
       case NodeType.Struct:
         if (aExprType.Template == SystemTypes.GenericBoxed)
           addr.Type = this.typeSystem.GetStreamElementType(aExprType, this.TypeViewer);
         break;
     }
   }
   return addr;
 }
Ejemplo n.º 7
0
	void Factor(Expression target, out Expression e) {
		e = null;
		Member  m;
		ExpressionList es; Expression p;
		Expression p1; Expression p2;
		TypeNode t1;
		/*Identifier blockVarId;*/
		MemberBinding mb;
		
		switch (la.kind) {
		case 2: case 3: case 4: case 70: case 71: case 72: case 73: case 74: case 75: {
			Literal(out e);
			break;
		}
		case 27: case 30: case 55: {
			Local(out p);
			e = p; 
			break;
		}
		case 1: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 25: case 26: case 28: case 35: {
			MemberRef(out m);
			Debug.Assert(m != null); e = new MemberBinding(target,m); 
			if (la.kind == 49) {
				ArgExprs(out es);
				Method meth = (Method)m;
				if ( ! meth.IsVirtual){
				 e = new MethodCall(e, es, NodeType.Call);
				}else{
				 e = new MethodCall(e, es, NodeType.Callvirt); /*dangerous*/
				}
				e.Type = meth.ReturnType;
				
			}
			break;
		}
		case 54: {
			BlockVar(out mb);
			Debug.Assert(target == null);
			e = mb;
			Debug.Assert(e != null);  // block variable not found
			
			break;
		}
		case 5: {
			Get();
			Expect(38);
			Expect(22);
			Expr(out e);
			OldExpression oe = new OldExpression(e);
			oe.Type = e.Type;
			e = oe;
			
			Expect(24);
			break;
		}
		case 22: {
			Get();
			Expr(out e);
			Expect(24);
			break;
		}
		case 39: {
			Get();
			Expect(22);
			Expr(out p);
			Expect(23);
			PType(out t1);
			Expect(24);
			e = new BinaryExpression(p,new Literal(t1,SystemTypes.Type),NodeType.ExplicitCoercion);
			e.Type = t1;
			
			break;
		}
		case 40: {
			Get();
			Expect(22);
			Expr(out p);
			Expect(23);
			PType(out t1);
			Expect(24);
			e = new BinaryExpression(p,new Literal(t1,SystemTypes.Type),NodeType.Is);
			e.Type = SystemTypes.Boolean;
			
			break;
		}
		case 41: {
			Get();
			Expect(22);
			Expr(out p);
			Expect(23);
			PType(out t1);
			Expect(24);
			e = new BinaryExpression(p,new Literal(t1,SystemTypes.Type),NodeType.Castclass);
			e.Type = t1;
			
			break;
		}
		case 42: {
			Get();
			Expect(22);
			PType(out t1);
			Expect(24);
			e = new UnaryExpression(new Literal(t1, SystemTypes.Type), NodeType.Typeof, OptionalModifier.For(SystemTypes.NonNullType, SystemTypes.Type));
			
			break;
		}
		case 43: {
			Get();
			Expect(22);
			Expr(out p);
			Expect(23);
			Expr(out p1);
			Expect(23);
			Expr(out p2);
			Expect(23);
			PType(out t1);
			Expect(24);
			e = new TernaryExpression(p,p1,p2,NodeType.Conditional,t1);
			
			break;
		}
		case 44: {
			Get();
			Expect(22);
			Expr(out p);
			Expect(23);
			PType(out t1);
			Expect(24);
			e = new BinaryExpression(p,new MemberBinding(null,t1),NodeType.Box);
			e.Type = SystemTypes.Object;
			
			break;
		}
		case 45: {
			Get();
			Expect(22);
			Expr(out p);
			Expect(23);
			PType(out t1);
			Expect(24);
			e = new BinaryExpression(p,new MemberBinding(null,t1),NodeType.Unbox);
			e.Type = t1.GetReferenceType();
			
			break;
		}
		case 46: {
			Get();
			Expect(22);
			Expr(out p);
			Expect(24);
			e = new UnaryExpression(p, NodeType.RefAddress, p.Type);
			
			break;
		}
		case 57: case 58: case 59: case 60: case 61: case 62: case 63: case 64: {
			Quantifier(out e);
			break;
		}
		case 65: {
			TrueComprehension(out e);
			break;
		}
		case 47: {
			Get();
			if (la.kind == 48 || la.kind == 51 || la.kind == 52) {
				if (la.kind == 48) {
					Get();
					Expect(22);
					PType(out t1);
					Expect(24);
					Expect(49);
					Expr(out p);
					Expect(50);
					TypeNode newType = p.Type.GetReferenceType();
					e = new UnaryExpression(p,NodeType.AddressOf,newType);
					
				} else if (la.kind == 51) {
					Get();
					Expect(49);
					Expr(out p);
					Expect(50);
					Reference r = (Reference) p.Type;
					if (r != null)
					 e = new AddressDereference(p,r.ElementType);
					else
					 e = new AddressDereference(p, SystemTypes.UInt8);
					
				} else {
					TypeNode tt1 = null, tt2 = null, tt3 = null; 
					Get();
					Expect(22);
					PType(out tt1);
					Expect(23);
					PType(out tt2);
					Expect(24);
					Expect(49);
					Expr(out p);
					Expect(23);
					PType(out tt3);
					Expect(50);
					e = new BinaryExpression(p, new Literal(tt3, SystemTypes.Type), NodeType.Isinst); e.Type = tt3; 
				}
			} else if (la.kind == 53) {
				TypeNode tt1 = null, tt2 = null, tt3 = null; 
				Get();
				Expect(22);
				PType(out tt1);
				Expect(23);
				PType(out tt2);
				Expect(24);
				Expect(49);
				Expr(out p);
				Expect(23);
				PType(out tt3);
				Expect(50);
				e = new BinaryExpression(p, new Literal(tt3, SystemTypes.Type), NodeType.Isinst); e.Type = tt3; 
			} else if (StartOf(2)) {
				OperatorNode(out p);
				e = p; 
			} else SynErr(111);
			break;
		}
		default: SynErr(112); break;
		}
	}
Ejemplo n.º 8
0
 public virtual void VisitAddressDereference(AddressDereference addr)
 {
   if (addr == null) return;
   this.VisitExpression(addr.Address);
 }
Ejemplo n.º 9
0
 private static string addrderef2str(AddressDereference ad) {
   return "*" + expression2str(ad.Address, false);
 }
Ejemplo n.º 10
0
    public virtual Expression VisitLiftedPostfixExpression(PostfixExpression pExpr) {
      if (pExpr == null) return null;
      if (!this.typeSystem.IsNullableType(pExpr.Type)) { Debug.Assert(false); return null; }
      LRExpression lrExpr = this.VisitTargetExpression(pExpr.Expression) as LRExpression;
      if (lrExpr == null) return null;
      TypeNode urType = this.typeSystem.RemoveNullableWrapper(pExpr.Type);
      TypeNode paramType = urType;
      LocalList locals = lrExpr.Temporaries;
      ExpressionList subs = lrExpr.SubexpressionsToEvaluateOnce;

      StatementList statements = new StatementList();
      BlockExpression result = new BlockExpression(new Block(statements));
      for (int i = 0, n = locals.Count; i < n; i++)
        statements.Add(new AssignmentStatement(locals[i], subs[i]));
      EnumNode eType = urType as EnumNode;
      if (eType != null) urType = eType.UnderlyingType;

      Local temp = new Local(Identifier.Empty, pExpr.Type);
      Local tempNew = new Local(Identifier.Empty, pExpr.Type);
      Expression e = this.typeSystem.ExplicitCoercion(lrExpr.Expression, pExpr.Type, this.TypeViewer);
      statements.Add(new AssignmentStatement(temp, this.VisitExpression(e)));

      Method hasValue = this.GetTypeView(pExpr.Type).GetMethod(StandardIds.getHasValue);
      Method getValueOrDefault = this.GetTypeView(pExpr.Type).GetMethod(StandardIds.GetValueOrDefault);
      Method ctor = this.GetTypeView(pExpr.Type).GetMethod(StandardIds.Ctor, paramType);
      Block pushValue = new Block();
      Block done = new Block();

      Expression tempHasValue = new MethodCall(new MemberBinding(new UnaryExpression(temp, NodeType.AddressOf), hasValue), null);
      statements.Add(new Branch(tempHasValue, pushValue));
      statements.Add(new AssignmentStatement(new AddressDereference(new UnaryExpression(tempNew, NodeType.AddressOf), pExpr.Type), new Literal(null, CoreSystemTypes.Object)));
      statements.Add(new Branch(null, done));
      statements.Add(pushValue);
      Expression value = new MethodCall(new MemberBinding(new UnaryExpression(temp, NodeType.AddressOf), getValueOrDefault), null);
      value.Type = paramType;
      Expression one = GetOneOfType(urType);
      Expression newUVal = new BinaryExpression(value, one, pExpr.Operator, urType is Pointer ? urType : one.Type);
      Construct cons = new Construct(new MemberBinding(null, ctor), new ExpressionList(newUVal));
      result.Type = ctor.DeclaringType;
      statements.Add(new AssignmentStatement(tempNew, cons));
      statements.Add(done);

      Expression target = this.VisitTargetExpression(lrExpr.Expression);
      MethodCall mcall = target as MethodCall;
      if (mcall != null) {
        mcall.Operands.Add(tempNew);
        statements.Add(new ExpressionStatement(mcall));
      } else if (target != null) {
        if (target.Type is Reference) {
          Local temp2 = new Local(Identifier.Empty, pExpr.Type);
          statements.Add(new AssignmentStatement(temp2, tempNew));
          tempNew = temp2;
          target = new AddressDereference(target, pExpr.Type);
        }
        statements.Add(new AssignmentStatement(target, tempNew));
      }

      statements.Add(new ExpressionStatement(temp));
      result.Type = pExpr.Type;
      result.SourceContext = pExpr.SourceContext;
      result.Block.SourceContext = pExpr.SourceContext;
      return result;
    }
Ejemplo n.º 11
0
 public override Expression VisitPrefixExpression(PrefixExpression pExpr) {
   if (pExpr == null) return null;
   if (this.typeSystem.IsNullableType(pExpr.Type))
     return VisitLiftedPrefixExpression(pExpr);
   StatementList statements = new StatementList();
   BlockExpression result = new BlockExpression(new Block(statements));
   LRExpression lrExpr = this.VisitTargetExpression(pExpr.Expression) as LRExpression;
   if (lrExpr == null) return null;
   LocalList locals = lrExpr.Temporaries;
   ExpressionList subs = lrExpr.SubexpressionsToEvaluateOnce;
   for (int i = 0, n = locals.Count; i < n; i++)
     statements.Add(new AssignmentStatement(locals[i], subs[i],pExpr.SourceContext));
   TypeNode rType = pExpr.Type;
   EnumNode eType = rType as EnumNode;
   if (eType != null) rType = eType.UnderlyingType;
   Expression newVal = null;
   if (pExpr.OperatorOverload != null){
     ExpressionList arguments = new ExpressionList(1);
     arguments.Add(this.VisitExpression(lrExpr.Expression));
     newVal = new MethodCall(new MemberBinding(null, pExpr.OperatorOverload), arguments, NodeType.Call, rType);
   }else{
     Expression e = this.typeSystem.AutoDereferenceCoercion(lrExpr.Expression);
     Expression one = GetOneOfType(rType);
     newVal = new BinaryExpression(this.VisitExpression(e), one, pExpr.Operator, rType is Pointer ? rType : one.Type);
   }
   Local temp = new Local(Identifier.Empty, newVal.Type);
   statements.Add(new AssignmentStatement(temp, newVal,pExpr.SourceContext));
   Expression target = this.VisitTargetExpression(lrExpr.Expression);
   MethodCall mcall = target as MethodCall;
   if (mcall != null){
     mcall.Operands.Add(temp);
     statements.Add(new ExpressionStatement(mcall));
   }else if (target != null){
     if (target.Type is Reference) {
       target = new AddressDereference(target, rType);
     }
     statements.Add(new AssignmentStatement(target, this.typeSystem.ExplicitCoercion(temp, target.Type, this.TypeViewer),pExpr.SourceContext));
   }
   statements.Add(new ExpressionStatement(temp,pExpr.SourceContext));
   result.Type = pExpr.Type;
   return result;
 }
Ejemplo n.º 12
0
    public override Expression VisitOldExpression(OldExpression oldExp) {
      Expression/*?*/ transformedExpression = oldExp;
      if (this.toplevelOldExpression == null) {
        this.toplevelOldExpression = oldExp;
        this.collectSubExpsDependentOnQuantifiedVars(oldExp);
        transformedExpression = this.markOldSubExps(oldExp);
      }
      if (transformedExpression != oldExp) {
        // if we are not at the toplevel, or the transformed top level is not the old expression, 
        // which means the old operator has been pushed down using the distribution law. 
        Expression result = this.VisitExpression(transformedExpression);
        if (this.toplevelOldExpression == oldExp) {
          // leave top level old expression
          this.toplevelOldExpression = null;
          this.subExpsDependentOnQuantifiedVars = null;
        }
        return result;
      } else {
        OldExpression oldExpression = transformedExpression as OldExpression;
        //^ assert oldExpression != null;
        TypeNode t = oldExpression.Type;
        Reference rt = t as Reference;
        Expression e = oldExpression.expression;
        if (rt != null) {
          e = new AddressDereference(e, rt.ElementType, e.SourceContext);
        }
        string oldName = e.SourceContext.SourceText != null && e.SourceContext.SourceText.Length > 0
          ? "old(" + e.SourceContext.SourceText + ")" : "$SSold" + e.UniqueKey;
        Local l = new Local(Identifier.For(oldName), e.Type);
        #region Add local to method's local list so it gets the right debug scope
        // Since the scope of the "old" local is the entire method body, it suffices
        // to add it to the method's local list. Because of how that is processed in Writer,
        // that means the local's scope will be the entire method body.
        if (this.currentMethod.LocalList == null) {
          this.currentMethod.LocalList = new LocalList();
        }
        this.currentMethod.LocalList.Add(l);
        #endregion
        // normalize the old expression itself
        e = this.VisitExpression(e);
        Statement a = this.initializeOldExp(l, e, oldExpression.ShallowCopyUptoDimension);
        
        this.currentContractPrelude.Statements.Add(a);
        this.currentContractPrelude.HasLocals = true;

        if (this.toplevelOldExpression == oldExpression) {
          this.toplevelOldExpression = null;
          this.subExpsDependentOnQuantifiedVars = null;
        }

        if (rt != null)
          return new UnaryExpression(l, NodeType.AddressOf, t, e.SourceContext);
        else
          return l;
      }
    }
Ejemplo n.º 13
0
 public Block CreateClosureClassInstance(Method method){
   Class closureClass = method.Scope.ClosureClass;
   Block newBlock = new Block();
   StatementList statements = new StatementList(3);
   newBlock.Statements = statements;
   newBlock.HasLocals = true;
   // can't set currentClosureLocal in SetUpClosureClass because in a ctor, cannot use "closure.this"
   // instead of "this" until after base/self ctor call is made.
   this.currentClosureLocal = new Local(Identifier.For("SS$Closure Class Local"+method.UniqueKey), closureClass,newBlock);
   statements.Add(new AssignmentStatement(this.currentClosureLocal, new Construct(new MemberBinding(null, this.GetTypeView(closureClass).GetConstructors()[0]), new ExpressionList(0))));
   if (method.Scope.ThisField != null){
     Expression thisValue = method.ThisParameter;
     if (this.currentType.IsValueType) thisValue = new AddressDereference(thisValue, this.currentType);
     statements.Add(new AssignmentStatement(new MemberBinding(this.currentClosureLocal, method.Scope.ThisField), thisValue));
   }
   MemberList members = method.Scope.Members;
   for (int i = 0, n = members.Length; i < n; i++){
     Field f = members[i] as Field;
     if (f != null && f.Type is Reference) continue;
     f.DeclaringType = closureClass;
     ParameterField pField = f as ParameterField;
     if (pField == null) continue;
     Parameter p = pField.Parameter;
     statements.Add(new AssignmentStatement(new MemberBinding(this.currentClosureLocal, f), p));
   }
   return newBlock;
 }
Ejemplo n.º 14
0
 public Block CreateClosureClassInstance(Method method) {
   Class closureClassTemplate = method.Scope.ClosureClass;
   if (closureClassTemplate == null) { Debug.Fail("method.Scope.ClosureClass == null"); return null; }
   Block newBlock = new Block();
   StatementList statements = new StatementList(1);
   newBlock.Statements = statements;
   newBlock.HasLocals = true;
   //At this point any base or chained constructors have been called and future references to parameters must happen via the closure
   MemberList scopeMembers = method.Scope.Members;
   for (int i = 0, n = scopeMembers.Count; i < n; i++) {
     Member m = scopeMembers[i];
     Field f = m as Field;
     if (f == null || f.Type is Reference) continue;
     f.DeclaringType = closureClassTemplate; //This signals that the parameter field now must bind to the closure field, not the actual parameter
     closureClassTemplate.Members.Add(f);
   }
   Class closureClass = method.Scope.ClosureClass;
   if (closureClass.TemplateParameters != null && closureClass.TemplateParameters.Count > 0)
     closureClass = (Class)closureClass.GetTemplateInstance(this.currentType, method.TemplateParameters);
   this.currentClosureLocal = new Local(Identifier.For("SS$Closure Class Local"+method.UniqueKey), closureClass, newBlock);
   ExpressionList arguments = new ExpressionList();
   if (method.Scope.ThisField != null){
     Expression thisValue = method.ThisParameter;
     TypeNode t = method.Scope.ThisTypeInstance;
     if (t != null && t.IsValueType) thisValue = new AddressDereference(thisValue, t);
     arguments.Add(thisValue);
   }
   ParameterList pars = method.Parameters;
   for (int i = 0, n = pars == null ? 0 : pars.Count; i < n; i++) {
     Parameter p = pars[i];
     if (p == null || p.Type == null || (p.Type is Reference)) continue;
     arguments.Add(p);
   }
   statements.Add(new AssignmentStatement(this.currentClosureLocal, new Construct(new MemberBinding(null, closureClass.GetConstructors()[0]), arguments)));
   return newBlock;
 }
Ejemplo n.º 15
0
 public override Expression VisitAddressDereference(AddressDereference addr)
 {
     throw new ApplicationException("unimplemented");
 }
Ejemplo n.º 16
0
    public virtual Differences VisitAddressDereference(AddressDereference/*!*/ addr1, AddressDereference addr2) {
      Differences differences = new Differences(addr1, addr2);
      if (addr1 == null || addr2 == null){
        if (addr1 != addr2) differences.NumberOfDifferences++; else differences.NumberOfSimilarities++;
        return differences;
      }
      AddressDereference changes = (AddressDereference)addr2.Clone();
      AddressDereference deletions = (AddressDereference)addr2.Clone();
      AddressDereference insertions = (AddressDereference)addr2.Clone();
  
      Differences diff = this.VisitExpression(addr1.Address, addr2.Address);
      if (diff == null){Debug.Assert(false); return differences;}
      changes.Address = diff.Changes as Expression;
      deletions.Address = diff.Deletions as Expression;
      insertions.Address = diff.Insertions as Expression;
      Debug.Assert(diff.Changes == changes.Address && diff.Deletions == deletions.Address && diff.Insertions == insertions.Address);
      differences.NumberOfDifferences += diff.NumberOfDifferences;
      differences.NumberOfSimilarities += diff.NumberOfSimilarities;

      if (addr1.Alignment == addr2.Alignment) differences.NumberOfSimilarities++; else differences.NumberOfDifferences++;
      if (addr1.Volatile == addr2.Volatile) differences.NumberOfSimilarities++; else differences.NumberOfDifferences++;

      if (differences.NumberOfDifferences == 0){
        differences.Changes = null;
        differences.Deletions = null;
        differences.Insertions = null;
      }else{
        differences.Changes = changes;
        differences.Deletions = deletions;
        differences.Insertions = insertions;
      }
      return differences;
    }
Ejemplo n.º 17
0
 public override Expression VisitPostfixExpression(PostfixExpression pExpr){
   if (pExpr == null) return null;
   if (this.typeSystem.IsNullableType(pExpr.Type))
     return VisitLiftedPostfixExpression(pExpr);
   StatementList statements = new StatementList();
   BlockExpression result = new BlockExpression(new Block(statements));
   LRExpression lrExpr = this.VisitTargetExpression(pExpr.Expression) as LRExpression;
   if (lrExpr == null) return null;
   LocalList locals = lrExpr.Temporaries;
   ExpressionList subs = lrExpr.SubexpressionsToEvaluateOnce;
   for (int i = 0, n = locals.Count; i < n; i++)
     statements.Add(new AssignmentStatement(locals[i], subs[i],pExpr.SourceContext));
   TypeNode rType = pExpr.Type;
   EnumNode eType = rType as EnumNode;
   if (eType != null) rType = eType.UnderlyingType;
   Local temp = new Local(Identifier.Empty, rType);
   Expression e = this.typeSystem.AutoDereferenceCoercion(lrExpr.Expression);
   statements.Add(new AssignmentStatement(temp, this.VisitExpression(e), pExpr.SourceContext));
   Expression newVal = null;
   if (pExpr.OperatorOverload != null){
     ExpressionList arguments = new ExpressionList(1);
     arguments.Add(this.VisitExpression(lrExpr.Expression));
     newVal = new MethodCall(new MemberBinding(null, pExpr.OperatorOverload), arguments, NodeType.Call, rType);
   }else{
     Expression one = Literal.Int32One;
     if (rType == SystemTypes.Int64 || rType == SystemTypes.UInt64)
       one = Literal.Int64One;
     else if (rType == SystemTypes.Double)
       one = Literal.DoubleOne;
     else if (rType == SystemTypes.Single)
       one = Literal.SingleOne;
     else if (rType is Pointer){
       Literal elementType = new Literal(((Pointer)rType).ElementType, SystemTypes.Type);
       UnaryExpression sizeOf = new UnaryExpression(elementType, NodeType.Sizeof, SystemTypes.Int32);
       one = PureEvaluator.EvalUnaryExpression(elementType, sizeOf);
       if (one == null) one = sizeOf;
     }
     newVal = new BinaryExpression(temp, one, pExpr.Operator, rType is Pointer ? rType : one.Type);
     newVal = this.typeSystem.ExplicitCoercion(newVal, lrExpr.Type, this.TypeViewer);
   }
   Expression target = this.VisitTargetExpression(lrExpr.Expression);
   MethodCall mcall = target as MethodCall;
   if (mcall != null){
     mcall.Operands.Add(newVal);
     statements.Add(new ExpressionStatement(mcall));
   }else if (target != null){
     if (target.Type is Reference){
       Local temp2 = new Local(Identifier.Empty, rType);
       statements.Add(new AssignmentStatement(temp2, newVal));
       newVal = temp2;
       target = new AddressDereference(target, rType);
     }
     statements.Add(new AssignmentStatement(target, newVal,pExpr.SourceContext));
   }
   statements.Add(new ExpressionStatement(temp));
   result.Type = pExpr.Type;
   result.SourceContext = pExpr.SourceContext;
   result.Block.SourceContext = pExpr.SourceContext;
   return result;
 }
Ejemplo n.º 18
0
 protected virtual Expression StandardImplicitCoercion(Expression source, bool sourceIsNonNullType, TypeNode sourceType, bool targetIsNonNullType, TypeNode targetType, TypeNode originalTargetType, TypeViewer typeViewer){
   if (Literal.IsNullLiteral(source)) {
     if (this.IsNullableType(targetType)) {
       Local temp = new Local(targetType);
       StatementList statements = new StatementList();
       BlockExpression result = new BlockExpression(new Block(statements));
       statements.Add(new AssignmentStatement(new AddressDereference(new UnaryExpression(temp, NodeType.AddressOf), targetType), new Literal(null, CoreSystemTypes.Object)));
       statements.Add(new ExpressionStatement(temp));
       return result;
     }
     if (targetType.IsTemplateParameter && !targetType.IsReferenceType) {
       // Check for reference constraint
       this.HandleError(source, Error.TypeVarCantBeNull, targetType.Name.Name);
       return new Local(targetType);
     }
   }
   //Identity coercion
   if (sourceType == targetType && (!targetIsNonNullType || (targetIsNonNullType == sourceIsNonNullType))) return source;
   ITypeParameter stp = sourceType as ITypeParameter;
   ITypeParameter ttp = targetType as ITypeParameter;
   if (stp != null && ttp != null && stp.ParameterListIndex == ttp.ParameterListIndex && stp.DeclaringMember == ttp.DeclaringMember &&
     (!targetIsNonNullType || (targetIsNonNullType == sourceIsNonNullType))) return source;
   if (source is This && targetType != null && sourceType == targetType.Template && targetType.IsNotFullySpecialized)
     //TODO: add check for sourceType.TemplateParameters == targetType.TemplateArguments
     return source;
   //Dereference source
   Reference sr = sourceType as Reference;
   if (sr != null){
     sourceType = sr.ElementType;
     Pointer pType = targetType as Pointer;
     if (pType != null && this.StandardImplicitCoercionFromTo(null, sourceType, pType.ElementType, typeViewer))
       return source;
     else if (pType != null && pType.ElementType == SystemTypes.Void)
       return source;
     bool sourceIsThis = source is This;
     source = new AddressDereference(source, sourceType, source.SourceContext);
     source.Type = sourceType;
     sourceIsNonNullType = this.IsNonNullType(sourceType);
     sourceType = TypeNode.StripModifier(sourceType, SystemTypes.NonNullType);
     //Special case for coercion of this in template class
     if (sourceIsThis && targetType != null && sourceType == targetType.Template && targetType.IsNotFullySpecialized)
       //TODO: add check for sourceType.TemplateParameters == targetType.TemplateArguments
       return source;
   }
   //Identity coercion after dereference
   if (sourceType == targetType && (!targetIsNonNullType || (targetIsNonNullType == sourceIsNonNullType))) return source;
   //Special case for null literal
   if (Literal.IsNullLiteral(source)){
     if (targetIsNonNullType) 
       return ImplicitNonNullCoercion(this.ErrorHandler, source, originalTargetType);
     if (targetType is ITypeParameter && this.useGenerics)
       return new BinaryExpression(source, new Literal(targetType, SystemTypes.Type), NodeType.UnboxAny);
     if (!targetType.IsValueType || targetType.Template == SystemTypes.GenericBoxed)
       return new Literal(null, targetType, source.SourceContext);
     if (this.IsNullableType(targetType))
       return new Local(StandardIds.NewObj, targetType, source.SourceContext);
     TypeAlias tAlias = targetType as TypeAlias;
     if (tAlias != null){
       if (tAlias.RequireExplicitCoercionFromUnderlyingType) return null;
       source = this.ImplicitCoercion(source, tAlias.AliasedType, typeViewer);
       if (source == null) return null;
       Method coercion = this.UserDefinedImplicitCoercionMethod(source, tAlias.AliasedType, targetType, false, typeViewer);
       if (coercion != null){
         ExpressionList args = new ExpressionList(this.ImplicitCoercion(source, coercion.Parameters[0].Type, typeViewer));
         return new MethodCall(new MemberBinding(null, coercion), args, NodeType.Call, coercion.ReturnType);
       }
     }else{
       Method coercion = this.UserDefinedImplicitCoercionMethod(source, source.Type, targetType, true, typeViewer);
       if (coercion != null){
         ExpressionList args = new ExpressionList(this.ImplicitCoercion(source, coercion.Parameters[0].Type, typeViewer));
         return new MethodCall(new MemberBinding(null, coercion), args, NodeType.Call, coercion.ReturnType);
       }
     }
     this.HandleError(source, Error.CannotCoerceNullToValueType, this.GetTypeName(targetType));
     return new Local(targetType);
   }
   //Special case for string literal
   if (source.NodeType == NodeType.Literal && sourceType == SystemTypes.String &&
       (targetType.Template == SystemTypes.GenericNonNull || targetType.Template == SystemTypes.GenericInvariant) && 
       this.GetStreamElementType(targetType, typeViewer) == SystemTypes.String)
       return this.ExplicitCoercion(source, targetType, typeViewer);
   //Implicit numeric coercions + implicit enumeration coercions + implicit constant expression coercions
   if (sourceType.IsPrimitive && sourceType != SystemTypes.String && (targetType.IsPrimitive || targetType == SystemTypes.Decimal || targetType is EnumNode)){
     Expression primitiveCoercion = this.ImplicitPrimitiveCoercion(source, sourceType, targetType, typeViewer);
     if (primitiveCoercion != null) return primitiveCoercion;
   }
   //Implicit coercion from string literal to numbers or eums
   if (this.allowStringLiteralToOtherPrimitiveCoercion && sourceType == SystemTypes.String && (targetType.IsPrimitive || targetType == SystemTypes.Decimal || targetType is EnumNode)){
     Expression primitiveCoercion = this.ImplicitPrimitiveCoercion(source, sourceType, targetType, typeViewer);
     if (primitiveCoercion != null) return primitiveCoercion;
   }
   
   //Implicit reference coercions
   if (TypeViewer.GetTypeView(typeViewer, sourceType).IsAssignableTo(targetType)){
     if (targetIsNonNullType && !(sourceIsNonNullType) && !sourceType.IsValueType) {
       //Handling for non null types
       return ImplicitNonNullCoercion(this.ErrorHandler, source, originalTargetType);
     }else if (sourceType.IsValueType && !targetType.IsValueType){
       if (sourceType.NodeType == NodeType.TypeUnion){
         Debug.Assert(targetType == SystemTypes.Object);
         return this.CoerceTypeUnionToObject(source, typeViewer);
       }
       if (sourceType is TupleType){
         if (targetType == SystemTypes.Object)
           return this.TupleCoercion(source, sourceType, targetType, false, typeViewer);
       }else if (targetType.Template != SystemTypes.GenericIEnumerable && this.GetStreamElementType(sourceType, typeViewer) != sourceType)
         return this.ExplicitCoercion(this.CoerceStreamToObject(source, sourceType, typeViewer), targetType, typeViewer);
       Expression e = new BinaryExpression(source, new MemberBinding(null, sourceType), NodeType.Box, targetType, source.SourceContext);
       e.Type = targetType;
       return e;
     }else if (this.useGenerics && (sourceType is TypeParameter || sourceType is ClassParameter)){
       source = new BinaryExpression(source, new MemberBinding(null, sourceType), NodeType.Box, sourceType);
       if (targetType == SystemTypes.Object) return source;
       return new BinaryExpression(source, new MemberBinding(null, targetType), NodeType.UnboxAny, targetType);
     }
     else if (this.useGenerics && sourceType is ArrayType) {
       ArrayType sat = (ArrayType)sourceType;
       while (sat.ElementType is ArrayType) sat = (ArrayType)sat.ElementType;
       if (sat.ElementType is ITypeParameter)
         return new BinaryExpression(source, new MemberBinding(null, targetType), NodeType.Castclass, targetType, source.SourceContext);
       return source;
     }else
       return source;
   }
   //Special case for delegates
   if (targetType is DelegateNode)
     return this.CoerceToDelegate(source, sourceType, (DelegateNode)targetType, false, typeViewer);
   //Special case for type union to common base type
   if (sourceType.NodeType == NodeType.TypeUnion)
     return this.CoerceFromTypeUnion(source, (TypeUnion)sourceType, targetType, false, originalTargetType, typeViewer);
   //Special case for Type intersection target type
   if (targetType.NodeType == NodeType.TypeIntersection)
     return this.CoerceToTypeIntersection(source, sourceType, (TypeIntersection)targetType, false, typeViewer);
   //Special cases for typed streams
   Expression streamCoercion = this.StreamCoercion(source, sourceType, targetType, false, originalTargetType, typeViewer);
   if (streamCoercion != null) return streamCoercion;
   //Implicit tuple coercions
   return this.TupleCoercion(source, sourceType, targetType, false, typeViewer);
 }
Ejemplo n.º 19
0
    public override Expression VisitBinaryExpression(BinaryExpression binaryExpression){
      if (binaryExpression == null) return null;
      if (this.typeSystem.IsNullableType(binaryExpression.Type)){
        switch(binaryExpression.NodeType){
          case NodeType.Add:
          case NodeType.And:
          case NodeType.Ceq:
          case NodeType.Cgt:
          case NodeType.Cgt_Un:
          case NodeType.Clt:
          case NodeType.Clt_Un:
          case NodeType.Div:
          case NodeType.Ge:
          case NodeType.Gt:
          case NodeType.Mul:
          case NodeType.Le:
          case NodeType.Lt:
          case NodeType.Or:
          case NodeType.Rem:
          case NodeType.Sub:
          case NodeType.Xor:
            return this.VisitLiftedBinaryExpression(binaryExpression);
        }
      }
      switch(binaryExpression.NodeType){
        case NodeType.Range:
          Expression range = new Construct(new MemberBinding(null,SystemTypes.Range.GetConstructor(SystemTypes.Int32,SystemTypes.Int32)),new ExpressionList(binaryExpression.Operand1, binaryExpression.Operand2),SystemTypes.Range);
          range.SourceContext = binaryExpression.SourceContext;
          return this.VisitExpression(range);       
        case NodeType.Maplet:
          Expression maplet = new Construct(new MemberBinding(null,SystemTypes.DictionaryEntry.GetConstructor(SystemTypes.Object,SystemTypes.Object)),new ExpressionList(binaryExpression.Operand1, binaryExpression.Operand2),SystemTypes.DictionaryEntry);
          maplet.SourceContext = binaryExpression.SourceContext;
          return this.VisitExpression(maplet);       
        case NodeType.Implies:
          Expression implies = new TernaryExpression(binaryExpression.Operand1, binaryExpression.Operand2, new Literal(true, SystemTypes.Boolean), NodeType.Conditional, SystemTypes.Boolean);
          implies.SourceContext = binaryExpression.SourceContext;
          return this.VisitExpression(implies);
        case NodeType.Iff:
          Expression iff = new BinaryExpression(binaryExpression.Operand1, binaryExpression.Operand2, NodeType.Eq, SystemTypes.Boolean);
          iff.SourceContext = binaryExpression.SourceContext;
          return this.VisitExpression(iff);
        case NodeType.LogicalAnd:
          if (binaryExpression.Operand1 is Local && binaryExpression.Operand2 is MethodCall)
            return this.VisitShortCircuitBitwiseOp(binaryExpression);
          Expression e = new TernaryExpression(binaryExpression.Operand1, binaryExpression.Operand2, new Literal(false, SystemTypes.Boolean), NodeType.Conditional, SystemTypes.Boolean);
          e.SourceContext = binaryExpression.SourceContext;
          return this.VisitExpression(e);
        case NodeType.LogicalOr: 
          if (binaryExpression.Operand1 is Local && binaryExpression.Operand2 is MethodCall)
            return this.VisitShortCircuitBitwiseOp(binaryExpression);
          e = new TernaryExpression(binaryExpression.Operand1, new Literal(true, SystemTypes.Boolean), binaryExpression.Operand2, NodeType.Conditional, SystemTypes.Boolean);
          e.SourceContext = binaryExpression.SourceContext;
          return this.VisitExpression(e);
      }
      binaryExpression.Operand1 = this.VisitExpression(binaryExpression.Operand1);
      binaryExpression.Operand2 = this.VisitExpression(binaryExpression.Operand2);
      TypeNode t = binaryExpression.Type;
      switch(binaryExpression.NodeType){
        case NodeType.Add:
        case NodeType.Sub:
          DelegateNode delType = t as DelegateNode;
          if (delType != null){
            ExpressionList args = new ExpressionList(2);
            args.Add(binaryExpression.Operand1);
            args.Add(binaryExpression.Operand2);
            MethodCall mcall = new MethodCall(new MemberBinding(null, Runtime.Combine), args, NodeType.Call, Runtime.Combine.ReturnType, binaryExpression.SourceContext);
            if (binaryExpression.NodeType == NodeType.Sub) 
              ((MemberBinding)mcall.Callee).BoundMember = Runtime.Remove;
            binaryExpression = new BinaryExpression(mcall, new Literal(delType, SystemTypes.Type), NodeType.Castclass, t, binaryExpression.SourceContext);
          }
          break;
        case NodeType.Box:
          Literal lit = binaryExpression.Operand2 as Literal;
          if (lit != null){
            TypeNode bt = lit.Value as TypeNode;
            if (bt != null)
              binaryExpression.Operand2 = lit = new Literal(this.VisitTypeReference(bt), lit.Type, lit.SourceContext);
          }
          break;
        case NodeType.ExplicitCoercion:
          return binaryExpression.Operand1;
        case NodeType.Castclass:
          if (t == null) return null;
          if (t.IsValueType){
            binaryExpression.NodeType = NodeType.Unbox;
            AddressDereference dref = new AddressDereference(binaryExpression, t); 
            dref.Type = t;
            return dref;
          }else if (t is Pointer)
            return this.NormalizeToPointerCoercion(binaryExpression);
          if (binaryExpression.Operand1 != null && binaryExpression.Operand1.Type != null && binaryExpression.Operand1.Type.IsValueType)
            binaryExpression.Operand1 =
              new BinaryExpression(binaryExpression.Operand1, new MemberBinding(null, binaryExpression.Operand1.Type), NodeType.Box, SystemTypes.Object);
          break;
        case NodeType.Comma:{
          StatementList statements = new StatementList(2);
          Expression opnd1 = binaryExpression.Operand1;
          if (opnd1 != null && opnd1.Type != SystemTypes.Void) opnd1 = new UnaryExpression(opnd1, NodeType.Pop, SystemTypes.Void);
          statements.Add(new ExpressionStatement(opnd1));
          statements.Add(new ExpressionStatement(binaryExpression.Operand2));
          return new BlockExpression(new Block(statements), SystemTypes.Boolean);
        }
        case NodeType.Eq :
        case NodeType.Ge : 
        case NodeType.Gt :
        case NodeType.Le : 
        case NodeType.Lt :
        case NodeType.Ne :
          // HACK: This tells normalizer to leave the expression as it is, because I need to run evaluator over it
          if (this.WrapToBlockExpression){
            Block pushTrue = new Block(null);
            Block done = new Block(null);
            StatementList statements = new StatementList(6);
            if (binaryExpression.Operand1.Type != null && binaryExpression.Operand2.Type != null && binaryExpression.Operand1.Type.IsPrimitiveUnsignedInteger && binaryExpression.Operand2.Type.IsPrimitiveUnsignedInteger) {
              statements.Add(new Branch(binaryExpression, pushTrue, binaryExpression.SourceContext, true));
            }
            else statements.Add(new Branch(binaryExpression, pushTrue));
            statements.Add(new ExpressionStatement(new Literal(false, SystemTypes.Boolean)));
            statements.Add(new Branch(null, done));
            statements.Add(pushTrue);
            statements.Add(new ExpressionStatement(new Literal(true, SystemTypes.Boolean)));
            statements.Add(done);
            return new BlockExpression(new Block(statements), SystemTypes.Boolean, binaryExpression.SourceContext);
          }
          return binaryExpression;
        case NodeType.Is :
          if (binaryExpression.Operand2 is Literal)
            binaryExpression.Type = (TypeNode)((Literal) binaryExpression.Operand2).Value;
          else
            binaryExpression.Type = (TypeNode)((MemberBinding)binaryExpression.Operand2).BoundMember;
          binaryExpression.NodeType = NodeType.Isinst;
          if (this.useGenerics && binaryExpression.Operand1 != null && binaryExpression.Operand1.Type != null && binaryExpression.Operand1.Type.IsTemplateParameter)
            binaryExpression.Operand1 = new BinaryExpression(binaryExpression.Operand1, new Literal(binaryExpression.Operand1.Type), NodeType.Box);
          binaryExpression = new BinaryExpression(binaryExpression, new Literal(null, SystemTypes.Object), NodeType.Ne);
          goto case NodeType.Eq;
        case NodeType.NullCoalescingExpression: {
          Expression cachedOperand1 = binaryExpression.Operand1;
          if (cachedOperand1 == null || cachedOperand1.Type == null || binaryExpression.Operand2 == null) return null;
          StatementList statements = new StatementList();
          if (!(cachedOperand1 is Local || cachedOperand1 is Parameter))
          {
              Expression cachedOperand1Temp = cachedOperand1;
              cachedOperand1 = new Local(cachedOperand1.Type);
              statements.Add(new AssignmentStatement(cachedOperand1, cachedOperand1Temp)); 
          }
          Local exprValue = new Local(binaryExpression.Type);
          Block pushValue = new Block();
          Block done = new Block();
          Expression operand1HasValue;
          Method hasValue = this.GetTypeView(binaryExpression.Operand1.Type).GetMethod(StandardIds.getHasValue);
          if (hasValue != null)
            operand1HasValue = new MethodCall(new MemberBinding(new UnaryExpression(cachedOperand1, NodeType.AddressOf), hasValue), null);
          else {
            operand1HasValue = new BinaryExpression(this.typeSystem.ImplicitCoercion(cachedOperand1, SystemTypes.Object), Literal.Null, NodeType.Ne);
          }
          statements.Add(new Branch(operand1HasValue, pushValue));
          Expression operand2 = this.typeSystem.ImplicitCoercion(binaryExpression.Operand2, binaryExpression.Type);
          statements.Add(new AssignmentStatement(exprValue, operand2));
          statements.Add(new Branch(null, done));
          statements.Add(pushValue);
          Expression operand1Value = null;
          if (hasValue != null) {
            Method getValueOrDefault = this.GetTypeView(binaryExpression.Operand1.Type).GetMethod(StandardIds.GetValueOrDefault);
            operand1Value = new MethodCall(new MemberBinding(new UnaryExpression(cachedOperand1, NodeType.AddressOf), getValueOrDefault), null);
            operand1Value.Type = getValueOrDefault.ReturnType;
            operand1Value = this.typeSystem.ImplicitCoercion(operand1Value, binaryExpression.Type);
            statements.Add(new AssignmentStatement(exprValue, operand1Value));
          } else {
            operand1Value = this.typeSystem.ImplicitCoercion(cachedOperand1, binaryExpression.Type);
            statements.Add(new AssignmentStatement(exprValue, operand1Value));
          }
          statements.Add(done);
          statements.Add(new ExpressionStatement(exprValue));
          return new BlockExpression(new Block(statements), binaryExpression.Type, binaryExpression.SourceContext);
        }
        case NodeType.Shr :
          t = binaryExpression.Operand1.Type;
          if (t == SystemTypes.Char || t.IsUnsignedPrimitiveNumeric)
            binaryExpression.NodeType = NodeType.Shr_Un;
          break;

      }
      return binaryExpression;
    }
Ejemplo n.º 20
0
 public override Expression VisitAddressDereference(AddressDereference addr)
 {
   throw new ApplicationException("unimplemented");
 }
Ejemplo n.º 21
0
 public virtual void VisitTypeswitchCaseList(TypeswitchCaseList oldCases, BlockList targets, StatementList statements, Block nextStatement, Local temp){
   for (int i = 0, n = oldCases.Count; i < n; i++){
     TypeswitchCase tcase = oldCases[i];
     StatementList stats = new StatementList(3);
     Block b = new Block(stats);
     if (tcase != null){
       Expression expr = null;
       if (tcase.LabelType.IsValueType)
         expr = new AddressDereference(new BinaryExpression(temp, new Literal(tcase.LabelType, SystemTypes.Type), NodeType.Unbox), tcase.LabelType);
       else
         expr = new BinaryExpression(temp, new Literal(tcase.LabelType, SystemTypes.Type), NodeType.Castclass);
       stats.Add(new AssignmentStatement(this.VisitTargetExpression(tcase.LabelVariable), expr));
       stats.Add(this.VisitBlock(tcase.Body));
     }
     stats.Add(new Branch(null, nextStatement));
     statements.Add(b);
     targets.Add(b);
   }
 }
Ejemplo n.º 22
0
	void Term(out Expression e) {
		TypeNode typ; 
		Factor(null, out e);
		while (la.kind == 28 || la.kind == 37) {
			if (la.kind == 37) {
				Get();
				Factor(e, out e);
			} else {
				Get();
				ExpressionList es = new ExpressionList(); Expression a; 
				Expr(out a);
				es.Add(a); 
				while (la.kind == 23) {
					Get();
					Expr(out a);
					es.Add(a); 
				}
				Expect(29);
				Indexer idx = new Indexer(e, es); 
				Expect(22);
				PType(out typ);
				idx.Type = typ; idx.ElementType = typ; 
				Expect(24);
				if (TypeNode.StripModifiers(e.Type).IsPointerType) {
				 e = new AddressDereference(new BinaryExpression(e, es[0], NodeType.Add, e.Type), typ);
				}
				else {
				 e = idx;
				}
				
			}
		}
	}
Ejemplo n.º 23
0
 protected virtual void VisitAddressDereference(AddressDereference adr) {
   if (adr == null) return;
   this.Visit(adr.Address);
   if (adr.Alignment > 0)
     this.ILGenerator.Emit(OpCodes.Unaligned, (byte)adr.Alignment);
   if (adr.Volatile)
     this.ILGenerator.Emit(OpCodes.Volatile);
   if (adr.Type == null) return;
   switch (adr.Type.typeCode){
     case ElementType.Int8: this.ILGenerator.Emit(OpCodes.Ldind_I1); return;
     case ElementType.UInt8: this.ILGenerator.Emit(OpCodes.Ldind_U1); return;
     case ElementType.Int16: this.ILGenerator.Emit(OpCodes.Ldind_I2); return;
     case ElementType.Char:
     case ElementType.UInt16: this.ILGenerator.Emit(OpCodes.Ldind_U2); return;
     case ElementType.Int32: this.ILGenerator.Emit(OpCodes.Ldind_I4); return;
     case ElementType.UInt32: this.ILGenerator.Emit(OpCodes.Ldind_U4); return;
     case ElementType.Int64:
     case ElementType.UInt64: this.ILGenerator.Emit(OpCodes.Ldind_I8); return;
     case ElementType.UIntPtr:
     case ElementType.IntPtr: this.ILGenerator.Emit(OpCodes.Ldind_I); return;
     case ElementType.Single: this.ILGenerator.Emit(OpCodes.Ldind_R4); return;
     case ElementType.Double: this.ILGenerator.Emit(OpCodes.Ldind_R8); return;
     default:
       if (adr.Type.IsValueType && !(adr.Type is TypeParameter)){
         this.ILGenerator.Emit(OpCodes.Ldobj, adr.Type.GetRuntimeType());
         return;
       }else if (TypeNode.StripModifiers(adr.Type) is Pointer){
         this.ILGenerator.Emit(OpCodes.Ldind_I);
         return;
       }
       this.ILGenerator.Emit(OpCodes.Ldind_Ref);
       return;
   }
 }
Ejemplo n.º 24
0
	void Local(out Expression p) {
		p  = null;
		int modifier = 0; /* 0 == none, 1 == address dereference, 2 == address of */
		
		if (la.kind == 27 || la.kind == 30) {
			if (la.kind == 30) {
				Get();
				modifier = 1; 
			} else {
				Get();
				modifier = 2; 
			}
		}
		Expect(55);
		if (la.kind == 2) {
			Parameter(out p);
		} else if (la.kind == 49) {
			SpecialName(out p);
		} else SynErr(114);
		switch (modifier){
		 case 1:
		   Debug.Assert(p.Type is Reference);
		   Reference r = p.Type as Reference;
		   p = new AddressDereference(p,r.ElementType);
		   break;
		 case 2:
		   TypeNode newType = p.Type.GetReferenceType();
		   p = new UnaryExpression(p,NodeType.AddressOf,newType);
		   break;
		 default:
		   /* nothing to do */
		   break;
		}
		
	}
Ejemplo n.º 25
0
 private static string addrderef2str(AddressDereference ad)
 {
     return("*" + expression2str(ad.Address, false));
 }
Ejemplo n.º 26
0
 public override Expression VisitAddressDereference(AddressDereference addr) {
   if (addr == null) return null;
   Expression expr = addr.Address = this.VisitExpression(addr.Address);
   if (expr == null) return null;
   TypeNode exprType = expr.Type;
   if (exprType == null) return null;
   exprType = TypeNode.StripModifiers(exprType);
   Reference refType = exprType as Reference;
   if (refType != null) {
     // Change to highlight an issue: elementType can be an optional modifier, 
     // in which case pointerType will be null. Is this the intention? 
     TypeNode elementType = refType.ElementType;//TypeNode.StripModifiers(refType.ElementType);
     Pointer pointerType = elementType as Pointer;
     if (pointerType != null) {
       exprType = elementType;
       expr = addr.Address = this.typeSystem.AutoDereferenceCoercion(expr);
     }
   }
   if (!(exprType is Pointer || exprType is Reference || exprType.Template == SystemTypes.GenericBoxed ||
     ((expr is Base) && exprType == SystemTypes.ValueType) ||
     ((expr is This || expr is ImplicitThis) && exprType.IsValueType))) {
     this.HandleError(expr, Error.CannotDeferenceNonPointerType, this.GetTypeName(exprType));
     return null;
   }
   if (exprType is Pointer && ((Pointer)exprType).ElementType == SystemTypes.Void) {
     this.HandleError(addr, Error.VoidError);
     return null;
   }
   int i = addr.Alignment;
   if (i > 0 && !(i == 1 || i == 2 || i == 4))
     addr.Alignment = -1; //It is up to the source language to complain.
   return addr;
 }
Ejemplo n.º 27
0
 public virtual Expression VisitAddressDereference(AddressDereference addr1, AddressDereference addr2)
 {
     if (addr1 == null) return null;
     if (addr2 == null)
         addr1.Address = this.VisitExpression(addr1.Address, null);
     else
         addr1.Address = this.VisitExpression(addr1.Address, addr2.Address);
     return addr1;
 }
Ejemplo n.º 28
0
      public Method methodToInferPostFrom = null;  //if set, Visit tries to infer a postcondition for method. 

      public override StatementList VisitStatementList(StatementList statements) {
        if (statements == null) return null;
        foreach (Statement stat in statements) {
          Return r = stat as Return;
          if (r != null && r.Expression != null) { //Statement return E; found. Test admissibility of E as a witness.
            WitnessFromCodeAdmissibilityVisitor admis = new WitnessFromCodeAdmissibilityVisitor();            
            try {
              admis.VisitExpression(r.Expression);
              this.Witnesses.Add(r.Expression); //witness found, otherwise exception would have been thrown
              
              #region add inferred postconditions if needed
              TypeNode retType = (methodToInferPostFrom == null || methodToInferPostFrom.ReturnType == null) ? null : methodToInferPostFrom.ReturnType;              
              if (r == statements[0] && retType != null && (retType.IsObjectReferenceType || retType.IsPrimitiveComparable)) {
                //the return statement is the first statement of the body.
                //We would like to add ensures result == r.Expression; However, we have to be careful, for 2 reasons.
                //1: == cannot be applied to structs and generic types. Note that we already tested that we do not return a struct.
                //2: result might be the implicitly boxed version of r.Expression (e.g., public object m() {returns 5;}), in which case result == r.Expression does not hold (in particular at runtime)
                //To account for 2, we have to box/unbox result and r.Expression as necessary
                //If r.Expression is a generic type, we have to distinguish cases !(r.Expression is System.ValueType) or (r.Expression is int) and act accordingly                              
                //(We do not (yet) support cases where r.Expression is a valueType other than an int, but they could be handled along the same lines.)

                if (methodToInferPostFrom.Contract == null) {
                  methodToInferPostFrom.Contract = new MethodContract(methodToInferPostFrom);
                }
                SourceContext scInferred = methodToInferPostFrom.Name.SourceContext; //can't set the sourcetext, so error message will be confusing...but then again, the idea is that this can never crash                                                                                
                
                //Duplicate the return expression to avoid sharing problems 
                Duplicator dup = new Duplicator(this.methodToInferPostFrom.DeclaringType.DeclaringModule, this.methodToInferPostFrom.DeclaringType);
                Expression returnInEq = dup.VisitExpression(r.Expression);

                //needed for casting/boxing/unboxing
                MemberBinding intType = new MemberBinding(null, SystemTypes.Int32);
                Literal objectLit = new Literal(SystemTypes.Object, SystemTypes.Type);
                Literal intLit = new Literal(SystemTypes.Int32, SystemTypes.Type);

                Expression resultBinding = new ReturnValue(methodToInferPostFrom.ReturnType, scInferred);
                Expression resultInEq = resultBinding;
                if (r.Expression.NodeType == NodeType.Box) { //if the return expression has been (implicitly) boxed, unbox both it and result
                  returnInEq = (returnInEq as BinaryExpression).Operand1; //as we have the return expression in hand, unboxing is easy
                  //adjust resultInEq to (returnInEq.Type)resultInEq (i.e., add an unbox), using an explicit coercion
                  BinaryExpression resultUnboxed = new BinaryExpression(resultInEq, intType, NodeType.Unbox, SystemTypes.Int32.GetReferenceType(), scInferred); //gets type System.Int32@ 
                  AddressDereference resultDeref = new AddressDereference(resultUnboxed, returnInEq.Type, scInferred);
                  resultInEq = new BinaryExpression(resultDeref, intLit, NodeType.ExplicitCoercion, SystemTypes.Int32, scInferred);
                }
                                
                if (returnInEq.Type != null && (returnInEq.Type.IsObjectReferenceType || returnInEq.Type.IsPrimitiveComparable)) {
                  //returnInEq is not a user-defined struct (to which we can't apply ==)
                  Expression eq = null; //holds the postcondition that is added
                  if (!(isGenericTypeThatCanBeStruct(returnInEq.Type))) {
                    //== can be applied to returnInEq. Therefore, it can also be applied to resultInEq, which is of a supertype (i.e., not generic type, not a struct). 
                    eq = new BinaryExpression(resultInEq, returnInEq, NodeType.Eq, SystemTypes.Boolean, scInferred);
                  } else {
                    #region adjust eq to compensate for generics 
                    //insert  ensures !(returnInEq is System.ValueType) ==> (object)resultInEq == (object)returnInEq;
                    //and     ensures returnInEq is int ==> (int)(object)resultInEq == (int)(object)returnInEq;
                    //the cast to object is needed to allow application of == and the cast to int. 
                    //Note that resultInEq.Type is known to also be a generic type as it is a supertype.
                    //(and note that in this case, there was no unboxing)

                    #region set up the antecedent !(returnInEq is System.ValueType)
                    TypeNode theType = SystemTypes.ValueType;

                    //antecedent: !(r.Expression is System.ValueType)
                    Expression ante = new BinaryExpression(r.Expression, new Literal(theType, SystemTypes.Type), NodeType.Is, SystemTypes.Boolean, scInferred);
                    ante = new UnaryExpression(ante, NodeType.LogicalNot, SystemTypes.Boolean, scInferred);
                    #endregion

                    #region adjust resultInEq and returnInEq to (object)resultInEq and (object)returnInEq
                    //adjust resultInEq to (object)result, so that it can be used in ==
                    //that means Box it to T, then ExplicitCast it to Object.
                    MemberBinding boxType = new MemberBinding(null, returnInEq.Type); //could also use method return type
                    BinaryExpression resultBoxed = new BinaryExpression(resultBinding, boxType, NodeType.Box, returnInEq.Type, scInferred);
                    resultInEq = new BinaryExpression(resultBoxed, objectLit, NodeType.ExplicitCoercion, SystemTypes.Object, scInferred);
                    
                    //adjust returnInEq to (object)returnInEq                    
                    BinaryExpression returnBoxed = new BinaryExpression(returnInEq, boxType, NodeType.Box, returnInEq.Type, scInferred);
                    returnInEq = new BinaryExpression(returnBoxed, objectLit, NodeType.ExplicitCoercion, SystemTypes.Object, scInferred);
                    #endregion

                    //Add first ensures; ensures ante ==> resultInEq == returnInEq;
                    eq = new BinaryExpression(resultInEq, returnInEq, NodeType.Eq, SystemTypes.Boolean, scInferred);
                    Expression impl = new BinaryExpression(ante, eq, NodeType.Implies, scInferred);
                    EnsuresNormal firstPost = new EnsuresNormal(impl);
                    firstPost.SourceContext = scInferred;
                    methodToInferPostFrom.Contract.Ensures.Add(firstPost);

                    //Now add ensures returnInEq is int ==> (int)(object)resultInEq == (int)(object)returnInEq;
                    //antecedent: r.Expression is int                
                    Expression secondAnte = new BinaryExpression(r.Expression, intLit, NodeType.Is, SystemTypes.Boolean, scInferred);

                    #region adjust resultInEq and returnInEq to (int)resultInEq and (int)returnInEq
                    //set resultInSecondEq to (int)resultInEq, i.e., to (int)(object)result
                    //this requires an unbox to int32@, then an adress-deref to int32, then an explicitcast to int32
                    //note that if we unbox to type Int32 directly, we get a "operation could destabilize the runtime" warining from the checkin tests
                    BinaryExpression resultUnboxed = new BinaryExpression(resultInEq, intType, NodeType.Unbox, SystemTypes.Int32.GetReferenceType(), scInferred); //gets type System.Int32@ 
                    AddressDereference resultDeref = new AddressDereference(resultUnboxed, SystemTypes.Int32, scInferred);
                    BinaryExpression resultInSecondEq = new BinaryExpression(resultDeref, intLit, NodeType.ExplicitCoercion, SystemTypes.Int32, scInferred);

                    //adjust returnInEq to (int)returnInEq 
                    BinaryExpression returnUnboxed = new BinaryExpression(returnInEq, intType, NodeType.Unbox, SystemTypes.Int32.GetReferenceType(), scInferred);
                    AddressDereference returnDeref = new AddressDereference(returnUnboxed, SystemTypes.Int32, scInferred);
                    BinaryExpression returnInSecondEq = new BinaryExpression(returnDeref, intLit, NodeType.ExplicitCoercion, SystemTypes.Int32, scInferred);
                    #endregion
                    
                    Expression secondEq = new BinaryExpression(resultInSecondEq, returnInSecondEq, NodeType.Eq, SystemTypes.Boolean, scInferred);
                    eq = new BinaryExpression(secondAnte, secondEq, NodeType.Implies, SystemTypes.Boolean, scInferred); //(Ab)use eq to hold the implication 
                    #endregion
                  }
                  //Add the constructed equality as a postcondition.
                  EnsuresNormal newPost = new EnsuresNormal(eq);
                  newPost.SourceContext = scInferred;
                  methodToInferPostFrom.Contract.Ensures.Add(newPost);  
                } //else don't generate a postcondition, can't apply == to a user-defined struct                 
              }
              #endregion
            }
            catch (ApplicationException e) { ApplicationException dumme = e; } //witness not admissible ('using' e to avoid warning)           
          }
        }
        return statements;
      }
Ejemplo n.º 29
0
 public override Expression VisitAddressDereference(AddressDereference addr)
 {
     if (addr == null) return null;
     return base.VisitAddressDereference((AddressDereference)addr.Clone());
 }
Ejemplo n.º 30
0
    public override Expression VisitBinaryExpression(BinaryExpression binaryExpression){
      if (binaryExpression == null) return null;
      bool opnd1IsInst = binaryExpression.Operand1 != null && binaryExpression.Operand1.NodeType == NodeType.Isinst;
      binaryExpression = (BinaryExpression)base.VisitBinaryExpression(binaryExpression);
      if (binaryExpression == null) return null;
      Expression opnd1 = binaryExpression.Operand1;
      Expression opnd2 = binaryExpression.Operand2;
      Literal lit = opnd2 as Literal;
      TypeNode t = lit == null ? null : lit.Value as TypeNode;
      if (binaryExpression.NodeType == NodeType.Castclass /*|| binaryExpression.NodeType == NodeType.ExplicitCoercion*/){
        //See if castclass must become box or unbox
        if (t != null){
          if (t.IsValueType){
            AddressDereference adref = new AddressDereference(new BinaryExpression(opnd1, lit, NodeType.Unbox), t);
            adref.Type = t;
            return adref;
          }
          if (opnd1 != null && opnd1.Type != null && opnd1.Type.IsValueType){
            return new BinaryExpression(opnd1, new MemberBinding(null, opnd1.Type), NodeType.Box, t);
          }
        }
      }else if (binaryExpression.NodeType == NodeType.Unbox){
        if (opnd1 != null && opnd1.Type != null && opnd1.Type.IsValueType)
          return opnd1;
#if ExtendedRuntime
      }else if (binaryExpression.NodeType == NodeType.Box){
        if (t != null && !(t is ITypeParameter) && t.IsReferenceType && !t.IsPointerType) { // using pointer types is a Sing# extension
          return opnd1;
        }
#endif
      }else if (binaryExpression.NodeType == NodeType.Eq) {
        //For value types, turn comparisons against null into false
        if (lit != null && lit.Value == null && opnd1 != null && opnd1.Type != null && opnd1.Type.IsValueType)
          return Literal.False;
        lit = opnd1 as Literal;
        if (lit != null && lit.Value == null && opnd2 != null && opnd2.Type != null && opnd2.Type.IsValueType)
          return Literal.False;
      }else if (binaryExpression.NodeType == NodeType.Ne){
        //For value types, turn comparisons against null into true
        if (lit != null && lit.Value == null && opnd1 != null && opnd1.Type != null && opnd1.Type.IsValueType){
          if (opnd1IsInst && opnd1.Type == CoreSystemTypes.Boolean) return opnd1;
          return Literal.True;
        }
        lit = opnd1 as Literal;
        if (lit != null && lit.Value == null && opnd2 != null && opnd2.Type != null && opnd2.Type.IsValueType)
          return Literal.True;
      }else if (binaryExpression.NodeType == NodeType.Isinst){
        //Do not emit isinst instruction if opnd1 is a value type.
        if (opnd1 != null && opnd1.Type != null && opnd1.Type.IsValueType){
          if (opnd1.Type == t)
            return Literal.True;
          else
            return Literal.False;
        }
      }
      return binaryExpression;
    }
Ejemplo n.º 31
0
 public override Expression VisitAddressDereference(AddressDereference addr) {
   if (this._string == null){ this._string = new StringBuilder(); }
   this._string.Append("::$Deref{");
   Expression e = base.VisitAddressDereference (addr);
   this._string.Append("}");
   return e;
 }
Ejemplo n.º 32
0
 public virtual Expression VisitAddressDereference(AddressDereference addr){
   if (addr == null) return null;
   addr.Address = this.VisitExpression(addr.Address);
   return addr;
 }
Ejemplo n.º 33
0
    protected virtual Expression StandardExplicitCoercionHelper(ErrorHandler savedErrorHandler, Expression source, bool sourceIsNonNullType, TypeNode sourceType, bool targetIsNonNullType, TypeNode targetType,
      TypeNode originalTargetType, TypeViewer typeViewer){
      //Identity coercion
      if (sourceType == targetType && (!targetIsNonNullType || (targetIsNonNullType == sourceIsNonNullType))){
        if (sourceType.IsPrimitiveNumeric){
          Expression e = this.ExplicitPrimitiveCoercionHelper(source, sourceType, targetType);
          if (e == null) return source;
          e.Type = targetType;
          return e;
        }
        return source;
      }
      //Dereference source
      Reference sr = sourceType as Reference;
      if (sr != null && targetType is Pointer) return source;
      if (sr != null && source.NodeType != NodeType.AddressOf){
        sourceType = sr.ElementType;
        source = new AddressDereference(source, sourceType, source.SourceContext);
        sourceType = TypeNode.StripModifier(sourceType, SystemTypes.NonNullType);
      }
      //Get rid of Nullable wrapper
      if (this.IsNullableType(sourceType)){
        Method getValue = TypeViewer.GetTypeView(typeViewer, sourceType).GetMethod(Identifier.For("get_Value"));
        sourceType = this.RemoveNullableWrapper(sourceType);
        source = new MethodCall(new MemberBinding(source, getValue), null, NodeType.Call, sourceType, source.SourceContext);
      }
      //Identity coercion after dereference
      if (sourceType == targetType && (!targetIsNonNullType || (targetIsNonNullType == sourceIsNonNullType))){
        if (sourceType.IsPrimitiveNumeric){
          source = this.ExplicitPrimitiveCoercionHelper(source, sourceType, targetType);
          if (source == null) return null;
          source.Type = targetType;
        }
        return source;
      }
      //Special case for type union
      if (sourceType.NodeType == NodeType.TypeUnion)
        return this.CoerceFromTypeUnion(source, (TypeUnion)sourceType, targetType, true, originalTargetType, typeViewer);
      //Special case for null literal
      if (source.NodeType == NodeType.Literal && ((Literal)source).Value == null){
        if (targetType.IsTemplateParameter && !targetType.IsReferenceType) {
          // Check for reference constraint
          //this.HandleError(source, Error.TypeVarCantBeNull, targetType.Name.Name);
          return null;
        }
        if (targetIsNonNullType) {
          //savedErrorHandler.HandleError(source, Error.CannotCoerceNullToNonNullType, savedErrorHandler.GetTypeName(targetType));
          return ExplicitNonNullCoercion(source, originalTargetType);
        }

        if (targetType is ITypeParameter && sourceType == SystemTypes.Object && this.useGenerics)
          return new BinaryExpression(source, new Literal(targetType, SystemTypes.Type), NodeType.UnboxAny);
        if (!targetType.IsValueType || targetType.Template == SystemTypes.GenericBoxed) 
          return new Literal(null, targetType, source.SourceContext);
        TypeAlias tAlias = targetType as TypeAlias;
        if (tAlias != null){
          source = this.ExplicitCoercion(source, tAlias.AliasedType, typeViewer);
          if (source == null) return null;
          Method coercion = this.UserDefinedExplicitCoercionMethod(source, tAlias.AliasedType, targetType, false, originalTargetType, typeViewer);
          if (coercion != null){
            ExpressionList args = new ExpressionList(this.ImplicitCoercion(source, coercion.Parameters[0].Type, typeViewer));
            return new MethodCall(new MemberBinding(null, coercion), args, NodeType.Call, coercion.ReturnType);
          }
        }
        return null;
      }
      //Explicit reference coercions
      if (TypeViewer.GetTypeView(typeViewer, sourceType).IsAssignableTo(targetType)){
        //Handling for non null types
        if (targetIsNonNullType && !sourceIsNonNullType && !sourceType.IsValueType) {
          //savedErrorHandler.HandleError(source, Error.CoercionToNonNullTypeMightFail, savedErrorHandler.GetTypeName(targetType));
          return ExplicitNonNullCoercion(source, originalTargetType);
        }
        if (targetType == SystemTypes.Object && sourceType.Template == SystemTypes.GenericIEnumerable)
          return this.CoerceStreamToObject(source, sourceType, typeViewer);
        if (sourceType.IsValueType && !targetType.IsValueType){
          if (sourceType.NodeType == NodeType.TypeUnion){
            Debug.Assert(targetType == SystemTypes.Object);
            return this.CoerceTypeUnionToObject(source, typeViewer);
          }
          if (sourceType is TupleType){
            if (targetType == SystemTypes.Object)
              return this.TupleCoercion(source, sourceType, targetType, true, typeViewer);
          }else if (this.GetStreamElementType(sourceType, typeViewer) != sourceType)
            return this.ExplicitCoercion(this.CoerceStreamToObject(source, sourceType, typeViewer), targetType, typeViewer);
          return new BinaryExpression(source, new MemberBinding(null, sourceType), NodeType.Box, targetType);
        }else if (this.useGenerics && sourceType is ITypeParameter){
          source = new BinaryExpression(source, new MemberBinding(null, sourceType), NodeType.Box, sourceType);
          if (targetType == SystemTypes.Object) return source;
          return new BinaryExpression(source, new MemberBinding(null, targetType), NodeType.UnboxAny, targetType);
        }else
          return source;
      }
      //Special case for typed streams
      Expression streamCoercion = this.StreamCoercion(source, sourceType, targetType, true, originalTargetType, typeViewer);
      if (streamCoercion != null) return streamCoercion;
      //Down casts
      if (!targetType.IsPointerType && !sourceType.IsPointerType && TypeViewer.GetTypeView(typeViewer, targetType).IsAssignableTo(sourceType)){
        if (!sourceType.IsValueType){
          if (targetType.NodeType == NodeType.TypeUnion)
            return this.CoerceObjectToTypeUnion(source, (TypeUnion)targetType, typeViewer);
          if (source.NodeType == NodeType.Literal && ((Literal)source).Value == null)
            return source;
          if (targetType.IsValueType){
            Expression e = new AddressDereference(new BinaryExpression(source, new MemberBinding(null, targetType), NodeType.Unbox, targetType.GetReferenceType()), targetType);
            e.Type = targetType;
            return e;
          }else{
            NodeType op = this.useGenerics && (targetType is ClassParameter || targetType is TypeParameter) ? NodeType.UnboxAny : NodeType.Castclass;
            Expression e = new BinaryExpression(source, new MemberBinding(null, targetType), op, source.SourceContext);
            e.Type = originalTargetType;
            //Handling for non null types
            if (targetIsNonNullType && !sourceIsNonNullType){
              //savedErrorHandler.HandleError(source, Error.CoercionToNonNullTypeMightFail, savedErrorHandler.GetTypeName(targetType));
              return ExplicitNonNullCoercion(e, originalTargetType);
            }
            return e;
          }
        }
      }
      //Special case for casts to and from interfaces
      if ((sourceType.NodeType == NodeType.Interface && !targetType.IsSealed) ||
        (targetType.NodeType == NodeType.Interface && !(sourceType.IsSealed || (sourceType is Pointer) || 
        (sourceType is ArrayType && this.GetStreamElementType(targetType, typeViewer) == targetType)))){
        Expression e = new BinaryExpression(source, new MemberBinding(null, targetType), NodeType.Castclass, source.SourceContext);
        e.Type = targetType;
        return e;
      }
      //Explicit numeric coercions + explicit enumeration coercions + explicit constant expression coercions
      Expression primitiveConversion = this.ExplicitPrimitiveCoercion(source, sourceType, targetType);
      if (primitiveConversion != null) return primitiveConversion;
      //Special case for decimal
      if (targetType == SystemTypes.Decimal && this.ImplicitCoercionFromTo(sourceType, targetType, typeViewer))
        return this.ImplicitCoercion(source, targetType, typeViewer);
      //Special case for delegates
      if (targetType is DelegateNode)
        return this.CoerceToDelegate(source, sourceType, (DelegateNode)targetType, true, typeViewer);
      //Special case for type union
      if (targetType.NodeType == NodeType.TypeUnion)
        return this.CoerceToTypeUnion(source, sourceType, (TypeUnion)targetType, typeViewer);
      //Special case for Type intersection target type
      if (targetType.NodeType == NodeType.TypeIntersection)
        return this.CoerceToTypeIntersection(source, sourceType, (TypeIntersection)targetType, false, typeViewer);
      //Tuple coercion
      return this.TupleCoercion(source, sourceType, targetType, true, typeViewer);
    }
Ejemplo n.º 34
0
 public virtual Expression VisitAddressDereference(AddressDereference addr, AddressDereference changes, AddressDereference deletions, AddressDereference insertions){
   this.UpdateSourceContext(addr, changes);
   if (addr == null) return changes;
   if (changes != null){
     if (deletions == null || insertions == null)
       Debug.Assert(false);
     else{
       addr.Address = this.VisitExpression(addr.Address, changes.Address, deletions.Address, insertions.Address);
       addr.Alignment = changes.Alignment;
       addr.Volatile = changes.Volatile;           
     }
   }else if (deletions != null)
     return null;
   return addr;
 }
Ejemplo n.º 35
0
 /// <summary>
 /// Can be called after Checker.VisitExpression to have expressions of type "reference"
 /// be automatically dereferenced
 /// </summary>
 public virtual Expression AutoDereferenceCoercion(Expression expression) {
   if (expression == null) return null;
   if (expression.NodeType == NodeType.AddressOf || expression.NodeType == NodeType.RefAddress || expression.NodeType == NodeType.OutAddress) {
     return expression;
   }
   UnaryExpression unexpr = expression as UnaryExpression;
   if (unexpr != null && unexpr.NodeType == NodeType.Parentheses) {
     unexpr.Operand = this.AutoDereferenceCoercion(unexpr.Operand);
     return unexpr;
   }
   Reference rt = expression.Type as Reference;
   if (rt != null) {
     expression = new AddressDereference(expression, rt.ElementType, expression.SourceContext);
   }
   return expression;
 }