Fix enum error when value contains char in compound expression

Problem: When enum value contains compound expression with a char
constant, the quotes around char constant is missing in the generated
expression. Example:

enum media_type {
  YUY2 = ((('2' << 24) | ('Y' << 16)) | ('U' << 8)) | 'Y'
};

The generated C# enum becomes:

public enum media_type {
  YUY2 = (((2 << 24)|(Y << 16))|(U << 8))|Y
}

While the correct representation (after this fix) should be:

public enum media_type {
  YUY2 = ((('2' << 24)|('Y' << 16))|('U' << 8))|'Y'
}

Causes: the exprcompound promotes the expression type from char to int
and uses $1.val in the generated expression. However $1.val does not
contain the quotes. Since the type is promoted to int, there's no way to
know there's char component in the compound expression.

Solution: in exprcomound, use $1.rawval if $1.type is T_CHAR or T_WCHAR.
The rawval contains quotes which yield correct expression.
This commit is contained in:
Jiulong Wang 2016-09-07 15:46:16 -07:00
commit e1afb6fdbe
2 changed files with 23 additions and 20 deletions

View file

@ -78,4 +78,7 @@ extern "C" {
#define SWIG_WARN_NODE_END(Node) \ #define SWIG_WARN_NODE_END(Node) \
if (wrnfilter) Swig_warnfilter(wrnfilter,0); \ if (wrnfilter) Swig_warnfilter(wrnfilter,0); \
} }
#define COMPOUND_EXPR_VAL(dtype) \
((dtype).type == T_CHAR || (dtype).type == T_WCHAR ? (dtype).rawval : (dtype).val)
#endif #endif

View file

@ -6095,81 +6095,81 @@ exprnum : NUM_INT { $$ = $1; }
; ;
exprcompound : expr PLUS expr { exprcompound : expr PLUS expr {
$$.val = NewStringf("%s+%s",$1.val,$3.val); $$.val = NewStringf("%s+%s", COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = promote($1.type,$3.type); $$.type = promote($1.type,$3.type);
} }
| expr MINUS expr { | expr MINUS expr {
$$.val = NewStringf("%s-%s",$1.val,$3.val); $$.val = NewStringf("%s-%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = promote($1.type,$3.type); $$.type = promote($1.type,$3.type);
} }
| expr STAR expr { | expr STAR expr {
$$.val = NewStringf("%s*%s",$1.val,$3.val); $$.val = NewStringf("%s*%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = promote($1.type,$3.type); $$.type = promote($1.type,$3.type);
} }
| expr SLASH expr { | expr SLASH expr {
$$.val = NewStringf("%s/%s",$1.val,$3.val); $$.val = NewStringf("%s/%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = promote($1.type,$3.type); $$.type = promote($1.type,$3.type);
} }
| expr MODULO expr { | expr MODULO expr {
$$.val = NewStringf("%s%%%s",$1.val,$3.val); $$.val = NewStringf("%s%%%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = promote($1.type,$3.type); $$.type = promote($1.type,$3.type);
} }
| expr AND expr { | expr AND expr {
$$.val = NewStringf("%s&%s",$1.val,$3.val); $$.val = NewStringf("%s&%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = promote($1.type,$3.type); $$.type = promote($1.type,$3.type);
} }
| expr OR expr { | expr OR expr {
$$.val = NewStringf("%s|%s",$1.val,$3.val); $$.val = NewStringf("%s|%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = promote($1.type,$3.type); $$.type = promote($1.type,$3.type);
} }
| expr XOR expr { | expr XOR expr {
$$.val = NewStringf("%s^%s",$1.val,$3.val); $$.val = NewStringf("%s^%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = promote($1.type,$3.type); $$.type = promote($1.type,$3.type);
} }
| expr LSHIFT expr { | expr LSHIFT expr {
$$.val = NewStringf("%s << %s",$1.val,$3.val); $$.val = NewStringf("%s << %s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = promote_type($1.type); $$.type = promote_type($1.type);
} }
| expr RSHIFT expr { | expr RSHIFT expr {
$$.val = NewStringf("%s >> %s",$1.val,$3.val); $$.val = NewStringf("%s >> %s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = promote_type($1.type); $$.type = promote_type($1.type);
} }
| expr LAND expr { | expr LAND expr {
$$.val = NewStringf("%s&&%s",$1.val,$3.val); $$.val = NewStringf("%s&&%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = cparse_cplusplus ? T_BOOL : T_INT; $$.type = cparse_cplusplus ? T_BOOL : T_INT;
} }
| expr LOR expr { | expr LOR expr {
$$.val = NewStringf("%s||%s",$1.val,$3.val); $$.val = NewStringf("%s||%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = cparse_cplusplus ? T_BOOL : T_INT; $$.type = cparse_cplusplus ? T_BOOL : T_INT;
} }
| expr EQUALTO expr { | expr EQUALTO expr {
$$.val = NewStringf("%s==%s",$1.val,$3.val); $$.val = NewStringf("%s==%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = cparse_cplusplus ? T_BOOL : T_INT; $$.type = cparse_cplusplus ? T_BOOL : T_INT;
} }
| expr NOTEQUALTO expr { | expr NOTEQUALTO expr {
$$.val = NewStringf("%s!=%s",$1.val,$3.val); $$.val = NewStringf("%s!=%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = cparse_cplusplus ? T_BOOL : T_INT; $$.type = cparse_cplusplus ? T_BOOL : T_INT;
} }
/* Sadly this causes 2 reduce-reduce conflicts with templates. FIXME resolve these. /* Sadly this causes 2 reduce-reduce conflicts with templates. FIXME resolve these.
| expr GREATERTHAN expr { | expr GREATERTHAN expr {
$$.val = NewStringf("%s > %s", $1.val, $3.val); $$.val = NewStringf("%s > %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
$$.type = cparse_cplusplus ? T_BOOL : T_INT; $$.type = cparse_cplusplus ? T_BOOL : T_INT;
} }
| expr LESSTHAN expr { | expr LESSTHAN expr {
$$.val = NewStringf("%s < %s", $1.val, $3.val); $$.val = NewStringf("%s < %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
$$.type = cparse_cplusplus ? T_BOOL : T_INT; $$.type = cparse_cplusplus ? T_BOOL : T_INT;
} }
*/ */
| expr GREATERTHANOREQUALTO expr { | expr GREATERTHANOREQUALTO expr {
$$.val = NewStringf("%s >= %s", $1.val, $3.val); $$.val = NewStringf("%s >= %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
$$.type = cparse_cplusplus ? T_BOOL : T_INT; $$.type = cparse_cplusplus ? T_BOOL : T_INT;
} }
| expr LESSTHANOREQUALTO expr { | expr LESSTHANOREQUALTO expr {
$$.val = NewStringf("%s <= %s", $1.val, $3.val); $$.val = NewStringf("%s <= %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
$$.type = cparse_cplusplus ? T_BOOL : T_INT; $$.type = cparse_cplusplus ? T_BOOL : T_INT;
} }
| expr QUESTIONMARK expr COLON expr %prec QUESTIONMARK { | expr QUESTIONMARK expr COLON expr %prec QUESTIONMARK {
$$.val = NewStringf("%s?%s:%s", $1.val, $3.val, $5.val); $$.val = NewStringf("%s?%s:%s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3), COMPOUND_EXPR_VAL($5));
/* This may not be exactly right, but is probably good enough /* This may not be exactly right, but is probably good enough
* for the purposes of parsing constant expressions. */ * for the purposes of parsing constant expressions. */
$$.type = promote($3.type, $5.type); $$.type = promote($3.type, $5.type);
@ -6187,7 +6187,7 @@ exprcompound : expr PLUS expr {
$$.type = $2.type; $$.type = $2.type;
} }
| LNOT expr { | LNOT expr {
$$.val = NewStringf("!%s",$2.val); $$.val = NewStringf("!%s",COMPOUND_EXPR_VAL($2));
$$.type = T_INT; $$.type = T_INT;
} }
| type LPAREN { | type LPAREN {