Merge branch 'simple-c++-attribute-support'

This commit is contained in:
Olly Betts 2022-07-08 15:58:35 +12:00
commit e56ce01dfe
8 changed files with 118 additions and 5 deletions

View file

@ -7,6 +7,11 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
2022-07-07: jmarrec
#1158 #2286 Add basic support for C++11 attributes. These are now
crudely ignored by SWIG's parser's tokeniser, which is better that
failing with a parse error.
2022-07-05: ianlancetaylor
[Go] #2245 Handle NULL pointers for string* conversions.
Rearrange generation of director methods and rename

View file

@ -1089,7 +1089,9 @@ Use the preprocessor to work around this for now:
<p>
Attributes such as those shown below, are not yet supported and will give a syntax error.
Attributes such as those shown below, are supported since SWIG 4.1.0 but are
currently crudely ignored by the parser's tokeniser so they have no effect on
SWIG's code generation.
</p>
<div class="code"><pre>

View file

@ -583,6 +583,7 @@ CPP11_TEST_CASES += \
cpp11_alias_nested_template_scoping \
cpp11_alignment \
cpp11_alternate_function_syntax \
cpp11_attribute_specifiers \
cpp11_constexpr \
cpp11_decltype \
cpp11_default_delete \

View file

@ -0,0 +1,50 @@
%module cpp11_attribute_specifiers
%inline %{
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // We're using a deprecated attribute here...
#pragma GCC diagnostic ignored "-Wattributes" // likely is C++20
#pragma GCC diagnostic ignored "-Wunused-variable" // We are using an unused variable on purpose here
#pragma GCC diagnostic ignored "-Wunused-parameter" // We are using an unused param on purpose here
#endif
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#pragma clang diagnostic ignored "-Wattributes"
#pragma clang diagnostic ignored "-Wunused-variable"
#pragma clang diagnostic ignored "-Wunused-parameter"
#endif
[[noreturn]] void noReturn() { throw; }
[[nodiscard]] bool noDiscard() { return true; }
[[nodiscard, deprecated("This has been replaced")]] bool noDiscardDeprecated() { return true; }
void maybeUnused1([[maybe_unused]] bool b) { }
bool maybeUnused2(bool a, [[maybe_unused]] bool b) { return a; }
[[deprecated, nodiscard]] bool likely([[maybe_unused]] bool a, bool b) {
[[maybe_unused]] bool c = b;
if (b) [[likely]] {
return true;
} else [[unlikely]] {
if(a) {
return true;
}
}
return false;
}
struct [[nodiscard]] S { };
const char *test_string_literal() { return "Test [[ and ]] in string literal"; }
#if 0
// Check that SWIG doesn't choke on ]] when it's not part of an attribute.
// FIXME: SWIG's parser doesn't handle this case currently.
int *a;
int b = a[a[0]];
#endif
%}

View file

@ -0,0 +1,14 @@
<?php
require "tests.php";
// New functions
check::functions(array('noReturn','noDiscard','noDiscardDeprecated','maybeUnused1','maybeUnused2','likely','test_string_literal'));
// New classes
check::classes(array('cpp11_attribute_specifiers','S'));
// No new vars
check::globals(array());
check::equal(test_string_literal(), 'Test [[ and ]] in string literal', "test_string_literal() wrong");
check::done();

View file

@ -354,6 +354,20 @@ static int yylook(void) {
case SWIG_TOKEN_ELLIPSIS:
return ELLIPSIS;
case SWIG_TOKEN_LLBRACKET:
do {
tok = Scanner_token(scan);
} while ((tok != SWIG_TOKEN_RRBRACKET) && (tok > 0));
if (tok <= 0) {
Swig_error(cparse_file, cparse_line, "Unbalanced double brackets, missing closing (']]'). Reached end of input.\n");
}
break;
case SWIG_TOKEN_RRBRACKET:
/* Turn an unmatched ]] back into two ] - e.g. `a[a[0]]` */
scanner_next_token(RBRACKET);
return RBRACKET;
/* Look for multi-character sequences */
case SWIG_TOKEN_RSTRING:

View file

@ -596,10 +596,6 @@ static int look(Scanner *s) {
state = 3;
else if (c == '\\')
return SWIG_TOKEN_BACKSLASH;
else if (c == '[')
return SWIG_TOKEN_LBRACKET;
else if (c == ']')
return SWIG_TOKEN_RBRACKET;
else if (c == '@')
return SWIG_TOKEN_AT;
else if (c == '$')
@ -637,6 +633,10 @@ static int look(Scanner *s) {
else if (c == '.')
state = 100; /* Maybe a number, maybe ellipsis, just a period */
else if (c == '[')
state = 102; /* Maybe a bracket or a double bracket */
else if (c == ']')
state = 103; /* Maybe a bracket or a double bracket */
else if (isdigit(c))
state = 8; /* A numerical value */
else
@ -1358,6 +1358,31 @@ static int look(Scanner *s) {
}
break;
/* A left bracket or a double left bracket */
case 102:
if ((c = nextchar(s)) == 0) {
return SWIG_TOKEN_LBRACKET;
} else if (c == '[') {
return SWIG_TOKEN_LLBRACKET;
} else {
retract(s, 1);
return SWIG_TOKEN_LBRACKET;
}
break;
/* a right bracket or a double right bracket */
case 103:
if ((c = nextchar(s)) == 0) {
return SWIG_TOKEN_RBRACKET;
} else if (c == ']') {
return SWIG_TOKEN_RRBRACKET;
} else {
retract(s, 1);
return SWIG_TOKEN_RBRACKET;
}
break;
case 200: /* PLUS, PLUSPLUS, PLUSEQUAL */
if ((c = nextchar(s)) == 0)
return SWIG_TOKEN_PLUS;

View file

@ -71,6 +71,8 @@ extern void Scanner_locator(Scanner *, String *loc);
#define SWIG_TOKEN_WSTRING 33 /* L"str" */
#define SWIG_TOKEN_WCHAR 34 /* L'c' */
#define SWIG_TOKEN_ELLIPSIS 35 /* ... */
#define SWIG_TOKEN_LLBRACKET 36 /* [[ */
#define SWIG_TOKEN_RRBRACKET 37 /* ]] */
#define SWIG_TOKEN_ILLEGAL 99
#define SWIG_TOKEN_ERROR -1