void Swig_print_tree(DOH *obj) { while (obj) { Swig_print_node(obj); obj = nextSibling(obj); } }
Node *Swig_cparse_template_locate(String *name, Parm *tparms, Symtab *tscope) { Node *n = template_locate(name, tparms, tscope); /* this function does what we want for templated classes */ if (n) { String *nodeType = nodeType(n); int isclass = 0; assert(Equal(nodeType, "template")); isclass = (Equal(Getattr(n, "templatetype"), "class")); if (!isclass) { /* If not a templated class we must have a templated function. The template found is not necessarily the one we want when dealing with templated functions. We don't want any specialized templated functions as they won't have the default parameters. Lets look for the unspecialized template. Also make sure the number of template parameters is correct as it is possible to overload a templated function with different numbers of template parameters. */ if (template_debug) { Printf(stdout, " Not a templated class, seeking most appropriate templated function\n"); } n = Swig_symbol_clookup_local(name, 0); while (n) { Parm *tparmsfound = Getattr(n, "templateparms"); if (ParmList_len(tparms) == ParmList_len(tparmsfound)) { /* successful match */ break; } /* repeat until we find a match with correct number of templated parameters */ n = Getattr(n, "sym:nextSibling"); } if (!n) { Swig_error(cparse_file, cparse_line, "Template '%s' undefined.\n", name); } if ((template_debug) && (n)) { Printf(stdout, "Templated function found: %p\n", n); Swig_print_node(n); } } } return n; }
static Node *template_locate(String *name, Parm *tparms, Symtab *tscope) { Node *n; String *tname, *rname = 0; Node *templ; List *mpartials = 0; Parm *p; Parm *parms; Parm *targs; ParmList *expandedparms; tname = Copy(name); parms = CopyParmList(tparms); /* Search for generic template */ templ = Swig_symbol_clookup(name, 0); /* Add default values from generic template */ if (templ) { Symtab *tsdecl = Getattr(templ, "sym:symtab"); targs = Getattr(templ, "templateparms"); expandedparms = Swig_symbol_template_defargs(parms, targs, tscope, tsdecl); } else { expandedparms = parms; } /* reduce the typedef */ p = expandedparms; while (p) { SwigType *ty = Getattr(p, "type"); if (ty) { SwigType *nt = Swig_symbol_type_qualify(ty, tscope); Setattr(p, "type", nt); Delete(nt); } p = nextSibling(p); } SwigType_add_template(tname, expandedparms); if (template_debug) { Printf(stdout, "\n%s:%d: template_debug: Searching for %s\n", cparse_file, cparse_line, tname); } /* Search for an exact specialization. Example: template<> class name<int> { ... } */ { if (template_debug) { Printf(stdout, " searching: '%s' (exact specialization)\n", tname); } n = Swig_symbol_clookup_local(tname, 0); if (!n) { SwigType *rname = Swig_symbol_typedef_reduce(tname, tscope); if (!Equal(rname, tname)) { if (template_debug) { Printf(stdout, " searching: '%s' (exact specialization)\n", rname); } n = Swig_symbol_clookup_local(rname, 0); } Delete(rname); } if (n) { Node *tn; String *nodeType = nodeType(n); if (Equal(nodeType, "template")) goto success; tn = Getattr(n, "template"); if (tn) { n = tn; goto success; /* Previously wrapped by a template return that */ } Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType(n)); Delete(tname); Delete(parms); return 0; /* Found a match, but it's not a template of any kind. */ } } /* Search for partial specialization. Example: template<typename T> class name<T *> { ... } */ /* Generate reduced template name (stripped of extraneous pointers, etc.) */ rname = NewStringf("%s<(", name); p = parms; while (p) { String *t; t = Getattr(p, "type"); if (!t) t = Getattr(p, "value"); if (t) { String *ty = Swig_symbol_typedef_reduce(t, tscope); String *tb = SwigType_base(ty); String *td = SwigType_default(ty); Replaceid(td, "enum SWIGTYPE", tb); Replaceid(td, "SWIGTYPE", tb); Append(rname, td); Delete(tb); Delete(ty); Delete(td); } p = nextSibling(p); if (p) { Append(rname, ","); } } Append(rname, ")>"); mpartials = NewList(); if (templ) { /* First, we search using an exact type prototype */ Parm *p; char tmp[32]; int i; List *partials; String *ss; Iterator pi; partials = Getattr(templ, "partials"); if (partials) { for (pi = First(partials); pi.item; pi = Next(pi)) { ss = Copy(pi.item); p = parms; i = 1; while (p) { String *t, *tn; sprintf(tmp, "$%d", i); t = Getattr(p, "type"); if (!t) t = Getattr(p, "value"); if (t) { String *ty = Swig_symbol_typedef_reduce(t, tscope); tn = SwigType_base(ty); Replaceid(ss, tmp, tn); Delete(tn); Delete(ty); } i++; p = nextSibling(p); } if (template_debug) { Printf(stdout, " searching: '%s' (partial specialization - %s)\n", ss, pi.item); } if ((Equal(ss, tname)) || (Equal(ss, rname))) { Append(mpartials, pi.item); } Delete(ss); } } } if (template_debug) { Printf(stdout, " Matched partials: %s\n", mpartials); } if (Len(mpartials)) { String *s = Getitem(mpartials, 0); n = Swig_symbol_clookup_local(s, 0); if (Len(mpartials) > 1) { if (n) { Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, cparse_file, cparse_line, "Instantiation of template '%s' is ambiguous,\n", SwigType_namestr(tname)); Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, Getfile(n), Getline(n), " instantiation '%s' is used.\n", SwigType_namestr(Getattr(n, "name"))); } } } if (!n) { n = templ; } if (!n) { Swig_error(cparse_file, cparse_line, "Template '%s' undefined.\n", name); } else if (n) { String *nodeType = nodeType(n); if (!Equal(nodeType, "template")) { Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType); n = 0; } } success: Delete(tname); Delete(rname); Delete(mpartials); if ((template_debug) && (n)) { Printf(stdout, "Node: %p\n", n); Swig_print_node(n); } Delete(parms); return n; }