22import cllvm
33#endif
44
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 {
641 func asMetadata( ) -> LLVMMetadataRef
742}
843
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+
9133struct AnyMetadata : Metadata {
10134 let llvm : LLVMMetadataRef
11135
@@ -14,59 +138,200 @@ struct AnyMetadata: Metadata {
14138 }
15139}
16140
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 {
18181 internal let llvm : LLVMMetadataRef
19182
20183 public func asMetadata( ) -> LLVMMetadataRef {
21184 return llvm
22185 }
186+
187+ public init ( llvm: LLVMMetadataRef ) {
188+ self . llvm = llvm
189+ }
23190}
24191
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 {
26200 internal let llvm : LLVMMetadataRef
27201
28202 public func asMetadata( ) -> LLVMMetadataRef {
29203 return llvm
30204 }
205+
206+ public init ( llvm: LLVMMetadataRef ) {
207+ self . llvm = llvm
208+ }
31209}
32210
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 {
34217 internal let llvm : LLVMMetadataRef
35218
36219 public func asMetadata( ) -> LLVMMetadataRef {
37220 return llvm
38221 }
222+
223+ public init ( llvm: LLVMMetadataRef ) {
224+ self . llvm = llvm
225+ }
39226}
40227
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 {
42235 internal let llvm : LLVMMetadataRef
43236
44237 public func asMetadata( ) -> LLVMMetadataRef {
45238 return llvm
46239 }
240+
241+ public init ( llvm: LLVMMetadataRef ) {
242+ self . llvm = llvm
243+ }
47244}
48245
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 {
50251 internal let llvm : LLVMMetadataRef
51252
52253 public func asMetadata( ) -> LLVMMetadataRef {
53254 return llvm
54255 }
256+
257+ public init ( llvm: LLVMMetadataRef ) {
258+ self . llvm = llvm
259+ }
55260}
56261
57- public struct DIExpression : Metadata {
262+ /// `LocalVariableMetadata` nodes represent local variables and function
263+ /// parameters in the source language.
264+ public struct LocalVariableMetadata : Metadata {
58265 internal let llvm : LLVMMetadataRef
59266
60267 public func asMetadata( ) -> LLVMMetadataRef {
61268 return llvm
62269 }
270+
271+ public init ( llvm: LLVMMetadataRef ) {
272+ self . llvm = llvm
273+ }
63274}
64275
276+ /// `ObjectiveCPropertyMetadata` nodes represent Objective-C property nodes.
277+ public struct ObjectiveCPropertyMetadata : Metadata {
278+ internal let llvm : LLVMMetadataRef
65279
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 {
67292 internal let llvm : LLVMMetadataRef
68293
69294 public func asMetadata( ) -> LLVMMetadataRef {
70295 return llvm
71296 }
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+ }
72337}
0 commit comments