Add in possibility to use scopes in target language module symbol table

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11855 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2010-02-12 23:20:58 +00:00
commit 6c275f00d9
4 changed files with 57 additions and 43 deletions

View file

@ -307,15 +307,15 @@ Language::Language():
none_comparison(NewString("$arg != 0")), none_comparison(NewString("$arg != 0")),
director_ctor_code(NewString("")), director_ctor_code(NewString("")),
director_prot_ctor_code(0), director_prot_ctor_code(0),
symbols(NewHash()), symtabs(NewHash()),
symbolDump(NewString("")),
classtypes(NewHash()), classtypes(NewHash()),
enumtypes(NewHash()), enumtypes(NewHash()),
overloading(0), overloading(0),
multiinput(0), multiinput(0),
cplus_runtime(0), cplus_runtime(0),
directors(0), directors(0) {
symbol_table_dump(0) { Hash *symbols = NewHash();
Setattr(symtabs, "", symbols); // create top level/global symbol table scope
argc_template_string = NewString("argc"); argc_template_string = NewString("argc");
argv_template_string = NewString("argv[%d]"); argv_template_string = NewString("argv[%d]");
@ -334,8 +334,7 @@ symbol_table_dump(0) {
} }
Language::~Language() { Language::~Language() {
Delete(symbols); Delete(symtabs);
Delete(symbolDump);
Delete(classtypes); Delete(classtypes);
Delete(enumtypes); Delete(enumtypes);
Delete(director_ctor_code); Delete(director_ctor_code);
@ -1140,7 +1139,7 @@ int Language::callbackfunctionHandler(Node *n) {
Setattr(n, "type", cbty); Setattr(n, "type", cbty);
Setattr(n, "value", calltype); Setattr(n, "value", calltype);
Node *ns = Getattr(symbols, cbname); Node *ns = symbolLookup(cbname);
if (!ns) if (!ns)
constantWrapper(n); constantWrapper(n);
@ -2462,7 +2461,7 @@ int Language::classHandler(Node *n) {
continue; continue;
String *methodname = Getattr(method, "sym:name"); String *methodname = Getattr(method, "sym:name");
String *wrapname = NewStringf("%s_%s", symname, methodname); String *wrapname = NewStringf("%s_%s", symname, methodname);
if (!Getattr(symbols, wrapname) && (!is_public(method))) { if (!symbolLookup(wrapname, "") && (!is_public(method))) {
Node *m = Copy(method); Node *m = Copy(method);
Setattr(m, "director", "1"); Setattr(m, "director", "1");
Setattr(m, "parentNode", n); Setattr(m, "parentNode", n);
@ -2915,20 +2914,34 @@ void Language::main(int argc, char *argv[]) {
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* Language::addSymbol() * Language::addSymbol()
* *
* Adds a symbol entry. Returns 1 if the symbol is added successfully. * Adds a symbol entry into the target language symbol tables.
* Returns 1 if the symbol is added successfully.
* Prints an error message and returns 0 if a conflict occurs. * Prints an error message and returns 0 if a conflict occurs.
* The scope is optional for target languages and if supplied must be a fully
* resolved scope and the symbol s must not contain any scope qualifiers.
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
int Language::addSymbol(const String *s, const Node *n) { int Language::addSymbol(const String *s, const Node *n, const_String_or_char_ptr scope) {
Node *c = Getattr(symbols, s); Hash *symbols = Getattr(symtabs, scope);
if (c && (c != n)) { if (!symbols) {
Swig_error(input_file, line_number, "'%s' is multiply defined in the generated target language module.\n", s); // New scope which has not been added by the target language - lazily created.
Swig_error(Getfile(c), Getline(c), "Previous declaration of '%s'\n", s); symbols = NewHash();
return 0; Setattr(symtabs, scope, symbols);
// Add the new scope as a symbol in the top level scope.
// Alternatively the target language must add it in before attempting to add symbols into the scope.
const_String_or_char_ptr top_scope = "";
Hash *topscope_symbols = Getattr(symtabs, top_scope);
Setattr(topscope_symbols, scope, NewHash());
} else {
Node *c = Getattr(symbols, s);
if (c && (c != n)) {
Swig_error(input_file, line_number, "'%s' is multiply defined in the generated target language module.\n", s);
Swig_error(Getfile(c), Getline(c), "Previous declaration of '%s'\n", s);
return 0;
}
} }
Setattr(symbols, s, n); Setattr(symbols, s, n);
if (symbol_table_dump)
Printf(symbolDump, "%s\n", s);
return 1; return 1;
} }
@ -2937,22 +2950,35 @@ int Language::addSymbol(const String *s, const Node *n) {
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
void Language::dumpSymbols() { void Language::dumpSymbols() {
if (symbol_table_dump) { Printf(stdout, "LANGUAGE SYMBOLS start =======================================\n");
Printf(stdout, "LANGUAGE SYMBOLS start =======================================\n");
/* The symbol table is a hash so no ordering is possible if we iterate through it. Node *table = symtabs;
* Instead we gather the symbols as they are added and display them here. */ Iterator ki = First(table);
Printf(stdout, "%s", symbolDump); while (ki.key) {
String *k = ki.key;
Printf(stdout, "LANGUAGE SYMBOLS finish =======================================\n"); Printf(stdout, "===================================================\n");
Printf(stdout, "%s -\n", k);
{
Symtab *symtab = Getattr(table, k);
Iterator it = First(symtab);
while (it.key) {
String *symname = it.key;
Printf(stdout, " %s\n", symname);
it = Next(it);
}
}
ki = Next(ki);
} }
Printf(stdout, "LANGUAGE SYMBOLS finish =======================================\n");
} }
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* Language::symbolLookup() * Language::symbolLookup()
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
Node *Language::symbolLookup(String *s) { Node *Language::symbolLookup(String *s, const_String_or_char_ptr scope) {
Hash *symbols = Getattr(symtabs, scope);
return Getattr(symbols, s); return Getattr(symbols, s);
} }
@ -3396,10 +3422,6 @@ void Language::setOverloadResolutionTemplates(String *argc, String *argv) {
argv_template_string = Copy(argv); argv_template_string = Copy(argv);
} }
void Language::setSymbolsDumpNeeded() {
symbol_table_dump = 1;
}
int Language::is_assignable(Node *n) { int Language::is_assignable(Node *n) {
if (GetFlag(n, "feature:immutable")) if (GetFlag(n, "feature:immutable"))
return 0; return 0;

View file

@ -908,9 +908,6 @@ int SWIG_main(int argc, char *argv[], Language *l) {
SWIG_getoptions(argc, argv); SWIG_getoptions(argc, argv);
if (dump_lang_symbols)
lang->setSymbolsDumpNeeded();
// Define the __cplusplus symbol // Define the __cplusplus symbol
if (CPlusPlus) if (CPlusPlus)
Preprocessor_define((DOH *) "__cplusplus __cplusplus", 0); Preprocessor_define((DOH *) "__cplusplus __cplusplus", 0);

View file

@ -208,9 +208,9 @@ public:
/* Miscellaneous */ /* Miscellaneous */
virtual int validIdentifier(String *s); /* valid identifier? */ virtual int validIdentifier(String *s); /* valid identifier? */
virtual int addSymbol(const String *s, const Node *n); /* Add symbol */ virtual int addSymbol(const String *s, const Node *n, const_String_or_char_ptr scope = ""); /* Add symbol */
virtual void dumpSymbols(); virtual void dumpSymbols();
virtual Node *symbolLookup(String *s); /* Symbol lookup */ virtual Node *symbolLookup(String *s, const_String_or_char_ptr scope = ""); /* Symbol lookup */
virtual Node *classLookup(SwigType *s); /* Class lookup */ virtual Node *classLookup(SwigType *s); /* Class lookup */
virtual Node *enumLookup(SwigType *s); /* Enum lookup */ virtual Node *enumLookup(SwigType *s); /* Enum lookup */
virtual int abstractClassTest(Node *n); /* Is class really abstract? */ virtual int abstractClassTest(Node *n); /* Is class really abstract? */
@ -252,9 +252,6 @@ public:
/* Set overload variable templates argc and argv */ /* Set overload variable templates argc and argv */
void setOverloadResolutionTemplates(String *argc, String *argv); void setOverloadResolutionTemplates(String *argc, String *argv);
/* Set language module symbol table dump option */
void setSymbolsDumpNeeded();
/* Language instance is a singleton - get instance */ /* Language instance is a singleton - get instance */
static Language* instance(); static Language* instance();
@ -308,15 +305,13 @@ protected:
int director_language; int director_language;
private: private:
Hash *symbols; Hash *symtabs; /* symbol tables */
String *symbolDump;
Hash *classtypes; Hash *classtypes;
Hash *enumtypes; Hash *enumtypes;
int overloading; int overloading;
int multiinput; int multiinput;
int cplus_runtime; int cplus_runtime;
int directors; int directors;
int symbol_table_dump;
static Language *this_; static Language *this_;
}; };

View file

@ -207,14 +207,14 @@ void Swig_symbol_print_tables_summary(void) {
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
static void symbol_print_symbols(const char *symboltabletype) { static void symbol_print_symbols(const char *symboltabletype) {
Node *obj = symtabs; Node *table = symtabs;
Iterator ki = First(obj); Iterator ki = First(table);
while (ki.key) { while (ki.key) {
String *k = ki.key; String *k = ki.key;
Printf(stdout, "===================================================\n"); Printf(stdout, "===================================================\n");
Printf(stdout, "%s -\n", k); Printf(stdout, "%s -\n", k);
{ {
Symtab *symtab = Getattr(Getattr(obj, k), symboltabletype); Symtab *symtab = Getattr(Getattr(table, k), symboltabletype);
Iterator it = First(symtab); Iterator it = First(symtab);
while (it.key) { while (it.key) {
String *symname = it.key; String *symname = it.key;