Beispiel #1
0
        public override Value?Visit(ConditionalExpression conditionalExpression)
        {
            conditionalExpression.ValidateNotNull(nameof(conditionalExpression));
            var result = LookupVariable(conditionalExpression.ResultVariable.Name);

            EmitLocation(conditionalExpression);
            var condition = conditionalExpression.Condition.Accept(this);

            if (condition == null)
            {
                return(null);
            }

            EmitLocation(conditionalExpression);

            var condBool = InstructionBuilder.Compare(RealPredicate.OrderedAndNotEqual, condition, Context.CreateConstant(0.0))
                           .RegisterName("ifcond");

            var function = InstructionBuilder.InsertFunction;

            if (function is null)
            {
                throw new InternalCodeGeneratorException("ICE: expected block that is attached to a function at this point");
            }

            var thenBlock     = function.AppendBasicBlock("then");
            var elseBlock     = function.AppendBasicBlock("else");
            var continueBlock = function.AppendBasicBlock("ifcont");

            InstructionBuilder.Branch(condBool, thenBlock, elseBlock);

            // generate then block instructions
            InstructionBuilder.PositionAtEnd(thenBlock);

            // InstructionBuilder.InserBlock after this point is !null
            Debug.Assert(InstructionBuilder.InsertBlock != null, "expected non-null InsertBlock");
            var thenValue = conditionalExpression.ThenExpression.Accept(this);

            if (thenValue == null)
            {
                return(null);
            }

            InstructionBuilder.Store(thenValue, result);
            InstructionBuilder.Branch(continueBlock);

            // generate else block
            InstructionBuilder.PositionAtEnd(elseBlock);
            var elseValue = conditionalExpression.ElseExpression.Accept(this);

            if (elseValue == null)
            {
                return(null);
            }

            InstructionBuilder.Store(elseValue, result);
            InstructionBuilder.Branch(continueBlock);

            // generate continue block
            InstructionBuilder.PositionAtEnd(continueBlock);

            // since the Alloca is created as a non-opaque pointer it is OK to just use the
            // ElementType. If full opaque pointer support was used, then the Lookup map
            // would need to include the type of the value allocated.
            return(InstructionBuilder.Load(result.ElementType, result)
                   .RegisterName("ifresult"));
        }