/// <summary>
        /// Release a local slot by its symbol.
        /// Slot is not associated with symbol after this.
        /// </summary>
        internal void FreeLocal(ILocalSymbolInternal symbol)
        {
            var slot = GetLocal(symbol);

            LocalMap.Remove(symbol);
            FreeSlot(slot);
        }
Beispiel #2
0
 public abstract LocalDefinition GetPreviousLocal(
     Cci.ITypeReference type,
     ILocalSymbolInternal symbol,
     string nameOpt,
     SynthesizedLocalKind kind,
     LocalDebugId id,
     LocalVariableAttributes pdbAttributes,
     LocalSlotConstraints constraints,
     ImmutableArray <string> tupleElementNames);
 public abstract LocalDefinition GetPreviousLocal(
     Cci.ITypeReference type,
     ILocalSymbolInternal symbol,
     string nameOpt,
     SynthesizedLocalKind kind,
     LocalDebugId id,
     uint pdbAttributes,
     LocalSlotConstraints constraints,
     bool isDynamic,
     ImmutableArray <TypedConstant> dynamicTransformFlags);
 public abstract LocalDefinition GetPreviousLocal(
     Cci.ITypeReference type,
     ILocalSymbolInternal symbol,
     string nameOpt,
     SynthesizedLocalKind kind,
     LocalDebugId id,
     LocalVariableAttributes pdbAttributes,
     LocalSlotConstraints constraints,
     bool isDynamic,
     ImmutableArray<TypedConstant> dynamicTransformFlags);
Beispiel #5
0
        private LocalDefinition DeclareLocalImpl(
            Cci.ITypeReference type,
            ILocalSymbolInternal symbolOpt,
            string nameOpt,
            SynthesizedLocalKind kind,
            LocalDebugId id,
            LocalVariableAttributes pdbAttributes,
            LocalSlotConstraints constraints,
            ImmutableArray <bool> dynamicTransformFlags,
            ImmutableArray <string> tupleElementNames)
        {
            if (_lazyAllLocals == null)
            {
                _lazyAllLocals = new ArrayBuilder <Cci.ILocalDefinition>(1);
            }

            LocalDefinition local;

            if (symbolOpt != null && _slotAllocatorOpt != null)
            {
                local = _slotAllocatorOpt.GetPreviousLocal(
                    type,
                    symbolOpt,
                    nameOpt,
                    kind,
                    id,
                    pdbAttributes,
                    constraints,
                    dynamicTransformFlags: dynamicTransformFlags,
                    tupleElementNames: tupleElementNames);
                if (local != null)
                {
                    int slot = local.SlotIndex;
                    _lazyAllLocals[slot] = local;
                    return(local);
                }
            }

            local = new LocalDefinition(
                symbolOpt: symbolOpt,
                nameOpt: nameOpt,
                type: type,
                slot: _lazyAllLocals.Count,
                synthesizedKind: kind,
                id: id,
                pdbAttributes: pdbAttributes,
                constraints: constraints,
                dynamicTransformFlags: dynamicTransformFlags,
                tupleElementNames: tupleElementNames);

            _lazyAllLocals.Add(local);
            return(local);
        }
Beispiel #6
0
        public override LocalDefinition GetPreviousLocal(
            Cci.ITypeReference currentType,
            ILocalSymbolInternal currentLocalSymbol,
            string nameOpt,
            SynthesizedLocalKind kind,
            LocalDebugId id,
            uint pdbAttributes,
            LocalSlotConstraints constraints,
            bool isDynamic,
            ImmutableArray <TypedConstant> dynamicTransformFlags)
        {
            if (id.IsNone)
            {
                return(null);
            }

            LocalDebugId previousId;

            if (!TryGetPreviousLocalId(currentLocalSymbol.GetDeclaratorSyntax(), id, out previousId))
            {
                return(null);
            }

            var previousType = _symbolMap.MapReference(currentType);

            if (previousType == null)
            {
                return(null);
            }

            // TODO (bug #781309): Should report a warning if the type of the local has changed
            // and the previous value will be dropped.
            var localKey = new EncLocalInfo(new LocalSlotDebugInfo(kind, previousId), previousType, constraints, signature: null);

            int slot;

            if (!_previousLocalSlots.TryGetValue(localKey, out slot))
            {
                return(null);
            }

            return(new LocalDefinition(
                       currentLocalSymbol,
                       nameOpt,
                       currentType,
                       slot,
                       kind,
                       id,
                       pdbAttributes,
                       constraints,
                       isDynamic,
                       dynamicTransformFlags));
        }
            public override LocalDefinition GetPreviousLocal(
                Cci.ITypeReference type,
                ILocalSymbolInternal symbol,
                string nameOpt,
                SynthesizedLocalKind synthesizedKind,
                LocalDebugId id,
                uint pdbAttributes,
                LocalSlotConstraints constraints,
                bool isDynamic,
                ImmutableArray <TypedConstant> dynamicTransformFlags)
            {
                var local = symbol as EELocalSymbol;

                if ((object)local == null)
                {
                    return(null);
                }

                return(_locals[local.Ordinal]);
            }
Beispiel #8
0
        internal LocalDefinition DeclareLocal(
            Cci.ITypeReference type,
            ILocalSymbolInternal symbol,
            string name,
            SynthesizedLocalKind kind,
            LocalDebugId id,
            LocalVariableAttributes pdbAttributes,
            LocalSlotConstraints constraints,
            ImmutableArray <TypedConstant> dynamicTransformFlags,
            ImmutableArray <TypedConstant> tupleElementNames,
            bool isSlotReusable)
        {
            if (!isSlotReusable || !FreeSlots.TryPop(new LocalSignature(type, constraints), out LocalDefinition local))
            {
                local = this.DeclareLocalImpl(type, symbol, name, kind, id, pdbAttributes, constraints, dynamicTransformFlags, tupleElementNames);
            }

            LocalMap.Add(symbol, local);
            return(local);
        }
