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)
|
||||
============================
|
||||
|
||||
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
|
||||
The wrappers for C nested structs are now generated in the same order as declared
|
||||
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
|
||||
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) SpatialIndex::Variant::val;
|
||||
#pragma SWIG nowarn=SWIGWARN_PARSE_UNNAMED_NESTED_CLASS
|
||||
|
||||
%inline %{
|
||||
namespace SpatialIndex
|
||||
|
|
|
|||
|
|
@ -7,12 +7,18 @@
|
|||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass2;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct2;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion2;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass3Name;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct3Name;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion3Name;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass4;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct4;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion4;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass4Typedef;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct4Typedef;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion4Typedef;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass5;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct5;
|
||||
%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 %{
|
||||
struct Outer {
|
||||
|
|
@ -51,64 +57,150 @@ struct Outer {
|
|||
class InnerClass2 {
|
||||
public:
|
||||
Integer x;
|
||||
} InnerClass2Name;
|
||||
} InnerClass2Instance;
|
||||
|
||||
struct InnerStruct2 {
|
||||
Integer x;
|
||||
} InnerStruct2Name;
|
||||
} InnerStruct2Instance;
|
||||
|
||||
union InnerUnion2 {
|
||||
Integer x;
|
||||
double y;
|
||||
} InnerUnion2Name;
|
||||
} InnerUnion2Instance;
|
||||
|
||||
///////////////////////////////////////////
|
||||
class {
|
||||
public:
|
||||
Integer x;
|
||||
} InnerClass3Name;
|
||||
} InnerClass3Instance;
|
||||
|
||||
struct {
|
||||
Integer x;
|
||||
} InnerStruct3Name;
|
||||
} InnerStruct3Instance;
|
||||
|
||||
union {
|
||||
Integer x;
|
||||
double y;
|
||||
} InnerUnion3Name;
|
||||
} InnerUnion3Instance;
|
||||
|
||||
///////////////////////////////////////////
|
||||
typedef class {
|
||||
public:
|
||||
Integer x;
|
||||
} InnerClass4;
|
||||
} InnerClass4Typedef;
|
||||
|
||||
typedef struct {
|
||||
Integer x;
|
||||
} InnerStruct4;
|
||||
} InnerStruct4Typedef;
|
||||
|
||||
typedef union {
|
||||
Integer x;
|
||||
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
|
||||
InnerStruct1* getInnerStruct1() { return 0; }
|
||||
InnerClass1* getInnerClass1() { return 0; }
|
||||
InnerUnion1* getInnerUnion1() { return 0; }
|
||||
InnerStruct1* makeInnerStruct1() { return 0; }
|
||||
InnerClass1* makeInnerClass1() { return 0; }
|
||||
InnerUnion1* makeInnerUnion1() { return 0; }
|
||||
|
||||
InnerStruct2* getInnerStruct2() { return 0; }
|
||||
InnerClass2* getInnerClass2() { return 0; }
|
||||
InnerUnion2* getInnerUnion2() { return 0; }
|
||||
InnerStruct2* makeInnerStruct2() { return 0; }
|
||||
InnerClass2* makeInnerClass2() { return 0; }
|
||||
InnerUnion2* makeInnerUnion2() { return 0; }
|
||||
|
||||
InnerStruct4* getInnerStruct4() { return 0; }
|
||||
InnerClass4* getInnerClass4() { return 0; }
|
||||
InnerUnion4* getInnerUnion4() { return 0; }
|
||||
InnerStruct4Typedef* makeInnerStruct4Typedef() { return 0; }
|
||||
InnerClass4Typedef* makeInnerClass4Typedef() { 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 {
|
||||
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
|
||||
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) s1::n;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) a::d;
|
||||
#pragma SWIG nowarn=SWIGWARN_PARSE_UNNAMED_NESTED_CLASS
|
||||
|
||||
// this example shows a problem with 'dump_nested' (parser.y).
|
||||
|
||||
// bug #949654
|
||||
%inline %{
|
||||
typedef struct s1 {
|
||||
union {
|
||||
int fsc; /* genie structure hiding - Conductor
|
||||
*/
|
||||
int fso; /* genie structure hiding - FSOptions
|
||||
*/
|
||||
struct {
|
||||
double *vals;
|
||||
int size;
|
||||
} vector_val; /* matrix values are mainly used
|
||||
in rlgc models */
|
||||
char *name;
|
||||
} n ;
|
||||
} s2;
|
||||
typedef struct s1 {
|
||||
union {
|
||||
int fsc; /* genie structure hiding - Conductor
|
||||
*/
|
||||
int fso; /* genie structure hiding - FSOptions
|
||||
*/
|
||||
struct {
|
||||
double *vals;
|
||||
int size;
|
||||
} vector_val; /* matrix values are mainly used
|
||||
in rlgc models */
|
||||
char *name;
|
||||
} n ;
|
||||
} s2;
|
||||
%}
|
||||
|
||||
// comment in nested struct
|
||||
|
|
|
|||
|
|
@ -1017,10 +1017,21 @@ static void add_nested(Nested *n) {
|
|||
/* -----------------------------------------------------------------------------
|
||||
* 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 *decl;
|
||||
|
||||
|
|
@ -1072,28 +1083,76 @@ static void nested_new_struct(Node *cpp_opt_declarators, const char *kind, Strin
|
|||
/* -----------------------------------------------------------------------------
|
||||
* nested_forward_declaration()
|
||||
*
|
||||
* Nested struct handling for C++ code only.
|
||||
*
|
||||
* Treat the nested class/struct/union as a forward declaration until a proper
|
||||
* nested class solution is implemented.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
static Node *nested_forward_declaration(const char *kind, const char *name) {
|
||||
Node *n = new_node("classforward");
|
||||
Setfile(n,cparse_file);
|
||||
Setline(n,cparse_line);
|
||||
Setattr(n,"kind", kind);
|
||||
Setattr(n,"name", name);
|
||||
Setattr(n,"sym:weak", "1");
|
||||
add_symbols(n);
|
||||
static Node *nested_forward_declaration(const char *storage, const char *kind, String *sname, const char *name, Node *cpp_opt_declarators) {
|
||||
Node *nn = 0;
|
||||
int warned = 0;
|
||||
|
||||
if (GetFlag(n, "feature:nestedworkaround")) {
|
||||
Swig_symbol_remove(n);
|
||||
n = 0;
|
||||
} 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, name);
|
||||
SWIG_WARN_NODE_END(n);
|
||||
if (sname) {
|
||||
/* Add forward declaration of the nested type */
|
||||
Node *n = new_node("classforward");
|
||||
Setfile(n, cparse_file);
|
||||
Setline(n, cparse_line);
|
||||
Setattr(n, "kind", kind);
|
||||
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. */
|
||||
|
|
@ -4460,67 +4519,64 @@ cpp_protection_decl : PUBLIC COLON {
|
|||
;
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
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!
|
||||
/* ------------------------------------------------------------
|
||||
Named nested structs:
|
||||
struct sname { };
|
||||
struct sname { } id;
|
||||
struct sname : bases { };
|
||||
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
|
||||
code attached to the nested class to generate both C/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.
|
||||
---------------------------------------------------------------------- */
|
||||
Adding inheritance, ie replacing 'ID' with 'idcolon inherit'
|
||||
added one shift/reduce
|
||||
------------------------------------------------------------ */
|
||||
|
||||
/* struct sname { } id; or struct sname { }; declaration */
|
||||
|
||||
cpp_nested : storage_class cpptype ID LBRACE {
|
||||
cpp_nested : storage_class cpptype idcolon inherit LBRACE {
|
||||
cparse_start_line = cparse_line; skip_balanced('{','}');
|
||||
$<str>$ = NewString(scanner_ccode); /* copied as initializers overwrite scanner_ccode */
|
||||
} cpp_opt_declarators {
|
||||
$$ = 0;
|
||||
if (cplus_mode == CPLUS_PUBLIC) {
|
||||
if (cparse_cplusplus) {
|
||||
$$ = nested_forward_declaration($2, $3);
|
||||
} else if ($6) {
|
||||
nested_new_struct($6, $2, $<str>5);
|
||||
$$ = nested_forward_declaration($1, $2, $3, $3, $7);
|
||||
} else if ($7) {
|
||||
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('{','}');
|
||||
$<str>$ = NewString(scanner_ccode); /* copied as initializers overwrite scanner_ccode */
|
||||
} cpp_opt_declarators {
|
||||
$$ = 0;
|
||||
if (cplus_mode == CPLUS_PUBLIC) {
|
||||
if ($5) {
|
||||
if (cparse_cplusplus) {
|
||||
$$ = nested_forward_declaration($2, Getattr($5, "name"));
|
||||
} else {
|
||||
nested_new_struct($5, $2, $<str>4);
|
||||
}
|
||||
if (cparse_cplusplus) {
|
||||
const char *name = $6 ? Getattr($6, "name") : 0;
|
||||
$$ = nested_forward_declaration($1, $2, 0, name, $6);
|
||||
} 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. */
|
||||
/*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue