|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Immutable;
using System.Diagnostics;
using System.Reflection.Metadata;
using Microsoft.CodeAnalysis.Symbols;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CodeGen
{
[DebuggerDisplay("{GetDebuggerDisplay(),nq}")]
internal sealed class LocalDefinition : Cci.ILocalDefinition
{
//TODO: locals are really just typed slots. They do not have names.
// name only matters for pdb generation where it is a scope-specific mapping to a slot.
// it may be better if local does not have a name as will restrict reuse of locals when we do it.
//Local symbol, currently used by edit and continue and for the location.
private readonly ILocalSymbolInternal? _symbolOpt;
private readonly string? _nameOpt;
//data type associated with the local signature slot.
private readonly Cci.ITypeReference _type;
// specifies whether local slot has a byref constraint and whether
// the type of the local has the "pinned modifier" (7.1.2).
// CLI spec Part I, paragraph 8.6.1.3:
// The byref constraint states that the content of the corresponding location is a managed pointer. A managed
// pointer can point to a local variable, parameter, field of a compound type, or element of an array.
private readonly LocalSlotConstraints _constraints;
//ordinal position of the slot in the local signature.
private readonly int _slot;
private readonly LocalSlotDebugInfo _slotInfo;
/// <see cref="Cci.ILocalDefinition.PdbAttributes"/>.
private readonly LocalVariableAttributes _pdbAttributes;
//Gives the synthesized dynamic attributes of the local definition
private readonly ImmutableArray<bool> _dynamicTransformFlags;
private readonly ImmutableArray<string> _tupleElementNames;
/// <summary>
/// Creates a new LocalDefinition.
/// </summary>
/// <param name="symbolOpt">Local symbol, used by edit and continue only, null otherwise.</param>
/// <param name="nameOpt">Name associated with the slot.</param>
/// <param name="type">Type associated with the slot.</param>
/// <param name="slot">Slot position in the signature.</param>
/// <param name="synthesizedKind">Local kind.</param>
/// <param name="id">Local id.</param>
/// <param name="pdbAttributes">Value to emit in the attributes field in the PDB.</param>
/// <param name="constraints">Specifies whether slot type should have pinned modifier and whether slot should have byref constraint.</param>
/// <param name="dynamicTransformFlags">The synthesized dynamic attributes of the local.</param>
/// <param name="tupleElementNames">Tuple element names of the local.</param>
public LocalDefinition(
ILocalSymbolInternal? symbolOpt,
string? nameOpt,
Cci.ITypeReference type,
int slot,
SynthesizedLocalKind synthesizedKind,
LocalDebugId id,
LocalVariableAttributes pdbAttributes,
LocalSlotConstraints constraints,
ImmutableArray<bool> dynamicTransformFlags,
ImmutableArray<string> tupleElementNames)
{
_symbolOpt = symbolOpt;
_nameOpt = nameOpt;
_type = type;
_slot = slot;
_slotInfo = new LocalSlotDebugInfo(synthesizedKind, id);
_pdbAttributes = pdbAttributes;
_dynamicTransformFlags = dynamicTransformFlags.NullToEmpty();
_tupleElementNames = tupleElementNames.NullToEmpty();
_constraints = constraints;
}
internal string GetDebuggerDisplay()
=> $"{_slot}: {_nameOpt ?? "<unnamed>"} ({_type})";
public ILocalSymbolInternal? SymbolOpt => _symbolOpt;
public Location Location
{
get
{
if (_symbolOpt != null)
{
ImmutableArray<Location> locations = _symbolOpt.Locations;
if (!locations.IsDefaultOrEmpty)
{
return locations[0];
}
}
return Location.None;
}
}
public int SlotIndex => _slot;
public MetadataConstant CompileTimeValue
{
get { throw ExceptionUtilities.Unreachable(); }
}
public ImmutableArray<Cci.ICustomModifier> CustomModifiers
=> ImmutableArray<Cci.ICustomModifier>.Empty;
public bool IsConstant
{
get { throw ExceptionUtilities.Unreachable(); }
}
public bool IsModified => false;
public LocalSlotConstraints Constraints => _constraints;
public bool IsPinned
=> (_constraints & LocalSlotConstraints.Pinned) != 0;
public bool IsReference
=> (_constraints & LocalSlotConstraints.ByRef) != 0;
public LocalVariableAttributes PdbAttributes => _pdbAttributes;
public ImmutableArray<bool> DynamicTransformFlags => _dynamicTransformFlags;
public ImmutableArray<string> TupleElementNames => _tupleElementNames;
public Cci.ITypeReference Type => _type;
public string? Name => _nameOpt;
public byte[]? Signature => null;
public LocalSlotDebugInfo SlotInfo => _slotInfo;
}
}
|