mirror of https://github.com/swig/swig
Fix type lookup in the presence of using directives and using declarations
Fix some cases of type lookup failure via a combination of both using directives and using declarations resulting in C++ code that did not compile as the generated type was not fully qualified for use in the global namespace. Example below: namespace Space5 { namespace SubSpace5 { namespace SubSubSpace5 { struct F {}; } } using namespace SubSpace5; using SubSubSpace5::F; void func(SubSubSpace5::F f); }
This commit is contained in:
parent
8bf81b8718
commit
bf98c5304f
|
@ -73,8 +73,7 @@ namespace Space5 {
|
||||||
struct SubSubSpace5::F {
|
struct SubSubSpace5::F {
|
||||||
void ff(Space5::SubSpace5::SubSubSpace5::F, SubSpace5::SubSubSpace5::F, SubSubSpace5::F, F) {}
|
void ff(Space5::SubSpace5::SubSubSpace5::F, SubSpace5::SubSubSpace5::F, SubSubSpace5::F, F) {}
|
||||||
};
|
};
|
||||||
// needs fixing
|
void fff(Space5::SubSpace5::SubSubSpace5::F, SubSpace5::SubSubSpace5::F, SubSubSpace5::F, F) {}
|
||||||
void fff(Space5::SubSpace5::SubSubSpace5::F, SubSpace5::SubSubSpace5::F, /*SubSubSpace5::F,*/ F) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Space6 {
|
namespace Space6 {
|
||||||
|
|
|
@ -292,6 +292,7 @@ CPP_TEST_CASES += \
|
||||||
multiple_inheritance_shared_ptr \
|
multiple_inheritance_shared_ptr \
|
||||||
name_cxx \
|
name_cxx \
|
||||||
name_warnings \
|
name_warnings \
|
||||||
|
namespace_chase \
|
||||||
namespace_class \
|
namespace_class \
|
||||||
namespace_enum \
|
namespace_enum \
|
||||||
namespace_extend \
|
namespace_extend \
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class class_scope_namespace_runme {
|
||||||
class_scope_namespace.ccc(c, c);
|
class_scope_namespace.ccc(c, c);
|
||||||
class_scope_namespace.ddd(d, d, d);
|
class_scope_namespace.ddd(d, d, d);
|
||||||
class_scope_namespace.eee(e, e, e);
|
class_scope_namespace.eee(e, e, e);
|
||||||
class_scope_namespace.fff(f, f, f);
|
class_scope_namespace.fff(f, f, f, f);
|
||||||
class_scope_namespace.ggg(g, g);
|
class_scope_namespace.ggg(g, g);
|
||||||
class_scope_namespace.hhh(h);
|
class_scope_namespace.hhh(h);
|
||||||
class_scope_namespace.iii(i, i);
|
class_scope_namespace.iii(i, i);
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
|
||||||
|
import namespace_chase.*;
|
||||||
|
|
||||||
|
public class namespace_chase_runme {
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
System.loadLibrary("namespace_chase");
|
||||||
|
} 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[])
|
||||||
|
{
|
||||||
|
Struct1A s1a = new Struct1A();
|
||||||
|
Struct1B s1b = new Struct1B();
|
||||||
|
Struct1C s1c = new Struct1C();
|
||||||
|
|
||||||
|
namespace_chase.sss3a(s1a, s1b, s1c);
|
||||||
|
namespace_chase.sss3b(s1a, s1b, s1c);
|
||||||
|
// needs fixing
|
||||||
|
// namespace_chase.sss3c(s1a, s1b, s1c);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
%module namespace_chase
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
namespace Space1A {
|
||||||
|
struct Struct1A {};
|
||||||
|
namespace Space1B {
|
||||||
|
struct Struct1B {};
|
||||||
|
namespace Space1C {
|
||||||
|
struct Struct1C {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
namespace Space2A {
|
||||||
|
using namespace Space1A;
|
||||||
|
namespace Space2B {
|
||||||
|
using namespace Space1B;
|
||||||
|
namespace Space2C {
|
||||||
|
using namespace Space1C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
namespace Space3 {
|
||||||
|
using namespace Space2A;
|
||||||
|
void sss3a(Space1A::Struct1A, Space1A::Space1B::Struct1B, Space1A::Space1B::Space1C::Struct1C) {}
|
||||||
|
void sss3b(Struct1A, Space1B::Struct1B, Space1B::Space1C::Struct1C) {}
|
||||||
|
// To fix: the last two parameters below fail and result in SWIGTYPE_ types instead of proxy classes
|
||||||
|
void sss3c(Space2A::Struct1A, Space2A::Space1B::Struct1B, Space2A::Space1B::Space1C::Struct1C) {}
|
||||||
|
}
|
||||||
|
namespace Space4 {
|
||||||
|
using namespace Space2A;
|
||||||
|
using namespace Space2A::Space2B;
|
||||||
|
using namespace Space2A::Space2B::Space2C;
|
||||||
|
void sss4a(Struct1A, Struct1B, Space2C::Struct1C) {}
|
||||||
|
void sss4b(Struct1A, Struct1B, Struct1C) {}
|
||||||
|
}
|
||||||
|
%}
|
|
@ -53,8 +53,7 @@
|
||||||
* typedef A B;
|
* typedef A B;
|
||||||
* typedef B *C;
|
* typedef B *C;
|
||||||
*
|
*
|
||||||
* typetab is built as follows:
|
* typetab in scope '' contains:
|
||||||
*
|
|
||||||
* "A" : "int"
|
* "A" : "int"
|
||||||
* "B" : "A"
|
* "B" : "A"
|
||||||
* "C" : "p.B"
|
* "C" : "p.B"
|
||||||
|
@ -67,31 +66,76 @@
|
||||||
* ---> a(40).p.p.A (B --> A)
|
* ---> a(40).p.p.A (B --> A)
|
||||||
* ---> a(40).p.p.int (A --> int)
|
* ---> a(40).p.p.int (A --> int)
|
||||||
*
|
*
|
||||||
|
*
|
||||||
|
* Using declarations are stored in the "typetab" hash table. For example,
|
||||||
|
*
|
||||||
|
* namespace NN {
|
||||||
|
* struct SS {};
|
||||||
|
* }
|
||||||
|
* namespace N {
|
||||||
|
* struct S {};
|
||||||
|
* using NN::SS;
|
||||||
|
* }
|
||||||
|
* using N::S;
|
||||||
|
*
|
||||||
|
* typetab in scope '' contains:
|
||||||
|
* "S" : "N::S"
|
||||||
|
*
|
||||||
|
* and typetab in scope 'N' contains:
|
||||||
|
* "SS" : "NN::SS"
|
||||||
|
* "S" : "S"
|
||||||
|
*
|
||||||
|
*
|
||||||
* For inheritance, SWIG tries to resolve types back to the base class. For instance, if
|
* For inheritance, SWIG tries to resolve types back to the base class. For instance, if
|
||||||
* you have this:
|
* you have this:
|
||||||
*
|
*
|
||||||
* class Foo {
|
* class Foo {
|
||||||
* public:
|
* public:
|
||||||
* typedef int Integer;
|
* typedef int Integer;
|
||||||
* };
|
* };
|
||||||
|
* struct Bar : public Foo {
|
||||||
|
* void blah(Integer x);
|
||||||
|
* };
|
||||||
*
|
*
|
||||||
* class Bar : public Foo {
|
* In this case typetab in scope '' contains:
|
||||||
* void blah(Integer x);
|
* "Foo" : "Foo"
|
||||||
* };
|
* "Bar" : "Bar"
|
||||||
|
* and scope 'Foo' contains:
|
||||||
|
* "Integer" : "int"
|
||||||
|
* and scope 'Bar' inherits from 'Foo' but is empty (observe that blah is not a scope or typedef)
|
||||||
*
|
*
|
||||||
* The argument type of Bar::blah will be set to Foo::Integer.
|
* The argument type of Bar::blah will be set to Foo::Integer.
|
||||||
*
|
*
|
||||||
|
*
|
||||||
|
* The scope-inheritance mechanism is used to manage C++ using directives.
|
||||||
|
*
|
||||||
|
* namespace XX {
|
||||||
|
* class CC {};
|
||||||
|
* }
|
||||||
|
* namespace X {
|
||||||
|
* class C {};
|
||||||
|
* using namespace XX;
|
||||||
|
* }
|
||||||
|
* using namespace X;
|
||||||
|
*
|
||||||
|
* typetab in scope '' inherits from 'X'
|
||||||
|
* typetab in scope 'X' inherits from 'XX' and contains:
|
||||||
|
* "C" : "C"
|
||||||
|
* typetab in scope 'XX' contains:
|
||||||
|
* "CC" : "CC"
|
||||||
|
*
|
||||||
|
*
|
||||||
* The scope-inheritance mechanism is used to manage C++ namespace aliases.
|
* The scope-inheritance mechanism is used to manage C++ namespace aliases.
|
||||||
* For example, if you have this:
|
* For example, if you have this:
|
||||||
*
|
*
|
||||||
* namespace Foo {
|
* namespace Foo {
|
||||||
* typedef int Integer;
|
* typedef int Integer;
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* namespace F = Foo;
|
* namespace F = Foo;
|
||||||
*
|
*
|
||||||
* In this case, "F::" is defined as a scope that "inherits" from Foo. Internally,
|
* In this case, F is defined as a scope that "inherits" from Foo. Internally,
|
||||||
* "F::" will merely be an empty scope that refers to Foo. SWIG will never
|
* F will merely be an empty scope that points to Foo. SWIG will never
|
||||||
* place new type information into a namespace alias---attempts to do so
|
* place new type information into a namespace alias---attempts to do so
|
||||||
* will generate a warning message (in the parser) and will place information into
|
* will generate a warning message (in the parser) and will place information into
|
||||||
* Foo instead.
|
* Foo instead.
|
||||||
|
@ -968,8 +1012,17 @@ SwigType *SwigType_typedef_resolve_all(const SwigType *t) {
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* SwigType_typedef_qualified()
|
* SwigType_typedef_qualified()
|
||||||
*
|
*
|
||||||
* Given a type declaration, this function tries to fully qualify it according to
|
* Given a type declaration, this function tries to fully qualify it so that the
|
||||||
* typedef scope rules.
|
* resulting type can be used in the global scope. The type name is resolved in
|
||||||
|
* the current scope.
|
||||||
|
*
|
||||||
|
* It provides a fully qualified name, not necessarily a fully expanded name.
|
||||||
|
* When a using declaration or using directive is found the type may not be fully
|
||||||
|
* expanded, but it will be resolved and fully qualified for use in the global scope.
|
||||||
|
*
|
||||||
|
* This function is for looking up scopes to qualify a type. It does not resolve
|
||||||
|
* C typedefs, it just qualifies them. See SwigType_typedef_resolve for resolving.
|
||||||
|
*
|
||||||
* If the unary scope operator (::) is used as a prefix to the type to denote global
|
* If the unary scope operator (::) is used as a prefix to the type to denote global
|
||||||
* scope, it is left in place.
|
* scope, it is left in place.
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
@ -1030,20 +1083,14 @@ SwigType *SwigType_typedef_qualified(const SwigType *t) {
|
||||||
out of the current scope */
|
out of the current scope */
|
||||||
|
|
||||||
Typetab *cs = current_scope;
|
Typetab *cs = current_scope;
|
||||||
while (cs) {
|
if (cs) {
|
||||||
String *qs = SwigType_scope_name(cs);
|
Typetab *found_scope = SwigType_find_scope(cs, e);
|
||||||
if (Len(qs)) {
|
if (found_scope) {
|
||||||
Append(qs, "::");
|
String *qs = SwigType_scope_name(found_scope);
|
||||||
}
|
|
||||||
Append(qs, e);
|
|
||||||
if (Getattr(scopes, qs)) {
|
|
||||||
Clear(e);
|
Clear(e);
|
||||||
Append(e, qs);
|
Append(e, qs);
|
||||||
Delete(qs);
|
Delete(qs);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
Delete(qs);
|
|
||||||
cs = Getattr(cs, "parent");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue