提交 ce65fbb8 编写于 作者: T Tomáš Matoušek

Merge pull request #7818 from tmat/SymWriterCleanup

ISymUnmanagedWriter cleanup
......@@ -14,12 +14,17 @@ internal interface ISymUnmanagedDocumentWriter
void SetCheckSum(Guid algorithmId, uint checkSumSize, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] checkSum);
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("0B97726E-9E6D-4f05-9A26-424022093CAA"), SuppressUnmanagedCodeSecurity]
internal interface ISymUnmanagedWriter2
/// <summary>
/// The highest version of the interface available on Desktop FX 4.0+.
/// </summary>
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("DCF7780D-BDE9-45DF-ACFE-21731A32000C"), SuppressUnmanagedCodeSecurity]
internal interface ISymUnmanagedWriter5
{
#region ISymUnmanagedWriter
ISymUnmanagedDocumentWriter DefineDocument(string url, ref Guid language, ref Guid languageVendor, ref Guid documentType);
void SetUserEntryPoint(uint entryMethod);
void OpenMethod(uint method);
void SetUserEntryPoint(uint entryMethodToken);
void OpenMethod(uint methodToken);
void CloseMethod();
uint OpenScope(uint startOffset);
void CloseScope(uint endOffset);
......@@ -35,7 +40,7 @@ internal interface ISymUnmanagedWriter2
void UsingNamespace(string fullName);
void SetMethodSourceRange(ISymUnmanagedDocumentWriter startDoc, uint startLine, uint startColumn, object endDoc, uint endLine, uint endColumn);
void Initialize([MarshalAs(UnmanagedType.IUnknown)] object emitter, string filename, [MarshalAs(UnmanagedType.IUnknown)] object ptrIStream, bool fullBuild);
void GetDebugInfo(ref ImageDebugDirectory ptrIDD, uint dataCount, out uint dataCountPtr, IntPtr data);
void GetDebugInfo(ref ImageDebugDirectory debugDirectory, uint dataCount, out uint dataCountPtr, IntPtr data);
void DefineSequencePoints(ISymUnmanagedDocumentWriter document, uint count,
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] uint[] offsets,
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] uint[] lines,
......@@ -46,6 +51,11 @@ internal interface ISymUnmanagedWriter2
void Initialize2([MarshalAs(UnmanagedType.IUnknown)] object emitter, string tempfilename, [MarshalAs(UnmanagedType.IUnknown)] object ptrIStream, bool fullBuild, string finalfilename);
void DefineConstant(string name, object value, uint sig, IntPtr signature);
void Abort();
#endregion
#region ISymUnmanagedWriter2
void DefineLocalVariable2(string name, uint attributes, uint sigToken, uint addrKind, uint addr1, uint addr2, uint addr3, uint startOffset, uint endOffset);
void DefineGlobalVariable2(string name, uint attributes, uint sigToken, uint addrKind, uint addr1, uint addr2, uint addr3);
......@@ -56,6 +66,59 @@ internal interface ISymUnmanagedWriter2
/// marshalled them as the number of ticks since the Unix epoch (i.e. a much, much larger number).
/// </remarks>
void DefineConstant2([MarshalAs(UnmanagedType.LPWStr)] string name, VariantStructure value, uint sigToken);
#endregion
#region ISymUnmanagedWriter3
void OpenMethod2(uint methodToken, int sectionIndex, int offsetRelativeOffset);
void Commit();
#endregion
#region ISymUnmanagedWriter4
void GetDebugInfoWithPadding(ref ImageDebugDirectory debugDirectory, uint dataCount, out uint dataCountPtr, IntPtr data);
#endregion
#region ISymUnmanagedWriter5
/// <summary>
/// Open a special custom data section to emit token to source span mapping information into.
/// Opening this section while a method is already open or vice versa is an error.
/// </summary>
void OpenMapTokensToSourceSpans();
/// <summary>
/// Close the special custom data section for token to source span mapping
/// information. Once it is closed no more mapping information can be added.
/// </summary>
void CloseMapTokensToSourceSpans();
/// <summary>
/// Maps the given metadata token to the given source line span in the specified source file.
/// Must be called between calls to <see cref="OpenMapTokensToSourceSpans"/> and <see cref="CloseMapTokensToSourceSpans"/>.
/// </summary>
void MapTokenToSourceSpan(uint token, ISymUnmanagedDocumentWriter document, uint startLine, uint startColumn, uint endLine, uint endColumn);
#endregion
}
/// <summary>
/// The highest version of the interface available in Microsoft.DiaSymReader.Native.
/// </summary>
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("22DAEAF2-70F6-4EF1-B0C3-984F0BF27BFD"), SuppressUnmanagedCodeSecurity]
interface ISymUnmanagedWriter7 : ISymUnmanagedWriter5
{
// ISymUnmanagedWriter, ISymUnmanagedWriter2, ISymUnmanagedWriter3, ISymUnmanagedWriter4, ISymUnmanagedWriter5
void _VtblGap1_33();
// ISymUnmanagedWriter6
void InitializeDeterministic([MarshalAs(UnmanagedType.IUnknown)] object emitter, [MarshalAs(UnmanagedType.IUnknown)] object stream);
// ISymUnmanagedWriter7
unsafe void UpdateSignatureByHashingContent([In]byte* buffer, int size);
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("98ECEE1E-752D-11d3-8D56-00C04F680B2B"), SuppressUnmanagedCodeSecurity]
......@@ -68,17 +131,7 @@ internal interface IPdbWriter
void GetSignatureAge(out uint sig, out uint age);
}
internal static class ISymUnmanagedWriter2Helper
{
public static unsafe void DefineConstant2(this ISymUnmanagedWriter2 writer, string name, object value, uint sigToken)
{
VariantStructure variant = new VariantStructure();
Marshal.GetNativeVariantForObject(value, new IntPtr(&variant));
writer.DefineConstant2(name, variant, sigToken);
}
}
/// <summary>
/// A struct with the same size and layout as the native VARIANT type:
/// 2 bytes for a discriminator (i.e. which type of variant it is).
......@@ -132,48 +185,6 @@ internal struct VariantPadding
public readonly IntPtr Data3;
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("DCF7780D-BDE9-45DF-ACFE-21731A32000C"), SuppressUnmanagedCodeSecurity]
internal interface ISymUnmanagedWriter5 : ISymUnmanagedWriter2
{
// ISymUnmanagedWriter, ISymUnmanagedWriter2, ISymUnmanagedWriter3, ISymUnmanagedWriter4
void _VtblGap1_30();
// ISymUnmanagedWriter5
void OpenMapTokensToSourceSpans();
void CloseMapTokensToSourceSpans();
void MapTokenToSourceSpan(uint token, ISymUnmanagedDocumentWriter document, uint startLine, uint startColumn, uint endLine, uint endColumn);
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("CA6C2ED9-103D-46A9-B03B-05446485848B"), SuppressUnmanagedCodeSecurity]
internal interface ISymUnmanagedWriter6 : ISymUnmanagedWriter5
{
// ISymUnmanagedWriter, ISymUnmanagedWriter2, ISymUnmanagedWriter3, ISymUnmanagedWriter4, ISymUnmanagedWriter5
void _VtblGap1_33();
// ISymUnmanagedWriter6
void InitializeDeterministic([MarshalAs(UnmanagedType.IUnknown)] object emitter, [MarshalAs(UnmanagedType.IUnknown)] object stream);
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("22DAEAF2-70F6-4EF1-B0C3-984F0BF27BFD"), SuppressUnmanagedCodeSecurity]
interface ISymUnmanagedWriter7 : ISymUnmanagedWriter6
{
// ISymUnmanagedWriter, ISymUnmanagedWriter2, ISymUnmanagedWriter3, ISymUnmanagedWriter4, ISymUnmanagedWriter5, ISymUnmanagedWriter6
void _VtblGap1_34();
// ISymUnmanagedWriter7
unsafe void UpdateSignatureByHashingContent([In]byte* buffer, int size);
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("B473C610-C958-4C3D-99A0-F2BA0A38807C"), SuppressUnmanagedCodeSecurity]
interface ISymUnmanagedWriter100 : ISymUnmanagedWriter6
{
// ISymUnmanagedWriter, ISymUnmanagedWriter2, ISymUnmanagedWriter3, ISymUnmanagedWriter4, ISymUnmanagedWriter5, ISymUnmanagedWriter6
void _VtblGap1_34();
// ISymUnmanagedWriter100
void SetSignature(uint sig, Guid sig70);
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct ImageDebugDirectory
{
......
......@@ -232,7 +232,7 @@ internal sealed class PdbWriter : IDisposable
private readonly Func<object> _symWriterFactory;
private ComMemoryStream _pdbStream;
private MetadataWriter _metadataWriter;
private ISymUnmanagedWriter2 _symWriter;
private ISymUnmanagedWriter5 _symWriter;
private readonly Dictionary<DebugSourceDocument, ISymUnmanagedDocumentWriter> _documentMap = new Dictionary<DebugSourceDocument, ISymUnmanagedDocumentWriter>();
......@@ -805,7 +805,7 @@ public void SetMetadataEmitter(MetadataWriter metadataWriter)
{
try
{
var symWriter = (ISymUnmanagedWriter2)(_symWriterFactory != null ? _symWriterFactory() : CreateSymWriterWorker());
var symWriter = (ISymUnmanagedWriter5)(_symWriterFactory != null ? _symWriterFactory() : CreateSymWriterWorker());
// Correctness: If the stream is not specified or if it is non-empty the SymWriter appends data to it (provided it contains valid PDB)
// and the resulting PDB has Age = existing_age + 1.
......@@ -813,12 +813,12 @@ public void SetMetadataEmitter(MetadataWriter metadataWriter)
if (_deterministic)
{
if (!(symWriter is ISymUnmanagedWriter7 || symWriter is ISymUnmanagedWriter100))
if (!(symWriter is ISymUnmanagedWriter7))
{
throw new NotSupportedException(CodeAnalysisResources.SymWriterNotDeterministic);
}
((ISymUnmanagedWriter6)symWriter).InitializeDeterministic(new PdbMetadataWrapper(metadataWriter), _pdbStream);
((ISymUnmanagedWriter7)symWriter).InitializeDeterministic(new PdbMetadataWrapper(metadataWriter), _pdbStream);
}
else
{
......@@ -843,18 +843,6 @@ public unsafe ContentId GetContentId()
try
{
// TODO: remove once we can rely on the presence of ISymUnmanagedWriter7
var writer100 = _symWriter as ISymUnmanagedWriter100;
if (writer100 != null)
{
var id = ContentId.FromHash(ImmutableArray.CreateRange(hash));
Debug.Assert(BitConverter.IsLittleEndian);
writer100.SetSignature(BitConverter.ToUInt32(id.Stamp, 0), new Guid(id.Guid));
return id;
}
fixed (byte* hashPtr = &hash[0])
{
((ISymUnmanagedWriter7)_symWriter).UpdateSignatureByHashingContent(hashPtr, hash.Length);
......@@ -1235,7 +1223,7 @@ private void DefineLocalConstant(string name, object value, PrimitiveTypeCode ty
{
try
{
_symWriter.DefineConstant2(name, value, constantSignatureToken);
DefineLocalConstantImpl(name, value, constantSignatureToken);
if (_callLogger.LogOperation(OP.DefineConstant2))
{
_callLogger.LogArgument(name);
......@@ -1250,6 +1238,13 @@ private void DefineLocalConstant(string name, object value, PrimitiveTypeCode ty
}
}
private unsafe void DefineLocalConstantImpl(string name, object value, uint sigToken)
{
VariantStructure variant = new VariantStructure();
Marshal.GetNativeVariantForObject(value, new IntPtr(&variant));
_symWriter.DefineConstant2(name, variant, sigToken);
}
private void DefineLocalStringConstant(string name, string value, uint constantSignatureToken)
{
Debug.Assert(value != null);
......@@ -1268,7 +1263,7 @@ private void DefineLocalStringConstant(string name, string value, uint constantS
try
{
_symWriter.DefineConstant2(name, value, constantSignatureToken);
DefineLocalConstantImpl(name, value, constantSignatureToken);
if (_callLogger.LogOperation(OP.DefineConstant2))
{
_callLogger.LogArgument(name);
......
......@@ -6,7 +6,7 @@
namespace Roslyn.Test.Utilities
{
internal class MockSymUnmanagedWriter : ISymUnmanagedWriter2
internal class MockSymUnmanagedWriter : ISymUnmanagedWriter5
{
public virtual void Abort()
{
......@@ -18,6 +18,11 @@ public virtual void Close()
throw new NotImplementedException();
}
public void CloseMapTokensToSourceSpans()
{
throw new NotImplementedException();
}
public virtual void CloseMethod()
{
throw new NotImplementedException();
......@@ -33,6 +38,11 @@ public virtual void CloseScope(uint endOffset)
throw new NotImplementedException();
}
public void Commit()
{
throw new NotImplementedException();
}
public virtual void DefineConstant(string name, object value, uint sig, IntPtr signature)
{
throw new NotImplementedException();
......@@ -88,6 +98,11 @@ public virtual void GetDebugInfo(ref ImageDebugDirectory ptrIDD, uint dataCount,
throw new NotImplementedException();
}
public void GetDebugInfoWithPadding(ref ImageDebugDirectory debugDirectory, uint dataCount, out uint dataCountPtr, IntPtr data)
{
throw new NotImplementedException();
}
public virtual void Initialize([MarshalAs(UnmanagedType.IUnknown)]object emitter, string filename, [MarshalAs(UnmanagedType.IUnknown)]object ptrIStream, bool fullBuild)
{
throw new NotImplementedException();
......@@ -98,11 +113,26 @@ public virtual void Initialize2([MarshalAs(UnmanagedType.IUnknown)]object emitte
throw new NotImplementedException();
}
public void MapTokenToSourceSpan(uint token, ISymUnmanagedDocumentWriter document, uint startLine, uint startColumn, uint endLine, uint endColumn)
{
throw new NotImplementedException();
}
public void OpenMapTokensToSourceSpans()
{
throw new NotImplementedException();
}
public virtual void OpenMethod(uint method)
{
throw new NotImplementedException();
}
public void OpenMethod2(uint methodToken, int sectionIndex, int offsetRelativeOffset)
{
throw new NotImplementedException();
}
public virtual void OpenNamespace(string name)
{
throw new NotImplementedException();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册