/tags/rel-1-3-30rc1-b4beautify/SWIG/Source/Modules/overload.cxx
C++ | 796 lines | 610 code | 75 blank | 111 comment | 182 complexity | 296a4f76b5e0820d32cffce2af94fd38 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
- /* -----------------------------------------------------------------------------
- * See the LICENSE file for information on copyright, usage and redistribution
- * of SWIG, and the README file for authors - http://www.swig.org/release.html.
- *
- * overload.cxx
- *
- * This file is used to analyze overloaded functions and methods.
- * It looks at signatures and tries to gather information for
- * building a dispatch function.
- * ----------------------------------------------------------------------------- */
- char cvsroot_overload_cxx[] = "$Header$";
- #include "swigmod.h"
- #define MAX_OVERLOAD 4096
- /* Overload "argc" and "argv" */
- String *argv_template_string;
- String *argc_template_string;
- struct Overloaded {
- Node *n; /* Node */
- int argc; /* Argument count */
- ParmList *parms; /* Parameters used for overload check */
- int error; /* Ambiguity error */
- };
- static int fast_dispatch_mode = 0;
- static int cast_dispatch_mode = 0;
- /* Set fast_dispatch_mode */
- void Wrapper_fast_dispatch_mode_set(int flag) {
- fast_dispatch_mode = flag;
- }
- void Wrapper_cast_dispatch_mode_set(int flag) {
- cast_dispatch_mode = flag;
- }
- /* -----------------------------------------------------------------------------
- * Swig_overload_rank()
- *
- * This function takes an overloaded declaration and creates a list that ranks
- * all overloaded methods in an order that can be used to generate a dispatch
- * function.
- * Slight difference in the way this function is used by scripting languages and
- * statically typed languages. The script languages call this method via
- * Swig_overload_dispatch() - where wrappers for all overloaded methods are generated,
- * however sometimes the code can never be executed. The non-scripting languages
- * call this method via Swig_overload_check() for each overloaded method in order
- * to determine whether or not the method should be wrapped. Note the slight
- * difference when overloading methods that differ by const only. The
- * scripting languages will ignore the const method, whereas the non-scripting
- * languages ignore the first method parsed.
- * ----------------------------------------------------------------------------- */
- static List *
- Swig_overload_rank(Node *n, bool script_lang_wrapping) {
- Overloaded nodes[MAX_OVERLOAD];
- int nnodes = 0;
- Node *o = Getattr(n,"sym:overloaded");
- Node *c;
- if (!o) return 0;
- c = o;
- while (c) {
- if (Getattr(c,"error")) {
- c = Getattr(c,"sym:nextSibling");
- continue;
- }
- /* if (SmartPointer && Getattr(c,"cplus:staticbase")) {
- c = Getattr(c,"sym:nextSibling");
- continue;
- } */
- /* Make a list of all the declarations (methods) that are overloaded with
- * this one particular method name */
- if (Getattr(c,"wrap:name")) {
- assert(nnodes < MAX_OVERLOAD);
- nodes[nnodes].n = c;
- nodes[nnodes].parms = Getattr(c,"wrap:parms");
- nodes[nnodes].argc = emit_num_required(nodes[nnodes].parms);
- nodes[nnodes].error = 0;
- nnodes++;
- }
- c = Getattr(c,"sym:nextSibling");
- }
-
- /* Sort the declarations by required argument count */
- {
- int i,j;
- for (i = 0; i < nnodes; i++) {
- for (j = i+1; j < nnodes; j++) {
- if (nodes[i].argc > nodes[j].argc) {
- Overloaded t = nodes[i];
- nodes[i] = nodes[j];
- nodes[j] = t;
- }
- }
- }
- }
- /* Sort the declarations by argument types */
- {
- int i,j;
- for (i = 0; i < nnodes-1; i++) {
- if (nodes[i].argc == nodes[i+1].argc) {
- for (j = i+1; (j < nnodes) && (nodes[j].argc == nodes[i].argc); j++) {
- Parm *p1 = nodes[i].parms;
- Parm *p2 = nodes[j].parms;
- int differ = 0;
- int num_checked = 0;
- while (p1 && p2 && (num_checked < nodes[i].argc)) {
- // Printf(stdout,"p1 = '%s', p2 = '%s'\n", Getattr(p1,"type"), Getattr(p2,"type"));
- if (checkAttribute(p1,"tmap:in:numinputs","0")) {
- p1 = Getattr(p1,"tmap:in:next");
- continue;
- }
- if (checkAttribute(p2,"tmap:in:numinputs","0")) {
- p2 = Getattr(p2,"tmap:in:next");
- continue;
- }
- String *t1 = Getattr(p1,"tmap:typecheck:precedence");
- String *t2 = Getattr(p2,"tmap:typecheck:precedence");
- if ((!t1) && (!nodes[i].error)) {
- Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[i].n), Getline(nodes[i].n),
- "Overloaded %s(%s) not supported (no type checking rule for '%s').\n",
- Getattr(nodes[i].n,"name"),ParmList_str_defaultargs(Getattr(nodes[i].n,"parms")),
- SwigType_str(Getattr(p1,"type"),0));
- nodes[i].error = 1;
- } else if ((!t2) && (!nodes[j].error)) {
- Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[j].n), Getline(nodes[j].n),
- "Overloaded %s(%s) not supported (no type checking rule for '%s').\n",
- Getattr(nodes[j].n,"name"),ParmList_str_defaultargs(Getattr(nodes[j].n,"parms")),
- SwigType_str(Getattr(p2,"type"),0));
- nodes[j].error = 1;
- }
- if (t1 && t2) {
- int t1v, t2v;
- t1v = atoi(Char(t1));
- t2v = atoi(Char(t2));
- differ = t1v-t2v;
- }
- else if (!t1 && t2) differ = 1;
- else if (t2 && !t1) differ = -1;
- else if (!t1 && !t2) differ = -1;
- num_checked++;
- if (differ > 0) {
- Overloaded t = nodes[i];
- nodes[i] = nodes[j];
- nodes[j] = t;
- break;
- } else if ((differ == 0) && (Strcmp(t1,"0") == 0)) {
- t1 = Getattr(p1,"ltype");
- if (!t1) {
- t1 = SwigType_ltype(Getattr(p1,"type"));
- if (Getattr(p1,"tmap:typecheck:SWIGTYPE")) {
- SwigType_add_pointer(t1);
- }
- Setattr(p1,"ltype",t1);
- }
- t2 = Getattr(p2,"ltype");
- if (!t2) {
- t2 = SwigType_ltype(Getattr(p2,"type"));
- if (Getattr(p2,"tmap:typecheck:SWIGTYPE")) {
- SwigType_add_pointer(t2);
- }
- Setattr(p2,"ltype",t2);
- }
- /* Need subtype check here. If t2 is a subtype of t1, then we need to change the
- order */
- if (SwigType_issubtype(t2,t1)) {
- Overloaded t = nodes[i];
- nodes[i] = nodes[j];
- nodes[j] = t;
- }
- if (Strcmp(t1,t2) != 0) {
- differ = 1;
- break;
- }
- } else if (differ) {
- break;
- }
- if (Getattr(p1,"tmap:in:next")) {
- p1 = Getattr(p1,"tmap:in:next");
- } else {
- p1 = nextSibling(p1);
- }
- if (Getattr(p2,"tmap:in:next")) {
- p2 = Getattr(p2,"tmap:in:next");
- } else {
- p2 = nextSibling(p2);
- }
- }
- if (!differ) {
- /* See if declarations differ by const only */
- String *d1 = Getattr(nodes[i].n,"decl");
- String *d2 = Getattr(nodes[j].n,"decl");
- if (d1 && d2) {
- String *dq1 = Copy(d1);
- String *dq2 = Copy(d2);
- if (SwigType_isconst(d1)) {
- Delete(SwigType_pop(dq1));
- }
- if (SwigType_isconst(d2)) {
- Delete(SwigType_pop(dq2));
- }
- if (Strcmp(dq1,dq2) == 0) {
-
- if (SwigType_isconst(d1) && !SwigType_isconst(d2)) {
- if (script_lang_wrapping) {
- // Swap nodes so that the const method gets ignored (shadowed by the non-const method)
- Overloaded t = nodes[i];
- nodes[i] = nodes[j];
- nodes[j] = t;
- }
- differ = 1;
- if (!nodes[j].error) {
- if (script_lang_wrapping) {
- Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n),
- "Overloaded %s(%s) const ignored. Non-const method at %s:%d used.\n",
- Getattr(nodes[j].n,"name"), ParmList_protostr(nodes[j].parms),
- Getfile(nodes[i].n), Getline(nodes[i].n));
- } else {
- if (!Getattr(nodes[j].n, "overload:ignore"))
- Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
- "Overloaded method %s(%s) ignored. Method %s(%s) const at %s:%d used.\n",
- Getattr(nodes[j].n,"name"), ParmList_protostr(nodes[j].parms),
- Getattr(nodes[i].n,"name"), ParmList_protostr(nodes[i].parms),
- Getfile(nodes[i].n), Getline(nodes[i].n));
- }
- }
- nodes[j].error = 1;
- } else if (!SwigType_isconst(d1) && SwigType_isconst(d2)) {
- differ = 1;
- if (!nodes[j].error) {
- if (script_lang_wrapping) {
- Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n),
- "Overloaded %s(%s) const ignored. Non-const method at %s:%d used.\n",
- Getattr(nodes[j].n,"name"), ParmList_protostr(nodes[j].parms),
- Getfile(nodes[i].n), Getline(nodes[i].n));
- } else {
- if (!Getattr(nodes[j].n, "overload:ignore"))
- Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
- "Overloaded method %s(%s) const ignored. Method %s(%s) at %s:%d used.\n",
- Getattr(nodes[j].n,"name"), ParmList_protostr(nodes[j].parms),
- Getattr(nodes[i].n,"name"), ParmList_protostr(nodes[i].parms),
- Getfile(nodes[i].n), Getline(nodes[i].n));
- }
- }
- nodes[j].error = 1;
- }
- }
- Delete(dq1);
- Delete(dq2);
- }
- }
- if (!differ) {
- if (!nodes[j].error) {
- if (script_lang_wrapping) {
- Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[j].n), Getline(nodes[j].n),
- "Overloaded %s(%s)%s is shadowed by %s(%s)%s at %s:%d.\n",
- Getattr(nodes[j].n,"name"), ParmList_protostr(nodes[j].parms),
- SwigType_isconst(Getattr(nodes[j].n,"decl")) ? " const" : "",
- Getattr(nodes[i].n,"name"), ParmList_protostr(nodes[i].parms),
- SwigType_isconst(Getattr(nodes[i].n,"decl")) ? " const" : "",
- Getfile(nodes[i].n),Getline(nodes[i].n));
- } else {
- if (!Getattr(nodes[j].n, "overload:ignore"))
- Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n),
- "Overloaded method %s(%s)%s ignored. Method %s(%s)%s at %s:%d used.\n",
- Getattr(nodes[j].n,"name"), ParmList_protostr(nodes[j].parms),
- SwigType_isconst(Getattr(nodes[j].n,"decl")) ? " const" : "",
- Getattr(nodes[i].n,"name"), ParmList_protostr(nodes[i].parms),
- SwigType_isconst(Getattr(nodes[i].n,"decl")) ? " const" : "",
- Getfile(nodes[i].n),Getline(nodes[i].n));
- }
- nodes[j].error = 1;
- }
- }
- }
- }
- }
- }
- List *result = NewList();
- {
- int i;
- for (i = 0; i < nnodes; i++) {
- if (nodes[i].error)
- Setattr(nodes[i].n, "overload:ignore", "1");
- Append(result,nodes[i].n);
- // Printf(stdout,"[ %d ] %s\n", i, ParmList_protostr(nodes[i].parms));
- // Swig_print_node(nodes[i].n);
- }
- }
- return result;
- }
- // /* -----------------------------------------------------------------------------
- // * print_typecheck()
- // * ----------------------------------------------------------------------------- */
- static bool
- print_typecheck(String *f, int j, Parm *pj) {
- char tmp[256];
- sprintf(tmp,Char(argv_template_string),j);
- String *tm = Getattr(pj,"tmap:typecheck");
- if (tm) {
- Replaceid(tm,Getattr(pj,"lname"),"_v");
- String *conv = Getattr(pj,"implicitconv");
- if (conv) {
- Replaceall(tm,"$implicitconv", conv);
- } else {
- Replaceall(tm,"$implicitconv", "0");
- }
- Replaceall(tm,"$input", tmp);
- Printv(f,tm,"\n",NIL);
- return true;
- }
- else
- return false;
- }
- /* -----------------------------------------------------------------------------
- * ReplaceFormat()
- * ----------------------------------------------------------------------------- */
- static String *
- ReplaceFormat (const String_or_char *fmt, int j) {
- String *lfmt = NewString (fmt);
- char buf[50];
- sprintf (buf, "%d", j);
- Replaceall (lfmt, "$numargs", buf);
- int i;
- String *commaargs = NewString ("");
- for (i=0; i < j; i++) {
- Printv (commaargs, ", ", NIL);
- Printf (commaargs, Char(argv_template_string), i);
- }
- Replaceall (lfmt, "$commaargs", commaargs);
- return lfmt;
- }
- /* -----------------------------------------------------------------------------
- * Swig_overload_dispatch()
- *
- * Generate a dispatch function. argc is assumed to hold the argument count.
- * argv is the argument vector.
- *
- * Note that for C++ class member functions, Swig_overload_dispatch() assumes
- * that argc includes the "self" argument and that the first element of argv[]
- * is the "self" argument. So for a member function:
- *
- * Foo::bar(int x, int y, int z);
- *
- * the argc should be 4 (not 3!) and the first element of argv[] would be
- * the appropriate scripting language reference to "self". For regular
- * functions (and static class functions) the argc and argv only include
- * the regular function arguments.
- * ----------------------------------------------------------------------------- */
- /*
- Cast dispatch mechanism.
- */
- String *
- Swig_overload_dispatch_cast(Node *n, const String_or_char *fmt, int *maxargs) {
- int i,j;
-
- *maxargs = 1;
- String *f = NewString("");
- String *sw = NewString("");
- Printf(f,"{\n");
- Printf(f,"unsigned long _index = 0;\n");
- Printf(f,"SWIG_TypeRank _rank = 0; \n");
- /* Get a list of methods ranked by precedence values and argument count */
- List *dispatch = Swig_overload_rank(n, true);
- int nfunc = Len(dispatch);
- /* Loop over the functions */
- bool emitcheck=1;
- for (i = 0; i < nfunc; i++) {
- int fn = 0;
- Node *ni = Getitem(dispatch,i);
- Parm *pi = Getattr(ni,"wrap:parms");
- int num_required = emit_num_required(pi);
- int num_arguments = emit_num_arguments(pi);
- if (num_arguments > *maxargs) *maxargs = num_arguments;
- int varargs = emit_isvarargs(pi);
-
- if (!varargs) {
- if (num_required == num_arguments) {
- Printf(f,"if (%s == %d) {\n", argc_template_string, num_required);
- } else {
- Printf(f,"if ((%s >= %d) && (%s <= %d)) {\n",
- argc_template_string, num_required,
- argc_template_string, num_arguments);
- }
- } else {
- Printf(f,"if (%s >= %d) {\n", argc_template_string, num_required);
- }
- Printf(f,"SWIG_TypeRank _ranki = 0;\n");
- Printf(f,"SWIG_TypeRank _rankm = 0;\n");
- if (num_arguments) Printf(f,"SWIG_TypeRank _pi = 1;\n");
- /* create a list with the wrappers that collide with the
- current one based on argument number */
- List *coll=NewList();
- for (int k=i+1; k<nfunc; k++) {
- Node *nk = Getitem(dispatch,k);
- Parm *pk = Getattr(nk,"wrap:parms");
- int nrk = emit_num_required(pk);
- int nak = emit_num_arguments(pk);
- if ((nrk>=num_required && nrk<=num_arguments) ||
- (nak>=num_required && nak<=num_arguments) ||
- (nrk<=num_required && nak>=num_arguments))
- Append(coll, nk);
- }
- // printf("overload: %s coll=%d\n", Char(Getattr(n, "sym:name")), Len(coll));
- int num_braces = 0;
- bool test=(num_arguments > 0);
- if (test) {
- int need_v = 1;
- j = 0;
- Parm *pj = pi;
- while (pj) {
- if (checkAttribute(pj,"tmap:in:numinputs","0")) {
- pj = Getattr(pj,"tmap:in:next");
- continue;
- }
- String *tm = Getattr(pj,"tmap:typecheck");
- if (tm) {
- /* normalise for comparison later */
- Replaceid(tm,Getattr(pj,"lname"),"_v");
- /* if all the wrappers have the same type check on this
- argument we can optimize it out */
- for (int k=0; k<Len(coll) && !emitcheck; k++) {
- Node *nk = Getitem(coll, k);
- Parm *pk = Getattr(nk,"wrap:parms");
- int nak=emit_num_arguments(pk);
- if (nak<=j) continue;
- int l=0;
- Parm *pl=pk;
- /* finds arg j on the collider wrapper */
- while(pl && l<=j) {
- if (checkAttribute(pl,"tmap:in:numinputs","0")) {
- pl = Getattr(pl,"tmap:in:next");
- continue;
- }
- if (l==j) {
- /* we are at arg j, so we compare the tmaps now */
- String *tml = Getattr(pl, "tmap:typecheck");
- /* normalise it before comparing */
- if (tml) Replaceid(tml,Getattr(pl,"lname"),"_v");
- if (!tml || Cmp(tm, tml)) emitcheck=1;
- //printf("tmap: %s[%d] (%d) => %s\n\n",
- // Char(Getattr(nk, "sym:name")),
- // l, emitcheck, tml?Char(tml):0);
- }
- Parm *pl1 = Getattr(pl,"tmap:in:next");
- if (pl1) pl = pl1;
- else pl = nextSibling(pl);
- l++;
- }
- }
- if (emitcheck) {
- if (need_v) {
- Printf(f,"int _v = 0;\n");
- need_v = 0;
- }
- if (j >= num_required) {
- Printf(f, "if (%s > %d) {\n", argc_template_string, j);
- num_braces++;
- }
- String *tmp=NewStringf(argv_template_string, j);
- String *conv = Getattr(pj,"implicitconv");
- if (conv) {
- Replaceall(tm,"$implicitconv", conv);
- } else {
- Replaceall(tm,"$implicitconv", "0");
- }
- Replaceall(tm,"$input", tmp);
- Printv(f,"{\n",tm,"}\n",NIL);
- fn = i + 1;
- Printf(f, "if (!_v) goto check_%d;\n", fn);
- Printf(f, "_ranki += _v*_pi;\n", fn);
- Printf(f, "_rankm += _pi;\n", fn);
- Printf(f, "_pi *= SWIG_MAXCASTRANK;\n", fn);
- }
- }
- if (!Getattr(pj,"tmap:in:SWIGTYPE") && Getattr(pj,"tmap:typecheck:SWIGTYPE")) {
- /* we emit a warning if the argument defines the 'in' typemap, but not the 'typecheck' one */
- Swig_warning(WARN_TYPEMAP_TYPECHECK_UNDEF, Getfile(ni), Getline(ni),
- "Overloaded %s(%s) with no explicit typecheck typemap for arg %d of type '%s'\n",
- Getattr(n,"name"),ParmList_str_defaultargs(pi),
- j+1, SwigType_str(Getattr(pj,"type"),0));
- }
- Parm *pj1 = Getattr(pj,"tmap:in:next");
- if (pj1) pj = pj1;
- else pj = nextSibling(pj);
- j++;
- }
- }
- /* close braces */
- for (/* empty */; num_braces > 0; num_braces--) Printf(f, "}\n");
- Printf(f,"if (!_index || (_ranki < _rank)) {\n",i+1);
- Printf(f," _rank = _ranki; _index = %d;\n",i+1);
- Printf(f," if (_rank == _rankm) goto dispatch;\n",i+1);
- Printf(f,"}\n",i+1);
- String *lfmt = ReplaceFormat (fmt, num_arguments);
- Printf(sw, "case %d:\n", i+1);
- Printf(sw, Char(lfmt),Getattr(ni,"wrap:name"));
- Printf(sw, "\n");
- Printf(f,"}\n"); /* braces closes "if" for this method */
- if (fn) Printf(f, "check_%d:\n\n", fn);
- Delete (lfmt);
- Delete(coll);
- }
- Delete(dispatch);
- Printf(f,"dispatch:\n");
- Printf(f,"switch(_index) {\n");
- Printf(f,"%s",sw);
- Printf(f,"}\n");
- Printf(f,"}\n");
- return f;
- }
- /*
- Fast dispatch mechanism, provided by Salvador Fandi~no Garc'ia (#930586).
- */
- String *
- Swig_overload_dispatch_fast(Node *n, const String_or_char *fmt, int *maxargs) {
- int i,j;
-
- *maxargs = 1;
- String *f = NewString("");
- /* Get a list of methods ranked by precedence values and argument count */
- List *dispatch = Swig_overload_rank(n, true);
- int nfunc = Len(dispatch);
- /* Loop over the functions */
- for (i = 0; i < nfunc; i++) {
- int fn = 0;
- Node *ni = Getitem(dispatch,i);
- Parm *pi = Getattr(ni,"wrap:parms");
- int num_required = emit_num_required(pi);
- int num_arguments = emit_num_arguments(pi);
- if (num_arguments > *maxargs) *maxargs = num_arguments;
- int varargs = emit_isvarargs(pi);
-
- if (!varargs) {
- if (num_required == num_arguments) {
- Printf(f,"if (%s == %d) {\n", argc_template_string, num_required);
- } else {
- Printf(f,"if ((%s >= %d) && (%s <= %d)) {\n",
- argc_template_string, num_required,
- argc_template_string, num_arguments);
- }
- } else {
- Printf(f,"if (%s >= %d) {\n", argc_template_string, num_required);
- }
- /* create a list with the wrappers that collide with the
- current one based on argument number */
- List *coll=NewList();
- for (int k=i+1; k<nfunc; k++) {
- Node *nk = Getitem(dispatch,k);
- Parm *pk = Getattr(nk,"wrap:parms");
- int nrk = emit_num_required(pk);
- int nak = emit_num_arguments(pk);
- if ((nrk>=num_required && nrk<=num_arguments) ||
- (nak>=num_required && nak<=num_arguments) ||
- (nrk<=num_required && nak>=num_arguments))
- Append(coll, nk);
- }
- // printf("overload: %s coll=%d\n", Char(Getattr(n, "sym:name")), Len(coll));
- int num_braces = 0;
- bool test=(Len(coll)>0 && num_arguments);
- if (test) {
- int need_v = 1;
- j = 0;
- Parm *pj = pi;
- while (pj) {
- if (checkAttribute(pj,"tmap:in:numinputs","0")) {
- pj = Getattr(pj,"tmap:in:next");
- continue;
- }
- String *tm = Getattr(pj,"tmap:typecheck");
- if (tm) {
- /* normalise for comparison later */
- Replaceid(tm,Getattr(pj,"lname"),"_v");
- /* if all the wrappers have the same type check on this
- argument we can optimize it out */
- bool emitcheck=0;
- for (int k=0; k<Len(coll) && !emitcheck; k++) {
- Node *nk = Getitem(coll, k);
- Parm *pk = Getattr(nk,"wrap:parms");
- int nak=emit_num_arguments(pk);
- if (nak<=j) continue;
- int l=0;
- Parm *pl=pk;
- /* finds arg j on the collider wrapper */
- while(pl && l<=j) {
- if (checkAttribute(pl,"tmap:in:numinputs","0")) {
- pl = Getattr(pl,"tmap:in:next");
- continue;
- }
- if (l==j) {
- /* we are at arg j, so we compare the tmaps now */
- String *tml = Getattr(pl, "tmap:typecheck");
- /* normalise it before comparing */
- if (tml) Replaceid(tml,Getattr(pl,"lname"),"_v");
- if (!tml || Cmp(tm, tml)) emitcheck=1;
- //printf("tmap: %s[%d] (%d) => %s\n\n",
- // Char(Getattr(nk, "sym:name")),
- // l, emitcheck, tml?Char(tml):0);
- }
- Parm *pl1 = Getattr(pl,"tmap:in:next");
- if (pl1) pl = pl1;
- else pl = nextSibling(pl);
- l++;
- }
- }
- if (emitcheck) {
- if (need_v) {
- Printf(f,"int _v = 0;\n");
- need_v = 0;
- }
- if (j >= num_required) {
- Printf(f, "if (%s > %d) {\n", argc_template_string, j);
- num_braces++;
- }
- String *tmp=NewStringf(argv_template_string, j);
- String *conv = Getattr(pj,"implicitconv");
- if (conv) {
- Replaceall(tm,"$implicitconv", conv);
- } else {
- Replaceall(tm,"$implicitconv", "0");
- }
- Replaceall(tm,"$input", tmp);
- Printv(f,"{\n",tm,"}\n",NIL);
- fn = i + 1;
- Printf(f, "if (!_v) goto check_%d;\n", fn);
- }
- }
- if (!Getattr(pj,"tmap:in:SWIGTYPE") && Getattr(pj,"tmap:typecheck:SWIGTYPE")) {
- /* we emit a warning if the argument defines the 'in' typemap, but not the 'typecheck' one */
- Swig_warning(WARN_TYPEMAP_TYPECHECK_UNDEF, Getfile(ni), Getline(ni),
- "Overloaded %s(%s) with no explicit typecheck typemap for arg %d of type '%s'\n",
- Getattr(n,"name"),ParmList_str_defaultargs(pi),
- j+1, SwigType_str(Getattr(pj,"type"),0));
- }
- Parm *pj1 = Getattr(pj,"tmap:in:next");
- if (pj1) pj = pj1;
- else pj = nextSibling(pj);
- j++;
- }
- }
- /* close braces */
- for (/* empty */; num_braces > 0; num_braces--) Printf(f, "}\n");
- String *lfmt = ReplaceFormat (fmt, num_arguments);
- Printf(f, Char(lfmt),Getattr(ni,"wrap:name"));
- Printf(f,"}\n"); /* braces closes "if" for this method */
- if (fn) Printf(f, "check_%d:\n\n", fn);
- Delete (lfmt);
- Delete(coll);
- }
- Delete(dispatch);
- return f;
- }
- String *
- Swig_overload_dispatch(Node *n, const String_or_char *fmt, int *maxargs) {
- if (fast_dispatch_mode || GetFlag(n,"feature:fastdispatch")) {
- return Swig_overload_dispatch_fast(n, fmt, maxargs);
- }
-
- int i,j;
-
- *maxargs = 1;
- String *f = NewString("");
- /* Get a list of methods ranked by precedence values and argument count */
- List *dispatch = Swig_overload_rank(n, true);
- int nfunc = Len(dispatch);
- /* Loop over the functions */
- for (i = 0; i < nfunc; i++) {
- Node *ni = Getitem(dispatch,i);
- Parm *pi = Getattr(ni,"wrap:parms");
- int num_required = emit_num_required(pi);
- int num_arguments = emit_num_arguments(pi);
- if (num_arguments > *maxargs) *maxargs = num_arguments;
- int varargs = emit_isvarargs(pi);
-
- if (!varargs) {
- if (num_required == num_arguments) {
- Printf(f,"if (%s == %d) {\n", argc_template_string, num_required);
- } else {
- Printf(f,"if ((%s >= %d) && (%s <= %d)) {\n",
- argc_template_string, num_required,
- argc_template_string, num_arguments);
- }
- } else {
- Printf(f,"if (%s >= %d) {\n", argc_template_string, num_required);
- }
- if (num_arguments) {
- Printf(f,"int _v;\n");
- }
-
- int num_braces = 0;
- j = 0;
- Parm *pj = pi;
- while (pj) {
- if (checkAttribute(pj,"tmap:in:numinputs","0")) {
- pj = Getattr(pj,"tmap:in:next");
- continue;
- }
- if (j >= num_required) {
- String *lfmt = ReplaceFormat (fmt, num_arguments);
- Printf(f, "if (%s <= %d) {\n", argc_template_string, j);
- Printf(f, Char(lfmt),Getattr(ni,"wrap:name"));
- Printf(f, "}\n");
- Delete (lfmt);
- }
- if (print_typecheck(f, j, pj)) {
- Printf(f, "if (_v) {\n");
- num_braces++;
- }
- if (!Getattr(pj,"tmap:in:SWIGTYPE") && Getattr(pj,"tmap:typecheck:SWIGTYPE")) {
- /* we emit a warning if the argument defines the 'in' typemap, but not the 'typecheck' one */
- Swig_warning(WARN_TYPEMAP_TYPECHECK_UNDEF, Getfile(ni), Getline(ni),
- "Overloaded %s(%s) with no explicit typecheck typemap for arg %d of type '%s'\n",
- Getattr(n,"name"),ParmList_str_defaultargs(pi),
- j+1, SwigType_str(Getattr(pj,"type"),0));
- }
- Parm *pk = Getattr(pj,"tmap:in:next");
- if (pk) pj = pk;
- else pj = nextSibling(pj);
- j++;
- }
- String *lfmt = ReplaceFormat (fmt, num_arguments);
- Printf(f, Char(lfmt),Getattr(ni,"wrap:name"));
- Delete (lfmt);
- /* close braces */
- for (/* empty */; num_braces > 0; num_braces--)
- Printf(f, "}\n");
- Printf(f,"}\n"); /* braces closes "if" for this method */
- }
- Delete(dispatch);
- return f;
- }
- /* -----------------------------------------------------------------------------
- * Swig_overload_check()
- * ----------------------------------------------------------------------------- */
- void Swig_overload_check(Node *n) {
- Swig_overload_rank(n, false);
- }