%template scope enforcement and class definition fixes
The scoping rules around %template have been specified and enforced.
The %template directive for a class template is the equivalent to an
explicit instantiation of a C++ class template. The scope for a valid
%template instantiation is now the same as the scope required for a
valid explicit instantiation of a C++ template. A definition of the
template for the explicit instantiation must be in scope where the
instantiation is declared and must not be enclosed within a different
namespace.
For example, a few %template and explicit instantiations of std::vector
are shown below:
// valid
namespace std {
%template(vin) vector<int>;
template class vector<int>;
}
// valid
using namespace std;
%template(vin) vector<int>;
template class vector<int>;
// valid
using std::vector;
%template(vin) vector<int>;
template class vector<int>;
// ill-formed
namespace unrelated {
using std::vector;
%template(vin) vector<int>;
template class vector<int>;
}
// ill-formed
namespace unrelated {
using namespace std;
%template(vin) vector<int>;
template class vector<int>;
}
// ill-formed
namespace unrelated {
namespace std {
%template(vin) vector<int>;
template class vector<int>;
}
}
// ill-formed
namespace unrelated {
%template(vin) std::vector<int>;
template class std::vector<int>;
}
When the scope is incorrect, an error now occurs such as:
cpp_template_scope.i:34: Error: 'vector' resolves to 'std::vector' and
was incorrectly instantiated in scope 'unrelated' instead of within scope 'std'.
Previously SWIG accepted the ill-formed examples above but this led to
numerous subtle template scope problems especially in the presence of
using declarations and using directives as well as with %feature and %typemap.
Actually, a valid instantiation is one which conforms to the C++03
standard as C++11 made a change to disallow using declarations and
using directives to find a template.
// valid C++03, ill-formed C++11
using std::vector;
template class vector<int>;
Similar fixes for defining classes using forward class references have
also been put in place. For example:
namespace Space1 {
struct A;
}
namespace Space2 {
struct Space1::A {
void x();
}
}
will now error out with:
cpp_class_definition.i:5: Error: 'Space1::A' resolves to 'Space1::A' and
was incorrectly instantiated in scope 'Space2' instead of within scope 'Space1'.
This commit is contained in:
parent
97ae9d66bc
commit
959e627208
21 changed files with 689 additions and 114 deletions
59
Examples/test-suite/java/class_scope_namespace_runme.java
Normal file
59
Examples/test-suite/java/class_scope_namespace_runme.java
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
|
||||
import class_scope_namespace.*;
|
||||
|
||||
public class class_scope_namespace_runme {
|
||||
|
||||
static {
|
||||
try {
|
||||
System.loadLibrary("class_scope_namespace");
|
||||
} 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[])
|
||||
{
|
||||
A a = new A();
|
||||
B b = new B();
|
||||
C c = new C();
|
||||
D d = new D();
|
||||
E e = new E();
|
||||
F f = new F();
|
||||
G g = new G();
|
||||
H.HH h = new H.HH();
|
||||
I.II i = new I.II();
|
||||
J j = new J();
|
||||
K k = new K();
|
||||
L l = new L();
|
||||
M m = new M();
|
||||
|
||||
a.aa(a, a, a);
|
||||
b.bb(b, b);
|
||||
c.cc(c, c);
|
||||
d.dd(d, d, d);
|
||||
e.ee(e, e, e);
|
||||
f.ff(f, f, f, f);
|
||||
g.gg(g, g);
|
||||
h.hh(h);
|
||||
i.ii(i, i);
|
||||
j.jj(j, j, j);
|
||||
k.kk(k, k, k);
|
||||
l.ll(l, l, l);
|
||||
m.mm(m, m, m);
|
||||
|
||||
class_scope_namespace.aaa(a, a, a);
|
||||
class_scope_namespace.bbb(b, b);
|
||||
class_scope_namespace.ccc(c, c);
|
||||
class_scope_namespace.ddd(d, d, d);
|
||||
class_scope_namespace.eee(e, e, e);
|
||||
class_scope_namespace.fff(f, f, f);
|
||||
class_scope_namespace.ggg(g, g);
|
||||
class_scope_namespace.hhh(h);
|
||||
class_scope_namespace.iii(i, i);
|
||||
class_scope_namespace.jjj(j, j, j);
|
||||
class_scope_namespace.kkk(k, k, k);
|
||||
class_scope_namespace.lll(l, l, l);
|
||||
class_scope_namespace.mmm(m, m, m);
|
||||
}
|
||||
}
|
||||
32
Examples/test-suite/java/namespace_template_runme.java
Normal file
32
Examples/test-suite/java/namespace_template_runme.java
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
import namespace_template.*;
|
||||
|
||||
public class namespace_template_runme {
|
||||
|
||||
static {
|
||||
try {
|
||||
System.loadLibrary("namespace_template");
|
||||
} 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[]) {
|
||||
vectorchar vc = new vectorchar();
|
||||
vectorshort vs = new vectorshort();
|
||||
vectorint vi = new vectorint();
|
||||
vectorlong vl = new vectorlong();
|
||||
|
||||
vc.blah((char)10);
|
||||
vs.blah((short)10);
|
||||
vi.blah(10);
|
||||
vl.blah(10);
|
||||
|
||||
vc.vectoruse(vc, vc);
|
||||
vs.vectoruse(vs, vs);
|
||||
vi.vectoruse(vi, vi);
|
||||
vl.vectoruse(vl, vl);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue