Fix using declarations combined with using directives with forward class

references.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@13502 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2012-08-04 20:23:07 +00:00
commit 6e6ce16e4e
11 changed files with 388 additions and 16 deletions

View file

@ -4,6 +4,7 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 2.0.8 (in progress) Version 2.0.8 (in progress)
=========================== ===========================
2012-06-27: wsfulton 2012-06-27: wsfulton
Fix display of pointers in various places on 64 bit systems - only 32 bits were being shown. Fix display of pointers in various places on 64 bit systems - only 32 bits were being shown.
@ -15,6 +16,45 @@ Version 2.0.8 (in progress)
2012-07-20: kwwette 2012-07-20: kwwette
[Octave] segfault-on-exit prevention hack now preserves exit status, and uses C99 _Exit(). [Octave] segfault-on-exit prevention hack now preserves exit status, and uses C99 _Exit().
2012-06-30: wsfulton
Fix namespace problems for symbols declared with a forward class declarations, such as:
namespace Space1 {
namespace Space2 {
struct XXX;
struct YYY;
}
struct Space2::YYY {};
struct Space1::Space2::XXX {};
void testXXX2(Space2::XXX xx) {}
void testYYY2(Space2::YYY yy) {}
}
where xx and yy were not recognised as the proxy classes XXX and YYY.
2012-06-30: wsfulton
Fix using declarations combined with using directives with forward class declarations so that
types are correctly found in scope.
namespace Outer2 {
namespace Space2 {
class Thing2;
}
}
using namespace Outer2;
using Space2::Thing2;
class Thing2 {};
// None of the methods below correctly used the Thing2 proxy class
void useit2(Thing2 t) {}
void useit2a(Outer2::Space2::Thing2 t) {}
void useit2b(::Outer2::Space2::Thing2 t) {}
void useit2c(Space2::Thing2 t) {}
namespace Outer2 {
void useit2d(Space2::Thing2 t) {}
}
2012-06-25: wsfulton 2012-06-25: wsfulton
Fix using declarations combined with using directives so that types are correctly found in scope. Fix using declarations combined with using directives so that types are correctly found in scope.
Example: Example:
@ -28,6 +68,8 @@ Version 2.0.8 (in progress)
using Space2::Thing2; // using declaration using Space2::Thing2; // using declaration
void useit2(Thing2 t) {} void useit2(Thing2 t) {}
Similarly for templated classes.
2012-05-29: wsfulton 2012-05-29: wsfulton
Fix #3529601 - seg fault when a protected method has the "director" Fix #3529601 - seg fault when a protected method has the "director"
feature but the parent class does not. Also fix similar problems with feature but the parent class does not. Also fix similar problems with

View file

@ -257,6 +257,7 @@ CPP_TEST_CASES += \
namespace_class \ namespace_class \
namespace_enum \ namespace_enum \
namespace_extend \ namespace_extend \
namespace_forward_declaration \
namespace_nested \ namespace_nested \
namespace_spaces \ namespace_spaces \
namespace_template \ namespace_template \
@ -443,6 +444,7 @@ CPP_TEST_CASES += \
using2 \ using2 \
using_composition \ using_composition \
using_directive_and_declaration \ using_directive_and_declaration \
using_directive_and_declaration_forward \
using_extend \ using_extend \
using_inherit \ using_inherit \
using_namespace \ using_namespace \

View file

@ -0,0 +1,26 @@
import namespace_forward_declaration.*;
public class namespace_forward_declaration_runme {
static {
try {
System.loadLibrary("namespace_forward_declaration");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
System.exit(1);
}
}
public static void main(String argv[]) {
XXX xxx = new XXX();
namespace_forward_declaration.testXXX1(xxx);
namespace_forward_declaration.testXXX2(xxx);
namespace_forward_declaration.testXXX3(xxx);
YYY yyy = new YYY();
namespace_forward_declaration.testYYY1(yyy);
namespace_forward_declaration.testYYY2(yyy);
namespace_forward_declaration.testYYY3(yyy);
}
}

View file

