diff --git a/Lib/swiglabels.swg b/Lib/swiglabels.swg index b3855665e..43b2f6edc 100644 --- a/Lib/swiglabels.swg +++ b/Lib/swiglabels.swg @@ -121,3 +121,8 @@ #ifdef __INTEL_COMPILER # pragma warning disable 592 #endif + +/* We replace `<<` with `SWIG_LSHIFT` in constant expressions to avoid + * confusing SWIG's type system into thinking there's a template. + */ +#define SWIG_LSHIFT << diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 816264de6..ce0602f3b 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -6803,7 +6803,11 @@ exprcompound : expr PLUS expr { $$.type = promote($1.type,$3.type); } | expr LSHIFT expr { - $$.val = NewStringf("%s << %s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3)); + /* To avoid confusing SWIG's type system, we replace `<<` with + * `SWIG_LSHIFT` here, then define the latter as a macro in + * the generated wrapper file. + */ + $$.val = NewStringf("%s SWIG_LSHIFT %s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3)); $$.type = promote_type($1.type); } | expr RSHIFT expr { diff --git a/Source/Swig/typesys.c b/Source/Swig/typesys.c index 464b89f28..710688a0f 100644 --- a/Source/Swig/typesys.c +++ b/Source/Swig/typesys.c @@ -1702,9 +1702,7 @@ void SwigType_remember_clientdata(const SwigType *t, const_String_or_char_ptr cl if (t) { char *ct = Char(t); - const char *lt = strchr(ct, '<'); - /* Allow for `<<` operator in constant expression for array size. */ - if (lt && lt[1] != '(' && lt[1] != '<') { + if (strchr(ct, '<') && !(strstr(ct, "<("))) { Printf(stdout, "Bad template type passed to SwigType_remember: %s\n", t); assert(0); }