コード例 #1
0
ファイル: templ.c プロジェクト: ChunHungLiu/swig
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;
}
コード例 #2
0
ファイル: templ.c プロジェクト: veeramarni/xuggle-swig
static int cparse_template_expand(Node *n, String *tname, String *rname, String *templateargs, List *patchlist, List *typelist, List *cpatchlist) {
  static int expanded = 0;
  int ret;
  String *nodeType;
  if (!n)
    return 0;
  nodeType = nodeType(n);
  if (Getattr(n, "error"))
    return 0;

  if (Equal(nodeType, "template")) {
    /* Change the node type back to normal */
    if (!expanded) {
      expanded = 1;
      set_nodeType(n, Getattr(n, "templatetype"));
      ret = cparse_template_expand(n, tname, rname, templateargs, patchlist, typelist, cpatchlist);
      expanded = 0;
      return ret;
    } else {
      /* Called when template appears inside another template */
      /* Member templates */

      set_nodeType(n, Getattr(n, "templatetype"));
      ret = cparse_template_expand(n, tname, rname, templateargs, patchlist, typelist, cpatchlist);
      set_nodeType(n, "template");
      return ret;
    }
  } else if (Equal(nodeType, "cdecl")) {
    /* A simple C declaration */
    SwigType *t, *v, *d;
    String *code;
    t = Getattr(n, "type");
    v = Getattr(n, "value");
    d = Getattr(n, "decl");

    code = Getattr(n, "code");

    Append(typelist, t);
    Append(typelist, d);
    Append(patchlist, v);
    Append(cpatchlist, code);

    if (Getattr(n, "conversion_operator")) {
      Append(cpatchlist, Getattr(n, "name"));
      if (Getattr(n, "sym:name")) {
	Append(cpatchlist, Getattr(n, "sym:name"));
      }
    }

    add_parms(Getattr(n, "parms"), cpatchlist, typelist);
    add_parms(Getattr(n, "throws"), cpatchlist, typelist);

  } else if (Equal(nodeType, "class")) {
    /* Patch base classes */
    {
      int b = 0;
      for (b = 0; b < 3; ++b) {
	List *bases = Getattr(n, baselists[b]);
	if (bases) {
	  int i;
	  int ilen = Len(bases);
	  for (i = 0; i < ilen; i++) {
	    String *name = Copy(Getitem(bases, i));
	    Setitem(bases, i, name);
	    Append(typelist, name);
	  }
	}
      }
    }
    /* Patch children */
    {
      Node *cn = firstChild(n);
      while (cn) {
	cparse_template_expand(cn, tname, rname, templateargs, patchlist, typelist, cpatchlist);
	cn = nextSibling(cn);
      }
    }
  } else if (Equal(nodeType, "constructor")) {
    String *name = Getattr(n, "name");
    if (!(Getattr(n, "templatetype"))) {
      String *symname;
      String *stripped_name = SwigType_templateprefix(name);
      if (Strstr(tname, stripped_name)) {
	Replaceid(name, stripped_name, tname);
      }
      Delete(stripped_name);
      symname = Getattr(n, "sym:name");
      if (symname) {
	stripped_name = SwigType_templateprefix(symname);
	if (Strstr(tname, stripped_name)) {
	  Replaceid(symname, stripped_name, tname);
	}
	Delete(stripped_name);
      }
      if (strchr(Char(name), '<')) {
	Append(patchlist, Getattr(n, "name"));
      } else {
	Append(name, templateargs);
      }
      name = Getattr(n, "sym:name");
      if (name) {
	if (strchr(Char(name), '<')) {
	  Clear(name);
	  Append(name, rname);
	} else {
	  String *tmp = Copy(name);
	  Replace(tmp, tname, rname, DOH_REPLACE_ANY);
	  Clear(name);
	  Append(name, tmp);
	  Delete(tmp);
	}
      }
      /* Setattr(n,"sym:name",name); */
    }
    Append(cpatchlist, Getattr(n, "code"));
    Append(typelist, Getattr(n, "decl"));
    add_parms(Getattr(n, "parms"), cpatchlist, typelist);
    add_parms(Getattr(n, "throws"), cpatchlist, typelist);
  } else if (Equal(nodeType, "destructor")) {
    String *name = Getattr(n, "name");
    if (name) {
      if (strchr(Char(name), '<'))
        Append(patchlist, Getattr(n, "name"));
      else
        Append(name, templateargs);
    }
    name = Getattr(n, "sym:name");
    if (name) {
      if (strchr(Char(name), '<')) {
        String *sn = Copy(tname);
        Setattr(n, "sym:name", sn);
        Delete(sn);
      } else {
        Replace(name, tname, rname, DOH_REPLACE_ANY);
      }
    }
    /* Setattr(n,"sym:name",name); */
    Append(cpatchlist, Getattr(n, "code"));
  } else if (Equal(nodeType, "using")) {
    String *uname = Getattr(n, "uname");
    if (uname && strchr(Char(uname), '<')) {
      Append(patchlist, uname);
    }
    if (Getattr(n, "namespace")) {
      /* Namespace link.   This is nasty.  Is other namespace defined? */

    }
  } else {
    /* Look for obvious parameters */
    Node *cn;
    Append(cpatchlist, Getattr(n, "code"));
    Append(typelist, Getattr(n, "type"));
    Append(typelist, Getattr(n, "decl"));
    add_parms(Getattr(n, "parms"), cpatchlist, typelist);
    add_parms(Getattr(n, "kwargs"), cpatchlist, typelist);
    add_parms(Getattr(n, "pattern"), cpatchlist, typelist);
    add_parms(Getattr(n, "throws"), cpatchlist, typelist);
    cn = firstChild(n);
    while (cn) {
      cparse_template_expand(cn, tname, rname, templateargs, patchlist, typelist, cpatchlist);
      cn = nextSibling(cn);
    }
  }
  return 0;
}
コード例 #3
0
ファイル: templ.c プロジェクト: veeramarni/xuggle-swig
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;
}
コード例 #4
0
ファイル: templ.c プロジェクト: kkaempf/swig
static void cparse_template_expand(Node *templnode, Node *n, String *tname, String *rname, String *templateargs, List *patchlist, List *typelist, List *cpatchlist) {
  static int expanded = 0;
  String *nodeType;
  if (!n)
    return;
  nodeType = nodeType(n);
  if (Getattr(n, "error"))
    return;

  if (Equal(nodeType, "template")) {
    /* Change the node type back to normal */
    if (!expanded) {
      expanded = 1;
      set_nodeType(n, Getattr(n, "templatetype"));
      cparse_template_expand(templnode, n, tname, rname, templateargs, patchlist, typelist, cpatchlist);
      expanded = 0;
      return;
    } else {
      /* Called when template appears inside another template */
      /* Member templates */

      set_nodeType(n, Getattr(n, "templatetype"));
      cparse_template_expand(templnode, n, tname, rname, templateargs, patchlist, typelist, cpatchlist);
      set_nodeType(n, "template");
      return;
    }
  } else if (Equal(nodeType, "cdecl")) {
    /* A simple C declaration */
    SwigType *t, *v, *d;
    String *code;
    t = Getattr(n, "type");
    v = Getattr(n, "value");
    d = Getattr(n, "decl");

    code = Getattr(n, "code");

    Append(typelist, t);
    Append(typelist, d);
    Append(patchlist, v);
    Append(cpatchlist, code);

    if (Getattr(n, "conversion_operator")) {
      Append(cpatchlist, Getattr(n, "name"));
      if (Getattr(n, "sym:name")) {
	Append(cpatchlist, Getattr(n, "sym:name"));
      }
    }
    if (checkAttribute(n, "storage", "friend")) {
      String *symname = Getattr(n, "sym:name");
      if (symname) {
	String *stripped_name = SwigType_templateprefix(symname);
	Setattr(n, "sym:name", stripped_name);
	Delete(stripped_name);
      }
      Append(typelist, Getattr(n, "name"));
    }

    add_parms(Getattr(n, "parms"), cpatchlist, typelist);
    add_parms(Getattr(n, "throws"), cpatchlist, typelist);

  } else if (Equal(nodeType, "class")) {
    /* Patch base classes */
    {
      int b = 0;
      for (b = 0; b < 3; ++b) {
	List *bases = Getattr(n, baselists[b]);
	if (bases) {
	  int i;
	  int ilen = Len(bases);
	  for (i = 0; i < ilen; i++) {
	    String *name = Copy(Getitem(bases, i));
	    Setitem(bases, i, name);
	    Append(typelist, name);
	  }
	}
      }
    }
    /* Patch children */
    {
      Node *cn = firstChild(n);
      while (cn) {
	cparse_template_expand(templnode, cn, tname, rname, templateargs, patchlist, typelist, cpatchlist);
	cn = nextSibling(cn);
      }
    }
  } else if (Equal(nodeType, "constructor")) {
    String *name = Getattr(n, "name");
    if (!(Getattr(n, "templatetype"))) {
      String *symname;
      String *stripped_name = SwigType_templateprefix(name);
      if (Strstr(tname, stripped_name)) {
	Replaceid(name, stripped_name, tname);
      }
      Delete(stripped_name);
      symname = Getattr(n, "sym:name");
      if (symname) {
	stripped_name = SwigType_templateprefix(symname);
	if (Strstr(tname, stripped_name)) {
	  Replaceid(symname, stripped_name, tname);
	}
	Delete(stripped_name);
      }
      if (strchr(Char(name), '<')) {
	Append(patchlist, Getattr(n, "name"));
      } else {
	Append(name, templateargs);
      }
      name = Getattr(n, "sym:name");
      if (name) {
	if (strchr(Char(name), '<')) {
	  Clear(name);
	  Append(name, rname);
	} else {
	  String *tmp = Copy(name);
	  Replace(tmp, tname, rname, DOH_REPLACE_ANY);
	  Clear(name);
	  Append(name, tmp);
	  Delete(tmp);
	}
      }
      /* Setattr(n,"sym:name",name); */
    }
    Append(cpatchlist, Getattr(n, "code"));
    Append(typelist, Getattr(n, "decl"));
    add_parms(Getattr(n, "parms"), cpatchlist, typelist);
    add_parms(Getattr(n, "throws"), cpatchlist, typelist);
  } else if (Equal(nodeType, "destructor")) {
    /* We only need to patch the dtor of the template itself, not the destructors of any nested classes, so check that the parent of this node is the root
     * template node, with the special exception for %extend which adds its methods under an intermediate node. */
    Node* parent = parentNode(n);
    if (parent == templnode || (parentNode(parent) == templnode && Equal(nodeType(parent), "extend"))) {
      String *name = Getattr(n, "name");
      if (name) {
	if (strchr(Char(name), '<'))
	  Append(patchlist, Getattr(n, "name"));
	else
	  Append(name, templateargs);
      }
      name = Getattr(n, "sym:name");
      if (name) {
	if (strchr(Char(name), '<')) {
	  String *sn = Copy(tname);
	  Setattr(n, "sym:name", sn);
	  Delete(sn);
	} else {
	  Replace(name, tname, rname, DOH_REPLACE_ANY);
	}
      }
      /* Setattr(n,"sym:name",name); */
      Append(cpatchlist, Getattr(n, "code"));
    }
  } else if (Equal(nodeType, "using")) {
    String *uname = Getattr(n, "uname");
    if (uname && strchr(Char(uname), '<')) {
      Append(patchlist, uname);
    }
    if (Getattr(n, "namespace")) {
      /* Namespace link.   This is nasty.  Is other namespace defined? */

    }
  } else {
    /* Look for obvious parameters */
    Node *cn;
    Append(cpatchlist, Getattr(n, "code"));
    Append(typelist, Getattr(n, "type"));
    Append(typelist, Getattr(n, "decl"));
    add_parms(Getattr(n, "parms"), cpatchlist, typelist);
    add_parms(Getattr(n, "kwargs"), cpatchlist, typelist);
    add_parms(Getattr(n, "pattern"), cpatchlist, typelist);
    add_parms(Getattr(n, "throws"), cpatchlist, typelist);
    cn = firstChild(n);
    while (cn) {
      cparse_template_expand(templnode, cn, tname, rname, templateargs, patchlist, typelist, cpatchlist);
      cn = nextSibling(cn);
    }
  }
}