public static BoundStatement Rewrite(BoundStatement node, MethodSymbol containingSymbol, NamedTypeSymbol containingType, SynthesizedSubmissionFields previousSubmissionFields, Compilation compilation)
 {
     Debug.Assert(node != null);
     var rewriter = new CallRewriter(containingSymbol, containingType, previousSubmissionFields, compilation);
     var result = (BoundStatement)rewriter.Visit(node);
     return result;
 }
 private CallRewriter(MethodSymbol containingSymbol, NamedTypeSymbol containingType, SynthesizedSubmissionFields previousSubmissionFields, Compilation compilation)
 {
     this.compilation = compilation;
     this.containingSymbol = containingSymbol;
     this.containingType = containingType ?? containingSymbol.ContainingType;
     this.previousSubmissionFields = previousSubmissionFields;
 }
 internal ConstructedEmptyAnonymousTypeSymbol(AnonymousTypeTemplateSymbol constructedFrom, AnonymousTypeDescriptor typeDescr)
 {
     this.template = constructedFrom;
     this.typeDescr = typeDescr;
     
     this.ctorMethod = new AnonymousTypeConstructorSymbol(this);
 }
Exemplo n.º 4
0
 public static BoundStatement Rewrite(BoundStatement node, MethodSymbol containingMethod, Compilation compilation, bool generateDebugInfo, out bool sawLambdas)
 {
     Debug.Assert(node != null);
     var rewriter = new ControlFlowRewriter(containingMethod, compilation, generateDebugInfo);
     var result = (BoundStatement)rewriter.Visit(node);
     sawLambdas = rewriter.sawLambdas;
     return result;
 }
 public UnaryOperatorSignature(UnaryOperatorKind kind, TypeSymbol operandType, TypeSymbol returnType, MethodSymbol method = null)
     : this()
 {
     this.Kind = kind;
     this.OperandType = operandType;
     this.ReturnType = returnType;
     this.Method = method;
 }
        internal static BoundStatement AnalyzeMethodBody(MethodBodyCompiler methodCompiler, MethodSymbol method, BoundBlock body, DiagnosticBag diagnostics)
        {
            Debug.Assert(diagnostics != null);

            body = FlowAnalysisPass.Rewrite(method, body, diagnostics);
            var analyzedBody = (BoundBlock)RewritePass.Rewrite(methodCompiler, method.ContainingType, body);
            return RewritePass.InsertPrologueSequencePoint(analyzedBody, method);
        }
Exemplo n.º 7
0
        public List<GuardedParameter> Inspect(MethodDeclarationSyntax method, MethodSymbol methodSymbol)
        {
            List<GuardedParameter> guardedParameters = new List<GuardedParameter>();

            InspectHierarchy(methodSymbol, guardedParameters);

            return guardedParameters;
        }
        internal void AddMethod(MethodSymbol methodSymbol)
        {
            Debug.Assert(methodSymbol != null);

            // TODO--need to turn this guy into a token in conjuction with emitter
            stream.Add(methodSymbol);
            this.PutSymbol(methodSymbol);
            codesize += 4; // <token>
        }
        public static BoundStatement Rewrite(BoundStatement node, MethodSymbol containingSymbol, Compilation compilation)
        {
            Debug.Assert(node != null);
            Debug.Assert(compilation != null);

            var rewriter = new IsAndAsRewriter(containingSymbol, compilation);
            var result = (BoundStatement)rewriter.Visit(node);
            return result;
        }
 public BinaryOperatorSignature(BinaryOperatorKind kind, TypeSymbol leftType, TypeSymbol rightType, TypeSymbol returnType, MethodSymbol method = null)
     : this()
 {
     this.Kind = kind;
     this.LeftType = leftType;
     this.RightType = rightType;
     this.ReturnType = returnType;
     this.Method = method;
 }
Exemplo n.º 11
0
        protected RegionPlace regionPlace; // tells whether we are analyzing the region before, during, or after the region

        protected RegionAnalysisWalker(Compilation compilation, SyntaxTree tree, MethodSymbol method, BoundStatement block, TextSpan region, ThisSymbolCache thisSymbolCache, HashSet<Symbol> unassignedVariables = null, bool trackUnassignmentsInLoops = false)
            : base(compilation, tree, method, block, thisSymbolCache, unassignedVariables, trackUnassignmentsInLoops)
        {
            this.region = region;

            // assign slots to the parameters
            foreach (var parameter in method.Parameters)
            {
                MakeSlot(parameter);
            }
        }
