private IDiaSymbol GetTypeSymbol(string typeName, SymTagEnum symTag) { ValidateArg.NotNullOrEmpty(typeName, "typeName"); IDiaEnumSymbols enumSymbols = null; IDiaSymbol typeSymbol = null; IDiaSymbol global = null; try { typeName = typeName.Replace('+', '.'); if (this.typeSymbols.ContainsKey(typeName)) { return(this.typeSymbols[typeName]); } this.session.GetGlobalScope(out global); global.FindChildren(symTag, typeName, 0, out enumSymbols); enumSymbols.GetNext(1, out typeSymbol, out uint celt); #if DEBUG if (typeSymbol == null) { IDiaEnumSymbols enumAllSymbols = null; try { global.FindChildren(symTag, null, 0, out enumAllSymbols); List <string> children = new List <string>(); while (true) { enumAllSymbols.GetNext(1, out IDiaSymbol childSymbol, out uint fetchedCount); if (fetchedCount == 0 || childSymbol == null) { break; } childSymbol.GetName(out var childSymbolName); children.Add(childSymbolName); ReleaseComObject(ref childSymbol); } Debug.Assert(children.Count > 0); } finally { ReleaseComObject(ref enumAllSymbols); } } #endif } finally { ReleaseComObject(ref enumSymbols); ReleaseComObject(ref global); } if (typeSymbol != null) { this.typeSymbols[typeName] = typeSymbol; } return(typeSymbol); }
private IDiaSymbol GetMethodSymbol(IDiaSymbol typeSymbol, string methodName) { ValidateArg.NotNull(typeSymbol, "typeSymbol"); ValidateArg.NotNullOrEmpty(methodName, "methodName"); IDiaEnumSymbols enumSymbols = null; IDiaSymbol methodSymbol = null; Dictionary <string, IDiaSymbol> methodSymbolsForType; try { typeSymbol.GetName(out string symbolName); if (this.methodSymbols.ContainsKey(symbolName)) { methodSymbolsForType = this.methodSymbols[symbolName]; if (methodSymbolsForType.ContainsKey(methodName)) { return(methodSymbolsForType[methodName]); } } else { methodSymbolsForType = new Dictionary <string, IDiaSymbol>(); this.methodSymbols[symbolName] = methodSymbolsForType; } typeSymbol.FindChildren(SymTagEnum.SymTagFunction, methodName, 0, out enumSymbols); enumSymbols.GetNext(1, out methodSymbol, out uint celtFetched); #if DEBUG if (methodSymbol == null) { IDiaEnumSymbols enumAllSymbols = null; try { typeSymbol.FindChildren(SymTagEnum.SymTagFunction, null, 0, out enumAllSymbols); List <string> children = new List <string>(); while (true) { enumAllSymbols.GetNext(1, out IDiaSymbol childSymbol, out uint fetchedCount); if (fetchedCount == 0 || childSymbol == null) { break; } childSymbol.GetName(out string childSymbolName); children.Add(childSymbolName); ReleaseComObject(ref childSymbol); } Debug.Assert(children.Count > 0); } finally { ReleaseComObject(ref enumAllSymbols); } } #endif } finally { ReleaseComObject(ref enumSymbols); } if (methodSymbol != null) { methodSymbolsForType[methodName] = methodSymbol; } return(methodSymbol); }
private void PopulateCacheForTypeAndMethodSymbols() { IDiaEnumSymbols enumTypeSymbols = null; IDiaSymbol global = null; try { this.session.GetGlobalScope(out global); global.FindChildren(SymTagEnum.SymTagCompiland, null, 0, out enumTypeSymbols); // NOTE:: // If foreach loop is used instead of Enumerator iterator, for some reason it leaves // the reference to pdb active, which prevents pdb from being rebuilt (in VS IDE scenario). enumTypeSymbols.GetNext(1, out IDiaSymbol typeSymbol, out uint celtTypeSymbol); while (celtTypeSymbol == 1 && typeSymbol != null) { typeSymbol.GetName(out var name); this.typeSymbols[name] = typeSymbol; IDiaEnumSymbols enumMethodSymbols = null; try { Dictionary <string, IDiaSymbol> methodSymbolsForType = new Dictionary <string, IDiaSymbol>(); typeSymbol.FindChildren(SymTagEnum.SymTagFunction, null, 0, out enumMethodSymbols); enumMethodSymbols.GetNext(1, out IDiaSymbol methodSymbol, out uint celtMethodSymbol); while (celtMethodSymbol == 1 && methodSymbol != null) { methodSymbol.GetName(out var methodName); UpdateMethodSymbolCache(methodName, methodSymbol, methodSymbolsForType); enumMethodSymbols.GetNext(1, out methodSymbol, out celtMethodSymbol); } this.methodSymbols[name] = methodSymbolsForType; } catch (Exception ex) { if (EqtTrace.IsErrorEnabled) { EqtTrace.Error( "Ignoring the exception while iterating method symbols:{0} for type:{1}", ex, name); } } finally { ReleaseComObject(ref enumMethodSymbols); } enumTypeSymbols.GetNext(1, out typeSymbol, out celtTypeSymbol); } } catch (Exception ex) { if (EqtTrace.IsErrorEnabled) { EqtTrace.Error("Ignoring the exception while iterating type symbols:{0}", ex); } } finally { ReleaseComObject(ref enumTypeSymbols); ReleaseComObject(ref global); } }