C++11 inheriting constructors (using Base::Base;) now work when the immediate
base class is named through a typedef, a chain of typedefs, a typedef whose
template argument is itself a typedef, a scope-qualified or namespaced name, or
a type-template parameter used directly as the base class (the mixin idiom).
The inheriting constructor's using-declaration qualifier is normalized in the
typepass stage; the inheriting base is then found by identity in the resolved base
class list and the base class' constructors are used to implement the inherited
constructors.
An inheriting-constructor using declaration whose qualifier is not an immediate
base class is reported with Warning 329 (uses base '...' which is not an
immediate base of '...') rather than the generic Warning 315.
Closes#2951)
Assisted-by: Claude Opus 4.8
Add support for using declarations to introduce templated member
methods and for inheriting templated constructors, such as:
struct Base {
// templated constructor
template <typename T> Base(const T &t, const char *s) {}
// templated member method
template <typename T> void template_method(const T &t, const char *s) {}
};
%template(Base) Base::Base<int>;
%template(template_method) Base::template_method<double>;
struct Derived : Base {
using Base::Base;
using Base::template_method;
};
Previously the templated methods and constructors were ignored and
not introduced into the Derived class.
Fixes inheritance hierarchies more than two deep and the using
declarations are overloaded. Using declarations
from a base class' base were not available for use in the target
language. For example in the code below, Using1::usingmethod(int i)
was not wrapped for use in Using3:
struct Using1 {
protected:
void usingmethod(int i) {}
};
struct Using2 : Using1 {
protected:
void usingmethod(int i, int j) {}
using Using1::usingmethod;
};
struct Using3 : Using2 {
void usingmethod(int i, int j, int k) {}
using Using2::usingmethod;
};
Similarly for C++11 using declarations for inheriting constructors.
Recent commits for internal constructor and destructor names resulted
in destructors declared with template parameters being ignored
with warnings like:
Illegal destructor name TemplPublicBase6< int >::~TemplPublicBase6(). Ignored.
Although declaring constructors and destructors with template parameters
are rejected by modern compilers and C++20, SWIG continues to support it.
Make sure the name stored in the parse tree is the C++20 compliant name
name, that is, without the template parameters.
Fixes using declarations for templated constructors declared with
template parameters, was warning with:
Nothing known about 'TemplPublicBase6< int >::TemplPublicBase6'.
Support extended to directors.
Go protected constructors fix required for new testcase:
- Emit wrappers if director class is abstract
- If called, errors out with: accessing abstract class or protected constructor
- Now consistent with other target languages
Parser no longer checks for a declared constructor when handling a
using declaration in order to correct the name as it won't find
implicitly declared constructors. Now it checks that a using
declaration is for something that looks like a constructor instead
by checking the immediate base classes for allowed constructors.
Internal using name no longer contains template parameters.
Fixes symbol table lookup for non-instantiated template constructor.
Builds on previous few commits where the internal name no longer
contains the template parameters for constructors and destructors.