Exemplo n.º 12
0
        public void InspectHierarchy(MethodSymbol methodSymbol, List<GuardedParameter> guardedParameters)
        {
            MethodSymbol overriddenMethod = methodSymbol.OverriddenMethod;
            TypeSymbol owningType = methodSymbol.ContainingType;

            if (overriddenMethod != null)
            {
                InspectHierarchy(overriddenMethod, guardedParameters);
            }
            else
            {
                //Check to see if this method is an implementation of an interface method

                var members = owningType.AllInterfaces.SelectMany(x => x.GetMembers());

                IEnumerable<Symbol> interfaceMethods = members.
                    Where(m => methodSymbol.Equals(owningType.FindImplementationForInterfaceMember(m)));

                foreach (Symbol interfaceMethod in interfaceMethods)
                {
                    MethodSymbol interfaceMethodSymbol = interfaceMethod as MethodSymbol;
                    if (interfaceMethodSymbol != null)
                    {
                        InspectHierarchy(interfaceMethodSymbol, guardedParameters);
                    }
                }
            }

            foreach (var parameter in methodSymbol.Parameters)
            {
                GuardedParameter guardedParameter = null;

                foreach (var attribute in parameter.GetAttributes())
                {
                    //TODO: Think of a nicer way to ensure the type is declared in the correct assembly and derives from the correct type
                    Type baseAutoGuardType = typeof(AutoGuardAttribute);
                    if (string.Equals(attribute.AttributeClass.BaseType.ContainingAssembly.Name, baseAutoGuardType.Assembly.GetName().Name, StringComparison.Ordinal) &&
                        string.Equals(attribute.AttributeClass.BaseType.Name, baseAutoGuardType.Name, StringComparison.Ordinal))
                    {
                        if (guardedParameter == null)
                        {
                            guardedParameter = new GuardedParameter();
                            guardedParameter.ParameterName = parameter.Name;
                            guardedParameter.ParameterType = parameter.Type;

                            guardedParameters.Add(guardedParameter);
                        }

                        guardedParameter.Emitters.Add(new EmitterAttributePair(_emitterResolver.Resolve(attribute.AttributeClass.Name), attribute));
                    }
                }
            }
        }
Exemplo n.º 13
0
        internal static BoundStatementList AnalyzeFieldInitializers(MethodBodyCompiler methodCompiler, MethodSymbol constructor, ReadOnlyArray<BoundInitializer> boundInitializers)
        {
            if (boundInitializers.IsNull)
            {
                return null;
            }

            // The lowered tree might be reused in multiple constructors. Therefore, unless there is just a single constructor 
            // (e.g. in interactive submission), the lowered code should not refer to it.
            var initializerStatements = InitializerRewriter.Rewrite(boundInitializers, constructor.IsInteractiveSubmissionConstructor ? constructor : null);
            return (BoundStatementList)RewritePass.Rewrite(methodCompiler, constructor.ContainingType, initializerStatements);
        }
 public override BoundNode VisitLambda(BoundLambda node)
 {
     var oldContainingSymbol = this.containingSymbol;
     try
     {
         this.containingSymbol = node.Symbol;
         return base.VisitLambda(node);
     }
     finally
     {
         this.containingSymbol = oldContainingSymbol;
     }
 }
Exemplo n.º 15
0
 internal static IEnumerable<StatementSyntax> Analyze(Compilation compilation, MethodSymbol sourceMethod, BoundNode node, BoundNode firstInRegion, BoundNode lastInRegion)
 {
     var walker = new ReturnStatementsWalker(compilation, sourceMethod, node, firstInRegion, lastInRegion);
     try
     {
         bool badRegion = false;
         walker.Analyze(ref badRegion);
         return badRegion ? Enumerable.Empty<StatementSyntax>() : walker.returnStatements.ToArray();
     }
     finally
     {
         walker.Free();
     }
 }
Exemplo n.º 16
0
        public Function(Chunk chunk, int nFunction, SemanticModel model, MethodSymbol sym)
        {
            Chunk = chunk;
            Model = model;
            MethodSymbol = sym;
            NumFunction = nFunction;

            EmittedInstructions = new List<string>();
            EmittedLabels = new Dictionary<string, int>();
            Registers = new List<FlatValue>();
            FunctionValues = new List<FlatValue>();
            NamedRegisters = new Dictionary<string, int>();
            MetaValues = new Dictionary<string, FlatValue>();
            PackedRegisters = -1;
            InitializeMetadata();
        }