@ -0,0 +1,53 @@
import using_directive_and_declaration_forward.*;
public class using_directive_and_declaration_forward_runme {
static {
try {
System.loadLibrary("using_directive_and_declaration_forward");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
System.exit(1);
}
}
public static void main(String argv[])
{
using_directive_and_declaration_forward.useit1(new Thing1());
using_directive_and_declaration_forward.useit1a(new Thing1());
using_directive_and_declaration_forward.useit1b(new Thing1());
using_directive_and_declaration_forward.useit1c(new Thing1());
using_directive_and_declaration_forward.useit2(new Thing2());
using_directive_and_declaration_forward.useit2a(new Thing2());
using_directive_and_declaration_forward.useit2b(new Thing2());
using_directive_and_declaration_forward.useit2c(new Thing2());
using_directive_and_declaration_forward.useit2d(new Thing2());
using_directive_and_declaration_forward.useit3(new Thing3());
using_directive_and_declaration_forward.useit3a(new Thing3());
using_directive_and_declaration_forward.useit3b(new Thing3());
using_directive_and_declaration_forward.useit3c(new Thing3());
using_directive_and_declaration_forward.useit3d(new Thing3());
using_directive_and_declaration_forward.useit4(new Thing4());
using_directive_and_declaration_forward.useit4a(new Thing4());
using_directive_and_declaration_forward.useit4b(new Thing4());
using_directive_and_declaration_forward.useit4c(new Thing4());
using_directive_and_declaration_forward.useit4d(new Thing4());
using_directive_and_declaration_forward.useit5(new Thing5());
using_directive_and_declaration_forward.useit5a(new Thing5());
using_directive_and_declaration_forward.useit5b(new Thing5());
using_directive_and_declaration_forward.useit5c(new Thing5());
using_directive_and_declaration_forward.useit5d(new Thing5());
using_directive_and_declaration_forward.useit7(new Thing7());
using_directive_and_declaration_forward.useit7a(new Thing7());
using_directive_and_declaration_forward.useit7b(new Thing7());
using_directive_and_declaration_forward.useit7c(new Thing7());
using_directive_and_declaration_forward.useit7d(new Thing7());
}
}

View file

@ -24,5 +24,6 @@ public class using_directive_and_declaration_runme {
Thing6 t6b = new Thing6(); Thing6 t6b = new Thing6();
t6b.b(); t6b.b();
using_directive_and_declaration.useit6(t6a, t6b); using_directive_and_declaration.useit6(t6a, t6b);
using_directive_and_declaration.useit7(new Thing7());
} }
} }

View file

@ -0,0 +1,35 @@
%module namespace_forward_declaration
%inline %{
namespace Space1 {
namespace Space2 {
struct XXX;
struct YYY;
}
struct Space2::YYY {
int yyy(int h) {
return h;
}
};
struct Space1::Space2::XXX {
int xxx(int h) {
return h;
}
};
void testXXX1(Space1::Space2::XXX xx) {
}
void testXXX2(Space2::XXX xx) {
}
void testXXX3(::Space1::Space2::XXX xx) {
}
void testYYY1(Space1::Space2::YYY yy) {
}
void testYYY2(Space2::YYY yy) {
}
void testYYY3(::Space1::Space2::YYY yy) {
}
}
%}

View file

@ -81,5 +81,26 @@ namespace Outer6 {
} }
using namespace Outer6::Space6b; using namespace Outer6::Space6b;
void useit6(Outer6::Space6a::Thing6 ta, Thing6 tb) {} void useit6(Outer6::Space6a::Thing6 ta, Thing6 tb) {}
namespace Outer7 {
namespace Space7 {
namespace Middle7 {
class Thing7;
}
}
}
using namespace Outer7::Space7;
class Middle7::Thing7 {};
using Middle7::Thing7;
void useit7(Thing7 t) {}
void useit7a(Outer7::Space7::Middle7::Thing7 t) {}
void useit7b(::Outer7::Space7::Middle7::Thing7 t) {}
void useit7c(Middle7::Thing7 t) {}
namespace Outer7 {
namespace Space7 {
void useit7d(Middle7::Thing7 t) {}
}
}
%} %}

View file

