From 63452e9fc1c66e970de951e787daffd3d8b688cc Mon Sep 17 00:00:00 2001 From: Frank Schlimbach Date: Tue, 26 Feb 2019 07:27:12 -0600 Subject: [PATCH] better handling of using directives --- Examples/test-suite/common.mk | 1 + .../test-suite/python/using_member_runme.py | 10 ++++ Examples/test-suite/using_member.i | 52 +++++++++++++++++++ Source/CParse/parser.y | 5 +- Source/Swig/swig.h | 1 + Source/Swig/symbol.c | 34 +++++++++++- 6 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 Examples/test-suite/python/using_member_runme.py create mode 100644 Examples/test-suite/using_member.i diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 19e5d170c..86f052de5 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -549,6 +549,7 @@ CPP_TEST_CASES += \ using_directive_and_declaration_forward \ using_extend \ using_inherit \ + using_member \ using_namespace \ using_namespace_loop \ using_pointers \ diff --git a/Examples/test-suite/python/using_member_runme.py b/Examples/test-suite/python/using_member_runme.py new file mode 100644 index 000000000..a666059e2 --- /dev/null +++ b/Examples/test-suite/python/using_member_runme.py @@ -0,0 +1,10 @@ +from using_member import * + +b = B() +assert b.get(int(1)) == 10 +assert b.get(float(1)) == 20 + +bb = BB() +assert bb.greater(int(1)) == 0 +assert bb.greater(float(1)) == 1 +assert bb.great(True) == 2 diff --git a/Examples/test-suite/using_member.i b/Examples/test-suite/using_member.i new file mode 100644 index 000000000..938060956 --- /dev/null +++ b/Examples/test-suite/using_member.i @@ -0,0 +1,52 @@ +%module using_member; + +%rename(greater) one::two::three::interface1::AA::great(int); +%rename(greater) one::two::three::interface1::AA::great(float); + +%inline %{ +namespace interface1 +{ + class A + { + public: + int get(int) {return 10;} + }; +} +using interface1::A; + +class B : public A +{ + public: + using A::get; + int get(double) {return 20;} +}; + + +namespace one { + namespace two { + namespace three { + namespace interface1 + { + class AA + { + public: + int great(int) {return 0;} + int great(float) {return 1;} + }; + } + using interface1::AA; + } + } + namespace twotwo { + namespace threetwo { + class BB : public two::three::AA + { + public: + using two::three::AA::great; + int great(bool) {return 2;} + int jj() {return 3;}; + }; + } + } +} +%} diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index dfbfa43b6..aafec5cbb 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -4468,11 +4468,12 @@ templateparameterstail : COMMA templateparameter templateparameterstail { /* Namespace support */ cpp_using_decl : USING idcolon SEMI { - String *uname = Swig_symbol_type_qualify($2,0); + String *uname = Swig_symbol_type_qualify($2,0); String *name = Swig_scopename_last($2); - $$ = new_node("using"); + $$ = new_node("using"); Setattr($$,"uname",uname); Setattr($$,"name", name); + Swig_symbol_add_using(name, uname, $$); Delete(uname); Delete(name); add_symbols($$); diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h index 76691269e..6742c18b5 100644 --- a/Source/Swig/swig.h +++ b/Source/Swig/swig.h @@ -221,6 +221,7 @@ extern "C" { extern void Swig_symbol_print_tables_summary(void); extern void Swig_symbol_print_symbols(void); extern void Swig_symbol_print_csymbols(void); + extern void Swig_symbol_add_using(String * name, String * uname, Node * n); extern void Swig_symbol_init(void); extern void Swig_symbol_setscopename(const_String_or_char_ptr name); extern String *Swig_symbol_getscopename(void); diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c index aacaf24be..14de509be 100644 --- a/Source/Swig/symbol.c +++ b/Source/Swig/symbol.c @@ -382,6 +382,26 @@ String *Swig_symbol_qualified_language_scopename(Symtab *n) { return result; } +/* ----------------------------------------------------------------------------- + * Swig_symbol_add_using() + * ----------------------------------------------------------------------------- */ + +void Swig_symbol_add_using(String * name, String * uname, Node * n) { + Hash *h; + h = Swig_symbol_clookup(uname,0); + if (h && checkAttribute(h, "kind", "class")) { + String *qcurrent = Swig_symbol_qualifiedscopename(0); + if (qcurrent) { + Append(qcurrent, "::"); + Append(qcurrent, name); + } else { + qcurrent = NewString(name); + } + Setattr(symtabs, qcurrent, n); + Delete(qcurrent); + } +} + /* ----------------------------------------------------------------------------- * Swig_symbol_newscope() * @@ -1074,7 +1094,19 @@ static Node *symbol_lookup_qualified(const_String_or_char_ptr name, Symtab *symt Delete(qalloc); return st; } - n = symbol_lookup(name, st, checkfunc); + if (checkAttribute(st, "nodeType", "using")) { + String *uname = Getattr(st, "uname"); + if (uname) { + st = Getattr(symtabs, uname); + if (st) { + n = symbol_lookup(name, st, checkfunc); + } else { + fprintf(stderr, "Error: Found corrupt 'using' node\n"); + } + } + } else if (Getattr(st, "csymtab")) { + n = symbol_lookup(name, st, checkfunc); + } } if (qalloc) Delete(qalloc);