1 /** 2 Copyright: Copyright (c) 2017, Joakim Brännström. All rights reserved. 3 License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) 4 Author: Joakim Brännström (joakim.brannstrom@gmx.com) 5 */ 6 module llvm_hiwrap.value.metadata; 7 8 import llvm_hiwrap.types; 9 import llvm_hiwrap.value.value; 10 11 /** Example of a named metadata node: !foo = !{!4, !3} 12 * 13 * See Context for how to convert this to a MetadataNodeValue. 14 */ 15 struct NamedMetadataValue { 16 LxNamedMetadataValue value; 17 alias value this; 18 } 19 20 /** Correspond to a named metadata node where the operands are resolved. 21 * 22 * An example would be in pseudo LLVM IR: 23 * !0 = !{i32 4} 24 * !1 = !{i32 10} 25 * !foo = !{!0, !1} 26 * 27 * resolved to: 28 * !<anonymouse> = !{!{i32 4}, !{i32 10}} 29 * 30 * Note how it wrappes the data. But it is not _true_ data but still only 31 * references. But one reference, the MDNode, have at least been stripped away. 32 * 33 * This lead to the simple retrival of data via LLVMGetMDNodeOperands. 34 */ 35 struct ResolvedNamedMetadataValue { 36 import llvm; 37 import llvm_hiwrap.context : Context; 38 39 LxResolvedNamedMetadataValue value; 40 alias value this; 41 42 /// Obtain the number of operands. 43 auto countOperands() { 44 return LLVMGetMDNodeNumOperands(this); 45 } 46 47 /// Obtain the given MDNode's operands. 48 OperandsValue2 operands() { 49 return OperandsValue2(this); 50 } 51 } 52 53 /** 54 * It is statically known that the operands are all MDNode's wrapping values 55 * because this is derived from a named metadata. 56 * 57 * See Core.cpp function LLVMMDStringInContext in the llvm source code. 58 */ 59 struct OperandsValue2 { 60 import llvm; 61 import llvm_hiwrap.value.value; 62 63 private LLVMValueRef[] ops; 64 private const size_t length_; 65 66 this(ResolvedNamedMetadataValue v) { 67 length_ = v.countOperands; 68 if (length_ != 0) { 69 ops.length = length_; 70 LLVMGetMDNodeOperands(v, ops.ptr); 71 } 72 } 73 74 size_t length() { 75 return length_; 76 } 77 78 MetadataNodeValue opIndex(size_t index) { 79 return ops[index].LxValue.LxMetadataNodeValue.MetadataNodeValue; 80 } 81 82 import llvm_hiwrap.util : IndexedRangeX; 83 84 mixin IndexedRangeX!MetadataNodeValue; 85 } 86 87 /** Correspond to an unnamed metadata node. 88 * 89 * Example of a node: !0 = !{!"test\00", i32 10} 90 * 91 * For the composite nodes (DICompositeType) types. 92 * See: https://llvm.org/docs/LangRef.html#metadata 93 */ 94 struct MetadataNodeValue { 95 import llvm; 96 import llvm_hiwrap.context : Context; 97 98 LxMetadataNodeValue value; 99 alias value this; 100 101 /// Obtain the number of operands. 102 auto countOperands() { 103 return LLVMGetMDNodeNumOperands(this); 104 } 105 106 /// Obtain the given MDNode's operands. 107 OperandsValue operands() { 108 return OperandsValue(this); 109 } 110 } 111 112 struct OperandsValue { 113 import llvm; 114 import llvm_hiwrap.value.value; 115 116 private LLVMValueRef[] ops; 117 private const size_t length_; 118 119 this(MetadataNodeValue v) { 120 length_ = v.countOperands; 121 if (length_ != 0) { 122 ops.length = length_; 123 LLVMGetMDNodeOperands(v, ops.ptr); 124 } 125 } 126 127 size_t length() { 128 return length_; 129 } 130 131 Value opIndex(size_t index) { 132 return ops[index].LxValue.Value; 133 } 134 135 import llvm_hiwrap.util : IndexedRangeX; 136 137 mixin IndexedRangeX!Value; 138 } 139 140 /// Obtained from a Context. 141 struct MetadataStringValue { 142 import llvm; 143 144 LxMetadataStringValue value; 145 alias value this; 146 147 /** Obtain the underlying string from a MDString value. 148 * 149 * @param V Instance to obtain string from. 150 * @param Length Memory address which will hold length of returned string. 151 * @return String data in MDString. 152 */ 153 const(char)[] toString() { 154 uint len; 155 auto s = LLVMGetMDString(this, &len); 156 return s[0 .. len]; 157 } 158 } 159 160 /** Obtain a MDString value from the global context. 161 */ 162 //LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count);