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); }
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); }
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; }
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); } }
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)); } } } }
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; } }
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(); } }
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(); }
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); }
internal ReturnStatementsWalker(Compilation compilation, MethodSymbol sourceMethod, BoundNode node, BoundNode firstInRegion, BoundNode lastInRegion) : base(compilation, sourceMethod, node, firstInRegion, lastInRegion) { }
public static FlatValue StaticMethod(MethodSymbol value) { return new FlatValue() { ValueType = FlatValueType.VT_StaticMethod, Object = value }; }
internal SynthesizedStruct(MethodSymbol topLevelMethod, string name) : base(topLevelMethod, name) { }
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. }
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; }
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()); }
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); }
/// <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); } }