Fix using declarations and templates. %template was putting the

instantiated template into the global namespace instead of the namespace
of the template definition. This fixes regression in swig-2.0.5 copying
the std::pair typemaps which occurs with a 'using std::pair'
declaration. This also fixes lots of other using declarations of
template problems (template forward declarations. combinations
using directives).

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@13504 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2012-08-04 20:24:22 +00:00
parent 3e33774c8c
commit 54726b9d09
9 changed files with 339 additions and 7 deletions

View File

@ -16,6 +16,55 @@ Version 2.0.8 (in progress)
2012-07-20: kwwette
[Octave] segfault-on-exit prevention hack now preserves exit status, and uses C99 _Exit().
2012-07-02: wsfulton
Fix Debian bug http://bugs.debian.org/672035, typemap copy failure - regression introduced
in swig-2.0.5:
%include<stl.i>
using std::pair;
%template(StrPair) pair<std::string, std::string>;
2012-07-02: wsfulton
Fix using declarations combined with using directives with forward class declarations so that
types are correctly found in scope for templates. Example:
namespace Outer2 {
namespace Space2 {
template<typename T> class Thing2;
}
}
using namespace Outer2;
using Space2::Thing2;
template<typename T> class Thing2 {};
// STILL BROKEN void useit2(Thing2<int> t) {}
void useit2a(Outer2::Space2::Thing2<int> t) {}
void useit2b(::Outer2::Space2::Thing2<int> t) {}
void useit2c(Space2::Thing2<int> t) {}
namespace Outer2 {
void useit2d(Space2::Thing2<int> t) {}
}
%template(Thing2Int) Thing2<int>;
2012-06-30: wsfulton
Fix template namespace problems for symbols declared with a forward class declarations, such as:
namespace Space1 {
namespace Space2 {
template<typename T> struct YYY;
}
template<typename T> struct Space2::YYY {
T yyy(T h) {
return h;
}
};
void testYYY1(Space1::Space2::YYY<int> yy) {}
void testYYY2(Space2::YYY<int> yy) {}
void testYYY3(::Space1::Space2::YYY<int> yy) {}
}
%template(YYYInt) Space1::Space2::YYY<int>;
2012-06-30: wsfulton
Fix namespace problems for symbols declared with a forward class declarations, such as:

View File

@ -370,6 +370,8 @@ CPP_TEST_CASES += \
template_inherit_abstract \
template_int_const \
template_methods \
template_namespace_forward_declaration \
template_using_directive_and_declaration_forward \
template_nested \
template_nested_typemaps \
template_ns \
@ -476,6 +478,7 @@ CPP_STD_TEST_CASES += \
li_std_except \
li_std_map \
li_std_pair \
li_std_pair_using \
li_std_string \
li_std_vector \
li_std_vector_enum \

View File

