private AnalysisEntity( ISymbol?symbol, ImmutableArray <AbstractIndex> indices, SyntaxNode?instanceReferenceOperationSyntax, InterproceduralCaptureId?captureId, PointsToAbstractValue location, ITypeSymbol type, AnalysisEntity?parent, bool isThisOrMeInstance) { Debug.Assert(!indices.IsDefault); Debug.Assert(symbol != null || !indices.IsEmpty || instanceReferenceOperationSyntax != null || captureId.HasValue); Debug.Assert(parent == null || parent.Type.HasValueCopySemantics() || !indices.IsEmpty); Symbol = symbol; Indices = indices; InstanceReferenceOperationSyntax = instanceReferenceOperationSyntax; CaptureId = captureId; InstanceLocation = location; Type = type; Parent = parent; IsThisOrMeInstance = isThisOrMeInstance; _ignoringLocationHashCodeParts = ComputeIgnoringLocationHashCodeParts(); EqualsIgnoringInstanceLocationId = HashUtilities.Combine(_ignoringLocationHashCodeParts); }
protected override PropertySetAbstractValue VisitAssignmentOperation(IAssignmentOperation operation, object?argument) { PropertySetAbstractValue?baseValue = base.VisitAssignmentOperation(operation, argument); // If we need to evaluate hazardous usages on initializations, track assignments of properties and fields, so // at the end of the CFG we can figure out which assignment operations to flag. if (this.TrackedFieldPropertyAssignments != null && this.TrackedTypeSymbols.Any(s => operation.Target.Type.GetBaseTypesAndThis().Contains(s)) && (operation.Target.Kind == OperationKind.PropertyReference || operation.Target.Kind == OperationKind.FieldReference || operation.Target.Kind == OperationKind.FlowCaptureReference)) { AnalysisEntity?targetAnalysisEntity = null; if (operation.Target.Kind == OperationKind.FlowCaptureReference) { if (this.TryUnwrapFlowCaptureReference(operation.Target, out IOperation? lValueOperation, OperationKind.PropertyReference, OperationKind.FieldReference)) { this.AnalysisEntityFactory.TryCreate(lValueOperation, out targetAnalysisEntity); } } else { this.AnalysisEntityFactory.TryCreate(operation.Target, out targetAnalysisEntity); } if (targetAnalysisEntity != null) { PointsToAbstractValue pointsToAbstractValue = this.GetPointsToAbstractValue(operation.Value); if (!this.TrackedFieldPropertyAssignments.TryGetValue( targetAnalysisEntity, out TrackedAssignmentData trackedAssignmentData)) { trackedAssignmentData = new TrackedAssignmentData(); this.TrackedFieldPropertyAssignments.Add(targetAnalysisEntity, trackedAssignmentData); } if (pointsToAbstractValue.Kind == PointsToAbstractValueKind.KnownLocations) { foreach (AbstractLocation abstractLocation in pointsToAbstractValue.Locations) { trackedAssignmentData.TrackAssignmentWithAbstractLocation(operation, abstractLocation); } } else if (pointsToAbstractValue.Kind is PointsToAbstractValueKind.Unknown or PointsToAbstractValueKind.UnknownNotNull) { trackedAssignmentData.TrackAssignmentWithUnknownLocation(operation); } else if (pointsToAbstractValue.NullState == NullAbstractValue.Null) { // Do nothing. } else { Debug.Fail($"Unhandled PointsToAbstractValue: Kind = {pointsToAbstractValue.Kind}, NullState = {pointsToAbstractValue.NullState}"); } } }
public ArgumentInfo( IOperation operation, AnalysisEntity?analysisEntity, PointsToAbstractValue instanceLocation, TAbstractAnalysisValue value) { Operation = operation; AnalysisEntity = analysisEntity; InstanceLocation = instanceLocation; Value = value; }
protected virtual void SetAbstractValueForAssignment(AnalysisEntity targetAnalysisEntity, IOperation?assignedValueOperation, TAbstractAnalysisValue assignedValue) { AnalysisEntity?assignedValueEntity = null; if (assignedValueOperation != null) { var success = AnalysisEntityFactory.TryCreate(assignedValueOperation, out assignedValueEntity); Debug.Assert(success || assignedValueEntity == null); } SetAbstractValueForAssignment(targetAnalysisEntity, assignedValueEntity, assignedValueOperation, assignedValue); }
public bool TryCreateForSymbolDeclaration(ISymbol symbol, [NotNullWhen(returnValue: true)] out AnalysisEntity?analysisEntity) { Debug.Assert(symbol.Kind is SymbolKind.Local or SymbolKind.Parameter or SymbolKind.Field or SymbolKind.Property); var indices = ImmutableArray <AbstractIndex> .Empty; IOperation?instance = null; var type = symbol.GetMemberOrLocalOrParameterType(); RoslynDebug.Assert(type != null); return(TryCreate(symbol, indices, type, instance, out analysisEntity)); }
private AbstractLocation(IOperation?creation, ImmutableStack <IOperation>?creationCallStack, AnalysisEntity?analysisEntity, ISymbol?symbol, InterproceduralCaptureId?captureId, ITypeSymbol?locationType, bool isSpecialSingleton) { Debug.Assert(isSpecialSingleton ^ (locationType != null)); CreationOpt = creation; CreationCallStack = creationCallStack ?? ImmutableStack <IOperation> .Empty; AnalysisEntityOpt = analysisEntity; SymbolOpt = symbol; CaptureIdOpt = captureId; LocationTypeOpt = locationType; _isSpecialSingleton = isSpecialSingleton; }
internal AnalysisEntityFactory( ControlFlowGraph controlFlowGraph, WellKnownTypeProvider wellKnownTypeProvider, Func <IOperation, PointsToAbstractValue>?getPointsToAbstractValue, Func <bool> getIsInsideAnonymousObjectInitializer, Func <IFlowCaptureOperation, bool> getIsLValueFlowCapture, INamedTypeSymbol containingTypeSymbol, AnalysisEntity?interproceduralInvocationInstance, AnalysisEntity?interproceduralThisOrMeInstanceForCaller, ImmutableStack <IOperation>?interproceduralCallStack, ImmutableDictionary <ISymbol, PointsToAbstractValue>?interproceduralCapturedVariablesMap, Func <IOperation, AnalysisEntity?>?interproceduralGetAnalysisEntityForFlowCapture, Func <ISymbol, ImmutableStack <IOperation>?> getInterproceduralCallStackForOwningSymbol) { _controlFlowGraph = controlFlowGraph; _wellKnownTypeProvider = wellKnownTypeProvider; _getPointsToAbstractValue = getPointsToAbstractValue; _getIsInsideAnonymousObjectInitializer = getIsInsideAnonymousObjectInitializer; _getIsLValueFlowCapture = getIsLValueFlowCapture; _interproceduralThisOrMeInstanceForCaller = interproceduralThisOrMeInstanceForCaller; _interproceduralCallStack = interproceduralCallStack; _interproceduralGetAnalysisEntityForFlowCapture = interproceduralGetAnalysisEntityForFlowCapture; _getInterproceduralCallStackForOwningSymbol = getInterproceduralCallStackForOwningSymbol; _analysisEntityMap = new Dictionary <IOperation, AnalysisEntity?>(); _tupleElementEntitiesMap = new Dictionary <ITupleOperation, ImmutableArray <AnalysisEntity> >(); _captureIdEntityMap = new Dictionary <CaptureId, AnalysisEntity>(); _captureIdCopyValueMap = new Dictionary <CaptureId, CopyAbstractValue>(); _instanceLocationsForSymbols = new Dictionary <ISymbol, PointsToAbstractValue>(); if (interproceduralCapturedVariablesMap != null) { _instanceLocationsForSymbols.AddRange(interproceduralCapturedVariablesMap); } if (interproceduralInvocationInstance != null) { ThisOrMeInstance = interproceduralInvocationInstance; } else { var thisOrMeInstanceLocation = AbstractLocation.CreateThisOrMeLocation(containingTypeSymbol, interproceduralCallStack); var instanceLocation = PointsToAbstractValue.Create(thisOrMeInstanceLocation, mayBeNull: false); ThisOrMeInstance = AnalysisEntity.CreateThisOrMeInstance(containingTypeSymbol, instanceLocation); } }
/// <summary> /// Updates the the copy values for all entities that are part of the given <paramref name="copyValue"/> set, /// i.e. <see cref="CopyAbstractValue.AnalysisEntities"/>. /// We do not support the <see cref="SetAbstractValue(AnalysisEntity, CopyAbstractValue)"/> overload /// that updates copy value for each individual entity. /// </summary> internal void SetAbstactValueForEntities(CopyAbstractValue copyValue, AnalysisEntity?entityBeingAssigned) { foreach (var entity in copyValue.AnalysisEntities) { // If we have any predicate data based on the previous value of this entity, // and we are changing the copy value for an assigment (i.e. entity == entityBeingAssigned), // we need to drop all the predicate data based on this entity. if (entity == entityBeingAssigned && HasPredicatedDataForEntity(entity)) { StopTrackingPredicatedData(entity); } // Remove all predicated values for this entity as we are going to set // a new value in CoreAnalysisData below, which is non-predicated. if (HasPredicatedData) { RemoveEntriesInPredicatedData(entity); } // Finally, set the value in the core analysis data. CoreAnalysisData[entity] = copyValue; } }
/// <summary> /// Transfers the analysis data rooted from <paramref name="valueAnalysisEntity"/> or <paramref name="assignedValueOperation"/> to <paramref name="targetAnalysisEntity"/>, for a value type assignment operation. /// This involves transfer of data for of all <see cref="AnalysisEntity"/> instances that share the same <see cref="AnalysisEntity.InstanceLocation"/> as <paramref name="valueAnalysisEntity"/> or allocation for the <paramref name="assignedValueOperation"/> /// to all <see cref="AnalysisEntity"/> instances that share the same <see cref="AnalysisEntity.InstanceLocation"/> as <paramref name="targetAnalysisEntity"/>. /// </summary> private void TransferValueTypeInstanceAnalysisDataForAssignment(AnalysisEntity targetAnalysisEntity, AnalysisEntity?valueAnalysisEntity, IOperation?assignedValueOperation) { Debug.Assert(HasPointsToAnalysisResult); Debug.Assert(targetAnalysisEntity.Type.HasValueCopySemantics()); IEnumerable <AnalysisEntity> dependentAnalysisEntities; if (valueAnalysisEntity != null) { if (!valueAnalysisEntity.Type.HasValueCopySemantics()) { // Unboxing conversion from assigned value (reference type) to target (value copy semantics). // We do not need to transfer any data for such a case as there is no entity for unboxed value. return; } dependentAnalysisEntities = GetChildAnalysisEntities(valueAnalysisEntity); } else if (assignedValueOperation != null) { // For allocations. PointsToAbstractValue newValueLocation = GetPointsToAbstractValue(assignedValueOperation); dependentAnalysisEntities = GetChildAnalysisEntities(newValueLocation); } else { return; } foreach (AnalysisEntity dependentInstance in dependentAnalysisEntities) { // Clone the dependent instance but with with target as the root. AnalysisEntity newAnalysisEntity = AnalysisEntityFactory.CreateWithNewInstanceRoot(dependentInstance, targetAnalysisEntity); var dependentValue = GetAbstractValue(dependentInstance); SetAbstractValue(newAnalysisEntity, dependentValue); } }
private void SetAbstractValueForAssignment(AnalysisEntity targetAnalysisEntity, AnalysisEntity?assignedValueEntity, IOperation?assignedValueOperation, TAbstractAnalysisValue assignedValue) { // Value type and string type assignment has copy semantics. if (HasPointsToAnalysisResult && targetAnalysisEntity.Type.HasValueCopySemantics()) { // Reset the analysis values for analysis entities within the target instance. ResetValueTypeInstanceAnalysisData(targetAnalysisEntity); // Transfer the values of symbols from the assigned instance to the analysis entities in the target instance. TransferValueTypeInstanceAnalysisDataForAssignment(targetAnalysisEntity, assignedValueEntity, assignedValueOperation); } var addressSharedCopyValue = TryGetAddressSharedCopyValue(targetAnalysisEntity); if (addressSharedCopyValue != null) { Debug.Assert(addressSharedCopyValue.AnalysisEntities.Contains(targetAnalysisEntity)); foreach (var entity in addressSharedCopyValue.AnalysisEntities) { SetAbstractValue(entity, assignedValue); } } else { SetAbstractValue(targetAnalysisEntity, assignedValue); } }
public static AnalysisEntity Create(ISymbol?symbol, ImmutableArray <AbstractIndex> indices, ITypeSymbol type, PointsToAbstractValue instanceLocation, AnalysisEntity?parent) { Debug.Assert(symbol != null || !indices.IsEmpty); Debug.Assert(parent == null || parent.InstanceLocation == instanceLocation); return(new AnalysisEntity(symbol, indices, instanceLocation, type, parent)); }
private AnalysisEntity(ISymbol?symbol, ImmutableArray <AbstractIndex> indices, PointsToAbstractValue location, ITypeSymbol type, AnalysisEntity?parent) : this(symbol, indices, instanceReferenceOperationSyntax : null, captureId : null, location : location, type : type, parent : parent, isThisOrMeInstance : false) { Debug.Assert(symbol != null || !indices.IsEmpty); }
public bool TryCreateForTupleElements(ITupleOperation tupleOperation, [NotNullWhen(returnValue: true)] out ImmutableArray <AnalysisEntity> elementEntities) { if (_tupleElementEntitiesMap.TryGetValue(tupleOperation, out elementEntities)) { return(!elementEntities.IsDefault); } try { elementEntities = default; if (tupleOperation.Type?.IsTupleType != true || _getPointsToAbstractValue == null) { return(false); } var tupleType = (INamedTypeSymbol)tupleOperation.Type; if (tupleType.TupleElements.IsDefault) { return(false); } PointsToAbstractValue instanceLocation = _getPointsToAbstractValue(tupleOperation); var underlyingValueTupleType = tupleType.GetUnderlyingValueTupleTypeOrThis(); AnalysisEntity?parentEntity = null; if (tupleOperation.TryGetParentTupleOperation(out var parentTupleOperationOpt, out var elementOfParentTupleContainingTuple) && TryCreateForTupleElements(parentTupleOperationOpt, out var parentTupleElementEntities)) { Debug.Assert(parentTupleOperationOpt.Elements.Length == parentTupleElementEntities.Length); for (int i = 0; i < parentTupleOperationOpt.Elements.Length; i++) { if (parentTupleOperationOpt.Elements[i] == elementOfParentTupleContainingTuple) { parentEntity = parentTupleElementEntities[i]; instanceLocation = parentEntity.InstanceLocation; break; } } RoslynDebug.Assert(parentEntity != null); } else { parentEntity = AnalysisEntity.Create(underlyingValueTupleType, ImmutableArray <AbstractIndex> .Empty, underlyingValueTupleType, instanceLocation, parent: null); } Debug.Assert(parentEntity.InstanceLocation == instanceLocation); using var builder = ArrayBuilder <AnalysisEntity> .GetInstance(tupleType.TupleElements.Length); foreach (var field in tupleType.TupleElements) { var tupleFieldName = field.CorrespondingTupleField.Name; var mappedValueTupleField = underlyingValueTupleType.GetMembers(tupleFieldName).OfType <IFieldSymbol>().FirstOrDefault(); if (mappedValueTupleField == null) { return(false); } builder.Add(AnalysisEntity.Create(mappedValueTupleField, indices: ImmutableArray <AbstractIndex> .Empty, type: mappedValueTupleField.Type, instanceLocation, parentEntity)); } elementEntities = builder.ToImmutable(); return(true); }
public bool TryCreate(IOperation operation, [NotNullWhen(returnValue: true)] out AnalysisEntity?analysisEntity) { if (_analysisEntityMap.TryGetValue(operation, out analysisEntity)) { return(analysisEntity != null); } analysisEntity = null; ISymbol?symbol = null; ImmutableArray <AbstractIndex> indices = ImmutableArray <AbstractIndex> .Empty; IOperation? instance = null; ITypeSymbol?type = operation.Type; switch (operation) { case ILocalReferenceOperation localReference: symbol = localReference.Local; break; case IParameterReferenceOperation parameterReference: symbol = parameterReference.Parameter; break; case IMemberReferenceOperation memberReference: instance = memberReference.Instance; GetSymbolAndIndicesForMemberReference(memberReference, ref symbol, ref indices); // Workaround for https://github.com/dotnet/roslyn/issues/22736 (IPropertyReferenceExpressions in IAnonymousObjectCreationExpression are missing a receiver). if (instance == null && symbol != null && memberReference is IPropertyReferenceOperation propertyReference) { instance = propertyReference.GetAnonymousObjectCreation(); } break; case IArrayElementReferenceOperation arrayElementReference: instance = arrayElementReference.ArrayReference; indices = CreateAbstractIndices(arrayElementReference.Indices); break; case IDynamicIndexerAccessOperation dynamicIndexerAccess: instance = dynamicIndexerAccess.Operation; indices = CreateAbstractIndices(dynamicIndexerAccess.Arguments); break; case IConditionalAccessInstanceOperation conditionalAccessInstance: IConditionalAccessOperation?conditionalAccess = conditionalAccessInstance.GetConditionalAccess(); instance = conditionalAccess?.Operation; if (conditionalAccessInstance.Parent is IMemberReferenceOperation memberReferenceParent) { GetSymbolAndIndicesForMemberReference(memberReferenceParent, ref symbol, ref indices); } break; case IInstanceReferenceOperation instanceReference: if (_getPointsToAbstractValue != null) { instance = instanceReference.GetInstance(_getIsInsideAnonymousObjectInitializer()); if (instance == null) { // Reference to this or base instance. analysisEntity = _interproceduralCallStack != null && _interproceduralCallStack.Peek().DescendantsAndSelf().Contains(instanceReference) ? _interproceduralThisOrMeInstanceForCaller : ThisOrMeInstance; } else { var instanceLocation = _getPointsToAbstractValue(instanceReference); analysisEntity = AnalysisEntity.Create(instanceReference, instanceLocation); } } break; case IConversionOperation conversion: return(TryCreate(conversion.Operand, out analysisEntity)); case IParenthesizedOperation parenthesized: return(TryCreate(parenthesized.Operand, out analysisEntity)); case IArgumentOperation argument: return(TryCreate(argument.Value, out analysisEntity)); case IFlowCaptureOperation flowCapture: var isLvalueFlowCapture = _getIsLValueFlowCapture(flowCapture); analysisEntity = GetOrCreateForFlowCapture(flowCapture.Id, flowCapture.Value.Type, flowCapture, isLvalueFlowCapture); // Store flow capture copy values for simple flow captures of non-flow captured entity. // This enables pseudo copy-analysis of values of these two entities in absence of true copy analysis, which is expensive. if (!isLvalueFlowCapture && TryCreate(flowCapture.Value, out var capturedEntity) && capturedEntity.CaptureId == null && !_captureIdCopyValueMap.ContainsKey(flowCapture.Id) && analysisEntity.Type.IsValueType == capturedEntity.Type.IsValueType) { // Skip flow capture for conversions unless we know the points to value // for conversion and operand is identical. if (flowCapture.Value is IConversionOperation conversion) { if (_getPointsToAbstractValue == null || _getPointsToAbstractValue(conversion) != _getPointsToAbstractValue(conversion.Operand)) { break; } } var kind = capturedEntity.Type.IsValueType ? CopyAbstractValueKind.KnownValueCopy : CopyAbstractValueKind.KnownReferenceCopy; var copyValue = new CopyAbstractValue(ImmutableHashSet.Create(analysisEntity, capturedEntity), kind); _captureIdCopyValueMap.Add(flowCapture.Id, copyValue); } break; case IFlowCaptureReferenceOperation flowCaptureReference: analysisEntity = GetOrCreateForFlowCapture(flowCaptureReference.Id, flowCaptureReference.Type, flowCaptureReference, flowCaptureReference.IsLValueFlowCaptureReference()); break; case IDeclarationExpressionOperation declarationExpression: switch (declarationExpression.Expression) { case ILocalReferenceOperation localReference: return(TryCreateForSymbolDeclaration(localReference.Local, out analysisEntity)); case ITupleOperation tupleOperation: return(TryCreate(tupleOperation, out analysisEntity)); } break; case IVariableDeclaratorOperation variableDeclarator: symbol = variableDeclarator.Symbol; type = variableDeclarator.Symbol.Type; break; case IDeclarationPatternOperation declarationPattern: var declaredLocal = declarationPattern.DeclaredSymbol as ILocalSymbol; symbol = declaredLocal; type = declaredLocal?.Type; break; default: break; } if (symbol != null || !indices.IsEmpty) { TryCreate(symbol, indices, type !, instance, out analysisEntity); } _analysisEntityMap[operation] = analysisEntity; return(analysisEntity != null); }
public bool TryCreate(IOperation operation, [NotNullWhen(returnValue: true)] out AnalysisEntity?analysisEntity) { if (_analysisEntityMap.TryGetValue(operation, out analysisEntity)) { return(analysisEntity != null); } analysisEntity = null; ISymbol?symbol = null; ImmutableArray <AbstractIndex> indices = ImmutableArray <AbstractIndex> .Empty; IOperation? instance = null; ITypeSymbol?type = operation.Type; switch (operation) { case ILocalReferenceOperation localReference: symbol = localReference.Local; break; case IParameterReferenceOperation parameterReference: symbol = parameterReference.Parameter; break; case IMemberReferenceOperation memberReference: instance = memberReference.Instance; GetSymbolAndIndicesForMemberReference(memberReference, ref symbol, ref indices); // Workaround for https://github.com/dotnet/roslyn/issues/22736 (IPropertyReferenceExpressions in IAnonymousObjectCreationExpression are missing a receiver). if (instance == null && symbol != null && memberReference is IPropertyReferenceOperation propertyReference) { instance = propertyReference.GetAnonymousObjectCreation(); } break; case IArrayElementReferenceOperation arrayElementReference: instance = arrayElementReference.ArrayReference; indices = CreateAbstractIndices(arrayElementReference.Indices); break; case IDynamicIndexerAccessOperation dynamicIndexerAccess: instance = dynamicIndexerAccess.Operation; indices = CreateAbstractIndices(dynamicIndexerAccess.Arguments); break; case IConditionalAccessInstanceOperation conditionalAccessInstance: IConditionalAccessOperation?conditionalAccess = conditionalAccessInstance.GetConditionalAccess(); instance = conditionalAccess?.Operation; if (conditionalAccessInstance.Parent is IMemberReferenceOperation memberReferenceParent) { GetSymbolAndIndicesForMemberReference(memberReferenceParent, ref symbol, ref indices); } break; case IInstanceReferenceOperation instanceReference: if (_getPointsToAbstractValue != null) { instance = instanceReference.GetInstance(_getIsInsideAnonymousObjectInitializer()); if (instance == null) { // Reference to this or base instance. analysisEntity = _interproceduralCallStack != null && _interproceduralCallStack.Peek().DescendantsAndSelf().Contains(instanceReference) ? _interproceduralThisOrMeInstanceForCaller : ThisOrMeInstance; } else { var instanceLocation = _getPointsToAbstractValue(instanceReference); analysisEntity = AnalysisEntity.Create(instanceReference, instanceLocation); } } break; case IConversionOperation conversion: return(TryCreate(conversion.Operand, out analysisEntity)); case IParenthesizedOperation parenthesized: return(TryCreate(parenthesized.Operand, out analysisEntity)); case IArgumentOperation argument: return(TryCreate(argument.Value, out analysisEntity)); case IFlowCaptureOperation flowCapture: analysisEntity = GetOrCreateForFlowCapture(flowCapture.Id, flowCapture.Value.Type, flowCapture, _getIsLValueFlowCapture(flowCapture)); break; case IFlowCaptureReferenceOperation flowCaptureReference: analysisEntity = GetOrCreateForFlowCapture(flowCaptureReference.Id, flowCaptureReference.Type, flowCaptureReference, flowCaptureReference.IsLValueFlowCaptureReference()); break; case IDeclarationExpressionOperation declarationExpression: switch (declarationExpression.Expression) { case ILocalReferenceOperation localReference: return(TryCreateForSymbolDeclaration(localReference.Local, out analysisEntity)); case ITupleOperation tupleOperation: return(TryCreate(tupleOperation, out analysisEntity)); } break; case IVariableDeclaratorOperation variableDeclarator: symbol = variableDeclarator.Symbol; type = variableDeclarator.Symbol.Type; break; case IDeclarationPatternOperation declarationPattern: var declaredLocal = declarationPattern.DeclaredSymbol as ILocalSymbol; symbol = declaredLocal; type = declaredLocal?.Type; break; default: break; } if (symbol != null || !indices.IsEmpty) { TryCreate(symbol, indices, type !, instance, out analysisEntity); } _analysisEntityMap[operation] = analysisEntity; return(analysisEntity != null); }
private static AbstractLocation Create(IOperation?creation, ImmutableStack <IOperation>?creationCallStack, AnalysisEntity?analysisEntity, ISymbol?symbol, InterproceduralCaptureId?captureId, ITypeSymbol?locationType) { Debug.Assert(creation != null ^ symbol != null ^ analysisEntity != null ^ captureId != null); Debug.Assert(locationType != null); return(new AbstractLocation(creation, creationCallStack, analysisEntity, symbol, captureId, locationType, isSpecialSingleton: false)); }