From a335fff2ec6303cb54d03596d266d2cff149f85d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 5 Dec 2021 20:49:20 +0100 Subject: [PATCH] Avoid errors due to generating identical overloads Add typecheck typemaps for primitive types and string and call Swig_overload_check() to ensure that we don't generate two wrappers functions taking the same "const char*" type if we have overloads taking it and "std::string" (or a reference) in the original code. --- Lib/c/c.swg | 84 ++++++++++++++++++++++++++++++++++++++++++++ Lib/c/std_string.i | 4 +++ Source/Modules/c.cxx | 8 +++++ 3 files changed, 96 insertions(+) diff --git a/Lib/c/c.swg b/Lib/c/c.swg index 67da4e96c..081955d51 100644 --- a/Lib/c/c.swg +++ b/Lib/c/c.swg @@ -239,6 +239,90 @@ same_action_all_primitive_types(out, "$result = $1;", "$result = *$1;") $result = ($1_ltype) 0; } +/* Typecheck typemaps - The purpose of these is merely to issue a warning for overloaded C++ functions + * that cannot be overloaded in the wrappers as more than one C++ type maps to a single C type */ + +%typecheck(SWIG_TYPECHECK_BOOL) + bool, + const bool & + "" + +%typecheck(SWIG_TYPECHECK_CHAR) + char, + const char & + "" + +%typecheck(SWIG_TYPECHECK_INT8) + signed char, + const signed char & + "" + +%typecheck(SWIG_TYPECHECK_UINT8) + unsigned char, + const unsigned char & + "" + +%typecheck(SWIG_TYPECHECK_INT16) + short, + const short & + "" + +%typecheck(SWIG_TYPECHECK_UINT16) + unsigned short, + const unsigned short & + "" + +%typecheck(SWIG_TYPECHECK_INT32) + int, + long, + const int &, + const long & + "" + +%typecheck(SWIG_TYPECHECK_UINT32) + unsigned int, + unsigned long, + const unsigned int &, + const unsigned long & + "" + +%typecheck(SWIG_TYPECHECK_INT64) + long long, + const long long & + "" + +%typecheck(SWIG_TYPECHECK_UINT64) + unsigned long long, + const unsigned long long & + "" + +%typecheck(SWIG_TYPECHECK_FLOAT) + float, + const float & + "" + +%typecheck(SWIG_TYPECHECK_DOUBLE) + double, + const double & + "" + +%typecheck(SWIG_TYPECHECK_STRING) + char *, + char *&, + char[ANY], + char[] + "" + +%typecheck(SWIG_TYPECHECK_POINTER) + SWIGTYPE, + SWIGTYPE *, + SWIGTYPE &, + SWIGTYPE &&, + SWIGTYPE *const&, + SWIGTYPE [], + SWIGTYPE (CLASS::*) + "" + #ifdef SWIG_CPPMODE %insert("runtime") %{ diff --git a/Lib/c/std_string.i b/Lib/c/std_string.i index cf2dee864..896fa7195 100644 --- a/Lib/c/std_string.i +++ b/Lib/c/std_string.i @@ -64,4 +64,8 @@ class string; $result = strdup(cppresult->c_str()); %} +// This is required to warn about clashes between the overloaded functions +// taking strings and raw pointers in the generated wrappers. +%typemap(typecheck) string, const string &, string *, string & = char *; + } diff --git a/Source/Modules/c.cxx b/Source/Modules/c.cxx index 199ca260a..3b6990d32 100644 --- a/Source/Modules/c.cxx +++ b/Source/Modules/c.cxx @@ -402,6 +402,14 @@ public: if (Checkattr(n, "storage", "friend")) return; + // Usually generating wrappers for overloaded methods is fine, but sometimes their types can clash after applying typemaps and in this case we have no + // choice but to avoid generating them, as otherwise we'd just generate uncompilable code. + if (Getattr(n, "sym:overloaded")) { + Swig_overload_check(n); + if (Getattr(n, "overload:ignore")) + return; + } + temp_ptr_setter set(&node_func_, n); // As mentioned elsewhere, we can't use Swig_storage_isstatic() here because the "storage" attribute is temporarily saved in another view when this