mirror of https://github.com/swig/swig
Improve alternative operator names support
Handle alternative operator names in C++ preprocessor expressions. Handle full set of alternative operator names in C++ expressions (previously only "and", "or" and "not" were understood). Fixes #2914
This commit is contained in:
parent
99df7a085d
commit
0ce05c33e9
|
@ -7,6 +7,12 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
|||
Version 4.3.0 (in progress)
|
||||
===========================
|
||||
|
||||
2024-05-30: olly
|
||||
#2914 Handle alternative operator names in C++ preprocessor
|
||||
expressions. Handle full set of alternative operator names in
|
||||
C++ expressions (previously only "and", "or" and "not" were
|
||||
understood).
|
||||
|
||||
2024-05-15: olly
|
||||
#2868 Support C++17 fold expressions.
|
||||
|
||||
|
|
|
@ -74,6 +74,9 @@
|
|||
// so this would end up wrapped as int.
|
||||
decltype(!0) should_be_bool;
|
||||
|
||||
// Test alternative operator names work in this context.
|
||||
decltype(((compl 42) and (not 1)) or (2 xor 4)) should_be_bool2;
|
||||
|
||||
decltype(E1) should_be_enum;
|
||||
|
||||
auto get_number_sum(decltype(i+j) a) -> decltype(i+j) {
|
||||
|
|
|
@ -9,5 +9,9 @@ struct A
|
|||
// Regression test for preprocessor bug with handling a slash immediately
|
||||
// followed by a single quote, fixed in 4.2.0. (#2630)
|
||||
int f(int i = 64/' ') { return i; }
|
||||
|
||||
// Regression test for alternative operator names - this failed to parse in
|
||||
// SWIG 4.2.0 and earlier.
|
||||
int g(bool b = (compl 1 or not 2) xor (3 and 4) xor (3 bitand 6) xor (3 bitor 5) xor (2 + 2 not_eq 5)) { return (int)b; }
|
||||
};
|
||||
%}
|
||||
|
|
|
@ -52,6 +52,7 @@ check::equal(gettype($b->should_be_int9), "integer");
|
|||
check::equal(gettype($b->should_be_int10), "integer");
|
||||
|
||||
check::equal(gettype($b->should_be_bool), "boolean");
|
||||
check::equal(gettype($b->should_be_bool2), "boolean");
|
||||
|
||||
check::equal(gettype($b::should_be_char), "string");
|
||||
check::equal($b::should_be_char, "\0");
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
%module preproc_cpp
|
||||
|
||||
|
||||
// booleans start
|
||||
// Test boolean literals (https://github.com/swig/swig/pull/2394):
|
||||
#if false
|
||||
# error "boolean preproc check fail false"
|
||||
#else
|
||||
|
@ -31,7 +31,43 @@
|
|||
#else
|
||||
# error "boolean preproc check fail (0 || true)"
|
||||
#endif
|
||||
// booleans end
|
||||
|
||||
|
||||
// Test alternative operator names (https://github.com/swig/swig/issues/2914):
|
||||
#if true or 0
|
||||
#else
|
||||
# error "boolean preproc check fail true or 0"
|
||||
#endif
|
||||
|
||||
#if true and 1
|
||||
#else
|
||||
# error "boolean preproc check fail true and 1"
|
||||
#endif
|
||||
|
||||
#if true xor false
|
||||
#else
|
||||
# error "boolean preproc check fail true xor false"
|
||||
#endif
|
||||
|
||||
#if 1 bitor 2
|
||||
#else
|
||||
# error "boolean preproc check fail 1 bitor 2"
|
||||
#endif
|
||||
|
||||
#if not(1 bitand 2)
|
||||
#else
|
||||
# error "boolean preproc check fail not(1 bitand 2)"
|
||||
#endif
|
||||
|
||||
#if compl 0
|
||||
#else
|
||||
# error "boolean preproc check fail compl 0"
|
||||
#endif
|
||||
|
||||
#if (1 bitor 2) not_eq 1
|
||||
#else
|
||||
# error "boolean preproc check fail (1 bitor 2) not_eq 1"
|
||||
#endif
|
||||
|
||||
|
||||
// Regression tests for bugs handling a comma in a comment in a macro:
|
||||
|
|
|
@ -719,12 +719,6 @@ num_common:
|
|||
|
||||
/* C++ keywords */
|
||||
if (cparse_cplusplus) {
|
||||
if (strcmp(yytext, "and") == 0)
|
||||
return (LAND);
|
||||
if (strcmp(yytext, "or") == 0)
|
||||
return (LOR);
|
||||
if (strcmp(yytext, "not") == 0)
|
||||
return (LNOT);
|
||||
if (strcmp(yytext, "class") == 0)
|
||||
return (CLASS);
|
||||
if (strcmp(yytext, "private") == 0)
|
||||
|
@ -802,9 +796,12 @@ num_common:
|
|||
yylval.str = s;
|
||||
return OPERATOR;
|
||||
} else if (nexttok == SWIG_TOKEN_ID) {
|
||||
/* We have an identifier. This could be any number of things. It could be a named version of
|
||||
an operator (e.g., 'and_eq') or it could be a conversion operator. To deal with this, we're
|
||||
going to read tokens until we encounter a ( or ;. Some care is needed for formatting. */
|
||||
/* We have an identifier. It could be "new" or "delete",
|
||||
* potentially followed by "[]", or it could be a conversion
|
||||
* operator (it can't be "and_eq" or similar as those are returned
|
||||
* as SWIG_TOKEN_ANDEQUAL, etc by Scanner_token()). To deal with
|
||||
* this we read tokens until we encounter a suitable terminating
|
||||
* token. Some care is needed for formatting. */
|
||||
int needspace = 1;
|
||||
int termtoken = 0;
|
||||
const char *termvalue = 0;
|
||||
|
@ -856,17 +853,6 @@ num_common:
|
|||
|| (strcmp(t, "delete") == 0)
|
||||
|| (strcmp(t, "new[]") == 0)
|
||||
|| (strcmp(t, "delete[]") == 0)
|
||||
|| (strcmp(t, "and") == 0)
|
||||
|| (strcmp(t, "and_eq") == 0)
|
||||
|| (strcmp(t, "bitand") == 0)
|
||||
|| (strcmp(t, "bitor") == 0)
|
||||
|| (strcmp(t, "compl") == 0)
|
||||
|| (strcmp(t, "not") == 0)
|
||||
|| (strcmp(t, "not_eq") == 0)
|
||||
|| (strcmp(t, "or") == 0)
|
||||
|| (strcmp(t, "or_eq") == 0)
|
||||
|| (strcmp(t, "xor") == 0)
|
||||
|| (strcmp(t, "xor_eq") == 0)
|
||||
)) {
|
||||
/* retract(strlen(t)); */
|
||||
|
||||
|
|
|
@ -1025,12 +1025,35 @@ static int look(Scanner *s) {
|
|||
}
|
||||
break;
|
||||
|
||||
case 76: /* Identifier or true/false */
|
||||
case 76: /* Identifier, true/false or alternative token */
|
||||
if (cparse_cplusplus) {
|
||||
if (Strcmp(s->text, "true") == 0)
|
||||
return SWIG_TOKEN_BOOL;
|
||||
else if (Strcmp(s->text, "false") == 0)
|
||||
if (Strcmp(s->text, "false") == 0)
|
||||
return SWIG_TOKEN_BOOL;
|
||||
|
||||
if (Strcmp(s->text, "and") == 0)
|
||||
return SWIG_TOKEN_LAND;
|
||||
if (Strcmp(s->text, "and_eq") == 0)
|
||||
return SWIG_TOKEN_ANDEQUAL;
|
||||
if (Strcmp(s->text, "bitand") == 0)
|
||||
return SWIG_TOKEN_AND;
|
||||
if (Strcmp(s->text, "bitor") == 0)
|
||||
return SWIG_TOKEN_OR;
|
||||
if (Strcmp(s->text, "compl") == 0)
|
||||
return SWIG_TOKEN_NOT;
|
||||
if (Strcmp(s->text, "not") == 0)
|
||||
return SWIG_TOKEN_LNOT;
|
||||
if (Strcmp(s->text, "not_eq") == 0)
|
||||
return SWIG_TOKEN_NOTEQUAL;
|
||||
if (Strcmp(s->text, "or") == 0)
|
||||
return SWIG_TOKEN_LOR;
|
||||
if (Strcmp(s->text, "or_eq") == 0)
|
||||
return SWIG_TOKEN_OREQUAL;
|
||||
if (Strcmp(s->text, "xor") == 0)
|
||||
return SWIG_TOKEN_XOR;
|
||||
if (Strcmp(s->text, "xor_eq") == 0)
|
||||
return SWIG_TOKEN_XOREQUAL;
|
||||
}
|
||||
return SWIG_TOKEN_ID;
|
||||
|
||||
|
|
Loading…
Reference in New Issue