Add scoped enums into correct correct scope in type system. Note that cpp0x_strongly_typed_enumerations.i still shows further language symbol table problems which need fixing.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2009-matevz@13841 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2012-09-20 18:17:52 +00:00
commit 6d655a7f41
2 changed files with 58 additions and 15 deletions

View file

@ -1690,7 +1690,7 @@ static void tag_nodes(Node *n, const_String_or_char_ptr attrname, DOH *value) {
%type <node> types_directive template_directive warn_directive ; %type <node> types_directive template_directive warn_directive ;
/* C declarations */ /* C declarations */
%type <node> c_declaration c_decl c_decl_tail c_enum_keyword c_enum_inherit c_enum_decl c_enum_forward_decl c_constructor_decl c_lambda_decl c_lambda_decl_front ; %type <node> c_declaration c_decl c_decl_tail c_enum_key c_enum_inherit c_enum_decl c_enum_forward_decl c_constructor_decl c_lambda_decl c_lambda_decl_front ;
%type <node> enumlist edecl; %type <node> enumlist edecl;
/* C++ declarations */ /* C++ declarations */
@ -3307,11 +3307,14 @@ c_lambda_decl_front : storage_class AUTO idcolon EQUAL LBRACKET { skip_balanced(
enum class enum class
------------------------------------------------------------ */ ------------------------------------------------------------ */
c_enum_keyword : ENUM { c_enum_key : ENUM {
$$ = (char*)"enumkeyword"; $$ = (char *)"enum";
} }
| ENUM CLASS { | ENUM CLASS {
$$ = (char*)"enumclasskeyword"; $$ = (char *)"enum class";
}
| ENUM STRUCT {
$$ = (char *)"enum struct";
} }
; ;
@ -3329,12 +3332,16 @@ c_enum_inherit : COLON type_right {
enum [class] Name [: base_type]; enum [class] Name [: base_type];
------------------------------------------------------------ */ ------------------------------------------------------------ */
c_enum_forward_decl : storage_class c_enum_keyword ename c_enum_inherit SEMI { c_enum_forward_decl : storage_class c_enum_key ename c_enum_inherit SEMI {
SwigType *ty = 0; SwigType *ty = 0;
int scopedenum = $3 && !Equal($2, "enum");
$$ = new_node("enumforward"); $$ = new_node("enumforward");
ty = NewStringf("enum %s", $3); ty = NewStringf("enum %s", $3);
Setattr($$,"enumkeyword",$2); Setattr($$,"enumkey",$2);
if (scopedenum)
SetFlag($$, "scopedenum");
Setattr($$,"name",$3); Setattr($$,"name",$3);
Setattr($$,"inherit",$4);
Setattr($$,"type",ty); Setattr($$,"type",ty);
Setattr($$,"sym:weak", "1"); Setattr($$,"sym:weak", "1");
add_symbols($$); add_symbols($$);
@ -3347,26 +3354,46 @@ c_enum_forward_decl : storage_class c_enum_keyword ename c_enum_inherit SEMI {
enum [class] Name [: base_type] { ... } MyEnum [= ...]; enum [class] Name [: base_type] { ... } MyEnum [= ...];
* ------------------------------------------------------------ */ * ------------------------------------------------------------ */
c_enum_decl : storage_class c_enum_keyword ename c_enum_inherit LBRACE enumlist RBRACE SEMI { c_enum_decl : storage_class c_enum_key ename c_enum_inherit LBRACE enumlist RBRACE SEMI {
SwigType *ty = 0; SwigType *ty = 0;
int scopedenum = $3 && !Equal($2, "enum");
$$ = new_node("enum"); $$ = new_node("enum");
ty = NewStringf("enum %s", $3); ty = NewStringf("enum %s", $3);
Setattr($$,"enumkeyword",$2); Setattr($$,"enumkey",$2);
if (scopedenum)
SetFlag($$, "scopedenum");
Setattr($$,"name",$3); Setattr($$,"name",$3);
Setattr($$,"inherit",$4); Setattr($$,"inherit",$4);
Setattr($$,"type",ty); Setattr($$,"type",ty);
appendChild($$,$6); appendChild($$,$6);
add_symbols($$); /* Add to tag space */ add_symbols($$); /* Add to tag space */
add_symbols($6); /* Add enum values to id space */
if (scopedenum) {
Swig_symbol_newscope();
Swig_symbol_setscopename($3);
Delete(Namespaceprefix);
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
}
add_symbols($6); /* Add enum values to appropriate enum or enum class scope */
if (scopedenum) {
Setattr($$,"symtab", Swig_symbol_popscope());
Delete(Namespaceprefix);
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
}
} }
| storage_class c_enum_keyword ename c_enum_inherit LBRACE enumlist RBRACE declarator initializer c_decl_tail { | storage_class c_enum_key ename c_enum_inherit LBRACE enumlist RBRACE declarator initializer c_decl_tail {
Node *n; Node *n;
SwigType *ty = 0; SwigType *ty = 0;
String *unnamed = 0; String *unnamed = 0;
int unnamedinstance = 0; int unnamedinstance = 0;
int scopedenum = $3 && !Equal($2, "enum");
$$ = new_node("enum"); $$ = new_node("enum");
Setattr($$,"enumkeyword",$2); Setattr($$,"enumkey",$2);
if (scopedenum)
SetFlag($$, "scopedenum");
Setattr($$,"inherit",$4); Setattr($$,"inherit",$4);
if ($3) { if ($3) {
Setattr($$,"name",$3); Setattr($$,"name",$3);
@ -3433,7 +3460,22 @@ c_enum_decl : storage_class c_enum_keyword ename c_enum_inherit LBRACE enumlist
add_symbols($$); /* Add enum to tag space */ add_symbols($$); /* Add enum to tag space */
set_nextSibling($$,n); set_nextSibling($$,n);
Delete(n); Delete(n);
add_symbols($6); /* Add enum values to id space */
if (scopedenum) {
Swig_symbol_newscope();
Swig_symbol_setscopename($3);
Delete(Namespaceprefix);
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
}
add_symbols($6); /* Add enum values to appropriate enum or enum class scope */
if (scopedenum) {
Setattr($$,"symtab", Swig_symbol_popscope());
Delete(Namespaceprefix);
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
}
add_symbols(n); add_symbols(n);
Delete(unnamed); Delete(unnamed);
} }
@ -5760,7 +5802,7 @@ type_right : primitive_type { $$ = $1;
| TYPE_BOOL { $$ = $1; } | TYPE_BOOL { $$ = $1; }
| TYPE_VOID { $$ = $1; } | TYPE_VOID { $$ = $1; }
| TYPE_TYPEDEF template_decl { $$ = NewStringf("%s%s",$1,$2); } | TYPE_TYPEDEF template_decl { $$ = NewStringf("%s%s",$1,$2); }
| c_enum_keyword idcolon { $$ = NewStringf("enum %s", $2); } | c_enum_key idcolon { $$ = NewStringf("enum %s", $2); }
| TYPE_RAW { $$ = $1; } | TYPE_RAW { $$ = $1; }
| idcolon { | idcolon {

View file

@ -834,16 +834,17 @@ class TypePass:private Dispatcher {
virtual int enumvalueDeclaration(Node *n) { virtual int enumvalueDeclaration(Node *n) {
String *name = Getattr(n, "name"); String *name = Getattr(n, "name");
String *value = Getattr(n, "value"); String *value = Getattr(n, "value");
String *scopedenum = Getattr(parentNode(n), "scopedenum");
if (!value) if (!value)
value = name; value = name;
if (Strcmp(value, name) == 0) { if (Strcmp(value, name) == 0) {
String *new_value; String *new_value;
if ((nsname || inclass) && cparse_cplusplus) { if ((nsname || inclass || scopedenum) && cparse_cplusplus) {
new_value = NewStringf("%s::%s", SwigType_namestr(Swig_symbol_qualified(n)), value); new_value = NewStringf("%s::%s", SwigType_namestr(Swig_symbol_qualified(n)), value);
} else { } else {
new_value = NewString(value); new_value = NewString(value);
} }
if ((nsname || inclass) && !cparse_cplusplus) { if ((nsname || inclass || scopedenum) && !cparse_cplusplus) {
String *cppvalue = NewStringf("%s::%s", SwigType_namestr(Swig_symbol_qualified(n)), value); String *cppvalue = NewStringf("%s::%s", SwigType_namestr(Swig_symbol_qualified(n)), value);
Setattr(n, "cppvalue", cppvalue); /* for target languages that always generate C++ code even when wrapping C code */ Setattr(n, "cppvalue", cppvalue); /* for target languages that always generate C++ code even when wrapping C code */
} }