From 73b0431fbc29e34833f7fc4d8dbcc7b6a64b0f1b Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 1 May 2012 18:44:22 +0000 Subject: [PATCH] Fix C enum forward declarations in some target languages (notably Java) git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@13030 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 3 ++ Examples/test-suite/common.mk | 1 + .../test-suite/csharp/enum_forward_runme.cs | 16 +++++++++ Examples/test-suite/enum_forward.i | 35 +++++++++++++++++++ .../test-suite/java/enum_forward_runme.java | 33 +++++++++++++++++ .../test-suite/python/enum_forward_runme.py | 10 ++++++ Source/Modules/lang.cxx | 6 +++- Source/Modules/typepass.cxx | 17 ++++++++- 8 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 Examples/test-suite/csharp/enum_forward_runme.cs create mode 100644 Examples/test-suite/enum_forward.i create mode 100644 Examples/test-suite/java/enum_forward_runme.java create mode 100644 Examples/test-suite/python/enum_forward_runme.py diff --git a/CHANGES.current b/CHANGES.current index 12e378ed8..682ae47a2 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,3 +5,6 @@ See the RELEASENOTES file for a summary of changes in each release. Version 2.0.7 (in progress) =========================== +2012-05-01: wsfulton + Fix generated code for C forward enum declarations in some languages. + diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 7cc410e7a..84a81b08f 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -495,6 +495,7 @@ C_TEST_CASES += \ constant_expr \ empty \ enums \ + enum_forward \ extern_declaration \ funcptr \ function_typedef \ diff --git a/Examples/test-suite/csharp/enum_forward_runme.cs b/Examples/test-suite/csharp/enum_forward_runme.cs new file mode 100644 index 000000000..3ae714ff0 --- /dev/null +++ b/Examples/test-suite/csharp/enum_forward_runme.cs @@ -0,0 +1,16 @@ +using System; +using enum_forwardNamespace; + +public class runme { + static void Main() { + ForwardEnum1 f1 = enum_forward.get_enum1(); + f1 = enum_forward.test_function1(f1); + + ForwardEnum2 f2 = enum_forward.get_enum2(); + f2 = enum_forward.test_function2(f2); + + ForwardEnum3 f3 = enum_forward.get_enum3(); + f3 = enum_forward.test_function3(f3); + } +} + diff --git a/Examples/test-suite/enum_forward.i b/Examples/test-suite/enum_forward.i new file mode 100644 index 000000000..4540aecb6 --- /dev/null +++ b/Examples/test-suite/enum_forward.i @@ -0,0 +1,35 @@ +%module enum_forward + +%{ +enum ForwardEnum1 { AAA, BBB }; +enum ForwardEnum2 { CCC, DDD }; +%} + +%inline %{ +enum ForwardEnum1; +enum ForwardEnum1 get_enum1() { return AAA; } +enum ForwardEnum1 test_function1(enum ForwardEnum1 e) { + return e; +} +%} + +%inline %{ +enum ForwardEnum2; +enum ForwardEnum2; +enum ForwardEnum2 get_enum2() { return CCC; } +enum ForwardEnum2 test_function2(enum ForwardEnum2 e) { + return e; +} +enum ForwardEnum2; +%} + +%inline %{ +enum ForwardEnum3; +enum ForwardEnum3 { EEE, FFF }; +enum ForwardEnum3 get_enum3() { return EEE; } +enum ForwardEnum3 test_function3(enum ForwardEnum3 e) { + return e; +} +enum ForwardEnum3; +%} + diff --git a/Examples/test-suite/java/enum_forward_runme.java b/Examples/test-suite/java/enum_forward_runme.java new file mode 100644 index 000000000..3827e8320 --- /dev/null +++ b/Examples/test-suite/java/enum_forward_runme.java @@ -0,0 +1,33 @@ + +import enum_forward.*; + +public class enum_forward_runme { + + static { + try { + System.loadLibrary("enum_forward"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) + { + try { + ForwardEnum1 f1 = enum_forward.get_enum1(); + f1 = enum_forward.test_function1(f1); + } catch (IllegalArgumentException e) { + } + + try { + ForwardEnum2 f2 = enum_forward.get_enum2(); + f2 = enum_forward.test_function2(f2); + } catch (IllegalArgumentException e) { + } + + ForwardEnum3 f3 = enum_forward.get_enum3(); + f3 = enum_forward.test_function3(f3); + } +} + diff --git a/Examples/test-suite/python/enum_forward_runme.py b/Examples/test-suite/python/enum_forward_runme.py new file mode 100644 index 000000000..9af476f97 --- /dev/null +++ b/Examples/test-suite/python/enum_forward_runme.py @@ -0,0 +1,10 @@ +import enum_forward + +f1 = enum_forward.get_enum1(); +f1 = enum_forward.test_function1(f1); + +f2 = enum_forward.get_enum2(); +f2 = enum_forward.test_function2(f2); + +f3 = enum_forward.get_enum3(); +f3 = enum_forward.test_function3(f3); diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index c797a101e..c90ebeb73 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -1664,6 +1664,8 @@ int Language::enumvalueDeclaration(Node *n) { int Language::enumforwardDeclaration(Node *n) { (void) n; + if (GetFlag(n, "enumMissing")) + enumDeclaration(n); // Generate an empty enum in target language return SWIG_OK; } @@ -3156,7 +3158,9 @@ Node *Language::enumLookup(SwigType *s) { n = Swig_symbol_clookup(base, stab); if (!n) break; - if (Strcmp(nodeType(n), "enum") == 0) + if (Equal(nodeType(n), "enum")) + break; + if (Equal(nodeType(n), "enumforward") && GetFlag(n, "enumMissing")) break; n = parentNode(n); if (!n) diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx index 15768f203..d757d53a7 100644 --- a/Source/Modules/typepass.cxx +++ b/Source/Modules/typepass.cxx @@ -886,7 +886,22 @@ class TypePass:private Dispatcher { // Use enumDeclaration() to do all the hard work. // Note that no children can be emitted in a forward declaration as there aren't any. - return enumDeclaration(n); + int result = enumDeclaration(n); + if (result == SWIG_OK) { + // Detect when the real enum matching the forward enum declaration has not been parsed/declared + SwigType *ty = SwigType_typedef_resolve_all(Getattr(n, "type")); + Replaceall(ty, "enum ", ""); + Node *nn = Swig_symbol_clookup(ty, 0); + + String *nodetype = nn ? nodeType(nn) : 0; + if (nodetype) { + if (Equal(nodetype, "enumforward")) { + SetFlag(nn, "enumMissing"); + } // if a real enum was declared this would be an "enum" node type + } + Delete(ty); + } + return result; } #ifdef DEBUG_OVERLOADED