1
+ const std = @import ("std" );
1
2
const builtin = @import ("builtin" );
2
3
const Scope = @import ("scope.zig" ).Scope ;
3
4
const Module = @import ("module.zig" ).Module ;
4
5
const Value = @import ("value.zig" ).Value ;
6
+ const llvm = @import ("llvm.zig" );
7
+ const CompilationUnit = @import ("codegen.zig" ).CompilationUnit ;
5
8
6
9
pub const Type = struct {
7
10
base : Value ,
@@ -39,6 +42,36 @@ pub const Type = struct {
39
42
}
40
43
}
41
44
45
+ pub fn getLlvmType (base : * Type , cunit : * CompilationUnit ) (error {OutOfMemory }! llvm .TypeRef ) {
46
+ switch (base .id ) {
47
+ Id .Struct = > return @fieldParentPtr (Struct , "base" , base ).getLlvmType (cunit ),
48
+ Id .Fn = > return @fieldParentPtr (Fn , "base" , base ).getLlvmType (cunit ),
49
+ Id .Type = > unreachable ,
50
+ Id .Void = > unreachable ,
51
+ Id .Bool = > return @fieldParentPtr (Bool , "base" , base ).getLlvmType (cunit ),
52
+ Id .NoReturn = > unreachable ,
53
+ Id .Int = > return @fieldParentPtr (Int , "base" , base ).getLlvmType (cunit ),
54
+ Id .Float = > return @fieldParentPtr (Float , "base" , base ).getLlvmType (cunit ),
55
+ Id .Pointer = > return @fieldParentPtr (Pointer , "base" , base ).getLlvmType (cunit ),
56
+ Id .Array = > return @fieldParentPtr (Array , "base" , base ).getLlvmType (cunit ),
57
+ Id .ComptimeFloat = > unreachable ,
58
+ Id .ComptimeInt = > unreachable ,
59
+ Id .Undefined = > unreachable ,
60
+ Id .Null = > unreachable ,
61
+ Id .Optional = > return @fieldParentPtr (Optional , "base" , base ).getLlvmType (cunit ),
62
+ Id .ErrorUnion = > return @fieldParentPtr (ErrorUnion , "base" , base ).getLlvmType (cunit ),
63
+ Id .ErrorSet = > return @fieldParentPtr (ErrorSet , "base" , base ).getLlvmType (cunit ),
64
+ Id .Enum = > return @fieldParentPtr (Enum , "base" , base ).getLlvmType (cunit ),
65
+ Id .Union = > return @fieldParentPtr (Union , "base" , base ).getLlvmType (cunit ),
66
+ Id .Namespace = > unreachable ,
67
+ Id .Block = > unreachable ,
68
+ Id .BoundFn = > return @fieldParentPtr (BoundFn , "base" , base ).getLlvmType (cunit ),
69
+ Id .ArgTuple = > unreachable ,
70
+ Id .Opaque = > return @fieldParentPtr (Opaque , "base" , base ).getLlvmType (cunit ),
71
+ Id .Promise = > return @fieldParentPtr (Promise , "base" , base ).getLlvmType (cunit ),
72
+ }
73
+ }
74
+
42
75
pub fn dump (base : * const Type ) void {
43
76
std .debug .warn ("{}" , @tagName (base .id ));
44
77
}
@@ -54,27 +87,72 @@ pub const Type = struct {
54
87
pub fn destroy (self : * Struct , module : * Module ) void {
55
88
module .a ().destroy (self );
56
89
}
90
+
91
+ pub fn getLlvmType (self : * Struct , cunit : * CompilationUnit ) llvm.TypeRef {
92
+ @panic ("TODO" );
93
+ }
57
94
};
58
95
59
96
pub const Fn = struct {
60
97
base : Type ,
98
+ return_type : * Type ,
99
+ params : []Param ,
100
+ is_var_args : bool ,
61
101
62
- pub fn create (module : * Module ) ! * Fn {
63
- return module .a ().create (Fn {
102
+ pub const Param = struct {
103
+ is_noalias : bool ,
104
+ typeof : * Type ,
105
+ };
106
+
107
+ pub fn create (module : * Module , return_type : * Type , params : []Param , is_var_args : bool ) ! * Fn {
108
+ const result = try module .a ().create (Fn {
64
109
.base = Type {
65
110
.base = Value {
66
111
.id = Value .Id .Type ,
67
112
.typeof = & MetaType .get (module ).base ,
68
- .ref_count = 1 ,
113
+ .ref_count = std . atomic . Int ( usize ). init ( 1 ) ,
69
114
},
70
115
.id = builtin .TypeId .Fn ,
71
116
},
117
+ .return_type = return_type ,
118
+ .params = params ,
119
+ .is_var_args = is_var_args ,
72
120
});
121
+ errdefer module .a ().destroy (result );
122
+
123
+ result .return_type .base .ref ();
124
+ for (result .params ) | param | {
125
+ param .typeof .base .ref ();
126
+ }
127
+ return result ;
73
128
}
74
129
75
130
pub fn destroy (self : * Fn , module : * Module ) void {
131
+ self .return_type .base .deref (module );
132
+ for (self .params ) | param | {
133
+ param .typeof .base .deref (module );
134
+ }
76
135
module .a ().destroy (self );
77
136
}
137
+
138
+ pub fn getLlvmType (self : * Fn , cunit : * CompilationUnit ) ! llvm.TypeRef {
139
+ const llvm_return_type = switch (self .return_type .id ) {
140
+ Type .Id .Void = > llvm .VoidTypeInContext (cunit .context ) orelse return error .OutOfMemory ,
141
+ else = > try self .return_type .getLlvmType (cunit ),
142
+ };
143
+ const llvm_param_types = try cunit .a ().alloc (llvm .TypeRef , self .params .len );
144
+ defer cunit .a ().free (llvm_param_types );
145
+ for (llvm_param_types ) | * llvm_param_type , i | {
146
+ llvm_param_type .* = try self .params [i ].typeof .getLlvmType (cunit );
147
+ }
148
+
149
+ return llvm .FunctionType (
150
+ llvm_return_type ,
151
+ llvm_param_types .ptr ,
152
+ @intCast (c_uint , llvm_param_types .len ),
153
+ @boolToInt (self .is_var_args ),
154
+ ) orelse error .OutOfMemory ;
155
+ }
78
156
};
79
157
80
158
pub const MetaType = struct {
@@ -118,6 +196,10 @@ pub const Type = struct {
118
196
pub fn destroy (self : * Bool , module : * Module ) void {
119
197
module .a ().destroy (self );
120
198
}
199
+
200
+ pub fn getLlvmType (self : * Bool , cunit : * CompilationUnit ) llvm.TypeRef {
201
+ @panic ("TODO" );
202
+ }
121
203
};
122
204
123
205
pub const NoReturn = struct {
@@ -140,6 +222,10 @@ pub const Type = struct {
140
222
pub fn destroy (self : * Int , module : * Module ) void {
141
223
module .a ().destroy (self );
142
224
}
225
+
226
+ pub fn getLlvmType (self : * Int , cunit : * CompilationUnit ) llvm.TypeRef {
227
+ @panic ("TODO" );
228
+ }
143
229
};
144
230
145
231
pub const Float = struct {
@@ -148,6 +234,10 @@ pub const Type = struct {
148
234
pub fn destroy (self : * Float , module : * Module ) void {
149
235
module .a ().destroy (self );
150
236
}
237
+
238
+ pub fn getLlvmType (self : * Float , cunit : * CompilationUnit ) llvm.TypeRef {
239
+ @panic ("TODO" );
240
+ }
151
241
};
152
242
pub const Pointer = struct {
153
243
base : Type ,
@@ -180,77 +270,116 @@ pub const Type = struct {
180
270
) * Pointer {
181
271
@panic ("TODO get pointer" );
182
272
}
273
+
274
+ pub fn getLlvmType (self : * Pointer , cunit : * CompilationUnit ) llvm.TypeRef {
275
+ @panic ("TODO" );
276
+ }
183
277
};
278
+
184
279
pub const Array = struct {
185
280
base : Type ,
186
281
187
282
pub fn destroy (self : * Array , module : * Module ) void {
188
283
module .a ().destroy (self );
189
284
}
285
+
286
+ pub fn getLlvmType (self : * Array , cunit : * CompilationUnit ) llvm.TypeRef {
287
+ @panic ("TODO" );
288
+ }
190
289
};
290
+
191
291
pub const ComptimeFloat = struct {
192
292
base : Type ,
193
293
194
294
pub fn destroy (self : * ComptimeFloat , module : * Module ) void {
195
295
module .a ().destroy (self );
196
296
}
197
297
};
298
+
198
299
pub const ComptimeInt = struct {
199
300
base : Type ,
200
301
201
302
pub fn destroy (self : * ComptimeInt , module : * Module ) void {
202
303
module .a ().destroy (self );
203
304
}
204
305
};
306
+
205
307
pub const Undefined = struct {
206
308
base : Type ,
207
309
208
310
pub fn destroy (self : * Undefined , module : * Module ) void {
209
311
module .a ().destroy (self );
210
312
}
211
313
};
314
+
212
315
pub const Null = struct {
213
316
base : Type ,
214
317
215
318
pub fn destroy (self : * Null , module : * Module ) void {
216
319
module .a ().destroy (self );
217
320
}
218
321
};
322
+
219
323
pub const Optional = struct {
220
324
base : Type ,
221
325
222
326
pub fn destroy (self : * Optional , module : * Module ) void {
223
327
module .a ().destroy (self );
224
328
}
329
+
330
+ pub fn getLlvmType (self : * Optional , cunit : * CompilationUnit ) llvm.TypeRef {
331
+ @panic ("TODO" );
332
+ }
225
333
};
334
+
226
335
pub const ErrorUnion = struct {
227
336
base : Type ,
228
337
229
338
pub fn destroy (self : * ErrorUnion , module : * Module ) void {
230
339
module .a ().destroy (self );
231
340
}
341
+
342
+ pub fn getLlvmType (self : * ErrorUnion , cunit : * CompilationUnit ) llvm.TypeRef {
343
+ @panic ("TODO" );
344
+ }
232
345
};
346
+
233
347
pub const ErrorSet = struct {
234
348
base : Type ,
235
349
236
350
pub fn destroy (self : * ErrorSet , module : * Module ) void {
237
351
module .a ().destroy (self );
238
352
}
353
+
354
+ pub fn getLlvmType (self : * ErrorSet , cunit : * CompilationUnit ) llvm.TypeRef {
355
+ @panic ("TODO" );
356
+ }
239
357
};
358
+
240
359
pub const Enum = struct {
241
360
base : Type ,
242
361
243
362
pub fn destroy (self : * Enum , module : * Module ) void {
244
363
module .a ().destroy (self );
245
364
}
365
+
366
+ pub fn getLlvmType (self : * Enum , cunit : * CompilationUnit ) llvm.TypeRef {
367
+ @panic ("TODO" );
368
+ }
246
369
};
370
+
247
371
pub const Union = struct {
248
372
base : Type ,
249
373
250
374
pub fn destroy (self : * Union , module : * Module ) void {
251
375
module .a ().destroy (self );
252
376
}
377
+
378
+ pub fn getLlvmType (self : * Union , cunit : * CompilationUnit ) llvm.TypeRef {
379
+ @panic ("TODO" );
380
+ }
253
381
};
382
+
254
383
pub const Namespace = struct {
255
384
base : Type ,
256
385
@@ -273,6 +402,10 @@ pub const Type = struct {
273
402
pub fn destroy (self : * BoundFn , module : * Module ) void {
274
403
module .a ().destroy (self );
275
404
}
405
+
406
+ pub fn getLlvmType (self : * BoundFn , cunit : * CompilationUnit ) llvm.TypeRef {
407
+ @panic ("TODO" );
408
+ }
276
409
};
277
410
278
411
pub const ArgTuple = struct {
@@ -289,6 +422,10 @@ pub const Type = struct {
289
422
pub fn destroy (self : * Opaque , module : * Module ) void {
290
423
module .a ().destroy (self );
291
424
}
425
+
426
+ pub fn getLlvmType (self : * Opaque , cunit : * CompilationUnit ) llvm.TypeRef {
427
+ @panic ("TODO" );
428
+ }
292
429
};
293
430
294
431
pub const Promise = struct {
@@ -297,5 +434,9 @@ pub const Type = struct {
297
434
pub fn destroy (self : * Promise , module : * Module ) void {
298
435
module .a ().destroy (self );
299
436
}
437
+
438
+ pub fn getLlvmType (self : * Promise , cunit : * CompilationUnit ) llvm.TypeRef {
439
+ @panic ("TODO" );
440
+ }
300
441
};
301
442
};
0 commit comments