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 {
|
||||
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 {
|
||||
|
|
|
@ -292,6 +292,7 @@ CPP_TEST_CASES += \
|
|||
multiple_inheritance_shared_ptr \
|
||||
name_cxx \
|
||||
name_warnings \
|
||||
namespace_chase \
|
||||
namespace_class \
|
||||
namespace_enum \
|
||||
namespace_extend \
|
||||
|
|
|
@ -47,7 +47,7 @@ public class class_scope_namespace_runme {
|
|||
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.fff(f, f, f, f);
|
||||
class_scope_namespace.ggg(g, g);
|
||||
class_scope_namespace.hhh(h);
|
||||
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 B *C;
|
||||
*
|
||||
* typetab is built as follows:
|
||||
*
|
||||
* typetab in scope '' contains:
|
||||
* "A" : "int"
|
||||
* "B" : "A"
|
||||
* "C" : "p.B"
|
||||
|
@ -67,31 +66,76 @@
|
|||
* ---> a(40).p.p.A (B --> A)
|
||||
* ---> 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
|
||||
* you have this:
|
||||
*
|
||||
* class Foo {
|
||||
* public:
|
||||
* typedef int Integer;
|
||||
* };
|
||||
* class Foo {
|
||||
* public:
|
||||
* typedef int Integer;
|
||||
* };
|
||||
* struct Bar : public Foo {
|
||||
* void blah(Integer x);
|
||||
* };
|
||||
*
|
||||
* class Bar : public Foo {
|
||||
* void blah(Integer x);
|
||||
* };
|
||||
* In this case typetab in scope '' contains:
|
||||
* "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 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.
|
||||
* For example, if you have this:
|
||||
*
|
||||
* namespace Foo {
|
||||
* typedef int Integer;
|
||||
* }
|
||||
* namespace Foo {
|
||||
* typedef int Integer;
|
||||
* }
|
||||
*
|
||||
* namespace F = Foo;
|
||||
* namespace F = Foo;
|
||||
*
|
||||
* 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
|
||||
* In this case, F is defined as a scope that "inherits" from Foo. Internally,
|
||||
* 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
|
||||
* will generate a warning message (in the parser) and will place information into
|
||||
* Foo instead.
|
||||
|
@ -968,8 +1012,17 @@ SwigType *SwigType_typedef_resolve_all(const SwigType *t) {
|
|||
/* -----------------------------------------------------------------------------
|
||||
* SwigType_typedef_qualified()
|
||||
*
|
||||
* Given a type declaration, this function tries to fully qualify it according to
|
||||
* typedef scope rules.
|
||||
* Given a type declaration, this function tries to fully qualify it so that the
|
||||
* 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
|
||||
* scope, it is left in place.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
@ -1030,20 +1083,14 @@ SwigType *SwigType_typedef_qualified(const SwigType *t) {
|
|||
out of the current scope */
|
||||
|
||||
Typetab *cs = current_scope;
|
||||
while (cs) {
|
||||
String *qs = SwigType_scope_name(cs);
|
||||
if (Len(qs)) {
|
||||
Append(qs, "::");
|
||||
}
|
||||
Append(qs, e);
|
||||
if (Getattr(scopes, qs)) {
|
||||
if (cs) {
|
||||
Typetab *found_scope = SwigType_find_scope(cs, e);
|
||||
if (found_scope) {
|
||||
String *qs = SwigType_scope_name(found_scope);
|
||||
Clear(e);
|
||||
Append(e, qs);
|
||||
Delete(qs);
|
||||
break;
|
||||
}
|
||||
Delete(qs);
|
||||
cs = Getattr(cs, "parent");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue