@@ -296,19 +296,20 @@ end
296
296
297
297
# ############################## Struct ###############################
298
298
299
- function _emit_getproperty_ptr ! (body, root_cursor, cursor, options)
299
+ function _emit_pointer_access ! (body, root_cursor, cursor, options)
300
300
field_cursors = fields (getCursorType (cursor))
301
301
field_cursors = isempty (field_cursors) ? children (cursor) : field_cursors
302
302
for field_cursor in field_cursors
303
303
n = name (field_cursor)
304
304
if isempty (n)
305
- _emit_getproperty_ptr ! (body, root_cursor, field_cursor, options)
305
+ _emit_pointer_access ! (body, root_cursor, field_cursor, options)
306
306
continue
307
307
end
308
308
fsym = make_symbol_safe (n)
309
309
fty = getCursorType (field_cursor)
310
310
ty = translate (tojulia (fty), options)
311
311
offset = getOffsetOf (getCursorType (root_cursor), n)
312
+
312
313
if isBitField (field_cursor)
313
314
w = getFieldDeclBitWidth (field_cursor)
314
315
@assert w <= 32 # Bit fields should not be larger than int(32 bits)
@@ -322,12 +323,63 @@ function _emit_getproperty_ptr!(body, root_cursor, cursor, options)
322
323
end
323
324
end
324
325
325
- # Base.getproperty(x::Ptr, f::Symbol) -> Ptr
326
+ # getptr(x::Ptr, f::Symbol) -> Ptr
327
+ function emit_getptr! (dag, node, options)
328
+ sym = make_symbol_safe (node. id)
329
+ signature = Expr (:call , :getptr , :(x:: Ptr{$sym} ), :(f:: Symbol ))
330
+ body = Expr (:block )
331
+ _emit_pointer_access! (body, node. cursor, node. cursor, options)
332
+
333
+ push! (body. args, :(error ($ (" Unrecognized field of type `$sym `" ) * " : $f " )))
334
+ push! (node. exprs, Expr (:function , signature, body))
335
+ return dag
336
+ end
337
+
338
+ function emit_deref_getproperty! (body, root_cursor, cursor, options)
339
+ field_cursors = fields (getCursorType (cursor))
340
+ field_cursors = isempty (field_cursors) ? children (cursor) : field_cursors
341
+ for field_cursor in field_cursors
342
+ n = name (field_cursor)
343
+ if isempty (n)
344
+ emit_deref_getproperty! (body, root_cursor, field_cursor, options)
345
+ continue
346
+ end
347
+ fsym = make_symbol_safe (n)
348
+ fty = getCursorType (field_cursor)
349
+ canonical_type = getCanonicalType (fty)
350
+
351
+ return_expr = :(getptr (x, f))
352
+
353
+ # Automatically dereference all field types except for nested structs
354
+ # and arrays.
355
+ if ! (canonical_type isa Union{CLRecord, CLConstantArray}) && ! isBitField (field_cursor)
356
+ return_expr = :(unsafe_load ($ return_expr))
357
+ elseif isBitField (field_cursor)
358
+ return_expr = :(getbitfieldproperty (x, $ return_expr))
359
+ end
360
+
361
+ ex = :(f === $ (QuoteNode (fsym)) && return $ return_expr)
362
+ push! (body. args, ex)
363
+ end
364
+ end
365
+
366
+ # Base.getproperty(x::Ptr, f::Symbol)
326
367
function emit_getproperty_ptr! (dag, node, options)
368
+ auto_deref = get (options, " auto_field_dereference" , false )
327
369
sym = make_symbol_safe (node. id)
370
+
371
+ # If automatically dereferencing, we first need to emit getptr!()
372
+ if auto_deref
373
+ emit_getptr! (dag, node, options)
374
+ end
375
+
328
376
signature = Expr (:call , :(Base. getproperty), :(x:: Ptr{$sym} ), :(f:: Symbol ))
329
377
body = Expr (:block )
330
- _emit_getproperty_ptr! (body, node. cursor, node. cursor, options)
378
+ if auto_deref
379
+ emit_deref_getproperty! (body, node. cursor, node. cursor, options)
380
+ else
381
+ _emit_pointer_access! (body, node. cursor, node. cursor, options)
382
+ end
331
383
push! (body. args, :(return getfield (x, f)))
332
384
getproperty_expr = Expr (:function , signature, body)
333
385
push! (node. exprs, getproperty_expr)
@@ -370,10 +422,14 @@ end
370
422
function emit_setproperty! (dag, node, options)
371
423
sym = make_symbol_safe (node. id)
372
424
signature = Expr (:call , :(Base. setproperty!), :(x:: Ptr{$sym} ), :(f:: Symbol ), :v )
373
- store_expr = :(unsafe_store! (getproperty (x, f), v))
425
+
426
+ auto_deref = get (options, " auto_field_dereference" , false )
427
+ pointer_getter = auto_deref ? :getptr : :getproperty
428
+ store_expr = :(unsafe_store! ($ pointer_getter (x, f), v))
429
+
374
430
if is_bitfield_type (node. type)
375
431
body = quote
376
- fptr = getproperty (x, f)
432
+ fptr = $ pointer_getter (x, f)
377
433
if fptr isa Ptr
378
434
$ store_expr
379
435
else
@@ -398,7 +454,7 @@ function get_names_types(root_cursor, cursor, options)
398
454
for field_cursor in field_cursors
399
455
n = name (field_cursor)
400
456
if isempty (n)
401
- _emit_getproperty_ptr ! (root_cursor, field_cursor, options)
457
+ _emit_pointer_access ! (root_cursor, field_cursor, options)
402
458
continue
403
459
end
404
460
fsym = make_symbol_safe (n)
0 commit comments