summaryrefslogtreecommitdiff
path: root/Source/CParse/parser.y
diff options
context:
space:
mode:
Diffstat (limited to 'Source/CParse/parser.y')
-rw-r--r--Source/CParse/parser.y231
1 files changed, 77 insertions, 154 deletions
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index 7e7e5633f..1fb759081 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -41,7 +41,6 @@ int yyparse();
static Node *top = 0; /* Top of the generated parse tree */
static int unnamed = 0; /* Unnamed datatype counter */
-static Hash *extendhash = 0; /* Hash table of added methods */
static Hash *classes = 0; /* Hash table of classes */
static Hash *classes_typedefs = 0; /* Hash table of typedef classes: typedef struct X {...} Y; */
static Symtab *prev_symtab = 0;
@@ -60,6 +59,7 @@ static int compact_default_args = 0;
static int template_reduce = 0;
static int cparse_externc = 0;
int ignore_nested_classes = 0;
+int kwargs_supported = 0;
/* -----------------------------------------------------------------------------
* Assist Functions
* ----------------------------------------------------------------------------- */
@@ -71,14 +71,6 @@ static void yyerror (const char *e) {
(void)e;
}
-static Node *new_node(const_String_or_char_ptr tag) {
- Node *n = NewHash();
- set_nodeType(n,tag);
- Setfile(n,cparse_file);
- Setline(n,cparse_line);
- return n;
-}
-
/* Copies a node. Does not copy tree links or symbol table data (except for
sym:name) */
@@ -650,106 +642,6 @@ static void add_symbols_copy(Node *n) {
}
}
-/* Extension merge. This function is used to handle the %extend directive
- when it appears before a class definition. To handle this, the %extend
- actually needs to take precedence. Therefore, we will selectively nuke symbols
- from the current symbol table, replacing them with the added methods */
-
-static void merge_extensions(Node *cls, Node *am) {
- Node *n;
- Node *csym;
-
- n = firstChild(am);
- while (n) {
- String *symname;
- if (Strcmp(nodeType(n),"constructor") == 0) {
- symname = Getattr(n,"sym:name");
- if (symname) {
- if (Strcmp(symname,Getattr(n,"name")) == 0) {
- /* If the name and the sym:name of a constructor are the same,
- then it hasn't been renamed. However---the name of the class
- itself might have been renamed so we need to do a consistency
- check here */
- if (Getattr(cls,"sym:name")) {
- Setattr(n,"sym:name", Getattr(cls,"sym:name"));
- }
- }
- }
- }
-
- symname = Getattr(n,"sym:name");
- DohIncref(symname);
- if ((symname) && (!Getattr(n,"error"))) {
- /* Remove node from its symbol table */
- Swig_symbol_remove(n);
- csym = Swig_symbol_add(symname,n);
- if (csym != n) {
- /* Conflict with previous definition. Nuke previous definition */
- String *e = NewStringEmpty();
- String *en = NewStringEmpty();
- String *ec = NewStringEmpty();
- Printf(ec,"Identifier '%s' redefined by %%extend (ignored),",symname);
- Printf(en,"%%extend definition of '%s'.",symname);
- SWIG_WARN_NODE_BEGIN(n);
- Swig_warning(WARN_PARSE_REDEFINED,Getfile(csym),Getline(csym),"%s\n",ec);
- Swig_warning(WARN_PARSE_REDEFINED,Getfile(n),Getline(n),"%s\n",en);
- SWIG_WARN_NODE_END(n);
- Printf(e,"%s:%d:%s\n%s:%d:%s\n",Getfile(csym),Getline(csym),ec,
- Getfile(n),Getline(n),en);
- Setattr(csym,"error",e);
- Delete(e);
- Delete(en);
- Delete(ec);
- Swig_symbol_remove(csym); /* Remove class definition */
- Swig_symbol_add(symname,n); /* Insert extend definition */
- }
- }
- n = nextSibling(n);
- }
-}
-
-static void append_previous_extension(Node *cls, Node *am) {
- Node *n, *ne;
- Node *pe = 0;
- Node *ae = 0;
-
- if (!am) return;
-
- n = firstChild(am);
- while (n) {
- ne = nextSibling(n);
- set_nextSibling(n,0);
- /* typemaps and fragments need to be prepended */
- if (((Cmp(nodeType(n),"typemap") == 0) || (Cmp(nodeType(n),"fragment") == 0))) {
- if (!pe) pe = new_node("extend");
- appendChild(pe, n);
- } else {
- if (!ae) ae = new_node("extend");
- appendChild(ae, n);
- }
- n = ne;
- }
- if (pe) prependChild(cls,pe);
- if (ae) appendChild(cls,ae);
-}
-
-
-/* Check for unused %extend. Special case, don't report unused
- extensions for templates */
-
-static void check_extensions() {
- Iterator ki;
-
- if (!extendhash) return;
- for (ki = First(extendhash); ki.key; ki = Next(ki)) {
- if (!Strchr(ki.key,'<')) {
- SWIG_WARN_NODE_BEGIN(ki.item);
- Swig_warning(WARN_PARSE_EXTEND_UNDEF,Getfile(ki.item), Getline(ki.item), "%%extend defined for an undeclared class %s.\n", SwigType_namestr(ki.key));
- SWIG_WARN_NODE_END(ki.item);
- }
- }
-}
-
/* Check a set of declarations to see if any are pure-abstract */
static List *pure_abstracts(Node *n) {
@@ -1126,7 +1018,7 @@ static Node *nested_forward_declaration(const char *storage, const char *kind, S
}
}
- if (!GetFlag(currentOuterClass, "nested")) {
+ if (!currentOuterClass || !GetFlag(currentOuterClass, "nested")) {
if (nn && Equal(nodeType(nn), "classforward")) {
Node *n = nn;
SWIG_WARN_NODE_BEGIN(n);
@@ -1286,7 +1178,7 @@ static void default_arguments(Node *n) {
if (compact_default_args
|| is_cfunction(function)
|| GetFlag(function,"feature:compactdefaultargs")
- || GetFlag(function,"feature:kwargs")) {
+ || (GetFlag(function,"feature:kwargs") && kwargs_supported)) {
ParmList *p = Getattr(function,"parms");
if (p)
Setattr(p,"compactdefargs", "1"); /* mark parameters for special handling */
@@ -1579,7 +1471,6 @@ program : interface {
Setattr(module_node,"name",ModuleName);
}
Setattr($1,"module",module_node);
- check_extensions();
top = $1;
}
| PARSETYPE parm SEMI {
@@ -1619,7 +1510,11 @@ declaration : swig_directive { $$ = $1; }
| SEMI { $$ = 0; }
| error {
$$ = 0;
- Swig_error(cparse_file, cparse_line,"Syntax error in input(1).\n");
+ if (cparse_unknown_directive) {
+ Swig_error(cparse_file, cparse_line, "Unknown directive '%s'.\n", cparse_unknown_directive);
+ } else {
+ Swig_error(cparse_file, cparse_line, "Syntax error in input(1).\n");
+ }
exit(1);
}
/* Out of class constructor/destructor declarations */
@@ -1683,14 +1578,13 @@ extend_directive : EXTEND options idcolon LBRACE {
cplus_mode = CPLUS_PUBLIC;
if (!classes) classes = NewHash();
if (!classes_typedefs) classes_typedefs = NewHash();
- if (!extendhash) extendhash = NewHash();
clsname = make_class_name($3);
cls = Getattr(classes,clsname);
if (!cls) {
cls = Getattr(classes_typedefs, clsname);
if (!cls) {
/* No previous definition. Create a new scope */
- Node *am = Getattr(extendhash,clsname);
+ Node *am = Getattr(Swig_extend_hash(),clsname);
if (!am) {
Swig_symbol_newscope();
Swig_symbol_setscopename($3);
@@ -1736,13 +1630,13 @@ extend_directive : EXTEND options idcolon LBRACE {
appendChild(current_class,$$);
} else {
/* We store the extensions in the extensions hash */
- Node *am = Getattr(extendhash,clsname);
+ Node *am = Getattr(Swig_extend_hash(),clsname);
if (am) {
/* Append the members to the previous extend methods */
appendChild(am,$6);
} else {
appendChild($$,$6);
- Setattr(extendhash,clsname,$$);
+ Setattr(Swig_extend_hash(),clsname,$$);
}
}
current_class = 0;
@@ -1991,6 +1885,7 @@ include_directive: includetype options string BEGINFILE {
Node *nint = new_node("import");
Node *mnode = new_node("module");
Setattr(mnode,"name", mname);
+ Setattr(mnode,"options",$2);
appendChild(nint,mnode);
Delete(mnode);
appendChild(nint,firstChild($$));
@@ -2613,6 +2508,7 @@ types_directive : TYPES LPAREN parms RPAREN stringbracesemi {
template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN valparms GREATERTHAN SEMI {
Parm *p, *tp;
Node *n;
+ Node *outer_class = currentOuterClass;
Symtab *tscope = 0;
int specialized = 0;
int variadic = 0;
@@ -2625,6 +2521,9 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
if (!inclass) {
$5 = resolve_create_node_scope($5);
}
+ if (nscope_inner && Strcmp(nodeType(nscope_inner), "class") == 0) {
+ outer_class = nscope_inner;
+ }
/*
We use the new namespace entry 'nscope' only to
@@ -2757,7 +2656,7 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
Setattr(templnode,"sym:typename","1");
}
/* for now, nested %template is allowed only in the same scope as the template declaration */
- if ($3 && !(nnisclass && ((currentOuterClass && (currentOuterClass != Getattr(nn, "nested:outer")))
+ if ($3 && !(nnisclass && ((outer_class && (outer_class != Getattr(nn, "nested:outer")))
||(extendmode && current_class && (current_class != Getattr(nn, "nested:outer")))))) {
/*
Comment this out for 1.3.28. We need to
@@ -2786,9 +2685,9 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
Setfile(templnode,cparse_file);
Setline(templnode,cparse_line);
Delete(temparms);
- if (currentOuterClass) {
+ if (outer_class && nnisclass) {
SetFlag(templnode, "nested");
- Setattr(templnode, "nested:outer", currentOuterClass);
+ Setattr(templnode, "nested:outer", outer_class);
}
add_symbols_copy(templnode);
@@ -2825,8 +2724,7 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
/* !!! This may be broken. We may have to add the
%extend methods at the beginning of the class */
-
- if (extendhash) {
+ {
String *stmp = 0;
String *clsname;
Node *am;
@@ -2835,32 +2733,32 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
} else {
clsname = Getattr(templnode,"name");
}
- am = Getattr(extendhash,clsname);
+ am = Getattr(Swig_extend_hash(),clsname);
if (am) {
Symtab *st = Swig_symbol_current();
Swig_symbol_setscope(Getattr(templnode,"symtab"));
/* Printf(stdout,"%s: %s %p %p\n", Getattr(templnode,"name"), clsname, Swig_symbol_current(), Getattr(templnode,"symtab")); */
- merge_extensions(templnode,am);
+ Swig_extend_merge(templnode,am);
Swig_symbol_setscope(st);
- append_previous_extension(templnode,am);
- Delattr(extendhash,clsname);
+ Swig_extend_append_previous(templnode,am);
+ Delattr(Swig_extend_hash(),clsname);
}
if (stmp) Delete(stmp);
}
+
/* Add to classes hash */
- if (!classes) classes = NewHash();
+ if (!classes)
+ classes = NewHash();
- {
- if (Namespaceprefix) {
- String *temp = NewStringf("%s::%s", Namespaceprefix, Getattr(templnode,"name"));
- Setattr(classes,temp,templnode);
- Delete(temp);
- } else {
- String *qs = Swig_symbol_qualifiedscopename(templnode);
- Setattr(classes, qs,templnode);
- Delete(qs);
- }
- }
+ if (Namespaceprefix) {
+ String *temp = NewStringf("%s::%s", Namespaceprefix, Getattr(templnode,"name"));
+ Setattr(classes,temp,templnode);
+ Delete(temp);
+ } else {
+ String *qs = Swig_symbol_qualifiedscopename(templnode);
+ Setattr(classes, qs,templnode);
+ Delete(qs);
+ }
}
}
@@ -3126,6 +3024,15 @@ c_decl_tail : SEMI {
skip_balanced('{','}');
$$ = 0;
}
+ | error {
+ $$ = 0;
+ if (yychar == RPAREN) {
+ Swig_error(cparse_file, cparse_line, "Unexpected ')'.\n");
+ } else {
+ Swig_error(cparse_file, cparse_line, "Syntax error - possibly a missing semicolon.\n");
+ }
+ exit(1);
+ }
;
initializer : def_args {
@@ -3515,6 +3422,9 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
} else {
cplus_mode = CPLUS_PUBLIC;
}
+ if (!cparse_cplusplus) {
+ set_scope_to_global();
+ }
Swig_symbol_newscope();
Swig_symbol_setscopename($3);
Swig_inherit_base_symbols(bases);
@@ -3558,8 +3468,14 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
nscope = Getattr($<node>$, "nested:nscope");
Delattr($<node>$, "nested:innerscope");
Delattr($<node>$, "nested:nscope");
- if (nscope_inner && Strcmp(nodeType(nscope_inner), "class") == 0) /* actual parent class for this class */
- Setattr($$, "nested:outer", nscope_inner);
+ if (nscope_inner && Strcmp(nodeType(nscope_inner), "class") == 0) { /* actual parent class for this class */
+ Node* forward_declaration = Swig_symbol_clookup_no_inherit(Getattr($<node>$,"name"), Getattr(nscope_inner, "symtab"));
+ if (forward_declaration) {
+ Setattr($<node>$, "access", Getattr(forward_declaration, "access"));
+ }
+ Setattr($<node>$, "nested:outer", nscope_inner);
+ SetFlag($<node>$, "nested");
+ }
if (!currentOuterClass)
inclass = 0;
cscope = Getattr($$, "prev_symtab");
@@ -3569,13 +3485,12 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
Setattr($$,"abstracts", pure_abstracts($7));
/* This bit of code merges in a previously defined %extend directive (if any) */
-
- if (extendhash) {
+ {
String *clsname = Swig_symbol_qualifiedscopename(0);
- am = Getattr(extendhash, clsname);
+ am = Getattr(Swig_extend_hash(), clsname);
if (am) {
- merge_extensions($$, am);
- Delattr(extendhash, clsname);
+ Swig_extend_merge($$, am);
+ Delattr(Swig_extend_hash(), clsname);
}
Delete(clsname);
}
@@ -3586,7 +3501,7 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
appendChild($$, $7);
if (am)
- append_previous_extension($$, am);
+ Swig_extend_append_previous($$, am);
p = $9;
if (p && !nscope_inner) {
@@ -3639,6 +3554,8 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
} else if (nscope_inner) {
/* this is tricky */
/* we add the declaration in the original namespace */
+ if (Strcmp(nodeType(nscope_inner), "class") == 0 && cparse_cplusplus && ignore_nested_classes && !GetFlag($$, "feature:flatnested"))
+ $$ = nested_forward_declaration($1, $2, $3, Copy($3), $9);
appendChild(nscope_inner, $$);
Swig_symbol_setscope(Getattr(nscope_inner, "symtab"));
Delete(Namespaceprefix);
@@ -3785,15 +3702,16 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
n = nextSibling(n);
}
n = $8;
- /* Check for previous extensions */
- if (extendhash) {
+
+ /* Check for previous extensions */
+ {
String *clsname = Swig_symbol_qualifiedscopename(0);
- Node *am = Getattr(extendhash,clsname);
+ Node *am = Getattr(Swig_extend_hash(),clsname);
if (am) {
- /* Merge the extension into the symbol table */
- merge_extensions($$,am);
- append_previous_extension($$,am);
- Delattr(extendhash,clsname);
+ /* Merge the extension into the symbol table */
+ Swig_extend_merge($$,am);
+ Swig_extend_append_previous($$,am);
+ Delattr(Swig_extend_hash(),clsname);
}
Delete(clsname);
}
@@ -4116,7 +4034,9 @@ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN {
Swig_symbol_setscope(cscope);
Delete(Namespaceprefix);
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
- if (error) $$ = 0;
+ if (error || (nscope_inner && Strcmp(nodeType(nscope_inner), "class") == 0)) {
+ $$ = 0;
+ }
if (currentOuterClass)
template_parameters = Getattr(currentOuterClass, "template_parameters");
else
@@ -4760,7 +4680,10 @@ storage_class : EXTERN { $$ = "extern"; }
| FRIEND { $$ = "friend"; }
| EXPLICIT { $$ = "explicit"; }
| CONSTEXPR { $$ = "constexpr"; }
+ | EXPLICIT CONSTEXPR { $$ = "explicit constexpr"; }
+ | CONSTEXPR EXPLICIT { $$ = "explicit constexpr"; }
| STATIC CONSTEXPR { $$ = "static constexpr"; }
+ | CONSTEXPR STATIC { $$ = "static constexpr"; }
| THREAD_LOCAL { $$ = "thread_local"; }
| THREAD_LOCAL STATIC { $$ = "static thread_local"; }
| STATIC THREAD_LOCAL { $$ = "static thread_local"; }