1 // ==++==
2 //
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 //
5 // ==--==
6 /*============================================================
7 **
8 ** Class:  ISymbolWriter
9 **
10 **
11 ** Represents a symbol writer for managed code. Provides methods to
12 ** define documents, sequence points, lexical scopes, and variables.
13 **
14 **
15 ===========================================================*/
16 namespace System.Diagnostics.SymbolStore {
17 
18     using System;
19     using System.Text;
20     using System.Reflection;
21     using System.Runtime.InteropServices;
22     using System.Runtime.Versioning;
23 
24     // Interface does not need to be marked with the serializable attribute
25 [System.Runtime.InteropServices.ComVisible(true)]
26     public interface ISymbolWriter
27     {
28         // Set the IMetadataEmitter that this symbol writer is associated
29         // with. This must be done only once before any other ISymbolWriter
30         // methods are called.
31         [ResourceExposure(ResourceScope.Machine)]
Initialize(IntPtr emitter, String filename, bool fFullBuild)32         void Initialize(IntPtr emitter, String filename, bool fFullBuild);
33 
34         // Define a source document. Guid's will be provided for the
35         // languages, vendors, and document types that we currently know
36         // about.
37         #if FEATURE_CORECLR
38         [System.Security.SecurityCritical] // auto-generated
39         #endif
DefineDocument(String url, Guid language, Guid languageVendor, Guid documentType)40         ISymbolDocumentWriter DefineDocument(String url,
41                                           Guid language,
42                                           Guid languageVendor,
43                                           Guid documentType);
44 
45         // Define the method that the user has defined as their entrypoint
46         // for this module. This would be, perhaps, the user's main method
47         // rather than compiler generated stubs before main.
48         #if FEATURE_CORECLR
49         [System.Security.SecurityCritical] // auto-generated
50         #endif
SetUserEntryPoint(SymbolToken entryMethod)51         void SetUserEntryPoint(SymbolToken entryMethod);
52 
53         // Open a method to emit symbol information into. The given method
54         // becomes the current method for calls do define sequence points,
55         // parameters and lexical scopes. There is an implicit lexical
56         // scope around the entire method. Re-opening a method that has
57         // been previously closed effectivley erases any previously
58         // defined symbols for that method.
59         //
60         // There can be only one open method at a time.
61         #if FEATURE_CORECLR
62         [System.Security.SecurityCritical] // auto-generated
63         #endif
OpenMethod(SymbolToken method)64         void OpenMethod(SymbolToken method);
65 
66         // Close the current method. Once a method is closed, no more
67         // symbols can be defined within it.
68         #if FEATURE_CORECLR
69         [System.Security.SecurityCritical] // auto-generated
70         #endif
CloseMethod()71         void CloseMethod();
72 
73         // Define a group of sequence points within the current method.
74         // Each line/column defines the start of a statement within a
75         // method. The arrays should be sorted by offset. The offset is
76         // always the offset from the start of the method, in bytes.
77         #if FEATURE_CORECLR
78         [System.Security.SecurityCritical] // auto-generated
79         #endif
DefineSequencePoints(ISymbolDocumentWriter document, int[] offsets, int[] lines, int[] columns, int[] endLines, int[] endColumns)80         void DefineSequencePoints(ISymbolDocumentWriter document,
81                                   int[] offsets,
82                                   int[] lines,
83                                   int[] columns,
84                                   int[] endLines,
85                                   int[] endColumns);
86 
87         // Open a new lexical scope in the current method. The scope
88         // becomes the new current scope and is effectivley pushed onto a
89         // stack of scopes. startOffset is the offset, in bytes from the
90         // beginning of the method, of the first instruction in the
91         // lexical scope. Scopes must form a hierarchy. Siblings are not
92         // allowed to overlap.
93         //
94         // OpenScope returns an opaque scope id that can be used with
95         // SetScopeRange to define a scope's start/end offset at a later
96         // time. In this case, the offsets passed to OpenScope and
97         // CloseScope are ignored.
98         //
99         // Note: scope id's are only valid in the current method.
100         //
101         // <TODO>@todo: should we require that startOffset and endOffset for
102         // scopes also be defined as sequence points?</TODO>
103         #if FEATURE_CORECLR
104         [System.Security.SecurityCritical] // auto-generated
105         #endif
OpenScope(int startOffset)106         int OpenScope(int startOffset);
107 
108         // Close the current lexical scope. Once a scope is closed no more
109         // variables can be defined within it. endOffset points past the
110         // last instruction in the scope.
111         #if FEATURE_CORECLR
112         [System.Security.SecurityCritical] // auto-generated
113         #endif
CloseScope(int endOffset)114         void CloseScope(int endOffset);
115 
116         // Define the offset range for a given lexical scope.
SetScopeRange(int scopeID, int startOffset, int endOffset)117         void SetScopeRange(int scopeID, int startOffset, int endOffset);
118 
119         // Define a single variable in the current lexical
120         // scope. startOffset and endOffset are optional. If 0, then they
121         // are ignored and the variable is defined over the entire
122         // scope. If non-zero, then they must fall within the offsets of
123         // the current scope. This can be called multiple times for a
124         // variable of the same name that has multiple homes throughout a
125         // scope. (Note: start/end offsets must not overlap in such a
126         // case.)
127         #if FEATURE_CORECLR
128         [System.Security.SecurityCritical] // auto-generated
129         #endif
DefineLocalVariable(String name, FieldAttributes attributes, byte[] signature, SymAddressKind addrKind, int addr1, int addr2, int addr3, int startOffset, int endOffset)130         void DefineLocalVariable(String name,
131                                         FieldAttributes attributes,
132                                         byte[] signature,
133                                         SymAddressKind addrKind,
134                                         int addr1,
135                                         int addr2,
136                                         int addr3,
137                                         int startOffset,
138                                         int endOffset);
139 
140         // Define a single parameter in the current method. The type of
141         // each parameter is taken from its position (sequence) within the
142         // method's signature.
143         //
144         // Note: if parameters are defined in the metadata for a given
145         // method, then clearly one would not have to define them again
146         // with calls to this method. The symbol readers will have to be
147         // smart enough to check the normal metadata for these first then
148         // fall back to the symbol store.
DefineParameter(String name, ParameterAttributes attributes, int sequence, SymAddressKind addrKind, int addr1, int addr2, int addr3)149         void DefineParameter(String name,
150                                     ParameterAttributes attributes,
151                                     int sequence,
152                                     SymAddressKind addrKind,
153                                     int addr1,
154                                     int addr2,
155                                     int addr3);
156 
157         // Define a single variable not within a method. This is used for
158         // certian fields in classes, bitfields, etc.
DefineField(SymbolToken parent, String name, FieldAttributes attributes, byte[] signature, SymAddressKind addrKind, int addr1, int addr2, int addr3)159         void DefineField(SymbolToken parent,
160                                 String name,
161                                 FieldAttributes attributes,
162                                 byte[] signature,
163                                 SymAddressKind addrKind,
164                                 int addr1,
165                                 int addr2,
166                                 int addr3);
167 
168         // Define a single global variable.
DefineGlobalVariable(String name, FieldAttributes attributes, byte[] signature, SymAddressKind addrKind, int addr1, int addr2, int addr3)169         void DefineGlobalVariable(String name,
170                                          FieldAttributes attributes,
171                                          byte[] signature,
172                                          SymAddressKind addrKind,
173                                          int addr1,
174                                          int addr2,
175                                          int addr3);
176 
177         // Close will close the ISymbolWriter and commit the symbols
178         // to the symbol store. The ISymbolWriter becomes invalid
179         // after this call for further updates.
Close()180         void Close();
181 
182         // Defines a custom attribute based upon its name. Not to be
183         // confused with Metadata custom attributes, these attributes are
184         // held in the symbol store.
185         #if FEATURE_CORECLR
186         [System.Security.SecurityCritical] // auto-generated
187         #endif
SetSymAttribute(SymbolToken parent, String name, byte[] data)188         void SetSymAttribute(SymbolToken parent, String name, byte[] data);
189 
190         // Opens a new namespace. Call this before defining methods or
191         // variables that live within a namespace. Namespaces can be nested.
OpenNamespace(String name)192         void OpenNamespace(String name);
193 
194         // Close the most recently opened namespace.
CloseNamespace()195         void CloseNamespace();
196 
197         // Specifies that the given, fully qualified namespace name is
198         // being used within the currently open lexical scope. Closing the
199         // current scope will also stop using the namespace, and the
200         // namespace will be in use in all scopes that inherit from the
201         // currently open scope.
202         #if FEATURE_CORECLR
203         [System.Security.SecurityCritical] // auto-generated
204         #endif
UsingNamespace(String fullName)205         void UsingNamespace(String fullName);
206 
207         // Specifies the true start and end of a method within a source
208         // file. Use this to specify the extent of a method independently
209         // of what sequence points exist within the method.
SetMethodSourceRange(ISymbolDocumentWriter startDoc, int startLine, int startColumn, ISymbolDocumentWriter endDoc, int endLine, int endColumn)210         void SetMethodSourceRange(ISymbolDocumentWriter startDoc,
211                                          int startLine,
212                                          int startColumn,
213                                          ISymbolDocumentWriter endDoc,
214                                          int endLine,
215                                          int endColumn);
216 
217         // Used to set the underlying ISymUnmanagedWriter that a
218         // managed ISymbolWriter may use to emit symbols with.
SetUnderlyingWriter(IntPtr underlyingWriter)219         void SetUnderlyingWriter(IntPtr underlyingWriter);
220     }
221 
222 }
223