diff options
Diffstat (limited to 'Source/Swig/stype.c')
-rw-r--r-- | Source/Swig/stype.c | 163 |
1 files changed, 131 insertions, 32 deletions
diff --git a/Source/Swig/stype.c b/Source/Swig/stype.c index 66518f50c..b0eec2fdb 100644 --- a/Source/Swig/stype.c +++ b/Source/Swig/stype.c @@ -4,7 +4,7 @@ * terms also apply to certain portions of SWIG. The full details of the SWIG * license and copyrights can be found in the LICENSE and COPYRIGHT files * included with the SWIG source code as distributed by the SWIG developers - * and at http://www.swig.org/legal.html. + * and at https://www.swig.org/legal.html. * * stype.c * @@ -42,6 +42,7 @@ * 'p.' = Pointer (*) * 'r.' = Reference (&) * 'z.' = Rvalue reference (&&) + * 'v.' = Variadic (...) * 'a(n).' = Array of size n [n] * 'f(..,..).' = Function with arguments (args) * 'q(str).' = Qualifier, such as const or volatile (cv-qualifier) @@ -108,71 +109,59 @@ SwigType *NewSwigType(int t) { switch (t) { case T_BOOL: return NewString("bool"); - break; + case T_UNKNOWN: + /* Handle like T_INT since we used to just use T_INT where we now use + * T_UNKNOWN. + */ case T_INT: return NewString("int"); - break; case T_UINT: return NewString("unsigned int"); - break; case T_SHORT: return NewString("short"); - break; case T_USHORT: return NewString("unsigned short"); - break; case T_LONG: return NewString("long"); - break; case T_ULONG: return NewString("unsigned long"); - break; case T_FLOAT: return NewString("float"); - break; case T_DOUBLE: return NewString("double"); - break; + case T_LONGDOUBLE: + return NewString("long double"); + case T_FLTCPLX: + return NewString("float _Complex"); case T_COMPLEX: - return NewString("complex"); - break; + return NewString("_Complex"); case T_CHAR: return NewString("char"); - break; case T_SCHAR: return NewString("signed char"); - break; case T_UCHAR: return NewString("unsigned char"); - break; case T_STRING: { SwigType *t = NewString("char"); SwigType_add_qualifier(t, "const"); SwigType_add_pointer(t); return t; - break; } case T_WCHAR: return NewString("wchar_t"); - break; case T_WSTRING: { SwigType *t = NewString("wchar_t"); SwigType_add_pointer(t); return t; - break; } case T_LONGLONG: return NewString("long long"); - break; case T_ULONGLONG: return NewString("unsigned long long"); - break; case T_VOID: return NewString("void"); - break; case T_AUTO: return NewString("auto"); - break; default: break; } @@ -260,8 +249,12 @@ int SwigType_isconst(const SwigType *t) { int SwigType_ismutable(const SwigType *t) { int r; SwigType *qt = SwigType_typedef_resolve_all(t); - if (SwigType_isreference(qt) || SwigType_isrvalue_reference(qt) || SwigType_isarray(qt)) { + if (SwigType_isreference(qt) || SwigType_isrvalue_reference(qt)) { Delete(SwigType_pop(qt)); + } else { + while (SwigType_isarray(qt)) { + Delete(SwigType_pop(qt)); + } } r = SwigType_isconst(qt); Delete(qt); @@ -549,7 +542,7 @@ String *SwigType_str(const SwigType *s, const_String_or_char_ptr id) { int nelements, i; if (id) { - /* stringify the id expanding templates, for example when the id is a fully qualified templated class name */ + /* Stringify the id expanding templates, for example when the id is a fully qualified class template name */ String *id_str = NewString(id); /* unfortunate copy due to current const limitations */ result = SwigType_str(id_str, 0); Delete(id_str); @@ -624,6 +617,12 @@ String *SwigType_str(const SwigType *s, const_String_or_char_ptr id) { Insert(result, 0, "("); Append(result, ")"); } + } else if (SwigType_isvariadic(element)) { + Insert(result, 0, "..."); + if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { + Insert(result, 0, "("); + Append(result, ")"); + } } else if (SwigType_isarray(element)) { DOH *size; Append(result, "["); @@ -1190,7 +1189,9 @@ static String *manglestr_default(const SwigType *s) { SwigType *type = ss; if (SwigType_istemplate(ss)) { - SwigType *ty = Swig_symbol_template_deftype(ss, 0); + SwigType *dt = Swig_symbol_template_deftype(ss, 0); + String *ty = Swig_symbol_type_qualify(dt, 0); + Delete(dt); Delete(ss); ss = ty; type = ss; @@ -1253,10 +1254,10 @@ static String *manglestr_default(const SwigType *s) { String *SwigType_manglestr(const SwigType *s) { #if 0 /* Debugging checks to ensure a proper SwigType is passed in and not a stringified type */ - String *angle = Strstr(s, "<"); + String *angle = Strchr(s, '<'); if (angle && Strncmp(angle, "<(", 2) != 0) Printf(stderr, "SwigType_manglestr error: %s\n", s); - else if (Strstr(s, "*") || Strstr(s, "&") || Strstr(s, "[")) + else if (Strchr(s, '*') || Strchr(s, '&') || Strchr(s, '[')) Printf(stderr, "SwigType_manglestr error: %s\n", s); #endif return manglestr_default(s); @@ -1266,6 +1267,11 @@ String *SwigType_manglestr(const SwigType *s) { * SwigType_typename_replace() * * Replaces a typename in a type with something else. Needed for templates. + * Collapses duplicate const into a single const. + * Reference collapsing probably should be implemented here. + * Example: + * t=r.q(const).T pat=T rep=int => r.q(const).int + * t=r.q(const).T pat=T rep=q(const).int => r.q(const).int (duplicate const removed) * ----------------------------------------------------------------------------- */ void SwigType_typename_replace(SwigType *t, String *pat, String *rep) { @@ -1288,14 +1294,40 @@ void SwigType_typename_replace(SwigType *t, String *pat, String *rep) { if (SwigType_issimple(e)) { if (Equal(e, pat)) { /* Replaces a type of the form 'pat' with 'rep<args>' */ - Replace(e, pat, rep, DOH_REPLACE_ANY); + if (SwigType_isconst(rep) && i > 0 && SwigType_isconst(Getitem(elem, i - 1))) { + /* Collapse duplicate const into a single const */ + SwigType *rep_without_const = Copy(rep); + Delete(SwigType_pop(rep_without_const)); + Replace(e, pat, rep_without_const, DOH_REPLACE_ANY); + Delete(rep_without_const); + } else { + Replace(e, pat, rep, DOH_REPLACE_ANY); + } } else if (SwigType_istemplate(e)) { /* Replaces a type of the form 'pat<args>' with 'rep' */ - if (Equal(e, pat)) { - String *repbase = SwigType_templateprefix(rep); - Replace(e, pat, repbase, DOH_REPLACE_ID | DOH_REPLACE_FIRST); - Delete(repbase); + { + /* To match "e=TemplateTemplateT<(float)>" + * with "pat=TemplateTemplateT" + * we need to compare only the first part of the string e. + */ + int len = Len(pat); + + /* Len(e) > len, not >= (because we expect at least a + * character '<' following the template typename) + */ + if (Len(e) > len) { + String *firstPartOfType = NewStringWithSize(e, len); + const char* e_as_char = Char(e); + + if (Equal(firstPartOfType, pat) && e_as_char[len] == '<') { + String *repbase = SwigType_templateprefix(rep); + Replace(e, pat, repbase, DOH_REPLACE_ID | DOH_REPLACE_FIRST); + Delete(repbase); + } + Delete(firstPartOfType); + } } + { String *tsuffix; List *tparms = SwigType_parmlist(e); @@ -1366,6 +1398,73 @@ void SwigType_typename_replace(SwigType *t, String *pat, String *rep) { } /* ----------------------------------------------------------------------------- + * SwigType_variadic_replace() + * + * Replaces variadic parameter with a list of (zero or more) parameters. + * Needed for variadic templates. + * ----------------------------------------------------------------------------- */ + +void SwigType_variadic_replace(SwigType *t, Parm *unexpanded_variadic_parm, ParmList *expanded_variadic_parms) { + String *nt; + int i, ilen; + List *elem; + if (!unexpanded_variadic_parm) + return; + + if (SwigType_isvariadic(t)) { + /* Based on expand_variadic_parms() but input is single SwigType (t) instead of ParmList */ + String *unexpanded_name = Getattr(unexpanded_variadic_parm, "name"); + ParmList *expanded = CopyParmList(expanded_variadic_parms); + Parm *ep = expanded; + SwigType *fparms; + while (ep) { + SwigType *newtype = Copy(t); + SwigType_del_variadic(newtype); + Replaceid(newtype, unexpanded_name, Getattr(ep, "type")); + Setattr(ep, "type", newtype); + ep = nextSibling(ep); + } + Clear(t); + fparms = SwigType_function_parms_only(expanded); + Append(t, fparms); + Delete(expanded); + + return; + } + nt = NewStringEmpty(); + elem = SwigType_split(t); + ilen = Len(elem); + for (i = 0; i < ilen; i++) { + String *e = Getitem(elem, i); + if (SwigType_isfunction(e)) { + int j, jlen; + List *fparms = SwigType_parmlist(e); + Clear(e); + Append(e, "f("); + jlen = Len(fparms); + for (j = 0; j < jlen; j++) { + SwigType *type = Getitem(fparms, j); + SwigType_variadic_replace(type, unexpanded_variadic_parm, expanded_variadic_parms); + if (Len(type) > 0) { + if (j != 0) + Putc(',', e); + Append(e, type); + } else { + assert(j == jlen - 1); /* A variadic parm was replaced with zero parms, variadic parms are only changed at the end of the list */ + } + } + Append(e, ")."); + Delete(fparms); + } + Append(nt, e); + } + Clear(t); + Append(t, nt); + Delete(nt); + Delete(elem); +} + +/* ----------------------------------------------------------------------------- * SwigType_remove_global_scope_prefix() * * Removes the unary scope operator (::) prefix indicating global scope in all |