From 0ac8253c3fc4d78e17aa233d62648a7c37eb8fb8 Mon Sep 17 00:00:00 2001 From: Marcelo Matus Date: Thu, 16 Dec 2004 02:12:05 +0000 Subject: [PATCH] fixes for templates and template default args, cosmetics, and other fixes for OSS git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@6893 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/director_enum.i | 4 +- Examples/test-suite/primitive_types.i | 2 + Examples/test-suite/python/li_std_stream.i | 4 +- Examples/test-suite/smart_pointer_member.i | 1 + Examples/test-suite/template_default.i | 170 ++++++++- Source/CParse/cparse.h | 2 - Source/CParse/parser.y | 4 +- Source/CParse/templ.c | 168 +++------ Source/Include/swigwarn.h | 2 +- Source/Modules/allocate.cxx | 1 + Source/Modules/lang.cxx | 5 +- Source/Modules/tcl8.cxx | 5 +- Source/Swig/misc.c | 6 +- Source/Swig/naming.c | 16 + Source/Swig/stype.c | 15 +- Source/Swig/swig.h | 19 +- Source/Swig/symbol.c | 416 ++++++++++++++++----- Source/Swig/typemap.c | 12 +- Source/Swig/typeobj.c | 19 +- Source/Swig/typesys.c | 15 +- 20 files changed, 615 insertions(+), 271 deletions(-) diff --git a/Examples/test-suite/director_enum.i b/Examples/test-suite/director_enum.i index dde7c6190..24720c378 100644 --- a/Examples/test-suite/director_enum.i +++ b/Examples/test-suite/director_enum.i @@ -32,10 +32,10 @@ namespace EnumDirector { virtual Hello say_hello(Hello){ return hello;} virtual Hello say_hi(A *a){ return hi;} virtual Bye say_bye(Bye b){ return b;} - virtual const Hello & say_hi_ref(const Hello & h){ return h;} + virtual Hello say_hi_ref(const Hello & h){ return h;} Hello ping(Hello h){ return say_hi(h);} - const Hello & ping_ref(const Hello &h){ return say_hi_ref(h);} + Hello ping_ref(const Hello &h){ return say_hi_ref(h);} Bye ping_member_enum(Bye b){ return say_bye(b);} }; diff --git a/Examples/test-suite/primitive_types.i b/Examples/test-suite/primitive_types.i index 1ba2b3124..964d82f65 100644 --- a/Examples/test-suite/primitive_types.i +++ b/Examples/test-suite/primitive_types.i @@ -1,6 +1,8 @@ // Massive primitive datatype test. %module(directors="1") primitive_types +// Using thread unsafe wrapping +#pragma SWIG nowarn=470 /* if your language has problems with MyInt* and/or Hello*, diff --git a/Examples/test-suite/python/li_std_stream.i b/Examples/test-suite/python/li_std_stream.i index 22267a108..0a999ddbf 100644 --- a/Examples/test-suite/python/li_std_stream.i +++ b/Examples/test-suite/python/li_std_stream.i @@ -48,8 +48,8 @@ }; %} -%extend std::basic_ostream >{ - std::basic_ostream >& +%extend std::basic_ostream{ + std::basic_ostream& operator<<(const A& a) { *self << "A class"; diff --git a/Examples/test-suite/smart_pointer_member.i b/Examples/test-suite/smart_pointer_member.i index 572893bfd..4b245b125 100644 --- a/Examples/test-suite/smart_pointer_member.i +++ b/Examples/test-suite/smart_pointer_member.i @@ -33,6 +33,7 @@ return f; } }; + int get_y(Bar *b) { diff --git a/Examples/test-suite/template_default.i b/Examples/test-suite/template_default.i index 9de4eab38..2d395e763 100644 --- a/Examples/test-suite/template_default.i +++ b/Examples/test-suite/template_default.i @@ -1,10 +1,164 @@ %module template_default -%inline %{ -template -class A -{ -}; - %} -%template(A_ii) A; -%template(A_d) A; + + +%warnfilter(801) ns1::Traits::c; /* Ruby, wrong constant name */ +namespace ns1 { + namespace ns2 { + + %feature("hello") A; + %feature("hello") A; + %feature("hi") A; + %feature("hi") A; + + %extend A + { + int foo() { return 1; } + } + + %extend A + { + int foo() { return 1; } + } + + %extend A + { + int bar() { return 1; } + } + + %extend A + { + int bar() { return 1; } + } + + %extend N + { + int bar() { return 1; } + } + } +} + +%inline %{ + + namespace ns1 { + namespace ns2 { + + struct Parm + { + }; + + template + class A + { + +#ifdef SWIG + %typemap(in) A * { /* in A */ } + %typemap(out) A * { /* out A */ } +#endif + }; + + typedef unsigned int category; + + const category one = 1; + const category two = 1; + + + template + class N + { + +#ifdef SWIG + %typemap(in) N * { /* in N */ } + %typemap(out) N * { /* out N */ } +#endif + }; + } + } +%} + + + + +%template(A_p) ns1::ns2::A; +%template(N_1p) ns1::ns2::N; + + +namespace ns1 { + namespace ns2 { + %template(A_ii) A; + %template(A_d) A; + %template(N_d) N; + + } +} + + +%inline %{ + namespace ns1 { + namespace ns2 { + namespace ns3 { + + struct B : A + { + }; + + struct C : N + { + }; + + + A *get_a1(A *a) { + return a; + } + + A *get_a2(A *a) { + return a; + } + + } + } + } +%} + +%inline %{ + namespace ns1 { + struct Traits + { + static const ns2::category c = ns2::one; + }; + namespace ns4 { + + template + struct D : ns2::N + { + D() + { + } + + }; + + template > + struct Base : T2 + { + }; + } + } +%} + + +%template(Do) ns1::ns4::D; +%template(Bo) ns1::ns4::Base >; + + + +%inline %{ + namespace ns1 { + namespace ns5 { + + struct Der : ns4::Base + { + }; + } + } + +%} diff --git a/Source/CParse/cparse.h b/Source/CParse/cparse.h index 3825abc00..e3d3fa04f 100644 --- a/Source/CParse/cparse.h +++ b/Source/CParse/cparse.h @@ -57,8 +57,6 @@ extern int need_redefined_warn(Node* a, Node* b, int InClass); /* templ.c */ -extern void Swig_cparse_template_defargs(Parm *parms, Parm *targs, Symtab *tscope); -extern String* Swig_cparse_template_deftype(SwigType *type, Symtab *tscope); extern int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab *tscope); extern Node *Swig_cparse_template_locate(String *name, ParmList *tparms, Symtab *tscope); extern void Swig_cparse_debug_templates(int); diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 76137ebc6..d67240b65 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -3322,8 +3322,10 @@ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { template_para } else { /* Need to resolve exact specialization name */ /* add default args from generic template */ - String *fname = Swig_cparse_template_deftype(tname,0); + String *ty = Swig_symbol_template_deftype(tname,0); + String *fname = Swig_symbol_type_qualify(ty,0); Swig_symbol_cadd(fname,$$); + Delete(ty); } } else if ($$) { Setattr($$,"templatetype",nodeType($6)); diff --git a/Source/CParse/templ.c b/Source/CParse/templ.c index 36eb6fad4..01e640b6a 100644 --- a/Source/CParse/templ.c +++ b/Source/CParse/templ.c @@ -288,9 +288,11 @@ Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab *ts /* Printf(stdout,"%s\n", ParmList_str_defaultargs(tp)); */ if (tp) { + Symtab *tsdecl = Getattr(n,"sym:symtab"); while (p && tp) { String *name, *value, *valuestr, *tydef, *tmp, *tmpr; int sz, i; + String *dvalue = 0; name = Getattr(tp,"name"); value = Getattr(p,"value"); @@ -298,19 +300,22 @@ Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab *ts if (name) { if (!value) value = Getattr(p,"type"); - if (SwigType_istemplate(value)) { - value = Swig_cparse_template_deftype(value, 0); + dvalue = Swig_symbol_type_qualify(value,tsdecl); + if (SwigType_istemplate(dvalue)) { + String *ty = Swig_symbol_template_deftype(dvalue, tscope); + Delete(dvalue); + dvalue = ty; } - valuestr = SwigType_str(value,0); - assert(value); + assert(dvalue); + valuestr = SwigType_str(dvalue,0); /* Need to patch default arguments */ { Parm *rp = nextSibling(p); while (rp) { String *rvalue = Getattr(rp,"value"); if (rvalue) { - Replace(rvalue,name,value, DOH_REPLACE_ID); + Replace(rvalue,name,dvalue, DOH_REPLACE_ID); } rp = nextSibling(rp); } @@ -318,20 +323,20 @@ Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab *ts sz = Len(patchlist); for (i = 0; i < sz; i++) { String *s = Getitem(patchlist,i); - Replace(s,name,value, DOH_REPLACE_ID); + Replace(s,name,dvalue, DOH_REPLACE_ID); } sz = Len(typelist); for (i = 0; i < sz; i++) { String *s = Getitem(typelist,i); /* Replace(s,name,value, DOH_REPLACE_ID); */ - /* Printf(stdout,"name = '%s', value = '%s', tbase = '%s', iname='%s' s = '%s' --> ", name, value, tbase, iname, s); */ - SwigType_typename_replace(s,name,value); + /* Printf(stdout,"name = '%s', value = '%s', tbase = '%s', iname='%s' s = '%s' --> ", name, dvalue, tbase, iname, s); */ + SwigType_typename_replace(s,name,dvalue); SwigType_typename_replace(s,tbase,iname); /* Printf(stdout,"'%s'\n", s);*/ } if (!tydef) { - tydef = value; + tydef = dvalue; } tmp = NewStringf("#%s",name); tmpr = NewStringf("\"%s\"", valuestr); @@ -346,6 +351,7 @@ Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab *ts Delete(tmp); Delete(tmpr); Delete(valuestr); + Delete(dvalue); } p = nextSibling(p); tp = nextSibling(tp); @@ -383,105 +389,6 @@ Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab *ts return 0; } -/* ----------------------------------------------------------------------------- - * Swig_cparse_template_defargs() - * - * Apply default arg from generic template default args - * ----------------------------------------------------------------------------- */ - - -void -Swig_cparse_template_defargs(Parm *parms, Parm *targs, Symtab *tscope) { - if (Len(parms) < Len(targs)) { - Parm *lp = parms; - Parm *p = lp; - Parm *tp = targs; - while(p && tp) { - p = nextSibling(p); - tp = nextSibling(tp); - if (p) lp = p; - } - while (tp) { - String *value = Getattr(tp,"value"); - if (value) { - Parm *cp; - Parm *ta = targs; - Parm *p = parms; - SwigType *nt = Swig_symbol_typedef_reduce(value,tscope); - while(p && ta) { - String *name = Getattr(ta,"name"); - String *value = Getattr(p,"value"); - if (!value) value = Getattr(p,"type"); - Replace(nt, name, value, DOH_REPLACE_ID); - p = nextSibling(p); - ta = nextSibling(ta); - } - cp = NewParm(Swig_symbol_type_qualify(nt,tscope),0); - set_nextSibling(lp,cp); - lp = cp; - tp = nextSibling(tp); - Delete(nt); - } else { - tp = 0; - } - } - } -} - -/* ----------------------------------------------------------------------------- - * Swig_cparse_template_deftype() - * - * Apply default args to generic template type - * ----------------------------------------------------------------------------- */ -String* -Swig_cparse_template_deftype(SwigType *type, Symtab *tscope) { - String *prefix = SwigType_prefix(type); - String *base = SwigType_base(type); - String *tprefix = SwigType_templateprefix(base); - String *targs = SwigType_templateargs(base); - String *tsuffix = SwigType_templatesuffix(base); - ParmList *tparms = SwigType_function_parms(targs); - Node *tempn = Swig_symbol_clookup_local(tprefix,tscope); - if (tempn) { - ParmList *tnargs = Getattr(tempn,"templateparms"); - Parm *p; - /* Printf(stderr,"deftype type %s %s %s\n", tprefix, targs, tsuffix);*/ - Append(tprefix,"<("); - Swig_cparse_template_defargs(tparms, tnargs,tscope); - p = tparms; - while (p) { - SwigType *ptype = Getattr(p,"type"); - SwigType *ttr = Swig_symbol_typedef_reduce(ptype ? ptype : Getattr(p,"value") ,tscope); - SwigType *ttq = Swig_symbol_type_qualify(ttr,tscope); - if (SwigType_istemplate(ttq)) { - SwigType *t = Swig_cparse_template_deftype(ttq, tscope); - Delete(ttq); - ttq = t; - } - Append(tprefix,ttq); - p = nextSibling(p); - if (p) Putc(',',tprefix); - Delete(ttr); - Delete(ttq); - } - Append(tprefix,")>"); - Append(tprefix,tsuffix); - Append(prefix,tprefix); - /* Printf(stderr,"deftype default %s \n", tprefix); */ - type = Copy(prefix); - } else { - type = Copy(type); - } - - Delete(prefix); - Delete(base); - Delete(tprefix); - Delete(tsuffix); - Delete(targs); - Delete(tparms); - return type; -} - /* ----------------------------------------------------------------------------- * template_locate() * @@ -506,8 +413,10 @@ template_locate(String *name, Parm *tparms, Symtab *tscope) { /* Add default values from generic template */ if (templ) { + Symtab *tsdecl = Getattr(templ,"sym:symtab"); + targs = Getattr(templ,"templateparms"); - Swig_cparse_template_defargs(parms, targs, tscope); + Swig_symbol_template_defargs(parms, targs, tscope, tsdecl); } @@ -516,10 +425,8 @@ template_locate(String *name, Parm *tparms, Symtab *tscope) { while (p) { SwigType *ty = Getattr(p,"type"); if (ty) { - SwigType *rt = Swig_symbol_typedef_reduce(ty,tscope); - SwigType *nt = Swig_symbol_type_qualify(rt,tscope); + SwigType *nt = Swig_symbol_type_qualify(ty,tscope); Setattr(p,"type",nt); - Delete(rt); } p = nextSibling(p); } @@ -537,6 +444,16 @@ template_locate(String *name, Parm *tparms, Symtab *tscope) { 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 (Strcmp(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; if (Strcmp(nodeType(n),"template") == 0) goto success; @@ -562,16 +479,17 @@ template_locate(String *name, Parm *tparms, Symtab *tscope) { while (p) { String *t; t = Getattr(p,"type"); + if (!t) t = Getattr(p,"value"); if (t) { - String *tbase = SwigType_base(t); - t = SwigType_default(t); - Replaceid(t,"enum SWIGTYPE",tbase); - Replaceid(t,"SWIGTYPE",tbase); - Printf(rname,"%s",t); - Delete(t); - } else { - String *v = Getattr(p,"value"); - Printf(rname,"%s",v); + 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); + Printf(rname,"%s",td); + Delete(tb); + Delete(ty); + Delete(td); } p = nextSibling(p); if (p) { @@ -600,13 +518,13 @@ template_locate(String *name, Parm *tparms, Symtab *tscope) { String *t,*tn; sprintf(tmp,"$%d",i); t = Getattr(p,"type"); + if (!t) t = Getattr(p,"value"); if (t) { - tn = SwigType_base(t); + String *ty = Swig_symbol_typedef_reduce(t,tscope); + tn = SwigType_base(ty); Replaceid(ss,tmp,tn); Delete(tn); - } else { - String *v = Getattr(p,"value"); - Replaceid(ss,tmp,v); + Delete(ty); } i++; p = nextSibling(p); diff --git a/Source/Include/swigwarn.h b/Source/Include/swigwarn.h index fe8d99c72..256a7c529 100644 --- a/Source/Include/swigwarn.h +++ b/Source/Include/swigwarn.h @@ -147,7 +147,7 @@ #define WARN_TYPEMAP_TYPECHECK 467 #define WARN_TYPEMAP_THROW 468 #define WARN_TYPEMAP_DIRECTORIN_UNDEF 469 -#define WARN_TYPEMAP_THREAD_UNSAFE 470 +#define WARN_TYPEMAP_DIRECTOROUT_CREF 470 /* -- General code generation -- */ diff --git a/Source/Modules/allocate.cxx b/Source/Modules/allocate.cxx index 7b2001b73..cc92117ab 100644 --- a/Source/Modules/allocate.cxx +++ b/Source/Modules/allocate.cxx @@ -213,6 +213,7 @@ class Allocate : public Dispatcher { for (int i = 0; i < Len(abstract); i++) { Node *nn = Getitem(abstract,i); String *name = Getattr(nn,"name"); + if (!name) continue; String *base_decl = Getattr(nn,"decl"); if (base_decl) base_decl = SwigType_typedef_resolve_all(base_decl); if (Strstr(name,"~")) continue; /* Don't care about destructors */ diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index d5e357087..1016f1b56 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -91,8 +91,9 @@ int Dispatcher::emit_one(Node *n) { char *tag = Char(nodeType(n)); if (!tag) { - Printf(stderr,"SWIG: Fatal internal error. Malformed parse tree node!\n"); - return SWIG_ERROR; + /* Printf(stderr,"SWIG: Fatal internal error. Malformed parse tree + node!\n"); */ + return SWIG_OK; } /* Do not proceed if marked with an error */ diff --git a/Source/Modules/tcl8.cxx b/Source/Modules/tcl8.cxx index 7272c12ca..9e324e935 100644 --- a/Source/Modules/tcl8.cxx +++ b/Source/Modules/tcl8.cxx @@ -668,7 +668,7 @@ public: * ------------------------------------------------------------ */ virtual int classHandler(Node *n) { - + static Hash* emitted = NewHash(); String *mangled_classname = 0; String *real_classname = 0; @@ -698,6 +698,9 @@ public: real_classname = Getattr(n,"name"); mangled_classname = Swig_name_mangle(real_classname); + if (Getattr(emitted,mangled_classname)) return SWIG_NOWRAP; + Setattr(emitted,mangled_classname,"1"); + attr_tab = NewString(""); Printf(attr_tab, "static swig_attribute swig_"); Printv(attr_tab, mangled_classname, "_attributes[] = {\n", NIL); diff --git a/Source/Swig/misc.c b/Source/Swig/misc.c index 8ef4277ee..262497436 100644 --- a/Source/Swig/misc.c +++ b/Source/Swig/misc.c @@ -230,7 +230,11 @@ String *Swig_string_mangle(const String *s) { char *pc, *cb; String *b = Copy(s); if (SwigType_istemplate(b)) { - String *t = SwigType_namestr(b); + String *st = Swig_symbol_template_deftype(b, 0); + String *sq = Swig_symbol_type_qualify(st,0); + String *t = SwigType_namestr(sq); + Delete(st); + Delete(sq); Delete(b); b = t ; } diff --git a/Source/Swig/naming.c b/Source/Swig/naming.c index 64ccfcce0..c9acd5101 100644 --- a/Source/Swig/naming.c +++ b/Source/Swig/naming.c @@ -639,6 +639,14 @@ Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl, Delete(tname); } } + if (name && SwigType_istemplate(name)) { + String *dname = Swig_symbol_template_deftype(name,0); + if (Strcmp(dname,name)) { + Swig_features_get(features, prefix, dname, decl, node); + } + Delete(dname); + } + Delete(rname); Delete(rdecl); } @@ -700,6 +708,14 @@ Swig_feature_set(Hash *features, const String_or_char *name, SwigType *decl, con attribs = nextSibling(attribs); } } + + if (name && SwigType_istemplate(name)) { + String *dname = Swig_symbol_template_deftype(name,0); + if (Strcmp(dname,name)) { + Swig_feature_set(features, dname, decl, featurename, value, featureattribs); + } + Delete(dname); + } } diff --git a/Source/Swig/stype.c b/Source/Swig/stype.c index 4d56d33a0..db9e18772 100644 --- a/Source/Swig/stype.c +++ b/Source/Swig/stype.c @@ -898,20 +898,25 @@ String *SwigType_lcaststr(SwigType *s, const String_or_char *name) { return result; } + /* keep old mangling since Java codes need it */ String *SwigType_manglestr_default(SwigType *s) { char *c; String *result,*base; SwigType *lt; - SwigType *ss = SwigType_typedef_resolve_all(s); + SwigType *sr = SwigType_typedef_qualified(s); + SwigType *ss = SwigType_typedef_resolve_all(sr); + s = ss; - if (SwigType_istemplate(s)) { - String *st = ss; - ss = Swig_cparse_template_deftype(st, 0); + if (SwigType_istemplate(ss)) { + SwigType *ty = Swig_symbol_template_deftype(ss,0); + Delete(ss); + ss = ty; s = ss; - Delete(st); } + Delete(sr); + lt = SwigType_ltype(s); result = SwigType_prefix(lt); base = SwigType_base(lt); diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h index dff8c1200..357b4e06c 100644 --- a/Source/Swig/swig.h +++ b/Source/Swig/swig.h @@ -226,7 +226,7 @@ extern void SwigType_add_function(SwigType *t, ParmList *parms); extern void SwigType_add_template(SwigType *t, ParmList *parms); extern SwigType *SwigType_pop_function(SwigType *t); extern ParmList *SwigType_function_parms(SwigType *t); -extern List *SwigType_split(SwigType *t); +extern List *SwigType_split(const SwigType *t); extern String *SwigType_pop(SwigType *t); extern void SwigType_push(SwigType *t, SwigType *s); extern List *SwigType_parmlist(const SwigType *p); @@ -253,12 +253,12 @@ extern int SwigType_istemplate(const SwigType *t); extern int SwigType_isenum(SwigType *t); extern int SwigType_check_decl(SwigType *t, const String_or_char *decl); extern SwigType *SwigType_strip_qualifiers(SwigType *t); -extern String *SwigType_base(SwigType *t); +extern String *SwigType_base(const SwigType *t); extern String *SwigType_namestr(const SwigType *t); -extern String *SwigType_templateprefix(SwigType *t); +extern String *SwigType_templateprefix(const SwigType *t); extern String *SwigType_templatesuffix(const SwigType *t); -extern String *SwigType_templateargs(SwigType *t); -extern String *SwigType_prefix(SwigType *t); +extern String *SwigType_templateargs(const SwigType *t); +extern String *SwigType_prefix(const SwigType *t); extern int SwigType_array_ndim(SwigType *t); extern String *SwigType_array_getdim(SwigType *t, int n); extern void SwigType_array_setdim(SwigType *t, int n, const String_or_char *rep); @@ -267,6 +267,9 @@ 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); +extern void SwigType_template_defargs(Parm *parms, Parm *targs, Symtab *tscope, Symtab *tsdecl); +extern SwigType* SwigType_template_deftype(const SwigType *type, Symtab *tscope); + /* --- Type-system managment --- */ extern void SwigType_typesystem_init(); extern int SwigType_typedef(SwigType *type, String_or_char *name); @@ -316,10 +319,14 @@ extern Node *Swig_symbol_isoverloaded(Node *node); extern void Swig_symbol_remove(Node *node); extern void Swig_symbol_alias(String_or_char *aliasname, Symtab *tab); extern void Swig_symbol_inherit(Symtab *tab); -extern SwigType *Swig_symbol_type_qualify(SwigType *ty, Symtab *tab); +extern SwigType *Swig_symbol_type_qualify(const SwigType *ty, Symtab *tab); extern String *Swig_symbol_string_qualify(String *s, Symtab *tab); extern SwigType *Swig_symbol_typedef_reduce(SwigType *ty, Symtab *tab); +extern void Swig_symbol_template_defargs(Parm *parms, Parm *targs, Symtab *tscope, Symtab *tsdecl); +extern SwigType *Swig_symbol_template_deftype(const SwigType *type, Symtab *tscope); +extern SwigType *Swig_symbol_template_param_eval(const SwigType *p, Symtab *symtab); + /* --- Parameters and Parameter Lists --- */ /* Parameters are really just hidden behind a DOH object. The following diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c index 1d5fd92de..86987cb3d 100644 --- a/Source/Swig/symbol.c +++ b/Source/Swig/symbol.c @@ -15,6 +15,7 @@ char cvsroot_symbol_c[] = "$Header$"; #include "swigwarn.h" #include +/*#define SWIG_DEBUG*/ /* ----------------------------------------------------------------------------- * Synopsis * @@ -433,6 +434,17 @@ Swig_symbol_cadd(String_or_char *name, Node *n) { */ if (!name) return; + if (SwigType_istemplate(name)) { + String *dname = Swig_symbol_template_deftype(name,0); + if (Strcmp(dname,name)) { + Swig_symbol_cadd(dname, n); + } + Delete(dname); + } + +#ifdef SWIG_DEBUG + Printf(stderr,"symbol_cadd %s %x\n", name, n); +#endif cn = Getattr(ccurrent,name); if (cn && (Getattr(cn,"sym:typename"))) { @@ -558,7 +570,7 @@ Swig_symbol_add(String_or_char *symname, Node *n) { */ name = Getattr(n,"name"); - if (name) { + if (name && Len(name)) { Swig_symbol_cadd(name,n); } @@ -746,11 +758,16 @@ symbol_lookup(String_or_char *name, Symtab *symtab, int (*check)(Node *n)) { Node *n; List *inherit; Hash *sym = Getattr(symtab,"csymtab"); - if (Getmark(symtab)) return 0; Setmark(symtab,1); + n = Getattr(sym,name); + +#ifdef SWIG_DEBUG + Printf(stderr,"symbol_look %s %x %x %s\n", name, n, symtab, Getattr(symtab,"name")); +#endif + if (n) { /* if a check-function is defined. Call it to determine a match */ if (check) { @@ -770,6 +787,17 @@ symbol_lookup(String_or_char *name, Symtab *symtab, int (*check)(Node *n)) { } } + if (!n && SwigType_istemplate(name)) { + String *dname = 0; + Setmark(symtab,0); + dname = Swig_symbol_template_deftype(name,symtab); + if (Strcmp(name,dname)) { + n = symbol_lookup(dname, symtab, check); + } + Delete(dname); + if (n) return n; + } + inherit = Getattr(symtab,"inherit"); if (inherit) { int i,len; @@ -782,6 +810,7 @@ symbol_lookup(String_or_char *name, Symtab *symtab, int (*check)(Node *n)) { } } } + Setmark(symtab,0); return 0; } @@ -825,6 +854,7 @@ symbol_lookup_qualified(String_or_char *name, Symtab *symtab, String *prefix, in if (!name) return st; n = symbol_lookup(name, st,checkfunc); } + Delete(qname); if (!n) { if (!local) { @@ -936,6 +966,7 @@ Swig_symbol_clookup_check(String_or_char *name, Symtab *n, int (*checkfunc)(Node if (Swig_scopename_check(nname)) { s = symbol_lookup_qualified(nname,global_scope,0,0,checkfunc); } + Delete(nname); } else { String *prefix = Swig_scopename_prefix(name); if (prefix) { @@ -993,7 +1024,11 @@ Swig_symbol_clookup_local(String_or_char *name, Symtab *n) { if (Swig_scopename_check(name)) { if (Strncmp(name,"::",2) == 0) { - s = symbol_lookup_qualified(Char(name)+2,global_scope,0,0,0); + String *nname = NewString(Char(name)+2); + if (Swig_scopename_check(nname)) { + s = symbol_lookup_qualified(nname,global_scope,0,0,0); + } + Delete(nname); } else { s = symbol_lookup_qualified(name,hsym,0,0,0); } @@ -1036,7 +1071,11 @@ Swig_symbol_clookup_local_check(String_or_char *name, Symtab *n, int (*checkfunc if (Swig_scopename_check(name)) { if (Strncmp(name,"::",2) == 0) { - s = symbol_lookup_qualified(Char(name)+2,global_scope,0,0,checkfunc); + String *nname = NewString(Char(name)+2); + if (Swig_scopename_check(nname)) { + s = symbol_lookup_qualified(nname,global_scope,0,0,checkfunc); + } + Delete(nname); } else { s = symbol_lookup_qualified(name,hsym,0,0,checkfunc); } @@ -1161,6 +1200,9 @@ Swig_symbol_qualified(Node *n) { symtab = Getattr(n,"sym:symtab"); } if (!symtab) return NewString(""); +#ifdef SWIG_DEBUG + Printf(stderr,"symbol_qscope %s %x %s\n", Getattr(n,"name"), symtab,Getattr(symtab,"name")); +#endif return Swig_symbol_qualifiedscopename(symtab); } @@ -1181,8 +1223,48 @@ Swig_symbol_isoverloaded(Node *n) { * Create a fully qualified type name * ----------------------------------------------------------------------------- */ +static int no_constructor(Node *n) { + SwigType *type = nodeType(n); +#ifdef SWIG_DEBUG + Printf(stderr,"node type %s\n", Getattr(n,"name"), type); +#endif + return type ? (Strcmp(type,"constructor") != 0): 1; +} + +static SwigType * +Swig_symbol_template_qualify(const SwigType *e, Symtab *st) { + String *tprefix, *tsuffix; + SwigType *qprefix; + List *targs; + Iterator ti; + tprefix = SwigType_templateprefix(e); + tsuffix = SwigType_templatesuffix(e); + qprefix = Swig_symbol_type_qualify(tprefix,st); + targs = SwigType_parmlist(e); + Printf(qprefix,"<("); + for (ti = First(targs); ti.item;) { + String *qparm = Swig_symbol_type_qualify(ti.item,st); + String *vparm = Swig_symbol_template_param_eval(qparm, st); + Append(qprefix,vparm); + ti = Next(ti); + if (ti.item) { + Putc(',',qprefix); + } + Delete(qparm); + Delete(vparm); + } + Append(qprefix,")>"); + Append(qprefix,tsuffix); + Delete(tprefix); + Delete(tsuffix); +#ifdef SWIG_DEBUG + Printf(stderr,"symbol_temp_qual %s %s\n", e, qprefix); +#endif + return qprefix; +} + SwigType * -Swig_symbol_type_qualify(SwigType *t, Symtab *st) { +Swig_symbol_type_qualify(const SwigType *t, Symtab *st) { List *elements; String *result; int i,len; @@ -1194,75 +1276,29 @@ Swig_symbol_type_qualify(SwigType *t, Symtab *st) { for (i = 0; i < len; i++) { String *e = Getitem(elements,i); if (SwigType_issimple(e)) { - Node *n = Swig_symbol_clookup(e,st); + Node *n = Swig_symbol_clookup_check(e,st,no_constructor); if (n) { String *name = Getattr(n,"name"); Clear(e); Append(e,name); +#ifdef SWIG_DEBUG + Printf(stderr,"symbol_qual_ei %d %s %s %x\n", i, name, e, st); +#endif if (!Swig_scopename_check(name)) { String *qname = Swig_symbol_qualified(n); if (Len(qname)) { Insert(e,0,"::"); Insert(e,0,qname); } +#ifdef SWIG_DEBUG + Printf(stderr,"symbol_qual_sc %d %s %s %x\n", i, qname, e, st); +#endif Delete(qname); } } else if (SwigType_istemplate(e)) { - String *tprefix, *tsuffix; - SwigType *qprefix; - List *targs; - Iterator ti; - tprefix = SwigType_templateprefix(e); - tsuffix = SwigType_templatesuffix(e); - qprefix = Swig_symbol_type_qualify(tprefix,st); - targs = SwigType_parmlist(e); - Printf(qprefix,"<("); - for (ti = First(targs); ti.item;) { - String *qparm = Swig_symbol_type_qualify(ti.item,st); - while (1) { - /* It is possible for an integer to show up here. If so, we need to evaluate it */ - Node *nn = Swig_symbol_clookup(qparm,st); - if (nn) { - SwigType *nt = nodeType(nn); - if (Strcmp(nt,"cdecl") == 0) { - String *nv = Getattr(nn,"value"); - if (nv) { - Clear(qparm); - Append(qparm,nv); - } else { - break; - } - } else if (Strcmp(nt,"enumitem") == 0) { - String *qn = Swig_symbol_qualified(nn); - if (Len(qn)) { - Append(qn,"::"); - Append(qn,Getattr(nn,"name")); - Clear(qparm); - Append(qparm,qn); - } - Delete(qn); - break; - } else { - break; - } - } else { - break; - } - } - Append(qprefix,qparm); - ti = Next(ti); - if (ti.item) { - Putc(',',qprefix); - } - Delete(qparm); - } - Append(qprefix,")>"); - Append(qprefix,tsuffix); + SwigType *ty = Swig_symbol_template_qualify(e,st); Clear(e); - Append(e,qprefix); - Delete(tprefix); - Delete(tsuffix); - Delete(qprefix); + Append(e,ty); } if (Strncmp(e,"::",2) == 0) { Delitem(e,0); @@ -1289,6 +1325,9 @@ Swig_symbol_type_qualify(SwigType *t, Symtab *st) { } } Delete(elements); +#ifdef SWIG_DEBUG + Printf(stderr,"symbol_qualify %s %s %x %s\n", t, result, st, st ?Getattr(st,"name"): 0); +#endif return result; } @@ -1298,6 +1337,48 @@ Swig_symbol_type_qualify(SwigType *t, Symtab *st) { * Chase a typedef through symbol tables looking for a match. * ----------------------------------------------------------------------------- */ +static +SwigType *Swig_symbol_template_reduce(SwigType *qt, Symtab *ntab) +{ + Iterator pi; + Parm *p; + List *parms = SwigType_parmlist(qt); + String *tprefix = SwigType_templateprefix(qt); + String *tsuffix = SwigType_templatesuffix(qt); + String *qprefix = SwigType_typedef_qualified(tprefix); + Printv(qprefix,"<(",NIL); + pi = First(parms); + while ((p = pi.item)) { + String *np; + String *tp = Swig_symbol_typedef_reduce(p, ntab); + String *qp = Swig_symbol_type_qualify(tp, ntab); + Node *n = Swig_symbol_clookup(qp,ntab); + if (n) { + String *qual = Swig_symbol_qualified(n); + np = Copy(Getattr(n,"name")); + tp = np; + if (qual) { + Insert(np,0,"::"); + Insert(np,0,qual); + Delete(qual); + } + } else { + np = qp; + } + Append(qprefix,np); + pi= Next(pi); + if (pi.item) { + Append(qprefix,","); + } + Delete(qp); + Delete(tp); + } + Append(qprefix,")>"); + Insert(tsuffix, 0, qprefix); + return tsuffix; +} + + SwigType *Swig_symbol_typedef_reduce(SwigType *ty, Symtab *tab) { SwigType *prefix, *base; Node *n; @@ -1309,8 +1390,20 @@ SwigType *Swig_symbol_typedef_reduce(SwigType *ty, Symtab *tab) { n = Swig_symbol_clookup(base,tab); if (!n) { Delete(base); - Delete(prefix); - return Copy(ty); + if (SwigType_istemplate(ty)) { + SwigType *qt = Swig_symbol_template_reduce(ty,tab); + Append(prefix,qt); +#ifdef SWIG_DEBUG + Printf(stderr,"symbol_reduce %s %s\n", ty, prefix); +#endif + return prefix; + } else { + Delete(prefix); +#ifdef SWIG_DEBUG + Printf(stderr,"symbol_reduce %s %s\n", ty, ty); +#endif + return Copy(ty); + } } if (Strcmp(nodeType(n),"using") == 0) { String *uname = Getattr(n,"uname"); @@ -1319,6 +1412,9 @@ SwigType *Swig_symbol_typedef_reduce(SwigType *ty, Symtab *tab) { if (!n) { Delete(base); Delete(prefix); +#ifdef SWIG_DEBUG + Printf(stderr,"symbol_reduce %s %s\n", ty, ty); +#endif return Copy(ty); } } @@ -1354,52 +1450,23 @@ SwigType *Swig_symbol_typedef_reduce(SwigType *ty, Symtab *tab) { rt = Swig_symbol_typedef_reduce(nt, ntab); qt = Swig_symbol_type_qualify(rt, ntab); if (SwigType_istemplate(qt)) { - Iterator pi; - Parm *p; - List *parms = SwigType_parmlist(qt); - String *tprefix = SwigType_templateprefix(qt); - String *tsuffix = SwigType_templatesuffix(qt); - String *qprefix = SwigType_typedef_qualified(tprefix); - Printv(qprefix,"<(",NIL); - pi = First(parms); - while ((p = pi.item)) { - String *np; - String *tp = 0; - String *qp = Swig_symbol_type_qualify(p, ntab); - Node *n = Swig_symbol_clookup(qp,ntab); - if (n) { - String *qual = Swig_symbol_qualified(n); - np = Copy(Getattr(n,"name")); - tp = np; - if (qual) { - Insert(np,0,"::"); - Insert(np,0,qual); - Delete(qual); - } - } else { - np = qp; - } - Append(qprefix,np); - pi= Next(pi); - if (pi.item) { - Append(qprefix,","); - } - Delete(qp); - Delete(tp); - } - Append(qprefix,")>"); - Insert(tsuffix, 0, qprefix); + SwigType *qtr = Swig_symbol_template_reduce(qt,ntab); Delete(qt); - qt = tsuffix; + qt = qtr; } Delete(nt); Delete(rt); - /* Printf(stderr,"reduce %s %s\n", ty, qt); */ +#ifdef SWIG_DEBUG + Printf(stderr,"symbol_reduce %s %s\n", qt, ty); +#endif return qt; } } Delete(base); Delete(prefix); +#ifdef SWIG_DEBUG + Printf(stderr,"symbol_reduce %s %s\n", ty, ty); +#endif return Copy(ty); } @@ -1446,3 +1513,154 @@ Swig_symbol_string_qualify(String *s, Symtab *st) { return r; } + +/* ----------------------------------------------------------------------------- + * Swig_symbol_template_defargs() + * + * Apply default arg from generic template default args + * ----------------------------------------------------------------------------- */ + + +void +Swig_symbol_template_defargs(Parm *parms, Parm *targs, Symtab *tscope, Symtab *tsdecl) { + if (Len(parms) < Len(targs)) { + Parm *lp = parms; + Parm *p = lp; + Parm *tp = targs; + while(p && tp) { + p = nextSibling(p); + tp = nextSibling(tp); + if (p) lp = p; + } + while (tp) { + String *value = Getattr(tp,"value"); + if (value) { + Parm *cp; + Parm *ta = targs; + Parm *p = parms; + SwigType *nt = Swig_symbol_string_qualify(value,tsdecl); + SwigType *ntq = 0; +#ifdef SWIG_DEBUG + Printf(stderr,"value %s %s %s\n",value, nt,tsdecl?Getattr(tsdecl,"name") : tsdecl); +#endif + while(p && ta) { + String *name = Getattr(ta,"name"); + String *value = Getattr(p,"value") ? Getattr(p,"value") : Getattr(p,"type"); + String *ttq = Swig_symbol_type_qualify(value,tscope); + /* value = SwigType_typedef_resolve_all(value);*/ + Replaceid(nt, name, ttq); + p = nextSibling(p); + ta = nextSibling(ta); + Delete(ttq); + } + ntq = Swig_symbol_type_qualify(nt,tsdecl); + if (SwigType_istemplate(ntq)) { + String *ty = Swig_symbol_template_deftype(ntq, tscope); + Delete(ntq); + ntq = ty; + } + /* Printf(stderr,"value %s %s %s\n",value,ntr,ntq);*/ + cp = NewParm(ntq,0); + set_nextSibling(lp,cp); + lp = cp; + tp = nextSibling(tp); + Delete(nt); + Delete(ntq); + } else { + tp = 0; + } + } + } +} + +/* ----------------------------------------------------------------------------- + * Swig_symbol_template_deftype() + * + * Apply default args to generic template type + * ----------------------------------------------------------------------------- */ +SwigType* +Swig_symbol_template_deftype(const SwigType *type, Symtab *tscope) { + String *result = 0; + String *prefix = SwigType_prefix(type); + String *base = SwigType_base(type); + String *tprefix = SwigType_templateprefix(base); + String *targs = SwigType_templateargs(base); + String *tsuffix = SwigType_templatesuffix(base); + ParmList *tparms = SwigType_function_parms(targs); + Node *tempn = Swig_symbol_clookup_local(tprefix,tscope); + /* Printf(stderr,"deftype type %s \n", type);*/ + if (tempn) { + ParmList *tnargs = Getattr(tempn,"templateparms"); + Parm *p; + Symtab *tsdecl = Getattr(tempn,"sym:symtab"); + + /* Printf(stderr,"deftype type %s %s %s %s\n", tprefix, targs, tsuffix);*/ + Append(tprefix,"<("); + Swig_symbol_template_defargs(tparms, tnargs,tscope,tsdecl); + p = tparms; + while (p) { + SwigType *ptype = Getattr(p,"type"); + SwigType *ttr = ptype ? ptype : Getattr(p,"value"); + SwigType *ttf = Swig_symbol_type_qualify(ttr,tscope); + SwigType *ttq = Swig_symbol_template_param_eval(ttf,tscope); + SwigType *ttd = 0; + if (SwigType_istemplate(ttq)) { + ttd = Swig_symbol_template_deftype(ttq, tscope); + ttq = ttd; + } + Append(tprefix,ttq); + p = nextSibling(p); + if (p) Putc(',',tprefix); + Delete(ttr); + Delete(ttf); + Delete(ttd); + } + Append(tprefix,")>"); + Append(tprefix,tsuffix); + Append(prefix,tprefix); + /* Printf(stderr,"deftype %s %s \n", type, tprefix); */ + result = Copy(prefix); + } else { + result = Copy(type); + } + Delete(prefix); + Delete(base); + Delete(tprefix); + Delete(tsuffix); + Delete(targs); + Delete(tparms); + return result; +} + +SwigType *Swig_symbol_template_param_eval(const SwigType *p, Symtab *symtab) +{ + String *value = Copy(p); + Node *lastnode = 0; + while (1) { + Node *n = Swig_symbol_clookup(value,symtab); + if (n == lastnode) break; + lastnode = n; + if (n) { + if (Strcmp(nodeType(n),"enumitem") == 0) { + /* An enum item. Generate a fully qualified name */ + String *qn = Swig_symbol_qualified(n); + if (Len(qn)) { + Append(qn,"::"); + Append(qn,Getattr(n,"name")); + Delete(value); + value = qn; + continue; + } else { + Delete(qn); + break; + } + } else if ((Strcmp(nodeType(n),"cdecl") == 0) && (Getattr(n,"value"))) { + Delete(value); + value = Copy(Getattr(n,"value")); + continue; + } + } + break; + } + return value; +} diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c index e19c1572a..eb7c6f756 100644 --- a/Source/Swig/typemap.c +++ b/Source/Swig/typemap.c @@ -51,12 +51,14 @@ static Hash* get_typemap(int tm_scope, SwigType* type) Hash *tm = 0; SwigType* dtype = 0; if (SwigType_istemplate(type)) { - dtype = Swig_cparse_template_deftype(type,0); + String *ty = Swig_symbol_template_deftype(type,0); + dtype = Swig_symbol_type_qualify(ty,0); /* Printf(stderr,"gettm %s %s\n", type, dtype);*/ type = dtype; + Delete(ty); } tm = Getattr(typemaps[tm_scope],type); - if (dtype) Delete(dtype); + Delete(dtype); return tm; } @@ -64,12 +66,14 @@ static void set_typemap(int tm_scope, SwigType* type, Hash* tm) { SwigType* dtype = 0; if (SwigType_istemplate(type)) { - dtype = Swig_cparse_template_deftype(type,0); + String *ty = Swig_symbol_template_deftype(type,0); + dtype = Swig_symbol_type_qualify(ty,0); /* Printf(stderr,"settm %s %s\n", type, dtype);*/ type = dtype; + Delete(ty); } Setattr(typemaps[tm_scope],Copy(type),tm); - if (dtype) Delete(dtype); + Delete(dtype); } diff --git a/Source/Swig/typeobj.c b/Source/Swig/typeobj.c index 3db8c6164..a4a35755d 100644 --- a/Source/Swig/typeobj.c +++ b/Source/Swig/typeobj.c @@ -229,7 +229,7 @@ SwigType_parm(SwigType *t) { * Splits a type into it's component parts and returns a list of string. * ----------------------------------------------------------------------------- */ -List *SwigType_split(SwigType *t) { +List *SwigType_split(const SwigType *t) { DOH *item; List *list; char *c; @@ -769,8 +769,9 @@ SwigType_add_template(SwigType *t, ParmList *parms) { * ----------------------------------------------------------------------------- */ String * -SwigType_templateprefix(SwigType *t) { - char *c,*s; +SwigType_templateprefix(const SwigType *t) { + const char *c; + const char *s; s = Char(t); c = s; @@ -796,7 +797,7 @@ SwigType_templateprefix(SwigType *t) { String * SwigType_templatesuffix(const SwigType *t) { - char *c; + const char *c; c = Char(t); while (*c) { if ((*c == '<') && (*(c+1) == '(')) { @@ -821,9 +822,9 @@ SwigType_templatesuffix(const SwigType *t) { * ----------------------------------------------------------------------------- */ String * -SwigType_templateargs(SwigType *t) { - char *c; - char *start; +SwigType_templateargs(const SwigType *t) { + const char *c; + const char *start; c = Char(t); while (*c) { if ((*c == '<') && (*(c+1) == '(')) { @@ -862,7 +863,7 @@ SwigType_istemplate(const SwigType *t) { * ----------------------------------------------------------------------------- */ SwigType * -SwigType_base(SwigType *t) { +SwigType_base(const SwigType *t) { char *c; char *lastop = 0; c = Char(t); @@ -915,7 +916,7 @@ SwigType_base(SwigType *t) { * ----------------------------------------------------------------------------- */ String * -SwigType_prefix(SwigType *t) { +SwigType_prefix(const SwigType *t) { char *c, *d; String *r = 0; diff --git a/Source/Swig/typesys.c b/Source/Swig/typesys.c index 8fcba3f4b..51b4f7cfd 100644 --- a/Source/Swig/typesys.c +++ b/Source/Swig/typesys.c @@ -862,6 +862,7 @@ SwigType *SwigType_typedef_qualified(SwigType *t) elements = SwigType_split(t); len = Len(elements); for (i = 0; i < len; i++) { + String *ty = 0; String *e = Getitem(elements,i); if (SwigType_issimple(e)) { if (!SwigType_istemplate(e)) { @@ -927,7 +928,10 @@ SwigType *SwigType_typedef_qualified(SwigType *t) String *tsuffix; Iterator pi; Parm *p; - List *parms = SwigType_parmlist(e); + List *parms; + ty = Swig_symbol_template_deftype(e,current_symtab); + e = ty; + parms = SwigType_parmlist(e); tprefix = SwigType_templateprefix(e); tsuffix = SwigType_templatesuffix(e); qprefix = SwigType_typedef_qualified(tprefix); @@ -996,6 +1000,7 @@ SwigType *SwigType_typedef_qualified(SwigType *t) Delitem(e,0); } Append(result,e); + Delete(ty); } else if (SwigType_isfunction(e)) { List *parms = SwigType_parmlist(e); String *s = NewString("f("); @@ -1588,10 +1593,14 @@ SwigType_inherit(String *derived, String *base, String *cast) { /* Printf(stdout,"'%s' --> '%s' '%s'\n", derived, base, cast); */ if (SwigType_istemplate(derived)) { - derived = SwigType_typedef_qualified(SwigType_typedef_resolve_all(derived)); + String *ty = SwigType_typedef_resolve_all(derived); + derived = SwigType_typedef_qualified(ty); + Delete(ty); } if (SwigType_istemplate(base)) { - base = SwigType_typedef_qualified(SwigType_typedef_resolve_all(base)); + String *ty = SwigType_typedef_resolve_all(base); + base = SwigType_typedef_qualified(ty); + Delete(ty); } /* Printf(stdout,"'%s' --> '%s' '%s'\n", derived, base, cast);*/