New default argument wrapping approach. This adds default argument support for statically typed languages, fixes wrapping of default arguments that are non-public plus fixes other bugs where SWIG could not or failed to correctly lookup up the default value in the symbol table.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@6305 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
1535e5506e
commit
ad39b124c8
1 changed files with 108 additions and 31 deletions
|
|
@ -713,7 +713,7 @@ static void add_nested(Nested *n) {
|
||||||
* However. We need to do a few name replacements and other munging
|
* However. We need to do a few name replacements and other munging
|
||||||
* first. This function must be called before closing a class! */
|
* first. This function must be called before closing a class! */
|
||||||
|
|
||||||
static Node *dump_nested(char *parent) {
|
static Node *dump_nested(const char *parent) {
|
||||||
Nested *n,*n1;
|
Nested *n,*n1;
|
||||||
Node *ret = 0;
|
Node *ret = 0;
|
||||||
n = nested_list;
|
n = nested_list;
|
||||||
|
|
@ -869,6 +869,92 @@ static void new_feature(const char *featurename, String *val, Hash *featureattri
|
||||||
Delete(name);
|
Delete(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If the Node is a function with parameters, check to see if any of the parameters
|
||||||
|
* have default arguments. If so create a new function for each defaulted argument.
|
||||||
|
* The additional functions form a linked list of nodes with the head being the original Node n. */
|
||||||
|
static void default_arguments(Node *n) {
|
||||||
|
Node *function = n;
|
||||||
|
while (function) {
|
||||||
|
/* Look for parameters with default arguments */
|
||||||
|
ParmList *p = Getattr(function,"parms");
|
||||||
|
int default_args = 0;
|
||||||
|
while (p) {
|
||||||
|
if (Getattr(p, "value")) {
|
||||||
|
default_args = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p = nextSibling(p);
|
||||||
|
}
|
||||||
|
if (default_args) {
|
||||||
|
ParmList* newparms = 0;
|
||||||
|
|
||||||
|
/* Create a parameter list for the new function by copying all
|
||||||
|
but the last (defaulted) parameter */
|
||||||
|
{
|
||||||
|
ParmList *p = Getattr(function,"parms");
|
||||||
|
Parm *newparm = 0;
|
||||||
|
Parm *pp = 0;
|
||||||
|
Parm *fp = 0;
|
||||||
|
while (nextSibling(p)) {
|
||||||
|
newparm = CopyParm(p);
|
||||||
|
if (pp) {
|
||||||
|
set_nextSibling(pp,newparm);
|
||||||
|
} else {
|
||||||
|
fp = newparm;
|
||||||
|
}
|
||||||
|
pp = newparm;
|
||||||
|
p = nextSibling(p);
|
||||||
|
}
|
||||||
|
newparms = fp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create new function and add to symbol table */
|
||||||
|
{
|
||||||
|
Node *new_function = new_node(Copy(nodeType(function)));
|
||||||
|
SwigType *decl = Copy(Getattr(function,"decl"));
|
||||||
|
Delete(SwigType_pop_function(decl)); /* remove the old parameter list from decl */
|
||||||
|
SwigType_add_function(decl,newparms);
|
||||||
|
|
||||||
|
Setattr(new_function,"name",Copy(Getattr(function,"name")));
|
||||||
|
Setattr(new_function,"code",Copy(Getattr(function,"code")));
|
||||||
|
Setattr(new_function,"decl", decl);
|
||||||
|
Setattr(new_function,"parms",newparms);
|
||||||
|
Setattr(new_function,"storage",Copy(Getattr(function,"storage")));
|
||||||
|
Setattr(new_function,"type",Copy(Getattr(function,"type")));
|
||||||
|
|
||||||
|
{
|
||||||
|
Node *throws = Getattr(function,"throws");
|
||||||
|
if (throws) Setattr(new_function,"throws",CopyParmList(throws));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy template specific attributes */
|
||||||
|
if (Strcmp(nodeType(function),"template") == 0) {
|
||||||
|
Node *templatetype = Getattr(function,"templatetype");
|
||||||
|
Node *symname = Getattr(function,"sym:name");
|
||||||
|
Node *symtypename = Getattr(function,"sym:typename");
|
||||||
|
Parm *templateparms = Getattr(function,"templateparms");
|
||||||
|
if (templatetype) Setattr(new_function,"templatetype",Copy(templatetype));
|
||||||
|
if (symname) Setattr(new_function,"sym:name",Copy(symname));
|
||||||
|
if (symtypename) Setattr(new_function,"sym:typename",Copy(symtypename));
|
||||||
|
if (templateparms) Setattr(new_function,"templateparms",CopyParmList(templateparms));
|
||||||
|
}
|
||||||
|
|
||||||
|
add_symbols(new_function);
|
||||||
|
|
||||||
|
/* mark added functions as ones with overloaded parameters and point to the parsed method */
|
||||||
|
Setattr(new_function,"defaultargs", n);
|
||||||
|
|
||||||
|
/* Point to the new function, extending the linked list */
|
||||||
|
set_nextSibling(function, new_function);
|
||||||
|
|
||||||
|
function = new_function;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
function = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%union {
|
%union {
|
||||||
|
|
@ -1042,6 +1128,7 @@ program : interface {
|
||||||
;
|
;
|
||||||
|
|
||||||
interface : interface declaration {
|
interface : interface declaration {
|
||||||
|
/* add declaration to end of linked list (the declaration isn't always a single declaration, sometimes it is a linked list itself) */
|
||||||
appendChild($1,$2);
|
appendChild($1,$2);
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
|
|
@ -2146,7 +2233,6 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
|
||||||
}
|
}
|
||||||
Swig_symbol_setscope(tscope);
|
Swig_symbol_setscope(tscope);
|
||||||
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
|
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
|
||||||
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -2169,6 +2255,7 @@ c_declaration : c_decl {
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
if ($$) {
|
if ($$) {
|
||||||
add_symbols($$);
|
add_symbols($$);
|
||||||
|
default_arguments($$);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| c_enum_decl { $$ = $1; }
|
| c_enum_decl { $$ = $1; }
|
||||||
|
|
@ -2907,6 +2994,7 @@ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { template_para
|
||||||
Setattr($$,"sym:typename","1");
|
Setattr($$,"sym:typename","1");
|
||||||
}
|
}
|
||||||
add_symbols($$);
|
add_symbols($$);
|
||||||
|
default_arguments($$);
|
||||||
/* We also place a fully parameterized version in the symbol table */
|
/* We also place a fully parameterized version in the symbol table */
|
||||||
{
|
{
|
||||||
Parm *p;
|
Parm *p;
|
||||||
|
|
@ -3089,6 +3177,7 @@ cpp_namespace_decl : NAMESPACE idcolon LBRACE {
|
||||||
|
|
||||||
cpp_members : cpp_member cpp_members {
|
cpp_members : cpp_member cpp_members {
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
|
/* Insert cpp_member (including any siblings) to the front of the cpp_members linked list */
|
||||||
if ($$) {
|
if ($$) {
|
||||||
Node *p = $$;
|
Node *p = $$;
|
||||||
Node *pp =0;
|
Node *pp =0;
|
||||||
|
|
@ -3146,6 +3235,7 @@ cpp_member : c_declaration { $$ = $1; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
add_symbols($$);
|
add_symbols($$);
|
||||||
|
default_arguments($$);
|
||||||
}
|
}
|
||||||
| cpp_destructor_decl { $$ = $1; }
|
| cpp_destructor_decl { $$ = $1; }
|
||||||
| cpp_protection_decl { $$ = $1; }
|
| cpp_protection_decl { $$ = $1; }
|
||||||
|
|
@ -3613,22 +3703,14 @@ def_args : EQUAL definetype {
|
||||||
Node *n = Swig_symbol_clookup($3.id,0);
|
Node *n = Swig_symbol_clookup($3.id,0);
|
||||||
if (n) {
|
if (n) {
|
||||||
String *q = Swig_symbol_qualified(n);
|
String *q = Swig_symbol_qualified(n);
|
||||||
if (Getattr(n,"access")) {
|
if (q) {
|
||||||
if (cplus_mode == CPLUS_PUBLIC) {
|
String *temp = NewStringf("%s::%s", q, Getattr(n,"name"));
|
||||||
Swig_warning(WARN_PARSE_PRIVATE, cparse_file, cparse_line,"'%s' is private in this context.\n", $3.id);
|
$$.val = NewStringf("&%s", SwigType_str($3.type,temp));
|
||||||
Swig_warning(WARN_PARSE_BAD_DEFAULT, cparse_file, cparse_line,"Can't set default argument value (ignored)\n");
|
Delete(q);
|
||||||
}
|
Delete(temp);
|
||||||
$$.val = 0;
|
} else {
|
||||||
} else {
|
$$.val = NewStringf("&%s", SwigType_str($3.type,$3.id));
|
||||||
if (q) {
|
}
|
||||||
String *temp = NewStringf("%s::%s", q, Getattr(n,"name"));
|
|
||||||
$$.val = NewStringf("&%s", SwigType_str($3.type,temp));
|
|
||||||
Delete(q);
|
|
||||||
Delete(temp);
|
|
||||||
} else {
|
|
||||||
$$.val = NewStringf("&%s", SwigType_str($3.type,$3.id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
$$.val = NewStringf("&%s",SwigType_str($3.type,$3.id));
|
$$.val = NewStringf("&%s",SwigType_str($3.type,$3.id));
|
||||||
}
|
}
|
||||||
|
|
@ -4418,19 +4500,14 @@ expr : exprnum { $$ = $1; }
|
||||||
/* Check if value is in scope */
|
/* Check if value is in scope */
|
||||||
n = Swig_symbol_clookup($1,0);
|
n = Swig_symbol_clookup($1,0);
|
||||||
if (n) {
|
if (n) {
|
||||||
if (Getattr(n,"access") && (cplus_mode == CPLUS_PUBLIC)) {
|
/* A band-aid for enum values used in expressions. */
|
||||||
Swig_warning(WARN_PARSE_PRIVATE,cparse_file, cparse_line, "'%s' is private in this context.\n", $1);
|
if (Strcmp(nodeType(n),"enumitem") == 0) {
|
||||||
$$.type = T_ERROR;
|
String *q = Swig_symbol_qualified(n);
|
||||||
} else {
|
if (q) {
|
||||||
/* A band-aid for enum values used in expressions. */
|
$$.val = NewStringf("%s::%s", q, Getattr(n,"name"));
|
||||||
if (Strcmp(nodeType(n),"enumitem") == 0) {
|
Delete(q);
|
||||||
String *q = Swig_symbol_qualified(n);
|
}
|
||||||
if (q) {
|
}
|
||||||
$$.val = NewStringf("%s::%s", q, Getattr(n,"name"));
|
|
||||||
Delete(q);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue