From befc9bc1f07be3b9ba83001b331cfac8315ebc20 Mon Sep 17 00:00:00 2001 From: Seth R Johnson Date: Tue, 23 Apr 2019 19:26:53 -0400 Subject: [PATCH 1/6] Mark 'externc' storage for variables --- Examples/test-suite/extern_c.i | 10 ++++++++++ Examples/test-suite/python/extern_c_runme.py | 3 +++ Source/CParse/parser.y | 3 +-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Examples/test-suite/extern_c.i b/Examples/test-suite/extern_c.i index e56d9f128..78c9d1061 100644 --- a/Examples/test-suite/extern_c.i +++ b/Examples/test-suite/extern_c.i @@ -5,6 +5,7 @@ extern "C" { void RealFunction(int value); typedef void Function1(int value); // Fails typedef int Integer1; +int Integer3; } typedef void Function2(int value); // Works typedef int Integer2; @@ -27,5 +28,14 @@ Hook2_t hook2; extern "C" typedef int Integer; Integer int1; +extern "C" int int2; +extern "C" { extern int int3; } +extern "C" { int int4 = 789; } %} +%{ +extern "C" { + int int2 = 123; + int int3 = 456; +} +%} diff --git a/Examples/test-suite/python/extern_c_runme.py b/Examples/test-suite/python/extern_c_runme.py index 91a218a87..5bc4bae89 100644 --- a/Examples/test-suite/python/extern_c_runme.py +++ b/Examples/test-suite/python/extern_c_runme.py @@ -1,3 +1,6 @@ import extern_c extern_c.RealFunction(2) +assert extern_c.cvar.int2 == 123 +assert extern_c.cvar.int3 == 456 +assert extern_c.cvar.int4 == 789 diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 87f2a7c44..beb326646 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -3133,8 +3133,7 @@ c_declaration : c_decl { Setattr($$,"name",$2); appendChild($$,n); while (n) { - SwigType *decl = Getattr(n,"decl"); - if (SwigType_isfunction(decl) && !Equal(Getattr(n, "storage"), "typedef")) { + if (!Equal(Getattr(n, "storage"), "typedef")) { Setattr(n,"storage","externc"); } n = nextSibling(n); From 4bdf454e977d67ecae138b9a933a5d00be071190 Mon Sep 17 00:00:00 2001 From: Seth R Johnson Date: Wed, 9 Feb 2022 21:02:41 -0500 Subject: [PATCH 2/6] Add extern C thread_local test cases --- Examples/test-suite/cpp11_thread_local.i | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Examples/test-suite/cpp11_thread_local.i b/Examples/test-suite/cpp11_thread_local.i index 21f21859b..7a82f7582 100644 --- a/Examples/test-suite/cpp11_thread_local.i +++ b/Examples/test-suite/cpp11_thread_local.i @@ -16,6 +16,7 @@ thread_local static int tsval; extern thread_local int etval; thread_local extern int teval; extern "C" thread_local int ectval; +extern "C" { thread_local int ectval2; } extern "C++" thread_local int ecpptval; thread_local int ThreadLocals::stval = 11; @@ -31,5 +32,6 @@ thread_local const int ThreadLocals::tscval99; thread_local int etval = 33; thread_local int teval = 44; thread_local int ectval = 55; +thread_local int ectval2 = 56; thread_local int ecpptval = 66; %} From 2ecc5bc214ad03894aefac26419b8e50cc61fbbb Mon Sep 17 00:00:00 2001 From: Seth R Johnson Date: Thu, 10 Feb 2022 07:18:43 -0500 Subject: [PATCH 3/6] Don't warn about legal `extern "C++" {}` block --- Examples/test-suite/cpp11_thread_local.i | 2 ++ Source/CParse/parser.y | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Examples/test-suite/cpp11_thread_local.i b/Examples/test-suite/cpp11_thread_local.i index 7a82f7582..80c9e4e87 100644 --- a/Examples/test-suite/cpp11_thread_local.i +++ b/Examples/test-suite/cpp11_thread_local.i @@ -18,6 +18,7 @@ thread_local extern int teval; extern "C" thread_local int ectval; extern "C" { thread_local int ectval2; } extern "C++" thread_local int ecpptval; +extern "C++" { thread_local int ecpptval2; } thread_local int ThreadLocals::stval = 11; thread_local int ThreadLocals::tsval = 22; @@ -34,4 +35,5 @@ thread_local int teval = 44; thread_local int ectval = 55; thread_local int ectval2 = 56; thread_local int ecpptval = 66; +thread_local int ecpptval2 = 67; %} diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index beb326646..2fd81ad9d 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -3139,7 +3139,9 @@ c_declaration : c_decl { n = nextSibling(n); } } else { - Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\".\n", $2); + if (!Equal($2,"C++")) { + Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\".\n", $2); + } $$ = new_node("extern"); Setattr($$,"name",$2); appendChild($$,firstChild($5)); From 14c09425054fc53ed357a56c615d4aea15d96d9e Mon Sep 17 00:00:00 2001 From: Seth R Johnson Date: Thu, 10 Feb 2022 07:33:09 -0500 Subject: [PATCH 4/6] Preserve thread_local for brace-enclosed extern "C" --- Source/CParse/parser.y | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 2fd81ad9d..35415bb28 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -3133,15 +3133,22 @@ c_declaration : c_decl { Setattr($$,"name",$2); appendChild($$,n); while (n) { - if (!Equal(Getattr(n, "storage"), "typedef")) { + String *s = Getattr(n, "storage"); + if (s) { + if (Strstr(s, "thread_local")) { + Insert(s,0,"externc "); + } else if (!Equal(s, "typedef")) { + Setattr(n,"storage","externc"); + } + } else { Setattr(n,"storage","externc"); } n = nextSibling(n); } } else { - if (!Equal($2,"C++")) { + if (!Equal($2,"C++")) { Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\".\n", $2); - } + } $$ = new_node("extern"); Setattr($$,"name",$2); appendChild($$,firstChild($5)); From af56a1f5c7cf91a841bdb11c48dbb65814d3a0cb Mon Sep 17 00:00:00 2001 From: Seth R Johnson Date: Thu, 10 Feb 2022 07:46:16 -0500 Subject: [PATCH 5/6] Preserve "externc" for non-brace thread_local --- Source/CParse/parser.y | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 35415bb28..0f9cffa61 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -5094,7 +5094,13 @@ extern_string : EXTERN string { storage_class : EXTERN { $$ = "extern"; } | extern_string { $$ = $1; } - | extern_string THREAD_LOCAL { $$ = "thread_local"; } + | extern_string THREAD_LOCAL { + if (Equal($1, "extern")) { + $$ = "extern thread_local"; + } else { + $$ = "externc thread_local"; + } + } | extern_string TYPEDEF { $$ = "typedef"; } | STATIC { $$ = "static"; } | TYPEDEF { $$ = "typedef"; } From c21b4a5529585218511399b19964990d97c06483 Mon Sep 17 00:00:00 2001 From: Seth R Johnson Date: Thu, 10 Feb 2022 10:02:18 -0500 Subject: [PATCH 6/6] Fix cpp11_thread_local test --- Examples/test-suite/cpp11_thread_local.i | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Examples/test-suite/cpp11_thread_local.i b/Examples/test-suite/cpp11_thread_local.i index 80c9e4e87..a85289149 100644 --- a/Examples/test-suite/cpp11_thread_local.i +++ b/Examples/test-suite/cpp11_thread_local.i @@ -16,9 +16,9 @@ thread_local static int tsval; extern thread_local int etval; thread_local extern int teval; extern "C" thread_local int ectval; -extern "C" { thread_local int ectval2; } +extern "C" { thread_local int ectval2 = 56; } extern "C++" thread_local int ecpptval; -extern "C++" { thread_local int ecpptval2; } +extern "C++" { thread_local int ecpptval2 = 67; } thread_local int ThreadLocals::stval = 11; thread_local int ThreadLocals::tsval = 22; @@ -32,8 +32,10 @@ thread_local const int ThreadLocals::tscval99; // externs thread_local int etval = 33; thread_local int teval = 44; +extern "C" { thread_local int ectval = 55; -thread_local int ectval2 = 56; +} +extern "C++" { thread_local int ecpptval = 66; -thread_local int ecpptval2 = 67; +} %}