1 module contract.functions; 2 3 4 import contract; 5 import std.array: array; 6 7 8 // See #43 9 @Tags("contract") 10 @("functionproto.deref") 11 @safe unittest { 12 13 const tu = parse( 14 C( 15 q{ 16 int binOp(int (f)(int x, int y), int a, int b); 17 } 18 ) 19 ); 20 21 tu.children.length.should == 1; 22 23 const binOp = tu.child(0); 24 binOp.shouldMatch(Cursor.Kind.FunctionDecl, "binOp"); 25 26 binOp.type.paramTypes.array.length.should == 3; 27 const f = binOp.type.paramTypes.array[0]; 28 // need canonical for old versions of libclang 29 f.canonical.shouldMatch(Type.Kind.FunctionProto, "int (int, int)"); 30 writelnUt(f.pointee); 31 // presumably, not a pointer 32 f.pointee.isInvalid.should == true; 33 } 34 35 36 @Tags("contract") 37 @("functionproto.star") 38 @safe unittest { 39 40 const tu = parse( 41 C( 42 q{ 43 int binOp(int (*f)(int x, int y), int a, int b); 44 } 45 ) 46 ); 47 48 tu.children.length.should == 1; 49 50 const binOp = tu.child(0); 51 binOp.shouldMatch(Cursor.Kind.FunctionDecl, "binOp"); 52 53 binOp.type.paramTypes.array.length.should == 3; 54 const f = binOp.type.paramTypes.array[0]; 55 // Even though the declaration here is effectively the same as the 56 // one in the test above, it shows up as a pointer 57 f.shouldMatch(Type.Kind.Pointer, "int (*)(int, int)"); 58 writelnUt(f.pointee); 59 // it's a pointer 60 f.pointee.isInvalid.should == false; 61 62 f.pointee.canonical.shouldMatch(Type.Kind.FunctionProto, "int (int, int)"); 63 }