Skip to content

Commit

Permalink
Add support for extern "C" thread_local
Browse files Browse the repository at this point in the history
  • Loading branch information
wsfulton committed Feb 8, 2013
1 parent 7fcfdee commit e44656c
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 6 deletions.
2 changes: 2 additions & 0 deletions Examples/test-suite/cpp0x_thread_local.i
Expand Up @@ -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;
Expand All @@ -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;
%}
4 changes: 4 additions & 0 deletions Examples/test-suite/java/cpp0x_thread_local_runme.java
Expand Up @@ -39,5 +39,9 @@ public static void main(String argv[])
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();
}
}
4 changes: 4 additions & 0 deletions Examples/test-suite/python/cpp0x_thread_local_runme.py
Expand Up @@ -28,3 +28,7 @@
if cvar.teval != -55:
raise RuntimeError

cvar.ectval = -66
if cvar.ectval != -66:
raise RuntimeError

13 changes: 11 additions & 2 deletions Source/CParse/parser.y
Expand Up @@ -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;
Expand Down Expand Up @@ -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"; }
Expand Down
5 changes: 2 additions & 3 deletions Source/Modules/clisp.cxx
Expand Up @@ -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");
Expand Down Expand Up @@ -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");
Expand Down
2 changes: 1 addition & 1 deletion Source/Modules/lang.cxx
Expand Up @@ -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);
Expand Down
11 changes: 11 additions & 0 deletions Source/Swig/misc.c
Expand Up @@ -273,6 +273,17 @@ int Swig_storage_isextern(Node *n) {
return storage ? Strcmp(storage, "extern") == 0 || Strncmp(storage, "extern ", 7) == 0 : 0;
}

/* -----------------------------------------------------------------------------
* 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()
*
Expand Down
1 change: 1 addition & 0 deletions Source/Swig/swig.h
Expand Up @@ -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);
Expand Down

0 comments on commit e44656c

Please sign in to comment.