Fix handle of constant expressions containing character literals (e.g. 'x').

Fixes bug #1474463.

Fix type of result of << and >> to match C rules (the type depends only on
the left argument).


git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@9354 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Olly Betts 2006-09-24 23:39:30 +00:00
commit 429d55824d
2 changed files with 23 additions and 11 deletions

View file

@ -185,8 +185,15 @@ int SWIG_cparse_template_reduce(int treduce) {
* Assist functions * Assist functions
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
static int promote_type(int t) {
if (t <= T_UCHAR || t == T_CHAR) return T_INT;
return t;
}
/* Perform type-promotion for binary operators */ /* Perform type-promotion for binary operators */
static int promote(int t1, int t2) { static int promote(int t1, int t2) {
t1 = promote_type(t1);
t2 = promote_type(t2);
return t1 > t2 ? t1 : t2; return t1 > t2 ? t1 : t2;
} }
@ -5284,7 +5291,7 @@ etype : expr {
if (($$.type != T_INT) && ($$.type != T_UINT) && if (($$.type != T_INT) && ($$.type != T_UINT) &&
($$.type != T_LONG) && ($$.type != T_ULONG) && ($$.type != T_LONG) && ($$.type != T_ULONG) &&
($$.type != T_SHORT) && ($$.type != T_USHORT) && ($$.type != T_SHORT) && ($$.type != T_USHORT) &&
($$.type != T_SCHAR) && ($$.type != T_UCHAR) && ($$.type != T_SCHAR) && ($$.type != T_UCHAR) &&
($$.type != T_CHAR)) { ($$.type != T_CHAR)) {
Swig_error(cparse_file,cparse_line,"Type error. Expecting an int\n"); Swig_error(cparse_file,cparse_line,"Type error. Expecting an int\n");
} }
@ -5292,12 +5299,17 @@ etype : expr {
} }
; ;
/* Arithmetic expressions. Used for constants and other cool stuff. /* Arithmetic expressions. Used for constants, C++ templates, and other cool stuff. */
Really, we're not doing anything except string concatenation, but
this does allow us to parse many constant declarations.
*/
expr : valexpr { $$ = $1; } expr : valexpr {
$$ = $1;
/* We want the rawval for a character constant (e.g. 'x'
* not just x) since we use it in C code. */
if ($$.type == T_CHAR && $$.rawval) {
$$.val = $$.rawval;
$$.rawval = 0;
}
}
| type { | type {
Node *n; Node *n;
$$.val = $1; $$.val = $1;
@ -5331,9 +5343,9 @@ valexpr : exprnum { $$ = $1; }
| CHARCONST { | CHARCONST {
$$.val = NewString($1); $$.val = NewString($1);
if (Len($$.val)) { if (Len($$.val)) {
$$.rawval = NewStringf("\'%(escape)s\'", $$.val); $$.rawval = NewStringf("'%(escape)s'", $$.val);
} else { } else {
$$.rawval = NewString("\'\\0'"); $$.rawval = NewString("'\\0'");
} }
$$.type = T_CHAR; $$.type = T_CHAR;
$$.bitfield = 0; $$.bitfield = 0;
@ -5430,11 +5442,11 @@ exprcompound : expr PLUS expr {
} }
| expr LSHIFT expr { | expr LSHIFT expr {
$$.val = NewStringf("%s << %s",$1.val,$3.val); $$.val = NewStringf("%s << %s",$1.val,$3.val);
$$.type = promote($1.type,$3.type); $$.type = promote_type($1.type);
} }
| expr RSHIFT expr { | expr RSHIFT expr {
$$.val = NewStringf("%s >> %s",$1.val,$3.val); $$.val = NewStringf("%s >> %s",$1.val,$3.val);
$$.type = promote($1.type,$3.type); $$.type = promote_type($1.type);
} }
| expr LAND expr { | expr LAND expr {
$$.val = NewStringf("%s&&%s",$1.val,$3.val); $$.val = NewStringf("%s&&%s",$1.val,$3.val);

View file

@ -495,7 +495,7 @@ int Language::constantDirective(Node *n) {
value = NewStringf("%(escape)s", value); value = NewStringf("%(escape)s", value);
} }
*/ */
Setattr(n,"rawvalue",value); Setattr(n,"rawval",value);
value = NewStringf("%(escape)s", value); value = NewStringf("%(escape)s", value);
if (!Len(value)) Append(value,"\\0"); if (!Len(value)) Append(value,"\\0");
/* Printf(stdout,"'%s' = '%s'\n", name, value); */ /* Printf(stdout,"'%s' = '%s'\n", name, value); */