private void RecordReadInLocalFunction(int slot) { var localFunc = GetNearestLocalFunctionOpt(currentSymbol); Debug.Assert(localFunc != null); var usages = GetOrCreateLocalFuncUsages(localFunc); // If this slot is a struct with individually assignable // fields we need to record each field assignment separately, // since some fields may be assigned when this read is replayed VariableIdentifier id = variableBySlot[slot]; var type = VariableTypeWithAnnotations(id.Symbol).Type; Debug.Assert(!_emptyStructTypeCache.IsEmptyStructType(type)); if (EmptyStructTypeCache.IsTrackableStructType(type)) { foreach (var field in _emptyStructTypeCache.GetStructInstanceFields(type)) { int fieldSlot = GetOrCreateSlot(field, slot); if (fieldSlot > 0 && !State.IsAssigned(fieldSlot)) { RecordReadInLocalFunction(fieldSlot); } } } else { usages.ReadVars[slot] = true; } }
private UnassignedVariablesWalker( CSharpCompilation compilation, Symbol member, BoundNode node ) : base(compilation, member, node, EmptyStructTypeCache.CreateNeverEmpty()) { }
private IteratorAndAsyncCaptureWalker(CSharpCompilation compilation, MethodSymbol method, BoundNode node, HashSet <Symbol> initiallyAssignedVariables) : base(compilation, method, node, EmptyStructTypeCache.CreateNeverEmpty(), trackUnassignments: true, initiallyAssignedVariables: initiallyAssignedVariables) { }
protected LocalDataFlowPass( CSharpCompilation compilation, Symbol member, BoundNode node, EmptyStructTypeCache emptyStructs, bool trackUnassignments) : base(compilation, member, node, nonMonotonicTransferFunction: trackUnassignments) { _emptyStructTypeCache = emptyStructs; }
protected DataFlowPassBase( CSharpCompilation compilation, Symbol member, BoundNode node, EmptyStructTypeCache emptyStructs, bool trackUnassignments) : base(compilation, member, node, trackUnassignments: trackUnassignments) { _emptyStructTypeCache = emptyStructs; }
protected LocalDataFlowPass( CSharpCompilation compilation, Symbol?member, BoundNode node, EmptyStructTypeCache emptyStructs, bool trackUnassignments, int maxSlotDepth = 0) : base(compilation, member, node, nonMonotonicTransferFunction: trackUnassignments) { Debug.Assert(emptyStructs != null); _maxSlotDepth = maxSlotDepth; _emptyStructTypeCache = emptyStructs; }
internal static HashSet<Symbol> Analyze(CSharpCompilation compilation, Symbol member, BoundNode node, EmptyStructTypeCache emptyStructCache = null) { var walker = new UnassignedVariablesWalker(compilation, member, node, emptyStructCache); try { bool badRegion = false; var result = walker.Analyze(ref badRegion); return badRegion ? new HashSet<Symbol>() : result; } finally { walker.Free(); } }
UnassignedVariablesWalker(CSharpCompilation compilation, Symbol member, BoundNode node, EmptyStructTypeCache emptyStructCache = null) : base(compilation, member, node, emptyStructCache) { }
internal static HashSet <Symbol> Analyze(CSharpCompilation compilation, Symbol member, BoundNode node, EmptyStructTypeCache emptyStructCache = null) { var walker = new UnassignedVariablesWalker(compilation, member, node, emptyStructCache); try { bool badRegion = false; var result = walker.Analyze(ref badRegion); return(badRegion ? new HashSet <Symbol>() : result); } finally { walker.Free(); } }