Exemplo n.º 17
0
            public ExpandedVarargsMethodSymbol(MethodSymbol underlyingMethod, BoundArgListOperator argList)
            {
                this.underlyingMethod = underlyingMethod;

                ArrayBuilder<ParameterSymbol> builder = ArrayBuilder<ParameterSymbol>.GetInstance();
                for (int i = 0; i < argList.Arguments.Count; ++i)
                {
                    Debug.Assert(argList.Arguments[i].Type != null);

                    builder.Add(new SynthesizedParameterSymbol(
                        container: this, 
                        type: argList.Arguments[i].Type,
                        ordinal: i + underlyingMethod.ParameterCount,
                        refKind: argList.ArgumentRefKindsOpt.IsNullOrEmpty ? RefKind.None : argList.ArgumentRefKindsOpt[i],
                        name: "")); // these fake parameters are never accessed by name.
                }

                this.extraParameters = builder.ToReadOnlyAndFree();
            }
 internal ReadOnlyArray<TypeSymbol> ArgumentTypes(MethodSymbol method)
 {
     return new TypeMap(
         IndexedTypeParameterSymbol.Take(SyntaxArity).AsReadOnly<TypeSymbol>(),
         method.TypeParameters.Cast<TypeParameterSymbol, TypeSymbol>()).SubstituteTypes(declaredParameterTypes);
 }
Exemplo n.º 19
0
 internal ReturnStatementsWalker(Compilation compilation, MethodSymbol sourceMethod, BoundNode node, BoundNode firstInRegion, BoundNode lastInRegion)
     : base(compilation, sourceMethod, node, firstInRegion, lastInRegion)
 {
 }
Exemplo n.º 20
0
 public static FlatValue StaticMethod(MethodSymbol value)
 {
     return new FlatValue() { ValueType = FlatValueType.VT_StaticMethod, Object = value };
 }
 internal SynthesizedStruct(MethodSymbol topLevelMethod, string name)
     : base(topLevelMethod, name) { }
Exemplo n.º 22
0
        protected FlowAnalysisWalker(
            Compilation compilation,
            SyntaxTree tree,
            MethodSymbol method,
            BoundStatement block,
            ThisSymbolCache thisSymbolCache = null,
            HashSet<Symbol> initiallyAssignedVariables = null,
            bool trackUnassignmentsInLoops = false)
        {
            this.compilation = compilation;
            this.tree = tree;
            this.method = method;
            this.block = block;
            this.thisSymbolCache = thisSymbolCache ?? new ThisSymbolCache();
            this.initiallyAssignedVariables = initiallyAssignedVariables;
            this.loopHeadState = trackUnassignmentsInLoops ? new Dictionary<BoundLoopStatement, FlowAnalysisLocalState>() : null;

            // TODO: mark "this" as not assigned in a struct constructor (unless it has no fields)
            // TODO: accommodate instance variables of a local variable of struct type.
        }
Exemplo n.º 23
0
        public FlatOperand Resolve(MethodSymbol method, FlatOperand fop_type, FlatOperand into_lvalue, List<FlatStatement> instructions)
        {
            string method_name = method.GetFullyQualifiedName();

            if (into_lvalue == null)
            {
                FlatOperand register_fop = AllocateRegister("");
                into_lvalue = register_fop.GetLValue(this, instructions);
            }

            FlatOperand fop_methodname = FlatOperand.Immediate(FlatValue.String(method_name));

            if (method.IsStatic)
            {
                instructions.Add(FlatStatement.RESOLVESTATICMETHOD(into_lvalue,fop_type,fop_methodname));
                return into_lvalue.AsRValue(FlatValue.StaticMethod(method));
            }

            instructions.Add(FlatStatement.RESOLVEMETHOD(into_lvalue, fop_type, fop_methodname));
            return into_lvalue.AsRValue(FlatValue.Method(method));
        }
 public FixedBinder(FixedStatementSyntax syntax, MethodSymbol owner, Binder enclosing)
     : base(owner, enclosing)
 {
     this.syntax = syntax;
 }
 private IsAndAsRewriter(MethodSymbol containingSymbol, Compilation compilation)
 {
     this.compilation = compilation;
     this.containingSymbol = containingSymbol;
 }
