Add warnings for badly named destructors. Fix %extend and destructors for templates - they weren't always being wrapped. Fix destructor "name" attribute.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12804 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2011-09-13 06:15:29 +00:00
commit 4c6f66577a
10 changed files with 226 additions and 28 deletions

View file

@ -936,6 +936,9 @@ Allocate():
} else if (cplus_mode == PROTECTED) {
Setattr(inclass, "allocate:default_base_destructor", "1");
}
} else {
Setattr(inclass, "allocate:has_destructor", "1");
Setattr(inclass, "allocate:default_destructor", "1");
}
return SWIG_OK;
}

View file

@ -2609,17 +2609,18 @@ int Language::constructorDeclaration(Node *n) {
}
}
} else {
if (name && (!Equal(Swig_scopename_last(name), Swig_scopename_last(ClassName))) && !(Getattr(n, "template"))) {
bool illegal_method = true;
String *expected_name = ClassName;
if (name && (!Equal(Swig_scopename_last(name), Swig_scopename_last(expected_name))) && !(Getattr(n, "template"))) {
bool illegal_name = true;
if (Extend) {
// SWIG extension - allow typedef names as constructor name in %extend - an unnamed struct declared with a typedef can thus be given a 'constructor'.
SwigType *name_resolved = SwigType_typedef_resolve_all(name);
SwigType *classname_resolved = SwigType_typedef_resolve_all(ClassName);
illegal_method = !Equal(name_resolved, classname_resolved);
SwigType *expected_name_resolved = SwigType_typedef_resolve_all(expected_name);
illegal_name = !Equal(name_resolved, expected_name_resolved);
Delete(name_resolved);
Delete(classname_resolved);
Delete(expected_name_resolved);
}
if (illegal_method) {
if (illegal_name) {
Swig_warning(WARN_LANG_RETURN_TYPE, input_file, line_number, "Function %s must have a return type. Ignored.\n", SwigType_namestr(name));
Swig_restore(n);
return SWIG_NOWRAP;
@ -2727,24 +2728,12 @@ int Language::destructorDeclaration(Node *n) {
if (ImportMode)
return SWIG_NOWRAP;
if (Extend) {
/* extend destructor can be safely ignored if there is already one */
if (Getattr(CurrentClass, "has_destructor")) {
return SWIG_NOWRAP;
}
}
Swig_save("destructorDeclaration", n, "name", "sym:name", NIL);
char *c = GetChar(n, "name");
if (c && (*c == '~'))
Setattr(n, "name", c + 1);
c = GetChar(n, "sym:name");
if (c && (*c == '~'))
char *c = GetChar(n, "sym:name");
if (c && (*c == '~')) {
Setattr(n, "sym:name", c + 1);
/* Name adjustment for %name */
}
String *name = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
@ -2753,10 +2742,33 @@ int Language::destructorDeclaration(Node *n) {
Setattr(n, "sym:name", ClassPrefix);
}
String *expected_name = NewString(ClassName);
Replace(expected_name, "~", "", DOH_REPLACE_FIRST);
String *actual_name = NewString(name);
Replace(actual_name, "~", "", DOH_REPLACE_FIRST);
if (name && (!Equal(Swig_scopename_last(actual_name), Swig_scopename_last(expected_name))) && !(Getattr(n, "template"))) {
bool illegal_name = true;
if (Extend) {
// SWIG extension - allow typedef names as destructor name in %extend - an unnamed struct declared with a typedef can thus be given a 'destructor'.
SwigType *name_resolved = SwigType_typedef_resolve_all(actual_name);
SwigType *expected_name_resolved = SwigType_typedef_resolve_all(expected_name);
illegal_name = !Equal(name_resolved, expected_name_resolved);
Delete(name_resolved);
Delete(expected_name_resolved);
}
if (illegal_name) {
Swig_warning(WARN_LANG_ILLEGAL_DESTRUCTOR, input_file, line_number, "Illegal destructor name %s. Ignored.\n", SwigType_namestr(name));
Swig_restore(n);
Delete(expected_name);
return SWIG_NOWRAP;
}
}
destructorHandler(n);
Setattr(CurrentClass, "has_destructor", "1");
Swig_restore(n);
Delete(expected_name);
return SWIG_OK;
}