several fixes, see CHANGES.current 10/04/2004

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@6317 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Marcelo Matus 2004-10-05 00:19:26 +00:00
commit 2792ac8752
17 changed files with 216 additions and 97 deletions

View file

@ -1,7 +1,30 @@
Version 1.3.23 (in progress)
==================================
04/11/2004: wsfulton
10/04/2004: mmatus
- Properly qualify type in syntax as 'long(2)' or 'Foo()',
this solve old problem with default args, and probably
other problems around. However, the default arg problem
was also already solved by William (see bellow).
- Fix feature_set and feature_get methods. Before
they look from particular to general and keep the first
feature found. This didn't work well with templates.
Now the methods look from general to particular, and
override any found feature.
- Fix missing features for default const/dest, by really
'creating' the methods and applying the features.
- Fix return_const_value.i case by adding SwigValueWrapper<const T>
specialization.
- Fix %extend + overload, including overloading actual
class methods.
- Adding more cases in related files in the test-suite.
10/04/2004: wsfulton
Changes to the way default arguments are wrapped. Previously a single
method was generated for each method that had default arguments. If
a method had 5 arguments, say, of which 1 had a default argument

View file

@ -45,17 +45,12 @@ LIBPREFIX = lib
# Broken C++ test cases. (Can be run individually using make testcase.cpptest.)
CPP_TEST_BROKEN += \
defvalue_constructor \
derived_nested \
features \
multiple_inheritance \
namespace_union \
overload_complicated \
return_const_value \
smart_pointer_namespace2 \
template_default_arg \
template_specialization_defarg \
template_specialization_enum \
template_typedef_ptr \
using_namespace
@ -117,6 +112,7 @@ CPP_TEST_CASES += \
default_ns \
default_args \
default_ref \
defvalue_constructor \
director_abstract \
director_basic \
director_detect \
@ -142,6 +138,7 @@ CPP_TEST_CASES += \
extend_template \
extend_template_ns \
extern_throws \
features \
friends \
global_ns_arg \
grouping \
@ -188,6 +185,7 @@ CPP_TEST_CASES += \
reference_global_vars \
rename_default \
rename_scope \
return_const_value \
return_value_scope \
rname \
smart_pointer_const \
@ -217,6 +215,7 @@ CPP_TEST_CASES += \
template_construct \
template_default \
template_default2 \
template_default_arg \
template_default_inherit \
template_default_qualify \
template_default_vw \
@ -248,6 +247,7 @@ CPP_TEST_CASES += \
template_rename \
template_retvalue \
template_specialization \
template_specialization_enum \
template_static \
template_tbase_template \
template_type_namespace \

View file

@ -6,15 +6,29 @@
%exception "this_will_not_compile";
// Test 1: Test for no user supplied constructors and destructor
%exception Simple::Simple "$action /*Simple::Simple*/";
%exception Simple::~Simple "$action /*Simple::~Simple*/";
%exception Simple::Simple() "$action /*Simple::Simple*/";
%exception Simple::~Simple() "$action /*Simple::~Simple*/";
%inline %{
class Simple {};
%}
%exception NS::SimpleNS::SimpleNS() "$action /*Simple::Simple*/";
%exception NS::SimpleNS::~SimpleNS() "$action /*Simple::~Simple*/";
%inline %{
namespace NS
{
class SimpleNS {};
}
%}
// Test 2: Test templated functions
%exception foobar<int> "$action /*foobar<int>*/";
%exception foobar "caca";
%exception foobar<int>(int) "$action /*foobar<int>*/";
%inline %{
template<class T> void foobar(T t) {}
@ -23,34 +37,33 @@ template<class T> void foobar(T t) {}
%template(FooBarInt) foobar<int>;
// Test 3: Test templates with no user supplied constructors and destructor
%exception SimpleTemplate<int>::SimpleTemplate<int> "$action /*SimpleTemplate<int>::SimpleTemplate<int>*/";
%exception SimpleTemplate<int>::~SimpleTemplate "$action /*SimpleTemplate<int>::~SimpleTemplate*/";
%exception SimpleTemplate<int>::SimpleTemplate() "$action /*SimpleTemplate<int>::SimpleTemplate<int>*/";
%exception SimpleTemplate<int>::~SimpleTemplate() "$action /*SimpleTemplate<int>::~SimpleTemplate*/";
%inline %{
template<class T> class SimpleTemplate {};
template<class T> class SimpleTemplate {
public:
};
%}
%template(SimpleDouble) SimpleTemplate<double>;
%template(SimpleInt) SimpleTemplate<int>;
// Test 4: Test templates with user supplied constructors and destructor
%exception Template<int>::Template "$action /*Template<int>::Template<int>*/";
%exception Template<int>::Template() "$action /*Template<int>::Template<int>*/";
%exception Template<int>::Template(const Template&) "$action /*Template<int>::Template<int>(const Template&)*/";
%exception Template<int>::~Template "$action /*Template<int>::~Template*/";
%exception Template<int>::~Template() "$action /*Template<int>::~Template*/";
%exception Template<int>::foo "$action /*Template<int>::foo*/";
%inline %{
template<class T> class Template {
public:
Template();
Template(const Template&);
~Template();
void foo();
Template(){}
Template(const Template&){}
~Template(){}
void foo(){}
};
// Supply methods just for the int case. Note syntax is same as the %exception syntax.
Template<int>::Template() {}
Template<int>::Template(const Template&) {}
Template<int>::~Template() {}
void Template<int>::foo() {}
%}
%template(TemplateInt) Template<int>;

View file

@ -2,6 +2,7 @@
%inline %{
struct Foo {
int test() { return 0; }
};
%}

View file

@ -1,6 +1,8 @@
import overload_extend
f = overload_extend.Foo()
if f.test() != 0:
raise RuntimeError
if f.test(3) != 1:
raise RuntimeError
if f.test("hello") != 2:

View file

@ -1,12 +1,12 @@
import return_const_value
import sys
p = return_const_value.FooPtr.getPtr()
p = return_const_value.Foo_ptr.getPtr()
if (p.getVal() != 17):
print "Runtime test1 faild. p.getVal()=", p.getVal()
sys.exit(1)
p = return_const_value.FooPtr.getConstPtr()
p = return_const_value.Foo_ptr.getConstPtr()
if (p.getVal() != 17):
print "Runtime test2 faild. p.getVal()=", p.getVal()
sys.exit(1)

View file

@ -14,15 +14,15 @@ public:
}
};
class FooPtr {
class Foo_ptr {
Foo *_ptr;
public:
FooPtr(Foo *p): _ptr(p) {}
static FooPtr getPtr() {
return FooPtr(new Foo(17));
Foo_ptr(Foo *p): _ptr(p) {}
static Foo_ptr getPtr() {
return Foo_ptr(new Foo(17));
}
static const FooPtr getConstPtr() {
return FooPtr(new Foo(17));
static const Foo_ptr getConstPtr() {
return Foo_ptr(new Foo(17));
}
const Foo *operator->() {
return _ptr;

View file

@ -13,6 +13,11 @@
// This doesn't
Hello(size_type n = size_type(0) ) { }
enum Hi { hi, hello };
void foo(Hi h = hi) { }
};
%}

View file

@ -16,14 +16,10 @@
return 0;
}
C(int a = 0)
C(int a)
{
}
protected:
C()
{
}
};
@ -35,14 +31,10 @@
return 0;
}
C(double a = 0)
C(double a)
{
}
protected:
C()
{
}
};

View file

@ -24,7 +24,7 @@
template <class A>
struct C<hello , A> : Base<hello, A>
{
int hello()
int fhello()
{
return hello;
}
@ -39,7 +39,7 @@
template <class A>
struct C<hi , A> : Base<hi, A>
{
int hi()
int fhi()
{
return hi;
}

View file

@ -349,7 +349,22 @@ public:
T *operator&() { return tt; }
private:
SwigValueWrapper& operator=(const SwigValueWrapper<T>& rhs);
};
template<class T> class SwigValueWrapper<const T> {
T *tt;
public:
SwigValueWrapper() : tt(0) { }
SwigValueWrapper(const SwigValueWrapper<T>& rhs) : tt(new T(*rhs.tt)) { }
SwigValueWrapper(const T& t) : tt(new T(t)) { }
~SwigValueWrapper() { delete tt; }
SwigValueWrapper& operator=(const T& t) { delete tt; tt = new T(t); return *this; }
operator T&() const { return *tt; }
T *operator&() { return tt; }
private:
SwigValueWrapper& operator=(const SwigValueWrapper<T>& rhs);
};
#endif
%}
#endif

View file

@ -43,6 +43,7 @@ extern int yylex();
/* parser.y */
extern SwigType *Swig_cparse_type(String *);
extern Node *Swig_cparse(File *);
extern Hash *Swig_cparse_features();
/* util.c */
extern void Swig_cparse_replace_descriptor(String *s);

View file

@ -171,6 +171,11 @@ static Hash *rename_hash = 0;
static Hash *namewarn_hash = 0;
static Hash *features_hash = 0;
Hash *Swig_cparse_features() {
if (!features_hash) features_hash = NewHash();
return features_hash;
}
static String *feature_identifier_fix(String *s) {
if (SwigType_istemplate(s)) {
String *tp, *ts, *ta, *tq;
@ -4620,6 +4625,7 @@ exprcompound : expr PLUS expr {
}
| type LPAREN {
skip_balanced('(',')');
$1 = Swig_symbol_type_qualify($1,0);
if (SwigType_istemplate($1)) {
$1 = SwigType_namestr($1);
}

View file

@ -21,6 +21,7 @@ static void add_parms(ParmList *p, List *patchlist, List *typelist) {
SwigType *ty = Getattr(p,"type");
SwigType *val = Getattr(p,"value");
Append(typelist,ty);
Append(typelist,val);
Append(patchlist,val);
p = nextSibling(p);
}

View file

@ -1853,6 +1853,51 @@ int Language::classDeclaration(Node *n) {
/* ----------------------------------------------------------------------
* Language::classHandler()
* ---------------------------------------------------------------------- */
static Node *makeConstructor(Node *n)
{
Node *cn = Copy(n);
String *name = Getattr(n,"name");
String *rname = 0;
String *dname = NewStringf("%s::",name);
if (SwigType_istemplate(name)) {
rname = SwigType_templateprefix(name);
name = rname;
}
String *lname = Swig_scopename_last(name);
Append(dname,lname);
Setattr(cn,"feature:new","1");
Setattr(cn,"decl","f().");
Swig_features_get(Swig_cparse_features(), 0, dname, Getattr(cn,"decl"), cn);
Delete(rname);
Delete(dname);
Delete(lname);
return cn;
}
static Node *makeDestructor(Node *n)
{
Node *cn = Copy(n);
String *name = Getattr(n,"name");
String *rname = 0;
String *dname = NewStringf("%s::~",name);
if (SwigType_istemplate(name)) {
rname = SwigType_templateprefix(name);
name = rname;
}
String *lname = Swig_scopename_last(name);
Append(dname,lname);
Setattr(cn,"decl","f().");
Swig_features_get(Swig_cparse_features(), 0, dname, Getattr(cn,"decl"), cn);
Delete(rname);
Delete(dname);
Delete(lname);
return cn;
}
int Language::classHandler(Node *n) {
@ -1879,13 +1924,15 @@ int Language::classHandler(Node *n) {
if (!Getattr(n,"has_constructor") && !Getattr(n,"allocate:has_constructor") && (Getattr(n,"allocate:default_constructor"))) {
/* Note: will need to change this to support different kinds of classes */
if (!Abstract || hasDirector) {
Setattr(CurrentClass,"feature:new","1");
constructorHandler(CurrentClass);
Delattr(CurrentClass,"feature:new");
Node *cn = makeConstructor(CurrentClass);
constructorHandler(cn);
Delete(cn);
}
}
if (!Getattr(n,"has_destructor") && (!Getattr(n,"allocate:has_destructor")) && (Getattr(n,"allocate:default_destructor"))) {
destructorHandler(CurrentClass);
Node *cn = makeDestructor(CurrentClass);
destructorHandler(cn);
Delete(cn);
}
}

View file

@ -162,10 +162,12 @@ int Swig_cargs(Wrapper *w, ParmList *p) {
tycode = SwigType_type(type);
if (tycode == T_REFERENCE) {
if (pvalue) {
String *defname, *defvalue;
String *defname, *defvalue, *rvalue;
rvalue = SwigType_typedef_resolve_all(pvalue);
defname = NewStringf("%s_defvalue", lname);
defvalue = NewStringf("%s = %s", SwigType_str(type,defname), pvalue);
defvalue = NewStringf("%s = %s", SwigType_str(type,defname), rvalue);
Wrapper_add_localv(w,defname, defvalue, NIL);
Delete(rvalue);
Delete(defname);
Delete(defvalue);
}

View file

@ -389,7 +389,7 @@ void
Swig_name_object_set(Hash *namehash, String *name, SwigType *decl, DOH *object) {
DOH *n;
/* Printf(stdout,"name: '%s', '%s'\n", name, decl);*/
/* Printf(stdout,"name: '%s', '%s'\n", name, decl); */
n = Getattr(namehash,name);
if (!n) {
n = NewHash();
@ -530,9 +530,11 @@ static void merge_features(Hash *features, Node *n) {
if (!features) return;
for (ki = First(features); ki.key; ki = Next(ki)) {
/*
if (Getattr(n,ki.key)) {
continue;
}
*/
Setattr(n,ki.key,Copy(ki.item));
}
}
@ -550,9 +552,11 @@ Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl,
DOH *rn = 0;
Hash *n;
char *ncdecl = 0;
String *rdecl = 0;
SwigType *rname = 0;
if (!features) return;
if ((decl) && (SwigType_isqualifier(decl))) {
ncdecl = strchr(Char(decl),'.');
ncdecl++;
@ -563,38 +567,32 @@ Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl,
((Strcmp(nodeType(node),"constructor") == 0)
|| (Strcmp(nodeType(node),"destructor") == 0))) {
rname = SwigType_templateprefix(name);
rdecl = Copy(decl);
Replaceall(rdecl,name,rname);
decl = rdecl;
name = rname;
}
/* Printf(stdout,"feature_get: %s %s %s\n", prefix, name, decl); */
/* Global features */
n = Getattr(features,"");
rn = get_object(n,0);
merge_features(rn,node);
if (name) {
/* Catch-all */
n = Getattr(features,name);
rn = get_object(n,0);
merge_features(rn,node);
if (ncdecl) {
rn = get_object(n,ncdecl);
merge_features(rn,node);
}
rn = get_object(n,decl);
merge_features(rn,node);
/* Perform a class-based lookup (if class prefix supplied) */
if (prefix) {
if (Len(prefix)) {
tname = NewStringf("%s::%s",prefix,name);
n = Getattr(features,tname);
rn = get_object(n,decl);
merge_features(rn,node);
if (ncdecl) {
rn = get_object(n,ncdecl);
merge_features(rn,node);
}
rn = get_object(n,0);
merge_features(rn,node);
Delete(tname);
}
/* A wildcard-based class lookup */
tname = NewStringf("*::%s",name);
n = Getattr(features,tname);
rn = get_object(n,decl);
merge_features(rn,node);
if (ncdecl) {
rn = get_object(n,ncdecl);
merge_features(rn,node);
}
rn = get_object(n,0);
merge_features(rn,node);
Delete(tname);
/* A class-generic feature */
if (Len(prefix)) {
tname = NewStringf("%s::",prefix);
@ -603,38 +601,50 @@ Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl,
merge_features(rn,node);
Delete(tname);
}
} else {
/* Lookup in the global namespace only */
tname = NewStringf("::%s",name);
/* A wildcard-based class lookup */
tname = NewStringf("*::%s",name);
n = Getattr(features,tname);
rn = get_object(n,decl);
rn = get_object(n,0);
merge_features(rn,node);
if (ncdecl) {
rn = get_object(n,ncdecl);
merge_features(rn,node);
}
rn = get_object(n,decl);
merge_features(rn,node);
Delete(tname);
/* A specific class lookup */
if (Len(prefix)) {
tname = NewStringf("%s::%s",prefix,name);
n = Getattr(features,tname);
rn = get_object(n,0);
merge_features(rn,node);
if (ncdecl) {
rn = get_object(n,ncdecl);
merge_features(rn,node);
}
rn = get_object(n,decl);
merge_features(rn,node);
Delete(tname);
}
} else {
/* Lookup in the global namespace only */
tname = NewStringf("::%s",name);
n = Getattr(features,tname);
rn = get_object(n,0);
merge_features(rn,node);
if (ncdecl) {
rn = get_object(n,ncdecl);
merge_features(rn,node);
}
rn = get_object(n,decl);
merge_features(rn,node);
Delete(tname);
}
/* Catch-all */
n = Getattr(features,name);
rn = get_object(n,decl);
merge_features(rn,node);
if (ncdecl) {
rn = get_object(n,ncdecl);
merge_features(rn,node);
}
rn = get_object(n,0);
merge_features(rn,node);
}
/* Global features */
n = Getattr(features,"");
rn = get_object(n,0);
merge_features(rn,node);
Delete(rname);
Delete(rdecl);
}
@ -650,7 +660,8 @@ void
Swig_feature_set(Hash *features, const String_or_char *name, SwigType *decl, const String_or_char *featurename, String *value, Hash *featureattribs) {
Hash *n;
Hash *fhash;
/* Printf(stdout,"feature: %s %s %s %s\n", name, decl, featurename, value);*/
/* Printf(stdout,"feature_set: %s %s %s %s\n", name, decl, featurename, value); */
n = Getattr(features,name);
if (!n) {