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.user;
7 
8 import llvm_hiwrap.types;
9 
10 /** Function in this group pertain to LLVMValueRef instances that descent from
11  * llvm::User.
12  *
13  * This includes constants, instructions, and operators.
14  *
15  * TODO add a spelling function.
16  */
17 struct UserValue {
18     import llvm;
19     import llvm_hiwrap.value.value;
20     import llvm_hiwrap.value.use;
21 
22     LxUserValue value;
23     alias value this;
24 
25     auto asValue() {
26         return Value(this);
27     }
28 
29     /// Returns: a range over all operands.
30     OperandsRange operands() {
31         return OperandsRange(this);
32     }
33 
34     /**
35      * Obtain an operand at a specific index in a llvm::User value.
36      *
37      * @see llvm::User::getOperand()
38      */
39     Operand operandAt(size_t index) {
40         assert(index < countOperands);
41         return LLVMGetOperand(this, cast(uint) index).LxValue.LxOperandValue.Operand;
42     }
43 
44     /** Obtain the use of an operand at a specific index in a llvm::User value.
45      *
46      * @see llvm::User::getOperandUse()
47      */
48     UseValue operandUseAt(size_t index) {
49         return LLVMGetOperandUse(this, cast(uint) index).LxUseValue.UseValue;
50     }
51 
52     /** Set an operand at a specific index in a llvm::User value.
53      *
54      * @see llvm::User::setOperand()
55      */
56     void setOperandAt(size_t index, Value v) {
57         LLVMSetOperand(this, cast(uint) index, v);
58     }
59 
60     /** Obtain the number of operands in a llvm::User value.
61      *
62      * @see llvm::User::getNumOperands()
63      */
64     auto countOperands() {
65         return LLVMGetNumOperands(this);
66     }
67 }
68 
69 struct Operand {
70     import llvm;
71     import llvm_hiwrap.value.value;
72     import llvm_hiwrap.value.use;
73 
74     LxOperandValue value;
75     alias value this;
76 
77     auto asValue() {
78         return Value(this);
79     }
80 }
81 
82 struct OperandsRange {
83     import llvm;
84     import llvm_hiwrap.value.use;
85 
86     private immutable size_t length_;
87     private UserValue value;
88 
89     this(UserValue v) {
90         length_ = v.countOperands;
91         value = v;
92     }
93 
94     size_t length() {
95         return length_;
96     }
97 
98     Operand opIndex(size_t index) {
99         return value.operandAt(index);
100     }
101 
102     import llvm_hiwrap.util : IndexedRangeX;
103 
104     mixin IndexedRangeX!Operand;
105 }