summaryrefslogtreecommitdiff
path: root/Source/Modules/utils.cxx
blob: 2072b73fa85c42bbaa94058ae33d3db53e4afd32 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
/* ----------------------------------------------------------------------------- 
 * This file is part of SWIG, which is licensed as a whole under version 3 
 * (or any later version) of the GNU General Public License. Some additional
 * terms also apply to certain portions of SWIG. The full details of the SWIG
 * license and copyrights can be found in the LICENSE and COPYRIGHT files
 * included with the SWIG source code as distributed by the SWIG developers
 * and at https://www.swig.org/legal.html.
 *
 * utils.cxx
 *
 * Various utility functions.
 * ----------------------------------------------------------------------------- */

#include "swigmod.h"

int is_public(Node *n) {
  String *access = Getattr(n, "access");
  return !access || !Cmp(access, "public");
}

int is_private(Node *n) {
  String *access = Getattr(n, "access");
  return access && !Cmp(access, "private");
}

int is_protected(Node *n) {
  String *access = Getattr(n, "access");
  return access && !Cmp(access, "protected");
}

static int is_member_director_helper(Node *parentnode, Node *member) {
  int parent_nodirector = GetFlag(parentnode, "feature:nodirector");
  if (parent_nodirector)
    return 0;
  int parent_director = Swig_director_mode() && GetFlag(parentnode, "feature:director");
  int cdecl_director = parent_director || GetFlag(member, "feature:director");
  int cdecl_nodirector = GetFlag(member, "feature:nodirector");
  return cdecl_director && !cdecl_nodirector && !GetFlag(member, "feature:extend");
}

int is_member_director(Node *parentnode, Node *member) {
  if (parentnode && checkAttribute(member, "storage", "virtual")) {
    return is_member_director_helper(parentnode, member);
  } else {
    return 0;
  }
}

int is_member_director(Node *member) {
  return is_member_director(Getattr(member, "parentNode"), member);
}

// Identifies the additional protected members that are generated when the allprotected option is used.
// This does not include protected virtual methods as they are turned on with the dirprot option.
int is_non_virtual_protected_access(Node *n) {
  int result = 0;
  if (Swig_director_mode() && Swig_director_protected_mode() && Swig_all_protected_mode() && is_protected(n) && !checkAttribute(n, "storage", "virtual")) {
    Node *parentNode = Getattr(n, "parentNode");
    // When vtable is empty, the director class does not get emitted, so a check for an empty vtable should be done.
    // However, vtable is set in Language and so is not yet set when methods in Typepass call clean_overloaded()
    // which calls is_non_virtual_protected_access. So commented out below.
    // Moving the director vtable creation into Typepass should solve this problem.
    if (is_member_director_helper(parentNode, n) /* && Getattr(parentNode, "vtable")*/)
      result = 1;
  }
  return result;
}

/* Clean overloaded list.  Removes templates, ignored, and errors */

void clean_overloaded(Node *n) {
  Node *nn = Getattr(n, "sym:overloaded");
  Node *first = 0;
  while (nn) {
    String *ntype = nodeType(nn);
    if ((GetFlag(nn, "feature:ignore")) ||
	(Getattr(nn, "error")) ||
	(Strcmp(ntype, "template") == 0) ||
	((Strcmp(ntype, "cdecl") == 0) && is_protected(nn) && !is_member_director(nn) && !is_non_virtual_protected_access(n))) {
      /* Remove from overloaded list */
      Node *ps = Getattr(nn, "sym:previousSibling");
      Node *ns = Getattr(nn, "sym:nextSibling");
      if (ps) {
	Setattr(ps, "sym:nextSibling", ns);
      }
      if (ns) {
	Setattr(ns, "sym:previousSibling", ps);
      }
      Delattr(nn, "sym:previousSibling");
      Delattr(nn, "sym:nextSibling");
      Delattr(nn, "sym:overloaded");
      nn = ns;
      continue;
    } else {
      if (!first)
	first = nn;
      Setattr(nn, "sym:overloaded", first);
    }
    nn = Getattr(nn, "sym:nextSibling");
  }
  if (!first || (first && !Getattr(first, "sym:nextSibling"))) {
    if (Getattr(n, "sym:overloaded"))
      Delattr(n, "sym:overloaded");
  }
}

/* -----------------------------------------------------------------------------
 * Swig_set_max_hash_expand()
 *
 * Controls how many Hash objects are displayed when displaying nested Hash objects.
 * Makes DohSetMaxHashExpand an externally callable function (for debugger).
 * ----------------------------------------------------------------------------- */

void Swig_set_max_hash_expand(int count) {
  SetMaxHashExpand(count);
}

/* -----------------------------------------------------------------------------
 * misc_identifier_fix()
 *
 * If a template, return template with all template parameters fully resolved.
 *
 * This is a copy and modification of feature_identifier_fix and typemap_identifier_fix.
 * ----------------------------------------------------------------------------- */

