Node *Swig_directormap(Node *module, String *type) {
  int is_void = !Cmp(type, "void");
  if (!is_void && module) {
    /* ?? follow the inheritance hierarchy? */

    String *base = SwigType_base(type);

    Node *directormap = Getattr(module, k_wrapdirectormap);
    if (directormap)
      return Getattr(directormap, base);
  }
  return 0;
}
Example #2
0
static EMatch does_parm_match(SwigType *type, SwigType *partial_parm_type, const char *partial_parm_type_base, Symtab *tscope, int *specialization_priority) {
  static const int EXACT_MATCH_PRIORITY = 99999; /* a number bigger than the length of any conceivable type */
  int matches;
  int substitutions;
  EMatch match;
  SwigType *ty = Swig_symbol_typedef_reduce(type, tscope);
  String *base = SwigType_base(ty);
  SwigType *t = Copy(partial_parm_type);
  substitutions = Replaceid(t, partial_parm_type_base, base); /* eg: Replaceid("p.$1", "$1", "int") returns t="p.int" */
  matches = Equal(ty, t);
  *specialization_priority = -1;
  if (substitutions == 1) {
    /* we have a non-explicit specialized parameter (in partial_parm_type) because a substitution for $1, $2... etc has taken place */
    SwigType *tt = Copy(partial_parm_type);
    int len;
    /*
       check for match to partial specialization type, for example, all of the following could match the type in the %template:
       template <typename T> struct XX {};
       template <typename T> struct XX<T &> {};         // r.$1
       template <typename T> struct XX<T const&> {};    // r.q(const).$1
       template <typename T> struct XX<T *const&> {};   // r.q(const).p.$1
       %template(XXX) XX<int *const&>;                  // r.q(const).p.int

       where type="r.q(const).p.int" will match either of tt="r.", tt="r.q(const)" tt="r.q(const).p"
    */
    Replaceid(tt, partial_parm_type_base, ""); /* remove the $1, $2 etc, eg tt="p.$1" => "p." */
    len = Len(tt);
    if (Strncmp(tt, ty, len) == 0) {
      match = PartiallySpecializedMatch;
      *specialization_priority = len;
    } else {
      match = PartiallySpecializedNoMatch;
    }
    Delete(tt);
  } else {
    match = matches ? ExactMatch : ExactNoMatch;
    if (matches)
      *specialization_priority = EXACT_MATCH_PRIORITY; /* exact matches always take precedence */
  }
  /*
  Printf(stdout, "      does_parm_match %2d %5d [%s] [%s]\n", match, *specialization_priority, type, partial_parm_type);
  */
  Delete(t);
  Delete(base);
  Delete(ty);
  return match;
}
Example #3
0
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;
}
Example #4
0
static String *manglestr_default(const SwigType *s) {
  char *c;
  String *result = 0;
  String *base = 0;
  SwigType *lt;
  SwigType *sr = SwigType_typedef_resolve_all(s);
  SwigType *sq = SwigType_typedef_qualified(sr);
  SwigType *ss = SwigType_remove_global_scope_prefix(sq);
  SwigType *type = ss;

  if (SwigType_istemplate(ss)) {
    SwigType *ty = Swig_symbol_template_deftype(ss, 0);
    Delete(ss);
    ss = ty;
    type = ss;
  }

  lt = SwigType_ltype(type);
  result = SwigType_prefix(lt);
  base = SwigType_base(lt);

  c = Char(result);
  while (*c) {
    if (!isalnum((int) *c))
      *c = '_';
    c++;
  }
  if (SwigType_istemplate(base)) {
    String *b = SwigType_namestr(base);
    Delete(base);
    base = b;
  }

  Replace(base, "struct ", "", DOH_REPLACE_ANY);	/* This might be problematic */
  Replace(base, "class ", "", DOH_REPLACE_ANY);
  Replace(base, "union ", "", DOH_REPLACE_ANY);
  Replace(base, "enum ", "", DOH_REPLACE_ANY);

  c = Char(base);
  while (*c) {
    if (*c == '<')
      *c = 'T';
    else if (*c == '>')
      *c = 't';
    else if (*c == '*')
      *c = 'p';
    else if (*c == '[')
      *c = 'a';
    else if (*c == ']')
      *c = 'A';
    else if (*c == '&')
      *c = 'R';
    else if (*c == '(')
      *c = 'f';
    else if (*c == ')')
      *c = 'F';
    else if (!isalnum((int) *c))
      *c = '_';
    c++;
  }
  Append(result, base);
  Insert(result, 0, "_");
  Delete(lt);
  Delete(base);
  Delete(ss);
  Delete(sq);
  Delete(sr);
  return result;
}