@@ -280,6 +280,170 @@ const toEnumType = (
280280 return result ;
281281} ;
282282
283+ const UNSIGNED_LONG : PlainType = {
284+ kind : "plain" ,
285+ name : "unsignedLong" ,
286+ type : "u64" ,
287+ comment : null ,
288+ } ;
289+ const INT : PlainType = {
290+ kind : "plain" ,
291+ name : "int" ,
292+ type : "i32" ,
293+ comment : null ,
294+ } ;
295+ const VOID : PlainType = {
296+ kind : "plain" ,
297+ name : "void" ,
298+ type : "void" ,
299+ comment : null ,
300+ } ;
301+ const VOID_POINTER : PointerType = {
302+ kind : "pointer" ,
303+ name : "void*" ,
304+ pointee : VOID ,
305+ comment : null ,
306+ useBuffer : false ,
307+ } ;
308+
309+ const BLOCK_DESCRIPTOR : StructType = {
310+ fields : [
311+ {
312+ name : "reserved" ,
313+ type : UNSIGNED_LONG ,
314+ offset : 0 ,
315+ size : 8 ,
316+ comment : null ,
317+ } ,
318+ {
319+ name : "size" ,
320+ type : UNSIGNED_LONG ,
321+ offset : 8 ,
322+ size : 8 ,
323+ comment : null ,
324+ } ,
325+ {
326+ name : "copy" ,
327+ type : {
328+ kind : "function" ,
329+ comment : null ,
330+ name : "void (*copy)(void *dst, void *src)" ,
331+ parameters : [
332+ {
333+ comment : null ,
334+ name : "dst" ,
335+ type : VOID_POINTER ,
336+ } ,
337+ {
338+ comment : null ,
339+ name : "src" ,
340+ type : VOID_POINTER ,
341+ } ,
342+ ] ,
343+ reprName : "copyT" ,
344+ result : VOID ,
345+ } ,
346+ offset : 16 ,
347+ size : 8 ,
348+ comment : null ,
349+ } ,
350+ {
351+ name : "dispose" ,
352+ type : {
353+ kind : "function" ,
354+ comment : null ,
355+ name : "void (*dispose)(void *)" ,
356+ parameters : [
357+ {
358+ comment : null ,
359+ name : "this" ,
360+ type : VOID_POINTER ,
361+ } ,
362+ ] ,
363+ reprName : "disposeT" ,
364+ result : VOID ,
365+ } ,
366+ offset : 24 ,
367+ size : 8 ,
368+ comment : null ,
369+ } ,
370+ ] ,
371+ kind : "struct" ,
372+ name : "Block_descriptor" ,
373+ size : 32 ,
374+ reprName : `Block_descriptorT` ,
375+ comment : null ,
376+ } ;
377+
378+ /**
379+ * See https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/BlocksRuntime/Block_private.h#L62-L77
380+ */
381+ const BLOCK_LAYOUT : StructType = {
382+ fields : [
383+ {
384+ name : "isa" ,
385+ type : VOID_POINTER ,
386+ offset : 0 ,
387+ size : 8 ,
388+ comment : null ,
389+ } ,
390+ {
391+ name : "flags" ,
392+ type : INT ,
393+ offset : 8 ,
394+ size : 4 ,
395+ comment : null ,
396+ } ,
397+ {
398+ name : "reserved" ,
399+ type : INT ,
400+ offset : 12 ,
401+ size : 4 ,
402+ comment : null ,
403+ } ,
404+ {
405+ name : "invoke" ,
406+ type : {
407+ kind : "function" ,
408+ comment : null ,
409+ name : "void (*invoke)(void *, ...)" ,
410+ parameters : [
411+ {
412+ comment : null ,
413+ name : "this" ,
414+ type : VOID_POINTER ,
415+ } ,
416+ ] ,
417+ reprName : "invokeT" ,
418+ result : VOID ,
419+ } ,
420+ offset : 16 ,
421+ size : 8 ,
422+ comment : null ,
423+ } ,
424+ {
425+ name : "descriptor" ,
426+ type : {
427+ kind : "pointer" ,
428+ name : "struct Block_descriptor *" ,
429+ pointee : BLOCK_DESCRIPTOR ,
430+ comment : null ,
431+ useBuffer : false ,
432+ } ,
433+ offset : 24 ,
434+ size : 8 ,
435+ comment : null ,
436+ } ,
437+ ] ,
438+ kind : "struct" ,
439+ name : "Block_layout" ,
440+ size : 32 ,
441+ reprName : `Block_layoutT` ,
442+ comment : `/**
443+ * See https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/BlocksRuntime/Block_private.h#L62-L77
444+ */` ,
445+ } ;
446+
283447export const toAnyType = (
284448 typeMemory : Map < string , AnyType > ,
285449 type : CXType ,
@@ -513,6 +677,28 @@ export const toAnyType = (
513677 const result = toEnumType ( typeMemory , name , typeDeclaration ) ;
514678 typeMemory . set ( name , result ) ;
515679 return result ;
680+ } else if (
681+ typekind === CXTypeKind . CXType_BlockPointer
682+ ) {
683+ if ( ! typeMemory . has ( "Block_layout" ) ) {
684+ if ( ! typeMemory . has ( "unsignedLong" ) ) {
685+ typeMemory . set ( "unsignedLong" , UNSIGNED_LONG ) ;
686+ }
687+ if ( ! typeMemory . has ( "int" ) ) {
688+ typeMemory . set ( "int" , INT ) ;
689+ }
690+ typeMemory . set ( "Block_descriptor" , BLOCK_DESCRIPTOR ) ;
691+ typeMemory . set ( "Block_layout" , BLOCK_LAYOUT ) ;
692+ }
693+ const result : PointerType = {
694+ kind : "pointer" ,
695+ name : type . getSpelling ( ) ,
696+ pointee : BLOCK_LAYOUT ,
697+ comment : null ,
698+ // BlockPointers should always use buffers.
699+ useBuffer : true ,
700+ } ;
701+ return result ;
516702 } else if (
517703 typekind !== CXTypeKind . CXType_Void &&
518704 typekind !== CXTypeKind . CXType_Bool &&
0 commit comments