Ejemplo n.º 1
0
        public override BoundNode VisitStackAllocArrayCreation(BoundStackAllocArrayCreation stackAllocNode)
        {
            var rewrittenCount = VisitExpression(stackAllocNode.Count);
            var type           = stackAllocNode.Type;

            if (rewrittenCount.ConstantValue?.Int32Value == 0)
            {
                // either default(span) or nullptr
                return(_factory.Default(type));
            }

            var elementType = stackAllocNode.ElementType;

            var initializerOpt = stackAllocNode.InitializerOpt;

            if (initializerOpt != null)
            {
                initializerOpt = initializerOpt.Update(VisitList(initializerOpt.Initializers));
            }

            if (type.IsPointerType())
            {
                var stackSize = RewriteStackAllocCountToSize(rewrittenCount, elementType);
                return(new BoundConvertedStackAllocExpression(stackAllocNode.Syntax, elementType, stackSize, initializerOpt, stackAllocNode.Type));
            }
            else if (TypeSymbol.Equals(type.OriginalDefinition, _compilation.GetWellKnownType(WellKnownType.core_Span_T), TypeCompareKind.ConsiderEverything2))
            {
                var spanType    = (NamedTypeSymbol)stackAllocNode.Type;
                var sideEffects = ArrayBuilder <BoundExpression> .GetInstance();

                var locals = ArrayBuilder <LocalSymbol> .GetInstance();

                var countTemp = CaptureExpressionInTempIfNeeded(rewrittenCount, sideEffects, locals);
                var stackSize = RewriteStackAllocCountToSize(countTemp, elementType);
                stackAllocNode = new BoundConvertedStackAllocExpression(stackAllocNode.Syntax, elementType, stackSize, initializerOpt, spanType);

                BoundExpression constructorCall;
                if (TryGetWellKnownTypeMember(stackAllocNode.Syntax, WellKnownMember.System_Span_T__ctor, out MethodSymbol spanConstructor))
                {
                    constructorCall = _factory.New((MethodSymbol)spanConstructor.SymbolAsMember(spanType), stackAllocNode, countTemp);
                }
                else
                {
                    constructorCall = new BoundBadExpression(
                        syntax: stackAllocNode.Syntax,
                        resultKind: LookupResultKind.NotInvocable,
                        symbols: ImmutableArray <Symbol> .Empty,
                        childBoundNodes: ImmutableArray <BoundExpression> .Empty,
                        type: ErrorTypeSymbol.UnknownResultType);
                }

                return(new BoundSequence(
                           syntax: stackAllocNode.Syntax,
                           locals: locals.ToImmutableAndFree(),
                           sideEffects: sideEffects.ToImmutableAndFree(),
                           value: constructorCall,
                           type: spanType));
            }
            else
            {
                throw ExceptionUtilities.UnexpectedValue(type);
            }
        }
Ejemplo n.º 2
0
 public override BoundNode VisitConvertedStackAllocExpression(BoundConvertedStackAllocExpression stackAllocNode)
 {
     return(VisitStackAllocArrayCreation(stackAllocNode));
 }