diff options
author | Olly Betts <olly@survex.com> | 2023-01-05 16:54:16 +1300 |
---|---|---|
committer | Olly Betts <olly@survex.com> | 2023-05-11 13:11:22 +1200 |
commit | 9c8d6563498bbfd22d05b225930409236834b867 (patch) | |
tree | 197887f358073c65a911882674c874ee4e17cd9a /Source/Modules | |
parent | 38f8f15fcd4747cb1db136de74874dd779a75c6f (diff) | |
download | swig-parse-storage-class-flexibly.tar.gz |
Parse storage class more flexiblyparse-storage-class-flexibly
Previously we had a hard-coded list of allowed combinations in the
grammar, but this suffers from combinatorial explosion, and results
in a vague `Syntax error in input` error for invalid combinations.
This means we now support a number of cases which are valid C++
but weren't supported.
Fixes #302
Fixes #2079 (friend constexpr)
Fixes #2474 (virtual explicit)
Diffstat (limited to 'Source/Modules')
-rw-r--r-- | Source/Modules/allocate.cxx | 2 | ||||
-rw-r--r-- | Source/Modules/go.cxx | 6 | ||||
-rw-r--r-- | Source/Modules/lang.cxx | 4 | ||||
-rw-r--r-- | Source/Modules/php.cxx | 14 | ||||
-rw-r--r-- | Source/Modules/typepass.cxx | 2 |
5 files changed, 14 insertions, 14 deletions
diff --git a/Source/Modules/allocate.cxx b/Source/Modules/allocate.cxx index 0e1262f83..233830791 100644 --- a/Source/Modules/allocate.cxx +++ b/Source/Modules/allocate.cxx @@ -396,7 +396,7 @@ class Allocate:public Dispatcher { if (!GetFlag(c, "feature:ignore")) { String *storage = Getattr(c, "storage"); if (!((Cmp(storage, "typedef") == 0)) - && !((Cmp(storage, "friend") == 0))) { + && !Strstr(storage, "friend")) { String *name = Getattr(c, "name"); String *symname = Getattr(c, "sym:name"); Node *e = Swig_symbol_clookup_local(name, 0); diff --git a/Source/Modules/go.cxx b/Source/Modules/go.cxx index 27e3060bf..6339cc15d 100644 --- a/Source/Modules/go.cxx +++ b/Source/Modules/go.cxx @@ -2271,7 +2271,7 @@ private: } String *storage = Getattr(entry, "storage"); - if (storage && (Strcmp(storage, "typedef") == 0 || Strcmp(storage, "friend") == 0)) { + if (storage && (Strcmp(storage, "typedef") == 0 || Strstr(storage, "friend"))) { return SWIG_OK; } @@ -5620,7 +5620,7 @@ private: bool isStatic(Node *n) { String *storage = Getattr(n, "storage"); - return (storage && (Swig_storage_isstatic(n) || Strcmp(storage, "friend") == 0) && (!SmartPointer || !Getattr(n, "allocate:smartpointeraccess"))); + return (storage && (Swig_storage_isstatic(n) || Strstr(storage, "friend")) && (!SmartPointer || !Getattr(n, "allocate:smartpointeraccess"))); } /* ---------------------------------------------------------------------- @@ -5631,7 +5631,7 @@ private: bool isFriend(Node *n) { String *storage = Getattr(n, "storage"); - return storage && Strcmp(storage, "friend") == 0; + return storage && Strstr(storage, "friend"); } /* ---------------------------------------------------------------------- diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index 7a85c2d63..ba52e265c 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -882,7 +882,7 @@ int Language::cDeclaration(Node *n) { /* discards nodes following the access control rules */ if (cplus_mode != PUBLIC || !is_public(n)) { /* except for friends, they are not affected by access control */ - int isfriend = Cmp(storage, "friend") == 0; + int isfriend = (Strstr(storage, "friend") != NULL); if (!isfriend) { /* Check what the director needs. If the method is pure virtual, it is always needed. * Also wrap non-virtual protected members if asked for (allprotected mode). */ @@ -1061,7 +1061,7 @@ int Language::cDeclaration(Node *n) { int Language::functionHandler(Node *n) { String *storage = Getattr(n, "storage"); - int isfriend = CurrentClass && Cmp(storage, "friend") == 0; + int isfriend = CurrentClass && Strstr(storage, "friend"); int isstatic = CurrentClass && Swig_storage_isstatic(n) && !(SmartPointer && Getattr(n, "allocate:smartpointeraccess")); Parm *p = Getattr(n, "parms"); if (GetFlag(n, "feature:del")) { diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index 8e16c6969..67c73aa6b 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -951,7 +951,7 @@ public: void create_command(String *cname, String *fname, Node *n, bool dispatch, String *modes) { // This is for the single main zend_function_entry record ParmList *l = Getattr(n, "parms"); - if (cname && !Equal(Getattr(n, "storage"), "friend")) { + if (cname && !Strstr(Getattr(n, "storage"), "friend")) { Printf(f_h, "static PHP_METHOD(%s%s,%s);\n", prefix, cname, fname); if (wrapperType != staticmemberfn && wrapperType != staticmembervar && @@ -973,7 +973,7 @@ public: String *arginfo_id = phptypes->get_arginfo_id(); String *s = cs_entry; if (!s) s = s_entry; - if (cname && !Equal(Getattr(n, "storage"), "friend")) { + if (cname && !Strstr(Getattr(n, "storage"), "friend")) { Printf(all_cs_entry, " PHP_ME(%s%s,%s,swig_arginfo_%s,%s)\n", prefix, cname, fname, arginfo_id, modes); } else { if (dispatch) { @@ -1043,7 +1043,7 @@ public: create_command(class_name, wname, n, true, modes); - if (class_name && !Equal(Getattr(n, "storage"), "friend")) { + if (class_name && !Strstr(Getattr(n, "storage"), "friend")) { Printv(f->def, "static PHP_METHOD(", prefix, class_name, ",", wname, ") {\n", NIL); } else { Printv(f->def, "static ZEND_NAMED_FUNCTION(", wname, ") {\n", NIL); @@ -1340,7 +1340,7 @@ public: wname = Getattr(n, "staticmemberfunctionHandler:sym:name"); } else { if (class_name) { - if (Cmp(Getattr(n, "storage"), "friend") == 0 && Cmp(Getattr(n, "view"), "globalfunctionHandler") == 0) { + if (Strstr(Getattr(n, "storage"), "friend") && Cmp(Getattr(n, "view"), "globalfunctionHandler") == 0) { wname = iname; } else { wname = Getattr(n, "destructorHandler:sym:name"); @@ -1364,7 +1364,7 @@ public: phptypes = NULL; String *key; - if (class_name && !Equal(Getattr(n, "storage"), "friend")) { + if (class_name && !Strstr(Getattr(n, "storage"), "friend")) { key = NewStringf("%s:%s", class_name, wname); } else { key = NewStringf(":%s", wname); @@ -1395,7 +1395,7 @@ public: if (!overloaded) { if (!static_getter) { - if (class_name && !Equal(Getattr(n, "storage"), "friend")) { + if (class_name && !Strstr(Getattr(n, "storage"), "friend")) { Printv(f->def, "static PHP_METHOD(", prefix, class_name, ",", wname, ") {\n", NIL); } else { if (wrap_nonclass_global) { @@ -1589,7 +1589,7 @@ public: List *return_types = phptypes->process_phptype(n, 0, "tmap:out:phptype"); - if (class_name && !Equal(Getattr(n, "storage"), "friend")) { + if (class_name && !Strstr(Getattr(n, "storage"), "friend")) { if (is_member_director(n)) { String *parent = class_name; while ((parent = Getattr(php_parent_class, parent)) != NULL) { diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx index 83ec8ad72..01949b2ba 100644 --- a/Source/Modules/typepass.cxx +++ b/Source/Modules/typepass.cxx @@ -1043,7 +1043,7 @@ class TypePass:private Dispatcher { if (Strcmp(nodeType(c), "cdecl") == 0) { if (!(Swig_storage_isstatic(c) || checkAttribute(c, "storage", "typedef") - || checkAttribute(c, "storage", "friend") + || Strstr(Getattr(c, "storage"), "friend") || (Getattr(c, "feature:extend") && !Getattr(c, "code")) || GetFlag(c, "feature:ignore"))) { |