Exemplo n.º 26
0
            public void Add(MethodSymbol ms)
            {
                FlatArrayBuilder fab = new FlatArrayBuilder();
                fab.Add(FlatValue.Int32(ms.IsStatic ? (int)ClassMemberType.StaticMethod : (int)ClassMemberType.Method));
                fab.Add(FlatValue.String(ms.GetFullyQualifiedName()));

                Function f;
                if (!Chunk.Functions.TryGetValue(ms, out f))
                {
                    throw new NotImplementedException("Method not found " + ms.ToString());
                }

                fab.Add(FlatValue.Int32(f.NumFunction));

                Members.Add(fab.GetFlatValue());
            }
Exemplo n.º 27
0
        public void AddFunction(MethodSymbol ms)
        {
            Function f;
            if (Functions.TryGetValue(ms, out f))
            {
                return;
            }
            int nFunction = FunctionsByNumber.Count;
            f = new Function(this, nFunction, Model, ms);
            Functions.Add(f.MethodSymbol, f);
            FunctionsByNumber.Add(f);

            TypeExtraInfo tei = AddTypeExtraInfo(ms.ContainingType);
            tei.MetadataGenerator.Add(ms);
        }
Exemplo n.º 28
0
 /// <summary>
 /// Perform flow analysis, reporting all necessary diagnostics.  Returns true if the end of
 /// the body might be reachable..
 /// </summary>
 /// <param name="compilation"></param>
 /// <param name="tree"></param>
 /// <param name="method"></param>
 /// <param name="block"></param>
 /// <param name="diagnostics"></param>
 /// <returns></returns>
 public static bool Analyze(Compilation compilation, SyntaxTree tree, MethodSymbol method, BoundStatement block, DiagnosticBag diagnostics)
 {
     var walker = new FlowAnalysisWalker(compilation, tree, method, block);
     var result = walker.Analyze(diagnostics);
     walker.Free();
     return result;
 }
 private OperatorRewriter(MethodSymbol containingSymbol, Compilation compilation)
 {
     this.compilation = compilation;
     this.containingSymbol = containingSymbol;
 }
        /// <summary>
        /// Synthesize a no-argument call to a given method, possibly applying a conversion to the receiver.
        /// 
        /// If the receiver is of struct type and the method is an interface method, then skip the conversion
        /// and just call the interface method directly - the code generator will detect this and generate a 
        /// constrained virtual call.
        /// </summary>
        /// <param name="syntax">A syntax node to attach to the synthesized bound node.</param>
        /// <param name="receiver">Receiver of method call.</param>
        /// <param name="method">Method to invoke.</param>
        /// <param name="receiverConversion">Conversion to be applied to the receiver if not calling an interface method on a struct.</param>
        /// <param name="convertedReceiverType">Type of the receiver after applying the conversion.</param>
        /// <returns>A BoundExpression representing the call.</returns>
        private static BoundExpression SynthesizeCall(SyntaxNode syntax, BoundExpression receiver, MethodSymbol method, Conversion receiverConversion, TypeSymbol convertedReceiverType)
        {
            if (receiver.Type.TypeKind == TypeKind.Struct && method.ContainingType.TypeKind == TypeKind.Interface)
            {
                Debug.Assert(receiverConversion.IsBoxing);

                // NOTE: The spec says that disposing of a struct enumerator won't cause any 
                // unnecessary boxing to occur.  However, Dev10 extends this improvement to the
                // GetEnumerator call as well.

                // We're going to let the emitter take care of avoiding the extra boxing. 
                // When it sees an interface call to a struct, it will generate a constrained
                // virtual call, which will skip boxing, if possible.

                // CONSIDER: In cases where the struct implicitly implements the interface method
                // (i.e. with a public method), we could save a few bytes of IL by creating a 
                // BoundCall to the struct method rather than the interface method (so that the
                // emitter wouldn't need to create a constrained virtual call).  It is not clear 
                // what effect this would have on back compat.

                // NOTE: This call does not correspond to anything that can be written in C# source.
                // We're invoking the interface method directly on the struct (which may have a private
                // explicit implementation).  The code generator knows how to handle it though.

                // receiver.InterfaceMethod()
                return BoundCall.Synthesized(syntax, receiver, method);
            }
            else
            {
                // ((Interface)receiver).InterfaceMethod()
                return BoundCall.Synthesized(
                    syntax: syntax,
                    receiverOpt: SynthesizeConversion(
                        syntax: syntax,
                        operand: receiver,
                        conversion: receiverConversion,
                        type: convertedReceiverType),
                    method: method);
            }
        }