Below are the changes for the current release.
See the CHANGES file for changes in older releases.
See the RELEASENOTES file for a summary of changes in each release.
Issue # numbers mentioned below can be found on Github. For more details, add
the issue number to the end of the URL: https://github.com/swig/swig/issues/

Version 4.5.0 (06 Aug 2026)
===========================

2026-08-04: Nerixyz
            #3526 Fix the scope of a template argument being added twice when the
            argument is named through an alias declaration of a template
            instantiation, for example:

              namespace space1 {
                struct Point { int x; };
                template <typename T> struct Holder { using size_type = int; };
              }
              using PointHolder = space1::Holder<space1::Point>;
              using PointSizeHolder = space1::Holder<PointHolder::size_type>;

            generated space1::space1::Point in the wrappers, which did not compile.

2026-08-04: wsfulton
            [Python] #3473 Generated .pyi stub files now use valid bodies for
            classes without wrapped members and include imports needed by base
            classes from %import directives.

2026-08-04: wsfulton
            [Python] #3473 Add the %pythonstubcode and %pythonstubbegin directives for
            adding Python code to the .pyi stub file generated by the -pyi and -pyifile
            options. They are the stub file equivalents of %pythoncode and %pythonbegin
            and do nothing unless a stub file is being generated. For example:

              %pythonstubcode %{
              import collections.abc
              %}

            pyabc.i uses this to import collections.abc into the stub file, so that the
            abstract base classes it adds with %pythonabc resolve for a type checker.

2026-08-03: wsfulton
            [Python] When using -builtin, internal new_ prefixed entry points for
            alternate constructors were mistakenly exposed by the low-level C/C++
            module. This occurred for constructors explicitly renamed with %rename,
            constructor template instantiations named with %template, and synthesized
            default constructors for C structs renamed with %rename. These constructors
            are now exported only under their public names, without aliases in the
            generated Python module.

            *** POTENTIAL INCOMPATIBILITY ***

2026-08-02: wsfulton
            [Python] #735 Added the -typehints command line option, which turns on
            PEP 484 type hints for the whole interface, equivalent to using the global
            feature:

              %feature("python:annotations", "typing");

            The python:annotations feature takes precedence over the option, so it can
            still be used to override it for individual symbols. A feature value of "0"
            turns the type hints off again:

              %feature("python:annotations", "0") no_hints;

            The SWIGPYTHON_TYPEHINTS preprocessor symbol is defined when using -typehints.

2026-08-02: Nerixyz, wsfulton
            [Python] #3469 Fix the PEP 484 type hint generated for a function with
            more than one output value. Such a function returns the values in a Python
            list, but was annotated with a bare comma separated list of the individual
            types, which is not a valid annotation. For example:

              void divide(int numerator, int denominator, int *OUTPUT, int *OUTPUT);

            was annotated "typing.Any, typing.Any" and is now
            "typing.List[typing.Union[typing.Any, typing.Any]]". The function's own
            return value, when not void, is the first element of the list and is now
            included in the annotation. Multi-argument argout typemaps now use their
            matching pytyping typemap too. The C/C++ annotations, that is
            %feature("python:annotations", "c"), are unchanged.

2026-08-01: wsfulton
            [D] Fix a director method taking a pointer to a primitive type by const
            reference, such as:

              %feature("director") Callback;
              struct Callback {
                virtual void callback(int *const &param1) = 0;
              };

            The generated D did not compile.  The proxy method takes the wrapper
            class, SWIGTYPE_p_int in this case, but the director callback passed the
            raw pointer straight to it.

2026-08-01: wsfulton
            [Python] Fix reference count leak for a swig::SwigVar_PyObject director
            method argument passed by value.  The count was incremented twice on each
            upcall, once by the assignment into the director wrapper variable and once
            by the directorin typemap, but only decremented once.

2026-08-01: wsfulton
            [Python, Ruby, Perl, Octave] Fix director method arguments taking a const
            reference to the language object type, such as:

              %feature("director") Callback;
              struct Callback {
                virtual void callback(PyObject *const &param1) = 0;
              };

            There was no directorin typemap for these, so the argument was wrapped as
            an opaque proxy object instead of being passed through unchanged.  For Ruby
            the generated code did not even compile.  swig::SwigPtr_PyObject const& and
            swig::SwigVar_PyObject const& are fixed too.

2026-08-01: jschueller, wsfulton
            [Python] #2015 Fix reference count underflow for a PyObject *
            director method argument, such as:

              %feature("director") Callback;
              struct Callback {
                virtual void callback(PyObject *param1) = 0;
              };

            The count dropped by one on each upcall until the object was freed while
            still in use. swig::SwigPtr_PyObject and swig::SwigVar_PyObject too.

2026-07-31: wsfulton
            [OCaml] Fix wrapping of char array members and parameters, such as:

              struct S { char name[8]; };

            The generated code copied the string with strcpy through the
            uninitialised local for the array, that is, a null pointer.  The string
            is now just pointed at and the existing bounded copy in the memberin
            typemap puts it into the array.

2026-07-31: wsfulton
            [JavaScript] The v8 and node engines now build against v8 13.x and 14.x,
            as used by Node.js 24 and 26. These removed FunctionCallbackInfo::Holder(),
            PropertyCallbackInfo::Holder(), String::Utf8Length, String::WriteUtf8 and
            the untagged v8::Object aligned internal field pointer accessors, and
            deprecated the untagged v8::External accessors.

            The minimum supported v8 version is unchanged at 7.4.

2026-07-30: erezgeva, wsfulton
            [JavaScript, Octave, Perl, Python, R, Ruby, Scilab] #3522
            SWIG_FromCharPtrAndSize, SWIG_FromBinaryCharPtrAndSize,
            SWIG_ToUint8Array, SWIG_FromUint8Array and the Scilab SWIG_AsVal_* and
            SWIG_From_* macros are now passed on to the generated wrapper instead of
            being consumed by the SWIG preprocessor. Code that SWIG does not macro
            expand can now use them, such as a typemap delimited with %{ ... %}:

              %typemap(out,fragment="SWIG_FromCharPtrAndSize") struct CharBuf %{
                $result = SWIG_FromCharPtrAndSize($1.str, $1.len);
              %}

            Note that a %{ ... %} block inserting code into the header section is
            emitted before the fragment defining these macros and so still cannot
            use them.

2026-07-30: wsfulton
            [JavaScript] Fixed building the examples and test-suite with the node
            engine when node-addon-api is not installed.

            Also, the node-addon-api headers provided by a distro package (such as
            the Debian/Ubuntu node-addon-api package) are now detected by configure
            without npm needing to be installed, enabling the napi engine.

