fixes for namespaces + class declarations + %template directive

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@6576 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Marcelo Matus 2004-11-01 08:38:21 +00:00
commit 3fc7b773d9
6 changed files with 377 additions and 100 deletions

View file

@ -57,9 +57,9 @@ extern int need_redefined_warn(Node* a, Node* b, int InClass);
/* templ.c */
extern void Swig_cparse_template_defargs(Parm *parms, Parm *targs);
extern int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms);
extern Node *Swig_cparse_template_locate(String *name, ParmList *tparms);
extern void Swig_cparse_template_defargs(Parm *parms, Parm *targs, 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);
#ifdef __cplusplus

View file

@ -713,6 +713,102 @@ static void merge_extensions(Node *cls, Node *am) {
return bases;
}
/* If the class name is qualified. We need to create or lookup namespace entries */
static Node *nspace = 0;
static Node *nspace_inner = 0;
static String *resolve_namespace_class(String *cname) {
nspace = 0;
nspace_inner = 0;
if (Swig_scopename_check(cname)) {
Node *ns;
String *prefix = Swig_scopename_prefix(cname);
String *base = Swig_scopename_last(cname);
if (!prefix) {
/* Use the global scope */
Symtab *symtab = Swig_symbol_current();
Node *pn = parentNode(symtab);
while (pn) {
symtab = pn;
pn = parentNode(symtab);
if (!pn) break;
}
Swig_symbol_setscope(symtab);
Namespaceprefix = 0;
nspace = new_node("namespace");
Setattr(nspace,"symtab", symtab);
nspace_inner = nspace;
return base;
}
/* Try to locate the scope */
ns = Swig_symbol_clookup(prefix,0);
if (!ns) {
Swig_error(cparse_file,cparse_line,"Undefined scope '%s'\n", prefix);
} else {
if (Strcmp(nodeType(ns),"namespace") != 0) {
Swig_error(cparse_file,cparse_line,"'%s' is not defined as namespace.\n", prefix);
ns = 0;
} else {
Symtab *nscope = Getattr(ns,"symtab");
String *tname = Swig_symbol_qualifiedscopename(0);
String *nname = Swig_symbol_qualifiedscopename(nscope);
if (tname && (Strcmp(tname,nname) == 0)) {
ns = 0;
cname = base;
}
Delete(tname);
Delete(nname);
}
if (ns) {
List *scopes;
String *sname;
Iterator si;
String *name = NewString(prefix);
scopes = NewList();
while (name) {
String *base = Swig_scopename_last(name);
String *tprefix = Swig_scopename_prefix(name);
Insert(scopes,0,base);
Delete(name);
name = tprefix;
}
for (si = First(scopes); si.item; si = Next(si)) {
Node *ns1,*ns2;
sname = si.item;
ns1 = Swig_symbol_clookup(sname,0);
assert(ns1);
if (Strcmp(nodeType(ns1),"namespace") == 0) {
if (Getattr(ns1,"alias")) {
ns1 = Getattr(ns1,"namespace");
}
} else {
assert(0);
}
ns2 = new_node("namespace");
Setattr(ns2,"name",sname);
Setattr(ns2,"symtab", Getattr(ns1,"symtab"));
add_symbols(ns2);
Swig_symbol_setscope(Getattr(ns1,"symtab"));
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
if (nspace_inner) {
if (Getattr(nspace_inner,"symtab") != Getattr(ns2,"symtab")) {
appendChild(nspace_inner,ns2);
}
}
nspace_inner = ns2;
if (!nspace) nspace = ns2;
}
cname = base;
}
}
Delete(prefix);
}
return cname;
}
/* Structures for handling code fragments built for nested classes */
typedef struct Nested {
@ -2049,7 +2145,6 @@ types_directive : TYPES LPAREN parms RPAREN SEMI {
template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN valparms GREATERTHAN SEMI {
Parm *p, *tp;
Node *n;
Node *nspace = 0, *nspace_inner = 0;
Node *tnode = 0;
Symtab *tscope = 0;
int specialized = 0;
@ -2058,78 +2153,17 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
tscope = Swig_symbol_current(); /* Get the current scope */
/* If the template name is qualified. We need to create or lookup namespace entries */
if (Swig_scopename_check($5)) {
String *prefix, *base;
Node *ns;
prefix = Swig_scopename_prefix($5);
base = Swig_scopename_last($5);
/* If the class name is qualified. We need to create or lookup namespace entries */
$5 = resolve_namespace_class($5);
/*
we use the new namespace entry 'nspace' only to
emit the template node. The template parameters are
resolved in the current 'tscope'.
/* Try to locate the scope */
ns = Swig_symbol_clookup(prefix,0);
if (!ns) {
Swig_error(cparse_file,cparse_line,"Undefined scope '%s'\n", prefix);
} else {
if (Strcmp(nodeType(ns),"namespace") != 0) {
Swig_error(cparse_file,cparse_line,"'%s' is not defined as namespace.\n", prefix);
ns = 0;
} else {
/* Swig_symbol_setscope(Getattr(ns,"symtab"));
Namespaceprefix = Swig_symbol_qualifiedscopename(0); */
}
}
if (ns && Namespaceprefix) {
Swig_error(cparse_file,cparse_line,
"Can't instantiate template '%s' inside namespace '%s'.\n"
"Suggest moving %%template outside the namespace.\n", $5, Namespaceprefix);
}
/* Create namespace nodes to enclose the template declaration */
if (ns) {
List *scopes;
String *sname;
Iterator si;
String *name = NewString(prefix);
scopes = NewList();
while (name) {
String *tprefix;
String *base = Swig_scopename_last(name);
Insert(scopes,0,base);
tprefix = Swig_scopename_prefix(name);
Delete(name);
name = tprefix;
}
for (si = First(scopes); si.item; si = Next(si)) {
Node *ns1,*ns2;
sname = si.item;
ns1 = Swig_symbol_clookup(sname,0);
assert(ns1);
if (Strcmp(nodeType(ns1),"namespace") == 0) {
if (Getattr(ns1,"alias")) {
ns1 = Getattr(ns1,"namespace");
}
} else {
assert(0);
}
ns2 = new_node("namespace");
Setattr(ns2,"name",sname);
Setattr(ns2,"symtab", Getattr(ns1,"symtab"));
add_symbols(ns2);
Swig_symbol_setscope(Getattr(ns1,"symtab"));
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
if (nspace_inner) {
appendChild(nspace_inner,ns2);
}
nspace_inner = ns2;
if (!nspace) nspace = ns2;
}
$5 = base;
}
}
n = Swig_cparse_template_locate($5,$7);
this is closer to the C++ (typedef) behavior.
*/
n = Swig_cparse_template_locate($5,$7,tscope);
/* Patch the argument types to respect namespaces */
p = $7;
@ -2139,17 +2173,17 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
SwigType *ty = Getattr(p,"type");
if (ty) {
if (template_reduce) {
SwigType *rty = Swig_symbol_typedef_reduce(ty,0);
ty = Swig_symbol_type_qualify(rty,0);
SwigType *rty = Swig_symbol_typedef_reduce(ty,tscope);
ty = Swig_symbol_type_qualify(rty,tscope);
Setattr(p,"type",ty);
Delete(rty);
} else {
ty = Swig_symbol_type_qualify(ty,0);
ty = Swig_symbol_type_qualify(ty,tscope);
Setattr(p,"type",ty);
}
}
} else {
value = Swig_symbol_type_qualify(value,0);
value = Swig_symbol_type_qualify(value,tscope);
Setattr(p,"value",value);
}
@ -2217,12 +2251,12 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
Setattr(templnode,"sym:typename","1");
}
if ($3) {
Swig_cparse_template_expand(templnode,$3,temparms);
Swig_cparse_template_expand(templnode,$3,temparms,tscope);
Setattr(templnode,"sym:name",$3);
} else {
static int cnt = 0;
String *nname = NewStringf("__dummy_%d__", cnt++);
Swig_cparse_template_expand(templnode,nname,temparms);
Swig_cparse_template_expand(templnode,nname,temparms,tscope);
Setattr(templnode,"sym:name",nname);
if (!Swig_template_extmode()) {
Setattr(templnode,"feature:ignore","1");
@ -2644,6 +2678,13 @@ cpp_class_decl :
/* A simple class/struct/union definition */
storage_class cpptype idcolon inherit LBRACE {
List *bases = 0;
/* preserve the current scope */
prev_symtab = Swig_symbol_current();
/* If the class name is qualified. We need to create or lookup namespace entries */
$3 = resolve_namespace_class($3);
class_rename = make_name($3,0);
Classprefix = NewString($3);
/* Deal with inheritance */
@ -2700,6 +2741,7 @@ cpp_class_decl :
} cpp_members RBRACE cpp_opt_declarators {
Node *p;
SwigType *ty;
Symtab *cscope = prev_symtab;
Node *am = 0;
inclass = 0;
$$ = new_node("class");
@ -2768,12 +2810,23 @@ cpp_class_decl :
}
Setattr($$,"symtab",Swig_symbol_popscope());
yyrename = NewString(class_rename);
Classprefix = 0;
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
if (nspace) {
appendChild(nspace_inner,$$);
Swig_symbol_setscope(Getattr(nspace_inner,"symtab"));
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
add_symbols($$);
$$ = nspace;
Swig_symbol_setscope(cscope);
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
add_symbols($9);
} else {
yyrename = NewString(class_rename);
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
add_symbols($$);
add_symbols($9);
add_symbols($$);
add_symbols($9);
}
}
/* An unnamed struct, possibly with a typedef */
@ -2908,6 +2961,23 @@ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { template_para
String *tname = 0;
int error = 0;
/* check if we get a namespace node with a class declaration, and retrieve the class */
Symtab *cscope = Swig_symbol_current();
Symtab *sti = 0;
Node *ntop = $6;
Node *ni = ntop;
SwigType *ntype = ni ? nodeType(ni) : 0;
while (ni && Strcmp(ntype,"namespace") == 0) {
sti = Getattr(ni,"symtab");
ni = firstChild(ni);
ntype = nodeType(ni);
}
if (sti) {
Swig_symbol_setscope(sti);
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
$6 = ni;
}
template_parameters = 0;
$$ = $6;
if ($$) tname = Getattr($$,"name");
@ -3085,7 +3155,7 @@ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { template_para
fname = SwigType_templateprefix(tname);
tparms = SwigType_function_parms(tname);
/* add default args from generic template */
Swig_cparse_template_defargs(tparms, Getattr(tempn,"templateparms"));
Swig_cparse_template_defargs(tparms, Getattr(tempn,"templateparms"),0);
Append(fname,"<(");
p = tparms;
while (p){
@ -3124,6 +3194,9 @@ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { template_para
Swig_symbol_cadd(fname,$$);
}
}
$$ = ntop;
Swig_symbol_setscope(cscope);
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
if (error) $$ = 0;
}
| TEMPLATE cpptype idcolon {

View file

@ -210,7 +210,7 @@ String *partial_arg(String *s, String *p) {
}
int
Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms) {
Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab *tscope) {
List *patchlist, *cpatchlist, *typelist;
String *templateargs;
String *tname;
@ -364,7 +364,7 @@ Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms) {
if (bases) {
Iterator b;
for (b = First(bases); b.item; b = Next(b)) {
String *qn = Swig_symbol_type_qualify(b.item,0);
String *qn = Swig_symbol_type_qualify(b.item,tscope);
Clear(b.item);
Append(b.item,qn);
}
@ -387,7 +387,7 @@ Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms) {
void
Swig_cparse_template_defargs(Parm *parms, Parm *targs) {
Swig_cparse_template_defargs(Parm *parms, Parm *targs, Symtab *tscope) {
if (Len(parms) < Len(targs)) {
Parm *lp = parms;
Parm *p = lp;
@ -403,7 +403,7 @@ Swig_cparse_template_defargs(Parm *parms, Parm *targs) {
Parm *cp;
Parm *ta = targs;
Parm *p = parms;
SwigType *nt = Swig_symbol_typedef_reduce(value,0);
SwigType *nt = Swig_symbol_typedef_reduce(value,tscope);
while(p && ta) {
String *name = Getattr(ta,"name");
String *value = Getattr(p,"value");
@ -412,7 +412,7 @@ Swig_cparse_template_defargs(Parm *parms, Parm *targs) {
p = nextSibling(p);
ta = nextSibling(ta);
}
cp = NewParm(Swig_symbol_type_qualify(nt,0),0);
cp = NewParm(Swig_symbol_type_qualify(nt,tscope),0);
set_nextSibling(lp,cp);
lp = cp;
tp = nextSibling(tp);
@ -432,7 +432,7 @@ Swig_cparse_template_defargs(Parm *parms, Parm *targs) {
* ----------------------------------------------------------------------------- */
static Node *
template_locate(String *name, Parm *tparms) {
template_locate(String *name, Parm *tparms, Symtab *tscope) {
Node *n;
String *tname, *rname = 0;
Node *templ;
@ -445,12 +445,12 @@ template_locate(String *name, Parm *tparms) {
parms = CopyParmList(tparms);
/* Search for generic template */
templ = Swig_symbol_clookup_local(name,0);
templ = Swig_symbol_clookup(name,0);
/* Add default values from generic template */
if (templ) {
targs = Getattr(templ,"templateparms");
Swig_cparse_template_defargs(parms, targs);
Swig_cparse_template_defargs(parms, targs, tscope);
}
@ -459,8 +459,8 @@ template_locate(String *name, Parm *tparms) {
while (p) {
SwigType *ty = Getattr(p,"type");
if (ty) {
SwigType *rt = Swig_symbol_typedef_reduce(ty,0);
SwigType *nt = Swig_symbol_type_qualify(rt,0);
SwigType *rt = Swig_symbol_typedef_reduce(ty,tscope);
SwigType *nt = Swig_symbol_type_qualify(rt,tscope);
Setattr(p,"type",nt);
Delete(rt);
}
@ -616,9 +616,9 @@ template_locate(String *name, Parm *tparms) {
* ----------------------------------------------------------------------------- */
Node *
Swig_cparse_template_locate(String *name, Parm *tparms) {
Swig_cparse_template_locate(String *name, Parm *tparms, Symtab *tscope) {
Node *n = 0;
n = template_locate(name, tparms); /* this function does what we want for templated classes */
n = template_locate(name, tparms, tscope); /* this function does what we want for templated classes */
if (n) {
int isclass = 0;