diff --git a/Examples/test-suite/csharp/enum_thorough_typesafe_runme.cs b/Examples/test-suite/csharp/enum_thorough_typesafe_runme.cs index 86179dcf4c2..82c52a31f64 100644 --- a/Examples/test-suite/csharp/enum_thorough_typesafe_runme.cs +++ b/Examples/test-suite/csharp/enum_thorough_typesafe_runme.cs @@ -405,6 +405,10 @@ static void Main() { if (enum_thorough_typesafe.repeatTest(repeat.llast).swigValue != 3) throw new Exception("repeatTest 5 failed"); if (enum_thorough_typesafe.repeatTest(repeat.end).swigValue != 3) throw new Exception("repeatTest 6 failed"); } + { + if (enum_thorough_typesafe.enumWithMacroTest(enumWithMacro.ABCD).swigValue != (('A' << 24) | ('B' << 16) | ('C' << 8) | 'D')) throw new Exception("enumWithMacroTest 1 failed"); + if (enum_thorough_typesafe.enumWithMacroTest(enumWithMacro.ABCD2).swigValue != enum_thorough_typesafe.enumWithMacroTest(enumWithMacro.ABCD).swigValue) throw new Exception("enumWithMacroTest 2 failed"); + } // different types { if (enum_thorough_typesafe.differentTypesTest(DifferentTypes.typeint).swigValue != 10) throw new Exception("differentTypes 1 failed"); @@ -413,6 +417,8 @@ static void Main() { if (enum_thorough_typesafe.differentTypesTest(DifferentTypes.typeboolfalse).swigValue != 0) throw new Exception("differentTypes 4 failed"); if (enum_thorough_typesafe.differentTypesTest(DifferentTypes.typechar).swigValue != (int)'C') throw new Exception("differentTypes 5 failed"); if (enum_thorough_typesafe.differentTypesTest(DifferentTypes.typedefaultint).swigValue != (int)'D') throw new Exception("differentTypes 6 failed"); + if (enum_thorough_typesafe.differentTypesTest(DifferentTypes.typecharcompound).swigValue != (int)'A' + 1) throw new Exception("differentTypes 7 failed"); + if (enum_thorough_typesafe.differentTypesTest(DifferentTypes.typecharcompound2).swigValue != (int)'B' << 2) throw new Exception("differentTypes 8 failed"); int global_enum = enum_thorough_typesafe.global_typeint; if (enum_thorough_typesafe.globalDifferentTypesTest(global_enum) != 10) throw new Exception("global differentTypes 1 failed"); @@ -426,6 +432,10 @@ static void Main() { if (enum_thorough_typesafe.globalDifferentTypesTest(global_enum) != 'C') throw new Exception("global differentTypes 5 failed"); global_enum = enum_thorough_typesafe.global_typedefaultint; if (enum_thorough_typesafe.globalDifferentTypesTest(global_enum) != 'D') throw new Exception("global differentTypes 6 failed"); + global_enum = enum_thorough_typesafe.global_typecharcompound; + if (enum_thorough_typesafe.globalDifferentTypesTest(global_enum) != (int)'A' + 1) throw new Exception("global differentTypes 7 failed"); + global_enum = enum_thorough_typesafe.global_typecharcompound2; + if (enum_thorough_typesafe.globalDifferentTypesTest(global_enum) != (int)'B' << 2) throw new Exception("global differentTypes 8 failed"); } } } diff --git a/Examples/test-suite/enum_thorough.i b/Examples/test-suite/enum_thorough.i index f17a7ee966b..e54c03a85cd 100644 --- a/Examples/test-suite/enum_thorough.i +++ b/Examples/test-suite/enum_thorough.i @@ -563,6 +563,17 @@ repeat repeatTest(repeat e) { return e; } } %} +%inline %{ +namespace EnumWithMacro { +#define PACK(C1,C2,C3,C4) ((C1<<24)|(C2<<16)|(C3<<8)|C4) +typedef enum { + ABCD = PACK('A','B','C','D'), + ABCD2 = ABCD +} enumWithMacro; +enumWithMacro enumWithMacroTest(enumWithMacro e) { return e; } +} +%} + %inline %{ namespace DifferentSpace { enum DifferentTypes { @@ -571,7 +582,9 @@ enum DifferentTypes { typebooltrue = true, typebooltwo, typechar = 'C', - typedefaultint + typedefaultint, + typecharcompound='A'+1, + typecharcompound2='B' << 2 }; DifferentTypes differentTypesTest(DifferentTypes n) { return n; } @@ -581,7 +594,9 @@ enum { global_typebooltrue = true, global_typebooltwo, global_typechar = 'C', - global_typedefaultint + global_typedefaultint, + global_typecharcompound='A'+1, + global_typecharcompound2='B' << 2 }; int globalDifferentTypesTest(int n) { return n; } } diff --git a/Examples/test-suite/preproc_constants.i b/Examples/test-suite/preproc_constants.i index db71bd2d7cc..3a999ada367 100644 --- a/Examples/test-suite/preproc_constants.i +++ b/Examples/test-suite/preproc_constants.i @@ -51,7 +51,7 @@ // Expressions - runtime tests check the type for any necessary type promotions of the expressions #define INT_AND_BOOL 0xFF & true -//#define INT_AND_CHAR 0xFF & 'A' /* FIXME compile error */ +#define INT_AND_CHAR 0xFF & 'A' #define INT_AND_INT 0xFF & 2 #define INT_AND_UINT 0xFF & 2u #define INT_AND_LONG 0xFF & 2l @@ -60,8 +60,7 @@ #define INT_AND_ULLONG 0xFF & 2ull #define BOOL_AND_BOOL true & true // Note integral promotion to type int -//#define CHAR_AND_CHAR 'A' & 'B' // Note integral promotion to type int -/* FIXME ABOVE */ +#define CHAR_AND_CHAR 'A' & 'B' // Note integral promotion to type int #define EXPR_MULTIPLY 0xFF * 2 @@ -88,6 +87,9 @@ #define EXPR_LOR 0xFF || 1 #define EXPR_CONDITIONAL true ? 2 : 2.2 +#define EXPR_CHAR_COMPOUND_ADD 'A' + 12 +#define EXPR_CHAR_COMPOUND_LSHIFT 'B' << 6 +#define H_SUPPRESS_SCALING_MAGIC (('s'<<24) | ('u'<<16) | ('p'<<8) | 'p') /// constant assignment in enum #if defined(SWIGCSHARP) diff --git a/Source/CParse/cparse.h b/Source/CParse/cparse.h index ab5f74b1908..8079805e466 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 784187c28ff..82608053ec5 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -5828,7 +5828,7 @@ definetype : { /* scanner_check_typedef(); */ } expr { if ($$.type == T_STRING) { $$.rawval = NewStringf("\"%(escape)s\"",$$.val); } else if ($$.type != T_CHAR && $$.type != T_WSTRING && $$.type != T_WCHAR) { - $$.rawval = 0; + $$.rawval = NewStringf("%s", $$.val); } $$.qualifier = 0; $$.bitfield = 0; @@ -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 { diff --git a/Source/Modules/go.cxx b/Source/Modules/go.cxx index 7fa9b26705f..e505d4ddccc 100644 --- a/Source/Modules/go.cxx +++ b/Source/Modules/go.cxx @@ -2800,29 +2800,39 @@ class GO:public Language { String *get = NewString(""); Printv(get, Swig_cresult_name(), " = ", NULL); - char quote; - if (Getattr(n, "wrappedasconstant")) { - quote = '\0'; - } else if (SwigType_type(type) == T_CHAR) { - quote = '\''; - } else if (SwigType_type(type) == T_STRING) { - Printv(get, "(char *)", NULL); - quote = '"'; + String *rawval = Getattr(n, "rawval"); + if (rawval && Len(rawval)) { + if (SwigType_type(type) == T_STRING) { + Printv(get, "(char *)", NULL); + } + + Printv(get, rawval, NULL); } else { - quote = '\0'; - } + char quote; + if (Getattr(n, "wrappedasconstant")) { + quote = '\0'; + } else if (SwigType_type(type) == T_CHAR) { + quote = '\''; + } else if (SwigType_type(type) == T_STRING) { + Printv(get, "(char *)", NULL); + quote = '"'; + } else { + quote = '\0'; + } - if (quote != '\0') { - Printf(get, "%c", quote); - } + if (quote != '\0') { + Printf(get, "%c", quote); + } - Printv(get, Getattr(n, "value"), NULL); + Printv(get, Getattr(n, "value"), NULL); - if (quote != '\0') { - Printf(get, "%c", quote); + if (quote != '\0') { + Printf(get, "%c", quote); + } } Printv(get, ";\n", NULL); + Setattr(n, "wrap:action", get); String *sname = Copy(symname);