2026-07-28: Nerixyz, wsfulton
            [Python] #3473 Added the -pyi command line option, which generates a .pyi
            PEP 484 stub file alongside the wrapped module. This gives the
            python:annotations PEP 484 typing support (see #3390 below) somewhere to
            attach to when using -builtin or -fastproxy, where the generated module has
            no (or only a partial) Python-level function/class definitions of its own.
            The -pyifile <file> option additionally overrides the stub's filename
            (implying -pyi). When -pyi/-pyifile is active, PEP 484 annotations are
            only generated in the .pyi, not duplicated in the .py file.

            Note: this is new and still under active development for this release,
            like the rest of the pytyping annotation support below - the generated stub
            content may change in subsequent SWIG releases as the feature matures.

2026-07-28: wsfulton
            A multicharacter constant, such as 'ab', now has type int instead
            of char, matching the C and C++ standards. For example:

              #define MULTI 'ab'

            is now wrapped as an int. Previously it was incorrectly wrapped
            as a char, which silently truncated the value.

2026-07-27: Nerixyz, wsfulton
            [Python] #3390 Added the $pytypename special variable for use in 'pytyping'
            typemaps, analogous to $javaclassname. It expands to the wrapped proxy class
            name for a type, or to an opaque SWIGTYPE_* type wrapper class (declared only
            for static type checkers inside an 'if typing.TYPE_CHECKING' block) for types
            that have no proxy class. The $*pytypename and $&pytypename variants are also
            available. The default annotations are unchanged; the special variables only
            take effect in user-defined 'pytyping' typemaps.

            The 'typing' module is now imported unconditionally in the generated code as
            SWIG supports Python 3.5 and later.

            Note: the pytyping annotation support (this feature, and -pyi below) is new
            and still under active development for this release. The generated
            annotations and stub content may change in subsequent SWIG releases as the
            feature matures.

2026-07-27: wsfulton
            [JavaScript, Octave, Perl, Python, R, Ruby, Scilab, Tcl]
            The INPUT typemaps no longer generate a redundant delete of the
            parameter. For example, the code generated for:

              int func_input(int *INPUT);

            no longer contains:

              if (SWIG_IsNewObj(res1)) delete arg1;

            The delete could never execute, but GCC was unable to determine this
            and warned about it via -Wfree-nonheap-object when compiling with
            optimisation and link time optimisation enabled.

2026-07-27: wsfulton
            [Java] Fix javac dangling-doc-comments warning "documentation comment is
            not attached to any declaration" in code generated using -doxygen for enums
            wrapped as simple constants. The comment for the enum itself is now
            generated as a plain comment, as there is no Java declaration for the enum
            for javadoc to attach to:

              // SomeEnum
              /*
               * Comment for the enum itself
               */
              /**
               * Comment for the first item
               */
              public final static int SOME_ITEM_1 = exampleJNI.SOME_ITEM_1_get();

2026-07-24: jun66j5, wsfulton
            [Ruby] #3512 Fix segfault when converting a proxy object that hand written
            code has detached from its C/C++ object using the pre SWIG 4.5 idiom:

              DATA_PTR(obj) = NULL;

            SWIG 4.5 stores the wrapped pointer in an internal struct, so this clears
            the pointer to that struct rather than the wrapped pointer. Such an object
            is now treated as one whose pointer has been cleared, as it was before SWIG
            4.5, instead of crashing. New code should use the SWIG API instead:

              SWIG_ConvertPtr(obj, NULL, NULL, SWIG_POINTER_CLEAR);

2026-07-23: Nerixyz
            [Python] #3408 Corrected the PEP 484 annotations generated by the
            python:annotations feature:

              const references to primitive types  typing.Any -> as the value type
              std::size_t, std::ptrdiff_t          typing.Any -> int
              std::string, std::wstring            str
              std::complex<float>, <double>        complex
              char *, wchar_t *                    str -> typing.Optional[str]
              long double                          float -> typing.Any

            The annotations for std::string, std::wstring, std::complex, wchar_t and
            the C99 _Complex types are now only generated when the library file
            defining their in and out typemaps is included.

2026-07-22: jschueller
            [Python] #3315 Fix "metaclass conflict" TypeError raised when importing a
            module built with -builtin that defines a class deriving from base classes
            wrapped in different SWIG extension modules. Each module used to create its
            own SwigPyObjectType metaclass instance, so a class combining bases from two
            modules had two unrelated metaclasses. The SwigPyObjectType metaclass (and
            the SwigPyStaticVar type) are now shared across all modules via the runtime
            data module. This only affected Python 3.12 and later, since heap types were
            enabled by default in SWIG 4.4.0.

2026-07-16: jschueller
            #3497 Fixed the SWIG_CastCmpStruct comparator in the generated runtime
            so that it provides a strict weak ordering. The comparator mixed the
            type-pointer ordering with the next-field priority, which could make the
            binary search in SWIG_TypeCheck miss a valid type entry and fail a cast
            at runtime. Affects scripting languages using SWIG's runtime type table.

2026-07-15: wsfulton
            [R] %rename of an enum (including an enum class) is now honoured for the
            generated R enum name. Previously the C++ enum name was always used for the
            name passed to defineEnumeration, so a renamed enum was registered under its
            original name while its enum item names used the renamed name. The enum
            class returned by the generated accessor functions (via enumFromInteger /
            enumToInteger) now also uses the renamed name, matching the other target
            languages.

2026-07-14: wsfulton
            [Go] %rename of an enum (including an enum class) is now honoured for the
            generated Go type name. Previously the C++ enum name was always used, so a
            renamed enum produced a Go type with the original name while its enum item
            constants used the renamed name.

            A side effect is that a typedef named enum now uses the typedef name for the
            Go type instead of the enum name used previously, matching the enum item names
            used by all the other target languages. The previous behaviour can be restored
            by renaming the typedef back to the enum name, for example:

              %rename(Foo) FooEnum;
              typedef enum Foo { FooA, FooB } FooEnum;

            makes the generated Go type Foo again.

            This also fixes the Go type name generated for a forward declared enum,
            which previously incorrectly embedded the mangled "enum" keyword, for example
            Enum_SS_ForwardEnum1 instead of ForwardEnum1.

2026-07-14: wsfulton
            [R] %rename of an enum item is now honoured in the generated R code. The
            enum item name passed to defineEnumeration previously used the original
            C++ name, so %rename had no effect on the name used with enumToInteger and
            enumFromInteger even though the underlying wrapper function was renamed.

2026-07-14: jschueller
            [R] #2984 Fix scoped enums (enum class) that are not declared within a class.
            The enum name was added twice to the enum item's wrapper function name,
            resulting in a mismatch with the name used in the generated R code.

2026-07-12: wsfulton
            [Lua] #3493 Directors now work with Lua 5.1 and LuaJIT, which do not have the
            Lua 5.2 uservalue functions ('lua_getuservalue'/'lua_setuservalue') used
            to store the table of Lua method overrides for a director object. The
            userdata environment functions that uservalues replaced
            ('lua_getfenv'/'lua_setfenv') are used instead when wrapping for Lua 5.1.

2026-07-12: wsfulton
            [Lua] #3493 Restore support for Lua 5.1 and LuaJIT (which implements the
            Lua 5.1 API) for non-director wrapping. Reverts part of #3394 which
            dropped Lua 5.1 support.

