Exemple #1
0
        private void VisitChildren(Expr pExpr)
        {
            Debug.Assert(pExpr != null);

            Expr exprRet;

            switch (pExpr.Kind)
            {
            case ExpressionKind.List:

                // Lists are a special case.  We treat a list not as a
                // binary node but rather as a node with n children.
                ExprList list = (ExprList)pExpr;
                while (true)
                {
                    list.OptionalElement = Visit(list.OptionalElement);
                    Expr nextNode = list.OptionalNextListNode;
                    if (nextNode == null)
                    {
                        return;
                    }

                    if (!(nextNode is ExprList next))
                    {
                        list.OptionalNextListNode = Visit(nextNode);
                        return;
                    }

                    list = next;
                }

            case ExpressionKind.Assignment:
                exprRet = Visit((pExpr as ExprAssignment).LHS);
                Debug.Assert(exprRet != null);
                (pExpr as ExprAssignment).LHS = exprRet;
                exprRet = Visit((pExpr as ExprAssignment).RHS);
                Debug.Assert(exprRet != null);
                (pExpr as ExprAssignment).RHS = exprRet;
                break;

            case ExpressionKind.ArrayIndex:
                exprRet = Visit((pExpr as ExprArrayIndex).Array);
                Debug.Assert(exprRet != null);
                (pExpr as ExprArrayIndex).Array = exprRet;
                exprRet = Visit((pExpr as ExprArrayIndex).Index);
                Debug.Assert(exprRet != null);
                (pExpr as ExprArrayIndex).Index = exprRet;
                break;

            case ExpressionKind.UnaryOp:
            case ExpressionKind.True:
            case ExpressionKind.False:
            case ExpressionKind.Inc:
            case ExpressionKind.Dec:
            case ExpressionKind.LogicalNot:
            case ExpressionKind.Negate:
            case ExpressionKind.UnaryPlus:
            case ExpressionKind.BitwiseNot:
            case ExpressionKind.Addr:
            case ExpressionKind.DecimalNegate:
            case ExpressionKind.DecimalInc:
            case ExpressionKind.DecimalDec:
                exprRet = Visit((pExpr as ExprUnaryOp).Child);
                Debug.Assert(exprRet != null);
                (pExpr as ExprUnaryOp).Child = exprRet;
                break;

            case ExpressionKind.UserLogicalOp:
                exprRet = Visit((pExpr as ExprUserLogicalOp).TrueFalseCall);
                Debug.Assert(exprRet != null);
                (pExpr as ExprUserLogicalOp).TrueFalseCall = exprRet;
                exprRet = Visit((pExpr as ExprUserLogicalOp).OperatorCall);
                Debug.Assert(exprRet != null);
                (pExpr as ExprUserLogicalOp).OperatorCall = exprRet as ExprCall;
                exprRet = Visit((pExpr as ExprUserLogicalOp).FirstOperandToExamine);
                Debug.Assert(exprRet != null);
                (pExpr as ExprUserLogicalOp).FirstOperandToExamine = exprRet;
                break;

            case ExpressionKind.TypeOf:
                break;

            case ExpressionKind.Cast:
                exprRet = Visit((pExpr as ExprCast).Argument);
                Debug.Assert(exprRet != null);
                (pExpr as ExprCast).Argument = exprRet;
                break;

            case ExpressionKind.UserDefinedConversion:
                exprRet = Visit((pExpr as ExprUserDefinedConversion).UserDefinedCall);
                Debug.Assert(exprRet != null);
                (pExpr as ExprUserDefinedConversion).UserDefinedCall = exprRet;
                break;

            case ExpressionKind.ZeroInit:
                break;

            case ExpressionKind.MemberGroup:

                // The object expression. NULL for a static invocation.
                exprRet = Visit((pExpr as ExprMemberGroup).OptionalObject);
                (pExpr as ExprMemberGroup).OptionalObject = exprRet;
                break;

            case ExpressionKind.Call:
                exprRet = Visit((pExpr as ExprCall).OptionalArguments);
                (pExpr as ExprCall).OptionalArguments = exprRet;
                exprRet = Visit((pExpr as ExprCall).MemberGroup);
                Debug.Assert(exprRet != null);
                (pExpr as ExprCall).MemberGroup = exprRet as ExprMemberGroup;
                break;

            case ExpressionKind.Property:
                exprRet = Visit((pExpr as ExprProperty).OptionalArguments);
                (pExpr as ExprProperty).OptionalArguments = exprRet;
                exprRet = Visit((pExpr as ExprProperty).MemberGroup);
                Debug.Assert(exprRet != null);
                (pExpr as ExprProperty).MemberGroup = exprRet as ExprMemberGroup;
                break;

            case ExpressionKind.Field:
                exprRet = Visit((pExpr as ExprField).OptionalObject);
                (pExpr as ExprField).OptionalObject = exprRet;
                break;

            case ExpressionKind.Constant:

                // Used for when we zeroinit 0 parameter constructors for structs/enums.
                exprRet = Visit((pExpr as ExprConstant).OptionalConstructorCall);
                (pExpr as ExprConstant).OptionalConstructorCall = exprRet;
                break;

            /*************************************************************************************************
            *  TYPEEXPRs defined:
            *
            *  The following exprs are used to represent the results of type binding, and are defined as follows:
            *
            *  TYPEARGUMENTS - This wraps the type arguments for a class. It contains the TypeArray* which is
            *   associated with the AggregateType for the instantiation of the class.
            *
            *  TYPEORNAMESPACE - This is the base class for this set of Exprs. When binding a type, the result
            *   must be a type or a namespace. This Expr encapsulates that fact. The lhs member is the Expr
            *   tree that was bound to resolve the type or namespace.
            *
            *  TYPEORNAMESPACEERROR - This is the error class for the type or namespace exprs when we don't know
            *   what to bind it to.
            *
            *  The following two exprs all have a TYPEORNAMESPACE child, which is their fundamental type:
            *   POINTERTYPE - This wraps the sym for the pointer type.
            *   NULLABLETYPE - This wraps the sym for the nullable type.
            *
            *  CLASS - This represents an instantiation of a class.
            *
            *  NSPACE - This represents a namespace, which is the intermediate step when attempting to bind
            *   a qualified name.
            *
            *  ALIAS - This represents an alias
            *
            *************************************************************************************************/

            case ExpressionKind.Multi:
                exprRet = Visit((pExpr as ExprMulti).Left);
                Debug.Assert(exprRet != null);
                (pExpr as ExprMulti).Left = exprRet;
                exprRet = Visit((pExpr as ExprMulti).Operator);
                Debug.Assert(exprRet != null);
                (pExpr as ExprMulti).Operator = exprRet;
                break;

            case ExpressionKind.Concat:
                exprRet = Visit((pExpr as ExprConcat).FirstArgument);
                Debug.Assert(exprRet != null);
                (pExpr as ExprConcat).FirstArgument = exprRet;
                exprRet = Visit((pExpr as ExprConcat).SecondArgument);
                Debug.Assert(exprRet != null);
                (pExpr as ExprConcat).SecondArgument = exprRet;
                break;

            case ExpressionKind.ArrayInit:
                exprRet = Visit((pExpr as ExprArrayInit).OptionalArguments);
                (pExpr as ExprArrayInit).OptionalArguments = exprRet;
                exprRet = Visit((pExpr as ExprArrayInit).OptionalArgumentDimensions);
                (pExpr as ExprArrayInit).OptionalArgumentDimensions = exprRet;
                break;

            case ExpressionKind.Local:
            case ExpressionKind.Class:
            case ExpressionKind.MultiGet:
            case ExpressionKind.Wrap:
            case ExpressionKind.NoOp:
            case ExpressionKind.FieldInfo:
            case ExpressionKind.MethodInfo:
                break;

            default:
                pExpr.AssertIsBin();
                exprRet = Visit((pExpr as ExprBinOp).OptionalLeftChild);
                (pExpr as ExprBinOp).OptionalLeftChild = exprRet;
                exprRet = Visit((pExpr as ExprBinOp).OptionalRightChild);
                (pExpr as ExprBinOp).OptionalRightChild = exprRet;
                break;
            }
        }
