more uniform treatment of extern C. This also fix the defarg mechanism when declaring C functions inside C++.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@6621 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Marcelo Matus 2004-11-02 19:03:01 +00:00
commit ec2d6ba128
2 changed files with 50 additions and 9 deletions

View file

@ -180,3 +180,19 @@ Klass constructorcall(const Klass& k = Klass()) { return k; }
} }
%} %}
%inline
%{
extern "C" double cfunc1(double x,double p = 1) {
return(x+p);
}
extern "C" {
double cfunc2(double x,double p = 2) {
return(x+p);
}
double cfunc3(double x,double p = 3) {
return(x+p);
}
}
%}

View file

@ -54,6 +54,7 @@ static int extendmode = 0;
static int dirprot_mode = 0; static int dirprot_mode = 0;
static int compact_default_args = 0; static int compact_default_args = 0;
static int template_reduce = 0; static int template_reduce = 0;
static int cparse_externc = 0;
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* Assist Functions * Assist Functions
@ -310,6 +311,7 @@ static int is_friend(Node *n) {
return Cmp(Getattr(n,"storage"),"friend") == 0; return Cmp(Getattr(n,"storage"),"friend") == 0;
} }
/* Add declaration list to symbol table */ /* Add declaration list to symbol table */
static int add_only_one = 0; static int add_only_one = 0;
@ -1011,6 +1013,16 @@ static void new_feature(const char *featurename, String *val, Hash *featureattri
Delete(name); Delete(name);
} }
/* check if a function declaration is a plain C object */
static int is_cfunction(Node *n) {
if (!cparse_cplusplus || cparse_externc) return 1;
if (Cmp(Getattr(n,"storage"),"externc") == 0) {
return 1;
}
return 0;
}
/* If the Node is a function with parameters, check to see if any of the parameters /* 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. * 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. */ * The additional functions form a linked list of nodes with the head being the original Node n. */
@ -1020,7 +1032,10 @@ static void default_arguments(Node *n) {
/* Do not add in functions if kwargs is being used or if user wants old default argument wrapping /* Do not add in functions if kwargs is being used or if user wants old default argument wrapping
(one wrapped method per function irrespective of number of default arguments) */ (one wrapped method per function irrespective of number of default arguments) */
if (function) { if (function) {
if (compact_default_args || !cparse_cplusplus || Getattr(function,"feature:compactdefaultargs") || Getattr(function,"feature:kwargs")) { if (compact_default_args
|| is_cfunction(function)
|| Getattr(function,"feature:compactdefaultargs")
|| Getattr(function,"feature:kwargs")) {
ParmList *p = Getattr(function,"parms"); ParmList *p = Getattr(function,"parms");
if (p) if (p)
Setattr(p,"compactdefargs", "1"); /* mark parameters for special handling */ Setattr(p,"compactdefargs", "1"); /* mark parameters for special handling */
@ -2403,18 +2418,28 @@ c_declaration : c_decl {
| c_enum_decl { $$ = $1; } | c_enum_decl { $$ = $1; }
| c_enum_forward_decl { $$ = $1; } | c_enum_forward_decl { $$ = $1; }
/* A an extern C type declaration. Does nothing, but is ignored */ /* A an extern C type declaration, disable cparse_cplusplus if needed. */
| EXTERN string LBRACE interface RBRACE { | EXTERN string LBRACE {
if (Strcmp($2,"C") == 0) { if (Strcmp($2,"C") == 0) {
cparse_externc = 1;
}
} interface RBRACE {
cparse_externc = 0;
if (Strcmp($2,"C") == 0) {
Node *n = firstChild($5);
$$ = new_node("extern"); $$ = new_node("extern");
Setattr($$,"name",$2); Setattr($$,"name",$2);
appendChild($$,firstChild($4)); appendChild($$,n);
while (n) {
Setattr(n,"storage","externc");
n = nextSibling(n);
}
} else { } else {
Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\" (using extern \"C\").\n", $2); Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\".\n", $2);
$$ = new_node("extern"); $$ = new_node("extern");
Setattr($$,"name","C"); Setattr($$,"name",$2);
appendChild($$,firstChild($4)); appendChild($$,firstChild($5));
} }
} }
; ;
@ -3776,8 +3801,8 @@ storage_class : EXTERN { $$ = "extern"; }
if (strcmp($2,"C") == 0) { if (strcmp($2,"C") == 0) {
$$ = "externc"; $$ = "externc";
} else { } else {
Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\" (using extern \"C\").\n", $2); Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\".\n", $2);
$$ = "externc"; $$ = 0;
} }
} }
| STATIC { $$ = "static"; } | STATIC { $$ = "static"; }