summaryrefslogtreecommitdiff
path: root/Source/Modules/lang.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Modules/lang.cxx')
-rw-r--r--Source/Modules/lang.cxx106
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()
* ----------------------------------------------------------------------------- */