Exemple #2
0
 protected virtual Expr VisitLIST(ExprList pExpr)
 {
     return(VisitEXPR(pExpr));
 }
Exemple #3
0
        private Expr GenerateUserDefinedBinaryOperator(ExprBinOp expr)
        {
            Debug.Assert(expr != null);
            PREDEFMETH pdm;

            switch (expr.Kind)
            {
            case ExpressionKind.LogicalOr: pdm = PREDEFMETH.PM_EXPRESSION_ORELSE_USER_DEFINED; break;

            case ExpressionKind.LogicalAnd: pdm = PREDEFMETH.PM_EXPRESSION_ANDALSO_USER_DEFINED; break;

            case ExpressionKind.LeftShirt: pdm = PREDEFMETH.PM_EXPRESSION_LEFTSHIFT_USER_DEFINED; break;

            case ExpressionKind.RightShift: pdm = PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT_USER_DEFINED; break;

            case ExpressionKind.BitwiseExclusiveOr: pdm = PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR_USER_DEFINED; break;

            case ExpressionKind.BitwiseOr: pdm = PREDEFMETH.PM_EXPRESSION_OR_USER_DEFINED; break;

            case ExpressionKind.BitwiseAnd: pdm = PREDEFMETH.PM_EXPRESSION_AND_USER_DEFINED; break;

            case ExpressionKind.Modulo: pdm = PREDEFMETH.PM_EXPRESSION_MODULO_USER_DEFINED; break;

            case ExpressionKind.Divide: pdm = PREDEFMETH.PM_EXPRESSION_DIVIDE_USER_DEFINED; break;

            case ExpressionKind.StringEq:
            case ExpressionKind.StringNotEq:
            case ExpressionKind.DelegateEq:
            case ExpressionKind.DelegateNotEq:
            case ExpressionKind.Eq:
            case ExpressionKind.NotEq:
            case ExpressionKind.GreaterThanOrEqual:
            case ExpressionKind.GreaterThan:
            case ExpressionKind.LessThanOrEqual:
            case ExpressionKind.LessThan:
                return(GenerateUserDefinedComparisonOperator(expr));

            case ExpressionKind.DelegateSubtract:
            case ExpressionKind.Subtract:
                pdm = expr.isChecked() ? PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED_USER_DEFINED : PREDEFMETH.PM_EXPRESSION_SUBTRACT_USER_DEFINED;
                break;

            case ExpressionKind.DelegateAdd:
            case ExpressionKind.Add:
                pdm = expr.isChecked() ? PREDEFMETH.PM_EXPRESSION_ADDCHECKED_USER_DEFINED : PREDEFMETH.PM_EXPRESSION_ADD_USER_DEFINED;
                break;

            case ExpressionKind.Multiply:
                pdm = expr.isChecked() ? PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED_USER_DEFINED : PREDEFMETH.PM_EXPRESSION_MULTIPLY_USER_DEFINED;
                break;

            default:
                throw Error.InternalCompilerError();
            }
            Expr p1     = expr.OptionalLeftChild;
            Expr p2     = expr.OptionalRightChild;
            Expr udcall = expr.OptionalUserDefinedCall;

            if (udcall != null)
            {
                Debug.Assert(udcall.Kind == ExpressionKind.Call || udcall.Kind == ExpressionKind.UserLogicalOp);
                if (udcall is ExprCall ascall)
                {
                    ExprList args = (ExprList)ascall.OptionalArguments;
                    Debug.Assert(args.OptionalNextListNode.Kind != ExpressionKind.List);
                    p1 = args.OptionalElement;
                    p2 = args.OptionalNextListNode;
                }
                else
                {
                    ExprUserLogicalOp userLogOp = udcall as ExprUserLogicalOp;
                    Debug.Assert(userLogOp != null);
                    ExprList args = (ExprList)userLogOp.OperatorCall.OptionalArguments;
                    Debug.Assert(args.OptionalNextListNode.Kind != ExpressionKind.List);
                    p1 = ((ExprWrap)args.OptionalElement).OptionalExpression;
                    p2 = args.OptionalNextListNode;
                }
            }
            p1 = Visit(p1);
            p2 = Visit(p2);
            FixLiftedUserDefinedBinaryOperators(expr, ref p1, ref p2);
            Expr methodInfo = GetExprFactory().CreateMethodInfo(expr.UserDefinedCallMethod);
            Expr call       = GenerateCall(pdm, p1, p2, methodInfo);

            // Delegate add/subtract generates a call to Combine/Remove, which returns System.Delegate,
            // not the operand delegate CType.  We must cast to the delegate CType.
            if (expr.Kind == ExpressionKind.DelegateSubtract || expr.Kind == ExpressionKind.DelegateAdd)
            {
                Expr pTypeOf = CreateTypeOf(expr.Type);
                return(GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, call, pTypeOf));
            }
            return(call);
        }