diff --git a/libexec/trick/convert_swig b/libexec/trick/convert_swig index 80c5c5e7..94815fa9 100755 --- a/libexec/trick/convert_swig +++ b/libexec/trick/convert_swig @@ -60,6 +60,7 @@ my %sim ; my %out_of_date ; my ($version, $thread, $year) ; my %processed_templates ; +my $global_template_typedefs ; my $typedef_def = qr/typedef\s+ # the word typedef (?:[_A-Za-z][\s\w]*\s*) # resolved type @@ -336,6 +337,7 @@ sub process_file() { } print OUT "\n$new_contents" ; print OUT "$contents\n" ; + print OUT $global_template_typedefs ; # Add a trick_cast_as macro line for each class parsed in the file. These lines must appear at the bottom of the # file to ensure they are not in a namespace directive and they are after the #define statements they depend on. undef %class_typemap_printed ; @@ -638,13 +640,27 @@ sub process_class($$$$$) { my ($template_type_no_sp) = $template_full_type ; $template_type_no_sp =~ s/\s//g ; + + # If the type is qualified, assume it's fully qualified and put the + # %template directive in the global namespace. + # See https://github.com/nasa/trick/issues/768 + my $qualified = $template_type_no_sp =~ /^\w+(::)\w+ + +namespace a { + template class A { + private: + void operator=(const A&); + }; +} + +namespace b { + + template class A {}; + template class B {}; + + class C { + public: + std::vector v; + a::A a; + a::A a2; + A a3; + A a4; + B b; + B b2; + b::B b3; + b::B b4; + B > ba; + B > ba2; + b::B > ba3; + b::B > ba4; + B > ba5; + B > ba6; + + // These don't work. Because the type is qualified, convert_swig assumes + // it's fully qualified and puts the %template directive in the global + // namespace. However, there is no A in the global namespace, so the wrapper + // code fails to compile. Bonus points if you can fix this without breaking + // something else. + //b::B > ba7; + //b::B > ba8; + }; + + // This class is the same as the previous. Seems weird, but it reveals scoping + // errors under SWIG 2. The replication is not necessary in SWIG 4, which has + // better error detection. + class D { + public: + std::vector v; + a::A a; + a::A a2; + A a3; + A a4; + B b; + B b2; + b::B b3; + b::B b4; + B > ba; + B > ba2; + b::B > ba3; + b::B > ba4; + B > ba5; + B > ba6; + //b::B > ba7; + //b::B > ba8; + }; +} + +class E { + public: + std::vector v; + a::A a; + a::A a2; + b::B b3; + b::B b4; + b::B > ba3; + b::B > ba4; +}; + +namespace a { + class B { + public: + std::vector v; + a::A a; + a::A a2; + A a3; + A a4; + b::B b3; + b::B b4; + b::B > ba3; + b::B > ba4; + //b::B > ba7; + //b::B > ba8; + }; +}