mirror of https://github.com/swig/swig
Fix scope lookup for template parameters containing unary scope operators
Fixes cases like: namespace Alloc { template<typename T> struct Rebind { typedef int Integer; }; } %template(RebindBucket) Alloc::Rebind< Bucket >; OR %template(RebindBucket) Alloc::Rebind< ::Bucket >; Alloc::Rebind< Bucket >::Integer Bucket1() { return 1; } Alloc::Rebind< ::Bucket >::Integer Bucket2() { return 2; } Alloc::Rebind<::template TemplateBucket<double>>::Integer Bucket3() { return 3; };
This commit is contained in:
parent
aa2932f409
commit
26e14c4f18
|
@ -444,6 +444,7 @@ CPP_TEST_CASES += \
|
|||
template_ns_enum2 \
|
||||
template_ns_inherit \
|
||||
template_ns_scope \
|
||||
template_parameters_global_scope \
|
||||
template_partial_arg \
|
||||
template_partial_specialization \
|
||||
template_partial_specialization_typedef \
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
import cpp11_template_typedefs.*;
|
||||
|
||||
public class cpp11_template_typedefs_runme {
|
||||
|
||||
static {
|
||||
try {
|
||||
System.loadLibrary("cpp11_template_typedefs");
|
||||
} 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[]) {
|
||||
int alloc1 = cpp11_template_typedefs.get_bucket_allocator1();
|
||||
int alloc2 = cpp11_template_typedefs.get_bucket_allocator2();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
import template_parameters_global_scope.*;
|
||||
|
||||
public class template_parameters_global_scope_runme {
|
||||
|
||||
static {
|
||||
try {
|
||||
System.loadLibrary("template_parameters_global_scope");
|
||||
} 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[]) {
|
||||
|
||||
int alloc = 0;
|
||||
|
||||
// Check 1
|
||||
alloc = template_parameters_global_scope.Bucket1();
|
||||
alloc = template_parameters_global_scope.Bucket2();
|
||||
alloc = template_parameters_global_scope.Bucket3();
|
||||
alloc = template_parameters_global_scope.Bucket4();
|
||||
alloc = template_parameters_global_scope.Bucket5();
|
||||
alloc = template_parameters_global_scope.Bucket6();
|
||||
|
||||
// Check 2
|
||||
alloc = template_parameters_global_scope.Spade1();
|
||||
alloc = template_parameters_global_scope.Spade2();
|
||||
alloc = template_parameters_global_scope.Spade3();
|
||||
alloc = template_parameters_global_scope.Spade4();
|
||||
alloc = template_parameters_global_scope.Spade5();
|
||||
alloc = template_parameters_global_scope.Spade6();
|
||||
|
||||
// Check 3
|
||||
alloc = template_parameters_global_scope.Ball1();
|
||||
alloc = template_parameters_global_scope.Ball2();
|
||||
alloc = template_parameters_global_scope.Ball3();
|
||||
alloc = template_parameters_global_scope.Ball4();
|
||||
alloc = template_parameters_global_scope.Ball5();
|
||||
alloc = template_parameters_global_scope.Ball6();
|
||||
|
||||
// Check 4
|
||||
alloc = template_parameters_global_scope.Bat1();
|
||||
alloc = template_parameters_global_scope.Bat2();
|
||||
alloc = template_parameters_global_scope.Bat3();
|
||||
alloc = template_parameters_global_scope.Bat4();
|
||||
alloc = template_parameters_global_scope.Bat5();
|
||||
alloc = template_parameters_global_scope.Bat6();
|
||||
|
||||
// Check 5
|
||||
alloc = template_parameters_global_scope.Chair1();
|
||||
alloc = template_parameters_global_scope.Chair2();
|
||||
alloc = template_parameters_global_scope.Chair3();
|
||||
alloc = template_parameters_global_scope.Chair4();
|
||||
alloc = template_parameters_global_scope.Chair5();
|
||||
alloc = template_parameters_global_scope.Chair6();
|
||||
|
||||
// Check 6
|
||||
alloc = template_parameters_global_scope.Table1();
|
||||
alloc = template_parameters_global_scope.Table2();
|
||||
alloc = template_parameters_global_scope.Table3();
|
||||
alloc = template_parameters_global_scope.Table4();
|
||||
alloc = template_parameters_global_scope.Table5();
|
||||
alloc = template_parameters_global_scope.Table6();
|
||||
|
||||
/*
|
||||
alloc = template_parameters_global_scope.rejig1();
|
||||
alloc = template_parameters_global_scope.rejig2();
|
||||
alloc = template_parameters_global_scope.rejig3();
|
||||
alloc = template_parameters_global_scope.rejig4();
|
||||
alloc = template_parameters_global_scope.rejig5();
|
||||
alloc = template_parameters_global_scope.rejig6();
|
||||
*/
|
||||
}
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
%module template_parameters_global_scope
|
||||
|
||||
%inline %{
|
||||
namespace Alloc {
|
||||
template<typename T> struct Rebind {
|
||||
typedef int Integer;
|
||||
};
|
||||
}
|
||||
%}
|
||||
|
||||
%inline %{
|
||||
struct Bucket {};
|
||||
typedef Bucket TDBucket;
|
||||
typedef ::Bucket TDGlobalBucket;
|
||||
%}
|
||||
|
||||
// Check 1: %template no unary scope operator
|
||||
%template(RebindBucket) Alloc::Rebind< Bucket >;
|
||||
|
||||
%inline %{
|
||||
Alloc::Rebind< Bucket >::Integer Bucket1() { return 1; }
|
||||
Alloc::Rebind< ::Bucket >::Integer Bucket2() { return 2; }
|
||||
Alloc::Rebind< TDBucket >::Integer Bucket3() { return 3; }
|
||||
Alloc::Rebind< ::TDBucket >::Integer Bucket4() { return 4; }
|
||||
Alloc::Rebind< TDGlobalBucket >::Integer Bucket5() { return 5; }
|
||||
Alloc::Rebind< ::TDGlobalBucket >::Integer Bucket6() { return 6; }
|
||||
%}
|
||||
|
||||
// Check 2: %template with unary scope operator
|
||||
%inline %{
|
||||
struct Spade {};
|
||||
typedef Spade TDSpade;
|
||||
typedef ::Spade TDGlobalSpade;
|
||||
%}
|
||||
%template(RebindSpade) Alloc::Rebind< ::Spade >;
|
||||
|
||||
%inline %{
|
||||
Alloc::Rebind< Spade >::Integer Spade1() { return 1; }
|
||||
Alloc::Rebind< ::Spade >::Integer Spade2() { return 2; }
|
||||
Alloc::Rebind< TDSpade >::Integer Spade3() { return 3; }
|
||||
Alloc::Rebind< ::TDSpade >::Integer Spade4() { return 4; }
|
||||
Alloc::Rebind< TDGlobalSpade >::Integer Spade5() { return 5; }
|
||||
Alloc::Rebind< ::TDGlobalSpade >::Integer Spade6() { return 6; }
|
||||
%}
|
||||
|
||||
// Check 3: %template typedef no unary scope operator
|
||||
%inline %{
|
||||
struct Ball {};
|
||||
typedef Ball TDBall;
|
||||
typedef ::Ball TDGlobalBall;
|
||||
%}
|
||||
%template(RebindBall) Alloc::Rebind< TDBall >;
|
||||
|
||||
%inline %{
|
||||
Alloc::Rebind< Ball >::Integer Ball1() { return 1; }
|
||||
Alloc::Rebind< ::Ball >::Integer Ball2() { return 2; }
|
||||
Alloc::Rebind< TDBall >::Integer Ball3() { return 3; }
|
||||
Alloc::Rebind< ::TDBall >::Integer Ball4() { return 4; }
|
||||
Alloc::Rebind< TDGlobalBall >::Integer Ball5() { return 5; }
|
||||
Alloc::Rebind< ::TDGlobalBall >::Integer Ball6() { return 6; }
|
||||
%}
|
||||
|
||||
// Check 4: %template typedef with unary scope operator
|
||||
%inline %{
|
||||
struct Bat {};
|
||||
typedef Bat TDBat;
|
||||
typedef ::Bat TDGlobalBat;
|
||||
%}
|
||||
%template(RebindBat) Alloc::Rebind< ::TDBat >;
|
||||
|
||||
%inline %{
|
||||
Alloc::Rebind< Bat >::Integer Bat1() { return 1; }
|
||||
Alloc::Rebind< ::Bat >::Integer Bat2() { return 2; }
|
||||
Alloc::Rebind< TDBat >::Integer Bat3() { return 3; }
|
||||
Alloc::Rebind< ::TDBat >::Integer Bat4() { return 4; }
|
||||
Alloc::Rebind< TDGlobalBat >::Integer Bat5() { return 5; }
|
||||
Alloc::Rebind< ::TDGlobalBat >::Integer Bat6() { return 6; }
|
||||
%}
|
||||
|
||||
// Check 5: %template double typedef no unary scope operator
|
||||
%inline %{
|
||||
struct Chair {};
|
||||
typedef Chair TDChair;
|
||||
typedef ::Chair TDGlobalChair;
|
||||
%}
|
||||
%template(RebindChair) Alloc::Rebind< TDGlobalChair >;
|
||||
|
||||
%inline %{
|
||||
Alloc::Rebind< Chair >::Integer Chair1() { return 1; }
|
||||
Alloc::Rebind< ::Chair >::Integer Chair2() { return 2; }
|
||||
Alloc::Rebind< TDChair >::Integer Chair3() { return 3; }
|
||||
Alloc::Rebind< ::TDChair >::Integer Chair4() { return 4; }
|
||||
Alloc::Rebind< TDGlobalChair >::Integer Chair5() { return 5; }
|
||||
Alloc::Rebind< ::TDGlobalChair >::Integer Chair6() { return 6; }
|
||||
%}
|
||||
|
||||
// Check 6: %template double typedef with unary scope operator
|
||||
%inline %{
|
||||
struct Table {};
|
||||
typedef Table TDTable;
|
||||
typedef ::Table TDGlobalTable;
|
||||
%}
|
||||
%template(RebindTable) Alloc::Rebind< ::TDGlobalTable >;
|
||||
|
||||
%inline %{
|
||||
Alloc::Rebind< Table >::Integer Table1() { return 1; }
|
||||
Alloc::Rebind< ::Table >::Integer Table2() { return 2; }
|
||||
Alloc::Rebind< TDTable >::Integer Table3() { return 3; }
|
||||
Alloc::Rebind< ::TDTable >::Integer Table4() { return 4; }
|
||||
Alloc::Rebind< TDGlobalTable >::Integer Table5() { return 5; }
|
||||
Alloc::Rebind< ::TDGlobalTable >::Integer Table6() { return 6; }
|
||||
%}
|
||||
|
||||
#if 0
|
||||
%inline %{
|
||||
namespace Alloc {
|
||||
template<typename T=::Spade/*, typename T2=TDSpade, typename T3=::TDSpade, typename T4=TDGlobalSpade, typename T5=::TDGlobalSpade*/> struct Rejig {
|
||||
typedef int Integer;
|
||||
};
|
||||
}
|
||||
%}
|
||||
|
||||
%template(RejigSpade) Alloc::Rejig<::Spade>;
|
||||
|
||||
%inline %{
|
||||
Alloc::Rejig<>::Integer rejig1() { return 1; }
|
||||
Alloc::Rejig< ::Spade >::Integer rejig2() { return 2; }
|
||||
Alloc::Rejig< ::TDSpade >::Integer rejig3() { return 3; }
|
||||
Alloc::Rejig< ::TDSpade >::Integer rejig4() { return 4; }
|
||||
Alloc::Rejig< TDGlobalSpade >::Integer rejig5() { return 5; }
|
||||
Alloc::Rejig< ::TDGlobalSpade >::Integer rejig6() { return 6; }
|
||||
%}
|
||||
#endif
|
|
@ -248,10 +248,26 @@ void SwigType_new_scope(const_String_or_char_ptr name) {
|
|||
ttab = NewHash();
|
||||
Setattr(s, "typetab", ttab);
|
||||
|
||||
/* Build fully qualified name and */
|
||||
/* Build fully qualified name */
|
||||
qname = SwigType_scope_name(s);
|
||||
#if 1
|
||||
{
|
||||
/* TODO: only do with templates? What happens with non-templates with code below? */
|
||||
String *stripped_qname;
|
||||
stripped_qname = SwigType_remove_global_scope_prefix(qname);
|
||||
/* Use fully qualified name for hash key without unary scope prefix, qname may contain unary scope */
|
||||
Setattr(scopes, stripped_qname, s);
|
||||
Setattr(s, "qname", qname);
|
||||
/*
|
||||
Printf(stdout, "SwigType_new_scope stripped %s %s\n", qname, stripped_qname);
|
||||
*/
|
||||
Delete(stripped_qname);
|
||||
}
|
||||
#else
|
||||
Printf(stdout, "SwigType_new_scope %s\n", qname);
|
||||
Setattr(scopes, qname, s);
|
||||
Setattr(s, "qname", qname);
|
||||
#endif
|
||||
Delete(qname);
|
||||
|
||||
current_scope = s;
|
||||
|
@ -418,12 +434,14 @@ static Typetab *SwigType_find_scope(Typetab *s, const SwigType *nameprefix) {
|
|||
Typetab *s_orig = s;
|
||||
String *nnameprefix = 0;
|
||||
static int check_parent = 1;
|
||||
int is_template = 0;
|
||||
|
||||
if (Getmark(s))
|
||||
return 0;
|
||||
Setmark(s, 1);
|
||||
|
||||
if (SwigType_istemplate(nameprefix)) {
|
||||
is_template = SwigType_istemplate(nameprefix);
|
||||
if (is_template) {
|
||||
nnameprefix = SwigType_typedef_resolve_all(nameprefix);
|
||||
nameprefix = nnameprefix;
|
||||
}
|
||||
|
@ -437,10 +455,12 @@ static Typetab *SwigType_find_scope(Typetab *s, const SwigType *nameprefix) {
|
|||
} else {
|
||||
full = NewString(nameprefix);
|
||||
}
|
||||
if (Getattr(scopes, full)) {
|
||||
s = Getattr(scopes, full);
|
||||
} else {
|
||||
s = 0;
|
||||
s = Getattr(scopes, full);
|
||||
if (!s && is_template) {
|
||||
/* try look up scope with all the unary scope operators within the template parameter list removed */
|
||||
SwigType *full_stripped = SwigType_remove_global_scope_prefix(full);
|
||||
s = Getattr(scopes, full_stripped);
|
||||
Delete(full_stripped);
|
||||
}
|
||||
Delete(full);
|
||||
if (s) {
|
||||
|
@ -911,6 +931,9 @@ SwigType *SwigType_typedef_resolve_all(const SwigType *t) {
|
|||
return Copy(r);
|
||||
}
|
||||
|
||||
#ifdef SWIG_DEBUG
|
||||
Printf(stdout, "SwigType_typedef_resolve_all start ... %s\n", t);
|
||||
#endif
|
||||
/* Recursively resolve the typedef */
|
||||
r = NewString(t);
|
||||
while ((n = SwigType_typedef_resolve(r))) {
|
||||
|
@ -931,6 +954,9 @@ SwigType *SwigType_typedef_resolve_all(const SwigType *t) {
|
|||
Delete(key);
|
||||
Delete(rr);
|
||||
}
|
||||
#ifdef SWIG_DEBUG
|
||||
Printf(stdout, "SwigType_typedef_resolve_all end === %s => %s\n", t, r);
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue