From e1afb6fdbe8d5200c6aa2a06a657c8befedc7cdf Mon Sep 17 00:00:00 2001 From: Jiulong Wang Date: Wed, 7 Sep 2016 15:46:16 -0700 Subject: [PATCH] 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. --- Source/CParse/cparse.h | 3 +++ Source/CParse/parser.y | 40 ++++++++++++++++++++-------------------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/Source/CParse/cparse.h b/Source/CParse/cparse.h index ab5f74b19..8079805e4 100644 --- a/Source/CParse/cparse.h +++ b/Source/CParse/cparse.h @@ -78,4 +78,7 @@ extern "C" { #define SWIG_WARN_NODE_END(Node) \ if (wrnfilter) Swig_warnfilter(wrnfilter,0); \ } + +#define COMPOUND_EXPR_VAL(dtype) \ + ((dtype).type == T_CHAR || (dtype).type == T_WCHAR ? (dtype).rawval : (dtype).val) #endif diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 784187c28..f6af46801 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -6095,81 +6095,81 @@ exprnum : NUM_INT { $$ = $1; } ; 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); } | 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); } | 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); } | 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); } | 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); } | 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); } | 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); } | 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); } | 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); } | 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); } | 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; } | 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; } | 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; } | 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; } /* Sadly this causes 2 reduce-reduce conflicts with templates. FIXME resolve these. | 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; } | 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; } */ | 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; } | 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; } | 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 * for the purposes of parsing constant expressions. */ $$.type = promote($3.type, $5.type); @@ -6187,7 +6187,7 @@ exprcompound : expr PLUS expr { $$.type = $2.type; } | LNOT expr { - $$.val = NewStringf("!%s",$2.val); + $$.val = NewStringf("!%s",COMPOUND_EXPR_VAL($2)); $$.type = T_INT; } | type LPAREN {