Rework std::initializer_list handling to warn about usage in any method, not just constructors. A typemap is used to issue the warning and can be overridden with user defined behaviour.
This commit is contained in:
parent
c8ff23de0c
commit
d613ef42f2
10 changed files with 259 additions and 134 deletions
|
|
@ -125,53 +125,133 @@ public:
|
|||
|
||||
<H3><a name="Cpp0x_Initializer_lists"></a>7.2.4 Initializer lists</H3>
|
||||
|
||||
|
||||
<p>
|
||||
Constructors using the std::initializer_list class are removed
|
||||
from the wrapped class because the only way to access such a
|
||||
constructor is at compile time using the initialization list syntax.
|
||||
Initializer lists are very much a C++ construct and not very accessible from wrappers.
|
||||
Initializer lists are very much a C++ compiler construct and are not very accessible from wrappers as
|
||||
they are intended for compile time initialization of classes using the special <tt>std::initializer_list</tt> type.
|
||||
SWIG detects usage of initializer lists and will emit a special informative warning each time one is used:
|
||||
</p>
|
||||
|
||||
<p>For now, if you want to fill the class components like this:</p>
|
||||
<div class="shell">
|
||||
<pre>
|
||||
example.i:33: Warning 476: Initialization using std::initializer_list.
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Initializer lists usually appear in constructors but can appear in any function or method.
|
||||
They often appear in constructors which are overloaded with alternative approaches to initializing a class,
|
||||
such as the std container's push_back method for adding elements to a container.
|
||||
The recommended approach then is to simply ignore the initializer-list constructor, for example:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
class A {
|
||||
%ignore Container::Container(std::initializer_list<int>);
|
||||
class Container {
|
||||
public:
|
||||
A( std::initializer_list<int> );
|
||||
Container(std::initializer_list<int>); // initializer-list constructor
|
||||
Container();
|
||||
void push_back(const int &);
|
||||
...
|
||||
};
|
||||
A a1 = {1,2,3,4};
|
||||
</pre></div>
|
||||
|
||||
<p>you could add another constructor using <tt>std::vector</tt> for example:</p>
|
||||
<p>Alternatively you could modify the class and add another constructor for initialization by some other means,
|
||||
for example by a <tt>std::vector</tt>:</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
class A {
|
||||
%include <std_vector.i>
|
||||
class Container {
|
||||
public:
|
||||
A( std::initializer_list<int> );
|
||||
A( std::vector<int> );
|
||||
Container(const std::vector<int> &);
|
||||
Container(std::initializer_list<int>); // initializer-list constructor
|
||||
Container();
|
||||
void push_back(const int &);
|
||||
...
|
||||
};
|
||||
A a1 = {1,2,3,4};
|
||||
</pre></div>
|
||||
|
||||
<p>And then construct it from your target language, for example, in Python:</p>
|
||||
<p>And then call this constructor from your target language, for example, in Python, the following will call the constructor taking the <tt>std::vector</tt>:</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
>>> a2 = A( [1,2,3,4] )
|
||||
>>> c = Container( [1,2,3,4] )
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
<tt>std::initializer_list</tt> is simply a container that can only be initialised at compile time.
|
||||
As such it is possible to write typemaps for a target language container to map onto
|
||||
<tt>std::initializer_list</tt>. However, this can only be done for a fixed number of elements ...
|
||||
there is no way to construct an initializer list with a variable number of arguments at runtime.
|
||||
This is not particularly flexible though outside of C++ static initialization,
|
||||
hence the need to provide an alternative for use from a target language.
|
||||
If you are unable to modify the class being wrapped, consider ignoring the initializer-list constructor and using
|
||||
%extend to add in an alternative constructor:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%include <std_vector.i>
|
||||
%extend Container {
|
||||
Container(const std::vector<int> &elements) {
|
||||
Container *c = new Container();
|
||||
for (int element : elements)
|
||||
c->push_back(element);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
%ignore Container::Container(std::initializer_list<int>);
|
||||
|
||||
class Container {
|
||||
public:
|
||||
Container(std::initializer_list<int>); // initializer-list constructor
|
||||
Container();
|
||||
void push_back(const int &);
|
||||
...
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
The above makes the wrappers look is as if the class had been declared as follows:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%include <std_vector.i>
|
||||
class Container {
|
||||
public:
|
||||
Container(const std::vector<int> &);
|
||||
// Container(std::initializer_list<int>); // initializer-list constructor (ignored)
|
||||
Container();
|
||||
void push_back(const int &);
|
||||
...
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
<tt>std::initializer_list</tt> is simply a container that can only be initialized at compile time.
|
||||
As it is just a C++ type, it is possible to write typemaps for a target language container to map onto
|
||||
<tt>std::initializer_list</tt>. However, this can only be done for a fixed number of elements as
|
||||
initializer lists are not designed to be constructed with a variable number of arguments at runtime.
|
||||
The example below is a very simple approach which ignores any parameters passed in and merely initializes
|
||||
with a fixed list of fixed integer values chosen at compile time:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%typemap(in) std::initializer_list<int> {
|
||||
$1 = {10, 20, 30, 40, 50};
|
||||
}
|
||||
class Container {
|
||||
public:
|
||||
Container(std::initializer_list<int>); // initializer-list constructor
|
||||
Container();
|
||||
void push_back(const int &);
|
||||
...
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
Any attempt at passing in values from the target language will be ignored and replaced by <tt>{10, 20, 30, 40, 50}</tt>.
|
||||
Needless to say, this approach is very limited, but could be improved upon, but only slightly.
|
||||
A typemap could be written to map a fixed number of elements on to the <tt>std::initializer_list</tt>,
|
||||
but with values decided at runtime.
|
||||
The typemaps would be target language specific.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Initializer lists can appear in any function or method, not just constructors.
|
||||
SWIG only ignores the constructors as this is where they commonly occur.
|
||||
Users are recommended to manually ignore any other methods using an initialization list with <tt>%ignore</tt>.
|
||||
Note that the default typemap for <tt>std::initializer_list</tt> does nothing but issue the warning
|
||||
and hence any user supplied typemaps will override it and suppress the warning.
|
||||
</p>
|
||||
|
||||
<H3><a name="Cpp0x_Uniform_initialization"></a>7.2.5 Uniform initialization</H3>
|
||||
|
|
|
|||
|
|
@ -497,6 +497,7 @@ example.i(4) : Syntax error in input.
|
|||
<li>471. Unable to use return type <em>type</em> in director method
|
||||
<li>474. Method <em>method</em> usage of the optimal attribute ignored in the out typemap as the following cannot be used to generate optimal code: <em>code</em>
|
||||
<li>475. Multiple calls to <em>method</em> might be generated due to optimal attribute usage in the out typemap.
|
||||
<li>476. Initialization using std::initializer_list.
|
||||
</ul>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -486,6 +486,7 @@ CPP0X_TEST_CASES = \
|
|||
cpp0x_explicit_conversion_operators \
|
||||
cpp0x_function_objects \
|
||||
cpp0x_initializer_list \
|
||||
cpp0x_initializer_list_extend \
|
||||
cpp0x_lambda_functions \
|
||||
cpp0x_null_pointer_constant \
|
||||
cpp0x_raw_string_literals \
|
||||
|
|
|
|||
|
|
@ -1,22 +1,34 @@
|
|||
/* This testcase checks whether SWIG correctly uses the new initializer_list
|
||||
/* This testcase shows a few simple ways to deal with the new initializer_list
|
||||
introduced in C++0x. */
|
||||
%module cpp0x_initializer_list
|
||||
%warnfilter(SWIGWARN_LANG_INITIALIZER_LIST) A;
|
||||
|
||||
%warnfilter(SWIGWARN_TYPEMAP_INITIALIZER_LIST) B::B;
|
||||
%ignore A::A(std::initializer_list<int>);
|
||||
%ignore B::method;
|
||||
|
||||
%typemap(in) std::initializer_list<const char *> {
|
||||
$1 = {"Ab", "Fab"};
|
||||
}
|
||||
|
||||
%inline %{
|
||||
#include <initializer_list>
|
||||
|
||||
class A {
|
||||
public:
|
||||
A( std::initializer_list<int> ) {}
|
||||
A(std::initializer_list<int>) {}
|
||||
A() {}
|
||||
A(double d) {}
|
||||
};
|
||||
class B {
|
||||
public:
|
||||
B( std::initializer_list<int>, std::initializer_list<double> ) {}
|
||||
B(std::initializer_list<int>, std::initializer_list<double>) {}
|
||||
B() {}
|
||||
void method(std::initializer_list<int> init) {}
|
||||
};
|
||||
class C {
|
||||
public:
|
||||
C(std::initializer_list<const char *>) {}
|
||||
C() {}
|
||||
};
|
||||
%}
|
||||
|
||||
|
|
|
|||
29
Examples/test-suite/cpp0x_initializer_list_extend.i
Normal file
29
Examples/test-suite/cpp0x_initializer_list_extend.i
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/* This testcase shows how to replace std_initializer_list with std_vector. */
|
||||
|
||||
%module cpp0x_initializer_list_extend
|
||||
|
||||
%ignore Container::Container(std::initializer_list<int>);
|
||||
%include <std_vector.i>
|
||||
%template(VectorInt) std::vector<int>;
|
||||
|
||||
%extend Container {
|
||||
Container(const std::vector<int> &elements) {
|
||||
Container *c = new Container();
|
||||
for (int element : elements)
|
||||
c->push_back(element);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
%inline %{
|
||||
#include <initializer_list>
|
||||
|
||||
class Container {
|
||||
public:
|
||||
Container(std::initializer_list<int>) {}
|
||||
Container() {}
|
||||
void push_back(const int&) {}
|
||||
};
|
||||
%}
|
||||
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
import cpp0x_initializer_list_extend
|
||||
|
||||
c = cpp0x_initializer_list_extend.Container( [10, 20, 30, 40] )
|
||||
|
||||
169
Lib/swig.swg
169
Lib/swig.swg
|
|
@ -309,6 +309,88 @@ static int NAME(TYPE x) {
|
|||
|
||||
%include <swigwarnings.swg>
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Overloading support
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Function/method overloading support. This is done through typemaps,
|
||||
* but also involve a precedence level.
|
||||
*/
|
||||
|
||||
/* Macro for overload resolution */
|
||||
|
||||
%define %typecheck(_x...) %typemap(typecheck, precedence=_x) %enddef
|
||||
|
||||
/* Macros for precedence levels */
|
||||
|
||||
%define SWIG_TYPECHECK_POINTER 0 %enddef
|
||||
%define SWIG_TYPECHECK_ITERATOR 5 %enddef
|
||||
%define SWIG_TYPECHECK_VOIDPTR 10 %enddef
|
||||
%define SWIG_TYPECHECK_BOOL 15 %enddef
|
||||
%define SWIG_TYPECHECK_UINT8 20 %enddef
|
||||
%define SWIG_TYPECHECK_INT8 25 %enddef
|
||||
%define SWIG_TYPECHECK_UINT16 30 %enddef
|
||||
%define SWIG_TYPECHECK_INT16 35 %enddef
|
||||
%define SWIG_TYPECHECK_UINT32 40 %enddef
|
||||
%define SWIG_TYPECHECK_INT32 45 %enddef
|
||||
%define SWIG_TYPECHECK_SIZE 47 %enddef
|
||||
%define SWIG_TYPECHECK_PTRDIFF 48 %enddef
|
||||
%define SWIG_TYPECHECK_UINT64 50 %enddef
|
||||
%define SWIG_TYPECHECK_INT64 55 %enddef
|
||||
%define SWIG_TYPECHECK_UINT128 60 %enddef
|
||||
%define SWIG_TYPECHECK_INT128 65 %enddef
|
||||
%define SWIG_TYPECHECK_INTEGER 70 %enddef
|
||||
%define SWIG_TYPECHECK_FLOAT 80 %enddef
|
||||
%define SWIG_TYPECHECK_DOUBLE 90 %enddef
|
||||
%define SWIG_TYPECHECK_CPLXFLT 95 %enddef
|
||||
%define SWIG_TYPECHECK_CPLXDBL 100 %enddef
|
||||
%define SWIG_TYPECHECK_COMPLEX 105 %enddef
|
||||
%define SWIG_TYPECHECK_UNICHAR 110 %enddef
|
||||
%define SWIG_TYPECHECK_STDUNISTRING 115 %enddef
|
||||
%define SWIG_TYPECHECK_UNISTRING 120 %enddef
|
||||
%define SWIG_TYPECHECK_CHAR 130 %enddef
|
||||
%define SWIG_TYPECHECK_STDSTRING 135 %enddef
|
||||
%define SWIG_TYPECHECK_STRING 140 %enddef
|
||||
%define SWIG_TYPECHECK_PAIR 150 %enddef
|
||||
%define SWIG_TYPECHECK_VECTOR 160 %enddef
|
||||
%define SWIG_TYPECHECK_DEQUE 170 %enddef
|
||||
%define SWIG_TYPECHECK_LIST 180 %enddef
|
||||
%define SWIG_TYPECHECK_SET 190 %enddef
|
||||
%define SWIG_TYPECHECK_MULTISET 200 %enddef
|
||||
%define SWIG_TYPECHECK_MAP 210 %enddef
|
||||
%define SWIG_TYPECHECK_MULTIMAP 220 %enddef
|
||||
%define SWIG_TYPECHECK_STACK 230 %enddef
|
||||
%define SWIG_TYPECHECK_QUEUE 240 %enddef
|
||||
|
||||
%define SWIG_TYPECHECK_BOOL_ARRAY 1015 %enddef
|
||||
%define SWIG_TYPECHECK_INT8_ARRAY 1025 %enddef
|
||||
%define SWIG_TYPECHECK_INT16_ARRAY 1035 %enddef
|
||||
%define SWIG_TYPECHECK_INT32_ARRAY 1045 %enddef
|
||||
%define SWIG_TYPECHECK_INT64_ARRAY 1055 %enddef
|
||||
%define SWIG_TYPECHECK_INT128_ARRAY 1065 %enddef
|
||||
%define SWIG_TYPECHECK_FLOAT_ARRAY 1080 %enddef
|
||||
%define SWIG_TYPECHECK_DOUBLE_ARRAY 1090 %enddef
|
||||
%define SWIG_TYPECHECK_CHAR_ARRAY 1130 %enddef
|
||||
%define SWIG_TYPECHECK_STRING_ARRAY 1140 %enddef
|
||||
%define SWIG_TYPECHECK_OBJECT_ARRAY 1150 %enddef
|
||||
|
||||
%define SWIG_TYPECHECK_BOOL_PTR 2015 %enddef
|
||||
%define SWIG_TYPECHECK_UINT8_PTR 2020 %enddef
|
||||
%define SWIG_TYPECHECK_INT8_PTR 2025 %enddef
|
||||
%define SWIG_TYPECHECK_UINT16_PTR 2030 %enddef
|
||||
%define SWIG_TYPECHECK_INT16_PTR 2035 %enddef
|
||||
%define SWIG_TYPECHECK_UINT32_PTR 2040 %enddef
|
||||
%define SWIG_TYPECHECK_INT32_PTR 2045 %enddef
|
||||
%define SWIG_TYPECHECK_UINT64_PTR 2050 %enddef
|
||||
%define SWIG_TYPECHECK_INT64_PTR 2055 %enddef
|
||||
%define SWIG_TYPECHECK_FLOAT_PTR 2080 %enddef
|
||||
%define SWIG_TYPECHECK_DOUBLE_PTR 2090 %enddef
|
||||
%define SWIG_TYPECHECK_CHAR_PTR 2130 %enddef
|
||||
|
||||
%define SWIG_TYPECHECK_SWIGOBJECT 5000 %enddef
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Default handling of certain overloaded operators
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
|
@ -340,6 +422,10 @@ static int NAME(TYPE x) {
|
|||
|
||||
/* Define std namespace */
|
||||
namespace std {
|
||||
/* Warn about std::initializer_list usage. The constructor/method where used should probably be ignored. See docs. */
|
||||
template<typename T> class initializer_list {};
|
||||
%typemap(in, warning=SWIGWARN_TYPEMAP_INITIALIZER_LIST_MSG) initializer_list<T> ""
|
||||
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER) initializer_list<T> ""
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -500,89 +586,6 @@ namespace std {
|
|||
}
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Overloading support
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Function/method overloading support. This is done through typemaps,
|
||||
* but also involve a precedence level.
|
||||
*/
|
||||
|
||||
/* Macro for overload resolution */
|
||||
|
||||
%define %typecheck(_x...) %typemap(typecheck, precedence=_x) %enddef
|
||||
|
||||
/* Macros for precedence levels */
|
||||
|
||||
%define SWIG_TYPECHECK_POINTER 0 %enddef
|
||||
%define SWIG_TYPECHECK_ITERATOR 5 %enddef
|
||||
%define SWIG_TYPECHECK_VOIDPTR 10 %enddef
|
||||
%define SWIG_TYPECHECK_BOOL 15 %enddef
|
||||
%define SWIG_TYPECHECK_UINT8 20 %enddef
|
||||
%define SWIG_TYPECHECK_INT8 25 %enddef
|
||||
%define SWIG_TYPECHECK_UINT16 30 %enddef
|
||||
%define SWIG_TYPECHECK_INT16 35 %enddef
|
||||
%define SWIG_TYPECHECK_UINT32 40 %enddef
|
||||
%define SWIG_TYPECHECK_INT32 45 %enddef
|
||||
%define SWIG_TYPECHECK_SIZE 47 %enddef
|
||||
%define SWIG_TYPECHECK_PTRDIFF 48 %enddef
|
||||
%define SWIG_TYPECHECK_UINT64 50 %enddef
|
||||
%define SWIG_TYPECHECK_INT64 55 %enddef
|
||||
%define SWIG_TYPECHECK_UINT128 60 %enddef
|
||||
%define SWIG_TYPECHECK_INT128 65 %enddef
|
||||
%define SWIG_TYPECHECK_INTEGER 70 %enddef
|
||||
%define SWIG_TYPECHECK_FLOAT 80 %enddef
|
||||
%define SWIG_TYPECHECK_DOUBLE 90 %enddef
|
||||
%define SWIG_TYPECHECK_CPLXFLT 95 %enddef
|
||||
%define SWIG_TYPECHECK_CPLXDBL 100 %enddef
|
||||
%define SWIG_TYPECHECK_COMPLEX 105 %enddef
|
||||
%define SWIG_TYPECHECK_UNICHAR 110 %enddef
|
||||
%define SWIG_TYPECHECK_STDUNISTRING 115 %enddef
|
||||
%define SWIG_TYPECHECK_UNISTRING 120 %enddef
|
||||
%define SWIG_TYPECHECK_CHAR 130 %enddef
|
||||
%define SWIG_TYPECHECK_STDSTRING 135 %enddef
|
||||
%define SWIG_TYPECHECK_STRING 140 %enddef
|
||||
%define SWIG_TYPECHECK_PAIR 150 %enddef
|
||||
%define SWIG_TYPECHECK_VECTOR 160 %enddef
|
||||
%define SWIG_TYPECHECK_DEQUE 170 %enddef
|
||||
%define SWIG_TYPECHECK_LIST 180 %enddef
|
||||
%define SWIG_TYPECHECK_SET 190 %enddef
|
||||
%define SWIG_TYPECHECK_MULTISET 200 %enddef
|
||||
%define SWIG_TYPECHECK_MAP 210 %enddef
|
||||
%define SWIG_TYPECHECK_MULTIMAP 220 %enddef
|
||||
%define SWIG_TYPECHECK_STACK 230 %enddef
|
||||
%define SWIG_TYPECHECK_QUEUE 240 %enddef
|
||||
|
||||
%define SWIG_TYPECHECK_BOOL_ARRAY 1015 %enddef
|
||||
%define SWIG_TYPECHECK_INT8_ARRAY 1025 %enddef
|
||||
%define SWIG_TYPECHECK_INT16_ARRAY 1035 %enddef
|
||||
%define SWIG_TYPECHECK_INT32_ARRAY 1045 %enddef
|
||||
%define SWIG_TYPECHECK_INT64_ARRAY 1055 %enddef
|
||||
%define SWIG_TYPECHECK_INT128_ARRAY 1065 %enddef
|
||||
%define SWIG_TYPECHECK_FLOAT_ARRAY 1080 %enddef
|
||||
%define SWIG_TYPECHECK_DOUBLE_ARRAY 1090 %enddef
|
||||
%define SWIG_TYPECHECK_CHAR_ARRAY 1130 %enddef
|
||||
%define SWIG_TYPECHECK_STRING_ARRAY 1140 %enddef
|
||||
%define SWIG_TYPECHECK_OBJECT_ARRAY 1150 %enddef
|
||||
|
||||
%define SWIG_TYPECHECK_BOOL_PTR 2015 %enddef
|
||||
%define SWIG_TYPECHECK_UINT8_PTR 2020 %enddef
|
||||
%define SWIG_TYPECHECK_INT8_PTR 2025 %enddef
|
||||
%define SWIG_TYPECHECK_UINT16_PTR 2030 %enddef
|
||||
%define SWIG_TYPECHECK_INT16_PTR 2035 %enddef
|
||||
%define SWIG_TYPECHECK_UINT32_PTR 2040 %enddef
|
||||
%define SWIG_TYPECHECK_INT32_PTR 2045 %enddef
|
||||
%define SWIG_TYPECHECK_UINT64_PTR 2050 %enddef
|
||||
%define SWIG_TYPECHECK_INT64_PTR 2055 %enddef
|
||||
%define SWIG_TYPECHECK_FLOAT_PTR 2080 %enddef
|
||||
%define SWIG_TYPECHECK_DOUBLE_PTR 2090 %enddef
|
||||
%define SWIG_TYPECHECK_CHAR_PTR 2130 %enddef
|
||||
|
||||
|
||||
%define SWIG_TYPECHECK_SWIGOBJECT 5000 %enddef
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Runtime code
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
%define SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG "454:Setting a pointer/reference variable may leak memory." %enddef
|
||||
%define SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG "470:Thread/reentrant unsafe wrapping, consider returning by value instead." %enddef
|
||||
%define SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG "473:Returning a pointer or reference in a director method is not recommended." %enddef
|
||||
%define SWIGWARN_TYPEMAP_INITIALIZER_LIST_MSG "476:Initialization using std::initializer_list." %enddef
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Operator related warning messages
|
||||
|
|
|
|||
|
|
@ -4635,27 +4635,21 @@ cpp_member : c_declaration { $$ = $1; }
|
|||
|
||||
cpp_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end {
|
||||
if (Classprefix) {
|
||||
if ($4 && Getattr($4,"type") && strstr(Char(Getattr($4,"type")), "initializer_list<")) {
|
||||
/* Ignore constructors containing initializer_list<> introduced in C++0x */
|
||||
Swig_warning(WARN_LANG_INITIALIZER_LIST, cparse_file, cparse_line, "Constructor with std::initializer_list<> argument ignored.\n");
|
||||
$$ = 0;
|
||||
} else {
|
||||
SwigType *decl = NewStringEmpty();
|
||||
$$ = new_node("constructor");
|
||||
Setattr($$,"storage",$1);
|
||||
Setattr($$,"name",$2);
|
||||
Setattr($$,"parms",$4);
|
||||
SwigType_add_function(decl,$4);
|
||||
Setattr($$,"decl",decl);
|
||||
Setattr($$,"throws",$6.throws);
|
||||
Setattr($$,"throw",$6.throwf);
|
||||
if (Len(scanner_ccode)) {
|
||||
String *code = Copy(scanner_ccode);
|
||||
Setattr($$,"code",code);
|
||||
Delete(code);
|
||||
}
|
||||
SetFlag($$,"feature:new");
|
||||
}
|
||||
SwigType *decl = NewStringEmpty();
|
||||
$$ = new_node("constructor");
|
||||
Setattr($$,"storage",$1);
|
||||
Setattr($$,"name",$2);
|
||||
Setattr($$,"parms",$4);
|
||||
SwigType_add_function(decl,$4);
|
||||
Setattr($$,"decl",decl);
|
||||
Setattr($$,"throws",$6.throws);
|
||||
Setattr($$,"throw",$6.throwf);
|
||||
if (Len(scanner_ccode)) {
|
||||
String *code = Copy(scanner_ccode);
|
||||
Setattr($$,"code",code);
|
||||
Delete(code);
|
||||
}
|
||||
SetFlag($$,"feature:new");
|
||||
} else {
|
||||
$$ = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -174,6 +174,7 @@
|
|||
#define WARN_TYPEMAP_DIRECTOROUT_PTR 473
|
||||
#define WARN_TYPEMAP_OUT_OPTIMAL_IGNORED 474
|
||||
#define WARN_TYPEMAP_OUT_OPTIMAL_MULTIPLE 475
|
||||
#define WARN_TYPEMAP_INITIALIZER_LIST 476
|
||||
|
||||
/* -- Fragments -- */
|
||||
#define WARN_FRAGMENT_NOT_FOUND 490
|
||||
|
|
@ -201,7 +202,6 @@
|
|||
#define WARN_LANG_TEMPLATE_METHOD_IGNORE 519
|
||||
#define WARN_LANG_SMARTPTR_MISSING 520
|
||||
#define WARN_LANG_ILLEGAL_DESTRUCTOR 521
|
||||
#define WARN_LANG_INITIALIZER_LIST 522
|
||||
|
||||
/* -- Reserved (600-799) -- */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue