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 # LxValue
7 The following is copied from llvm-c/Core.h
8 
9 The bulk of LLVM's object model consists of values, which comprise a very
10 rich type hierarchy.
11 
12 LLVMValueRef essentially represents llvm::Value. There is a rich
13 hierarchy of classes within this type. Depending on the instance
14 obtained, not all APIs are available.
15 
16 Callers can determine the type of an LLVMValueRef by calling the
17 LLVMIsA* family of functions (e.g. LLVMIsAArgument()). These
18 functions are defined by a macro, so it isn't obvious which are
19 available by looking at the Doxygen source code. Instead, look at the
20 source definition of LLVM_FOR_EACH_VALUE_SUBCLASS and note the list
21 of value names given. These value names also correspond to classes in
22 the llvm::Value hierarchy.
23 
24   macro(Argument)
25   macro(BasicBlock)
26   macro(InlineAsm)
27   macro(User)
28     macro(Constant)
29       macro(BlockAddress)
30       macro(ConstantAggregateZero)
31       macro(ConstantArray)
32       macro(ConstantDataSequential)
33         macro(ConstantDataArray)
34         macro(ConstantDataVector)
35       macro(ConstantExpr)
36       macro(ConstantFP)
37       macro(ConstantInt)
38       macro(ConstantPointerNull)
39       macro(ConstantStruct)
40       macro(ConstantTokenNone)
41       macro(ConstantVector)
42       macro(GlobalValue)
43         macro(GlobalAlias)
44         macro(GlobalObject)
45           macro(Function)
46           macro(GlobalVariable)
47       macro(UndefValue)
48     macro(Instruction)
49       macro(BinaryOperator)
50       macro(CallInst)
51         macro(IntrinsicInst)
52           macro(DbgInfoIntrinsic)
53             macro(DbgDeclareInst)
54           macro(MemIntrinsic)
55             macro(MemCpyInst)
56             macro(MemMoveInst)
57             macro(MemSetInst)
58       macro(CmpInst)
59         macro(FCmpInst)
60         macro(ICmpInst)
61       macro(ExtractElementInst)
62       macro(GetElementPtrInst)
63       macro(InsertElementInst)
64       macro(InsertValueInst)
65       macro(LandingPadInst)
66       macro(PHINode)
67       macro(SelectInst)
68       macro(ShuffleVectorInst)
69       macro(StoreInst)
70       macro(TerminatorInst)
71         macro(BranchInst)
72         macro(IndirectBrInst)
73         macro(InvokeInst)
74         macro(ReturnInst)
75         macro(SwitchInst)
76         macro(UnreachableInst)
77         macro(ResumeInst)
78         macro(CleanupReturnInst)
79         macro(CatchReturnInst)
80       macro(FuncletPadInst)
81         macro(CatchPadInst)
82         macro(CleanupPadInst)
83       macro(UnaryInstruction)
84         macro(AllocaInst)
85         macro(CastInst)
86           macro(AddrSpaceCastInst)
87           macro(BitCastInst)
88           macro(FPExtInst)
89           macro(FPToSIInst)
90           macro(FPToUIInst)
91           macro(FPTruncInst)
92           macro(IntToPtrInst)
93           macro(PtrToIntInst)
94           macro(SExtInst)
95           macro(SIToFPInst)
96           macro(TruncInst)
97           macro(UIToFPInst)
98           macro(ZExtInst)
99         macro(ExtractValueInst)
100         macro(LoadInst)
101         macro(VAArgInst)
102 */
103 module llvm_hiwrap.value.value;
104 
105 import llvm_hiwrap.types;
106 
107 import llvm_hiwrap.type.type;
108 
109 struct Value {
110     LxValue value;
111     alias value this;
112 
113     /** Convert to a basic block.
114      *
115      * The type of a basic block is label.
116      *
117      * TODO are all basic block labels or are basic blocks a subset?
118      */
119     auto asBasicBlock() {
120         assert(type.kind == LxTypeKind.Label);
121         import llvm : LLVMValueAsBasicBlock;
122         import llvm_hiwrap.value.basic_block;
123 
124         auto raw = LLVMValueAsBasicBlock(this);
125         auto v = LxBasicBlock(raw);
126         return BasicBlock(v);
127     }
128 
129     auto asFunction() {
130         import llvm_hiwrap.value.function_;
131 
132         assert(type.kind == LxTypeKind.Function);
133         return FunctionValue(this.LxUserValue.LxFunctionValue);
134     }
135 
136     auto asUser() {
137         import llvm_hiwrap.value.user;
138 
139         return value.LxUserValue.UserValue;
140     }
141 
142     /// Uses the pointer as a unique identifier.
143     size_t id() {
144         return cast(size_t) value;
145     }
146 
147     /// Determine whether an LLVMValueRef is itself a basic block.
148     bool isBasicBlock() {
149         import llvm : LLVMValueIsBasicBlock;
150 
151         return LLVMValueIsBasicBlock(this) != 0;
152     }
153 
154     /// Determine whether the specified value instance is constant.
155     bool isConstant() {
156         import llvm : LLVMIsConstant;
157 
158         return LLVMIsConstant(rawPtr) != 0;
159     }
160 
161     LxValue isMDNode() {
162         import llvm : LLVMIsAMDNode;
163 
164         return LxValue(LLVMIsAMDNode(rawPtr));
165     }
166 
167     /// Determine whether a value instance is undefined.
168     bool isUndefined() {
169         import llvm : LLVMIsUndef;
170 
171         return LLVMIsUndef(rawPtr) != 0;
172     }
173 
174     /** Obtain the enumerated type of a Value instance.
175      *
176      * @see llvm::Value::getValueID()
177      */
178     LxValueKind kind() {
179         import llvm : LLVMGetValueKind;
180 
181         auto k = LLVMGetValueKind(this);
182         if (k >= LxValueKind.min && k <= LxValueKind.max)
183             return cast(LxValueKind) k;
184         return LxValueKind.Unknown;
185     }
186 
187     @property const(char)[] name() {
188         import std.string : fromStringz;
189         import llvm : LLVMGetValueName;
190 
191         auto s = LLVMGetValueName(rawPtr);
192         return s.fromStringz;
193     }
194 
195     @property void name(string s) {
196         import std.string : toStringz;
197         import llvm : LLVMSetValueName;
198 
199         auto tmp = s.toStringz;
200         LLVMSetValueName(rawPtr, tmp);
201     }
202 
203     /// Obtain the string name of a value.
204     LxMessage spelling() {
205         import llvm : LLVMPrintValueToString;
206 
207         auto s = LLVMPrintValueToString(rawPtr);
208         return LxMessage(s);
209     }
210 
211     /// Returns: Inspect all uses of the value.
212     auto uses() {
213         import llvm_hiwrap.value.use;
214 
215         return UseValueRange(this);
216     }
217 
218     /// Obtain the type of a value.
219     Type type() {
220         import llvm : LLVMTypeOf;
221 
222         return LLVMTypeOf(value).LxType.Type;
223     }
224 }
225 
226 struct UseValueRange {
227     import std.typecons : Nullable;
228     import llvm;
229     import llvm_hiwrap.value.use;
230 
231     private Nullable!UseValue cur;
232 
233     this(Value v) {
234         if (auto raw = LLVMGetFirstUse(v))
235             cur = LLVMGetFirstUse(v).LxUseValue.UseValue;
236     }
237 
238     UseValue front() @safe pure nothrow {
239         assert(!empty, "Can't get front of an empty range");
240         return cur.get;
241     }
242 
243     void popFront() nothrow {
244         assert(!empty, "Can't pop front of an empty range");
245         if (auto raw = LLVMGetNextUse(cur.get)) {
246             cur = raw.LxUseValue.UseValue;
247         } else {
248             cur.nullify;
249         }
250     }
251 
252     bool empty() @safe pure nothrow const @nogc {
253         return cur.isNull;
254     }
255 }