Beispiel #9
0
        /// <summary>
        /// Gets the name and id of the local that are going to be generated into the debug metadata.
        /// </summary>
        private string GetLocalDebugName(ILocalSymbolInternal local, out LocalDebugId localId)
        {
            localId = LocalDebugId.None;

            if (local.IsImportedFromMetadata)
            {
                return local.Name;
            }

            var localKind = local.SynthesizedKind;

            // only user-defined locals should be named during lowering:
            Debug.Assert((local.Name == null) == (localKind != SynthesizedLocalKind.UserDefined));

            // Generating debug names for instrumentation payloads should be allowed, as described in https://github.com/dotnet/roslyn/issues/11024.
            // For now, skip naming locals generated by instrumentation as they might not have a local syntax offset.
            // Locals generated by instrumentation might exist in methods which do not contain a body (auto property initializers).
            if (!localKind.IsLongLived() || localKind == SynthesizedLocalKind.InstrumentationPayload)
            {
                return null;
            }

            if (_ilEmitStyle == ILEmitStyle.Debug)
            {
                var syntax = local.GetDeclaratorSyntax();
                int syntaxOffset = _method.CalculateLocalSyntaxOffset(syntax.SpanStart, syntax.SyntaxTree);

                int ordinal = _synthesizedLocalOrdinals.AssignLocalOrdinal(localKind, syntaxOffset);

                // user-defined locals should have 0 ordinal:
                Debug.Assert(ordinal == 0 || localKind != SynthesizedLocalKind.UserDefined);

                localId = new LocalDebugId(syntaxOffset, ordinal);
            }

            return local.Name ?? GeneratedNames.MakeSynthesizedLocalName(localKind, ref _uniqueNameId);
        }
Beispiel #10
0
        /// <summary>
        /// Gets the name and id of the local that are going to be generated into the debug metadata.
        /// </summary>
        private string GetLocalDebugName(ILocalSymbolInternal local, out LocalDebugId localId)
        {
            localId = LocalDebugId.None;

            if (local.IsImportedFromMetadata)
            {
                return local.Name;
            }

            var localKind = local.SynthesizedKind;

            // only user-defined locals should be named during lowering:
            Debug.Assert((local.Name == null) == (localKind != SynthesizedLocalKind.UserDefined));

            if (!localKind.IsLongLived())
            {
                return null;
            }

            if (_optimizations == OptimizationLevel.Debug)
            {
                var syntax = local.GetDeclaratorSyntax();
                int syntaxOffset = _method.CalculateLocalSyntaxOffset(syntax.SpanStart, syntax.SyntaxTree);

                int ordinal = _synthesizedLocalOrdinals.AssignLocalOrdinal(localKind, syntaxOffset);

                // user-defined locals should have 0 ordinal:
                Debug.Assert(ordinal == 0 || localKind != SynthesizedLocalKind.UserDefined);

                localId = new LocalDebugId(syntaxOffset, ordinal);
            }

            return local.Name ?? GeneratedNames.MakeSynthesizedLocalName(localKind, ref _uniqueNameId);
        }
 /// <summary>
 /// Retrieve a local slot by its symbol.
 /// </summary>
 internal LocalDefinition GetLocal(ILocalSymbolInternal symbol)
 {
     return(LocalMap[symbol]);
 }
        public override LocalDefinition GetPreviousLocal(
            Cci.ITypeReference currentType,
            ILocalSymbolInternal currentLocalSymbol,
            string nameOpt,
            SynthesizedLocalKind kind,
            LocalDebugId id,
            uint pdbAttributes,
            LocalSlotConstraints constraints,
            bool isDynamic,
            ImmutableArray<TypedConstant> dynamicTransformFlags)
        {
            if (id.IsNone)
            {
                return null;
            }

            LocalDebugId previousId;
            if (!TryGetPreviousLocalId(currentLocalSymbol.GetDeclaratorSyntax(), id, out previousId))
            {
                return null;
            }

            var previousType = _symbolMap.MapReference(currentType);
            if (previousType == null)
            {
                return null;
            }

            // TODO (bug #781309): Should report a warning if the type of the local has changed
            // and the previous value will be dropped.
            var localKey = new EncLocalInfo(new LocalSlotDebugInfo(kind, previousId), previousType, constraints, signature: null);

            int slot;
            if (!_previousLocalSlots.TryGetValue(localKey, out slot))
            {
                return null;
            }

            return new LocalDefinition(
                currentLocalSymbol,
                nameOpt,
                currentType,
                slot,
                kind,
                id,
                pdbAttributes,
                constraints,
                isDynamic,
                dynamicTransformFlags);
        }
Beispiel #13
0
            public override LocalDefinition GetPreviousLocal(
                Cci.ITypeReference type,
                ILocalSymbolInternal symbol,
                string nameOpt,
                SynthesizedLocalKind synthesizedKind,
                LocalDebugId id,
                uint pdbAttributes,
                LocalSlotConstraints constraints,
                bool isDynamic,
                ImmutableArray<TypedConstant> dynamicTransformFlags)
            {
                var local = symbol as EELocalSymbol;
                if ((object)local == null)
                {
                    return null;
                }

                return _locals[local.Ordinal];
            }