@ -0,0 +1,124 @@
%module using_directive_and_declaration_forward
// Test using directives combined with using declarations and forward declarations
%inline %{
namespace Outer1 {
namespace Space1 {
class Thing1;
}
}
using namespace Outer1::Space1;
using Outer1::Space1::Thing1;
class Thing1 {};
void useit1(Thing1 t) {}
void useit1a(Outer1::Space1::Thing1 t) {}
void useit1b(::Outer1::Space1::Thing1 t) {}
namespace Outer1 {
void useit1c(Space1::Thing1 t) {}
}
namespace Outer2 {
namespace Space2 {
class Thing2;
}
}
using namespace Outer2;
using Space2::Thing2;
class Thing2 {};
void useit2(Thing2 t) {}
void useit2a(Outer2::Space2::Thing2 t) {}
void useit2b(::Outer2::Space2::Thing2 t) {}
void useit2c(Space2::Thing2 t) {}
namespace Outer2 {
void useit2d(Space2::Thing2 t) {}
}
namespace Outer3 {
namespace Space3 {
namespace Middle3 {
class Thing3;
}
}
}
using namespace Outer3;
using namespace Space3;
using Middle3::Thing3;
class Thing3 {};
void useit3(Thing3 t) {}
void useit3a(Outer3::Space3::Middle3::Thing3 t) {}
void useit3b(::Outer3::Space3::Middle3::Thing3 t) {}
void useit3c(Middle3::Thing3 t) {}
namespace Outer3 {
namespace Space3 {
void useit3d(Middle3::Thing3 t) {}
}
}
namespace Outer4 {
namespace Space4 {
namespace Middle4 {
class Thing4;
}
}
}
using namespace Outer4::Space4;
using Middle4::Thing4;
class Thing4 {};
void useit4(Thing4 t) {}
void useit4a(Outer4::Space4::Middle4::Thing4 t) {}
void useit4b(::Outer4::Space4::Middle4::Thing4 t) {}
void useit4c(Middle4::Thing4 t) {}
namespace Outer4 {
namespace Space4 {
void useit4d(Middle4::Thing4 t) {}
}
}
namespace Outer5 {
namespace Space5 {
namespace Middle5 {
namespace More5 {
class Thing5;
}
}
}
}
using namespace ::Outer5::Space5;
using namespace Middle5;
using More5::Thing5;
class Thing5 {};
void useit5(Thing5 t) {}
void useit5a(Outer5::Space5::Middle5::More5::Thing5 t) {}
void useit5b(::Outer5::Space5::Middle5::More5::Thing5 t) {}
void useit5c(Middle5::More5::Thing5 t) {}
namespace Outer5 {
namespace Space5 {
void useit5d(Middle5::More5::Thing5 t) {}
}
}
namespace Outer7 {
namespace Space7 {
namespace Middle7 {
class Thing7;
}
}
}
using namespace Outer7::Space7;
class Middle7::Thing7 {};
using Middle7::Thing7;
void useit7(Thing7 t) {}
void useit7a(Outer7::Space7::Middle7::Thing7 t) {}
void useit7b(::Outer7::Space7::Middle7::Thing7 t) {}
void useit7c(Middle7::Thing7 t) {}
namespace Outer7 {
namespace Space7 {
void useit7d(Middle7::Thing7 t) {}
}
}
%}

View file