2026-07-11: wsfulton
            Fixed a protected or private nested class deriving from a class used
            elsewhere in the wrapped API producing a runtime upcast helper function
            that referenced the nested class by its inaccessible qualified name in
            non-member scope, a C++ compile error ('class ... is protected within
            this context'). No target language ever wraps a non-public nested class,
            so it is now never registered for this. Affects any target language
            using SWIG's generic runtime type table (for example Perl, Python,
            Ruby, Tcl, Lua), most visibly since the "Keep unsupported nested
            classes as ignored classes, not forward declarations" change.

2026-07-11: wsfulton
            [Tcl] Add support for Tcl 9. Fix
              error: implicit declaration of function Tcl_NewSizeIntObj.

2026-07-09: wsfulton
            [Guile, JavaScript, Lua, OCaml, Octave, Perl, Python, R, Ruby, Scilab, Tcl]
            Added 'char *&' (a reference to a char pointer) string typemaps to the
            target languages that were missing them. A 'char *&' function
            argument, return value or variable - and, via const reference stripping,
            a 'char *const&' - is now marshalled as a string in every target
            language rather than as an opaque pointer; previously only C#, D, Go,
            Java and PHP did so. The common char_strings test now also has a runme
            for every target language, all exercising the same set of functions, so
            there is complete char *& typemap coverage and testing across all
            supported languages.

2026-07-09: wsfulton
            [Guile] #3290 Fixed 'invalid conversion from const void* to void*' C++
            compilation error when wrapping a function taking a 'const char *'
            argument hidden behind a typedef, such as 'typedef const char *MyString;'.

2026-07-09: wsfulton
            [Go] Fixed the wrapper generated for a function or variable returning
            'char *&' (a reference to a char pointer), which previously returned a
            corrupted string because the returned pointer was not dereferenced.

2026-07-09: jschueller, olly, wsfulton
            [Go] #3290 Fixed 'invalid conversion' C++ compilation errors in the
            generated wrapper when a function takes a 'const char *' argument
            hidden behind a typedef, such as 'typedef const char *MyString;'.