static SwigType *misc_identifier_fix(const SwigType *s) {
  String *tp = SwigType_istemplate_templateprefix(s);
  if (tp) {
    String *ts, *ta, *tq, *tr;
    ts = SwigType_templatesuffix(s);
    ta = SwigType_templateargs(s);
    tq = Swig_symbol_type_qualify(ta, 0);
    tr = SwigType_typedef_resolve_all(ta);
    Append(tp, tr);
    Append(tp, ts);
    Delete(ts);
    Delete(ta);
    Delete(tq);
    Delete(tr);
  }
  return tp;
}

/* -----------------------------------------------------------------------------
 * Swig_smartptr_upcast()
 *
 * Replace classname with baseclassname in smart (smart pointer) to morph smart into a
 * smart pointer containing the base class instead of the given classname.
 * All parameters should be fully qualified types.
 * ----------------------------------------------------------------------------- */

SwigType *Swig_smartptr_upcast(SwigType *smart, SwigType *classname, SwigType *baseclassname) {
  SwigType *bsmart = Copy(smart);

  SwigType *rclassname = SwigType_typedef_resolve_all(classname);
  SwigType *rbaseclassname = SwigType_typedef_resolve_all(baseclassname);

  int replace_count = Replaceall(bsmart, rclassname, rbaseclassname);
  if (replace_count == 0) {
    // If no replacement made, it will be because rclassname is fully resolved, but the
    // type in the smartptr feature used a typedef or is not a fully resolved name.
    replace_count = Replaceall(bsmart, classname, rbaseclassname);
    if (replace_count == 0) {
      // Next try with all the template parameters in the smartptr resolved
      Delete(bsmart);
      SwigType *bsmart = misc_identifier_fix(smart);
      if (bsmart) {
	replace_count = Replaceall(bsmart, rclassname, rbaseclassname);
      }
      assert(replace_count); // failed to substitute
    }
  }

  Delete(rbaseclassname);
  Delete(rclassname);
  return bsmart;
}


extern "C" {

/* -----------------------------------------------------------------------------
 * Swig_get_max_hash_expand()
 *
 * Returns how many Hash objects are displayed when displaying nested Hash objects.
 * Makes DohGetMaxHashExpand an externally callable function (for debugger).
 * ----------------------------------------------------------------------------- */

int Swig_get_max_hash_expand() {
  return GetMaxHashExpand();
}

/* -----------------------------------------------------------------------------
 * Swig_to_doh_string()
 *
 * DOH version of Swig_to_string()
 * ----------------------------------------------------------------------------- */

static String *Swig_to_doh_string(DOH *object, int count) {
  int old_count = Swig_get_max_hash_expand();
  if (count >= 0)
    Swig_set_max_hash_expand(count);

  String *debug_string = object ? NewStringf("%s", object) : NewString("NULL");

  Swig_set_max_hash_expand(old_count);
  return debug_string;
}

/* -----------------------------------------------------------------------------
 * Swig_to_doh_string_with_location()
 *
 * DOH version of Swig_to_string_with_location()
 * ----------------------------------------------------------------------------- */

static String *Swig_to_doh_string_with_location(DOH *object, int count) {
  int old_count = Swig_get_max_hash_expand();
  if (count >= 0)
    Swig_set_max_hash_expand(count);

  String *debug_string = Swig_stringify_with_location(object);

  Swig_set_max_hash_expand(old_count);
  return debug_string;
}

/* -----------------------------------------------------------------------------
 * Swig_to_string()
 *
 * Swig debug - return C string representation of any DOH type.
 * Nested Hash types expand count is value of Swig_get_max_hash_expand when count<0
 * Note: leaks memory.
 * ----------------------------------------------------------------------------- */

const char *Swig_to_string(DOH *object, int count) {
  return Char(Swig_to_doh_string(object, count));
}

/* -----------------------------------------------------------------------------
 * Swig_to_string_with_location()
 *
 * Swig debug - return C string representation of any DOH type, within [] brackets
 * for Hash and List types, prefixed by line and file information.
 * Nested Hash types expand count is value of Swig_get_max_hash_expand when count<0
 * Note: leaks memory.
 * ----------------------------------------------------------------------------- */

const char *Swig_to_string_with_location(DOH *object, int count) {
  return Char(Swig_to_doh_string_with_location(object, count));
}

/* -----------------------------------------------------------------------------
 * Swig_print()
 *
 * Swig debug - display string representation of any DOH type.
 * Nested Hash types expand count is value of Swig_get_max_hash_expand when count<0
 * ----------------------------------------------------------------------------- */

void Swig_print(DOH *object, int count) {
  String *output = Swig_to_doh_string(object, count);
  Printf(stdout, "%s\n", output);
  Delete(output);
}

/* -----------------------------------------------------------------------------
 * Swig_to_string_with_location()
 *
 * Swig debug - display string representation of any DOH type, within [] brackets
 * for Hash and List types, prefixed by line and file information.
 * Nested Hash types expand count is value of Swig_get_max_hash_expand when count<0
 * ----------------------------------------------------------------------------- */

void Swig_print_with_location(DOH *object, int count) {
  String *output = Swig_to_doh_string_with_location(object, count);
  Printf(stdout, "%s\n", output);
  Delete(output);
}

} // extern "C"