Skip to content

Commit 8486259

Browse files
authored
Merge branch 'swig:master' into pr-1262
2 parents 64c8e72 + 1d9ace9 commit 8486259

File tree

9 files changed

+75
-36
lines changed

9 files changed

+75
-36
lines changed

CHANGES.current

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
77
Version 4.5.0 (in progress)
88
===========================
99

10+
2025-11-08: wsfulton
11+
Fix handling of typedef to void in class methods/constructor's parameter
12+
lists, such as:
13+
14+
typedef void VOID_TYPE;
15+
struct S {
16+
S(VOID_TYPE);
17+
int f(VOID_TYPE) const;
18+
};
19+
1020
2025-11-06: olly
1121
[Octave, Ruby] #3281 `FALSE` and `TRUE` are no longer treated as
1222
aliases of `false` and `true` when generating documentation comments.

Examples/test-suite/python/voidtest_runme.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
import voidtest
22

33
voidtest.globalfunc()
4+
voidtest.globalfunc_typedef()
45
f = voidtest.Foo()
56
f.memberfunc()
67

78
voidtest.Foo.staticmemberfunc()
89

10+
fv = voidtest.FooVoidTypedef()
11+
fv.memberfunc()
12+
fv.memberfunc_const()
13+
fv.memberfunc_const_voidptr()
14+
15+
voidtest.FooVoidTypedef.staticmemberfunc()
916

1017
def fvoid():
1118
pass

Examples/test-suite/voidtest.i

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
%module voidtest
22

33
%inline %{
4+
void globalfunc(void) {}
45

5-
void globalfunc(void) {
6-
}
6+
typedef void VOID_TP;
7+
typedef VOID_TP VOID_TYPE;
8+
void globalfunc_typedef(VOID_TYPE) {}
79

810
class Foo {
911
public:
@@ -13,6 +15,15 @@ public:
1315
static void staticmemberfunc(void) { }
1416
};
1517

18+
class FooVoidTypedef {
19+
public:
20+
FooVoidTypedef(VOID_TYPE) { }
21+
void memberfunc(VOID_TYPE) { }
22+
void memberfunc_const(VOID_TYPE) const { }
23+
void *memberfunc_const_voidptr(VOID_TYPE) const { return 0; }
24+
virtual ~FooVoidTypedef() { }
25+
static void staticmemberfunc(VOID_TYPE) { }
26+
};
1627

1728
void *vfunc1(void *f) { return f; }
1829
void *vfunc2(Foo *f) { return f; }

Source/CParse/cparse.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ extern "C" {
5757
/* util.c */
5858
extern void Swig_cparse_replace_descriptor(String *s);
5959
extern SwigType *Swig_cparse_smartptr(Node *n);
60-
extern void cparse_normalize_void(Node *);
6160
extern Parm *Swig_cparse_parm(String *s);
6261
extern ParmList *Swig_cparse_parms(String *s, Node *file_line_node);
6362
extern Node *Swig_cparse_new_node(const_String_or_char_ptr tag);

Source/CParse/parser.y

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -407,9 +407,6 @@ static void add_symbols(Node *n) {
407407
String *decl;
408408
String *wrn = 0;
409409

410-
if (inclass && n) {
411-
cparse_normalize_void(n);
412-
}
413410
while (n) {
414411
String *symname = 0;
415412
String *old_prefix = 0;

Source/CParse/util.c

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -92,25 +92,6 @@ SwigType *Swig_cparse_smartptr(Node *n) {
9292
return smart;
9393
}
9494

95-
/* -----------------------------------------------------------------------------
96-
* cparse_normalize_void()
97-
*
98-
* This function is used to replace arguments of the form (void) with empty
99-
* arguments in C++
100-
* ----------------------------------------------------------------------------- */
101-
102-
void cparse_normalize_void(Node *n) {
103-
String *decl = Getattr(n, "decl");
104-
Parm *parms = Getattr(n, "parms");
105-
106-
if (SwigType_isfunction(decl)) {
107-
if ((ParmList_len(parms) == 1) && (SwigType_type(Getattr(parms, "type")) == T_VOID)) {
108-
Replaceall(decl, "f(void).", "f().");
109-
Delattr(n, "parms");
110-
}
111-
}
112-
}
113-
11495
/* -----------------------------------------------------------------------------
11596
* Swig_cparse_new_node()
11697
*

Source/Modules/directors.cxx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ String *Swig_csuperclass_call(String *base, String *method, ParmList *l) {
4646
else
4747
Printv(call, parm_name, NIL);
4848
Delete(pname_created);
49+
Delete(rpt);
4950
}
5051
Printf(call, ")");
5152
return call;

Source/Modules/typepass.cxx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,32 @@ class TypePass:private Dispatcher {
4848
normalize(0) {
4949
}
5050

51+
/* -----------------------------------------------------------------------------
52+
* normalize_void()
53+
*
54+
* This function is used to replace arguments of the form (void) with empty
55+
* arguments in C++ class constructors and methods only (not global functions).
56+
* ----------------------------------------------------------------------------- */
57+
58+
void normalize_void(Node *n) {
59+
String *decl = Getattr(n, "decl");
60+
Parm *parms = Getattr(n, "parms");
61+
62+
if (SwigType_isfunction(decl)) {
63+
if ((ParmList_len(parms) == 1) && (SwigType_type(Getattr(parms, "type")) == T_VOID)) {
64+
String *qualifiers = SwigType_pop_function_qualifiers(decl);
65+
String *func = SwigType_pop_function(decl);
66+
SwigType_add_function(decl, 0);
67+
SwigType_push(decl, qualifiers);
68+
69+
Delattr(n, "parms");
70+
71+
Delete(func);
72+
Delete(qualifiers);
73+
}
74+
}
75+
}
76+
5177
/* Normalize a type. Replaces type with fully qualified version */
5278
void normalize_type(SwigType *ty) {
5379
SwigType *qty;
@@ -749,6 +775,9 @@ class TypePass:private Dispatcher {
749775
}
750776

751777
/* Normalize types. */
778+
if (inclass) {
779+
normalize_void(n);
780+
}
752781
SwigType *ty = Getattr(n, "type");
753782
if (!ty) {
754783
return SWIG_OK;
@@ -819,6 +848,10 @@ class TypePass:private Dispatcher {
819848
Delattr(n, "throws");
820849
}
821850

851+
/* Normalize types. */
852+
if (inclass) {
853+
normalize_void(n);
854+
}
822855
normalize_parms(Getattr(n, "parms"));
823856
normalize_parms(Getattr(n, "throws"));
824857

Source/Swig/cwrap.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -393,8 +393,8 @@ String *Swig_cfunction_call(const_String_or_char_ptr name, ParmList *parms) {
393393

394394
while (p) {
395395
SwigType *pt = Getattr(p, "type");
396-
SwigType *rpt = SwigType_typedef_resolve_all(pt);
397-
if ((SwigType_type(rpt) != T_VOID)) {
396+
if ((SwigType_type(pt) != T_VOID)) {
397+
SwigType *rpt = SwigType_typedef_resolve_all(pt);
398398
String *pname = Swig_cparm_name(p, i);
399399
String *rcaststr = SwigType_rcaststr(rpt, pname);
400400
if (comma)
@@ -431,6 +431,7 @@ static String *Swig_cmethod_call(const_String_or_char_ptr name, ParmList *parms,
431431
String *func, *nname;
432432
int i = 0;
433433
Parm *p = parms;
434+
SwigType *pt;
434435
int comma = 0;
435436

436437
func = NewStringEmpty();
@@ -455,7 +456,7 @@ static String *Swig_cmethod_call(const_String_or_char_ptr name, ParmList *parms,
455456
Replaceall(func, "this", rcaststr);
456457
Delete(rcaststr);
457458
} else {
458-
SwigType *pt = Getattr(p, "type");
459+
pt = Getattr(p, "type");
459460

460461
/* If the method is invoked through a dereferenced pointer, we don't add any casts
461462
(needed for smart pointers). Otherwise, we cast to the appropriate type */
@@ -491,14 +492,13 @@ static String *Swig_cmethod_call(const_String_or_char_ptr name, ParmList *parms,
491492
i++;
492493
p = nextSibling(p);
493494
while (p) {
494-
SwigType *pt = Getattr(p, "type");
495-
SwigType *rpt = SwigType_typedef_resolve_all(pt);
496-
if ((SwigType_type(rpt) != T_VOID)) {
495+
pt = Getattr(p, "type");
496+
if ((SwigType_type(pt) != T_VOID)) {
497497
String *pname = Swig_cparm_name(p, i);
498498
String *rcaststr = SwigType_rcaststr(pt, pname);
499499
if (comma)
500500
Append(func, ",");
501-
if (cparse_cplusplus && SwigType_type(rpt) == T_USER)
501+
if (cparse_cplusplus && SwigType_type(pt) == T_USER)
502502
Printv(func, "SWIG_STD_MOVE(", rcaststr, ")", NIL);
503503
else
504504
Printv(func, rcaststr, NIL);
@@ -547,6 +547,7 @@ static String *Swig_cppconstructor_base_call(const_String_or_char_ptr name, Parm
547547
int i = 0;
548548
int comma = 0;
549549
Parm *p = parms;
550+
SwigType *pt;
550551
if (skip_self) {
551552
if (p)
552553
p = nextSibling(p);
@@ -556,9 +557,8 @@ static String *Swig_cppconstructor_base_call(const_String_or_char_ptr name, Parm
556557
func = NewStringEmpty();
557558
Printf(func, "new %s(", nname);
558559
while (p) {
559-
SwigType *pt = Getattr(p, "type");
560-
SwigType *rpt = SwigType_typedef_resolve_all(pt);
561-
if ((SwigType_type(rpt) != T_VOID)) {
560+
pt = Getattr(p, "type");
561+
if ((SwigType_type(pt) != T_VOID)) {
562562
String *rcaststr = 0;
563563
String *pname = 0;
564564
if (comma)
@@ -574,7 +574,7 @@ static String *Swig_cppconstructor_base_call(const_String_or_char_ptr name, Parm
574574
pname = Copy(Getattr(p, "name"));
575575
}
576576
rcaststr = SwigType_rcaststr(pt, pname);
577-
if (cparse_cplusplus && SwigType_type(rpt) == T_USER)
577+
if (cparse_cplusplus && SwigType_type(pt) == T_USER)
578578
Printv(func, "SWIG_STD_MOVE(", rcaststr, ")", NIL);
579579
else
580580
Printv(func, rcaststr, NIL);

0 commit comments

Comments
 (0)