From 2aa540b9c0dee27e42e7eb6db2cb3e9ea24ca2ba Mon Sep 17 00:00:00 2001 From: Vladimir Kalinin Date: Wed, 14 May 2014 00:51:36 +0400 Subject: [PATCH 1/4] %extend for nested unnamed C structs --- Source/CParse/parser.y | 9 ++++----- Source/Modules/main.cxx | 2 ++ Source/Modules/nested.cxx | 10 ++++++---- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 26af7be2d..a1a62cb62 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -41,7 +41,7 @@ int yyparse(); static Node *top = 0; /* Top of the generated parse tree */ static int unnamed = 0; /* Unnamed datatype counter */ -static Hash *extendhash = 0; /* Hash table of added methods */ +Hash *extendhash = 0; /* Hash table of added methods */ static Hash *classes = 0; /* Hash table of classes */ static Hash *classes_typedefs = 0; /* Hash table of typedef classes: typedef struct X {...} Y; */ static Symtab *prev_symtab = 0; @@ -655,7 +655,7 @@ static void add_symbols_copy(Node *n) { actually needs to take precedence. Therefore, we will selectively nuke symbols from the current symbol table, replacing them with the added methods */ -static void merge_extensions(Node *cls, Node *am) { +void merge_extensions(Node *cls, Node *am) { Node *n; Node *csym; @@ -708,7 +708,7 @@ static void merge_extensions(Node *cls, Node *am) { } } -static void append_previous_extension(Node *cls, Node *am) { +void append_previous_extension(Node *cls, Node *am) { Node *n, *ne; Node *pe = 0; Node *ae = 0; @@ -737,7 +737,7 @@ static void append_previous_extension(Node *cls, Node *am) { /* Check for unused %extend. Special case, don't report unused extensions for templates */ -static void check_extensions() { +void check_extensions() { Iterator ki; if (!extendhash) return; @@ -1579,7 +1579,6 @@ program : interface { Setattr(module_node,"name",ModuleName); } Setattr($1,"module",module_node); - check_extensions(); top = $1; } | PARSETYPE parm SEMI { diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx index 833394b9c..d8f20c207 100644 --- a/Source/Modules/main.cxx +++ b/Source/Modules/main.cxx @@ -198,6 +198,7 @@ static String *external_runtime_name = 0; enum { STAGE1=1, STAGE2=2, STAGE3=4, STAGE4=8, STAGEOVERFLOW=16 }; static List *libfiles = 0; static List *all_output_files = 0; +extern "C" void check_extensions(); /* ----------------------------------------------------------------------------- * check_extension() @@ -1172,6 +1173,7 @@ int SWIG_main(int argc, char *argv[], Language *l) { Printf(stdout, "Processing unnamed structs...\n"); Swig_nested_name_unnamed_c_structs(top); } + check_extensions(); if (Verbose) { Printf(stdout, "Processing types...\n"); diff --git a/Source/Modules/nested.cxx b/Source/Modules/nested.cxx index 3b45e9f90..169263c3f 100644 --- a/Source/Modules/nested.cxx +++ b/Source/Modules/nested.cxx @@ -338,7 +338,9 @@ static void insertNodeAfter(Node *n, Node *c) { set_nextSibling(n, c); set_previousSibling(c, n); } - +extern "C" Hash *extendhash; +extern "C" void merge_extensions(Node *cls, Node *am); +extern "C" void append_previous_extension(Node *cls, Node *am); void Swig_nested_name_unnamed_c_structs(Node *n) { if (!classhash) classhash = Getattr(n, "classes"); @@ -377,15 +379,15 @@ void Swig_nested_name_unnamed_c_structs(Node *n) { } Delete(ty); // Check for extensions -/* // TODO: we can save extensions hash like class hash and move check_extensions() after nesting processing + // TODO: we can save extensions hash like class hash and move check_extensions() after nesting processing if (extendhash) { if (Node *am = Getattr(extendhash, name)) { // Merge the extension into the symbol table merge_extensions(c, am); append_previous_extension(c, am); - Delattr(extendhash, clsname); + Delattr(extendhash, name); } - }*/ + } Swig_symbol_setscope(Swig_symbol_global_scope()); add_symbols_c(c); From 5d78f14b1c2a580ad08326de4900f51245560dd7 Mon Sep 17 00:00:00 2001 From: Vladimir Kalinin Date: Wed, 14 May 2014 00:56:39 +0400 Subject: [PATCH 2/4] test added for nested unnamed C struct %extend --- Examples/test-suite/nested_extend_c.i | 15 +++++++++++++++ Source/Modules/nested.cxx | 2 -- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Examples/test-suite/nested_extend_c.i b/Examples/test-suite/nested_extend_c.i index 83d8c0601..702c839b2 100644 --- a/Examples/test-suite/nested_extend_c.i +++ b/Examples/test-suite/nested_extend_c.i @@ -44,6 +44,13 @@ return $self->num; } } + +%extend FOO_bar { + void bar_extend() { + $self->d = 1; + } +}; + #endif %inline %{ @@ -72,5 +79,13 @@ typedef struct { int num; } lowB_instance; } NestedB; + +typedef struct { + int a; + union { + char c; + int d; + } bar; +} FOO; %} diff --git a/Source/Modules/nested.cxx b/Source/Modules/nested.cxx index 169263c3f..510270681 100644 --- a/Source/Modules/nested.cxx +++ b/Source/Modules/nested.cxx @@ -378,8 +378,6 @@ void Swig_nested_name_unnamed_c_structs(Node *n) { decl = nextSibling(decl); } Delete(ty); - // Check for extensions - // TODO: we can save extensions hash like class hash and move check_extensions() after nesting processing if (extendhash) { if (Node *am = Getattr(extendhash, name)) { // Merge the extension into the symbol table From 3692e175bc980d1e1a06729465ff932e3bcc8e08 Mon Sep 17 00:00:00 2001 From: Vladimir Kalinin Date: Thu, 15 May 2014 03:13:25 +0400 Subject: [PATCH 3/4] global unnamed structures ignored --- Examples/test-suite/nested_extend_c.i | 4 ++++ Source/Modules/nested.cxx | 7 ++++++- Source/Modules/typepass.cxx | 3 +++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Examples/test-suite/nested_extend_c.i b/Examples/test-suite/nested_extend_c.i index 702c839b2..0e1495f86 100644 --- a/Examples/test-suite/nested_extend_c.i +++ b/Examples/test-suite/nested_extend_c.i @@ -87,5 +87,9 @@ typedef struct { int d; } bar; } FOO; + +struct { + int i; +} THING; %} diff --git a/Source/Modules/nested.cxx b/Source/Modules/nested.cxx index 510270681..ca1c79a31 100644 --- a/Source/Modules/nested.cxx +++ b/Source/Modules/nested.cxx @@ -396,7 +396,12 @@ void Swig_nested_name_unnamed_c_structs(Node *n) { Delete(ins); Delattr(c, "nested:outer"); } else { - // global unnamed struct - ignore it + // global unnamed struct - ignore it and it's instances + SetFlag(c, "feature:ignore"); + while (next && Getattr(next, "nested:unnamedtype") == c) { + SetFlag(next, "feature:ignore"); + next = nextSibling(next); + } c = next; continue; } diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx index 329a601a8..ec6f64587 100644 --- a/Source/Modules/typepass.cxx +++ b/Source/Modules/typepass.cxx @@ -661,6 +661,9 @@ class TypePass:private Dispatcher { * ------------------------------------------------------------ */ virtual int cDeclaration(Node *n) { + if (GetFlag(n, "feature:ignore")) { + return SWIG_OK; + } if (NoExcept) { Delattr(n, "throws"); } From d2ab75f9071ae15d98dbf091f6461ef397d66ef5 Mon Sep 17 00:00:00 2001 From: Vladimir Kalinin Date: Mon, 19 May 2014 02:05:23 +0400 Subject: [PATCH 4/4] obscure case workaround in std::set wrapper, where ignored type still need to be processed --- Source/Modules/typepass.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx index ec6f64587..3e323f910 100644 --- a/Source/Modules/typepass.cxx +++ b/Source/Modules/typepass.cxx @@ -661,15 +661,15 @@ class TypePass:private Dispatcher { * ------------------------------------------------------------ */ virtual int cDeclaration(Node *n) { - if (GetFlag(n, "feature:ignore")) { - return SWIG_OK; - } if (NoExcept) { Delattr(n, "throws"); } /* Normalize types. */ SwigType *ty = Getattr(n, "type"); + if (!ty) { + return SWIG_OK; + } normalize_type(ty); SwigType *decl = Getattr(n, "decl"); if (decl) {