summaryrefslogtreecommitdiff
path: root/Source/Modules
diff options
context:
space:
mode:
authorOlly Betts <olly@survex.com>2023-01-05 16:54:16 +1300
committerOlly Betts <olly@survex.com>2023-05-11 13:11:22 +1200
commit9c8d6563498bbfd22d05b225930409236834b867 (patch)
tree197887f358073c65a911882674c874ee4e17cd9a /Source/Modules
parent38f8f15fcd4747cb1db136de74874dd779a75c6f (diff)
downloadswig-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.cxx2
-rw-r--r--Source/Modules/go.cxx6
-rw-r--r--Source/Modules/lang.cxx4
-rw-r--r--Source/Modules/php.cxx14
-rw-r--r--Source/Modules/typepass.cxx2
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"))) {