nested private classes are discarded while parsing
nested relate functions are moved to nested.cxx and renamed accordingly
This commit is contained in:
parent
053c605df0
commit
b0afa8a95c
6 changed files with 485 additions and 476 deletions
|
|
@ -3537,7 +3537,9 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
|
||||||
}
|
}
|
||||||
if (currentOuterClass)
|
if (currentOuterClass)
|
||||||
restore_access_mode($$);
|
restore_access_mode($$);
|
||||||
|
if (cplus_mode == CPLUS_PRIVATE) {
|
||||||
|
$$ = 0; /* skip private nested classes */
|
||||||
|
} else {
|
||||||
Setattr($$,"symtab",Swig_symbol_popscope());
|
Setattr($$,"symtab",Swig_symbol_popscope());
|
||||||
|
|
||||||
Classprefix = Getattr($<node>$,"Classprefix");
|
Classprefix = Getattr($<node>$,"Classprefix");
|
||||||
|
|
@ -3545,6 +3547,7 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
|
||||||
if (nscope_inner) {
|
if (nscope_inner) {
|
||||||
/* this is tricky */
|
/* this is tricky */
|
||||||
/* we add the declaration in the original namespace */
|
/* we add the declaration in the original namespace */
|
||||||
|
if (cplus_mode != CPLUS_PRIVATE)
|
||||||
appendChild(nscope_inner,$$);
|
appendChild(nscope_inner,$$);
|
||||||
Swig_symbol_setscope(Getattr(nscope_inner,"symtab"));
|
Swig_symbol_setscope(Getattr(nscope_inner,"symtab"));
|
||||||
Delete(Namespaceprefix);
|
Delete(Namespaceprefix);
|
||||||
|
|
@ -3591,6 +3594,7 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE {
|
||||||
Delattr($$, "class_rename");
|
Delattr($$, "class_rename");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Swig_symbol_setscope(cscope);
|
Swig_symbol_setscope(cscope);
|
||||||
Delete(Namespaceprefix);
|
Delete(Namespaceprefix);
|
||||||
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
|
Namespaceprefix = Swig_symbol_qualifiedscopename(0);
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ eswig_SOURCES = CParse/cscanner.c \
|
||||||
Modules/modula3.cxx \
|
Modules/modula3.cxx \
|
||||||
Modules/module.cxx \
|
Modules/module.cxx \
|
||||||
Modules/mzscheme.cxx \
|
Modules/mzscheme.cxx \
|
||||||
|
Modules/nested.cxx \
|
||||||
Modules/ocaml.cxx \
|
Modules/ocaml.cxx \
|
||||||
Modules/octave.cxx \
|
Modules/octave.cxx \
|
||||||
Modules/overload.cxx \
|
Modules/overload.cxx \
|
||||||
|
|
|
||||||
|
|
@ -1178,7 +1178,7 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
||||||
if (!CPlusPlus) {
|
if (!CPlusPlus) {
|
||||||
if (Verbose)
|
if (Verbose)
|
||||||
Printf(stdout, "Processing unnamed structs...\n");
|
Printf(stdout, "Processing unnamed structs...\n");
|
||||||
Swig_name_unnamed_c_structs(top);
|
Swig_nested_name_unnamed_c_structs(top);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Verbose) {
|
if (Verbose) {
|
||||||
|
|
@ -1203,7 +1203,7 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
||||||
if (CPlusPlus) {
|
if (CPlusPlus) {
|
||||||
if (Verbose)
|
if (Verbose)
|
||||||
Printf(stdout, "Processing nested classes...\n");
|
Printf(stdout, "Processing nested classes...\n");
|
||||||
Swig_process_nested_classes(top);
|
Swig_nested_process_classes(top);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dump_top & STAGE3) {
|
if (dump_top & STAGE3) {
|
||||||
|
|
|
||||||
431
Source/Modules/nested.cxx
Normal file
431
Source/Modules/nested.cxx
Normal file
|
|
@ -0,0 +1,431 @@
|
||||||
|
#include "swigmod.h"
|
||||||
|
#include "cparse.h"
|
||||||
|
|
||||||
|
// Nested classes processing section
|
||||||
|
static Hash *classhash = 0;
|
||||||
|
|
||||||
|
static String *make_name(Node *n, String *name, SwigType *decl) {
|
||||||
|
int destructor = name && (*(Char(name)) == '~');
|
||||||
|
if (String *yyrename = Getattr(n, "class_rename")) {
|
||||||
|
String *s = NewString(yyrename);
|
||||||
|
Delattr(n, "class_rename");
|
||||||
|
if (destructor && (*(Char(s)) != '~')) {
|
||||||
|
Insert(s, 0, "~");
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
return 0;
|
||||||
|
return Swig_name_make(n, 0, name, decl, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// C version of add_symbols()
|
||||||
|
static void add_symbols_c(Node *n) {
|
||||||
|
String *decl;
|
||||||
|
String *wrn = 0;
|
||||||
|
String *symname = 0;
|
||||||
|
int iscdecl = Cmp(nodeType(n), "cdecl") == 0;
|
||||||
|
Setattr(n, "ismember", "1");
|
||||||
|
Setattr(n, "access", "public");
|
||||||
|
if (Getattr(n, "sym:name"))
|
||||||
|
return;
|
||||||
|
decl = Getattr(n, "decl");
|
||||||
|
if (!SwigType_isfunction(decl)) {
|
||||||
|
String *name = Getattr(n, "name");
|
||||||
|
String *makename = Getattr(n, "parser:makename");
|
||||||
|
if (iscdecl) {
|
||||||
|
String *storage = Getattr(n, "storage");
|
||||||
|
if (Cmp(storage, "typedef") == 0) {
|
||||||
|
Setattr(n, "kind", "typedef");
|
||||||
|
} else {
|
||||||
|
SwigType *type = Getattr(n, "type");
|
||||||
|
String *value = Getattr(n, "value");
|
||||||
|
Setattr(n, "kind", "variable");
|
||||||
|
if (value && Len(value)) {
|
||||||
|
Setattr(n, "hasvalue", "1");
|
||||||
|
}
|
||||||
|
if (type) {
|
||||||
|
SwigType *ty;
|
||||||
|
SwigType *tmp = 0;
|
||||||
|
if (decl) {
|
||||||
|
ty = tmp = Copy(type);
|
||||||
|
SwigType_push(ty, decl);
|
||||||
|
} else {
|
||||||
|
ty = type;
|
||||||
|
}
|
||||||
|
if (!SwigType_ismutable(ty)) {
|
||||||
|
SetFlag(n, "hasconsttype");
|
||||||
|
SetFlag(n, "feature:immutable");
|
||||||
|
}
|
||||||
|
if (tmp)
|
||||||
|
Delete(tmp);
|
||||||
|
}
|
||||||
|
if (!type) {
|
||||||
|
Printf(stderr, "notype name %s\n", name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Swig_features_get(Swig_cparse_features(), 0, name, 0, n);
|
||||||
|
if (makename) {
|
||||||
|
symname = make_name(n, makename, 0);
|
||||||
|
Delattr(n, "parser:makename"); /* temporary information, don't leave it hanging around */
|
||||||
|
} else {
|
||||||
|
makename = name;
|
||||||
|
symname = make_name(n, makename, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!symname) {
|
||||||
|
symname = Copy(Getattr(n, "unnamed"));
|
||||||
|
}
|
||||||
|
if (symname) {
|
||||||
|
wrn = Swig_name_warning(n, 0, symname, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String *name = Getattr(n, "name");
|
||||||
|
SwigType *fdecl = Copy(decl);
|
||||||
|
SwigType *fun = SwigType_pop_function(fdecl);
|
||||||
|
if (iscdecl) {
|
||||||
|
Setattr(n, "kind", "function");
|
||||||
|
}
|
||||||
|
|
||||||
|
Swig_features_get(Swig_cparse_features(), 0, name, fun, n);
|
||||||
|
|
||||||
|
symname = make_name(n, name, fun);
|
||||||
|
wrn = Swig_name_warning(n, 0, symname, fun);
|
||||||
|
|
||||||
|
Delete(fdecl);
|
||||||
|
Delete(fun);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (!symname)
|
||||||
|
return;
|
||||||
|
if (GetFlag(n, "feature:ignore")) {
|
||||||
|
/* Only add to C symbol table and continue */
|
||||||
|
Swig_symbol_add(0, n);
|
||||||
|
} else if (strncmp(Char(symname), "$ignore", 7) == 0) {
|
||||||
|
char *c = Char(symname) + 7;
|
||||||
|
SetFlag(n, "feature:ignore");
|
||||||
|
if (strlen(c)) {
|
||||||
|
SWIG_WARN_NODE_BEGIN(n);
|
||||||
|
Swig_warning(0, Getfile(n), Getline(n), "%s\n", c + 1);
|
||||||
|
SWIG_WARN_NODE_END(n);
|
||||||
|
}
|
||||||
|
Swig_symbol_add(0, n);
|
||||||
|
} else {
|
||||||
|
Node *c;
|
||||||
|
if ((wrn) && (Len(wrn))) {
|
||||||
|
String *metaname = symname;
|
||||||
|
if (!Getmeta(metaname, "already_warned")) {
|
||||||
|
SWIG_WARN_NODE_BEGIN(n);
|
||||||
|
Swig_warning(0, Getfile(n), Getline(n), "%s\n", wrn);
|
||||||
|
SWIG_WARN_NODE_END(n);
|
||||||
|
Setmeta(metaname, "already_warned", "1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c = Swig_symbol_add(symname, n);
|
||||||
|
|
||||||
|
if (c != n) {
|
||||||
|
/* symbol conflict attempting to add in the new symbol */
|
||||||
|
if (Getattr(n, "sym:weak")) {
|
||||||
|
Setattr(n, "sym:name", symname);
|
||||||
|
} else {
|
||||||
|
String *e = NewStringEmpty();
|
||||||
|
String *en = NewStringEmpty();
|
||||||
|
String *ec = NewStringEmpty();
|
||||||
|
int redefined = Swig_need_redefined_warn(n, c, true);
|
||||||
|
if (redefined) {
|
||||||
|
Printf(en, "Identifier '%s' redefined (ignored)", symname);
|
||||||
|
Printf(ec, "previous definition of '%s'", symname);
|
||||||
|
} else {
|
||||||
|
Printf(en, "Redundant redeclaration of '%s'", symname);
|
||||||
|
Printf(ec, "previous declaration of '%s'", symname);
|
||||||
|
}
|
||||||
|
if (Cmp(symname, Getattr(n, "name"))) {
|
||||||
|
Printf(en, " (Renamed from '%s')", SwigType_namestr(Getattr(n, "name")));
|
||||||
|
}
|
||||||
|
Printf(en, ",");
|
||||||
|
if (Cmp(symname, Getattr(c, "name"))) {
|
||||||
|
Printf(ec, " (Renamed from '%s')", SwigType_namestr(Getattr(c, "name")));
|
||||||
|
}
|
||||||
|
Printf(ec, ".");
|
||||||
|
SWIG_WARN_NODE_BEGIN(n);
|
||||||
|
if (redefined) {
|
||||||
|
Swig_warning(WARN_PARSE_REDEFINED, Getfile(n), Getline(n), "%s\n", en);
|
||||||
|
Swig_warning(WARN_PARSE_REDEFINED, Getfile(c), Getline(c), "%s\n", ec);
|
||||||
|
} else {
|
||||||
|
Swig_warning(WARN_PARSE_REDUNDANT, Getfile(n), Getline(n), "%s\n", en);
|
||||||
|
Swig_warning(WARN_PARSE_REDUNDANT, Getfile(c), Getline(c), "%s\n", ec);
|
||||||
|
}
|
||||||
|
SWIG_WARN_NODE_END(n);
|
||||||
|
Printf(e, "%s:%d:%s\n%s:%d:%s\n", Getfile(n), Getline(n), en, Getfile(c), Getline(c), ec);
|
||||||
|
Setattr(n, "error", e);
|
||||||
|
Delete(e);
|
||||||
|
Delete(en);
|
||||||
|
Delete(ec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Delete(symname);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Strips C-style and C++-style comments from string in-place. */
|
||||||
|
static void strip_comments(char *string) {
|
||||||
|
int state = 0;
|
||||||
|
/*
|
||||||
|
* 0 - not in comment
|
||||||
|
* 1 - in c-style comment
|
||||||
|
* 2 - in c++-style comment
|
||||||
|
* 3 - in string
|
||||||
|
* 4 - after reading / not in comments
|
||||||
|
* 5 - after reading * in c-style comments
|
||||||
|
* 6 - after reading \ in strings
|
||||||
|
*/
|
||||||
|
char *c = string;
|
||||||
|
while (*c) {
|
||||||
|
switch (state) {
|
||||||
|
case 0:
|
||||||
|
if (*c == '\"')
|
||||||
|
state = 3;
|
||||||
|
else if (*c == '/')
|
||||||
|
state = 4;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (*c == '*')
|
||||||
|
state = 5;
|
||||||
|
*c = ' ';
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (*c == '\n')
|
||||||
|
state = 0;
|
||||||
|
else
|
||||||
|
*c = ' ';
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if (*c == '\"')
|
||||||
|
state = 0;
|
||||||
|
else if (*c == '\\')
|
||||||
|
state = 6;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
if (*c == '/') {
|
||||||
|
*(c - 1) = ' ';
|
||||||
|
*c = ' ';
|
||||||
|
state = 2;
|
||||||
|
} else if (*c == '*') {
|
||||||
|
*(c - 1) = ' ';
|
||||||
|
*c = ' ';
|
||||||
|
state = 1;
|
||||||
|
} else
|
||||||
|
state = 0;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
if (*c == '/')
|
||||||
|
state = 0;
|
||||||
|
else
|
||||||
|
state = 1;
|
||||||
|
*c = ' ';
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
state = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a %insert with a typedef to make a new name visible to C
|
||||||
|
static Node *create_insert(Node *n, bool noTypedef = false) {
|
||||||
|
// format a typedef
|
||||||
|
String *ccode = Getattr(n, "code");
|
||||||
|
Push(ccode, " ");
|
||||||
|
if (noTypedef) {
|
||||||
|
Push(ccode, Getattr(n, "name"));
|
||||||
|
Push(ccode, " ");
|
||||||
|
Push(ccode, Getattr(n, "kind"));
|
||||||
|
} else {
|
||||||
|
Push(ccode, Getattr(n, "kind"));
|
||||||
|
Push(ccode, "typedef ");
|
||||||
|
Append(ccode, " ");
|
||||||
|
Append(ccode, Getattr(n, "tdname"));
|
||||||
|
}
|
||||||
|
Append(ccode, ";");
|
||||||
|
|
||||||
|
/* Strip comments - further code may break in presence of comments. */
|
||||||
|
strip_comments(Char(ccode));
|
||||||
|
|
||||||
|
/* Make all SWIG created typedef structs/unions/classes unnamed else
|
||||||
|
redefinition errors occur - nasty hack alert. */
|
||||||
|
if (!noTypedef) {
|
||||||
|
const char *types_array[3] = { "struct", "union", "class" };
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
char *code_ptr = Char(ccode);
|
||||||
|
while (code_ptr) {
|
||||||
|
/* Replace struct name (as in 'struct name {...}' ) with whitespace
|
||||||
|
name will be between struct and opening brace */
|
||||||
|
|
||||||
|
code_ptr = strstr(code_ptr, types_array[i]);
|
||||||
|
if (code_ptr) {
|
||||||
|
char *open_bracket_pos;
|
||||||
|
code_ptr += strlen(types_array[i]);
|
||||||
|
open_bracket_pos = strchr(code_ptr, '{');
|
||||||
|
if (open_bracket_pos) {
|
||||||
|
/* Make sure we don't have something like struct A a; */
|
||||||
|
char *semi_colon_pos = strchr(code_ptr, ';');
|
||||||
|
if (!(semi_colon_pos && (semi_colon_pos < open_bracket_pos)))
|
||||||
|
while (code_ptr < open_bracket_pos)
|
||||||
|
*code_ptr++ = ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
/* Remove SWIG directive %constant which may be left in the SWIG created typedefs */
|
||||||
|
char *code_ptr = Char(ccode);
|
||||||
|
while (code_ptr) {
|
||||||
|
code_ptr = strstr(code_ptr, "%constant");
|
||||||
|
if (code_ptr) {
|
||||||
|
char *directive_end_pos = strchr(code_ptr, ';');
|
||||||
|
if (directive_end_pos) {
|
||||||
|
while (code_ptr <= directive_end_pos)
|
||||||
|
*code_ptr++ = ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Node *newnode = NewHash();
|
||||||
|
set_nodeType(newnode, "insert");
|
||||||
|
Setfile(newnode, Getfile(n));
|
||||||
|
Setline(newnode, Getline(n));
|
||||||
|
String *code = NewStringEmpty();
|
||||||
|
Wrapper_pretty_print(ccode, code);
|
||||||
|
Setattr(newnode, "code", code);
|
||||||
|
Delete(code);
|
||||||
|
Delattr(n, "code");
|
||||||
|
return newnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void insertNodeAfter(Node *n, Node *c) {
|
||||||
|
Node *g = parentNode(n);
|
||||||
|
set_parentNode(c, g);
|
||||||
|
Node *ns = nextSibling(n);
|
||||||
|
if (Node *outer = Getattr(c, "nested:outer")) {
|
||||||
|
while (ns && outer == Getattr(ns, "nested:outer")) {
|
||||||
|
n = ns;
|
||||||
|
ns = nextSibling(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!ns) {
|
||||||
|
set_lastChild(g, c);
|
||||||
|
} else {
|
||||||
|
set_nextSibling(c, ns);
|
||||||
|
set_previousSibling(ns, c);
|
||||||
|
}
|
||||||
|
set_nextSibling(n, c);
|
||||||
|
set_previousSibling(c, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Swig_nested_name_unnamed_c_structs(Node *n) {
|
||||||
|
if (!classhash)
|
||||||
|
classhash = Getattr(n, "classes");
|
||||||
|
Node *c = firstChild(n);
|
||||||
|
while (c) {
|
||||||
|
Node *next = nextSibling(c);
|
||||||
|
if (String *declName = Getattr(c, "nested:unnamed")) {
|
||||||
|
if (Node *outer = Getattr(c, "nested:outer")) {
|
||||||
|
// generate a name
|
||||||
|
String *name = NewStringf("%s_%s", Getattr(outer, "name"), declName);
|
||||||
|
Delattr(c, "nested:unnamed");
|
||||||
|
// set the name to the class and symbol table
|
||||||
|
Setattr(c, "tdname", name);
|
||||||
|
Setattr(c, "name", name);
|
||||||
|
Swig_symbol_setscope(Getattr(c, "symtab"));
|
||||||
|
Swig_symbol_setscopename(name);
|
||||||
|
// now that we have a name - gather base symbols
|
||||||
|
if (List *publicBases = Getattr(c, "baselist")) {
|
||||||
|
List *bases = Swig_make_inherit_list(name, publicBases, 0);
|
||||||
|
Swig_inherit_base_symbols(bases);
|
||||||
|
Delete(bases);
|
||||||
|
}
|
||||||
|
Setattr(classhash, name, c);
|
||||||
|
Swig_symbol_popscope();
|
||||||
|
// process declarations following this type (assign correct new type)
|
||||||
|
SwigType *ty = Copy(name);
|
||||||
|
Node *decl = nextSibling(c);
|
||||||
|
List *declList = NewList();
|
||||||
|
while (decl && Getattr(decl, "nested:unnamedtype") == c) {
|
||||||
|
Setattr(decl, "type", ty);
|
||||||
|
Append(declList, decl);
|
||||||
|
Delattr(decl, "nested:unnamedtype");
|
||||||
|
SetFlag(decl, "feature:immutable");
|
||||||
|
add_symbols_c(decl);
|
||||||
|
decl = nextSibling(decl);
|
||||||
|
}
|
||||||
|
Delete(ty);
|
||||||
|
// Check for extensions
|
||||||
|
/* // TODO: we can save extensions hash like class hash and move check_extensions() after nesting processing
|
||||||
|
if (extendhash) {
|
||||||
|
if (Node *am = Getattr(extendhash, name)) {
|
||||||
|
// Merge the extension into the symbol table
|
||||||
|
merge_extensions(c, am);
|
||||||
|
append_previous_extension(c, am);
|
||||||
|
Delattr(extendhash, clsname);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
Swig_symbol_setscope(Swig_symbol_global_scope());
|
||||||
|
add_symbols_c(c);
|
||||||
|
|
||||||
|
Node *ins = create_insert(c);
|
||||||
|
insertNodeAfter(c, ins);
|
||||||
|
removeNode(c);
|
||||||
|
insertNodeAfter(n, c);
|
||||||
|
Delete(ins);
|
||||||
|
Delattr(c, "nested:outer");
|
||||||
|
} else {
|
||||||
|
// global unnamed struct - ignore it
|
||||||
|
c = next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (CPlusPlusOut) {
|
||||||
|
if (Getattr(c, "nested:outer")) {
|
||||||
|
Node *ins = create_insert(c, true);
|
||||||
|
insertNodeAfter(c, ins);
|
||||||
|
Delete(ins);
|
||||||
|
Delattr(c, "nested:outer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// process children
|
||||||
|
Swig_nested_name_unnamed_c_structs(c);
|
||||||
|
c = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void remove_outer_class_reference(Node *n) {
|
||||||
|
for (Node *c = firstChild(n); c; c = nextSibling(c)) {
|
||||||
|
if (GetFlag(c, "feature:flatnested")) {
|
||||||
|
Delattr(c, "nested:outer");
|
||||||
|
remove_outer_class_reference(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Swig_nested_process_classes(Node *n) {
|
||||||
|
Node *c = firstChild(n);
|
||||||
|
while (c) {
|
||||||
|
Node *next = nextSibling(c);
|
||||||
|
if (!Getattr(c, "templatetype")) {
|
||||||
|
if (GetFlag(c, "nested") && GetFlag(c, "feature:flatnested")) {
|
||||||
|
removeNode(c);
|
||||||
|
if (!checkAttribute(c, "access", "public"))
|
||||||
|
SetFlag(c, "feature:ignore");
|
||||||
|
else
|
||||||
|
insertNodeAfter(n, c);
|
||||||
|
}
|
||||||
|
Swig_nested_process_classes(c);
|
||||||
|
}
|
||||||
|
c = next;
|
||||||
|
}
|
||||||
|
remove_outer_class_reference(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -421,7 +421,7 @@ int Swig_contract_mode_get();
|
||||||
void Swig_browser(Node *n, int);
|
void Swig_browser(Node *n, int);
|
||||||
void Swig_default_allocators(Node *n);
|
void Swig_default_allocators(Node *n);
|
||||||
void Swig_process_types(Node *n);
|
void Swig_process_types(Node *n);
|
||||||
void Swig_process_nested_classes(Node *n);
|
void Swig_nested_process_classes(Node *n);
|
||||||
void Swig_name_unnamed_c_structs(Node *n);
|
void Swig_nested_name_unnamed_c_structs(Node *n);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1283,430 +1283,3 @@ void Swig_process_types(Node *n) {
|
||||||
TypePass::pass(n);
|
TypePass::pass(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nested classes processing section
|
|
||||||
static Hash *classhash = 0;
|
|
||||||
|
|
||||||
static String *make_name(Node *n, String *name, SwigType *decl) {
|
|
||||||
int destructor = name && (*(Char(name)) == '~');
|
|
||||||
if (String *yyrename = Getattr(n, "class_rename")) {
|
|
||||||
String *s = NewString(yyrename);
|
|
||||||
Delattr(n, "class_rename");
|
|
||||||
if (destructor && (*(Char(s)) != '~')) {
|
|
||||||
Insert(s, 0, "~");
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!name)
|
|
||||||
return 0;
|
|
||||||
return Swig_name_make(n, 0, name, decl, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// C version of add_symbols()
|
|
||||||
static void add_symbols_c(Node *n) {
|
|
||||||
String *decl;
|
|
||||||
String *wrn = 0;
|
|
||||||
String *symname = 0;
|
|
||||||
int iscdecl = Cmp(nodeType(n), "cdecl") == 0;
|
|
||||||
Setattr(n, "ismember", "1");
|
|
||||||
Setattr(n, "access", "public");
|
|
||||||
if (Getattr(n, "sym:name"))
|
|
||||||
return;
|
|
||||||
decl = Getattr(n, "decl");
|
|
||||||
if (!SwigType_isfunction(decl)) {
|
|
||||||
String *name = Getattr(n, "name");
|
|
||||||
String *makename = Getattr(n, "parser:makename");
|
|
||||||
if (iscdecl) {
|
|
||||||
String *storage = Getattr(n, "storage");
|
|
||||||
if (Cmp(storage, "typedef") == 0) {
|
|
||||||
Setattr(n, "kind", "typedef");
|
|
||||||
} else {
|
|
||||||
SwigType *type = Getattr(n, "type");
|
|
||||||
String *value = Getattr(n, "value");
|
|
||||||
Setattr(n, "kind", "variable");
|
|
||||||
if (value && Len(value)) {
|
|
||||||
Setattr(n, "hasvalue", "1");
|
|
||||||
}
|
|
||||||
if (type) {
|
|
||||||
SwigType *ty;
|
|
||||||
SwigType *tmp = 0;
|
|
||||||
if (decl) {
|
|
||||||
ty = tmp = Copy(type);
|
|
||||||
SwigType_push(ty, decl);
|
|
||||||
} else {
|
|
||||||
ty = type;
|
|
||||||
}
|
|
||||||
if (!SwigType_ismutable(ty)) {
|
|
||||||
SetFlag(n, "hasconsttype");
|
|
||||||
SetFlag(n, "feature:immutable");
|
|
||||||
}
|
|
||||||
if (tmp)
|
|
||||||
Delete(tmp);
|
|
||||||
}
|
|
||||||
if (!type) {
|
|
||||||
Printf(stderr, "notype name %s\n", name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Swig_features_get(Swig_cparse_features(), 0, name, 0, n);
|
|
||||||
if (makename) {
|
|
||||||
symname = make_name(n, makename, 0);
|
|
||||||
Delattr(n, "parser:makename"); /* temporary information, don't leave it hanging around */
|
|
||||||
} else {
|
|
||||||
makename = name;
|
|
||||||
symname = make_name(n, makename, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!symname) {
|
|
||||||
symname = Copy(Getattr(n, "unnamed"));
|
|
||||||
}
|
|
||||||
if (symname) {
|
|
||||||
wrn = Swig_name_warning(n, 0, symname, 0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
String *name = Getattr(n, "name");
|
|
||||||
SwigType *fdecl = Copy(decl);
|
|
||||||
SwigType *fun = SwigType_pop_function(fdecl);
|
|
||||||
if (iscdecl) {
|
|
||||||
Setattr(n, "kind", "function");
|
|
||||||
}
|
|
||||||
|
|
||||||
Swig_features_get(Swig_cparse_features(), 0, name, fun, n);
|
|
||||||
|
|
||||||
symname = make_name(n, name, fun);
|
|
||||||
wrn = Swig_name_warning(n, 0, symname, fun);
|
|
||||||
|
|
||||||
Delete(fdecl);
|
|
||||||
Delete(fun);
|
|
||||||
|
|
||||||
}
|
|
||||||
if (!symname)
|
|
||||||
return;
|
|
||||||
if (GetFlag(n, "feature:ignore")) {
|
|
||||||
/* Only add to C symbol table and continue */
|
|
||||||
Swig_symbol_add(0, n);
|
|
||||||
} else if (strncmp(Char(symname), "$ignore", 7) == 0) {
|
|
||||||
char *c = Char(symname) + 7;
|
|
||||||
SetFlag(n, "feature:ignore");
|
|
||||||
if (strlen(c)) {
|
|
||||||
SWIG_WARN_NODE_BEGIN(n);
|
|
||||||
Swig_warning(0, Getfile(n), Getline(n), "%s\n", c + 1);
|
|
||||||
SWIG_WARN_NODE_END(n);
|
|
||||||
}
|
|
||||||
Swig_symbol_add(0, n);
|
|
||||||
} else {
|
|
||||||
Node *c;
|
|
||||||
if ((wrn) && (Len(wrn))) {
|
|
||||||
String *metaname = symname;
|
|
||||||
if (!Getmeta(metaname, "already_warned")) {
|
|
||||||
SWIG_WARN_NODE_BEGIN(n);
|
|
||||||
Swig_warning(0, Getfile(n), Getline(n), "%s\n", wrn);
|
|
||||||
SWIG_WARN_NODE_END(n);
|
|
||||||
Setmeta(metaname, "already_warned", "1");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c = Swig_symbol_add(symname, n);
|
|
||||||
|
|
||||||
if (c != n) {
|
|
||||||
/* symbol conflict attempting to add in the new symbol */
|
|
||||||
if (Getattr(n, "sym:weak")) {
|
|
||||||
Setattr(n, "sym:name", symname);
|
|
||||||
} else {
|
|
||||||
String *e = NewStringEmpty();
|
|
||||||
String *en = NewStringEmpty();
|
|
||||||
String *ec = NewStringEmpty();
|
|
||||||
int redefined = Swig_need_redefined_warn(n, c, true);
|
|
||||||
if (redefined) {
|
|
||||||
Printf(en, "Identifier '%s' redefined (ignored)", symname);
|
|
||||||
Printf(ec, "previous definition of '%s'", symname);
|
|
||||||
} else {
|
|
||||||
Printf(en, "Redundant redeclaration of '%s'", symname);
|
|
||||||
Printf(ec, "previous declaration of '%s'", symname);
|
|
||||||
}
|
|
||||||
if (Cmp(symname, Getattr(n, "name"))) {
|
|
||||||
Printf(en, " (Renamed from '%s')", SwigType_namestr(Getattr(n, "name")));
|
|
||||||
}
|
|
||||||
Printf(en, ",");
|
|
||||||
if (Cmp(symname, Getattr(c, "name"))) {
|
|
||||||
Printf(ec, " (Renamed from '%s')", SwigType_namestr(Getattr(c, "name")));
|
|
||||||
}
|
|
||||||
Printf(ec, ".");
|
|
||||||
SWIG_WARN_NODE_BEGIN(n);
|
|
||||||
if (redefined) {
|
|
||||||
Swig_warning(WARN_PARSE_REDEFINED, Getfile(n), Getline(n), "%s\n", en);
|
|
||||||
Swig_warning(WARN_PARSE_REDEFINED, Getfile(c), Getline(c), "%s\n", ec);
|
|
||||||
} else {
|
|
||||||
Swig_warning(WARN_PARSE_REDUNDANT, Getfile(n), Getline(n), "%s\n", en);
|
|
||||||
Swig_warning(WARN_PARSE_REDUNDANT, Getfile(c), Getline(c), "%s\n", ec);
|
|
||||||
}
|
|
||||||
SWIG_WARN_NODE_END(n);
|
|
||||||
Printf(e, "%s:%d:%s\n%s:%d:%s\n", Getfile(n), Getline(n), en, Getfile(c), Getline(c), ec);
|
|
||||||
Setattr(n, "error", e);
|
|
||||||
Delete(e);
|
|
||||||
Delete(en);
|
|
||||||
Delete(ec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Delete(symname);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Strips C-style and C++-style comments from string in-place. */
|
|
||||||
static void strip_comments(char *string) {
|
|
||||||
int state = 0;
|
|
||||||
/*
|
|
||||||
* 0 - not in comment
|
|
||||||
* 1 - in c-style comment
|
|
||||||
* 2 - in c++-style comment
|
|
||||||
* 3 - in string
|
|
||||||
* 4 - after reading / not in comments
|
|
||||||
* 5 - after reading * in c-style comments
|
|
||||||
* 6 - after reading \ in strings
|
|
||||||
*/
|
|
||||||
char *c = string;
|
|
||||||
while (*c) {
|
|
||||||
switch (state) {
|
|
||||||
case 0:
|
|
||||||
if (*c == '\"')
|
|
||||||
state = 3;
|
|
||||||
else if (*c == '/')
|
|
||||||
state = 4;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
if (*c == '*')
|
|
||||||
state = 5;
|
|
||||||
*c = ' ';
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (*c == '\n')
|
|
||||||
state = 0;
|
|
||||||
else
|
|
||||||
*c = ' ';
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
if (*c == '\"')
|
|
||||||
state = 0;
|
|
||||||
else if (*c == '\\')
|
|
||||||
state = 6;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
if (*c == '/') {
|
|
||||||
*(c - 1) = ' ';
|
|
||||||
*c = ' ';
|
|
||||||
state = 2;
|
|
||||||
} else if (*c == '*') {
|
|
||||||
*(c - 1) = ' ';
|
|
||||||
*c = ' ';
|
|
||||||
state = 1;
|
|
||||||
} else
|
|
||||||
state = 0;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
if (*c == '/')
|
|
||||||
state = 0;
|
|
||||||
else
|
|
||||||
state = 1;
|
|
||||||
*c = ' ';
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
state = 3;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
++c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a %insert with a typedef to make a new name visible to C
|
|
||||||
static Node *create_insert(Node *n, bool noTypedef = false) {
|
|
||||||
// format a typedef
|
|
||||||
String *ccode = Getattr(n, "code");
|
|
||||||
Push(ccode, " ");
|
|
||||||
if (noTypedef) {
|
|
||||||
Push(ccode, Getattr(n, "name"));
|
|
||||||
Push(ccode, " ");
|
|
||||||
Push(ccode, Getattr(n, "kind"));
|
|
||||||
} else {
|
|
||||||
Push(ccode, Getattr(n, "kind"));
|
|
||||||
Push(ccode, "typedef ");
|
|
||||||
Append(ccode, " ");
|
|
||||||
Append(ccode, Getattr(n, "tdname"));
|
|
||||||
}
|
|
||||||
Append(ccode, ";");
|
|
||||||
|
|
||||||
/* Strip comments - further code may break in presence of comments. */
|
|
||||||
strip_comments(Char(ccode));
|
|
||||||
|
|
||||||
/* Make all SWIG created typedef structs/unions/classes unnamed else
|
|
||||||
redefinition errors occur - nasty hack alert. */
|
|
||||||
if (!noTypedef) {
|
|
||||||
const char *types_array[3] = { "struct", "union", "class" };
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
char *code_ptr = Char(ccode);
|
|
||||||
while (code_ptr) {
|
|
||||||
/* Replace struct name (as in 'struct name {...}' ) with whitespace
|
|
||||||
name will be between struct and opening brace */
|
|
||||||
|
|
||||||
code_ptr = strstr(code_ptr, types_array[i]);
|
|
||||||
if (code_ptr) {
|
|
||||||
char *open_bracket_pos;
|
|
||||||
code_ptr += strlen(types_array[i]);
|
|
||||||
open_bracket_pos = strchr(code_ptr, '{');
|
|
||||||
if (open_bracket_pos) {
|
|
||||||
/* Make sure we don't have something like struct A a; */
|
|
||||||
char *semi_colon_pos = strchr(code_ptr, ';');
|
|
||||||
if (!(semi_colon_pos && (semi_colon_pos < open_bracket_pos)))
|
|
||||||
while (code_ptr < open_bracket_pos)
|
|
||||||
*code_ptr++ = ' ';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
/* Remove SWIG directive %constant which may be left in the SWIG created typedefs */
|
|
||||||
char *code_ptr = Char(ccode);
|
|
||||||
while (code_ptr) {
|
|
||||||
code_ptr = strstr(code_ptr, "%constant");
|
|
||||||
if (code_ptr) {
|
|
||||||
char *directive_end_pos = strchr(code_ptr, ';');
|
|
||||||
if (directive_end_pos) {
|
|
||||||
while (code_ptr <= directive_end_pos)
|
|
||||||
*code_ptr++ = ' ';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Node *newnode = NewHash();
|
|
||||||
set_nodeType(newnode, "insert");
|
|
||||||
Setfile(newnode, Getfile(n));
|
|
||||||
Setline(newnode, Getline(n));
|
|
||||||
String *code = NewStringEmpty();
|
|
||||||
Wrapper_pretty_print(ccode, code);
|
|
||||||
Setattr(newnode, "code", code);
|
|
||||||
Delete(code);
|
|
||||||
Delattr(n, "code");
|
|
||||||
return newnode;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void insertNodeAfter(Node *n, Node *c) {
|
|
||||||
Node *g = parentNode(n);
|
|
||||||
set_parentNode(c, g);
|
|
||||||
Node *ns = nextSibling(n);
|
|
||||||
if (Node *outer = Getattr(c, "nested:outer")) {
|
|
||||||
while (ns && outer == Getattr(ns, "nested:outer")) {
|
|
||||||
n = ns;
|
|
||||||
ns = nextSibling(n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!ns) {
|
|
||||||
set_lastChild(g, c);
|
|
||||||
} else {
|
|
||||||
set_nextSibling(c, ns);
|
|
||||||
set_previousSibling(ns, c);
|
|
||||||
}
|
|
||||||
set_nextSibling(n, c);
|
|
||||||
set_previousSibling(c, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Swig_name_unnamed_c_structs(Node *n) {
|
|
||||||
if (!classhash)
|
|
||||||
classhash = Getattr(n, "classes");
|
|
||||||
Node *c = firstChild(n);
|
|
||||||
while (c) {
|
|
||||||
Node *next = nextSibling(c);
|
|
||||||
if (String *declName = Getattr(c, "nested:unnamed")) {
|
|
||||||
if (Node *outer = Getattr(c, "nested:outer")) {
|
|
||||||
// generate a name
|
|
||||||
String *name = NewStringf("%s_%s", Getattr(outer, "name"), declName);
|
|
||||||
Delattr(c, "nested:unnamed");
|
|
||||||
// set the name to the class and symbol table
|
|
||||||
Setattr(c, "tdname", name);
|
|
||||||
Setattr(c, "name", name);
|
|
||||||
Swig_symbol_setscope(Getattr(c, "symtab"));
|
|
||||||
Swig_symbol_setscopename(name);
|
|
||||||
// now that we have a name - gather base symbols
|
|
||||||
if (List *publicBases = Getattr(c, "baselist")) {
|
|
||||||
List *bases = Swig_make_inherit_list(name, publicBases, 0);
|
|
||||||
Swig_inherit_base_symbols(bases);
|
|
||||||
Delete(bases);
|
|
||||||
}
|
|
||||||
Setattr(classhash, name, c);
|
|
||||||
Swig_symbol_popscope();
|
|
||||||
// process declarations following this type (assign correct new type)
|
|
||||||
SwigType *ty = Copy(name);
|
|
||||||
Node *decl = nextSibling(c);
|
|
||||||
List *declList = NewList();
|
|
||||||
while (decl && Getattr(decl, "nested:unnamedtype") == c) {
|
|
||||||
Setattr(decl, "type", ty);
|
|
||||||
Append(declList, decl);
|
|
||||||
Delattr(decl, "nested:unnamedtype");
|
|
||||||
SetFlag(decl, "feature:immutable");
|
|
||||||
add_symbols_c(decl);
|
|
||||||
decl = nextSibling(decl);
|
|
||||||
}
|
|
||||||
Delete(ty);
|
|
||||||
// Check for extensions
|
|
||||||
/* // TODO: we can save extensions hash like class hash and move check_extensions() after nesting processing
|
|
||||||
if (extendhash) {
|
|
||||||
if (Node *am = Getattr(extendhash, name)) {
|
|
||||||
// Merge the extension into the symbol table
|
|
||||||
merge_extensions(c, am);
|
|
||||||
append_previous_extension(c, am);
|
|
||||||
Delattr(extendhash, clsname);
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
Swig_symbol_setscope(Swig_symbol_global_scope());
|
|
||||||
add_symbols_c(c);
|
|
||||||
|
|
||||||
Node *ins = create_insert(c);
|
|
||||||
insertNodeAfter(c, ins);
|
|
||||||
removeNode(c);
|
|
||||||
insertNodeAfter(n, c);
|
|
||||||
Delete(ins);
|
|
||||||
Delattr(c, "nested:outer");
|
|
||||||
} else {
|
|
||||||
// global unnamed struct - ignore it
|
|
||||||
c = next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else if (CPlusPlusOut) {
|
|
||||||
if (Getattr(c, "nested:outer")) {
|
|
||||||
Node *ins = create_insert(c, true);
|
|
||||||
insertNodeAfter(c, ins);
|
|
||||||
Delete(ins);
|
|
||||||
Delattr(c, "nested:outer");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// process children
|
|
||||||
Swig_name_unnamed_c_structs(c);
|
|
||||||
c = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void remove_outer_class_reference(Node *n) {
|
|
||||||
for (Node *c = firstChild(n); c; c = nextSibling(c)) {
|
|
||||||
if (GetFlag(c, "feature:flatnested")) {
|
|
||||||
Delattr(c, "nested:outer");
|
|
||||||
remove_outer_class_reference(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Swig_process_nested_classes(Node *n) {
|
|
||||||
Node *c = firstChild(n);
|
|
||||||
while (c) {
|
|
||||||
Node *next = nextSibling(c);
|
|
||||||
if (!Getattr(c, "templatetype")) {
|
|
||||||
if (GetFlag(c, "nested") && GetFlag(c, "feature:flatnested")) {
|
|
||||||
removeNode(c);
|
|
||||||
if (!checkAttribute(c, "access", "public"))
|
|
||||||
SetFlag(c, "feature:ignore");
|
|
||||||
else
|
|
||||||
insertNodeAfter(n, c);
|
|
||||||
}
|
|
||||||
Swig_process_nested_classes(c);
|
|
||||||
}
|
|
||||||
c = next;
|
|
||||||
}
|
|
||||||
remove_outer_class_reference(n);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue