@@ -22,6 +22,9 @@ public protocol _IRMetadataInitializerHack {
2222/// Metadata does not have a type, and is not a value. If referenced from a call
2323/// instruction, it uses the metadata type.
2424///
25+ /// Debug Information
26+ /// =================
27+ ///
2528/// The idea of LLVM debugging information is to capture how the important
2629/// pieces of the source-language’s Abstract Syntax Tree map onto LLVM code.
2730/// LLVM takes a number of positions on the impact of the broader compilation
@@ -389,37 +392,60 @@ public struct NameSpaceMetadata: DIScope {
389392}
390393
391394/// `MDString` nodes represent string constants in metadata nodes.
392- public struct MDString : IRMetadata {
395+ public struct MDString : IRMetadata , ExpressibleByStringLiteral {
396+ public typealias StringLiteralType = String
397+
393398 private let llvm : LLVMMetadataRef
394399
395400 public init ( llvm: LLVMMetadataRef ) {
396401 self . llvm = llvm
397402 }
398403
404+ /// Create an `MDString` node from the given string value.
405+ ///
406+ /// - Parameters:
407+ /// - value: The string value to assign to this metadata node.
399408 public init ( _ value: String ) {
400409 self . llvm = LLVMValueAsMetadata ( LLVMMDString ( value, UInt32 ( value. count) ) )
401410 }
402411
412+ public init ( stringLiteral value: String ) {
413+ self . llvm = LLVMValueAsMetadata ( LLVMMDString ( value, UInt32 ( value. count) ) )
414+ }
415+
403416 public func asMetadata( ) -> LLVMMetadataRef {
404417 return llvm
405418 }
406419}
407420
408- /// `MDNode` nodes represent generic metadata nodes.
421+ /// `MDNode` objects represent generic nodes in a metadata graph.
422+ ///
423+ /// A metadata node is a tuple of references to other metadata. In general,
424+ /// metadata graphs are acyclic and terminate in metadata nodes without
425+ /// operands.
409426public struct MDNode : IRMetadata {
410427 private let llvm : LLVMMetadataRef
411428
412429 public init ( llvm: LLVMMetadataRef ) {
413430 self . llvm = llvm
414431 }
415432
433+ /// Create a metadata node in the given context with the given operands.
434+ ///
435+ /// - Parameters:
436+ /// - context: The context to allocate the node in.
437+ /// - operands: The operands to attach to the metadata node.
416438 public init ( in context: Context = . global, operands: [ IRMetadata ] ) {
417439 var operands = operands. map { $0. asMetadata ( ) as Optional }
418440 self . llvm = operands. withUnsafeMutableBufferPointer { buf in
419441 return LLVMMDNodeInContext2 ( context. llvm, buf. baseAddress!, UInt32 ( buf. count) )
420442 }
421443 }
422444
445+ /// Create a metadata node with the value of a given constant.
446+ ///
447+ /// - Parameters:
448+ /// - constant: The constant value to attach to the node.
423449 public init ( constant: IRConstant ) {
424450 self . llvm = LLVMValueAsMetadata ( constant. asLLVM ( ) )
425451 }
@@ -429,20 +455,56 @@ public struct MDNode: IRMetadata {
429455 }
430456}
431457
458+ /// Represents a temporary metadata node.
459+ ///
460+ /// Temporary metadata nodes aid in the construction of cyclic metadata. The
461+ /// typical construction pattern is usually as follows:
462+ ///
463+ /// // Allocate a temporary temp node
464+ /// let temp = TemporaryMDNode(in: context, operands: [])
465+ /// // Prepare the operands to the metadata node...
466+ /// var ops = [IRMetadata]()
467+ /// // ...
468+ /// // Create the real node
469+ /// let root = MDNode(in: context, operands: ops)
470+ ///
471+ /// At this point we have the following metadata structure:
472+ ///
473+ /// // !0 = metadata !{} <- temp
474+ /// // !1 = metadata !{metadata !0} <- root
475+ /// // Replace the temp operand with the root node
476+ ///
477+ /// The knot is tied by RAUW'ing the temporary node:
478+ ///
479+ /// temp.replaceAllUses(with: root)
480+ /// // We now have
481+ /// // !1 = metadata !{metadata !1} <- self-referential root
482+ ///
483+ /// - Warning: It is critical that temporary metadata nodes be "RAUW'd"
484+ /// (replace-all-uses-with) before the metadata graph is finalized. After
485+ /// that time, all remaining temporary metadata nodes will become unresolved
486+ /// metadata.
432487public class TemporaryMDNode : IRMetadata {
433488 private let llvm : LLVMMetadataRef
434489
435490 required public init ( llvm: LLVMMetadataRef ) {
436491 self . llvm = llvm
437492 }
438493
494+ /// Create a new temporary metadata node in the given context with the
495+ /// given operands.
496+ ///
497+ /// - Parameters:
498+ /// - context: The context to allocate the node in.
499+ /// - operands: The operands to attach to the metadata node.
439500 public init ( in context: Context = . global, operands: [ IRMetadata ] ) {
440501 var operands = operands. map { $0. asMetadata ( ) as Optional }
441502 self . llvm = operands. withUnsafeMutableBufferPointer { buf in
442503 return LLVMTemporaryMDNode ( context. llvm, buf. baseAddress!, buf. count)
443504 }
444505 }
445506
507+ /// Deinitialize this value and dispose of its resources.
446508 deinit {
447509 LLVMDisposeTemporaryMDNode ( self . llvm)
448510 }
0 commit comments