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 This file contains the simple type representation of llvm values and types.
7 It is meant to, when appropriate, reconstruct the llvm hierarchy in D.
8 
9 The complex functions and other manipulation that are possible are found in the
10 .type and .value submodules.
11 
12 The _simple_ types reflect the hierarchy. They are prefixed with Lx.
13 The comlex types add operations. This allows compositions of operations.
14 */
15 module llvm_hiwrap.types;
16 
17 import llvm;
18 
19 /// LLVM-4.0
20 /// See: llvm-c/Core.h
21 enum LxValueKind {
22     Argument,
23     BasicBlock,
24     MemoryUse,
25     MemoryDef,
26     MemoryPhi,
27 
28     Function,
29     GlobalAlias,
30     GlobalIFunc,
31     GlobalVariable,
32     BlockAddress,
33     ConstantExpr,
34     ConstantArray,
35     ConstantStruct,
36     ConstantVector,
37 
38     UndefValue,
39     ConstantAggregateZero,
40     ConstantDataArray,
41     ConstantDataVector,
42     ConstantInt,
43     ConstantFP,
44     ConstantPointerNull,
45     ConstantTokenNone,
46 
47     MetadataAsValue,
48     InlineAsm,
49 
50     Instruction,
51 
52     Unknown
53 }
54 
55 /// LLVM-4.0
56 /// See: llvm-c/Analysis.h
57 enum LxVerifierFailureAction {
58     /// verifier will print to stderr and abort()
59     AbortProcessAction,
60     /// verifier will print to stderr and return 1
61     PrintMessageAction,
62     /// verifier will just return 1
63     ReturnStatusAction
64 }
65 
66 /// LLVM-4.0
67 /// See: llvm-c/Core.h
68 enum LxDiagnosticSeverity {
69     Error,
70     Warning,
71     Remark,
72     Note
73 }
74 
75 /// LLVM-4.0
76 /// See: llvm-c/Core.h
77 enum LxTypeKind {
78     Void, /// type with no size
79     Half, /// 16 bit floating point type
80     Float, /// 32 bit floating point type
81     Double, /// 64 bit floating point type
82     X86_FP80, /// 80 bit floating point type (X87)
83     FP128, /// 128 bit floating point type (112-bit mantissa)
84     PPC_FP128, /// 128 bit floating point type (two 64-bits)
85     Label, /// Labels
86     Integer, /// Arbitrary bit width integers
87     Function, /// Functions
88     Struct, /// Structures
89     Array, /// Arrays
90     Pointer, /// Pointers
91     Vector, /// SIMD 'packed' format, or other vector type
92     Metadata, /// Metadata
93     X86_MMX, /// X86 MMX
94     Token, /// Tokens
95 
96     /* Added by llvm_hiwrap.
97      * Decouples the users of LxTypeKind from LLVMTypeKind.
98      *
99      * By having an unknown type the enum in the official LLVM lib can be
100      * extended without breaking the use of this enum.
101      * Lessons learned from libclang is that the enums will be extended.
102      */
103     Unknown,
104 }
105 
106 /// LLVM-4.0
107 /// See: llvm-c/Core.h
108 enum LxOpcode {
109     /* Terminator Instructions */
110     Ret = 1,
111     Br = 2,
112     Switch = 3,
113     IndirectBr = 4,
114     Invoke = 5,
115     /* removed 6 due to API changes */
116     Unreachable = 7,
117 
118     /* Standard Binary Operators */
119     Add = 8,
120     FAdd = 9,
121     Sub = 10,
122     FSub = 11,
123     Mul = 12,
124     FMul = 13,
125     UDiv = 14,
126     SDiv = 15,
127     FDiv = 16,
128     URem = 17,
129     SRem = 18,
130     FRem = 19,
131 
132     /* Logical Operators */
133     Shl = 20,
134     LShr = 21,
135     AShr = 22,
136     And = 23,
137     Or = 24,
138     Xor = 25,
139 
140     /* Memory Operators */
141     Alloca = 26,
142     Load = 27,
143     Store = 28,
144     GetElementPtr = 29,
145 
146     /* Cast Operators */
147     Trunc = 30,
148     ZExt = 31,
149     SExt = 32,
150     FPToUI = 33,
151     FPToSI = 34,
152     UIToFP = 35,
153     SIToFP = 36,
154     FPTrunc = 37,
155     FPExt = 38,
156     PtrToInt = 39,
157     IntToPtr = 40,
158     BitCast = 41,
159     AddrSpaceCast = 60,
160 
161     /* Other Operators */
162     ICmp = 42,
163     FCmp = 43,
164     PHI = 44,
165     Call = 45,
166     Select = 46,
167     UserOp1 = 47,
168     UserOp2 = 48,
169     VAArg = 49,
170     ExtractElement = 50,
171     InsertElement = 51,
172     ShuffleVector = 52,
173     ExtractValue = 53,
174     InsertValue = 54,
175 
176     /* Atomic operators */
177     Fence = 55,
178     AtomicCmpXchg = 56,
179     AtomicRMW = 57,
180 
181     /* Exception Handling Operators */
182     Resume = 58,
183     LandingPad = 59,
184     CleanupRet = 61,
185     CatchRet = 62,
186     CatchPad = 63,
187     CleanupPad = 64,
188     CatchSwitch = 65,
189 
190     /// Added by llvm_hiwrap.
191     Unknown,
192 }
193 
194 /// LLVM-4.0
195 /// See: llvm-c/Core.h
196 enum LxIntPredicate {
197     EQ = 32, /**< equal */
198     NE, /**< not equal */
199     UGT, /**< unsigned greater than */
200     UGE, /**< unsigned greater or equal */
201     ULT, /**< unsigned less than */
202     ULE, /**< unsigned less or equal */
203     SGT, /**< signed greater than */
204     SGE, /**< signed greater or equal */
205     SLT, /**< signed less than */
206     SLE /**< signed less or equal */
207 }
208 
209 /// LLVM-4.0
210 /// See: llvm-c/Core.h
211 enum LxRealPredicate {
212     PredicateFalse, /**< Always false (always folded) */
213     OEQ, /**< True if ordered and equal */
214     OGT, /**< True if ordered and greater than */
215     OGE, /**< True if ordered and greater than or equal */
216     OLT, /**< True if ordered and less than */
217     OLE, /**< True if ordered and less than or equal */
218     ONE, /**< True if ordered and operands are unequal */
219     ORD, /**< True if ordered (no nans) */
220     UNO, /**< True if unordered: isnan(X) | isnan(Y) */
221     UEQ, /**< True if unordered or equal */
222     UGT, /**< True if unordered or greater than */
223     UGE, /**< True if unordered, greater than, or equal */
224     ULT, /**< True if unordered or less than */
225     ULE, /**< True if unordered, less than, or equal */
226     UNE, /**< True if unordered or not equal */
227     PredicateTrue /**< Always true (always folded) */
228 }
229 
230 /// LLVM-4.0
231 /// See: llvm-c/Core.h
232 enum LxCallConv {
233     C,
234     Fast,
235     Cold,
236     WebKitJS,
237     AnyReg,
238     X86Stdcall,
239     X86Fastcall,
240 
241     /// Added by llvm_hiwrap.
242     Unknown
243 }
244 
245 /// Convert a llvm.LLVMCallConv.
246 LxCallConv toCallConv(LLVMCallConv v) {
247     switch (v) {
248     case 0:
249         return LxCallConv.C;
250     case 8:
251         return LxCallConv.Fast;
252     case 9:
253         return LxCallConv.Cold;
254     case 12:
255         return LxCallConv.WebKitJS;
256     case 13:
257         return LxCallConv.AnyReg;
258     case 64:
259         return LxCallConv.X86Stdcall;
260     case 65:
261         return LxCallConv.X86Fastcall;
262     default:
263         return LxCallConv.Unknown;
264     }
265 }
266 
267 /// ptr to a null terminated array of null terminated C strings.
268 struct LxMessage {
269     char* rawPtr;
270     private char[] str;
271 
272     alias rawPtr this;
273 
274     @disable this(this);
275 
276     ~this() {
277         import llvm : LLVMDisposeMessage;
278 
279         LLVMDisposeMessage(rawPtr);
280     }
281 
282     const(char)[] toChar() {
283         if (str.length == 0) {
284             import std.string : fromStringz;
285 
286             str = rawPtr.fromStringz;
287         }
288         return str;
289     }
290 }
291 
292 struct LxAttribute {
293     import llvm : LLVMAttributeRef;
294 
295     LLVMAttributeRef rawPtr;
296     alias rawPtr this;
297 
298     this(LLVMAttributeRef v) {
299         rawPtr = v;
300     }
301 }
302 
303 struct LxBasicBlock {
304     import llvm : LLVMBasicBlockRef;
305 
306     LLVMBasicBlockRef rawPtr;
307     alias rawPtr this;
308 
309     this(LLVMBasicBlockRef v) {
310         rawPtr = v;
311     }
312 }
313 
314 /// The entry block in a function.
315 struct LxEntryBasicBlock {
316     LxBasicBlock value;
317     alias value this;
318 }
319 
320 /** Represents an individual value in LLVM IR.
321  *
322  * See: llvm-c/Types.h
323  */
324 struct LxValue {
325     import llvm : LLVMValueRef;
326 
327     LLVMValueRef rawPtr;
328     alias rawPtr this;
329 
330     this(LLVMValueRef v) @safe pure nothrow @nogc {
331         rawPtr = v;
332     }
333 }
334 
335 /// Unnamed node
336 struct LxMetadataNodeValue {
337     LxValue value;
338     alias value this;
339 }
340 
341 struct LxMetadataStringValue {
342     LxValue value;
343     alias value this;
344 }
345 
346 struct LxNamedMetadataNodeValue {
347     LxValue value;
348     alias value this;
349 }
350 
351 // TODO should it also carry the name as a string?
352 // I do NOT want these nodes to be heavy so not added yet.
353 struct LxNamedMetadataValue {
354     LxNamedMetadataNodeValue[] operands;
355     alias operands this;
356 }
357 
358 struct LxResolvedNamedMetadataValue {
359     LxMetadataNodeValue operands;
360     alias operands this;
361 }
362 
363 struct LxInstructionValue {
364     LxValue value;
365     alias value this;
366 }
367 
368 struct LxInstructionCallValue {
369     LxInstructionValue value;
370     alias value this;
371 }
372 
373 struct LxInstructionTerminatorValue {
374     LxInstructionValue value;
375     alias value this;
376 }
377 
378 struct LxInstructionAllocaValue {
379     LxInstructionValue value;
380     alias value this;
381 }
382 
383 struct LxInstructionElementPtrValue {
384     LxInstructionValue value;
385     alias value this;
386 }
387 
388 struct LxType {
389     import llvm : LLVMTypeRef;
390 
391     LLVMTypeRef rawPtr;
392     alias rawPtr this;
393 
394     this(LLVMTypeRef v) @safe @nogc nothrow {
395         rawPtr = v;
396     }
397 }
398 
399 struct LxConstantValue {
400     LxUserValue value;
401     alias value this;
402 }
403 
404 struct LxFunctionValue {
405     LxUserValue value;
406     alias value this;
407 }
408 
409 struct LxGlobalValue {
410 }
411 
412 struct LxGlobalAliasValue {
413 }
414 
415 struct LxScalarConstantValue {
416 }
417 
418 struct LxCompositeConstantValue {
419 }
420 
421 struct LxConstantGlobalValue {
422 }
423 
424 /**
425  * Each LLVMUseRef (which corresponds to a llvm::Use instance) holds a
426  * llvm::User and llvm::Value.
427  */
428 struct LxUseValue {
429     LLVMUseRef rawPtr;
430     alias rawPtr this;
431 }
432 
433 struct LxUserValue {
434     LxValue value;
435     alias value this;
436 }
437 
438 struct LxOperandValue {
439     LxValue value;
440     alias value this;
441 }