diff options
Diffstat (limited to 'Source/CParse/parser.y')
-rw-r--r-- | Source/CParse/parser.y | 231 |
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"; } |