Improved C++ nested class support - nested typedef'd classes now parsed and treated as forward class declaration
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11756 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
43b6292681
commit
2a59a2e6a9
6 changed files with 324 additions and 99 deletions
|
|
@ -1,6 +1,12 @@
|
||||||
Version 1.3.41 (in progress)
|
Version 1.3.41 (in progress)
|
||||||
============================
|
============================
|
||||||
|
|
||||||
|
2009-11-23: wsfulton
|
||||||
|
C++ nested typedef classes can now be handled too, for example:
|
||||||
|
struct Outer {
|
||||||
|
typedef Foo { } FooTypedef1, FooTypedef2;
|
||||||
|
};
|
||||||
|
|
||||||
2009-11-18: wsfulton
|
2009-11-18: wsfulton
|
||||||
The wrappers for C nested structs are now generated in the same order as declared
|
The wrappers for C nested structs are now generated in the same order as declared
|
||||||
in the parsed code.
|
in the parsed code.
|
||||||
|
|
|
||||||
72
Examples/test-suite/java/nested_class_runme.java
Normal file
72
Examples/test-suite/java/nested_class_runme.java
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
|
||||||
|
import nested_class.*;
|
||||||
|
|
||||||
|
public class nested_class_runme {
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
System.loadLibrary("nested_class");
|
||||||
|
} 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[]) {
|
||||||
|
Outer outer = new Outer();
|
||||||
|
SWIGTYPE_p_Outer__InnerStruct1 is1 = outer.makeInnerStruct1();
|
||||||
|
SWIGTYPE_p_Outer__InnerClass1 ic1 = outer.makeInnerClass1();
|
||||||
|
SWIGTYPE_p_Outer__InnerUnion1 iu1 = outer.makeInnerUnion1();
|
||||||
|
|
||||||
|
SWIGTYPE_p_Outer__InnerStruct2 is2 = outer.makeInnerStruct2();
|
||||||
|
SWIGTYPE_p_Outer__InnerClass2 ic2 = outer.makeInnerClass2();
|
||||||
|
SWIGTYPE_p_Outer__InnerUnion2 iu2 = outer.makeInnerUnion2();
|
||||||
|
|
||||||
|
SWIGTYPE_p_Outer__InnerClass4Typedef ic4 = outer.makeInnerClass4Typedef();
|
||||||
|
SWIGTYPE_p_Outer__InnerStruct4Typedef is4 = outer.makeInnerStruct4Typedef();
|
||||||
|
SWIGTYPE_p_Outer__InnerUnion4Typedef iu4 = outer.makeInnerUnion4Typedef();
|
||||||
|
|
||||||
|
SWIGTYPE_p_Outer__InnerClass5 ic5 = outer.makeInnerClass5();
|
||||||
|
SWIGTYPE_p_Outer__InnerStruct5 is5 = outer.makeInnerStruct5();
|
||||||
|
SWIGTYPE_p_Outer__InnerUnion5 iu5 = outer.makeInnerUnion5();
|
||||||
|
|
||||||
|
ic5 = outer.makeInnerClass5Typedef();
|
||||||
|
is5 = outer.makeInnerStruct5Typedef();
|
||||||
|
iu5 = outer.makeInnerUnion5Typedef();
|
||||||
|
|
||||||
|
{
|
||||||
|
SWIGTYPE_p_Outer__InnerMultiple im1 = outer.getMultipleInstance1();
|
||||||
|
SWIGTYPE_p_Outer__InnerMultiple im2 = outer.getMultipleInstance2();
|
||||||
|
SWIGTYPE_p_Outer__InnerMultiple im3 = outer.getMultipleInstance3();
|
||||||
|
SWIGTYPE_p_Outer__InnerMultiple im4 = outer.getMultipleInstance4();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
SWIGTYPE_p_Outer__InnerMultipleDerived im1 = outer.getMultipleDerivedInstance1();
|
||||||
|
SWIGTYPE_p_Outer__InnerMultipleDerived im2 = outer.getMultipleDerivedInstance2();
|
||||||
|
SWIGTYPE_p_Outer__InnerMultipleDerived im3 = outer.getMultipleDerivedInstance3();
|
||||||
|
SWIGTYPE_p_Outer__InnerMultipleDerived im4 = outer.getMultipleDerivedInstance4();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
SWIGTYPE_p_Outer__InnerMultipleDerived im1 = outer.getMultipleDerivedInstance1();
|
||||||
|
SWIGTYPE_p_Outer__InnerMultipleDerived im2 = outer.getMultipleDerivedInstance2();
|
||||||
|
SWIGTYPE_p_Outer__InnerMultipleDerived im3 = outer.getMultipleDerivedInstance3();
|
||||||
|
SWIGTYPE_p_Outer__InnerMultipleDerived im4 = outer.getMultipleDerivedInstance4();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
SWIGTYPE_p_Outer__InnerMultipleAnonTypedef1 mat1 = outer.makeInnerMultipleAnonTypedef1();
|
||||||
|
SWIGTYPE_p_Outer__InnerMultipleAnonTypedef2 mat2 = outer.makeInnerMultipleAnonTypedef2();
|
||||||
|
SWIGTYPE_p_Outer__InnerMultipleAnonTypedef3 mat3 = outer.makeInnerMultipleAnonTypedef3();
|
||||||
|
|
||||||
|
SWIGTYPE_p_Outer__InnerMultipleNamedTypedef mnt = outer.makeInnerMultipleNamedTypedef();
|
||||||
|
SWIGTYPE_p_Outer__InnerMultipleNamedTypedef mnt1 = outer.makeInnerMultipleNamedTypedef1();
|
||||||
|
SWIGTYPE_p_Outer__InnerMultipleNamedTypedef mnt2 = outer.makeInnerMultipleNamedTypedef2();
|
||||||
|
SWIGTYPE_p_p_Outer__InnerMultipleNamedTypedef mnt3 = outer.makeInnerMultipleNamedTypedef3();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
SWIGTYPE_p_Outer__InnerSameName isn = outer.makeInnerSameName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
%module namespace_union
|
%module namespace_union
|
||||||
|
|
||||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) SpatialIndex::Variant::val;
|
#pragma SWIG nowarn=SWIGWARN_PARSE_UNNAMED_NESTED_CLASS
|
||||||
|
|
||||||
%inline %{
|
%inline %{
|
||||||
namespace SpatialIndex
|
namespace SpatialIndex
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,18 @@
|
||||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass2;
|
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass2;
|
||||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct2;
|
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct2;
|
||||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion2;
|
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion2;
|
||||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass3Name;
|
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass4Typedef;
|
||||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct3Name;
|
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct4Typedef;
|
||||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion3Name;
|
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion4Typedef;
|
||||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass4;
|
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass5;
|
||||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct4;
|
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct5;
|
||||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion4;
|
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion5;
|
||||||
|
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerMultiple;
|
||||||
|
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerMultipleDerived;
|
||||||
|
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerMultipleAnonTypedef1;
|
||||||
|
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerMultipleNamedTypedef;
|
||||||
|
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerSameName;
|
||||||
|
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer2::IgnoreMe;
|
||||||
|
|
||||||
%inline %{
|
%inline %{
|
||||||
struct Outer {
|
struct Outer {
|
||||||
|
|
@ -51,64 +57,150 @@ struct Outer {
|
||||||
class InnerClass2 {
|
class InnerClass2 {
|
||||||
public:
|
public:
|
||||||
Integer x;
|
Integer x;
|
||||||
} InnerClass2Name;
|
} InnerClass2Instance;
|
||||||
|
|
||||||
struct InnerStruct2 {
|
struct InnerStruct2 {
|
||||||
Integer x;
|
Integer x;
|
||||||
} InnerStruct2Name;
|
} InnerStruct2Instance;
|
||||||
|
|
||||||
union InnerUnion2 {
|
union InnerUnion2 {
|
||||||
Integer x;
|
Integer x;
|
||||||
double y;
|
double y;
|
||||||
} InnerUnion2Name;
|
} InnerUnion2Instance;
|
||||||
|
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
class {
|
class {
|
||||||
public:
|
public:
|
||||||
Integer x;
|
Integer x;
|
||||||
} InnerClass3Name;
|
} InnerClass3Instance;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
Integer x;
|
Integer x;
|
||||||
} InnerStruct3Name;
|
} InnerStruct3Instance;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
Integer x;
|
Integer x;
|
||||||
double y;
|
double y;
|
||||||
} InnerUnion3Name;
|
} InnerUnion3Instance;
|
||||||
|
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
typedef class {
|
typedef class {
|
||||||
public:
|
public:
|
||||||
Integer x;
|
Integer x;
|
||||||
} InnerClass4;
|
} InnerClass4Typedef;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Integer x;
|
Integer x;
|
||||||
} InnerStruct4;
|
} InnerStruct4Typedef;
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
Integer x;
|
Integer x;
|
||||||
double y;
|
double y;
|
||||||
} InnerUnion4;
|
} InnerUnion4Typedef;
|
||||||
|
|
||||||
|
///////////////////////////////////////////
|
||||||
|
typedef class InnerClass5 {
|
||||||
|
public:
|
||||||
|
Integer x;
|
||||||
|
} InnerClass5Typedef;
|
||||||
|
|
||||||
|
typedef struct InnerStruct5 {
|
||||||
|
Integer x;
|
||||||
|
} InnerStruct5Typedef;
|
||||||
|
|
||||||
|
typedef union InnerUnion5 {
|
||||||
|
Integer x;
|
||||||
|
double y;
|
||||||
|
} InnerUnion5Typedef;
|
||||||
|
|
||||||
// bug #909387 - inner declared types are treated as forward declarations
|
// bug #909387 - inner declared types are treated as forward declarations
|
||||||
InnerStruct1* getInnerStruct1() { return 0; }
|
InnerStruct1* makeInnerStruct1() { return 0; }
|
||||||
InnerClass1* getInnerClass1() { return 0; }
|
InnerClass1* makeInnerClass1() { return 0; }
|
||||||
InnerUnion1* getInnerUnion1() { return 0; }
|
InnerUnion1* makeInnerUnion1() { return 0; }
|
||||||
|
|
||||||
InnerStruct2* getInnerStruct2() { return 0; }
|
InnerStruct2* makeInnerStruct2() { return 0; }
|
||||||
InnerClass2* getInnerClass2() { return 0; }
|
InnerClass2* makeInnerClass2() { return 0; }
|
||||||
InnerUnion2* getInnerUnion2() { return 0; }
|
InnerUnion2* makeInnerUnion2() { return 0; }
|
||||||
|
|
||||||
InnerStruct4* getInnerStruct4() { return 0; }
|
InnerStruct4Typedef* makeInnerStruct4Typedef() { return 0; }
|
||||||
InnerClass4* getInnerClass4() { return 0; }
|
InnerClass4Typedef* makeInnerClass4Typedef() { return 0; }
|
||||||
InnerUnion4* getInnerUnion4() { return 0; }
|
InnerUnion4Typedef* makeInnerUnion4Typedef() { return 0; }
|
||||||
|
|
||||||
|
InnerStruct5* makeInnerStruct5() { return 0; }
|
||||||
|
InnerClass5* makeInnerClass5() { return 0; }
|
||||||
|
InnerUnion5* makeInnerUnion5() { return 0; }
|
||||||
|
|
||||||
|
InnerStruct5Typedef* makeInnerStruct5Typedef() { return 0; }
|
||||||
|
InnerClass5Typedef* makeInnerClass5Typedef() { return 0; }
|
||||||
|
InnerUnion5Typedef* makeInnerUnion5Typedef() { return 0; }
|
||||||
|
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
struct InnerMultiple {
|
struct InnerMultiple {
|
||||||
Integer x;
|
Integer x;
|
||||||
} MultipleInstance1, MultipleInstance2;
|
} MultipleInstance1, MultipleInstance2, *MultipleInstance3, MultipleInstance4[2];
|
||||||
|
|
||||||
|
struct InnerMultipleDerived : public InnerMultiple {
|
||||||
|
Integer xx;
|
||||||
|
} MultipleDerivedInstance1, MultipleDerivedInstance2, *MultipleDerivedInstance3, MultipleDerivedInstance4[2];
|
||||||
|
|
||||||
|
struct {
|
||||||
|
Integer x;
|
||||||
|
} MultipleInstanceAnon1, MultipleInstanceAnon2, *MultipleInstanceAnon3, MultipleInstanceAnon4[2];
|
||||||
|
|
||||||
|
struct : public InnerMultiple {
|
||||||
|
Integer xx;
|
||||||
|
} MultipleInstanceAnonDerived1, MultipleInstanceAnonDerived2, *MultipleInstanceAnonDerived3, MultipleInstanceAnonDerived4[2];
|
||||||
|
|
||||||
|
struct : public InnerMultiple {
|
||||||
|
Integer xx;
|
||||||
|
};
|
||||||
|
|
||||||
|
class : public InnerMultiple {
|
||||||
|
public:
|
||||||
|
Integer yy;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////
|
||||||
|
typedef struct {
|
||||||
|
Integer x;
|
||||||
|
} InnerMultipleAnonTypedef1, InnerMultipleAnonTypedef2, *InnerMultipleAnonTypedef3;
|
||||||
|
|
||||||
|
InnerMultipleAnonTypedef1* makeInnerMultipleAnonTypedef1() { return 0; }
|
||||||
|
InnerMultipleAnonTypedef2* makeInnerMultipleAnonTypedef2() { return 0; }
|
||||||
|
InnerMultipleAnonTypedef3* makeInnerMultipleAnonTypedef3() { return 0; }
|
||||||
|
|
||||||
|
typedef struct InnerMultipleNamedTypedef {
|
||||||
|
Integer x;
|
||||||
|
} InnerMultipleNamedTypedef1, InnerMultipleNamedTypedef2, *InnerMultipleNamedTypedef3;
|
||||||
|
|
||||||
|
InnerMultipleNamedTypedef* makeInnerMultipleNamedTypedef() { return 0; }
|
||||||
|
InnerMultipleNamedTypedef1* makeInnerMultipleNamedTypedef1() { return 0; }
|
||||||
|
InnerMultipleNamedTypedef2* makeInnerMultipleNamedTypedef2() { return 0; }
|
||||||
|
InnerMultipleNamedTypedef3* makeInnerMultipleNamedTypedef3() { return 0; }
|
||||||
|
|
||||||
|
///////////////////////////////////////////
|
||||||
|
typedef struct InnerSameName {
|
||||||
|
Integer x;
|
||||||
|
} InnerSameName;
|
||||||
|
|
||||||
|
InnerSameName* makeInnerSameName() { return 0; }
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Ignore nested struct instance
|
||||||
|
%ignore Outer2::IgnoreMeInstance;
|
||||||
|
%{
|
||||||
|
struct Outer2 {
|
||||||
|
struct IgnoreMe {
|
||||||
|
int xx;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
struct Outer2 {
|
||||||
|
struct IgnoreMe {
|
||||||
|
int xx;
|
||||||
|
} IgnoreMeInstance;
|
||||||
};
|
};
|
||||||
|
|
||||||
%}
|
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,25 @@
|
||||||
%module nested_comment
|
%module nested_comment
|
||||||
|
|
||||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) s1::n;
|
#pragma SWIG nowarn=SWIGWARN_PARSE_UNNAMED_NESTED_CLASS
|
||||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) a::d;
|
|
||||||
|
|
||||||
// this example shows a problem with 'dump_nested' (parser.y).
|
// this example shows a problem with 'dump_nested' (parser.y).
|
||||||
|
|
||||||
// bug #949654
|
// bug #949654
|
||||||
%inline %{
|
%inline %{
|
||||||
typedef struct s1 {
|
typedef struct s1 {
|
||||||
union {
|
union {
|
||||||
int fsc; /* genie structure hiding - Conductor
|
int fsc; /* genie structure hiding - Conductor
|
||||||
*/
|
*/
|
||||||
int fso; /* genie structure hiding - FSOptions
|
int fso; /* genie structure hiding - FSOptions
|
||||||
*/
|
*/
|
||||||
struct {
|
struct {
|
||||||
double *vals;
|
double *vals;
|
||||||
int size;
|
int size;
|
||||||
} vector_val; /* matrix values are mainly used
|
} vector_val; /* matrix values are mainly used
|
||||||
in rlgc models */
|
in rlgc models */
|
||||||
char *name;
|
char *name;
|
||||||
} n ;
|
} n ;
|
||||||
} s2;
|
} s2;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// comment in nested struct
|
// comment in nested struct
|
||||||
|
|
|
||||||
|
|
@ -1017,10 +1017,21 @@ static void add_nested(Nested *n) {
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* nested_new_struct()
|
* nested_new_struct()
|
||||||
*
|
*
|
||||||
* Nested struct handling creates a global struct from the nested struct.
|
* Nested struct handling for C code only creates a global struct from the nested struct.
|
||||||
|
*
|
||||||
|
* Nested structure. This is a sick "hack". If we encounter
|
||||||
|
* a nested structure, we're going to grab the text of its definition and
|
||||||
|
* feed it back into the scanner. In the meantime, we need to grab
|
||||||
|
* variable declaration information and generate the associated wrapper
|
||||||
|
* code later. Yikes!
|
||||||
|
*
|
||||||
|
* This really only works in a limited sense. Since we use the
|
||||||
|
* code attached to the nested class to generate both C code
|
||||||
|
* it can't have any SWIG directives in it. It also needs to be parsable
|
||||||
|
* by SWIG or this whole thing is going to puke.
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static void nested_new_struct(Node *cpp_opt_declarators, const char *kind, String *struct_code) {
|
static void nested_new_struct(const char *kind, String *struct_code, Node *cpp_opt_declarators) {
|
||||||
String *name;
|
String *name;
|
||||||
String *decl;
|
String *decl;
|
||||||
|
|
||||||
|
|
@ -1072,28 +1083,76 @@ static void nested_new_struct(Node *cpp_opt_declarators, const char *kind, Strin
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* nested_forward_declaration()
|
* nested_forward_declaration()
|
||||||
*
|
*
|
||||||
|
* Nested struct handling for C++ code only.
|
||||||
|
*
|
||||||
* Treat the nested class/struct/union as a forward declaration until a proper
|
* Treat the nested class/struct/union as a forward declaration until a proper
|
||||||
* nested class solution is implemented.
|
* nested class solution is implemented.
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static Node *nested_forward_declaration(const char *kind, const char *name) {
|
static Node *nested_forward_declaration(const char *storage, const char *kind, String *sname, const char *name, Node *cpp_opt_declarators) {
|
||||||
Node *n = new_node("classforward");
|
Node *nn = 0;
|
||||||
Setfile(n,cparse_file);
|
int warned = 0;
|
||||||
Setline(n,cparse_line);
|
|
||||||
Setattr(n,"kind", kind);
|
|
||||||
Setattr(n,"name", name);
|
|
||||||
Setattr(n,"sym:weak", "1");
|
|
||||||
add_symbols(n);
|
|
||||||
|
|
||||||
if (GetFlag(n, "feature:nestedworkaround")) {
|
if (sname) {
|
||||||
Swig_symbol_remove(n);
|
/* Add forward declaration of the nested type */
|
||||||
n = 0;
|
Node *n = new_node("classforward");
|
||||||
} else {
|
Setfile(n, cparse_file);
|
||||||
SWIG_WARN_NODE_BEGIN(n);
|
Setline(n, cparse_line);
|
||||||
Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", kind, name);
|
Setattr(n, "kind", kind);
|
||||||
SWIG_WARN_NODE_END(n);
|
Setattr(n, "name", sname);
|
||||||
|
Setattr(n, "storage", storage);
|
||||||
|
Setattr(n, "sym:weak", "1");
|
||||||
|
add_symbols(n);
|
||||||
|
nn = n;
|
||||||
}
|
}
|
||||||
return n;
|
|
||||||
|
/* Add any variable instances. Also add in any further typedefs of the nested type.
|
||||||
|
Note that anonymous typedefs (eg typedef struct {...} a, b;) are treated as class forward declarations */
|
||||||
|
if (cpp_opt_declarators) {
|
||||||
|
int storage_typedef = (storage && (strcmp(storage, "typedef") == 0));
|
||||||
|
int variable_of_anonymous_type = !sname && !storage_typedef;
|
||||||
|
if (!variable_of_anonymous_type) {
|
||||||
|
int anonymous_typedef = !sname && (storage && (strcmp(storage, "typedef") == 0));
|
||||||
|
Node *n = cpp_opt_declarators;
|
||||||
|
SwigType *type = NewString(name);
|
||||||
|
while (n) {
|
||||||
|
Setattr(n, "type", type);
|
||||||
|
Setattr(n, "storage", storage);
|
||||||
|
if (anonymous_typedef) {
|
||||||
|
Setattr(n, "nodeType", "classforward");
|
||||||
|
Setattr(n, "sym:weak", "1");
|
||||||
|
}
|
||||||
|
n = nextSibling(n);
|
||||||
|
}
|
||||||
|
Delete(type);
|
||||||
|
add_symbols(cpp_opt_declarators);
|
||||||
|
|
||||||
|
if (nn) {
|
||||||
|
set_nextSibling(nn, cpp_opt_declarators);
|
||||||
|
} else {
|
||||||
|
nn = cpp_opt_declarators;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nn && Equal(nodeType(nn), "classforward")) {
|
||||||
|
Node *n = nn;
|
||||||
|
if (GetFlag(n, "feature:nestedworkaround")) {
|
||||||
|
Swig_symbol_remove(n);
|
||||||
|
nn = 0;
|
||||||
|
warned = 1;
|
||||||
|
} else {
|
||||||
|
SWIG_WARN_NODE_BEGIN(n);
|
||||||
|
Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", kind, sname ? sname : name);
|
||||||
|
SWIG_WARN_NODE_END(n);
|
||||||
|
warned = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!warned)
|
||||||
|
Swig_warning(WARN_PARSE_UNNAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", kind);
|
||||||
|
|
||||||
|
return nn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Strips C-style and C++-style comments from string in-place. */
|
/* Strips C-style and C++-style comments from string in-place. */
|
||||||
|
|
@ -4460,67 +4519,64 @@ cpp_protection_decl : PUBLIC COLON {
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ------------------------------------------------------------
|
||||||
Nested structure. This is a sick "hack". If we encounter
|
Named nested structs:
|
||||||
a nested structure, we're going to grab the text of its definition and
|
struct sname { };
|
||||||
feed it back into the scanner. In the meantime, we need to grab
|
struct sname { } id;
|
||||||
variable declaration information and generate the associated wrapper
|
struct sname : bases { };
|
||||||
code later. Yikes!
|
struct sname : bases { } id;
|
||||||
|
typedef sname struct { } td;
|
||||||
|
typedef sname struct : bases { } td;
|
||||||
|
|
||||||
This really only works in a limited sense. Since we use the
|
Adding inheritance, ie replacing 'ID' with 'idcolon inherit'
|
||||||
code attached to the nested class to generate both C/C++ code,
|
added one shift/reduce
|
||||||
it can't have any SWIG directives in it. It also needs to be parsable
|
------------------------------------------------------------ */
|
||||||
by SWIG or this whole thing is going to puke.
|
|
||||||
---------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* struct sname { } id; or struct sname { }; declaration */
|
cpp_nested : storage_class cpptype idcolon inherit LBRACE {
|
||||||
|
|
||||||
cpp_nested : storage_class cpptype ID LBRACE {
|
|
||||||
cparse_start_line = cparse_line; skip_balanced('{','}');
|
cparse_start_line = cparse_line; skip_balanced('{','}');
|
||||||
$<str>$ = NewString(scanner_ccode); /* copied as initializers overwrite scanner_ccode */
|
$<str>$ = NewString(scanner_ccode); /* copied as initializers overwrite scanner_ccode */
|
||||||
} cpp_opt_declarators {
|
} cpp_opt_declarators {
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
if (cplus_mode == CPLUS_PUBLIC) {
|
if (cplus_mode == CPLUS_PUBLIC) {
|
||||||
if (cparse_cplusplus) {
|
if (cparse_cplusplus) {
|
||||||
$$ = nested_forward_declaration($2, $3);
|
$$ = nested_forward_declaration($1, $2, $3, $3, $7);
|
||||||
} else if ($6) {
|
} else if ($7) {
|
||||||
nested_new_struct($6, $2, $<str>5);
|
nested_new_struct($2, $<str>6, $7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Delete($<str>5);
|
Delete($<str>6);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* struct { } id; or struct { }; declaration */
|
/* ------------------------------------------------------------
|
||||||
|
Unnamed/anonymous nested structs:
|
||||||
|
struct { };
|
||||||
|
struct { } id;
|
||||||
|
struct : bases { };
|
||||||
|
struct : bases { } id;
|
||||||
|
typedef struct { } td;
|
||||||
|
typedef struct : bases { } td;
|
||||||
|
------------------------------------------------------------ */
|
||||||
|
|
||||||
| storage_class cpptype LBRACE {
|
| storage_class cpptype inherit LBRACE {
|
||||||
cparse_start_line = cparse_line; skip_balanced('{','}');
|
cparse_start_line = cparse_line; skip_balanced('{','}');
|
||||||
$<str>$ = NewString(scanner_ccode); /* copied as initializers overwrite scanner_ccode */
|
$<str>$ = NewString(scanner_ccode); /* copied as initializers overwrite scanner_ccode */
|
||||||
} cpp_opt_declarators {
|
} cpp_opt_declarators {
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
if (cplus_mode == CPLUS_PUBLIC) {
|
if (cplus_mode == CPLUS_PUBLIC) {
|
||||||
if ($5) {
|
if (cparse_cplusplus) {
|
||||||
if (cparse_cplusplus) {
|
const char *name = $6 ? Getattr($6, "name") : 0;
|
||||||
$$ = nested_forward_declaration($2, Getattr($5, "name"));
|
$$ = nested_forward_declaration($1, $2, 0, name, $6);
|
||||||
} else {
|
|
||||||
nested_new_struct($5, $2, $<str>4);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Swig_warning(WARN_PARSE_UNNAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2);
|
if ($6) {
|
||||||
|
nested_new_struct($2, $<str>5, $6);
|
||||||
|
} else {
|
||||||
|
Swig_warning(WARN_PARSE_UNNAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Delete($<str>4);
|
Delete($<str>5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* class name : base_list { }; declaration */
|
|
||||||
/* This adds one shift/reduce. */
|
|
||||||
|
|
||||||
| storage_class cpptype idcolon COLON base_list LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
|
|
||||||
} cpp_opt_declarators {
|
|
||||||
$$ = 0;
|
|
||||||
if (cplus_mode == CPLUS_PUBLIC) {
|
|
||||||
$$ = nested_forward_declaration($2, $3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This unfortunately introduces 4 shift/reduce conflicts, so instead the somewhat hacky nested_template is used for ignore nested template classes. */
|
/* This unfortunately introduces 4 shift/reduce conflicts, so instead the somewhat hacky nested_template is used for ignore nested template classes. */
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue