diff options
Diffstat (limited to 'Source/Modules/lang.cxx')
-rw-r--r-- | Source/Modules/lang.cxx | 106 |
1 files changed, 102 insertions, 4 deletions
diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index 5ea79f0ab..3efd4e425 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -57,7 +57,9 @@ extern "C" { /* Some status variables used during parsing */ static int InClass = 0; /* Parsing C++ or not */ static String *ClassName = 0; /* This is the real name of the current class */ +static String *EnumClassName = 0; /* Enum class name */ static String *ClassPrefix = 0; /* Class prefix */ +static String *EnumClassPrefix = 0; /* Prefix for strongly typed enums (including ClassPrefix) */ static String *NSpace = 0; /* Namespace for the nspace feature */ static String *ClassType = 0; /* Fully qualified type name to use */ static String *DirectorClassName = 0; /* Director name of the current class */ @@ -1650,10 +1652,24 @@ int Language::enumDeclaration(Node *n) { String *oldNSpace = NSpace; NSpace = Getattr(n, "sym:nspace"); + String *oldEnumClassPrefix = EnumClassPrefix; + if (GetFlag(n, "scopedenum")) { + assert(Getattr(n, "sym:name")); + assert(Getattr(n, "name")); + EnumClassPrefix = ClassPrefix ? NewStringf("%s_", ClassPrefix) : NewString(""); + Printv(EnumClassPrefix, Getattr(n, "sym:name"), NIL); + EnumClassName = Copy(Getattr(n, "name")); + } if (!ImportMode) { emit_children(n); } + if (GetFlag(n, "scopedenum")) { + Delete(EnumClassName); + EnumClassName = 0; + Delete(EnumClassPrefix); + EnumClassPrefix = oldEnumClassPrefix; + } NSpace = oldNSpace; return SWIG_OK; @@ -1667,7 +1683,7 @@ int Language::enumvalueDeclaration(Node *n) { if (CurrentClass && (cplus_mode != PUBLIC)) return SWIG_NOWRAP; - Swig_require("enumvalueDeclaration", n, "*name", "?value", NIL); + Swig_require("enumvalueDeclaration", n, "*name", "*sym:name", "?value", NIL); String *value = Getattr(n, "value"); String *name = Getattr(n, "name"); String *tmpValue; @@ -1678,6 +1694,13 @@ int Language::enumvalueDeclaration(Node *n) { tmpValue = NewString(name); Setattr(n, "value", tmpValue); + Node *parent = parentNode(n); + if (GetFlag(parent, "scopedenum")) { + String *symname = Swig_name_member(0, Getattr(parent, "sym:name"), Getattr(n, "sym:name")); + Setattr(n, "sym:name", symname); + Delete(symname); + } + if (!CurrentClass || !cparse_cplusplus) { Setattr(n, "name", tmpValue); /* for wrapping of enums in a namespace when emit_action is used */ constantWrapper(n); @@ -1716,16 +1739,19 @@ int Language::memberconstantHandler(Node *n) { Setattr(n, "feature:except", Getattr(n, "feature:exceptvar")); } + String *enumvalue_symname = Getattr(n, "enumvalueDeclaration:sym:name"); // Only set if a strongly typed enum String *name = Getattr(n, "name"); String *symname = Getattr(n, "sym:name"); String *value = Getattr(n, "value"); - String *mrename = Swig_name_member(0, ClassPrefix, symname); + String *mrename = Swig_name_member(0, EnumClassPrefix, enumvalue_symname ? enumvalue_symname : symname); Setattr(n, "sym:name", mrename); String *new_name = 0; if (Extend) new_name = Copy(value); + else if (EnumClassName) + new_name = NewStringf("%s::%s", isNonVirtualProtectedAccess(n) ? DirectorClassName : EnumClassName, name); else new_name = NewStringf("%s::%s", isNonVirtualProtectedAccess(n) ? DirectorClassName : ClassName, name); Setattr(n, "name", new_name); @@ -2043,7 +2069,7 @@ int Language::classDirectorConstructors(Node *n) { needed, since there is a public constructor already defined. (scottm) This code is needed here to make the director_abstract + - test generate compileable code (Example2 in director_abastract.i). + test generate compilable code (Example2 in director_abastract.i). (mmatus) This is very strange, since swig compiled with gcc3.2.3 doesn't need it here.... @@ -2369,6 +2395,7 @@ int Language::classDeclaration(Node *n) { int oldInClass = InClass; String *oldClassType = ClassType; String *oldClassPrefix = ClassPrefix; + String *oldEnumClassPrefix = EnumClassPrefix; String *oldClassName = ClassName; String *oldDirectorClassName = DirectorClassName; String *oldNSpace = NSpace; @@ -2410,6 +2437,7 @@ int Language::classDeclaration(Node *n) { Push(ClassPrefix, "_"); Push(ClassPrefix, Getattr(outerClass, "sym:name")); } + EnumClassPrefix = Copy(ClassPrefix); if (strip) { ClassType = Copy(name); } else { @@ -2477,6 +2505,8 @@ int Language::classDeclaration(Node *n) { CurrentClass = oldCurrentClass; Delete(ClassType); ClassType = oldClassType; + Delete(EnumClassPrefix); + EnumClassPrefix = oldEnumClassPrefix; Delete(ClassPrefix); ClassPrefix = oldClassPrefix; Delete(ClassName); @@ -2664,7 +2694,8 @@ int Language::constructorDeclaration(Node *n) { String *scope = Swig_scopename_check(ClassName) ? Swig_scopename_prefix(ClassName) : 0; String *actual_name = scope ? NewStringf("%s::%s", scope, name) : NewString(name); Delete(scope); - if (!Equal(actual_name, expected_name) && !SwigType_istemplate(expected_name)) { + if (!Equal(actual_name, expected_name) && !SwigType_istemplate(expected_name) && !SwigType_istemplate(actual_name)) { + // Checking templates is skipped but they ought to be checked... they are just somewhat more tricky to check correctly bool illegal_name = true; if (Extend) { // Check for typedef names used as a constructor name in %extend. This is deprecated except for anonymous @@ -2962,6 +2993,12 @@ int Language::variableWrapper(Node *n) { Delattr(n,"varset"); Delattr(n,"varget"); + String *newsymname = 0; + if (!CurrentClass && EnumClassPrefix) { + newsymname = Swig_name_member(0, EnumClassPrefix, symname); + symname = newsymname; + } + /* If no way to set variables. We simply create functions */ int assignable = is_assignable(n); int flags = use_naturalvar_mode(n); @@ -3019,6 +3056,7 @@ int Language::variableWrapper(Node *n) { functionWrapper(n); Delattr(n, "varget"); Swig_restore(n); + Delete(newsymname); return SWIG_OK; } @@ -3500,6 +3538,45 @@ int Language::is_smart_pointer() const { } /* ----------------------------------------------------------------------------- + * Language::makeParameterName() + * + * Inputs: + * n - Node + * p - parameter node + * arg_num - parameter argument number + * setter - set this flag when wrapping variables + * Return: + * arg - a unique parameter name + * ----------------------------------------------------------------------------- */ +String *Language::makeParameterName(Node *n, Parm *p, int arg_num, bool setter) const { + + String *arg = 0; + String *pn = Getattr(p, "name"); + + // Use C parameter name unless it is a duplicate or an empty parameter name + int count = 0; + ParmList *plist = Getattr(n, "parms"); + while (plist) { + if ((Cmp(pn, Getattr(plist, "name")) == 0)) + count++; + plist = nextSibling(plist); + } + String *wrn = pn ? Swig_name_warning(p, 0, pn, 0) : 0; + arg = (!pn || (count > 1) || wrn) ? NewStringf("arg%d", arg_num) : Copy(pn); + + if (setter && Cmp(arg, "self") != 0) { + // Some languages (C#) insist on calling the input variable "value" while + // others (D, Java) could, in principle, use something different but this + // would require more work, and so we just use "value" for them too. + // For setters the parameter name sometimes includes C++ scope resolution which needs removing. + Delete(arg); + arg = NewString("value"); + } + + return arg; +} + +/* ----------------------------------------------------------------------------- * Language::() * ----------------------------------------------------------------------------- */ @@ -3517,9 +3594,22 @@ bool Language::extraDirectorProtectedCPPMethodsRequired() const { return true; } +/* ----------------------------------------------------------------------------- + * Language::nestedClassesSupport() + * ----------------------------------------------------------------------------- */ + Language::NestedClassSupport Language::nestedClassesSupport() const { return NCS_Unknown; } + +/* ----------------------------------------------------------------------------- + * Language::kwargsSupport() + * ----------------------------------------------------------------------------- */ + +bool Language::kwargsSupport() const { + return false; +} + /* ----------------------------------------------------------------------------- * Language::is_wrapping_class() * ----------------------------------------------------------------------------- */ @@ -3561,6 +3651,14 @@ String *Language::getClassPrefix() const { } /* ----------------------------------------------------------------------------- + * Language::getEnumClassPrefix() + * ----------------------------------------------------------------------------- */ + +String *Language::getEnumClassPrefix() const { + return EnumClassPrefix; +} + +/* ----------------------------------------------------------------------------- * Language::getClassType() * ----------------------------------------------------------------------------- */ |