Exemple #1
0
        /// <summary>
        /// Contains a list of buckets, each of which contains a number of flags, a slot ID, and a name.
        /// TODO: comment when the structure is understood.
        /// </summary>
        /// <remarks>
        /// Appears when there are dynamic locals.
        /// </remarks>
        private void WriteDynamicLocalsCustomDebugInfo(CustomDebugInfoRecord record)
        {
            Debug.Assert(record.Kind == CustomDebugInfoKind.DynamicLocals);

            writer.WriteStartElement("dynamicLocals");

            var buckets = CDI.DecodeDynamicLocalsRecord(record.Data);

            foreach (DynamicLocalBucket bucket in buckets)
            {
                ulong flags     = bucket.Flags;
                int   flagCount = bucket.FlagCount;

                PooledStringBuilder pooled       = PooledStringBuilder.GetInstance();
                StringBuilder       flagsBuilder = pooled.Builder;
                for (int f = 0; f < flagCount; f++)
                {
                    flagsBuilder.Append((flags >> f) & 1UL);
                }

                writer.WriteStartElement("bucket");
                writer.WriteAttributeString("flagCount", flagCount.ToString());
                writer.WriteAttributeString("flags", pooled.ToStringAndFree());
                writer.WriteAttributeString("slotId", bucket.SlotId.ToString());
                writer.WriteAttributeString("localName", bucket.Name);
                writer.WriteEndElement(); //bucket
            }

            writer.WriteEndElement(); //dynamicLocals
        }
Exemple #2
0
        /// <summary>
        /// Contains a name string.
        /// TODO: comment when the structure is understood.
        /// </summary>
        /// <remarks>
        /// Appears when are iterator methods.
        /// </remarks>
        private void WriteForwardIteratorCustomDebugInfo(CustomDebugInfoRecord record)
        {
            Debug.Assert(record.Kind == CustomDebugInfoKind.ForwardIterator);

            writer.WriteStartElement("forwardIterator");

            string name = CDI.DecodeForwardIteratorRecord(record.Data);

            writer.WriteAttributeString("name", name);

            writer.WriteEndElement(); //forwardIterator
        }
Exemple #3
0
        /// <summary>
        /// This indicates that further information can be obtained by looking at the custom debug
        /// info of another method (specified by token).
        /// </summary>
        /// <remarks>
        /// Appears when there are extern aliases and edit-and-continue is disabled.
        /// Emitting tokens makes tests more fragile.
        /// </remarks>
        private void WriteForwardToModuleCustomDebugInfo(CustomDebugInfoRecord record)
        {
            Debug.Assert(record.Kind == CustomDebugInfoKind.ForwardToModuleInfo);

            writer.WriteStartElement("forwardToModule");

            int token = CDI.DecodeForwardRecord(record.Data);

            WriteMethodAttributes(token, isReference: true);

            writer.WriteEndElement(); //forwardToModule
        }
Exemple #4
0
        /// <summary>
        /// For each namespace declaration enclosing a method (innermost-to-outermost), there is a count
        /// of the number of imports in that declaration.
        /// </summary>
        /// <remarks>
        /// There's always at least one entry (for the global namespace).
        /// </remarks>
        private void WriteUsingCustomDebugInfo(CustomDebugInfoRecord record)
        {
            Debug.Assert(record.Kind == CustomDebugInfoKind.UsingInfo);

            writer.WriteStartElement("using");

            ImmutableArray <short> counts = CDI.DecodeUsingRecord(record.Data);

            foreach (short importCount in counts)
            {
                writer.WriteStartElement("namespace");
                writer.WriteAttributeString("usingCount", importCount.ToString());
                writer.WriteEndElement(); //namespace
            }

            writer.WriteEndElement(); //using
        }
Exemple #5
0
        /// <summary>
        /// Appears when iterator locals have to lifted into fields.  Contains a list of buckets with
        /// start and end offsets (presumably, into IL).
        /// TODO: comment when the structure is understood.
        /// </summary>
        /// <remarks>
        /// Appears when there are locals in iterator methods.
        /// </remarks>
        private void WriteStatemachineHoistedLocalScopesCustomDebugInfo(CustomDebugInfoRecord record)
        {
            Debug.Assert(record.Kind == CustomDebugInfoKind.StateMachineHoistedLocalScopes);

            writer.WriteStartElement("hoistedLocalScopes");

            var scopes = CDI.DecodeStateMachineHoistedLocalScopesRecord(record.Data);

            foreach (StateMachineHoistedLocalScope scope in scopes)
            {
                writer.WriteStartElement("slot");
                writer.WriteAttributeString("startOffset", AsILOffset(scope.StartOffset));
                writer.WriteAttributeString("endOffset", AsILOffset(scope.EndOffset));
                writer.WriteEndElement(); //bucket
            }

            writer.WriteEndElement();
        }
