summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam S Fulton <wsf@fultondesigns.co.uk>2013-02-08 18:45:29 +0000
committerWilliam S Fulton <wsf@fultondesigns.co.uk>2013-02-08 18:45:29 +0000
commite44656cfe5b1d79643a1b972736a5ab485a6e948 (patch)
tree380d96564a263cf5aff5705ee795900aebc9fd77
parent7fcfdeee0837fb240fb30c521a9471de6e0e7bfa (diff)
downloadswig-e44656cfe5b1d79643a1b972736a5ab485a6e948.tar.gz
Add support for extern "C" thread_local
-rw-r--r--Examples/test-suite/cpp0x_thread_local.i2
-rw-r--r--Examples/test-suite/java/cpp0x_thread_local_runme.java4
-rw-r--r--Examples/test-suite/python/cpp0x_thread_local_runme.py4
-rw-r--r--Source/CParse/parser.y13
-rw-r--r--Source/Modules/clisp.cxx5
-rw-r--r--Source/Modules/lang.cxx2
-rw-r--r--Source/Swig/misc.c11
-rw-r--r--Source/Swig/swig.h1
8 files changed, 36 insertions, 6 deletions
diff --git a/Examples/test-suite/cpp0x_thread_local.i b/Examples/test-suite/cpp0x_thread_local.i
index 5ba01ea58..96faaaec4 100644
--- a/Examples/test-suite/cpp0x_thread_local.i
+++ b/Examples/test-suite/cpp0x_thread_local.i
@@ -15,6 +15,7 @@ static thread_local int stval;
thread_local static int tsval;
extern thread_local int etval;
thread_local extern int teval;
+extern "C" thread_local int ectval;
thread_local int ThreadLocals::stval = 11;
thread_local int ThreadLocals::tsval = 22;
@@ -26,4 +27,5 @@ thread_local const int ThreadLocals::tscval99;
// externs
thread_local int etval = 33;
thread_local int teval = 44;
+thread_local int ectval = 55;
%}
diff --git a/Examples/test-suite/java/cpp0x_thread_local_runme.java b/Examples/test-suite/java/cpp0x_thread_local_runme.java
index adc88a903..d660f77db 100644
--- a/Examples/test-suite/java/cpp0x_thread_local_runme.java
+++ b/Examples/test-suite/java/cpp0x_thread_local_runme.java
@@ -39,5 +39,9 @@ public class cpp0x_thread_local_runme {
cpp0x_thread_local.setTeval(-55);
if (cpp0x_thread_local.getTeval() != -55)
throw new RuntimeException();
+
+ cpp0x_thread_local.setEctval(-55);
+ if (cpp0x_thread_local.getEctval() != -55)
+ throw new RuntimeException();
}
}
diff --git a/Examples/test-suite/python/cpp0x_thread_local_runme.py b/Examples/test-suite/python/cpp0x_thread_local_runme.py
index b4aa177f6..a4d9852f7 100644
--- a/Examples/test-suite/python/cpp0x_thread_local_runme.py
+++ b/Examples/test-suite/python/cpp0x_thread_local_runme.py
@@ -28,3 +28,7 @@ cvar.teval = -55
if cvar.teval != -55:
raise RuntimeError
+cvar.ectval = -66
+if cvar.ectval != -66:
+ raise RuntimeError
+
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index 33f11958e..35e600d5e 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -1491,8 +1491,9 @@ static void new_feature(const char *featurename, String *val, Hash *featureattri
/* check if a function declaration is a plain C object */
static int is_cfunction(Node *n) {
- if (!cparse_cplusplus || cparse_externc) return 1;
- if (Cmp(Getattr(n,"storage"),"externc") == 0) {
+ if (!cparse_cplusplus || cparse_externc)
+ return 1;
+ if (Swig_storage_isexternc(n)) {
return 1;
}
return 0;
@@ -5034,6 +5035,14 @@ storage_class : EXTERN { $$ = "extern"; }
$$ = 0;
}
}
+ | EXTERN string THREAD_LOCAL {
+ if (strcmp($2,"C") == 0) {
+ $$ = "externc thread_local";
+ } else {
+ Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\".\n", $2);
+ $$ = 0;
+ }
+ }
| STATIC { $$ = "static"; }
| TYPEDEF { $$ = "typedef"; }
| VIRTUAL { $$ = "virtual"; }
diff --git a/Source/Modules/clisp.cxx b/Source/Modules/clisp.cxx
index 7dfa74539..e7d971faa 100644
--- a/Source/Modules/clisp.cxx
+++ b/Source/Modules/clisp.cxx
@@ -148,7 +148,7 @@ int CLISP::top(Node *n) {
int CLISP::functionWrapper(Node *n) {
is_function = 1;
String *storage = Getattr(n, "storage");
- if (!extern_all_flag && (!storage || (!Swig_storage_isextern(n) && Strcmp(storage, "externc"))))
+ if (!extern_all_flag && (!storage || (!Swig_storage_isextern(n) && !Swig_storage_isexternc(n))))
return SWIG_OK;
String *func_name = Getattr(n, "sym:name");
@@ -217,10 +217,9 @@ int CLISP::constantWrapper(Node *n) {
int CLISP::variableWrapper(Node *n) {
is_function = 0;
- // SwigType *type=;
String *storage = Getattr(n, "storage");
- if (!extern_all_flag && (!storage || (!Swig_storage_isextern(n) && Strcmp(storage, "externc"))))
+ if (!extern_all_flag && (!storage || (!Swig_storage_isextern(n) && !Swig_storage_isexternc(n))))
return SWIG_OK;
String *var_name = Getattr(n, "sym:name");
diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx
index 5aa18a251..6c2ea8271 100644
--- a/Source/Modules/lang.cxx
+++ b/Source/Modules/lang.cxx
@@ -985,7 +985,7 @@ int Language::cDeclaration(Node *n) {
}
}
Printf(f_header, ";\n");
- } else if (Cmp(storage, "externc") == 0) {
+ } else if (Swig_storage_isexternc(n)) {
/* here 'extern "C"' is needed */
String *str = SwigType_str(ty, name);
Printf(f_header, "extern \"C\" %s;\n", str);
diff --git a/Source/Swig/misc.c b/Source/Swig/misc.c
index 297d1ccdc..229633bab 100644
--- a/Source/Swig/misc.c
+++ b/Source/Swig/misc.c
@@ -274,6 +274,17 @@ int Swig_storage_isextern(Node *n) {
}
/* -----------------------------------------------------------------------------
+ * Swig_storage_isexternc()
+ *
+ * Determine if the storage class specifier is externc (but not plain extern)
+ * ----------------------------------------------------------------------------- */
+
+int Swig_storage_isexternc(Node *n) {
+ const String *storage = Getattr(n, "storage");
+ return storage ? Strcmp(storage, "externc") == 0 || Strncmp(storage, "externc ", 8) == 0 : 0;
+}
+
+/* -----------------------------------------------------------------------------
* Swig_storage_isstatic_custom()
*
* Determine if the storage class specifier is static
diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h
index 85d8c0b3e..b730ab04d 100644
--- a/Source/Swig/swig.h
+++ b/Source/Swig/swig.h
@@ -316,6 +316,7 @@ extern int ParmList_is_compactdefargs(ParmList *p);
extern String *Swig_filename_escape(String *filename);
extern void Swig_filename_unescape(String *filename);
extern int Swig_storage_isextern(Node *n);
+ extern int Swig_storage_isexternc(Node *n);
extern int Swig_storage_isstatic_custom(Node *n, const_String_or_char_ptr storage);
extern int Swig_storage_isstatic(Node *n);
extern String *Swig_string_escape(String *s);