@ -205,7 +205,7 @@ static String *yyrename = 0;
/* Forward renaming operator */ /* Forward renaming operator */
static String *resolve_node_scope(String *cname); static String *resolve_create_node_scope(String *cname);
Hash *Swig_cparse_features(void) { Hash *Swig_cparse_features(void) {
@ -867,26 +867,86 @@ static Node *nscope = 0;
static Node *nscope_inner = 0; static Node *nscope_inner = 0;
/* Remove the scope prefix from cname and return the base name without the prefix. /* Remove the scope prefix from cname and return the base name without the prefix.
* The scopes specified in the prefix are found, or created in the current namespace. * The scopes required for the symbol name are resolved and/or created, if required.
* So ultimately the scope is changed to that required for the base name.
* For example AA::BB::CC as input returns CC and creates the namespace AA then inner * For example AA::BB::CC as input returns CC and creates the namespace AA then inner
* namespace BB in the current scope. If no scope separator (::) in the input, then nothing happens! */ * namespace BB in the current scope. If cname is found to already exist as a weak symbol
static String *resolve_node_scope(String *cname) { * (forward reference) then the scope might be changed to match, such as when a symbol match
* is made via a using reference. */
static String *resolve_create_node_scope(String *cname) {
Symtab *gscope = 0; Symtab *gscope = 0;
Node *cname_node = 0;
int skip_lookup = 0;
nscope = 0; nscope = 0;
nscope_inner = 0; nscope_inner = 0;
if (Swig_scopename_check(cname)) {
String *prefix = Swig_scopename_prefix(cname);
if (prefix && (Strncmp(prefix,"::",2) == 0))
skip_lookup = 1;
}
cname_node = skip_lookup ? 0 : Swig_symbol_clookup_no_inherit(cname, 0);
if (cname_node) {
/* The symbol has been defined already or is in another scope.
If it is a weak symbol, it needs replacing and if it was brought into the current scope
via a using declaration, the scope needs adjusting appropriately for the new symbol. */
Symtab *symtab = Getattr(cname_node, "sym:symtab");
Node *sym_weak = Getattr(cname_node, "sym:weak");
if (symtab && sym_weak) {
/* Check if the scope is the current scope */
String *current_scopename = Swig_symbol_qualifiedscopename(0);
String *found_scopename = Swig_symbol_qualifiedscopename(symtab);
int len;
if (!current_scopename)
current_scopename = NewString("");
if (!found_scopename)
found_scopename = NewString("");
len = Len(current_scopename);
if ((len > 0) && (Strncmp(current_scopename, found_scopename, len) == 0)) {
if (Len(found_scopename) > len + 2) {
/* A matching weak symbol was found in non-global scope, some scope adjustment may be required */
String *new_cname = NewString(Char(found_scopename) + len + 2); /* skip over "::" prefix */
String *base = Swig_scopename_last(cname);
Printf(new_cname, "::%s", base);
cname = new_cname;
Delete(base);
} else {
/* A matching weak symbol was found in the same non-global local scope, no scope adjustment required */
assert(len == Len(found_scopename));
}
} else {
String *base = Swig_scopename_last(cname);
if (Len(found_scopename) > 0) {
/* A matching weak symbol was found in a different scope to the local scope - probably via a using declaration */
cname = NewStringf("%s::%s", found_scopename, base);
} else {
/* Either:
1) A matching weak symbol was found in a different scope to the local scope - this is actually a
symbol with the same name in a different scope which we don't want, so no adjustment required.
2) A matching weak symbol was found in the global scope - no adjustment required.
*/
cname = Copy(base);
}
Delete(base);
}
Delete(current_scopename);
Delete(found_scopename);
}
}
if (Swig_scopename_check(cname)) { if (Swig_scopename_check(cname)) {
Node *ns; Node *ns;
String *prefix = Swig_scopename_prefix(cname); String *prefix = Swig_scopename_prefix(cname);
String *base = Swig_scopename_last(cname); String *base = Swig_scopename_last(cname);
if (prefix && (Strncmp(prefix,"::",2) == 0)) { if (prefix && (Strncmp(prefix,"::",2) == 0)) {
/* I don't think we can use :: global scope to declare classes and hence neither %template. - consider reporting error instead - wsfulton. */
/* Use the global scope */ /* Use the global scope */
String *nprefix = NewString(Char(prefix)+2); String *nprefix = NewString(Char(prefix)+2);
Delete(prefix); Delete(prefix);
prefix= nprefix; prefix= nprefix;
gscope = set_scope_to_global(); gscope = set_scope_to_global();
} }
if (!prefix || (Len(prefix) == 0)) { if (Len(prefix) == 0) {
/* Use the global scope, but we need to add a 'global' namespace. */ /* Use the global scope, but we need to add a 'global' namespace. */
if (!gscope) gscope = set_scope_to_global(); if (!gscope) gscope = set_scope_to_global();
/* note that this namespace is not the "unnamed" one, /* note that this namespace is not the "unnamed" one,
@ -904,8 +964,7 @@ static String *resolve_node_scope(String *cname) {
} else { } else {
Symtab *nstab = Getattr(ns,"symtab"); Symtab *nstab = Getattr(ns,"symtab");
if (!nstab) { if (!nstab) {
Swig_error(cparse_file,cparse_line, Swig_error(cparse_file,cparse_line, "'%s' is not defined as a valid scope.\n", prefix);
"'%s' is not defined as a valid scope.\n", prefix);
ns = 0; ns = 0;
} else { } else {
/* Check if the node scope is the current scope */ /* Check if the node scope is the current scope */
@ -986,6 +1045,7 @@ static String *resolve_node_scope(String *cname) {
} }
Delete(prefix); Delete(prefix);
} }
return cname; return cname;
} }
@ -2784,7 +2844,7 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
/* If the class name is qualified, we need to create or lookup namespace entries */ /* If the class name is qualified, we need to create or lookup namespace entries */
if (!inclass) { if (!inclass) {
$5 = resolve_node_scope($5); $5 = resolve_create_node_scope($5);
} }
/* /*
@ -3406,7 +3466,7 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
prev_symtab = Swig_symbol_current(); prev_symtab = Swig_symbol_current();
/* If the class name is qualified. We need to create or lookup namespace/scope entries */ /* If the class name is qualified. We need to create or lookup namespace/scope entries */
scope = resolve_node_scope($3); scope = resolve_create_node_scope($3);
Setfile(scope,cparse_file); Setfile(scope,cparse_file);
Setline(scope,cparse_line); Setline(scope,cparse_line);
$3 = scope; $3 = scope;

View file

@ -227,6 +227,7 @@ extern "C" {
extern void Swig_symbol_cadd(const_String_or_char_ptr symname, Node *node); extern void Swig_symbol_cadd(const_String_or_char_ptr symname, Node *node);
extern Node *Swig_symbol_clookup(const_String_or_char_ptr symname, Symtab *tab); extern Node *Swig_symbol_clookup(const_String_or_char_ptr symname, Symtab *tab);
extern Node *Swig_symbol_clookup_check(const_String_or_char_ptr symname, Symtab *tab, int (*check) (Node *)); extern Node *Swig_symbol_clookup_check(const_String_or_char_ptr symname, Symtab *tab, int (*check) (Node *));
extern Node *Swig_symbol_clookup_no_inherit(const_String_or_char_ptr name, Symtab *n);
extern Symtab *Swig_symbol_cscope(const_String_or_char_ptr symname, Symtab *tab); extern Symtab *Swig_symbol_cscope(const_String_or_char_ptr symname, Symtab *tab);
extern Node *Swig_symbol_clookup_local(const_String_or_char_ptr symname, Symtab *tab); extern Node *Swig_symbol_clookup_local(const_String_or_char_ptr symname, Symtab *tab);
extern Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr symname, Symtab *tab, int (*check) (Node *)); extern Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr symname, Symtab *tab, int (*check) (Node *));

View file

@ -176,6 +176,8 @@ static Hash *current_symtab = 0; /* Current symbol table node */
static Hash *symtabs = 0; /* Hash of all symbol tables by fully-qualified name */ static Hash *symtabs = 0; /* Hash of all symbol tables by fully-qualified name */
static Hash *global_scope = 0; /* Global scope */ static Hash *global_scope = 0; /* Global scope */
static int use_inherit = 1;
/* common attribute keys, to avoid calling find_key all the times */ /* common attribute keys, to avoid calling find_key all the times */
@ -482,9 +484,9 @@ void Swig_symbol_alias(const_String_or_char_ptr aliasname, Symtab *s) {
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* Swig_symbol_inherit() * Swig_symbol_inherit()
* *
* Inherit symbols from another scope. * Inherit symbols from another scope. Primarily for C++ inheritance and
* Primarily for using directives, such as 'using namespace X;'. * for using directives, such as 'using namespace X;'
* Not for using declarations, such as 'using A;'. * but not for using declarations, such as 'using A;'.
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
void Swig_symbol_inherit(Symtab *s) { void Swig_symbol_inherit(Symtab *s) {
@ -970,7 +972,7 @@ static Node *_symbol_lookup(const String *name, Symtab *symtab, int (*check) (No
} }
inherit = Getattr(symtab, "inherit"); inherit = Getattr(symtab, "inherit");
if (inherit) { if (inherit && use_inherit) {
int i, len; int i, len;
len = Len(inherit); len = Len(inherit);
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
@ -1060,7 +1062,7 @@ static Node *symbol_lookup_qualified(const_String_or_char_ptr name, Symtab *symt
/* Check inherited scopes */ /* Check inherited scopes */
if (!n) { if (!n) {
List *inherit = Getattr(symtab, "inherit"); List *inherit = Getattr(symtab, "inherit");
if (inherit) { if (inherit && use_inherit) {
int i, len; int i, len;
len = Len(inherit); len = Len(inherit);
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
@ -1327,6 +1329,11 @@ Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr name, Symtab *n,
return s; return s;
} }
Node *Swig_symbol_clookup_no_inherit(const_String_or_char_ptr name, Symtab *n) {
use_inherit = 0;
Swig_symbol_clookup(name, n);
use_inherit = 1;
}
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* Swig_symbol_cscope() * Swig_symbol_cscope()