Exemple #6
0
        private void WriteNamespace(ISymUnmanagedNamespace @namespace)
        {
            string rawName = @namespace.GetName();

            string           alias;
            string           externAlias;
            string           target;
            ImportTargetKind kind;
            ImportScope      scope;

            try
            {
                if (rawName.Length == 0)
                {
                    externAlias = null;
                    var parsingSucceeded = CDI.TryParseVisualBasicImportString(rawName, out alias, out target, out kind, out scope);
                    Debug.Assert(parsingSucceeded);
                }
                else
                {
                    switch (rawName[0])
                    {
                    case 'U':
                    case 'A':
                    case 'X':
                    case 'Z':
                    case 'E':
                    case 'T':
                        scope = ImportScope.Unspecified;
                        if (!CDI.TryParseCSharpImportString(rawName, out alias, out externAlias, out target, out kind))
                        {
                            throw new InvalidOperationException(string.Format("Invalid import '{0}'", rawName));
                        }
                        break;

                    default:
                        externAlias = null;
                        if (!CDI.TryParseVisualBasicImportString(rawName, out alias, out target, out kind, out scope))
                        {
                            throw new InvalidOperationException(string.Format("Invalid import '{0}'", rawName));
                        }
                        break;
                    }
                }
            }
            catch (ArgumentException) // TODO: filter
            {
                if ((options & PdbToXmlOptions.ThrowOnError) != 0)
                {
                    throw;
                }

                writer.WriteStartElement("invalid-custom-data");
                writer.WriteAttributeString("raw", rawName);
                writer.WriteEndElement();
                return;
            }

            switch (kind)
            {
            case ImportTargetKind.CurrentNamespace:
                Debug.Assert(alias == null);
                Debug.Assert(externAlias == null);
                Debug.Assert(scope == ImportScope.Unspecified);
                writer.WriteStartElement("currentnamespace");
                writer.WriteAttributeString("name", target);
                writer.WriteEndElement();     // </currentnamespace>
                break;

            case ImportTargetKind.DefaultNamespace:
                Debug.Assert(alias == null);
                Debug.Assert(externAlias == null);
                Debug.Assert(scope == ImportScope.Unspecified);
                writer.WriteStartElement("defaultnamespace");
                writer.WriteAttributeString("name", target);
                writer.WriteEndElement();     // </defaultnamespace>
                break;

            case ImportTargetKind.MethodToken:
                Debug.Assert(alias == null);
                Debug.Assert(externAlias == null);
                Debug.Assert(scope == ImportScope.Unspecified);
                int token = Convert.ToInt32(target);
                writer.WriteStartElement("importsforward");
                WriteMethodAttributes(token, isReference: true);
                writer.WriteEndElement();     // </importsforward>
                break;

            case ImportTargetKind.XmlNamespace:
                Debug.Assert(externAlias == null);
                writer.WriteStartElement("xmlnamespace");
                writer.WriteAttributeString("prefix", alias);
                writer.WriteAttributeString("name", target);
                WriteScopeAttribute(scope);
                writer.WriteEndElement();     // </xmlnamespace>
                break;

            case ImportTargetKind.NamespaceOrType:
                Debug.Assert(externAlias == null);
                writer.WriteStartElement("alias");
                writer.WriteAttributeString("name", alias);
                writer.WriteAttributeString("target", target);
                writer.WriteAttributeString("kind", "namespace"); // Strange, but retaining to avoid breaking tests.
                WriteScopeAttribute(scope);
                writer.WriteEndElement();                         // </alias>
                break;

            case ImportTargetKind.Namespace:
                if (alias != null)
                {
                    writer.WriteStartElement("alias");
                    writer.WriteAttributeString("name", alias);
                    if (externAlias != null)
                    {
                        writer.WriteAttributeString("qualifier", externAlias);
                    }
                    writer.WriteAttributeString("target", target);
                    writer.WriteAttributeString("kind", "namespace");
                    Debug.Assert(scope == ImportScope.Unspecified); // Only C# hits this case.
                    writer.WriteEndElement();                       // </alias>
                }
                else
                {
                    writer.WriteStartElement("namespace");
                    if (externAlias != null)
                    {
                        writer.WriteAttributeString("qualifier", externAlias);
                    }
                    writer.WriteAttributeString("name", target);
                    WriteScopeAttribute(scope);
                    writer.WriteEndElement();     // </namespace>
                }
                break;

            case ImportTargetKind.Type:
                Debug.Assert(externAlias == null);
                if (alias != null)
                {
                    writer.WriteStartElement("alias");
                    writer.WriteAttributeString("name", alias);
                    writer.WriteAttributeString("target", target);
                    writer.WriteAttributeString("kind", "type");
                    Debug.Assert(scope == ImportScope.Unspecified); // Only C# hits this case.
                    writer.WriteEndElement();                       // </alias>
                }
                else
                {
                    writer.WriteStartElement("type");
                    writer.WriteAttributeString("name", target);
                    WriteScopeAttribute(scope);
                    writer.WriteEndElement();     // </type>
                }
                break;

            case ImportTargetKind.Assembly:
                Debug.Assert(alias == null);
                Debug.Assert(scope == ImportScope.Unspecified);
                if (target == null)
                {
                    writer.WriteStartElement("extern");
                    writer.WriteAttributeString("alias", externAlias);
                    writer.WriteEndElement();     // </extern>
                }
                else
                {
                    writer.WriteStartElement("externinfo");
                    writer.WriteAttributeString("alias", externAlias);
                    writer.WriteAttributeString("assembly", target);
                    writer.WriteEndElement();     // </externinfo>
                }
                break;

            case ImportTargetKind.Defunct:
                Debug.Assert(alias == null);
                Debug.Assert(scope == ImportScope.Unspecified);
                writer.WriteStartElement("defunct");
                writer.WriteAttributeString("name", rawName);
                writer.WriteEndElement();     // </defunct>
                break;

            default:
                Debug.Assert(false, "Unexpected import kind '" + kind + "'");
                writer.WriteStartElement("unknown");
                writer.WriteAttributeString("name", rawName);
                writer.WriteEndElement();     // </unknown>
                break;
            }
        }