2
2
import cllvm
3
3
#endif
4
4
5
- public protocol Metadata {
5
+ public protocol _IRMetadataInitializerHack {
6
+ init ( llvm: LLVMMetadataRef )
7
+ }
8
+
9
+ /// The `Metadata` protocol captures those types that represent metadata nodes
10
+ /// in LLVM IR.
11
+ ///
12
+ /// LLVM IR allows metadata to be attached to instructions in the program that
13
+ /// can convey extra information about the code to the optimizers and code
14
+ /// generator. One example application of metadata is source-level debug
15
+ /// information.
16
+ ///
17
+ /// Metadata does not have a type, and is not a value. If referenced from a call
18
+ /// instruction, it uses the metadata type.
19
+ ///
20
+ /// The idea of LLVM debugging information is to capture how the important
21
+ /// pieces of the source-language’s Abstract Syntax Tree map onto LLVM code.
22
+ /// LLVM takes a number of positions on the impact of the broader compilation
23
+ /// process on debug information:
24
+ ///
25
+ /// - Debugging information should have very little impact on the rest of the
26
+ /// compiler. No transformations, analyses, or code generators should need to
27
+ /// be modified because of debugging information.
28
+ /// - LLVM optimizations should interact in well-defined and easily described
29
+ /// ways with the debugging information.
30
+ /// - Because LLVM is designed to support arbitrary programming languages,
31
+ /// LLVM-to-LLVM tools should not need to know anything about the semantics
32
+ /// of the source-level-language.
33
+ /// - Source-level languages are often widely different from one another. LLVM
34
+ /// should not put any restrictions of the flavor of the source-language, and
35
+ /// the debugging information should work with any language.
36
+ /// - With code generator support, it should be possible to use an LLVM compiler
37
+ /// to compile a program to native machine code and standard debugging
38
+ /// formats. This allows compatibility with traditional machine-code level
39
+ /// debuggers, like GDB, DBX, or CodeView.
40
+ public protocol Metadata : _IRMetadataInitializerHack {
6
41
func asMetadata( ) -> LLVMMetadataRef
7
42
}
8
43
44
+ extension Metadata {
45
+ /// Replaces all uses of the this metadata with the given metadata.
46
+ ///
47
+ /// - parameter metadata: The new value to swap in.
48
+ public func replaceAllUses( with metadata: Metadata ) {
49
+ LLVMMetadataReplaceAllUsesWith ( self . asMetadata ( ) , metadata. asMetadata ( ) )
50
+ }
51
+ }
52
+
53
+ extension Metadata {
54
+ /// Dumps a representation of this metadata to stderr.
55
+ public func dump( ) {
56
+ LLVMDumpValue ( LLVMMetadataAsValue ( LLVMGetGlobalContext ( ) , self . asMetadata ( ) ) )
57
+ }
58
+
59
+ public func forceCast< DestTy: Metadata > ( to: DestTy . Type ) -> DestTy {
60
+ return DestTy ( llvm: self . asMetadata ( ) )
61
+ }
62
+ }
63
+
64
+ /// Denotes a scope in which child metadata nodes can be inserted.
65
+ public protocol DIScope : Metadata { }
66
+
67
+ /// Denotes metadata for a type.
68
+ public protocol DIType : DIScope { }
69
+
70
+ extension DIType {
71
+ /// Retrieves the name of this type.
72
+ public var name : String {
73
+ var length : Int = 0
74
+ let cstring = LLVMDITypeGetName ( self . asMetadata ( ) , & length)
75
+ return String ( cString: cstring!)
76
+ }
77
+
78
+ /// Retrieves the size of the type represented by this metadata in bits.
79
+ public var sizeInBits : Size {
80
+ return Size ( LLVMDITypeGetSizeInBits ( self . asMetadata ( ) ) )
81
+ }
82
+
83
+ /// Retrieves the offset of the type represented by this metadata in bits.
84
+ public var offsetInBits : Size {
85
+ return Size ( LLVMDITypeGetOffsetInBits ( self . asMetadata ( ) ) )
86
+ }
87
+
88
+ /// Retrieves the alignment of the type represented by this metadata in bits.
89
+ public var alignmentInBits : Alignment {
90
+ return Alignment ( LLVMDITypeGetAlignInBits ( self . asMetadata ( ) ) )
91
+ }
92
+
93
+ /// Retrieves the line the type represented by this metadata is declared on.
94
+ public var line : Int {
95
+ return Int ( LLVMDITypeGetLine ( self . asMetadata ( ) ) )
96
+ }
97
+
98
+ /// Retrieves the flags the type represented by this metadata is declared
99
+ /// with.
100
+ public var flags : DIFlags {
101
+ return DIFlags ( rawValue: LLVMDITypeGetFlags ( self . asMetadata ( ) ) . rawValue)
102
+ }
103
+ }
104
+
105
+ /// A `DebugLocation` represents a location in source.
106
+ public struct DebugLocation : Metadata {
107
+ internal let llvm : LLVMMetadataRef
108
+
109
+ public func asMetadata( ) -> LLVMMetadataRef {
110
+ return llvm
111
+ }
112
+
113
+ /// Retrieves the line described by this location.
114
+ public var line : Int {
115
+ return Int ( LLVMDILocationGetLine ( self . llvm) )
116
+ }
117
+
118
+ /// Retrieves the column described by this location.
119
+ public var column : Int {
120
+ return Int ( LLVMDILocationGetColumn ( self . llvm) )
121
+ }
122
+
123
+ /// Retrieves the enclosing scope containing this location.
124
+ public var scope : DIScope {
125
+ return DIOpaqueType ( llvm: LLVMDILocationGetScope ( self . llvm) )
126
+ }
127
+
128
+ public init ( llvm: LLVMMetadataRef ) {
129
+ self . llvm = llvm
130
+ }
131
+ }
132
+
9
133
struct AnyMetadata : Metadata {
10
134
let llvm : LLVMMetadataRef
11
135
@@ -14,59 +138,200 @@ struct AnyMetadata: Metadata {
14
138
}
15
139
}
16
140
17
- public struct VariableMetadata : Metadata {
141
+ struct DIOpaqueType : DIType {
142
+ internal let llvm : LLVMMetadataRef
143
+
144
+ public func asMetadata( ) -> LLVMMetadataRef {
145
+ return llvm
146
+ }
147
+
148
+ public init ( llvm: LLVMMetadataRef ) {
149
+ self . llvm = llvm
150
+ }
151
+ }
152
+
153
+ /// `CompileUnitMetadata` nodes represent a compile unit, the root of a metadata
154
+ /// hierarchy for a translation unit.
155
+ ///
156
+ /// Compile unit descriptors provide the root scope for objects declared in a
157
+ /// specific compilation unit. `FileMetadata` descriptors are defined using this
158
+ /// scope.
159
+ ///
160
+ /// These descriptors are collected by a named metadata node `!llvm.dbg.cu`.
161
+ /// They keep track of global variables, type information, and imported entities
162
+ /// (declarations and namespaces).
163
+ public struct CompileUnitMetadata : DIScope {
164
+ internal let llvm : LLVMMetadataRef
165
+
166
+ public func asMetadata( ) -> LLVMMetadataRef {
167
+ return llvm
168
+ }
169
+
170
+ public init ( llvm: LLVMMetadataRef ) {
171
+ self . llvm = llvm
172
+ }
173
+ }
174
+
175
+
176
+ /// `FileMetadata` nodes represent files.
177
+ ///
178
+ /// The file name does not necessarily have to be a proper file path. For
179
+ /// example, it can include additional slash-separated path components.
180
+ public struct FileMetadata : DIScope {
18
181
internal let llvm : LLVMMetadataRef
19
182
20
183
public func asMetadata( ) -> LLVMMetadataRef {
21
184
return llvm
22
185
}
186
+
187
+ public init ( llvm: LLVMMetadataRef ) {
188
+ self . llvm = llvm
189
+ }
23
190
}
24
191
25
- public struct FileMetadata : Metadata {
192
+ /// `DIBasicType` nodes represent primitive types, such as `int`, `bool` and
193
+ /// `float`.
194
+ ///
195
+ /// Basic types carry an encoding describing the details of the type to
196
+ /// influence how it is presented in debuggers. LLVM currently supports
197
+ /// specific DWARF "Attribute Type Encodings" that are enumerated in
198
+ /// `DIAttributeTypeEncoding`.
199
+ public struct DIBasicType : DIType {
26
200
internal let llvm : LLVMMetadataRef
27
201
28
202
public func asMetadata( ) -> LLVMMetadataRef {
29
203
return llvm
30
204
}
205
+
206
+ public init ( llvm: LLVMMetadataRef ) {
207
+ self . llvm = llvm
208
+ }
31
209
}
32
210
33
- public struct Scope : Metadata {
211
+ /// `DISubroutineType` nodes represent subroutine types.
212
+ ///
213
+ /// Subroutine types are meant to mirror their formal declarations in source:
214
+ /// arguments are represented in order. The return type is optional and meant
215
+ /// to represent the concept of `void` in C-like languages.
216
+ public struct DISubroutineType : DIType {
34
217
internal let llvm : LLVMMetadataRef
35
218
36
219
public func asMetadata( ) -> LLVMMetadataRef {
37
220
return llvm
38
221
}
222
+
223
+ public init ( llvm: LLVMMetadataRef ) {
224
+ self . llvm = llvm
225
+ }
39
226
}
40
227
41
- public struct Macro : Metadata {
228
+ /// `LexicalBlockMetadata` nodes describe nested blocks within a subprogram. The
229
+ /// line number and column numbers are used to distinguish two lexical blocks at
230
+ /// same depth.
231
+ ///
232
+ /// Usually lexical blocks are distinct to prevent node merging based on
233
+ /// operands.
234
+ public struct LexicalBlockMetadata : DIScope {
42
235
internal let llvm : LLVMMetadataRef
43
236
44
237
public func asMetadata( ) -> LLVMMetadataRef {
45
238
return llvm
46
239
}
240
+
241
+ public init ( llvm: LLVMMetadataRef ) {
242
+ self . llvm = llvm
243
+ }
47
244
}
48
245
49
- public struct DIModule : Metadata {
246
+ /// `LexicalBlockFile` nodes are used to discriminate between sections of a
247
+ /// lexical block. The file field can be changed to indicate textual inclusion,
248
+ /// or the discriminator field can be used to discriminate between control flow
249
+ /// within a single block in the source language.
250
+ public struct LexicalBlockFileMetadata : DIScope {
50
251
internal let llvm : LLVMMetadataRef
51
252
52
253
public func asMetadata( ) -> LLVMMetadataRef {
53
254
return llvm
54
255
}
256
+
257
+ public init ( llvm: LLVMMetadataRef ) {
258
+ self . llvm = llvm
259
+ }
55
260
}
56
261
57
- public struct DIExpression : Metadata {
262
+ /// `LocalVariableMetadata` nodes represent local variables and function
263
+ /// parameters in the source language.
264
+ public struct LocalVariableMetadata : Metadata {
58
265
internal let llvm : LLVMMetadataRef
59
266
60
267
public func asMetadata( ) -> LLVMMetadataRef {
61
268
return llvm
62
269
}
270
+
271
+ public init ( llvm: LLVMMetadataRef ) {
272
+ self . llvm = llvm
273
+ }
63
274
}
64
275
276
+ /// `ObjectiveCPropertyMetadata` nodes represent Objective-C property nodes.
277
+ public struct ObjectiveCPropertyMetadata : Metadata {
278
+ internal let llvm : LLVMMetadataRef
65
279
66
- public struct DebugLocation : Metadata {
280
+ public func asMetadata( ) -> LLVMMetadataRef {
281
+ return llvm
282
+ }
283
+
284
+ public init ( llvm: LLVMMetadataRef ) {
285
+ self . llvm = llvm
286
+ }
287
+ }
288
+
289
+ /// `ImportedEntityMetadata` nodes represent entities (such as modules) imported
290
+ /// into a compile unit.
291
+ public struct ImportedEntityMetadata : DIType {
67
292
internal let llvm : LLVMMetadataRef
68
293
69
294
public func asMetadata( ) -> LLVMMetadataRef {
70
295
return llvm
71
296
}
297
+
298
+ public init ( llvm: LLVMMetadataRef ) {
299
+ self . llvm = llvm
300
+ }
301
+ }
302
+
303
+ public struct FunctionMetadata : DIScope {
304
+ internal let llvm : LLVMMetadataRef
305
+
306
+ public func asMetadata( ) -> LLVMMetadataRef {
307
+ return llvm
308
+ }
309
+
310
+ public init ( llvm: LLVMMetadataRef ) {
311
+ self . llvm = llvm
312
+ }
313
+ }
314
+
315
+ public struct ModuleMetadata : DIScope {
316
+ internal let llvm : LLVMMetadataRef
317
+
318
+ public func asMetadata( ) -> LLVMMetadataRef {
319
+ return llvm
320
+ }
321
+
322
+ public init ( llvm: LLVMMetadataRef ) {
323
+ self . llvm = llvm
324
+ }
325
+ }
326
+
327
+ public struct NameSpaceMetadata : DIScope {
328
+ internal let llvm : LLVMMetadataRef
329
+
330
+ public func asMetadata( ) -> LLVMMetadataRef {
331
+ return llvm
332
+ }
333
+
334
+ public init ( llvm: LLVMMetadataRef ) {
335
+ self . llvm = llvm
336
+ }
72
337
}
0 commit comments