void ReadConstants(SymbolScopeImpl scope, uint constantList, uint constantListEnd)
        {
            if (constantList == 0)
            {
                return;
            }
            Debug.Assert(constantList <= constantListEnd);
            if (constantList >= constantListEnd)
            {
                return;
            }
            var table = pdbMetadata.TablesStream.LocalConstantTable;

            Debug.Assert(table.IsValidRID(constantListEnd - 1));
            if (!table.IsValidRID(constantListEnd - 1))
            {
                return;
            }
            Debug.Assert(table.IsValidRID(constantList));
            if (!table.IsValidRID(constantList))
            {
                return;
            }
            scope.SetConstants(pdbMetadata, constantList, constantListEnd);
        }
        SymbolScopeImpl ReadScope(uint methodRid, GenericParamContext gpContext)
        {
            var             scopesRidList   = pdbMetadata.GetLocalScopeRidList(methodRid);
            SymbolScopeImpl rootScopeOrNull = null;

            if (scopesRidList.Count != 0)
            {
                var custInfos = ListCache <PdbCustomDebugInfo> .AllocList();

                var stack = ListCache <SymbolScopeImpl> .AllocList();

                var importScopeBlobReader = new ImportScopeBlobReader(module, pdbMetadata.BlobStream);
                for (int i = 0; i < scopesRidList.Count; i++)
                {
                    var  rid   = scopesRidList[i];
                    int  token = new MDToken(Table.LocalScope, rid).ToInt32();
                    bool b     = pdbMetadata.TablesStream.TryReadLocalScopeRow(rid, out var row);
                    Debug.Assert(b);
                    uint startOffset = row.StartOffset;
                    uint endOffset   = startOffset + row.Length;

                    SymbolScopeImpl parent = null;
                    while (stack.Count > 0)
                    {
                        var nextParent = stack[stack.Count - 1];
                        if (startOffset >= nextParent.StartOffset && endOffset <= nextParent.EndOffset)
                        {
                            parent = nextParent;
                            break;
                        }
                        stack.RemoveAt(stack.Count - 1);
                    }

                    Debug.Assert(parent != null || rootScopeOrNull == null);
                    custInfos.Clear();
                    GetCustomDebugInfos(token, gpContext, custInfos);
                    var customDebugInfos = custInfos.Count == 0 ? Array2.Empty <PdbCustomDebugInfo>() : custInfos.ToArray();
                    var scope            = new SymbolScopeImpl(this, parent, (int)startOffset, (int)endOffset, customDebugInfos);
                    if (rootScopeOrNull == null)
                    {
                        rootScopeOrNull = scope;
                    }
                    stack.Add(scope);
                    if (parent != null)
                    {
                        parent.childrenList.Add(scope);
                    }

                    scope.importScope = ReadPdbImportScope(ref importScopeBlobReader, row.ImportScope, gpContext);
                    GetEndOfLists(rid, out uint variableListEnd, out uint constantListEnd);
                    ReadVariables(scope, gpContext, row.VariableList, variableListEnd);
                    ReadConstants(scope, row.ConstantList, constantListEnd);
                }

                ListCache <SymbolScopeImpl> .Free(ref stack);

                ListCache <PdbCustomDebugInfo> .Free(ref custInfos);
            }
            return(rootScopeOrNull ?? new SymbolScopeImpl(this, null, 0, int.MaxValue, Array2.Empty <PdbCustomDebugInfo>()));
        }
Exemple #3
0
 public SymbolScopeImpl(PortablePdbReader owner, SymbolScopeImpl parent, int startOffset, int endOffset, PdbCustomDebugInfo[] customDebugInfos)
 {
     this.owner            = owner;
     method                = null;
     this.parent           = parent;
     this.startOffset      = startOffset;
     this.endOffset        = endOffset;
     childrenList          = new List <SymbolScope>();
     localsList            = new List <SymbolVariable>();
     this.customDebugInfos = customDebugInfos;
 }
        void ReadVariables(SymbolScopeImpl scope, GenericParamContext gpContext, uint variableList, uint variableListEnd)
        {
            if (variableList == 0)
            {
                return;
            }
            Debug.Assert(variableList <= variableListEnd);
            if (variableList >= variableListEnd)
            {
                return;
            }
            var table = pdbMetadata.TablesStream.LocalVariableTable;

            Debug.Assert(table.IsValidRID(variableListEnd - 1));
            if (!table.IsValidRID(variableListEnd - 1))
            {
                return;
            }
            Debug.Assert(table.IsValidRID(variableList));
            if (!table.IsValidRID(variableList))
            {
                return;
            }
            var custInfos = ListCache <PdbCustomDebugInfo> .AllocList();

            for (uint rid = variableList; rid < variableListEnd; rid++)
            {
                int token = new MDToken(Table.LocalVariable, rid).ToInt32();
                custInfos.Clear();
                GetCustomDebugInfos(token, gpContext, custInfos);
                var  customDebugInfos = custInfos.Count == 0 ? Array2.Empty <PdbCustomDebugInfo>() : custInfos.ToArray();
                bool b = pdbMetadata.TablesStream.TryReadLocalVariableRow(rid, out var row);
                Debug.Assert(b);
                var name = pdbMetadata.StringsStream.Read(row.Name);
                scope.localsList.Add(new SymbolVariableImpl(name, ToSymbolVariableAttributes(row.Attributes), row.Index, customDebugInfos));
            }
            ListCache <PdbCustomDebugInfo> .Free(ref custInfos);
        }