/// <summary> /// Determine the constant value of this local and the corresponding diagnostics. /// Set both to constantTuple in a single operation for thread safety. /// </summary> /// <param name="inProgress">Null for the initial call, non-null if we are in the process of evaluating a constant.</param> /// <param name="boundInitValue">If we already have the bound node for the initial value, pass it in to avoid recomputing it.</param> private void MakeConstantTuple(LocalSymbol inProgress, BoundExpression boundInitValue) { if (this.IsConst && this.constantTuple == null) { var value = Microsoft.CodeAnalysis.ConstantValue.Bad; var initValueNodeLocation = this.initializer.Value.Location; var diagnostics = DiagnosticBag.GetInstance(); if (inProgress == this) { // The problem is circularity, but Dev12 reports ERR_NotConstantExpression instead of ERR_CircConstValue. // Also, the native compiler squiggles the RHS for ERR_NotConstantExpression but the LHS for ERR_CircConstValue. diagnostics.Add(ErrorCode.ERR_NotConstantExpression, initValueNodeLocation, this); } else { var type = this.Type; if (boundInitValue == null) { var inProgressBinder = new LocalInProgressBinder(this, this.binder); boundInitValue = inProgressBinder.BindVariableOrAutoPropInitializer(this.initializer, type, diagnostics); } value = ConstantValueUtils.GetAndValidateConstantValue(boundInitValue, this, type, initValueNodeLocation, diagnostics); } Interlocked.CompareExchange(ref this.constantTuple, new EvaluatedConstant(value, diagnostics.ToReadOnlyAndFree()), null); } }
/// <summary> /// Determine the constant value of this local and the corresponding diagnostics. /// Set both to constantTuple in a single operation for thread safety. /// </summary> /// <param name="inProgress">Null for the initial call, non-null if we are in the process of evaluating a constant.</param> /// <param name="boundInitValue">If we already have the bound node for the initial value, pass it in to avoid recomputing it.</param> private void MakeConstantTuple(LocalSymbol inProgress, BoundExpression boundInitValue) { if (this.IsConst && _constantTuple == null) { var value = Microsoft.CodeAnalysis.ConstantValue.Bad; var initValueNodeLocation = _initializer.Value.Location; var diagnostics = DiagnosticBag.GetInstance(); Debug.Assert(inProgress != this); var type = this.Type; if (boundInitValue == null) { var inProgressBinder = new LocalInProgressBinder(this, this._initializerBinder); boundInitValue = inProgressBinder.BindVariableOrAutoPropInitializer(_initializer, this.RefKind, type, diagnostics); } value = ConstantValueUtils.GetAndValidateConstantValue(boundInitValue, this, type, initValueNodeLocation, diagnostics); Interlocked.CompareExchange(ref _constantTuple, new EvaluatedConstant(value, diagnostics.ToReadOnlyAndFree()), null); } }
/// <summary> /// Determine the constant value of this local and the corresponding diagnostics. /// Set both to constantTuple in a single operation for thread safety. /// </summary> /// <param name="inProgress">Null for the initial call, non-null if we are in the process of evaluating a constant.</param> /// <param name="boundInitValue">If we already have the bound node for the initial value, pass it in to avoid recomputing it.</param> private void MakeConstantTuple(LocalSymbol inProgress, BoundExpression boundInitValue) { if (this.IsConst && this.constantTuple == null && this.initializer != null) { var value = Microsoft.CodeAnalysis.ConstantValue.Bad; var initValueNodeLocation = this.initializer.Value.Location; var diagnostics = DiagnosticBag.GetInstance(); if (inProgress == this) { // The problem is circularity, but Dev12 reports ERR_NotConstantExpression instead of ERR_CircConstValue. // Also, the native compiler squiggles the RHS for ERR_CircConstValue but the LHS for ERR_CircConstValue. diagnostics.Add(ErrorCode.ERR_NotConstantExpression, initValueNodeLocation, this); } else { var type = this.Type; if (boundInitValue == null) { var inProgressBinder = new LocalInProgressBinder(this, this.binder); boundInitValue = inProgressBinder.BindVariableInitializer(this.initializer, type, diagnostics); } value = ConstantValueUtils.GetAndValidateConstantValue(boundInitValue, this, type, initValueNodeLocation, diagnostics); } Interlocked.CompareExchange(ref this.constantTuple, new EvaluatedConstant(value, diagnostics.ToReadOnlyAndFree()), null); } }
/// <summary> /// Determine the constant value of this local and the corresponding diagnostics. /// Set both to constantTuple in a single operation for thread safety. /// </summary> /// <param name="inProgress">Null for the initial call, non-null if we are in the process of evaluating a constant.</param> /// <param name="boundInitValue">If we already have the bound node for the initial value, pass it in to avoid recomputing it.</param> private void MakeConstantTuple(LocalSymbol inProgress, BoundExpression boundInitValue) { if (this.IsConst && _constantTuple == null) { var value = Microsoft.CodeAnalysis.ConstantValue.Bad; var initValueNodeLocation = _initializer.Value.Location; var diagnostics = DiagnosticBag.GetInstance(); Debug.Assert(inProgress != this); var type = this.Type; if (boundInitValue == null) { var inProgressBinder = new LocalInProgressBinder(this, this.binder); boundInitValue = inProgressBinder.BindVariableOrAutoPropInitializer(_initializer, this.RefKind, type, diagnostics); } value = ConstantValueUtils.GetAndValidateConstantValue(boundInitValue, this, type, initValueNodeLocation, diagnostics); Interlocked.CompareExchange(ref _constantTuple, new EvaluatedConstant(value, diagnostics.ToReadOnlyAndFree()), null); } }