2026-07-08: vadz
            #3403 Fixed a crash the doxygen parser triggered by a structural
            comment such as @name/@{ followed by a blank line with no documentation
            attached.

2026-07-08: phetdam
            [R] #3471 Fix corrupted output or a crash when the -package or -dll
            command line option is passed when generating R wrappers.

2026-07-06: wsfulton
            [Python] Removed the Python 2 compatibility macros that were kept in
            the generated code (pyhead.swg) only for user typemaps. A typemap
            still using any of these must be updated to call the Python 3 C API
            directly (the Python 3 equivalent is shown in brackets).

            Python 2 C API macros removed: PyClass_Check (PyObject_IsInstance),
            PyInt_Check (PyLong_Check), PyInt_AsLong (PyLong_AsLong),
            PyInt_FromLong (PyLong_FromLong), PyInt_FromSize_t
            (PyLong_FromSize_t), PyString_Check (PyBytes_Check),
            PyString_FromString (PyUnicode_FromString), PyString_Format
            (PyUnicode_Format), PyString_AsString (PyBytes_AsString),
            PyString_Size (PyBytes_Size), PyString_InternFromString
            (PyUnicode_InternFromString), Py_TPFLAGS_HAVE_CLASS
            (Py_TPFLAGS_BASETYPE) and _PyLong_FromSsize_t (PyLong_FromSsize_t).

            SWIG string helper macros removed: SWIG_Python_str_FromFormat
            (PyUnicode_FromFormat) and SWIG_Python_str_FromChar
            (PyUnicode_FromString).

            *** POTENTIAL INCOMPATIBILITY ***

2026-07-05: jschueller
            [Python] #2424 Updated the Python identifier warnings to match
            Python 3. The list of Python keywords and built-in names that SWIG
            warns about (a wrapped symbol clashing with one is renamed) now
            tracks Python 3: the Python 3 keywords and built-ins are added,
            including nonlocal, True, False, None and print and exec (no longer
            statements), and the Python 2 only names such as apply, buffer, cmp,
            file, long, unicode and xrange are dropped.

2026-07-05: jschueller, wsfulton
            [Python] #3201 Python 2 is no longer supported. SWIG now
            targets Python 3.5 and later only, and the Python 2 code paths have
            been removed from the generated wrappers and the SWIG library.

            Macros that only ever affected Python 2 have been removed and now
            have no effect if defined:
              - SWIG_PYTHON_2_UNICODE - in Python 2 this let a unicode object be
                accepted where a char* or std::string was expected; in Python 3
                str is already unicode so it is redundant.
              - SWIG_PYTHON_STRICT_UNICODE_WCHAR - in Python 2 this forced
                wchar_t* and std::wstring to accept only unicode and reject byte
                strings; that is already the only behavior in Python 3.
            SWIG_PYTHON_STRICT_BYTE_CHAR is unchanged and still supported.

            The deprecated embed.i library, which only ever worked with Python 2,
            has been removed, along with the python_static example build targets
            that used it.

            *** POTENTIAL INCOMPATIBILITY ***

2026-07-05: wsfulton
            [Octave] Fix Octave detection in configure with newer versions of
            Octave.  Newer Octave changed the format of the 'octave --version'
            output from "GNU Octave, version X" to "GNU Octave (arch) version
            X", so configure no longer recognised Octave as working and
            silently disabled it.  Also fix the mkoctfile check,
            which passed PATH and LD_LIBRARY_PATH to 'env' unquoted and so
            broke when either contained a directory with a space in it (as can
            happen with Windows paths under WSL).

2026-06-17: olly
            #3480 [Octave, Python, Ruby] Improve handling of NULL vs nullptr vs
            0 vs 0L.

            For these target languages, SWIG has previously treated nullptr or
            NULL as an integer 0 if used in a situation where the type wasn't
            known to be a pointer.

            For nullptr this is never helpful, because it has type nullptr_t
            which does not implicitly convert to 0, so we no longer do this.

            For NULL it's rather dubious - C and C++ allow NULL to be defined
            as integer 0, so `int i = NULL` may work and is occassionally seen
            in real code, but it is semantically wrong.  Also GCC and clang
            define NULL to a magic value and by default will warn about such
            misuse, so it's likely to be less common than before they did this.
            So now SWIG only converts NULL to 0 if used in a context where we
            know the underlying type is an arithmetic type.

            Using an integer zero (or equivalent value such as 0L) for a NULL
            pointer is valid, and SWIG will still treat it as a NULL pointer if
            used in a context where know the type is a pointer.  This is now
            done based on the value of the integer constant so also applies to
            0L (previously it was only done if the value was written in the
            code as literally `0`).

2026-06-17: wsfulton
            #3481 Fix the C++17 inheriting constructor pack 'using T::T ...;' over a
            variadic base pack so that the constructor of every base is wrapped.  For
            example:

              struct XB { XB(int a); };
              struct YB { YB(double a); };
              template <typename... T> struct A : T... { using T::T ...; };
              %template(AXY) A<XB, YB>;

            Previously the last base's constructor (YB(double) here) was silently dropped
            and a spurious Warning 526 was reported for it.  Every base's constructor is
            now wrapped and no warning is given.

2026-06-17: wsfulton
            #3480 Fix a syntax error when a using declaration imports an inherited
            conversion operator, such as 'using Base::operator int;'. The conversion
            operator is now brought into the derived class like any other inherited
            member.

2026-06-17: wsfulton
            #3479 Fix a syntax error when a using declaration combines the 'typename'
            disambiguator with a C++17 pack expansion to import a member type from each
            base in a base pack, for example:

              template <typename... Bases> struct Collector : Bases... {
                using typename Bases::value_type ...;
              };

2026-06-17: jschueller
            #2933 Fixed a regression where repeating an identical using declaration for
            a type, such as two 'using aa::Foo;' lines, caused that type to be referenced
            by its unqualified name in the generated wrapper code. This typically led to
            wrapper code that would not compile when the type was used in a template
            instantiation.

2026-06-16: wsfulton
            #1042, #1153 Fix the type of an inherited member brought into a derived
            class with a using declaration when the base class is named through a
            typedef or C++11 alias of a template instantiation.  For example:

              template <typename T> struct Owners { T value; };

              template <typename LinksT> class NodeI {
              public:
                using links_type = LinksT;
                Owners<links_type> owners;
              };
              template <typename LinksT> class Cluster : public NodeI<LinksT> {
              public:
                using NodeIT = NodeI<LinksT>;
                using NodeIT::owners;
              };

              %template(OwnersInt) Owners<int>;
              %template(NodeIInt) NodeI<int>;
              %template(ClusterInt) Cluster<int>;

            The wrapped 'owners' member now uses the expanded member type, such as
            Owners<NodeI<int>::links_type> for Cluster<int>.  Previously the template
            parameter was left unexpanded as Owners<links_type>, which failed to
            compile.  The same applies to a member function parameter or return type
            written in terms of the base template parameter (#1153).

2026-06-16: wsfulton
            #1827 Fix a hang (infinite loop) when a class inherits from a base
            class named through a redundant self-referential typedef, such as:

              typedef struct foo foo;
              struct foo { };
              class bar : public foo { };

            The base class is now resolved correctly so the derived class
            inherits from it.

2026-06-15: wsfulton
            #2659 A base class can now be named from within a derived class without
            its namespace qualifier, as C++ allows (the base class name is a
            member of the base, visible from the derived class).  For example

              namespace Space {
                struct Base { ... };
              }
              struct Derived : Space::Base {
                typedef Base base_type;       // Base, not Space::Base
                using base_type::method;      // no longer Warning 315

                Base copy(Base b) { return b; }   // 'Base' is Space::Base
              };

              // The base named through the derived class is also Space::Base.
              Derived::Base make(Derived::Base b) { return b; }

            The method 'Derived::copy' and the global function 'make' are now
            wrapped, taking and returning a Space::Base.  Previously a using
            declaration naming the base through such a typedef gave a spurious
            'Nothing known about ...' warning (Warning 315) and the member was
            silently dropped, and a base class named as a type without its
            namespace qualifier was not recognised (it was unresolved, or treated
            as a different type from the base named in full).  Such a name -
            unqualified ('Base') or through the derived class ('Derived::Base') -
            now resolves to the base class' own type, so a Space::Base value can
            be passed to both 'copy' and 'make' above.

2026-06-14: wsfulton
            A using declaration that brings a base class member into a
            derived class through a typedef naming the base, such as

              struct Derived : Base {
                typedef Base base_type;
                using base_type::method;
              };

            now resolves when the base class declares a constructor of its own.
            Previously this gave a spurious 'Nothing known about ...' warning
            (Warning 315) and the member was silently dropped.

2026-06-13: larskanis, wsfulton
            [Ruby] #3465 #3467 Wrapped objects now use Ruby's embedded TypedData
            storage on Ruby 3.3 and later, so each wrapped object uses one fewer
            memory allocation.  Ruby 3.2 and earlier are unaffected.

2026-06-07: larskanis, jschueller
            [Ruby] #3170 #3326 #3456 Generated wrappers now use Ruby's TypedData API
            instead of the deprecated untyped Data API (Data_Wrap_Struct, Data_Get_Struct,
            DATA_PTR).  Ruby 3.4 warns about the untyped Data API by default
            (an error under -Werror) and Ruby 4.1 removes it entirely.

            This is not fully backwards compatible: hand written code (typically
            in a typemap or %extend block) that reached the wrapped C/C++ pointer
            through the removed Ruby DATA_PTR macro or Data_Get_Struct must be changed to
            use the SWIG conversion functions, which work with both old and new SWIG.
            Read the pointer with

              void *ptr = 0;
              SWIG_ConvertPtr(self, &ptr, NULL, 0);

            and detach (clear) it with

              SWIG_ConvertPtr(self, NULL, NULL, SWIG_POINTER_CLEAR);

            See Examples/test-suite/ruby_manual_proxy.i for a worked example.

            *** POTENTIAL INCOMPATIBILITY ***

2026-06-08: wsfulton
            Names referring to a C++ class nested inside another class now
            resolve even when the nested class itself is not wrapped (the usual
            case for all target languages except Java and C#).

            A using declaration whose scope qualifier reaches the nested class through
            a typedef, such as 'using Outer::Nested::Me::method;' where 'Me' is a
            typedef naming the nested class, now resolves instead of giving a
            spurious 'Nothing known about ...' warning (Warning 315) and silently
            dropping the member.

            An out of line nested class definition written inside the enclosing class,
            such as:

              struct Outer::Nested { ... };

            is likewise now resolved instead of reporting an 'Outer is not defined
            as a valid scope' error.

2026-06-04: Nerixyz
            [Python] #3414 Fix PEP 484 type annotations for multi-argument
            pytyping typemaps.  A typemap matching more than one argument, such
            as %typemap(pytyping) (int argc, char **argv), is now applied to the
            whole argument group, so the generated annotation uses the type from
            the typemap instead of only annotating the first argument with its
            plain C++ type.

2026-06-02: wsfulton
            #2694 Improve resolution of qualified names whose scope qualifier is
            reached through a typedef, including a typedef to a template
            instantiation.  A using declaration such as
            'using BaseAlias::Me::Integer;', where 'BaseAlias' and 'Me' are
            typedefs naming a class, previously gave a 'Nothing known about ...'
            warning (Warning 315).  This includes a typedef to a template
            instantiation whose template name is itself introduced by a using
            declaration.  It now resolves.

2026-06-01: wsfulton
            [Go] Fix crash (null pointer dereference) on the first call to a
            director method returning a reference or pointer type, such as
            int&, const int& or a class pointer.

2026-06-01: jschueller
            [Go] #3441 Fix director returning reference to local variable in int&
            and int&& typemaps.

2026-05-31: wsfulton
            [Ruby] #3385 Fix segmentation fault when using STL containers of
            swig::GC_VALUE - the type that wraps an arbitrary Ruby object - such
            as std::vector<swig::GC_VALUE> or a std::map or std::set with a
            swig::BinaryPredicate comparator proc, while the Ruby 3.x garbage
            collector compacts the heap (GC.compact or GC.auto_compact).  The
            Ruby objects stored in such containers are now retained correctly
            across a compaction, instead of occasionally crashing the interpreter.

2026-05-30: erezgeva
            [Lua] #3394 Drop support for Lua 5.0 and Lua 5.1.
            Minimum supported Lua version is now 5.2.
            SWIG no longer compiles wrappers for Lua 5.0 or 5.1
            (this includes LuaJIT consumers still using the 5.1 ABI).

            Removed -squash-bases command-line option
            (and the SWIG_LUA_SQUASH_BASES runtime path).
            The implementation was broken;
            classes now always use the standard base-lookup path.

            Using this command-line option will generate error

                swig error : Unrecognized option -squash-bases

            Removed deprecated -no-old-metatable-bindings command-line option.
            Old-style metatable bindings are always generated,
            matching the long-standing default.

            Using this command-line option will generate error

                swig error : Unrecognized option -no-old-metatable-bindings

            *** POTENTIAL INCOMPATIBILITY ***

2026-05-30: wsfulton
            C++17: parse user-defined deduction guides used for class
            template argument deduction, for example:

                template <typename T> struct Box { Box(T); };

                Box(int) -> Box<int>;                     // non-template deduction guide
                template <typename T> Box(T) -> Box<T>;   // templated deduction guide

            A guide is written at the same scope as the class template, either
            as a non-template declaration or, when itself a template, under a
            template parameter list.  A deduction guide is not a function and
            emits no symbol - it only steers argument deduction at compile time -
            so there is nothing to wrap and SWIG parses and ignores it.
            Previously any deduction guide resulted in a syntax error.

2026-05-28: wsfulton
            #2951 Inheriting constructors now work when the immediate base
            class is named through a typedef, including when that base is a
            template instantiation:

                struct D : C<A> {
                  typedef C<A> base_type;
                  using base_type::base_type;
                };

            Previously SWIG warned "Nothing known about 'base_type::base_type'"
            and wrapped only the default constructor, leaving the inherited
            constructors unavailable from the target language.

2026-05-28: wsfulton
            #2951 A using-declaration whose qualifier is a type-template
            parameter used directly as the base class - the mixin idiom -

                template <typename I>
                struct Derived : I {
                  using I::I;
                  using I::call;
                };

            now has its template parameter substituted during instantiation,
            so wrappers for the inherited members - including inheriting
            constructors via 'using I::I;' - are emitted on the instantiated
            derived class. Previously SWIG warned "Nothing known about
            'I::call'" and no wrapper was generated.

2026-05-27: wsfulton
            C++20: parse and support constrained alias templates.  Both the
            type-constraint shorthand and the requires-clause long form are
            now accepted:

              template<Numeric T>                       using NumBox = Box<T>;
              template<typename T> requires Numeric<T>  using ReqBox = Box<T>;

            The requires-clause form previously resulted in a syntax error.

            Both forms wrap identically to an unconstrained alias template.
            Note that the constraint does not affect the generated wrappers.
            The C++ compiler enforces it when compiling the emitted
            wrapper.  Wrapping continues to use the documented two-step
            pattern: %template(Name) on the underlying template, followed by
            an empty %template() for each alias.

2026-05-26: wsfulton
            [Python] Class docstrings under -builtin now match the non-builtin
            proxy module. When neither %feature("docstring") nor a doxygen
            comment is supplied, inspect.getdoc(MyClass) previously returned
            the qualified C++ name such as "::MyClass"; it now returns
            "Proxy of C++ MyClass class." (or "Proxy of C MyStruct struct.")
            when %feature("autodoc") is enabled, and the empty string
            otherwise. Alternative documentation strings can of course still
            be set via %feature("python:tp_doc", "...") on the class.

            *** POTENTIAL INCOMPATIBILITY ***

2026-05-25: wsfulton
            [Python] %nokwargs on an individual function now correctly opts that
            function out of keyword argument handling using the -keyword option
            or a module-wide %feature("kwargs") has enabled kwargs globally. The
            change is visible under -builtin, where the affected function's
            wrapper is now generated with METH_VARARGS instead of
            METH_VARARGS|METH_KEYWORDS, so calling it by keyword raises
            TypeError as expected. Previously, %nokwargs was silently ignored
            once -keyword was passed.

2026-05-25: wsfulton, jschueller
            #3448 Fix ccache-swig (and the bundled CCache test suite) failing
            cache lookups when used with Apple clang 21 or upstream LLVM
            clang 21.  These compilers now emit
                clang: warning: argument unused during compilation: '-c' [-Wunused-command-line-argument]
            when -c and -E are passed together.  ccache-swig invoked the
            preprocessor as "cc -c -E foo.c" and hashed its stderr, so the
            warning text was folded into the cache key and prevented a cache hit
            between compiling foo.c and the equivalent preprocessed foo.i.
            ccache-swig now omits -c when invoking the preprocessor.

2026-05-25: clintonstimpson
            #3425 Suppress unused function warnings in the generated code when
            compiling with Clang-CL.

2026-05-24: wsfulton
            Fixed a one-byte buffer overflow in the cdata.i memmove typemap that
            occurred when the data length exactly matched the destination buffer size.

2026-05-20: erezgeva
            [Guile, JavaScript, Python, Scilab, Tcl] #3383 The cdata.i library
            functions (cdata, memmove and similar) now use a binary data type
            instead of a string, so that all byte values 0-255 round-trip
            correctly.

            The target language type used by the cdata.i functions has changed:

              - Python:     bytes object (was str)
              - JavaScript: Uint8Array (was string)
              - Tcl:        list of integers (was string)
              - Scilab:     list of uint8 values (was string)

            In Python, passing a str now fails with:

                TypeError: in method 'memmove', argument 2 of type 'void const *'

            so pass a bytes object instead. Guile cdata now also handles all
            byte values correctly.

            *** POTENTIAL INCOMPATIBILITY ***

2026-05-19: jmarrec
            #3415 Fix segmentation fault when a class declares a public
            'using Base::method;' that names a base-class member template with
            no %template instantiations and also declares a protected concrete
            override of the same name.

2026-05-16: erezgeva
            [Lua, Octave, Perl, PHP, Python, Ruby, Scilab, Tcl] #3409 Add memory allocation
            failure protection to the argcargv typemaps and to the string duplication paths
            in pystrings.swg, perlstrings.swg, rubystrings.swg and rfragments.swg.

            Potentially incompatible change: the `%new_copy_array` macro
            has been removed. User interface files calling `%new_copy_array(ptr, size, T)`
            will be passed through to the C/C++ compiler unchanged and fail with
            an error such as:

                error: expected expression before '%' token

            Replace such calls with an explicit allocate and copy that checks
            for allocation failure, e.g.

                T *p = %new_array(size, T);
                if (p) memcpy(p, ptr, size * sizeof(T));

            Potentially incompatible change: the `%typemaps_string` macro in
            `Lib/typemaps/strings.swg` now takes an additional argument naming a
            `SWIG_NewCopyCharArray` style fragment, and the related
            `%typemaps_string_alloc` macro has been removed (its allocator
            customisation is now expressed by passing the new argument to
            `%typemaps_string` directly). Existing callers of
            `%typemaps_string` with the old signature will fail with:

                Error: Macro '%typemaps_string' expects 13 arguments

            Existing callers of `%typemaps_string_alloc` will fail with:

                Error: Unknown directive '%typemaps_string_alloc'.

            Update such calls to pass the additional fragment, modelled on
            `SWIG_NewCopyWCharArray` in `Lib/typemaps/wstring.swg`.

            *** POTENTIAL INCOMPATIBILITY ***

2026-05-16: akarantanapa
            [C#] #3406 Fix the std_wstring.i and wchar.i pointer initialisations
            so the generated code compiles as both C and C++.

2026-05-18: wsfulton
            [Python] Doxygen comments on constructors are now emitted on
            __init__ when wrapping with -builtin, matching the default
            (non-builtin) behaviour.  Previously inspect.getdoc(Cls.__init__)
            returned the generic "Initialize self.  See help(type(self)) for
            accurate signature." regardless of the Doxygen documentation on
            the C++ constructor.

2026-05-15: blowekamp
            [R] #3407 Fix compilation with R 4.6.0 which removed the non-API macro
            SET_S4_OBJECT and made CHARACTER_POINTER return a const pointer.
            Use Rf_asS4, SET_STRING_ELT and STRING_ELT instead. These replacement
            APIs have been available since R 2.x so no version guards are required.

2026-05-28: wsfulton
            C++17: parse and support pack expansion in a using-declaration
            (P0195), e.g.

              template <typename... Ts>
              struct Overloaded : Ts... {
                using Ts::operator()...;
              };

            The names introduced by the using-declaration depend on an
            unexpanded template parameter pack, so SWIG accepts the syntax
            but produces no wrappers until %template instantiates the
            class.  %template now expands the pack using-declaration into
            one concrete using-declaration per base type, so the
            instantiated proxy class has a wrapper for each inherited
            member - matching how an ordinary 'using Base::name;' inside
            a class template behaves after instantiation.

            Combined with %rename(call) *::operator(); the proxy of
            Overloaded<IntCase, DoubleCase> has overloaded call(int) and
            call(double) methods that dispatch to the matching base.

2026-05-14: wsfulton
            C++17: detect class template argument deduction (CTAD) in a
            variable declaration, where a variable is declared with a bare
            class template name and the template arguments are deduced from
            the initializer, e.g.

              template <typename T>
              struct Box {
                T value;
                Box(T v) : value(v) {}
              };

              Box bx{42};   // CTAD deduces Box<int> from the constructor

            (and, with C++20 P1816, also for aggregates with no deduction
            guide).  CTAD is only valid for variables, so this is the only
            declaration kind affected.  SWIG performs no template argument
            deduction, so it now issues Warning 347 and skips the variable
            instead of generating uncompilable wrapper code that names the
            template without arguments.

2026-05-14: wsfulton
            User-defined literal operators are now emitted without the space
            between the "" and the suffix, that is operator""_x rather than
            operator "" _x. The spaced form is deprecated in C++23 (CWG2521) and
            is an error under clang and MSVC with -Wdeprecated-literal-operator.

2026-05-14: wsfulton
            [Perl] Fix a -Wimplicit-const-int-float-conversion compiler warning in
            the generated code.

2026-05-12: wsfulton
            C++20: %template can now instantiate abbreviated function templates
            that mix 'auto' parameters with a variadic explicit template pack,
            e.g.

              template<typename... Ts>
              std::string f_mix(auto x, Ts... ys);
              %template(f_mix_isd) f_mix<int, std::string, double>;

            Per the C++20 standard ([dcl.fct]/19) the invented type template-
            parameter for each 'auto' parm is appended after the explicit list,
            so the %template argument list is bound positionally: leading
            non-variadic parameters first, the variadic pack absorbs the middle
            args, then one trailing arg per 'auto' in declaration order.  Above,
            Ts={int, std::string} (absorbed by the pack) and the trailing
            'double' binds to the invented parm for 'x', giving the effective
            wrapper signature as:

              f_mix(double x, int y1, std::string y2)

2026-05-12: wsfulton
            C++20: parse and support decorated 'auto' parameters in abbreviated
            function templates:

              int h(auto& x);                  // reference
              int i(auto* x);                  // pointer
              int j(auto&& x);                 // forwarding reference
              int k(const auto x);             // const by value
              int l(const auto& x);            // const reference
              int m(Numeric auto& x);          // constrained reference
              int n(const Numeric auto& x);    // const constrained reference

2026-05-12: wsfulton
            C++20: fix segmentation fault when mixing abbreviated function template
            'auto' parameters with an explicit template parameter list, e.g.

              template<typename T>
              T mix(T x, auto y) { return T(x + y); }
              %template(mix_id) mix<int, double>;

            Each 'auto' parameter introduces an invented type template parameter
            appended to the explicit template parameter list.  When using
            %template, supply arguments for the explicit parameters first, then
            one for each 'auto' parameter in declaration order.

2026-05-11: wsfulton
            C++20: warning 332 (unresolved type-constraint in a templated
            parameter list) is no longer emitted. The remap to 'typename T' is
            still applied silently, so wrappers continue to compile when the
            concept definition is visible only to the C++ compiler.

2026-05-10: wsfulton
            C++20: template parameters with a type-constraint now accept a
            template-id concept-id as the constraint, the form most often seen with
            STL concepts like 'std::convertible_to', 'std::same_as', 'std::derived_from'
            or 'std::predicate'. Examples:

              template<std::convertible_to<int> T> int to_int(T x);
              template<typename T, typename U> concept Pair = std::convertible_to<T, U>;
              template<Pair<int> T>                int first_int(T x);

2026-05-09: wsfulton
            C++20: parse abbreviated function templates with a constrained auto return
            type, including the trailing return form:

              Numeric auto half(int x) -> int { return x / 2; }
              Numeric auto cube_constrained(Sized auto x) -> int { return x*x*x; }
              %template(cube_constrained_int) cube_constrained<int>;

            When an explicit (non-auto) trailing return type is provided the function
            wraps normally (the trailing return is the wrapped type); without one, the
            function is ignored with a warning since SWIG cannot deduce the return type,
            matching plain 'auto fn(...)' behaviour.  As a side fix, plain 'auto
            fn(Concept auto x) -> Type' now correctly introduces an invented type template
            parameter for the auto parameter so '%template' instantiates it.

2026-05-09: wsfulton
            C++20: parse and support type-constraints on template parameters.
            'template<Numeric T>' is now accepted as the standard shorthand for
            'template<typename T> requires Numeric<T>', as per the C++20 standard. This includes
            ::-qualified concept-ids, variadic packs, default arguments and class templates.

              template<typename T>
              concept Numeric = std::integral<T> || std::floating_point<T>;

              template<Numeric T> T cube(T x) { return x * x * x; }
              %template(cube_int) cube<int>;

            If the type-constraint identifier has not been parsed by SWIG, the parameter
            is silently remapped to 'typename T'; the generated wrapper compiles when
            the concept is visible to the C++ compiler.

2026-05-09: wsfulton
            C++20: parse abbreviated function templates with constrained auto parameters.
            Each auto parameter with a type-constraint (e.g. 'Numeric auto') introduces
            an invented type template parameter carrying the type-constraint as a
            captured constraint.

              int twice_numeric(Numeric auto x) { return x + x; }
              %template(twice_numeric_int) twice_numeric<int>;

2026-05-09: wsfulton
            C++14: parse generic lambdas - lambdas with one or more 'auto' parameters.
            Like non-templated lambdas, generic lambdas are not wrapped, but they no
            longer cause a syntax error when SWIG parses a header that contains them.

              auto twice = [](auto x) { return x + x; };
              auto add = [](auto a, auto b) { return a + b; };

2026-05-09: wsfulton
            C++20: parse abbreviated function templates - ordinary functions with one or
            more 'auto' parameters. C++20 treats the function as a function template with
            invented type template parameters for each auto parameter. Abbreviated
            function templates can now be wrapped with %template, just like a regular
            templated function. Note that an explicit (non-auto) return type is required.
            The return type is not included in the %template instantiation and SWIG
            remains unable to deduce auto return types.

              double scale(auto x, auto factor) { return x * factor; }
              %template(scale_id) scale<int, double>;

2026-05-09: wsfulton
            #3413 C++20: accept prefix requires-clauses on templated lambdas, and trailing
            requires-clauses placed after the lambda's return type.

              auto prefix = []<typename T> requires Numeric<T> (T x) { return x + x; };

2026-05-07: wsfulton
            #3413 %template applied to a C++20 concept now reports an error instead of
            silently producing a malformed wrapper.

2026-05-05: wsfulton
            #3413 C++20: parse a requires-expression as a primary in expression position,
            not just inside a requires-clause.  This allows a namespace scope variable
            template to be initialised from a requires-expression.

              template<typename T>
              constexpr bool Addable = requires (T t) { t + t; };

              %template(addable_int) Addable<int>;

2026-05-05: wsfulton
            Document existing coverage for C++14 variable templates which requires a
            %template instantiation of the variable template, resulting in a read only
            variable wrapper.

              template<typename T>
              constexpr int bits_in = sizeof(T) * 8;

              %template(bits_in_char) bits_in<char>;

2026-05-04: wsfulton
            #3413 Basic support for C++20 concept declarations and requires-clauses on
            function templates, in both the trailing position and the prefix position
            (between the template parameter list and the declarator).  Both constructs are silently
            consumed: a concept declaration produces no parse tree node, and a constrained
            template wraps as if it were unconstrained.

              template<typename T>
              concept Numeric = std::integral<T> || std::floating_point<T>;

              template<typename T>
              T cube(T x) requires Numeric<T> { return x * x * x; }

              template<typename T>
              requires Numeric<T>
              T quad(T x) { return x * x * x * x; }

              template<typename T>
              concept Summable = requires (T t) { t + t; };
              template<typename T>
              T sum_pair(T a, T b) requires Summable<T> { return a + b; }

            Compound constraints containing trailing return type constraints also work:

              template<typename T>
              concept AddableSame = requires(T a, T b) {
                { a + b } -> std::same_as<T>;
              };

2026-05-03: wsfulton
            [R] Fix function pointer wrappers involving move-only types.

2026-05-02: mmomtchev, wsfulton
            #341 #3297 #3298 Add support for wrapping std::function via the SWIG library file
            std_function.i.  The partial specialization
            std::function<RET(ARGS...)> is wrapped so that a C++ callable
            (free function, lambda, bound member function or functor) can be
            returned from C++ to the target language and invoked there.

              %include <std_function.i>

              %inline %{
              std::function<bool(int, const std::string &)> MakeFunctor(int pass) {
                return [pass](int passcode, const std::string &name) -> bool {
                  return passcode == pass && name == "magic";
                };
              }
              %}

              %template(MyFunctor) std::function<bool(int, const std::string &)>;

            One %template instantiation is required per RET(ARGS...) signature.
            std_function.i renames operator() to call so that target languages
            which cannot wrap operator() as an identifier still get a usable
            method name, and ignores the default constructor so std::function
            instances always originate on the C++ side.  See the new section
            "std::function" in the SWIG library chapter of the documentation
            for the full pattern, limitations and target-language notes.

2026-05-01: wsfulton
            Fix partial template specialization where the specialized argument
            is a function type, including function types carrying a parameter
            pack. This makes std::function and similar wrappers work correctly,
            eg:

              template <typename> class function;
              template <typename RET, typename... ARGS>
                class function<RET(ARGS...)> { ... };
              %template(FuncIntInt)    function<int(int, int)>;
              %template(FuncVoid)      function<int()>;
              %template(FuncMixed)     function<int(int, double, int)>;

            Previously the primary template was incorrectly chosen for these
            instantiations.  The partial specialization is now matched, with
            the function return type and parameter list (including trailing
            parameter packs) bound correctly.  Lib/std/std_function.i has been
            updated to use the standard forward declaration of std::function.

2026-04-26: wsfulton
            Fix partial template specialization where the specialized argument
            is a templated type carrying a parameter pack, eg:

              template <typename...> struct Pack {};
              template <typename T> struct Foo {};
              template <typename... ARGS> struct Foo<Pack<ARGS...>> {};
              %template(FooEmpty) Foo<Pack<>>;
              %template(FooStr)   Foo<Pack<std::string>>;
              %template(FooMix)   Foo<Pack<int, double>>;

            Such partial specializations are now matched and instantiated
            correctly for any pack length, including the empty pack.

2026-04-25: wsfulton
            Advanced %rename fixes for templates. It is now possible to use %rename
            on instantiated templates for various corner cases, see "Template renaming"
            section in SWIGPlus.html. For example, it is now possible to selectively rename
            overloaded templated functions. The full power of %rename (such as using regex)
            can now be used on templates.

            Example fix using %rename on templates:
              namespace Quirky {
                template<typename T> void funky() {}
              }
              %rename("%s_void") Quirky::funky<int>();
              %template(funky_int) Quirky::funky<int>;
            Will now generate funky_void() where previously there there was no wrapper, just
            a warning:
                Warning 503: Can't wrap 'funky< int >_void' unless renamed to a valid identifier.

2026-04-17: jwuttke
            #3403 Fix -doxygen: @file block bleeding into the first class
            docstring. Single-line //! (or ///) comments forming a file-level
            header (starting with @file) are now correctly discarded instead of
            being concatenated into the next declaration's docstring.

2026-03-26: Nerixyz
            [Python] #3389 Add missing C annotations and PEP 484 annotations to constants.

2026-03-25: christophe-calmejane
            [Lua] #3387 Added support for std::shared_ptr and boost::shared_ptr.

2026-03-25: Nerixyz
            [Python] #3334 Add PEP 484 annotations for a few simple types - primitive
            types and C strings.

2026-03-23: christophe-calmejane
            [Lua] #3386 Add support for std::unordered_set and std::unordered_map.

2026-03-23: erezgeva
            [Go] #3360 Makefile support for using and testing Go on Windows.

2026-03-20: christophe-calmejane
            [Lua] #3306 Added support for nested classes.

2026-03-19: wsfulton
            [C#, D] Always initialise the return type in the C/C++ code. Users with custom
            typemaps may need to provide a valid initial value via the "null" attribute
            in the "out" typemap if 0 is not a valid initial value.

2026-03-19: erezgeva
            #3348 Avoid a potential segfault by handling a failed dynamic_cast in generated
            director code by instead throwing a language specific exception:
            "'self' is not a director".

2026-03-18: jschueller
            [JavaScript, Python, Ruby] #3372 Remove redundant semicolons in the
            generated director and iterator code to fix -Wextra-semi compiler
            warnings.

2026-03-18: erezgeva
            [OCaml] #3378 Fix the cdata.i library so the cdata and memmove functions
            return the raw C data correctly.

2026-03-10: xSetech
            [Python] #3365 Fix descriptor() type lookup when SwigPyIterator is renamed
            via #define for use in multiple modules.

2026-03-06: wsfulton
            [Java] #3354 Fully qualify generated Java interfaces when using the %interface
            and %nspace features.

2026-03-05: FilipAlg
            [C#] #3354 Fully qualify generated C# interfaces when using the %interface
            and %nspace features.

2026-03-05: christophe-calmejane
            [Lua] #3305 Added std::array and std::set support.

2026-03-04: wsfulton
            #3312 SWIG source code in Source directory is now formatted with clang-format.

            Supported versions of clang-format are 18 and later (tested up to and including
            version 22). Formatting is enforced in Github Actions so contributors to the
            source code base must use clang-format before raising Github pull requests.
            Separate formatting only commits are strongly discouraged; each commit should
            be correctly formatted when committing (or format only commits squashed into
            prior commits prior to pushing to Github).

            Please see docs in Doc/Manual/Extending.html.

            In order to the ease pain of working on git branches that were branched prior to the
            commit on master that reformatted the code (bbdec1f7), the following is suggested.
            1. Merge/rebase onto the prior commit bbdec1f7^
            2. Copy Source/.clang-format from bbdec1f7 into your working directory
            3. Run the identical commands specified in the bbdec1f7 commit message
            The branch should then merge cleanly onto bbdec1f7.

2026-02-28: ArtemKozak666
            [C#] #3321 Fix undefined behaviour in std::string_view directorin typemap.

2026-02-27: erezgeva
            Various improvements to Github Actions CI testing to increase coverage notably
            with additional Windows and MacOS testing including via CMake.

2026-02-27: phetdam
            #3191 #3332 Buiding SWIG executable with CMake enhancements.
            - Update PCRE2 find module to be compatible with upstream CMake config script.
            - Update docs for users wishing to use CMake to build SWIG.

2026-02-23: aryler
            #3304 Correct LDSHARED for OpenBSD.

2026-02-20: benzwick
            [Guile] #3336 Fix segfault in Guile -proxy when class has public member variable.

2026-02-20: benzwick
            #3337 Fix cross-module type cast lookup in SWIG_InitializeModule
            using multiple modules.

2026-02-11: degasus, wsfulton
            #3327 [Java, C#] Add missing Doxygen documentation comments to code using the
            %interface directives.

2026-02-07: wsfulton
            #3323 Fix -Wsign-compare warning in 32-bit builds in SWIG_TypeClientData.

2026-02-04: jschueller
            #3325 Add include guard when generating SWIG runtime header.

2026-01-21: jschueller
            #3019 Issue deprecation warning if `%typedef` is used.  This is
            an undocumented directive which SWIG has treated as an alias for
            the standard C/C++ `typedef` since at least 1996.  Replace any
            remaining uses with `typedef`, which also works with older SWIG
            versions.

2026-01-15: olly
            [Octave] Octave 6 is now the oldest version we aim to support.  We
            haven't had any automated testing of older Octave versions since
            GHA dropped support for Ubuntu 20.04 on 2025-04-01.

2026-01-15: jschueller
            [Octave] Fix save_binary prototype to be correct for Octave >= 6.

2025-12-17: ysmilda
            [Go] #3291 
               - Add `-unique-id` and `-no-unique-id` flags to enable/disable the addition of a
                 unique id to the generated function names.
               - Deprecate `-cgo` flag as this doesn't do anything.
               - Cleanup docs and help output.
               
2025-12-12: christophe-calmejane
            [Lua] #3295 Add director support for Lua.

2025-12-05: jaw
            [Python] #3287 Fixes for gcc warnings: -Wconversion -Wsign-conversion.

2025-11-08: wsfulton
            Fix handling of typedef to void in class methods/constructor's parameter
            lists, such as:

              typedef void VOID_TYPE;
              struct S {
                 S(VOID_TYPE);
                 int f(VOID_TYPE) const;
              };

2025-11-06: olly
            [Octave, Ruby] #3281 `FALSE` and `TRUE` are no longer treated as
            aliases of `false` and `true` when generating documentation comments.

2025-11-06: olly
            [PHP] Fix -Wunused compiler warnings for unused helper functions in the
            generated code.

2025-11-04: olly
            [Octave] Fix a -Wmisleading-indentation compiler warning in the generated
            code.

2025-11-02: wsfulton
            [Go] Fix various compilation problems when wrapping rvalues references.

2025-11-01: wsfulton
            Fix wrapping rvalue reference typedefs in director constructors.

2025-11-01: wsfulton
            Multiple typedefs involving references fix.

            If a typedef to a typedef of a reference was wrapped, uncompilable code was
            generated. Note: this was previously okay with just a single typedef to a
            reference. Affected wrapping global and member variables as well as parameters
            in member methods and constructors.

2025-10-27: wsfulton
            #3276 Add missing std::move when wrapping move constructors for directors.
            Also add missing std::move for wrapped director (virtual) methods with
            rvalue references.