@ -0,0 +1,26 @@
import template_namespace_forward_declaration.*;
public class template_namespace_forward_declaration_runme {
static {
try {
System.loadLibrary("template_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[]) {
XXXInt xxx = new XXXInt();
template_namespace_forward_declaration.testXXX1(xxx);
template_namespace_forward_declaration.testXXX2(xxx);
template_namespace_forward_declaration.testXXX3(xxx);
YYYInt yyy = new YYYInt();
template_namespace_forward_declaration.testYYY1(yyy);
template_namespace_forward_declaration.testYYY2(yyy);
template_namespace_forward_declaration.testYYY3(yyy);
}
}

View File

@ -0,0 +1,53 @@
import template_using_directive_and_declaration_forward.*;
public class template_using_directive_and_declaration_forward_runme {
static {
try {
System.loadLibrary("template_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[])
{
template_using_directive_and_declaration_forward.useit1(new Thing1Int());
template_using_directive_and_declaration_forward.useit1a(new Thing1Int());
template_using_directive_and_declaration_forward.useit1b(new Thing1Int());
template_using_directive_and_declaration_forward.useit1c(new Thing1Int());
//BROKEN template_using_directive_and_declaration_forward.useit2(new Thing2Int());
template_using_directive_and_declaration_forward.useit2a(new Thing2Int());
template_using_directive_and_declaration_forward.useit2b(new Thing2Int());
template_using_directive_and_declaration_forward.useit2c(new Thing2Int());
template_using_directive_and_declaration_forward.useit2d(new Thing2Int());
//BROKEN template_using_directive_and_declaration_forward.useit3(new Thing3Int());
template_using_directive_and_declaration_forward.useit3a(new Thing3Int());
template_using_directive_and_declaration_forward.useit3b(new Thing3Int());
template_using_directive_and_declaration_forward.useit3c(new Thing3Int());
template_using_directive_and_declaration_forward.useit3d(new Thing3Int());
//BROKEN template_using_directive_and_declaration_forward.useit4(new Thing4Int());
template_using_directive_and_declaration_forward.useit4a(new Thing4Int());
template_using_directive_and_declaration_forward.useit4b(new Thing4Int());
template_using_directive_and_declaration_forward.useit4c(new Thing4Int());
template_using_directive_and_declaration_forward.useit4d(new Thing4Int());
//BROKEN template_using_directive_and_declaration_forward.useit5(new Thing5Int());
template_using_directive_and_declaration_forward.useit5a(new Thing5Int());
template_using_directive_and_declaration_forward.useit5b(new Thing5Int());
template_using_directive_and_declaration_forward.useit5c(new Thing5Int());
template_using_directive_and_declaration_forward.useit5d(new Thing5Int());
//BROKEN template_using_directive_and_declaration_forward.useit7(new Thing7Int());
template_using_directive_and_declaration_forward.useit7a(new Thing7Int());
template_using_directive_and_declaration_forward.useit7b(new Thing7Int());
template_using_directive_and_declaration_forward.useit7c(new Thing7Int());
template_using_directive_and_declaration_forward.useit7d(new Thing7Int());
}
}

View File

@ -0,0 +1,21 @@
%module li_std_pair_using
%include<stl.i>
using std::pair;
%template(StringStringPair) pair<std::string, std::string>;
%inline %{
typedef int Integer;
using std::string;
%}
%template(StringIntPair) pair<string, int>;
%inline %{
typedef std::string String;
typedef string Streeng;
std::pair<String, Streeng> bounce(std::pair<std::string, string> p) {
return p;
}
%}

View File

@ -0,0 +1,10 @@
from li_std_pair_using import *
one_tuple = ("one", "numero uno")
one = StringStringPair(one_tuple)
two_tuple = ("two", 2)
two = StringIntPair(two_tuple)
if bounce(one) != one_tuple:
raise RuntimeError

View File

@ -0,0 +1,38 @@
%module template_namespace_forward_declaration
%inline %{
namespace Space1 {
namespace Space2 {
template<typename T> struct XXX;
template<typename T> struct YYY;
}
template<typename T> struct Space2::YYY {
T yyy(T h) {
return h;
}
};
template<typename T> struct Space1::Space2::XXX {
T xxx(T h) {
return h;
}
};
void testXXX1(Space1::Space2::XXX<int> xx) {
}
void testXXX2(Space2::XXX<int> xx) {
}
void testXXX3(::Space1::Space2::XXX<int> xx) {
}
void testYYY1(Space1::Space2::YYY<int> yy) {
}
void testYYY2(Space2::YYY<int> yy) {
}
void testYYY3(::Space1::Space2::YYY<int> yy) {
}
}
%}
%template(XXXInt) Space1::Space2::XXX<int>;
%template(YYYInt) Space1::Space2::YYY<int>;

View File

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

View File

@ -879,20 +879,19 @@ static String *resolve_create_node_scope(String *cname) {
nscope = 0;
nscope_inner = 0;
if (Swig_scopename_check(cname)) {
String *prefix = Swig_scopename_prefix(cname);
if (prefix && (Strncmp(prefix,"::",2) == 0))
skip_lookup = 1;
}
if (Strncmp(cname,"::",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. */
via a using declaration, the scope needs adjusting appropriately for the new symbol.
Similarly for defined templates. */
Symtab *symtab = Getattr(cname_node, "sym:symtab");
Node *sym_weak = Getattr(cname_node, "sym:weak");
if (symtab && sym_weak) {
if ((symtab && sym_weak) || Equal(nodeType(cname_node), "template")) {
/* Check if the scope is the current scope */
String *current_scopename = Swig_symbol_qualifiedscopename(0);
String *found_scopename = Swig_symbol_qualifiedscopename(symtab);