fix SwigValueWrapper

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@6443 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Marcelo Matus 2004-10-19 23:34:04 +00:00
commit a75d2b0a4c
5 changed files with 109 additions and 5 deletions

View file

@ -215,6 +215,7 @@ public:
virtual Node *classLookup(SwigType *s); /* Class lookup */
virtual Node *enumLookup(SwigType *s); /* Enum lookup */
virtual int abstractClassTest(Node *n); /* Is class really abstract? */
virtual int is_assignable(Node *n); /* Is variable assignable? */
/* Allow director related code generation */
void allow_directors(int val = 1);
@ -235,9 +236,6 @@ public:
void setOverloadResolutionTemplates(String *argc, String *argv);
protected:
/* Patch C++ pass-by-value */
static void patch_parms(Parm *p);
/* Allow multiple-input typemaps */
void allow_multiple_input(int val = 1);

View file

@ -137,7 +137,6 @@ Swig_wrapped_var_assign(SwigType *t, const String_or_char *name) {
* Emit all of the local variables for a list of parameters. Returns the
* number of parameters.
* ----------------------------------------------------------------------------- */
int Swig_cargs(Wrapper *w, ParmList *p) {
int i;
SwigType *pt;
@ -157,8 +156,8 @@ int Swig_cargs(Wrapper *w, ParmList *p) {
pname = Getattr(p,"name");
/* pvalue = Getattr(p,"value");*/
pvalue = 0;
altty = Getattr(p,"alttype");
type = Getattr(p,"type");
altty = SwigType_alttype(type,0);
tycode = SwigType_type(type);
if (tycode == T_REFERENCE) {
if (pvalue) {
@ -178,6 +177,7 @@ int Swig_cargs(Wrapper *w, ParmList *p) {
local = Swig_clocal(pt,lname,pvalue);
} else {
local = Swig_clocal(altty,lname,pvalue);
Delete(altty);
}
Wrapper_add_localv(w,lname,local,NIL);
i++;

View file

@ -265,6 +265,7 @@ extern void SwigType_array_setdim(SwigType *t, int n, const String_or_cha
extern SwigType *SwigType_array_type(SwigType *t);
extern String *SwigType_default(SwigType *t);
extern void SwigType_typename_replace(SwigType *t, String *pat, String *rep);
extern SwigType *SwigType_alttype(SwigType *t, int ltmap);
/* --- Type-system managment --- */
extern void SwigType_typesystem_init();
@ -429,6 +430,8 @@ extern int Swig_scopename_check(String *s);
extern void Swig_init();
extern void Swig_warn(const char *filename, int line, const char *msg);
extern int Swig_value_wrapper_mode(int mode);
#define WARNING(msg) Swig_warn(__FILE__,__LINE__,msg)

View file

@ -1004,8 +1004,10 @@ static void typemap_locals(DOHString *s, ParmList *l, Wrapper *f, int argnum) {
p = l;
while (p) {
SwigType *pt = Getattr(p,"type");
SwigType *at = SwigType_alttype(pt, 1);
String *pn = Getattr(p,"name");
String *value = Getattr(p,"value");
if (at) pt = at;
if (pn) {
if (Len(pn) > 0) {
String *str;
@ -1041,6 +1043,7 @@ static void typemap_locals(DOHString *s, ParmList *l, Wrapper *f, int argnum) {
}
}
p = nextSibling(p);
Delete(at);
}
}

View file

@ -121,6 +121,23 @@ static String *k_inherit = 0;
static String *k_parent = 0;
static String *k_value = 0;
/*
Enable this one if your language fully support SwigValueWrapper<T>.
Leaving at '0' keeps the old swig behavior, which is not
always safe, but is well known.
Setting at '1' activates the new scheme, which is always safe but
it requires all the typemaps ready for that.
*/
static int value_wrapper_mode = 0;
int Swig_value_wrapper_mode(int mode)
{
value_wrapper_mode = mode;
return mode;
}
static void flush_cache() {
typedef_resolve_cache = 0;
@ -1194,6 +1211,89 @@ int SwigType_type(SwigType *t)
return T_USER;
}
/* -----------------------------------------------------------------------------
* SwigType_alttype()
*
* Returns the alternative value type needed in C++ for class value
* types. When swig is not sure about using a plain $ltype value,
* since the class doesn't have a default constructor, or it can't be
* assigned, you will get back 'SwigValueWrapper<type >'.
*
* This is the default behavior unless:
*
* 1.- swig detects a default_constructor and 'setallocate:default_constructor'
* attribute.
*
* 2.- swig doesn't mark 'type' as noassignable.
*
* 3.- the user specify that the value wrapper is not needed by using
* the %feature("novaluewrapper"), in that case the user need to type
*
* %feature("novaluewrapper") MyOpaqueClass;
* class MyOpaqueClass;
*
* Users can also force the use of the value wrapper by using the
* %feature("valuewrapper").
* ----------------------------------------------------------------------------- */
SwigType *SwigType_alttype(SwigType *t, int local_tmap) {
if (!cparse_cplusplus) return 0;
if (value_wrapper_mode == 0) {
/* old partial use of SwigValueTypes, it can fail for opaque types */
Node *n;
int use_wrapper = 0;
if (local_tmap) return 0;
if (!use_wrapper && SwigType_isclass(t)) {
SwigType *ftd = SwigType_typedef_resolve_all(t);
SwigType *td = SwigType_strip_qualifiers(ftd);
Delete(ftd);
if ((n = Swig_symbol_clookup(td,0)) && !Getattr(n,"feature:novaluewrapper")) {
if (Getattr(n,"feature:valuewrapper")) {
use_wrapper = 1;
} else {
if ((Strcmp(nodeType(n),"class") == 0)
&& (!Getattr(n,"allocate:default_constructor")
|| (Getattr(n,"allocate:noassign")))) {
use_wrapper = 1;
}
}
}
if (SwigType_issimple(td) && SwigType_istemplate(td)) {
use_wrapper = 1;
}
Delete(td);
}
return (use_wrapper ? NewStringf("SwigValueWrapper< %s >",SwigType_str(t,0)): 0);
} else {
/* safe use of SwigValueTypes, it can fail with some typemaps */
SwigType *w = 0;
Node *n = 0;
int use_wrapper = 1;
SwigType *ftd = SwigType_typedef_resolve_all(t);
SwigType *td = SwigType_strip_qualifiers(ftd);
if (SwigType_type(td) == T_USER) {
if ((n = Swig_symbol_clookup(td,0))) {
if (((Strcmp(nodeType(n),"class") == 0)
&& !Getattr(n,"allocate:noassign")
&& (Getattr(n,"allocate:default_constructor")))
|| (Getattr(n,"feature:novaluewrapper"))) {
use_wrapper = Getattr(n,"feature:valuewrapper") ? 1 : 0;
}
}
} else {
use_wrapper = 0;
}
if (use_wrapper) {
String *name = SwigType_str(t,0);
w = NewStringf("SwigValueWrapper<%s >",name);
Delete(name);
}
Delete(ftd);
Delete(td);
return w;
}
}
/******************************************************************************
*** * * * WARNING * * * ***
*** ***