1 /*
2 * The parse tree transformation module for SIP.
3 *
4 * Copyright (c) 2019 Riverbank Computing Limited <info@riverbankcomputing.com>
5 *
6 * This file is part of SIP.
7 *
8 * This copy of SIP is licensed for use under the terms of the SIP License
9 * Agreement. See the file LICENSE for more details.
10 *
11 * This copy of SIP may also used under the terms of the GNU General Public
12 * License v2 or v3 as published by the Free Software Foundation which can be
13 * found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
14 *
15 * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 */
18
19
20 #include <stddef.h>
21 #include <string.h>
22 #include <stdlib.h>
23
24 #include "sip.h"
25
26
27 static int samePythonSignature(signatureDef *sd1, signatureDef *sd2);
28 static int nextSignificantArg(signatureDef *sd, int a);
29 static int sameArgType(argDef *a1, argDef *a2, int strict);
30 static int supportedType(classDef *,overDef *,argDef *,int);
31 static int sameCppOverload(overDef *od1, overDef *od2);
32 static void setAllImports(moduleDef *mod);
33 static void addUniqueModule(moduleDef *mod, moduleDef *imp);
34 static void ensureInput(classDef *,overDef *,argDef *);
35 static void defaultInput(argDef *);
36 static void defaultOutput(argDef *ad);
37 static void createSortedNumberedTypesTable(sipSpec *pt, moduleDef *mod);
38 static int compareTypes(const void *t1, const void *t2);
39 static void addAutoOverload(sipSpec *,classDef *,overDef *);
40 static void ifaceFileIsUsed(ifaceFileList **used, argDef *ad, int need_types);
41 static void ifaceFilesAreUsedByOverload(ifaceFileList **used, overDef *od,
42 int need_types);
43 static void ifaceFilesAreUsedBySignature(ifaceFileList **used,
44 signatureDef *sd, int need_types);
45 static void scopeDefaultValue(sipSpec *,classDef *,argDef *);
46 static void setHierarchy(sipSpec *,classDef *,classDef *,classList **);
47 static void transformModules(sipSpec *pt, int strict, moduleDef *mod);
48 static void transformCtors(sipSpec *,classDef *);
49 static void transformCasts(sipSpec *,classDef *);
50 static void addDefaultCopyCtor(classDef *);
51 static void transformScopeOverloads(sipSpec *pt, int strict, classDef *c_scope,
52 mappedTypeDef *mt_scope, overDef *overs);
53 static void transformVariableList(sipSpec *pt, moduleDef *mod);
54 static void transformMappedTypes(sipSpec *pt, int strict, moduleDef *mod);
55 static void getVisiblePyMembers(sipSpec *pt, classDef *cd);
56 static void getVirtuals(sipSpec *pt, classDef *cd);
57 static void addVirtual(sipSpec *pt, overDef *od, classDef *cd);
58 static virtErrorHandler *getVirtErrorHandler(sipSpec *pt, overDef *od,
59 classDef *cd);
60 static virtHandlerDef *getVirtualHandler(sipSpec *pt, overDef *od,
61 classDef *cd);
62 static int checkVirtualHandler(overDef *od, virtHandlerDef *vhd);
63 static void transformTypedefs(sipSpec *pt, moduleDef *mod);
64 static void resolveMappedTypeTypes(sipSpec *,mappedTypeDef *);
65 static void resolveCtorTypes(sipSpec *,classDef *,ctorDef *);
66 static void resolveFuncTypes(sipSpec *pt, moduleDef *mod, classDef *c_scope,
67 overDef *od);
68 static void resolvePySigTypes(sipSpec *,moduleDef *,classDef *,overDef *,signatureDef *,int);
69 static void resolveVariableType(sipSpec *,varDef *);
70 SIP_NORETURN static void fatalNoDefinedType(scopedNameDef *);
71 static void resolveType(sipSpec *,moduleDef *,classDef *,argDef *,int);
72 static void setNeededType(argDef *ad);
73 static void setNeededExceptions(sipSpec *pt, moduleDef *mod,
74 throwArgs *exceptions);
75 static void setNeedsException(exceptionDef *xd);
76 static void searchClassScope(sipSpec *pt, classDef *c_scope,
77 scopedNameDef *snd, argDef *ad);
78 static void searchScope(sipSpec *pt, classDef *scope, scopedNameDef *snd,
79 argDef *ad);
80 static void nameLookup(sipSpec *pt, moduleDef *context, scopedNameDef *snd,
81 argDef *ad);
82 static void searchMappedTypes(sipSpec *,moduleDef *,scopedNameDef *,argDef *);
83 static void searchEnums(sipSpec *,scopedNameDef *,argDef *);
84 static void searchClasses(sipSpec *,moduleDef *mod,scopedNameDef *,argDef *);
85 static mroDef *newMRO(classDef *cd);
86 static void moveMainModuleCastsSlots(sipSpec *pt, moduleDef *mod);
87 static void moveClassCasts(sipSpec *pt, moduleDef *mod, classDef *cd);
88 static void moveGlobalSlot(sipSpec *pt, moduleDef *mod, memberDef *gmd);
89 static classDef *findAltClassImplementation(sipSpec *pt, mappedTypeDef *mtd);
90 static ifaceFileDef *getIfaceFile(argDef *ad);
91 static ifaceFileDef *getIfaceFileForEnum(enumDef *ed);
92 static void instantiateMappedTypeTemplate(sipSpec *pt, moduleDef *mod,
93 mappedTypeTmplDef *mtt, argDef *type);
94 static classDef *getProxy(moduleDef *mod, classDef *cd);
95 static int generatingCodeForModule(sipSpec *pt, moduleDef *mod);
96 static void checkHelpers(sipSpec *pt, classDef *cd);
97 static void addComplementarySlots(sipSpec *pt, classDef *cd);
98 static void addComplementarySlot(sipSpec *pt, classDef *cd, memberDef *md,
99 slotType cslot, const char *cslot_name);
100 static void resolveInstantiatedClassTemplate(sipSpec *pt, argDef *type);
101 static void setStringPoolOffsets(sipSpec *pt);
102 static mappedTypeDef *copyTemplateType(mappedTypeDef *mtd, argDef *ad);
103 static void checkProperties(classDef *cd);
104
105
106 /*
107 * Transform the parse tree.
108 */
109
transform(sipSpec * pt,int strict)110 void transform(sipSpec *pt, int strict)
111 {
112 moduleDef *mod;
113 classDef *cd, *rev, **tail;
114 classList *newl;
115 overDef *od;
116 exceptionDef *xd;
117
118 /*
119 * The class list has the main module's classes at the front and the ones
120 * from the module at the most nested %Import at the end. This affects
121 * some of the following algorithms. We have to have consistency whenever
122 * a module is used. To achieve this we reverse the order of the classes.
123 */
124 rev = NULL;
125 cd = pt -> classes;
126
127 while (cd != NULL)
128 {
129 classDef *next;
130
131 /*
132 * Take the opportunity to strip any classes that are only template
133 * arguments.
134 */
135 while (isTemplateArg(cd))
136 if ((cd = cd->next) == NULL)
137 break;
138
139 if (cd == NULL)
140 break;
141
142 next = cd -> next;
143
144 cd -> next = rev;
145 rev = cd;
146
147 /*
148 * Mark any QObject class. This flag will ripple through all derived
149 * classes when we set the hierarchy.
150 */
151 if (strcmp(classBaseName(cd), "QObject") == 0)
152 setIsQObjectSubClass(cd);
153
154 cd = next;
155 }
156
157 pt -> classes = rev;
158
159 /*
160 * Build the list of all imports for each module and check each has been
161 * named.
162 */
163 for (mod = pt->modules; mod != NULL; mod = mod->next)
164 {
165 if (mod->name == NULL)
166 fatal("A module is missing a %%Module or %%CModule directive\n");
167
168 setAllImports(mod);
169 }
170
171 /*
172 * Set the default meta-type for the main module if it doesn't have one
173 * explicitly set.
174 */
175 if (pt->module->defmetatype == NULL)
176 {
177 moduleListDef *mld;
178
179 for (mld = pt->module->allimports; mld != NULL; mld = mld->next)
180 {
181 if (mld->module->defmetatype == NULL)
182 continue;
183
184 if (pt->module->defmetatype == NULL)
185 pt->module->defmetatype = mld->module->defmetatype;
186 else if (pt->module->defmetatype != mld->module->defmetatype)
187 fatal("The %s module has imported different default meta-types %s and %s\n",
188 pt->module->fullname->text,
189 pt->module->defmetatype->text,
190 mld->module->defmetatype->text);
191 }
192 }
193
194 /* Check each class has been defined. */
195 for (cd = pt -> classes; cd != NULL; cd = cd -> next)
196 if (cd -> iff -> module == NULL)
197 {
198 fatalScopedName(classFQCName(cd));
199 fatal(" has not been defined\n");
200 }
201
202 /*
203 * Set the super-class hierarchy for each class and re-order the list of
204 * classes so that no class appears before a super class or an enclosing
205 * scope class.
206 */
207 newl = NULL;
208
209 for (cd = pt -> classes; cd != NULL; cd = cd -> next)
210 setHierarchy(pt,cd,cd,&newl);
211
212 /* Replace the old list with the new one. */
213 tail = &pt -> classes;
214
215 while (newl != NULL)
216 {
217 classList *cl = newl;
218
219 *tail = cl -> cd;
220 tail = &cl -> cd -> next;
221
222 newl = cl -> next;
223 free(cl);
224 }
225
226 *tail = NULL;
227
228 /* Transform the various types in the modules. */
229 if (isConsolidated(pt->module))
230 {
231 /* Transform the modules included by the consolidated module. */
232 for (mod = pt->modules->next; mod != NULL; mod = mod->next)
233 transformModules(pt, strict, mod);
234 }
235 else
236 {
237 transformModules(pt, strict, pt->modules);
238 }
239
240 /* Handle default ctors now that the argument types are resolved. */
241 if (!pt->genc)
242 for (cd = pt->classes; cd != NULL; cd = cd->next)
243 if (!noDefaultCtors(cd) && !isOpaque(cd) && cd->iff->type != namespace_iface)
244 addDefaultCopyCtor(cd);
245
246 /* Add any automatically generated methods. */
247 for (cd = pt -> classes; cd != NULL; cd = cd -> next)
248 for (od = cd -> overs; od != NULL; od = od -> next)
249 if (isAutoGen(od))
250 addAutoOverload(pt,cd,od);
251
252 /*
253 * Move casts and slots around to their correct classes (if in the same
254 * module) or create proxies for them (if cross-module).
255 */
256 if (!pt->genc)
257 for (mod = pt->modules; mod != NULL; mod = mod->next)
258 if (generatingCodeForModule(pt, mod))
259 moveMainModuleCastsSlots(pt, mod);
260
261 /* Automatically generate missing complementary slots. */
262 if (!pt->genc)
263 {
264 for (cd = pt->classes; cd != NULL; cd = cd->next)
265 addComplementarySlots(pt, cd);
266
267 for (mod = pt->modules; mod != NULL; mod = mod->next)
268 if (generatingCodeForModule(pt, mod))
269 for (cd = mod->proxies; cd != NULL; cd = cd->next)
270 addComplementarySlots(pt, cd);
271 }
272
273 /* Generate the different class views. */
274 for (cd = pt->classes; cd != NULL; cd = cd->next)
275 if (cd->iff->type == class_iface)
276 {
277 if (needsShadow(cd) && !isIncomplete(cd) && !isPrivateDtor(cd) && canCreate(cd))
278 setHasShadow(cd);
279
280 /* Get the list of visible Python member functions. */
281 getVisiblePyMembers(pt, cd);
282
283 /* Get the virtual members. */
284 if (needsShadow(cd))
285 getVirtuals(pt, cd);
286 }
287 else if (cd->iff->type == namespace_iface)
288 {
289 for (od = cd->overs; od != NULL; od = od->next)
290 ifaceFilesAreUsedByOverload(&cd->iff->used, od, FALSE);
291 }
292
293 for (mod = pt->modules; mod != NULL; mod = mod->next)
294 {
295 /* Create the array of numbered types sorted by type name. */
296 createSortedNumberedTypesTable(pt, mod);
297
298 for (od = mod->overs; od != NULL; od = od->next)
299 ifaceFilesAreUsedByOverload(&mod->used, od, FALSE);
300
301 /* Update proxies with some information from the real classes. */
302 for (cd = mod->proxies; cd != NULL; cd = cd->next)
303 cd->iff->ifacenr = cd->real->iff->ifacenr;
304 }
305
306 /* Additional class specific checks. */
307 for (cd = pt->classes; cd != NULL; cd = cd->next)
308 {
309 checkHelpers(pt, cd);
310 checkProperties(cd);
311 }
312
313 /* Number the exceptions as they will be seen by the main module. */
314 for (xd = pt->exceptions; xd != NULL; xd = xd->next)
315 {
316 moduleDef *xd_mod;
317
318 /*
319 * Skip those that don't require a Python exception object to be
320 * created.
321 */
322 if (xd->iff->type != exception_iface)
323 continue;
324
325 if (xd->bibase == NULL && xd->base == NULL)
326 continue;
327
328 xd_mod = xd->iff->module;
329
330 if (xd_mod == pt->module || xd->needed)
331 xd->exceptionnr = xd_mod->nrexceptions++;
332 }
333
334 setStringPoolOffsets(pt);
335 }
336
337
338 /*
339 * Transform a module and the modules it imports.
340 */
transformModules(sipSpec * pt,int strict,moduleDef * mod)341 static void transformModules(sipSpec *pt, int strict, moduleDef *mod)
342 {
343 classDef *cd;
344 moduleListDef *mld;
345
346 /* Handle the trivial case. */
347 if (isTransformed(mod))
348 return;
349
350 /*
351 * The modules on which this one depends must be done first because they
352 * might generate new template-based types and they must be defined in the
353 * right module.
354 */
355 for (mld = mod->imports; mld != NULL; mld = mld->next)
356 transformModules(pt, strict, mld->module);
357
358 /* Transform typedefs, variables and global functions. */
359 transformTypedefs(pt, mod);
360 transformVariableList(pt, mod);
361 transformScopeOverloads(pt, strict, NULL, NULL, mod->overs);
362
363 /* Transform class ctors, functions and casts. */
364 for (cd = pt->classes; cd != NULL; cd = cd->next)
365 {
366 if (cd->iff->module == mod)
367 {
368 transformCtors(pt, cd);
369
370 /* Handle any dtor exceptions. */
371 setNeededExceptions(pt, mod, cd->dtorexceptions);
372
373 if (!pt->genc)
374 {
375 transformScopeOverloads(pt, strict, cd, NULL, cd->overs);
376 transformCasts(pt, cd);
377 }
378 }
379 }
380
381 /* Transform mapped types based on templates. */
382 transformMappedTypes(pt, strict, mod);
383
384 setIsTransformed(mod);
385 }
386
387
388 /*
389 * Set the offset into the string pool for every used name.
390 */
setStringPoolOffsets(sipSpec * pt)391 static void setStringPoolOffsets(sipSpec *pt)
392 {
393 nameDef *nd;
394 size_t offset = 0;
395
396 for (nd = pt->namecache; nd != NULL; nd = nd->next)
397 {
398 size_t len;
399 nameDef *prev;
400
401 if (!isUsedName(nd))
402 continue;
403
404 /* See if the tail of a previous used name could be used instead. */
405 len = nd->len;
406
407 for (prev = pt->namecache; prev->len > len; prev = prev->next)
408 {
409 size_t pos;
410
411 if (!isUsedName(prev) || isSubstring(prev))
412 continue;
413
414 pos = prev->len - len;
415
416 if (memcmp(&prev->text[pos], nd->text, len) == 0)
417 {
418 setIsSubstring(nd);
419 nd->offset = prev->offset + pos;
420 break;
421 }
422 }
423
424 if (!isSubstring(nd))
425 {
426 nd->offset = offset;
427 offset += len + 1;
428 }
429 }
430 }
431
432
433 /*
434 * Add any missing complementary slots to a class. This emulates the C++
435 * behaviour of automatically interpreting (for example) >= as !<.
436 */
addComplementarySlots(sipSpec * pt,classDef * cd)437 static void addComplementarySlots(sipSpec *pt, classDef *cd)
438 {
439 memberDef *md;
440
441 for (md = cd->members; md != NULL; md = md->next)
442 switch (md->slot)
443 {
444 case lt_slot:
445 addComplementarySlot(pt, cd, md, ge_slot, "__ge__");
446 break;
447
448 case le_slot:
449 addComplementarySlot(pt, cd, md, gt_slot, "__gt__");
450 break;
451
452 case gt_slot:
453 addComplementarySlot(pt, cd, md, le_slot, "__le__");
454 break;
455
456 case ge_slot:
457 addComplementarySlot(pt, cd, md, lt_slot, "__lt__");
458 break;
459
460 case eq_slot:
461 addComplementarySlot(pt, cd, md, ne_slot, "__ne__");
462 break;
463
464 case ne_slot:
465 addComplementarySlot(pt, cd, md, eq_slot, "__eq__");
466 break;
467
468 /* Suppress a compiler warning. */
469 default:
470 ;
471 }
472 }
473
474
475 /*
476 * Add a complementary slot if it is missing.
477 */
addComplementarySlot(sipSpec * pt,classDef * cd,memberDef * md,slotType cslot,const char * cslot_name)478 static void addComplementarySlot(sipSpec *pt, classDef *cd, memberDef *md,
479 slotType cslot, const char *cslot_name)
480 {
481 overDef *od1;
482 memberDef *md2 = NULL;
483
484 for (od1 = cd->overs; od1 != NULL; od1 = od1->next)
485 {
486 overDef *od2;
487
488 if (od1->common != md || isComplementary(od1) || od1->methodcode != NULL)
489 continue;
490
491 /* Try and find an existing complementary slot. */
492 for (od2 = cd->overs; od2 != NULL; od2 = od2->next)
493 if (od2->common->slot == cslot && sameSignature(&od1->pysig, &od2->pysig, TRUE))
494 break;
495
496 /*
497 * If there is an explicit complementary slot then there is nothing to
498 * do.
499 */
500 if (od2 != NULL)
501 continue;
502
503 /* Create a new member if needed. */
504 if (md2 == NULL)
505 {
506 for (md2 = cd->members; md2 != NULL; md2 = md2->next)
507 if (md2->slot == cslot)
508 break;
509
510 if (md2 == NULL)
511 {
512 md2 = sipMalloc(sizeof (memberDef));
513
514 md2->pyname = cacheName(pt, cslot_name);
515 md2->memberflags = md->memberflags;
516 md2->slot = cslot;
517 md2->module = md->module;
518
519 md2->next = cd->members;
520 cd->members = md2;
521
522 if (isUsedName(md->pyname))
523 setIsUsedName(md2->pyname);
524 }
525 }
526
527 /* Create the complementary slot. */
528 od2 = sipMalloc(sizeof (overDef));
529
530 *od2 = *od1;
531 resetIsVirtual(od2);
532 setIsComplementary(od2);
533 od2->common = md2;
534 od2->cppname = cslot_name;
535
536 od2->next = cd->overs;
537 cd->overs = od2;
538 }
539 }
540
541
542 /*
543 * See if a class supports array and copy helpers.
544 */
checkHelpers(sipSpec * pt,classDef * cd)545 static void checkHelpers(sipSpec *pt, classDef *cd)
546 {
547 int pub_def_ctor, pub_copy_ctor;
548 ctorDef *ct;
549
550 /*
551 * We disregard classes that are abstract, or have a private assignment
552 * operator or don't have a public dtor.
553 */
554 if (isAbstractClass(cd))
555 return;
556
557 if (cannotAssign(cd))
558 return;
559
560 if (!isPublicDtor(cd))
561 return;
562
563 /* See if the class has a default ctor and a public copy ctor. */
564 pub_def_ctor = pub_copy_ctor = FALSE;
565
566 for (ct = cd->ctors; ct != NULL; ct = ct->next)
567 {
568 if (ct->cppsig == NULL || !isPublicCtor(ct))
569 continue;
570
571 if (ct->cppsig->nrArgs == 0 || ct->cppsig->args[0].defval != NULL)
572 {
573 /*
574 * The ctor either has no arguments or all arguments have defaults.
575 */
576 pub_def_ctor = TRUE;
577 }
578 else if (ct->cppsig->nrArgs == 1)
579 {
580 argDef *ad = &ct->cppsig->args[0];
581 classDef *arg_cd;
582
583 if (ad->atype == class_type)
584 arg_cd = ad->u.cd;
585 else if (ad->atype == mapped_type)
586 arg_cd = findAltClassImplementation(pt, ad->u.mtd);
587 else
588 arg_cd = NULL;
589
590 if (arg_cd == cd && isReference(ad) && isConstArg(ad) &&
591 ad->nrderefs == 0 && ad->defval == NULL)
592 pub_copy_ctor = TRUE;
593 }
594 }
595
596 if (pub_def_ctor)
597 {
598 setArrayHelper(cd);
599 appendToIfaceFileList(&cd->iff->module->used, cd->iff);
600 }
601
602 if (pub_copy_ctor)
603 {
604 setCopyHelper(cd);
605 appendToIfaceFileList(&cd->iff->module->used, cd->iff);
606 }
607 }
608
609
610 /*
611 * Set the list of all imports for a module. The list is ordered so that a
612 * module appears before any module that imports it.
613 */
setAllImports(moduleDef * mod)614 static void setAllImports(moduleDef *mod)
615 {
616 moduleListDef *mld;
617
618 /*
619 * Handle the trivial case where there are no imports, or the list has
620 * already been done.
621 */
622 if (mod->imports == NULL || mod->allimports != NULL)
623 return;
624
625 /* Check for recursive imports. */
626 if (settingImports(mod))
627 fatal("Module %s is imported recursively\n", mod->name);
628
629 setSettingImports(mod);
630
631 /* Make sure all the direct imports are done first. */
632 for (mld = mod->imports; mld != NULL; mld = mld->next)
633 setAllImports(mld->module);
634
635 /*
636 * Now build the list from our direct imports lists but ignoring
637 * duplicates.
638 */
639 for (mld = mod->imports; mld != NULL; mld = mld->next)
640 {
641 moduleListDef *amld;
642
643 for (amld = mld->module->allimports; amld != NULL; amld = amld->next)
644 addUniqueModule(mod, amld->module);
645
646 addUniqueModule(mod, mld->module);
647 }
648
649 resetSettingImports(mod);
650 }
651
652
653 /*
654 * Append a module to the list of all imported modules if it isn't already
655 * there.
656 */
addUniqueModule(moduleDef * mod,moduleDef * imp)657 static void addUniqueModule(moduleDef *mod, moduleDef *imp)
658 {
659 moduleListDef **tail;
660
661 for (tail = &mod->allimports; *tail != NULL; tail = &(*tail)->next)
662 if ((*tail)->module == imp)
663 return;
664
665 *tail = sipMalloc(sizeof (moduleListDef));
666
667 (*tail)->module = imp;
668 (*tail)->next = NULL;
669 }
670
671
672 /*
673 * Move the casts and slots to the correct place for a main module (ie. one we
674 * are generating code for).
675 */
moveMainModuleCastsSlots(sipSpec * pt,moduleDef * mod)676 static void moveMainModuleCastsSlots(sipSpec *pt, moduleDef *mod)
677 {
678 classDef *cd;
679 memberDef *md;
680
681 for (cd = pt->classes; cd != NULL; cd = cd->next)
682 if (cd->iff->module == mod)
683 moveClassCasts(pt, mod, cd);
684
685 for (md = mod->othfuncs; md != NULL; md = md->next)
686 if (md->slot != no_slot && md->module == mod)
687 moveGlobalSlot(pt, mod, md);
688 }
689
690
691 /*
692 * Move any class casts to its correct class, or publish as a ctor extender.
693 */
moveClassCasts(sipSpec * pt,moduleDef * mod,classDef * cd)694 static void moveClassCasts(sipSpec *pt, moduleDef *mod, classDef *cd)
695 {
696 argList *al;
697
698 for (al = cd->casts; al != NULL; al = al->next)
699 {
700 classDef *dcd = al->arg.u.cd;
701 ctorDef *ct, **ctp;
702 argDef *ad;
703
704 if (al->arg.atype == class_type)
705 dcd = al->arg.u.cd;
706 else
707 /* Previous error checking means this will always work. */
708 dcd = findAltClassImplementation(pt, al->arg.u.mtd);
709
710 /* Create the new ctor. */
711 ct = sipMalloc(sizeof (ctorDef));
712
713 ct->ctorflags = SECT_IS_PUBLIC | CTOR_CAST;
714 ct->cppsig = &ct->pysig;
715
716 /* Add the source class as the only argument. */
717 ct->pysig.result.atype = void_type;
718 ad = &ct->pysig.args[0];
719
720 ad->atype = class_type;
721 ad->name = NULL;
722 ad->argflags = ARG_IN | (al->arg.argflags & (ARG_IS_REF | ARG_IS_CONST));
723 ad->nrderefs = al->arg.nrderefs;
724 memcpy(ad->derefs, al->arg.derefs, sizeof (ad->derefs));
725 ad->defval = NULL;
726 ad->u.cd = cd;
727
728 /*
729 * If the destination class is in a different module then use
730 * a proxy.
731 */
732 if (dcd->iff->module != mod)
733 {
734 ifaceFileIsUsed(&mod->used, ad, FALSE);
735 dcd = getProxy(mod, dcd);
736 ct->no_typehint = TRUE;
737 }
738
739 ifaceFileIsUsed(&dcd->iff->used, ad, FALSE);
740
741 ct->pysig.nrArgs = 1;
742
743 /* Append it to the list. */
744 for (ctp = &dcd->ctors; *ctp != NULL; ctp = &(*ctp)->next)
745 if (sameSignature(&(*ctp)->pysig, &ct->pysig, FALSE))
746 {
747 fatalAppend("operator ");
748 fatalScopedName(classFQCName(dcd));
749 fatalAppend("::");
750 fatalScopedName(classFQCName(dcd));
751 fatalAppend("(");
752 fatalScopedName(classFQCName(cd));
753 fatal(") already defined\n");
754 }
755
756 *ctp = ct;
757 }
758 }
759
760
761 /*
762 * If possible, move a global slot to its correct class.
763 */
moveGlobalSlot(sipSpec * pt,moduleDef * mod,memberDef * gmd)764 static void moveGlobalSlot(sipSpec *pt, moduleDef *mod, memberDef *gmd)
765 {
766 overDef **odp = &mod->overs, *od;
767
768 while ((od = *odp) != NULL)
769 {
770 int second;
771 argDef *arg0, *arg1;
772 memberDef *md, **mdhead;
773 overDef **odhead;
774 moduleDef *mod;
775 enumDef *ed;
776
777 if (od->common != gmd)
778 {
779 odp = &od->next;
780 continue;
781 }
782
783 /*
784 * We know that the slot has the right number of arguments, but the
785 * first or second one needs to be a class or enum defined in the same
786 * module. Otherwise we leave it as it is and publish it as a slot
787 * extender.
788 */
789 arg0 = &od->pysig.args[0];
790 arg1 = &od->pysig.args[1];
791
792 mdhead = NULL;
793 second = FALSE;
794 ed = NULL;
795
796 if (arg0->atype == class_type)
797 {
798 mdhead = &arg0->u.cd->members;
799 odhead = &arg0->u.cd->overs;
800 mod = arg0->u.cd->iff->module;
801 }
802 else if (arg0->atype == mapped_type)
803 {
804 classDef *cd = findAltClassImplementation(pt, arg0->u.mtd);
805
806 if (cd != NULL)
807 {
808 mdhead = &cd->members;
809 odhead = &cd->overs;
810 mod = cd->iff->module;
811 }
812 }
813 else if (arg0->atype == enum_type)
814 {
815 mdhead = &arg0->u.ed->slots;
816 odhead = &arg0->u.ed->overs;
817 mod = arg0->u.ed->module;
818 ed = arg0->u.ed;
819 }
820 else if (arg1->atype == class_type)
821 {
822 mdhead = &arg1->u.cd->members;
823 odhead = &arg1->u.cd->overs;
824 mod = arg1->u.cd->iff->module;
825 second = TRUE;
826 }
827 else if (arg1->atype == mapped_type)
828 {
829 classDef *cd = findAltClassImplementation(pt, arg1->u.mtd);
830
831 if (cd != NULL)
832 {
833 mdhead = &cd->members;
834 odhead = &cd->overs;
835 mod = cd->iff->module;
836 second = TRUE;
837 }
838 }
839 else if (arg1->atype == enum_type)
840 {
841 mdhead = &arg1->u.ed->slots;
842 odhead = &arg1->u.ed->overs;
843 mod = arg1->u.ed->module;
844 ed = arg1->u.ed;
845 second = TRUE;
846 }
847
848 if (mdhead == NULL)
849 {
850 fatalAppend("%s:%d: One of the arguments of ", od->sloc.name,
851 od->sloc.linenr);
852 prOverloadName(NULL, od);
853 fatal(" must be a class or enum\n");
854 }
855
856 /*
857 * For rich comparisons the first argument must be a class or an enum.
858 * For cross-module slots then it may only be a class. (This latter
859 * limitation is artificial, but is unlikely to be a problem in
860 * practice.)
861 */
862 if (isRichCompareSlot(gmd))
863 {
864 if (second)
865 {
866 fatalAppend("%s:%d: Argument 1 of ", od->sloc.name,
867 od->sloc.linenr);
868 prOverloadName(NULL, od);
869 fatal(" must be a class or enum\n");
870 }
871
872 if (mod != gmd->module && arg0->atype == enum_type)
873 {
874 fatalAppend("%s:%d: Argument 1 of ", od->sloc.name,
875 od->sloc.linenr);
876 prOverloadName(NULL, od);
877 fatal(" must be a class\n");
878 }
879 }
880
881 if (mod != gmd->module)
882 {
883 if (isRichCompareSlot(gmd))
884 {
885 classDef *pcd = getProxy(mod, arg0->u.cd);
886 memberDef *pmd;
887 overDef *pod;
888
889 /* Create a new proxy member if needed. */
890 for (pmd = pcd->members; pmd != NULL; pmd = pmd->next)
891 if (pmd->slot == gmd->slot)
892 break;
893
894 if (pmd == NULL)
895 {
896 pmd = sipMalloc(sizeof (memberDef));
897
898 pmd->pyname = gmd->pyname;
899 pmd->memberflags = 0;
900 pmd->slot = gmd->slot;
901 pmd->module = mod;
902 pmd->ns_scope = gmd->ns_scope;
903 pmd->next = pcd->members;
904
905 pcd->members = pmd;
906 }
907
908 /* Add the proxy overload. */
909 pod = sipMalloc(sizeof (overDef));
910
911 *pod = *od;
912 pod->no_typehint = TRUE;
913 pod->common = pmd;
914 pod->next = pcd->overs;
915
916 pcd->overs = pod;
917
918 /* Remove the first argument. */
919 pod->pysig.args[0] = pod->pysig.args[1];
920 pod->pysig.nrArgs = 1;
921
922 /* Remove from the list. */
923 *odp = od->next;
924 }
925 else
926 odp = &od->next;
927
928 continue;
929 }
930
931 /* Remove from the list. */
932 *odp = od->next;
933
934 if (ed != NULL)
935 {
936 ifaceFileDef *enum_iff = getIfaceFileForEnum(ed);
937
938 /* The slot code is generated at the module level. */
939 if (enum_iff != NULL)
940 appendToIfaceFileList(&mod->used, enum_iff);
941
942 setIsUsedName(ed->pyname);
943 }
944
945 /* See if there is already a member or create a new one. */
946 for (md = *mdhead; md != NULL; md = md->next)
947 if (md->slot == gmd->slot)
948 break;
949
950 if (md == NULL)
951 {
952 md = sipMalloc(sizeof (memberDef));
953
954 *md = *gmd;
955
956 md->module = mod;
957 md->next = *mdhead;
958
959 *mdhead = md;
960 }
961
962 /* Move the overload to the end of the destination list. */
963 if (second)
964 setIsReflected(od);
965
966 setIsPublic(od);
967 setIsGlobal(od);
968 od->common = md;
969 od->next = NULL;
970
971 while (*odhead != NULL)
972 odhead = &(*odhead)->next;
973
974 *odhead = od;
975
976 /*
977 * Remove the first argument of inplace numeric operators and
978 * comparison operators.
979 */
980 if (isInplaceNumberSlot(md) || isRichCompareSlot(md))
981 {
982 /* Remember if the argument was a pointer. */
983 if (arg0->nrderefs > 0)
984 setDontDerefSelf(od);
985
986 *arg0 = *arg1;
987 od->pysig.nrArgs = 1;
988 }
989
990 /* Remove the only argument of unary operators. */
991 if (isZeroArgSlot(md))
992 od->pysig.nrArgs = 0;
993 }
994 }
995
996
997 /*
998 * Return an alternative class implementation of a mapped type if there is
999 * one. Note that we cheat as we assume there is one going to be one (as
1000 * there will be in PyQt at the moment).
1001 */
findAltClassImplementation(sipSpec * pt,mappedTypeDef * mtd)1002 static classDef *findAltClassImplementation(sipSpec *pt, mappedTypeDef *mtd)
1003 {
1004 ifaceFileDef *iff = mtd->iff->first_alt;
1005
1006 while (iff != NULL)
1007 {
1008 if (iff->type == class_iface)
1009 {
1010 classDef *cd;
1011
1012 for (cd = pt->classes; cd != NULL; cd = cd->next)
1013 if (cd->iff == iff)
1014 return cd;
1015 }
1016
1017 iff = iff->next_alt;
1018 }
1019
1020 return NULL;
1021 }
1022
1023
1024 /*
1025 * Create a proxy for a class if it doesn't already exist. Proxies are used as
1026 * containers for cross-module extenders.
1027 */
getProxy(moduleDef * mod,classDef * cd)1028 static classDef *getProxy(moduleDef *mod, classDef *cd)
1029 {
1030 classDef *pcd;
1031
1032 for (pcd = mod->proxies; pcd != NULL; pcd = pcd->next)
1033 if (pcd->iff == cd->iff)
1034 return pcd;
1035
1036 pcd = sipMalloc(sizeof (classDef));
1037
1038 pcd->pyname = cd->pyname;
1039 pcd->iff = cd->iff;
1040 pcd->ecd = cd->ecd;
1041 pcd->real = cd;
1042 pcd->supers = cd->supers;
1043 pcd->mro = cd->mro;
1044 pcd->next = mod->proxies;
1045
1046 mod->proxies = pcd;
1047
1048 return pcd;
1049 }
1050
1051
1052 /*
1053 * Add an overload that is automatically generated (typically by Qt's moc).
1054 */
addAutoOverload(sipSpec * pt,classDef * autocd,overDef * autood)1055 static void addAutoOverload(sipSpec *pt,classDef *autocd,overDef *autood)
1056 {
1057 classDef *cd;
1058
1059 /* Find every class that has this one in its hierarchy. */
1060
1061 for (cd = pt -> classes; cd != NULL; cd = cd -> next)
1062 {
1063 mroDef *mro;
1064
1065 if (cd == autocd)
1066 continue;
1067
1068 for (mro = cd -> mro; mro != NULL; mro = mro -> next)
1069 if (mro -> cd == autocd)
1070 {
1071 memberDef *md;
1072 overDef *od;
1073
1074 /* Another overload may already exist. */
1075
1076 for (md = cd -> members; md != NULL; md = md -> next)
1077 if (md -> pyname == autood -> common -> pyname)
1078 break;
1079
1080 if (md == NULL)
1081 {
1082 md = sipMalloc(sizeof (memberDef));
1083
1084 md -> pyname = autood -> common -> pyname;
1085 md -> memberflags = autood -> common -> memberflags;
1086 md -> slot = autood -> common -> slot;
1087 md -> module = cd -> iff -> module;
1088 md -> next = cd -> members;
1089 cd -> members = md;
1090 }
1091
1092 od = sipMalloc(sizeof (overDef));
1093
1094 *od = *autood;
1095 od -> common = md;
1096 od -> next = cd -> overs;
1097 cd -> overs = od;
1098
1099 resetIsAutoGen(od);
1100
1101 if (generatingCodeForModule(pt, cd->iff->module))
1102 setIsUsedName(md -> pyname);
1103
1104 break;
1105 }
1106 }
1107 }
1108
1109
1110 /*
1111 * Set the complete hierarchy for a class.
1112 */
setHierarchy(sipSpec * pt,classDef * base,classDef * cd,classList ** head)1113 static void setHierarchy(sipSpec *pt, classDef *base, classDef *cd,
1114 classList **head)
1115 {
1116 /* See if it has already been done. */
1117 if (cd->mro != NULL)
1118 return;
1119
1120 if (cd->ecd != NULL)
1121 {
1122 setHierarchy(pt, base, cd->ecd, head);
1123
1124 if (isDeprecatedClass(cd->ecd))
1125 setIsDeprecatedClass(cd);
1126 }
1127
1128 if (cd->iff->type == class_iface)
1129 {
1130 classList *cl;
1131
1132 /* The first thing is itself. */
1133 cd->mro = newMRO(cd);
1134
1135 if (cd->convtosubcode != NULL)
1136 cd->subbase = cd;
1137
1138 /* Now do it's superclasses. */
1139 setHierBeingSet(cd->mro);
1140
1141 for (cl = cd->supers; cl != NULL; cl = cl->next)
1142 {
1143 mroDef *mro;
1144
1145 if (cl->cd->mro != NULL && hierBeingSet(cl->cd->mro))
1146 {
1147 fatalAppend("Recursive class hierarchy detected: ");
1148 fatalScopedName(classFQCName(cd));
1149 fatalAppend(" and ");
1150 fatalScopedName(classFQCName(cl->cd));
1151 fatal("\n");
1152 }
1153
1154 /* Make sure the super-class's hierarchy has been done. */
1155 setHierarchy(pt, base, cl->cd, head);
1156
1157 /* Append the super-classes hierarchy. */
1158 for (mro = cl->cd->mro; mro != NULL; mro = mro->next)
1159 {
1160 mroDef **tailp;
1161
1162 /* See if the class is already in the hierarchy. */
1163 for (tailp = &cd->mro->next; *tailp != NULL; tailp = &(*tailp)->next)
1164 {
1165 if ((*tailp)->cd == mro->cd)
1166 {
1167 setInADiamond(*tailp);
1168 break;
1169 }
1170 }
1171
1172 if (*tailp == NULL)
1173 {
1174 *tailp = newMRO(mro->cd);
1175
1176 if (inADiamond(mro))
1177 setInADiamond(*tailp);
1178 }
1179
1180 if (generatingCodeForModule(pt, cd->iff->module))
1181 mro->cd->iff->first_alt->needed = TRUE;
1182
1183 if (isDeprecatedClass(mro->cd))
1184 setIsDeprecatedClass(cd);
1185
1186 /*
1187 * If the super-class is a QObject sub-class then this one is
1188 * as well.
1189 */
1190 if (isQObjectSubClass(mro->cd))
1191 setIsQObjectSubClass(cd);
1192
1193 /*
1194 * If the super-class can't be assigned to then this one
1195 * cannot either.
1196 */
1197 if (cannotAssign(mro->cd))
1198 setCannotAssign(cd);
1199
1200 /*
1201 * If the super-class needs a shadow then this one should have
1202 * one as well.
1203 */
1204 if (needsShadow(mro->cd))
1205 setNeedsShadow(cd);
1206
1207 /*
1208 * Ensure that the sub-class base class is the furthest up the
1209 * hierarchy.
1210 */
1211 if (mro->cd->subbase != NULL)
1212 cd->subbase = mro->cd->subbase;
1213 }
1214 }
1215
1216 resetHierBeingSet(cd->mro);
1217
1218 /*
1219 * If the class doesn't have an explicit meta-type then inherit from
1220 * the module's default.
1221 */
1222 if (cd->metatype == NULL && cd->supers == NULL)
1223 cd->metatype = cd->iff->module->defmetatype;
1224
1225 if (cd->metatype != NULL && generatingCodeForModule(pt, cd->iff->module))
1226 setIsUsedName(cd->metatype);
1227
1228 /*
1229 * If the class doesn't have an explicit super-type then inherit from
1230 * the module's default.
1231 */
1232 if (cd->supertype == NULL && cd->supers == NULL)
1233 cd->supertype = cd->iff->module->defsupertype;
1234
1235 if (cd->supertype != NULL && strcmp(cd->supertype->text, "sip.wrapper") == 0)
1236 cd->supertype = NULL;
1237
1238 if (cd->supertype != NULL && generatingCodeForModule(pt, cd->iff->module))
1239 setIsUsedName(cd->supertype);
1240 }
1241
1242 /*
1243 * Make sure that the module in which a sub-class convertor will be created
1244 * knows about the base class.
1245 */
1246 if (cd->subbase != NULL)
1247 appendToIfaceFileList(&cd->iff->module->used, cd->subbase->iff);
1248
1249 /*
1250 * We can't have a shadow if the specification is incomplete, there is a
1251 * private dtor, there are no non-private ctors or there are private
1252 * abstract methods.
1253 */
1254 if (isIncomplete(cd) || isPrivateDtor(cd) || !canCreate(cd))
1255 {
1256 resetHasShadow(cd);
1257 }
1258 else
1259 {
1260 overDef *od;
1261
1262 /*
1263 * Note that we should be able to provide better support for abstract
1264 * private methods than we do at the moment.
1265 */
1266 for (od = cd->overs; od != NULL; od = od->next)
1267 if (isAbstract(od) && isPrivate(od))
1268 {
1269 resetHasShadow(cd);
1270
1271 /* It also means we cannot create an instance from Python. */
1272 resetCanCreate(cd);
1273
1274 break;
1275 }
1276 }
1277
1278 /* Add it to the new list. */
1279 appendToClassList(head,cd);
1280 }
1281
1282
1283 /*
1284 * Create an MRO entry for a class.
1285 */
newMRO(classDef * cd)1286 static mroDef *newMRO(classDef *cd)
1287 {
1288 mroDef *mro;
1289
1290 mro = sipMalloc(sizeof (mroDef));
1291
1292 mro -> cd = cd;
1293 mro -> mroflags = 0;
1294 mro -> next = NULL;
1295
1296 return mro;
1297 }
1298
1299
1300 /*
1301 * Get the base types for all typedefs of a module.
1302 */
transformTypedefs(sipSpec * pt,moduleDef * mod)1303 static void transformTypedefs(sipSpec *pt, moduleDef *mod)
1304 {
1305 typedefDef *td;
1306
1307 for (td = pt->typedefs; td != NULL; td = td->next)
1308 if (td->module == mod)
1309 if (td->ecd == NULL || !isTemplateClass(td->ecd))
1310 resolveType(pt, td->module, td->ecd, &td->type, FALSE);
1311 }
1312
1313
1314 /*
1315 * Transform the data types for mapped types based on a template.
1316 */
transformMappedTypes(sipSpec * pt,int strict,moduleDef * mod)1317 static void transformMappedTypes(sipSpec *pt, int strict, moduleDef *mod)
1318 {
1319 mappedTypeDef *mt;
1320
1321 for (mt = pt->mappedtypes; mt != NULL; mt = mt->next)
1322 {
1323 if (mt->iff->module == mod)
1324 {
1325 if (mt->type.atype == template_type)
1326 resolveMappedTypeTypes(pt, mt);
1327 else
1328 transformScopeOverloads(pt, strict, NULL, mt, mt->overs);
1329 }
1330 }
1331 }
1332
1333
1334 /*
1335 * Transform the data types for a list of ctors.
1336 */
transformCtors(sipSpec * pt,classDef * cd)1337 static void transformCtors(sipSpec *pt, classDef *cd)
1338 {
1339 ctorDef *ct;
1340
1341 for (ct = cd->ctors; ct != NULL; ct = ct->next)
1342 {
1343 ctorDef *prev;
1344
1345 resolveCtorTypes(pt, cd, ct);
1346
1347 /*
1348 * Now check that the Python signature doesn't conflict with an
1349 * earlier one. If there is %MethodCode then assume that it will
1350 * handle any potential conflicts.
1351 */
1352 if (ct->methodcode == NULL)
1353 {
1354 for (prev = cd->ctors; prev != ct; prev = prev->next)
1355 {
1356 if (prev->methodcode != NULL)
1357 continue;
1358
1359 if (samePythonSignature(&prev->pysig, &ct->pysig))
1360 {
1361 fatalScopedName(classFQCName(cd));
1362 fatal(" has ctors with the same Python signature\n");
1363 }
1364 }
1365 }
1366
1367 if (isDeprecatedClass(cd))
1368 setIsDeprecatedCtor(ct);
1369 }
1370 }
1371
1372
1373 /*
1374 * Transform the data type for a list of casts.
1375 */
transformCasts(sipSpec * pt,classDef * cd)1376 static void transformCasts(sipSpec *pt, classDef *cd)
1377 {
1378 argList *al;
1379
1380 for (al = cd->casts; al != NULL; al = al->next)
1381 {
1382 classDef *dcd;
1383
1384 resolveType(pt, cd->iff->module, cd, &al->arg, FALSE);
1385
1386 if (al->arg.atype == class_type)
1387 dcd = al->arg.u.cd;
1388 else if (al->arg.atype == mapped_type)
1389 dcd = findAltClassImplementation(pt, al->arg.u.mtd);
1390 else
1391 dcd = NULL;
1392
1393 if (dcd == NULL)
1394 {
1395 fatalScopedName(classFQCName(cd));
1396 fatal(" operator cast must be to a class\n");
1397 }
1398 }
1399 }
1400
1401
1402 /*
1403 * Add a default copy ctor if required.
1404 */
addDefaultCopyCtor(classDef * cd)1405 static void addDefaultCopyCtor(classDef *cd)
1406 {
1407 ctorDef *copyct, **tailp;
1408 mroDef *mro;
1409
1410 /* See if there is a private copy ctor in the hierarchy. */
1411 for (mro = cd->mro; mro != NULL; mro = mro->next)
1412 {
1413 ctorDef *ct;
1414
1415 for (ct = mro->cd->ctors; ct != NULL; ct = ct->next)
1416 {
1417 argDef *ad = &ct -> pysig.args[0];
1418
1419 /* See if is a copy ctor. */
1420 if (ct->pysig.nrArgs == 1 && ad->nrderefs == 0 && isReference(ad))
1421 {
1422 ifaceFileDef *iff;
1423
1424 /* To check the type we have to look at all versions. */
1425 if (ad->atype == class_type)
1426 iff = ad->u.cd->iff;
1427 else if (ad->atype == mapped_type)
1428 iff = ad->u.mtd->iff;
1429 else
1430 continue;
1431
1432 for (iff = iff->first_alt; iff != NULL; iff = iff->next_alt)
1433 if (mro->cd->iff == iff)
1434 break;
1435
1436 if (iff != NULL)
1437 break;
1438 }
1439 }
1440
1441 if (ct != NULL)
1442 {
1443 /* If the copy ctor is private then the class can't be copied. */
1444 if (isPrivateCtor(ct))
1445 {
1446 setCannotCopy(cd);
1447 return;
1448 }
1449
1450 /*
1451 * If the ctor is in the class itself then there is nothing to do.
1452 */
1453 if (mro == cd->mro)
1454 return;
1455
1456 /* Otherwise we need to create a default. */
1457 break;
1458 }
1459 }
1460
1461 /* Create a default public copy ctor. */
1462 copyct = sipMalloc(sizeof (ctorDef));
1463
1464 copyct->ctorflags = SECT_IS_PUBLIC;
1465 copyct->pysig.nrArgs = 1;
1466 copyct->pysig.result.atype = void_type;
1467 copyct->pysig.args[0].atype = class_type;
1468 copyct->pysig.args[0].u.cd = cd;
1469 copyct->pysig.args[0].argflags = (ARG_IS_REF | ARG_IS_CONST | ARG_IN);
1470 copyct->pysig.args[0].nrderefs = 0;
1471 copyct->pysig.args[0].defval = NULL;
1472
1473 copyct->cppsig = ©ct->pysig;
1474
1475 if (isDeprecatedClass(cd))
1476 setIsDeprecatedCtor(copyct);
1477
1478 if (!isAbstractClass(cd))
1479 setCanCreate(cd);
1480
1481 /* Append it to the list. */
1482 for (tailp = &cd->ctors; *tailp != NULL; tailp = &(*tailp)->next)
1483 ;
1484
1485 *tailp = copyct;
1486 }
1487
1488
1489 /*
1490 * Transform the data types for a list of overloads.
1491 */
transformScopeOverloads(sipSpec * pt,int strict,classDef * c_scope,mappedTypeDef * mt_scope,overDef * overs)1492 static void transformScopeOverloads(sipSpec *pt, int strict, classDef *c_scope,
1493 mappedTypeDef *mt_scope, overDef *overs)
1494 {
1495 overDef *od;
1496
1497 for (od = overs; od != NULL; od = od->next)
1498 {
1499 overDef *prev;
1500
1501 resolveFuncTypes(pt, od->common->module, c_scope, od);
1502
1503 /*
1504 * Now check that the Python signature doesn't conflict with an earlier
1505 * one. If there is %MethodCode then assume that it will handle any
1506 * potential conflicts.
1507 */
1508 if (od->methodcode == NULL && strict)
1509 {
1510 for (prev = overs; prev != od; prev = prev->next)
1511 {
1512 if (prev->common != od->common)
1513 continue;
1514
1515 if (prev->methodcode != NULL)
1516 continue;
1517
1518 /* They can only conflict if one is unversioned. */
1519 if (prev->api_range != NULL && od->api_range != NULL)
1520 continue;
1521
1522 if (samePythonSignature(&prev->pysig, &od->pysig))
1523 {
1524 ifaceFileDef *iff;
1525
1526 fatalAppend("%s:%d: ", od->sloc.name, od->sloc.linenr);
1527
1528 if (mt_scope != NULL)
1529 iff = mt_scope->iff;
1530 else if (c_scope != NULL)
1531 iff = c_scope->iff;
1532 else
1533 iff = NULL;
1534
1535 if (iff != NULL)
1536 {
1537 fatalScopedName(iff->fqcname);
1538 fatalAppend("::");
1539 }
1540
1541 fatal("%s() has overloaded functions with the same Python signature\n", od->common->pyname->text);
1542 }
1543 }
1544 }
1545
1546 if (c_scope != NULL)
1547 {
1548 if (isDeprecatedClass(c_scope))
1549 setIsDeprecated(od);
1550
1551 if (isAbstract(od))
1552 setIsAbstractClass(c_scope);
1553 }
1554 }
1555 }
1556
1557
1558 /*
1559 * Transform the data types for the variables of a module.
1560 */
transformVariableList(sipSpec * pt,moduleDef * mod)1561 static void transformVariableList(sipSpec *pt, moduleDef *mod)
1562 {
1563 varDef *vd;
1564
1565 for (vd = pt->vars; vd != NULL; vd = vd->next)
1566 if (vd->module == mod)
1567 if (vd->ecd == NULL || !isTemplateClass(vd->ecd))
1568 resolveVariableType(pt, vd);
1569 }
1570
1571
1572 /*
1573 * Set the list of visible Python member functions for a class.
1574 */
getVisiblePyMembers(sipSpec * pt,classDef * cd)1575 static void getVisiblePyMembers(sipSpec *pt, classDef *cd)
1576 {
1577 mroDef *mro;
1578
1579 cd->visible = NULL;
1580
1581 for (mro = cd->mro; mro != NULL; mro = mro->next)
1582 {
1583 memberDef *md;
1584 classDef *mro_cd;
1585
1586 mro_cd = mro->cd;
1587
1588 for (md = mro_cd->members; md != NULL; md = md->next)
1589 {
1590 visibleList *vl;
1591
1592 /*
1593 * See if it is already in the list. This has the desired side
1594 * effect of eliminating any functions that have an implementation
1595 * closer to this class in the hierarchy. This is the only reason
1596 * to define private functions.
1597 */
1598 for (vl = cd->visible; vl != NULL; vl = vl->next)
1599 if (vl->m->pyname == md->pyname)
1600 break;
1601
1602 /* See if it is a new member function. */
1603 if (vl == NULL)
1604 {
1605 overDef *od;
1606
1607 vl = sipMalloc(sizeof (visibleList));
1608
1609 vl->m = md;
1610 vl->cd = mro_cd;
1611 vl->next = cd->visible;
1612
1613 cd->visible = vl;
1614
1615 for (od = mro_cd->overs; od != NULL; od = od->next)
1616 if (od->common == md)
1617 {
1618 int need_types = FALSE;
1619
1620 /*
1621 * If the visible overload is abstract then it hasn't
1622 * had a concrete implementation so this class must
1623 * also be abstract.
1624 */
1625 if (isAbstract(od))
1626 setIsAbstractClass(cd);
1627
1628 if (generatingCodeForModule(pt, cd->iff->module) && (cd == mro_cd || (isProtected(od) && hasShadow(cd))))
1629 {
1630 need_types = TRUE;
1631
1632 setIsUsedName(md->pyname);
1633
1634 /* Make sure we have any API name. */
1635 if (od->api_range != NULL)
1636 setIsUsedName(od->api_range->api_name);
1637 }
1638
1639 ifaceFilesAreUsedByOverload(&cd->iff->used, od,
1640 need_types);
1641 }
1642 }
1643 }
1644 }
1645 }
1646
1647
1648 /*
1649 * Get all the virtuals for a particular class.
1650 */
getVirtuals(sipSpec * pt,classDef * cd)1651 static void getVirtuals(sipSpec *pt, classDef *cd)
1652 {
1653 classList *cl;
1654 overDef *od;
1655
1656 /*
1657 * Copy the collected virtuals of each super-class updating from what we
1658 * find in this class.
1659 */
1660 for (cl = cd->supers; cl != NULL; cl = cl->next)
1661 {
1662 virtOverDef *s_vod;
1663
1664 for (s_vod = cl->cd->vmembers; s_vod != NULL; s_vod = s_vod->next)
1665 {
1666 int implicit = TRUE;
1667
1668 for (od = cd->overs; od != NULL; od = od->next)
1669 {
1670 if (strcmp(s_vod->od->cppname, od->cppname) != 0)
1671 continue;
1672
1673 implicit = FALSE;
1674
1675 if (isFinal(od))
1676 break;
1677
1678 /* See if it re-implements rather than hides. */
1679 if (sameCppOverload(s_vod->od, od))
1680 {
1681 // What if is is private?
1682 setIsVirtual(od);
1683 setIsVirtualReimp(od);
1684
1685 /*
1686 * Use the base implementation's virtual handler code if
1687 * there is any. We cannot just use it's virtual handler
1688 * because this re-implementation may have different
1689 * annotations which means the complete handler would be
1690 * different. In practice there is no reason why it
1691 * would be different (and maybe this should be detected as
1692 * an error) but if they are the same then the same handler
1693 * will eventually be chosen.
1694 */
1695 if (od->virtcode == NULL)
1696 od->virtcode = s_vod->od->virtcode;
1697
1698 /*
1699 * Use the base implementation's virtual error handler if
1700 * one isn't explicitly specified.
1701 */
1702 if (od->virt_error_handler == NULL)
1703 od->virt_error_handler = s_vod->od->virt_error_handler;
1704
1705 addVirtual(pt, od, cd);
1706 }
1707 }
1708
1709 /* Add it if it wasn't explcitly mentioned in the class. */
1710 if (implicit)
1711 addVirtual(pt, s_vod->od, cd);
1712 }
1713 }
1714
1715 /* Handle any new virtuals. */
1716 for (od = cd->overs; od != NULL; od = od->next)
1717 if (isVirtual(od) && !isVirtualReimp(od) && !isFinal(od))
1718 addVirtual(pt, od, cd);
1719 }
1720
1721
1722 /*
1723 * Add an overload to the list of virtuals for a class.
1724 */
addVirtual(sipSpec * pt,overDef * od,classDef * cd)1725 static void addVirtual(sipSpec *pt, overDef *od, classDef *cd)
1726 {
1727 virtHandlerDef *vhd;
1728 virtOverDef *vod;
1729
1730 /*
1731 * If this class is defined in the main module then make sure the virtuals
1732 * have a handler.
1733 */
1734 if (generatingCodeForModule(pt, cd->iff->module))
1735 {
1736 vhd = getVirtualHandler(pt, od, cd);
1737
1738 /* Make sure we get the name. */
1739 setIsUsedName(od->common->pyname);
1740
1741 /*
1742 * Make sure we have the interface files and type definitions for the
1743 * virtual handler.
1744 */
1745 ifaceFilesAreUsedByOverload(&pt->module->used, od, TRUE);
1746 }
1747 else
1748 {
1749 vhd = NULL;
1750 }
1751
1752 /* Add it to the class. */
1753 vod = sipMalloc(sizeof (virtOverDef));
1754 vod->od = od;
1755 vod->virthandler = vhd;
1756 vod->next = cd->vmembers;
1757
1758 cd->vmembers = vod;
1759 }
1760
1761 /*
1762 * Get the virtual error handler for a function.
1763 */
getVirtErrorHandler(sipSpec * pt,overDef * od,classDef * cd)1764 static virtErrorHandler *getVirtErrorHandler(sipSpec *pt, overDef *od,
1765 classDef *cd)
1766 {
1767 const char *name;
1768 virtErrorHandler *veh;
1769 moduleDef *mod = cd->iff->module;
1770
1771 /* Handle the trivial case. */
1772 if (noErrorHandler(od))
1773 return NULL;
1774
1775 /* Check the function itself. */
1776 if ((name = od->virt_error_handler) == NULL)
1777 {
1778 mroDef *mro;
1779
1780 /* Check the class hierarchy. */
1781 for (mro = cd->mro; mro != NULL; mro = mro->next)
1782 if ((name = mro->cd->virt_error_handler) != NULL)
1783 break;
1784
1785 if (name == NULL)
1786 {
1787 /* Check the class's module. */
1788 if ((name = mod->virt_error_handler) == NULL)
1789 {
1790 moduleListDef *mld;
1791
1792 /* Check the module hierarchy. */
1793 for (mld = mod->allimports; mld != NULL; mld = mld->next)
1794 if ((name = mld->module->virt_error_handler) != NULL)
1795 break;
1796 }
1797 }
1798 }
1799
1800 if (name == NULL)
1801 return NULL;
1802
1803 /* Find the handler with the name. */
1804 for (veh = pt->errorhandlers; veh != NULL; veh = veh->next)
1805 if (strcmp(veh->name, name) == 0)
1806 break;
1807
1808 if (veh == NULL)
1809 fatal("Unknown virtual error handler \"%s\"\n", name);
1810
1811 /* Assign it an index if we need to import the handler. */
1812 if (mod != veh->mod && veh->index < 0)
1813 veh->index = veh->mod->nrvirterrorhandlers++;
1814
1815 return veh;
1816 }
1817
1818
1819 /*
1820 * Get the virtual handler for an overload.
1821 */
getVirtualHandler(sipSpec * pt,overDef * od,classDef * cd)1822 static virtHandlerDef *getVirtualHandler(sipSpec *pt, overDef *od, classDef *cd)
1823 {
1824 virtHandlerDef *vhd;
1825
1826 /* See if there is an existing handler that is suitable. */
1827 for (vhd = pt->virthandlers; vhd != NULL; vhd = vhd->next)
1828 if (checkVirtualHandler(od, vhd))
1829 return vhd;
1830
1831 /* Create a new one. */
1832 vhd = sipMalloc(sizeof (virtHandlerDef));
1833
1834 vhd->virthandlernr = pt->nrvirthandlers++;
1835
1836 if (isFactory(od) || isResultTransferredBack(od))
1837 setIsTransferVH(vhd);
1838
1839 if (abortOnException(od))
1840 setAbortOnExceptionVH(vhd);
1841
1842 vhd->pysig = &od->pysig;
1843 vhd->cppsig = od->cppsig;
1844 vhd->virtcode = od->virtcode;
1845 vhd->veh = getVirtErrorHandler(pt, od, cd);
1846
1847 vhd->next = pt->virthandlers;
1848 pt->virthandlers = vhd;
1849
1850 return vhd;
1851 }
1852
1853
1854 /*
1855 * See if a virtual handler is appropriate for an overload.
1856 */
checkVirtualHandler(overDef * od,virtHandlerDef * vhd)1857 static int checkVirtualHandler(overDef *od, virtHandlerDef *vhd)
1858 {
1859 int a;
1860
1861 if (od->virtcode != vhd->virtcode)
1862 return FALSE;
1863
1864 /*
1865 * If the overload has an explicit error handler then it must be the same
1866 * as the candidate.
1867 */
1868 if (od->virt_error_handler != NULL)
1869 {
1870 if (vhd->veh == NULL || strcmp(od->virt_error_handler, vhd->veh->name) != 0)
1871 return FALSE;
1872 }
1873
1874 if ((isFactory(od) || isResultTransferredBack(od)) && !isTransferVH(vhd))
1875 return FALSE;
1876
1877 if (!abortOnException(od) != !abortOnExceptionVH(vhd))
1878 return FALSE;
1879
1880 if (!sameArgType(&od->pysig.result, &vhd->pysig->result, TRUE))
1881 return FALSE;
1882
1883 if (isAllowNone(&od->pysig.result) != isAllowNone(&vhd->pysig->result))
1884 return FALSE;
1885
1886 if (isDisallowNone(&od->pysig.result) != isDisallowNone(&vhd->pysig->result))
1887 return FALSE;
1888
1889 if (!sameSignature(&od->pysig, vhd->pysig, TRUE))
1890 return FALSE;
1891
1892 /* Take into account the argument directions in the Python signatures. */
1893 for (a = 0; a < od->pysig.nrArgs; ++a)
1894 {
1895 int dir1 = (od->pysig.args[a].argflags & (ARG_IN | ARG_OUT));
1896 int dir2 = (vhd->pysig->args[a].argflags & (ARG_IN | ARG_OUT));
1897
1898 if (dir1 != dir2)
1899 return FALSE;
1900 }
1901
1902 if (&od->pysig == od->cppsig && vhd->pysig == vhd->cppsig)
1903 return TRUE;
1904
1905 if (!sameArgType(&od->cppsig->result, &vhd->cppsig->result, TRUE))
1906 return FALSE;
1907
1908 return sameSignature(od->cppsig, vhd->cppsig, TRUE);
1909 }
1910
1911
1912 /*
1913 * Resolve the types of a mapped type based on a template.
1914 */
resolveMappedTypeTypes(sipSpec * pt,mappedTypeDef * mt)1915 static void resolveMappedTypeTypes(sipSpec *pt, mappedTypeDef *mt)
1916 {
1917 int a;
1918 signatureDef *sd = &mt->type.u.td->types;
1919
1920 for (a = 0; a < sd->nrArgs; ++a)
1921 {
1922 argDef *ad = &sd->args[a];
1923
1924 /* Leave templates as they are. */
1925 if (ad->atype != template_type)
1926 resolveType(pt, mt->iff->module, NULL, ad, TRUE);
1927 }
1928
1929 /* Make sure that the signature result won't cause problems. */
1930 sd->result.atype = no_type;
1931
1932 ifaceFilesAreUsedBySignature(&mt->iff->used, sd, FALSE);
1933 }
1934
1935
1936 /*
1937 * Resolve the types of a ctor.
1938 */
resolveCtorTypes(sipSpec * pt,classDef * scope,ctorDef * ct)1939 static void resolveCtorTypes(sipSpec *pt,classDef *scope,ctorDef *ct)
1940 {
1941 int a;
1942
1943 /* Handle any exceptions. */
1944 setNeededExceptions(pt, scope->iff->module, ct->exceptions);
1945
1946 /* Handle any C++ signature. */
1947 if (ct->cppsig != NULL && ct->cppsig != &ct->pysig)
1948 for (a = 0; a < ct -> cppsig -> nrArgs; ++a)
1949 resolveType(pt, scope->iff->module, scope, &ct->cppsig->args[a],
1950 TRUE);
1951
1952 /* Handle the Python signature. */
1953 for (a = 0; a < ct -> pysig.nrArgs; ++a)
1954 {
1955 argDef *ad = &ct -> pysig.args[a];
1956
1957 resolveType(pt, scope->iff->module, scope, ad, FALSE);
1958
1959 if (!supportedType(scope,NULL,ad,FALSE))
1960 {
1961 fatalScopedName(classFQCName(scope));
1962 fatal(" ctor argument %d has an unsupported type for a Python signature - provide a valid type, %%MethodCode and a C++ signature\n", a + 1);
1963 }
1964
1965 ifaceFileIsUsed(&scope->iff->used, ad, FALSE);
1966 scopeDefaultValue(pt, scope, ad);
1967 }
1968 }
1969
1970
1971 /*
1972 * Resolve the types of a function.
1973 */
resolveFuncTypes(sipSpec * pt,moduleDef * mod,classDef * c_scope,overDef * od)1974 static void resolveFuncTypes(sipSpec *pt, moduleDef *mod, classDef *c_scope,
1975 overDef *od)
1976 {
1977 argDef *res;
1978
1979 /* Handle any exceptions. */
1980 setNeededExceptions(pt, mod, od->exceptions);
1981
1982 /* Handle any C++ signature. */
1983 if (od->cppsig != &od->pysig)
1984 {
1985 int a;
1986 argDef *res = &od->cppsig->result;
1987
1988 resolveType(pt, mod, c_scope, res, TRUE);
1989
1990 if ((res->atype != void_type || res->nrderefs != 0) && isVirtual(od) && !supportedType(c_scope, od, &od->cppsig->result, FALSE) && od->virtcode == NULL)
1991 {
1992 fatalAppend("%s:%d: ", od->sloc.name, od->sloc.linenr);
1993
1994 if (c_scope != NULL)
1995 {
1996 fatalScopedName(classFQCName(c_scope));
1997 fatalAppend("::");
1998 }
1999
2000 fatal("%s() unsupported virtual function return type - provide %%VirtualCatcherCode\n", od->cppname);
2001 }
2002
2003 for (a = 0; a < od->cppsig->nrArgs; ++a)
2004 resolveType(pt, mod, c_scope, &od->cppsig->args[a], TRUE);
2005 }
2006
2007 /* Handle the Python signature. */
2008 resolvePySigTypes(pt, mod, c_scope, od, &od->pysig, isSignal(od));
2009
2010 res = &od->pysig.result;
2011
2012 /* These slots must return Py_ssize_t. */
2013 if (isSSizeReturnSlot(od->common))
2014 if ((res->atype != ssize_type && res->atype != int_type) || res->nrderefs != 0 ||
2015 isReference(res) || isConstArg(res))
2016 fatal("%s:%d: %s slots must return Py_ssize_t\n", od->sloc.name,
2017 od->sloc.linenr, od->common->pyname->text);
2018
2019 /* These slots must return int. */
2020 if (isIntReturnSlot(od->common))
2021 if (res->atype != int_type || res->nrderefs != 0 ||
2022 isReference(res) || isConstArg(res))
2023 fatal("%s:%d: %s slots must return int\n", od->sloc.name,
2024 od->sloc.linenr, od->common->pyname->text);
2025
2026 /* These slots must return void. */
2027 if (isVoidReturnSlot(od->common))
2028 if (res->atype != void_type || res->nrderefs != 0 ||
2029 isReference(res) || isConstArg(res))
2030 fatal("%s:%d: %s slots must return void\n", od->sloc.name,
2031 od->sloc.linenr, od->common->pyname->text);
2032
2033 /* These slots must return long. */
2034 if (isLongReturnSlot(od->common))
2035 if (res->atype != long_type || res->nrderefs != 0 ||
2036 isReference(res) || isConstArg(res))
2037 fatal("%s:%d: %s slots must return long\n", od->sloc.name,
2038 od->sloc.linenr, od->common->pyname->text);
2039 }
2040
2041
2042 /*
2043 * Resolve the types of a Python signature.
2044 */
resolvePySigTypes(sipSpec * pt,moduleDef * mod,classDef * scope,overDef * od,signatureDef * pysig,int issignal)2045 static void resolvePySigTypes(sipSpec *pt, moduleDef *mod, classDef *scope,
2046 overDef *od, signatureDef *pysig, int issignal)
2047 {
2048 int a;
2049 argDef *res = &pysig -> result;
2050
2051 if (res -> atype != void_type || res -> nrderefs != 0)
2052 {
2053 if (issignal)
2054 {
2055 fatalAppend("%s:%d: ", od->sloc.name, od->sloc.linenr);
2056
2057 if (scope != NULL)
2058 {
2059 fatalScopedName(classFQCName(scope));
2060 fatalAppend("::");
2061 }
2062
2063 fatal("%s() signals must return void\n", od->cppname);
2064 }
2065
2066 resolveType(pt, mod, scope, res, FALSE);
2067
2068 /* Results must be simple. */
2069 if (!supportedType(scope, od, res, FALSE))
2070 {
2071 int need_meth;
2072
2073 need_meth = (od->cppsig == &od->pysig || od->methodcode == NULL);
2074
2075 if (need_meth)
2076 {
2077 fatalAppend("%s:%d: ", od->sloc.name, od->sloc.linenr);
2078
2079 if (scope != NULL)
2080 {
2081 fatalScopedName(classFQCName(scope));
2082 fatalAppend("::");
2083 }
2084
2085 fatal("%s() unsupported function return type - provide %%MethodCode and a %s signature\n", od->cppname, (pt->genc ? "C" : "C++"));
2086 }
2087 }
2088 }
2089
2090 for (a = 0; a < pysig -> nrArgs; ++a)
2091 {
2092 argDef *ad = &pysig -> args[a];
2093
2094 resolveType(pt, mod, scope, ad, FALSE);
2095
2096 /*
2097 * Note signal arguments are restricted in their types because we don't
2098 * (yet) support handwritten code for them.
2099 */
2100 if (issignal)
2101 {
2102 if (!supportedType(scope,od,ad,FALSE))
2103 {
2104 fatalAppend("%s:%d: ", od->sloc.name, od->sloc.linenr);
2105
2106 if (scope != NULL)
2107 {
2108 fatalScopedName(classFQCName(scope));
2109 fatalAppend("::");
2110 }
2111
2112 fatal("%s() argument %d has an unsupported type for a Python signature\n", od->cppname, a + 1);
2113 }
2114 }
2115 else if (!supportedType(scope, od, ad, TRUE))
2116 {
2117 if (od->sloc.name != NULL)
2118 fatalAppend("%s:%d: ", od->sloc.name, od->sloc.linenr);
2119
2120 if (scope != NULL)
2121 {
2122 fatalScopedName(classFQCName(scope));
2123 fatalAppend("::");
2124 }
2125
2126 if (isVirtual(od))
2127 fatal("%s() argument %d has an unsupported type for a Python signature - provide a valid type, %%MethodCode, %%VirtualCatcherCode and a C++ signature\n", od->cppname, a + 1);
2128
2129 fatal("%s() argument %d has an unsupported type for a Python signature - provide a valid type, %%MethodCode and a C++ signature\n", od->cppname, a + 1);
2130 }
2131
2132 if (scope != NULL)
2133 scopeDefaultValue(pt,scope,ad);
2134 }
2135 }
2136
2137
2138 /*
2139 * Resolve the type of a variable.
2140 */
resolveVariableType(sipSpec * pt,varDef * vd)2141 static void resolveVariableType(sipSpec *pt, varDef *vd)
2142 {
2143 int bad = TRUE;
2144 argDef *vtype = &vd->type;
2145
2146 resolveType(pt, vd->module, vd->ecd, vtype, FALSE);
2147
2148 switch (vtype->atype)
2149 {
2150 case mapped_type:
2151 case class_type:
2152 /* Class, Class & and Class * are supported. */
2153
2154 if (vtype->nrderefs <= 1)
2155 bad = FALSE;
2156 break;
2157
2158 case ascii_string_type:
2159 case latin1_string_type:
2160 case utf8_string_type:
2161 case sstring_type:
2162 case ustring_type:
2163 case string_type:
2164 case wstring_type:
2165 /*
2166 * (signed/unsigned) char, (signed/unsigned) char *, wchar_t, wchar_t *
2167 * are supported.
2168 */
2169
2170 if (!isReference(vtype) && vtype->nrderefs <= 1)
2171 bad = FALSE;
2172 break;
2173
2174 case cfloat_type:
2175 case float_type:
2176 case cdouble_type:
2177 case double_type:
2178 case enum_type:
2179 case bool_type:
2180 case cbool_type:
2181 case byte_type:
2182 case sbyte_type:
2183 case ubyte_type:
2184 case ushort_type:
2185 case short_type:
2186 case uint_type:
2187 case cint_type:
2188 case int_type:
2189 case ulong_type:
2190 case long_type:
2191 case ulonglong_type:
2192 case longlong_type:
2193 case ssize_type:
2194 case size_type:
2195 case pyobject_type:
2196 case pytuple_type:
2197 case pylist_type:
2198 case pydict_type:
2199 case pycallable_type:
2200 case pyslice_type:
2201 case pytype_type:
2202 case pybuffer_type:
2203 case capsule_type:
2204 /* These are supported without pointers or references. */
2205
2206 if (!isReference(vtype) && vtype->nrderefs == 0)
2207 bad = FALSE;
2208 break;
2209
2210 case struct_type:
2211 case void_type:
2212 /* A simple pointer is supported. */
2213
2214 if (!isReference(vtype) && vtype->nrderefs == 1)
2215 bad = FALSE;
2216 break;
2217
2218 /* Suppress a compiler warning. */
2219 default:
2220 ;
2221 }
2222
2223 if (bad && (vd->getcode == NULL || (!noSetter(vd) && vd->setcode == NULL)))
2224 {
2225 fatalScopedName(vd->fqcname);
2226 fatal(" has an unsupported type - provide %%GetCode");
2227
2228 if (!noSetter(vd))
2229 fatal(" and %%SetCode");
2230
2231 fatal("\n");
2232 }
2233
2234 if (vtype->atype != class_type && vd->accessfunc != NULL)
2235 {
2236 fatalScopedName(vd->fqcname);
2237 fatal(" has %%AccessCode but isn't a class instance\n");
2238 }
2239
2240 if (vd->ecd != NULL)
2241 ifaceFileIsUsed(&vd->ecd->iff->used, vtype, FALSE);
2242 else
2243 ifaceFileIsUsed(&vd->module->used, vtype, FALSE);
2244
2245 /* Scoped variables need a handler unless they have %AccessCode. */
2246 if (pyScope(vd->ecd) != NULL && vd->accessfunc == NULL)
2247 {
2248 setNeedsHandler(vd);
2249 setHasVarHandlers(vd->ecd);
2250 }
2251 }
2252
2253
2254 /*
2255 * See if a type is supported by the generated code.
2256 */
supportedType(classDef * cd,overDef * od,argDef * ad,int outputs)2257 static int supportedType(classDef *cd,overDef *od,argDef *ad,int outputs)
2258 {
2259 switch (ad -> atype)
2260 {
2261 case ellipsis_type:
2262 /* This can only appear in argument lists without * or &. */
2263 ensureInput(cd,od,ad);
2264 return TRUE;
2265
2266 case ascii_string_type:
2267 case latin1_string_type:
2268 case utf8_string_type:
2269 case sstring_type:
2270 case ustring_type:
2271 case string_type:
2272 case wstring_type:
2273 if (isReference(ad))
2274 {
2275 if (outputs && ad -> nrderefs <= 1)
2276 {
2277 defaultOutput(ad);
2278 return TRUE;
2279 }
2280 }
2281 else if (ad -> nrderefs == 0)
2282 {
2283 ensureInput(cd,od,ad);
2284 return TRUE;
2285 }
2286 else if (ad -> nrderefs == 1)
2287 {
2288 if (outputs)
2289 defaultInput(ad);
2290 else
2291 ensureInput(cd,od,ad);
2292
2293 return TRUE;
2294 }
2295 else if (ad -> nrderefs == 2 && outputs)
2296 {
2297 defaultOutput(ad);
2298 return TRUE;
2299 }
2300
2301 break;
2302
2303 case cfloat_type:
2304 case float_type:
2305 case cdouble_type:
2306 case double_type:
2307 case enum_type:
2308 case bool_type:
2309 case cbool_type:
2310 case byte_type:
2311 case sbyte_type:
2312 case ubyte_type:
2313 case ushort_type:
2314 case short_type:
2315 case uint_type:
2316 case cint_type:
2317 case int_type:
2318 case ulong_type:
2319 case long_type:
2320 case ulonglong_type:
2321 case longlong_type:
2322 case ssize_type:
2323 case size_type:
2324 case pyobject_type:
2325 case pytuple_type:
2326 case pylist_type:
2327 case pydict_type:
2328 case pycallable_type:
2329 case pyslice_type:
2330 case pytype_type:
2331 case pybuffer_type:
2332 case capsule_type:
2333 if (isReference(ad))
2334 {
2335 if (isConstArg(ad))
2336 {
2337 ensureInput(cd, od, ad);
2338 return TRUE;
2339 }
2340
2341 if (ad -> nrderefs == 0 && outputs)
2342 {
2343 defaultOutput(ad);
2344 return TRUE;
2345 }
2346 }
2347 else if (ad -> nrderefs == 0)
2348 {
2349 ensureInput(cd,od,ad);
2350 return TRUE;
2351 }
2352 else if (ad -> nrderefs == 1 && outputs)
2353 {
2354 defaultOutput(ad);
2355 return TRUE;
2356 }
2357
2358 break;
2359
2360 case mapped_type:
2361 case class_type:
2362 if (isReference(ad))
2363 {
2364 if (ad -> nrderefs == 0)
2365 {
2366 defaultInput(ad);
2367 return TRUE;
2368 }
2369 else if (ad -> nrderefs == 1 && outputs)
2370 {
2371 defaultOutput(ad);
2372 return TRUE;
2373 }
2374 }
2375 else if (ad -> nrderefs == 0)
2376 {
2377 ensureInput(cd,od,ad);
2378 return TRUE;
2379 }
2380 else if (ad -> nrderefs == 1)
2381 {
2382 if (outputs)
2383 defaultInput(ad);
2384 else
2385 ensureInput(cd,od,ad);
2386
2387 return TRUE;
2388 }
2389 else if (ad -> nrderefs == 2 && outputs)
2390 {
2391 defaultOutput(ad);
2392 return TRUE;
2393 }
2394
2395 break;
2396
2397 case struct_type:
2398 case void_type:
2399 if (isReference(ad))
2400 {
2401 if (ad -> nrderefs == 1 && outputs)
2402 {
2403 defaultOutput(ad);
2404 return TRUE;
2405 }
2406 }
2407 else if (ad -> nrderefs == 1)
2408 {
2409 ensureInput(cd,od,ad);
2410 return TRUE;
2411 }
2412 else if (ad -> nrderefs == 2 && outputs)
2413 {
2414 defaultOutput(ad);
2415 return TRUE;
2416 }
2417
2418 break;
2419
2420 /* Suppress a compiler warning. */
2421 default:
2422 ;
2423 }
2424
2425 /* Unsupported if we got this far. */
2426 return FALSE;
2427 }
2428
2429
2430 /*
2431 * Ensure the direction of an argument is an input.
2432 */
ensureInput(classDef * cd,overDef * od,argDef * ad)2433 static void ensureInput(classDef *cd,overDef *od,argDef *ad)
2434 {
2435 if (isOutArg(ad))
2436 {
2437 if (cd != NULL)
2438 {
2439 fatalScopedName(classFQCName(cd));
2440 fatalAppend("::");
2441 }
2442
2443 if (od != NULL)
2444 fatalAppend("%s", od->cppname);
2445
2446 fatal("() invalid argument type for /Out/\n");
2447 }
2448
2449 setIsInArg(ad);
2450 }
2451
2452
2453 /*
2454 * Default the direction of an argument to an input.
2455 */
defaultInput(argDef * ad)2456 static void defaultInput(argDef *ad)
2457 {
2458 if (!isInArg(ad) && !isOutArg(ad))
2459 setIsInArg(ad);
2460 }
2461
2462
2463 /*
2464 * Default the direction of an argument to an output unless the argument is
2465 * const.
2466 */
defaultOutput(argDef * ad)2467 static void defaultOutput(argDef *ad)
2468 {
2469 if (!isOutArg(ad) && !isInArg(ad))
2470 {
2471 if (isConstArg(ad))
2472 setIsInArg(ad);
2473 else
2474 setIsOutArg(ad);
2475 }
2476 }
2477
2478
2479 /*
2480 * Put a scoped name to stderr.
2481 */
fatalScopedName(scopedNameDef * snd)2482 void fatalScopedName(scopedNameDef *snd)
2483 {
2484 while (snd != NULL)
2485 {
2486 fatalAppend("%s", snd->name);
2487
2488 snd = snd -> next;
2489
2490 if (snd != NULL)
2491 fatalAppend("::");
2492 }
2493 }
2494
2495
2496 /*
2497 * Compare two overloads and return TRUE if they are the same.
2498 */
sameCppOverload(overDef * od1,overDef * od2)2499 static int sameCppOverload(overDef *od1, overDef *od2)
2500 {
2501 /* They must both be enabled for the same API. */
2502 if (od1->api_range != od2->api_range)
2503 return FALSE;
2504
2505 /* They must both be const, or both not. */
2506 if (isConst(od1) != isConst(od2))
2507 return FALSE;
2508
2509 return sameSignature(od1->cppsig, od2->cppsig, TRUE);
2510 }
2511
2512
2513 /*
2514 * Compare two signatures and return TRUE if they are the same.
2515 */
sameSignature(signatureDef * sd1,signatureDef * sd2,int strict)2516 int sameSignature(signatureDef *sd1, signatureDef *sd2, int strict)
2517 {
2518 int a;
2519
2520 if (strict)
2521 {
2522 /* The number of arguments must be the same. */
2523 if (sd1 -> nrArgs != sd2 -> nrArgs)
2524 return FALSE;
2525 }
2526 else
2527 {
2528 int na1, na2;
2529
2530 /* We only count the compulsory arguments. */
2531 na1 = 0;
2532
2533 for (a = 0; a < sd1 -> nrArgs; ++a)
2534 {
2535 if (sd1 -> args[a].defval != NULL)
2536 break;
2537
2538 ++na1;
2539 }
2540
2541 na2 = 0;
2542
2543 for (a = 0; a < sd2 -> nrArgs; ++a)
2544 {
2545 if (sd2 -> args[a].defval != NULL)
2546 break;
2547
2548 ++na2;
2549 }
2550
2551 if (na1 != na2)
2552 return FALSE;
2553 }
2554
2555 /* The arguments must be the same. */
2556 for (a = 0; a < sd1 -> nrArgs; ++a)
2557 {
2558 if (!strict && sd1 -> args[a].defval != NULL)
2559 break;
2560
2561 if (!sameArgType(&sd1 -> args[a],&sd2 -> args[a],strict))
2562 return FALSE;
2563 }
2564
2565 /* Must be the same if we've got this far. */
2566 return TRUE;
2567 }
2568
2569
2570 #define pyAsString(t) ((t) == ustring_type || (t) == sstring_type || \
2571 (t) == string_type || (t) == ascii_string_type || \
2572 (t) == latin1_string_type || (t) == utf8_string_type)
2573 #define pyAsFloat(t) ((t) == cfloat_type || (t) == float_type || \
2574 (t) == cdouble_type || (t) == double_type)
2575 #define pyAsInt(t) ((t) == bool_type || (t) == ssize_type || \
2576 (t) == size_type || (t) == byte_type || (t) == sbyte_type || \
2577 (t) == ubyte_type || (t) == short_type || (t) == ushort_type || \
2578 (t) == cint_type || (t) == int_type || (t) == uint_type)
2579 #define pyAsLong(t) ((t) == long_type || (t) == longlong_type)
2580 #define pyAsULong(t) ((t) == ulong_type || (t) == ulonglong_type)
2581 #define pyAsAuto(t) ((t) == bool_type || \
2582 (t) == byte_type || (t) == sbyte_type || (t) == ubyte_type || \
2583 (t) == short_type || (t) == ushort_type || \
2584 (t) == int_type || (t) == uint_type || \
2585 (t) == float_type || (t) == double_type)
2586 #define pyIsConstrained(t) ((t) == cbool_type || (t) == cint_type || \
2587 (t) == cfloat_type || (t) == cdouble_type)
2588
2589 /*
2590 * Compare two argument types and return TRUE if they are the same. "strict"
2591 * means as C++ would see it, rather than Python.
2592 */
sameArgType(argDef * a1,argDef * a2,int strict)2593 static int sameArgType(argDef *a1, argDef *a2, int strict)
2594 {
2595 /* The references must be the same. */
2596 if (isReference(a1) != isReference(a2) || a1->nrderefs != a2->nrderefs)
2597 return FALSE;
2598
2599 if (strict)
2600 {
2601 /* The const should be the same. */
2602 if (isConstArg(a1) != isConstArg(a2))
2603 return FALSE;
2604
2605 return sameBaseType(a1,a2);
2606 }
2607
2608 /* If both are constrained fundamental types then the types must match. */
2609 if (pyIsConstrained(a1->atype) && pyIsConstrained(a2->atype))
2610 return (a1->atype == a2->atype);
2611
2612 /* An unconstrained enum also acts as a (very) constrained int. */
2613 if ((pyAsInt(a1->atype) && a2->atype == enum_type && !isConstrained(a2)) ||
2614 (a1->atype == enum_type && !isConstrained(a1) && pyAsInt(a2->atype)))
2615 return TRUE;
2616
2617 /* Python will see all these as strings. */
2618 if (pyAsString(a1->atype) && pyAsString(a2->atype))
2619 return TRUE;
2620
2621 /* Python will see all these as floats. */
2622 if (pyAsFloat(a1->atype) && pyAsFloat(a2->atype))
2623 return TRUE;
2624
2625 /* Python will see all these as ints. */
2626 if (pyAsInt(a1->atype) && pyAsInt(a2->atype))
2627 return TRUE;
2628
2629 /* Python will see all these as longs. */
2630 if (pyAsLong(a1->atype) && pyAsLong(a2->atype))
2631 return TRUE;
2632
2633 /* Python will see all these as unsigned longs. */
2634 if (pyAsULong(a1->atype) && pyAsULong(a2->atype))
2635 return TRUE;
2636
2637 /* Python will automatically convert between these. */
2638 if (pyAsAuto(a1->atype) && pyAsAuto(a2->atype))
2639 return TRUE;
2640
2641 /* All the special cases have been handled. */
2642 return sameBaseType(a1, a2);
2643 }
2644
2645
2646 /*
2647 * Compare two basic types and return TRUE if they are the same.
2648 */
sameBaseType(argDef * a1,argDef * a2)2649 int sameBaseType(argDef *a1, argDef *a2)
2650 {
2651 /* The types must be the same. */
2652 if (a1->atype != a2->atype)
2653 {
2654 /*
2655 * If we are comparing a template with those that have already been
2656 * used to instantiate a class or mapped type then we need to compare
2657 * with the class or mapped type name.
2658 */
2659 if (a1->atype == class_type && a2->atype == defined_type)
2660 return compareScopedNames(a1->u.cd->iff->fqcname, a2->u.snd) == 0;
2661
2662 if (a1->atype == defined_type && a2->atype == class_type)
2663 return compareScopedNames(a2->u.cd->iff->fqcname, a1->u.snd) == 0;
2664
2665 if (a1->atype == mapped_type && a2->atype == defined_type)
2666 return compareScopedNames(a1->u.mtd->iff->fqcname, a2->u.snd) == 0;
2667
2668 if (a1->atype == defined_type && a2->atype == mapped_type)
2669 return compareScopedNames(a2->u.mtd->iff->fqcname, a1->u.snd) == 0;
2670
2671 if (a1->atype == enum_type && a2->atype == defined_type)
2672 return compareScopedNames(a1->u.ed->fqcname, a2->u.snd) == 0;
2673
2674 if (a1->atype == defined_type && a2->atype == enum_type)
2675 return compareScopedNames(a2->u.ed->fqcname, a1->u.snd) == 0;
2676
2677 return FALSE;
2678 }
2679
2680 switch (a1->atype)
2681 {
2682 case class_type:
2683 if (a1->u.cd != a2->u.cd)
2684 return FALSE;
2685
2686 break;
2687
2688 case enum_type:
2689 if (a1->u.ed != a2->u.ed)
2690 return FALSE;
2691
2692 break;
2693
2694 case template_type:
2695 {
2696 int a;
2697 templateDef *td1, *td2;
2698
2699 td1 = a1->u.td;
2700 td2 = a2->u.td;
2701
2702 if (compareScopedNames(td1->fqname, td2->fqname) != 0 ||
2703 td1->types.nrArgs != td2->types.nrArgs)
2704 return FALSE;
2705
2706 for (a = 0; a < td1->types.nrArgs; ++a)
2707 {
2708 argDef *td1ad = &td1->types.args[a];
2709 argDef *td2ad = &td2->types.args[a];
2710
2711 if (td1ad->nrderefs != td2ad->nrderefs)
2712 return FALSE;
2713
2714 if (!sameBaseType(td1ad, td2ad))
2715 return FALSE;
2716 }
2717
2718 break;
2719 }
2720
2721 case struct_type:
2722 if (compareScopedNames(a1->u.sname, a2->u.sname) != 0)
2723 return FALSE;
2724
2725 break;
2726
2727 case defined_type:
2728 if (compareScopedNames(a1->u.snd, a2->u.snd) != 0)
2729 return FALSE;
2730
2731 break;
2732
2733 case mapped_type:
2734 if (a1->u.mtd != a2->u.mtd)
2735 return FALSE;
2736
2737 break;
2738
2739 /* Suppress a compiler warning. */
2740 default:
2741 ;
2742 }
2743
2744 /* Must be the same if we've got this far. */
2745 return TRUE;
2746 }
2747
2748
2749 /*
2750 * See if two Python signatures are the same as far as Python is concerned.
2751 */
samePythonSignature(signatureDef * sd1,signatureDef * sd2)2752 static int samePythonSignature(signatureDef *sd1, signatureDef *sd2)
2753 {
2754 int a1, a2;
2755
2756 a1 = a2 = -1;
2757
2758 for (;;)
2759 {
2760 a1 = nextSignificantArg(sd1, a1);
2761 a2 = nextSignificantArg(sd2, a2);
2762
2763 if (a1 < 0 || a2 < 0)
2764 break;
2765
2766 if (!sameArgType(&sd1->args[a1], &sd2->args[a2], FALSE))
2767 return FALSE;
2768 }
2769
2770 return (a1 < 0 && a2 < 0);
2771 }
2772
2773
2774 /*
2775 * Return the next significant argument from a Python signature (ie. one that
2776 * is not optional or an output only argument. Return -1 if there isn't one.
2777 */
nextSignificantArg(signatureDef * sd,int a)2778 static int nextSignificantArg(signatureDef *sd, int a)
2779 {
2780 while (++a < sd->nrArgs)
2781 {
2782 if (sd->args[a].defval != NULL)
2783 break;
2784
2785 if (isInArg(&sd->args[a]))
2786 return a;
2787 }
2788
2789 return -1;
2790 }
2791
2792
2793 /*
2794 * The equivalent of strcmp() for scoped names.
2795 */
compareScopedNames(scopedNameDef * snd1,scopedNameDef * snd2)2796 int compareScopedNames(scopedNameDef *snd1, scopedNameDef *snd2)
2797 {
2798 /* Strip the global scope if the target doesn't specify it. */
2799 if (snd2->name[0] != '\0')
2800 snd1 = removeGlobalScope(snd1);
2801
2802 while (snd1 != NULL && snd2 != NULL)
2803 {
2804 int res = strcmp(snd1->name, snd2->name);
2805
2806 if (res != 0)
2807 return res;
2808
2809 snd1 = snd1->next;
2810 snd2 = snd2->next;
2811 }
2812
2813 if (snd1 == NULL)
2814 return (snd2 == NULL ? 0 : -1);
2815
2816 return 1;
2817 }
2818
2819
2820 /*
2821 * Add an explicit scope to the default value of an argument if possible.
2822 */
2823
scopeDefaultValue(sipSpec * pt,classDef * cd,argDef * ad)2824 static void scopeDefaultValue(sipSpec *pt,classDef *cd,argDef *ad)
2825 {
2826 valueDef *vd, **tailp, *newvd;
2827
2828 /*
2829 * We do a quick check to see if we need to do anything. This means
2830 * we can limit the times we need to copy the default value. It needs
2831 * to be copied because it will be shared by class versions that have
2832 * been created on the fly and it may need to be scoped differently for
2833 * each of those versions.
2834 */
2835
2836 for (vd = ad -> defval; vd != NULL; vd = vd -> next)
2837 if (vd -> vtype == scoped_value && vd -> u.vscp -> next == NULL)
2838 break;
2839
2840 if (vd == NULL)
2841 return;
2842
2843 /*
2844 * It's not certain that we will do anything, but we assume we will and
2845 * start copying.
2846 */
2847
2848 newvd = NULL;
2849 tailp = &newvd;
2850
2851 for (vd = ad -> defval; vd != NULL; vd = vd -> next)
2852 {
2853 mroDef *mro;
2854 scopedNameDef *origname;
2855 valueDef *new;
2856
2857 /* Make the copy. */
2858
2859 new = sipMalloc(sizeof (valueDef));
2860
2861 *new = *vd;
2862 *tailp = new;
2863 tailp = &new -> next;
2864
2865 /*
2866 * Skip this part of the expression if it isn't a named value
2867 * or it already has a scope.
2868 */
2869
2870 if (vd -> vtype != scoped_value || vd -> u.vscp -> next != NULL)
2871 continue;
2872
2873 /*
2874 * Search the class hierarchy for an enum value with the same
2875 * name. If we don't find one, leave it as it is (the compiler
2876 * will find out if this is a problem).
2877 */
2878
2879 origname = vd -> u.vscp;
2880
2881 for (mro = cd -> mro; mro != NULL; mro = mro -> next)
2882 {
2883 enumDef *ed;
2884
2885 for (ed = pt -> enums; ed != NULL; ed = ed -> next)
2886 {
2887 enumMemberDef *emd;
2888
2889 if (ed -> ecd != mro -> cd)
2890 continue;
2891
2892 for (emd = ed -> members; emd != NULL; emd = emd -> next)
2893 if (strcmp(emd -> cname,origname -> name) == 0)
2894 {
2895 scopedNameDef *snd;
2896
2897 /*
2898 * Take the scope from the
2899 * class that the enum was
2900 * defined in.
2901 */
2902
2903 snd = copyScopedName(mro -> cd -> iff -> fqcname);
2904 appendScopedName(&snd,origname);
2905
2906 new -> u.vscp = snd;
2907
2908 /* Nothing more to do. */
2909
2910 break;
2911 }
2912
2913 if (emd != NULL)
2914 break;
2915 }
2916
2917 if (ed != NULL)
2918 break;
2919 }
2920 }
2921
2922 ad -> defval = newvd;
2923 }
2924
2925
2926 /*
2927 * Resolve a type if possible.
2928 */
resolveType(sipSpec * pt,moduleDef * mod,classDef * c_scope,argDef * type,int allow_defined)2929 static void resolveType(sipSpec *pt, moduleDef *mod, classDef *c_scope,
2930 argDef *type, int allow_defined)
2931 {
2932 /* Loop until we've got to a base type. */
2933 while (type->atype == defined_type)
2934 {
2935 scopedNameDef *snd = type->u.snd;
2936
2937 type->atype = no_type;
2938
2939 /*
2940 * Search the local scopes unless what we are looking for has an
2941 * explicit global scope.
2942 */
2943 if (snd->name[0] != '\0')
2944 {
2945 classDef *scope;
2946
2947 for (scope = c_scope; scope != NULL; scope = scope->ecd)
2948 {
2949 if (scope->iff->type == class_iface)
2950 searchClassScope(pt, scope, snd, type);
2951 else
2952 searchScope(pt, scope, snd, type);
2953
2954 if (type->atype != no_type)
2955 break;
2956 }
2957
2958 if (type->atype != no_type)
2959 break;
2960 }
2961
2962 nameLookup(pt, mod, snd, type);
2963
2964 if (type->atype != no_type)
2965 break;
2966
2967 if (allow_defined)
2968 {
2969 type->atype = defined_type;
2970 return;
2971 }
2972
2973 fatalNoDefinedType(snd);
2974 }
2975
2976 /* See if the type refers to an instantiated template. */
2977 resolveInstantiatedClassTemplate(pt, type);
2978
2979 /* Replace the base type if it has been mapped. */
2980 if (type->atype == struct_type || type->atype == template_type)
2981 {
2982 searchMappedTypes(pt, mod, NULL, type);
2983
2984 /*
2985 * If we still have a template then see if we need to automatically
2986 * instantiate it.
2987 */
2988 if (type->atype == template_type)
2989 {
2990 mappedTypeTmplDef *mtt;
2991
2992 for (mtt = pt->mappedtypetemplates; mtt != NULL; mtt = mtt->next)
2993 if (compareScopedNames(mtt->mt->type.u.td->fqname, type->u.td->fqname) == 0 && sameTemplateSignature(&mtt->mt->type.u.td->types, &type->u.td->types, TRUE))
2994 {
2995 instantiateMappedTypeTemplate(pt, mod, mtt, type);
2996 break;
2997 }
2998 }
2999 }
3000
3001 /*
3002 * If we are in the main module then mark any generated types as being
3003 * needed.
3004 */
3005 if (generatingCodeForModule(pt, mod))
3006 setNeededType(type);
3007 }
3008
3009
3010 /*
3011 * Specify that a generated type is needed.
3012 */
setNeededType(argDef * ad)3013 static void setNeededType(argDef *ad)
3014 {
3015 switch (ad->atype)
3016 {
3017 case class_type:
3018 ad->u.cd->iff->first_alt->needed = TRUE;
3019 break;
3020
3021 case mapped_type:
3022 ad->u.mtd->real->iff->first_alt->needed = TRUE;
3023 break;
3024
3025 case enum_type:
3026 setNeedsEnum(ad->u.ed->first_alt);
3027 break;
3028
3029 default:
3030 ;
3031 }
3032 }
3033
3034
3035 /*
3036 * Specify that a set of thrown exceptions are needed.
3037 */
setNeededExceptions(sipSpec * pt,moduleDef * mod,throwArgs * exceptions)3038 static void setNeededExceptions(sipSpec *pt, moduleDef *mod,
3039 throwArgs *exceptions)
3040 {
3041 if (generatingCodeForModule(pt, mod) && exceptions != NULL)
3042 {
3043 int i;
3044
3045 for (i = 0; i < exceptions->nrArgs; ++i)
3046 setNeedsException(exceptions->args[i]);
3047 }
3048 }
3049
3050
3051 /*
3052 * Specify that an exception is needed.
3053 */
setNeedsException(exceptionDef * xd)3054 static void setNeedsException(exceptionDef *xd)
3055 {
3056 if (xd->cd != NULL)
3057 xd->cd->iff->first_alt->needed = TRUE;
3058 else
3059 xd->needed = TRUE;
3060 }
3061
3062
3063 /*
3064 * If the type corresponds to a previously instantiated class template then
3065 * replace it with the class that was created.
3066 */
resolveInstantiatedClassTemplate(sipSpec * pt,argDef * type)3067 static void resolveInstantiatedClassTemplate(sipSpec *pt, argDef *type)
3068 {
3069 int a;
3070 classDef *cd;
3071 templateDef *td;
3072 signatureDef *sd;
3073
3074 if (type->atype != template_type)
3075 return;
3076
3077 td = type->u.td;
3078 sd = &td->types;
3079
3080 for (a = 0; a < sd->nrArgs; ++a)
3081 resolveInstantiatedClassTemplate(pt, &sd->args[a]);
3082
3083 for (cd = pt->classes; cd != NULL; cd = cd->next)
3084 if (cd->td != NULL &&
3085 compareScopedNames(cd->td->fqname, td->fqname) == 0 &&
3086 sameSignature(&cd->td->types, sd, TRUE))
3087 {
3088 type->atype = class_type;
3089 type->u.cd = cd;
3090
3091 break;
3092 }
3093 }
3094
3095
3096 /*
3097 * Instantiate a mapped type template.
3098 */
instantiateMappedTypeTemplate(sipSpec * pt,moduleDef * mod,mappedTypeTmplDef * mtt,argDef * type)3099 static void instantiateMappedTypeTemplate(sipSpec *pt, moduleDef *mod,
3100 mappedTypeTmplDef *mtt, argDef *type)
3101 {
3102 scopedNameDef *type_names, *type_values;
3103 mappedTypeDef *mtd;
3104
3105 type_names = type_values = NULL;
3106 appendTypeStrings(type->u.td->fqname, &mtt->mt->type.u.td->types, &type->u.td->types, &mtt->sig, &type_names, &type_values);
3107
3108 mtd = allocMappedType(pt, type);
3109
3110 if (generatingCodeForModule(pt, mod))
3111 setIsUsedName(mtd->cname);
3112
3113 mtd->iff = findIfaceFile(pt, mod, encodedTemplateName(type->u.td),
3114 mappedtype_iface, NULL, type);
3115 mtd->iff->module = mod;
3116
3117 mtd->mtflags = mtt->mt->mtflags;
3118
3119 if (mtt->mt->typehint_in != NULL)
3120 mtd->typehint_in = newTypeHint(
3121 templateString(mtt->mt->typehint_in->raw_hint, type_names,
3122 type_values));
3123
3124 if (mtt->mt->typehint_out != NULL)
3125 mtd->typehint_out = newTypeHint(
3126 templateString(mtt->mt->typehint_out->raw_hint, type_names,
3127 type_values));
3128
3129 mtd->typehint_value = mtt->mt->typehint_value;
3130
3131 appendCodeBlockList(&mtd->iff->hdrcode,
3132 templateCode(pt, &mtd->iff->used, mtt->mt->iff->hdrcode,
3133 type_names, type_values));
3134
3135 mtd->convfromcode = templateCode(pt, &mtd->iff->used,
3136 mtt->mt->convfromcode, type_names, type_values);
3137 mtd->convtocode = templateCode(pt, &mtd->iff->used, mtt->mt->convtocode,
3138 type_names, type_values);
3139
3140 mtd->next = pt->mappedtypes;
3141 pt->mappedtypes = mtd;
3142
3143 if (type_names != NULL)
3144 freeScopedName(type_names);
3145
3146 if (type_values != NULL)
3147 freeScopedName(type_values);
3148
3149 mtd = copyTemplateType(mtd, type);
3150
3151 /* Replace the template with the mapped type. */
3152 type->atype = mapped_type;
3153 type->typehint_in = mtd->typehint_in;
3154 type->typehint_out = mtd->typehint_out;
3155 type->typehint_value = mtd->typehint_value;
3156
3157 type->u.mtd = mtd;
3158 }
3159
3160
3161 /*
3162 * Return a string based on an original with names replaced by corresponding
3163 * values.
3164 */
templateString(const char * src,scopedNameDef * names,scopedNameDef * values)3165 char *templateString(const char *src, scopedNameDef *names,
3166 scopedNameDef *values)
3167 {
3168 char *dst = sipStrdup(src);
3169
3170 while (names != NULL && values != NULL)
3171 {
3172 char *cp, *vname = values->name;
3173 int vname_on_heap = FALSE;
3174 size_t name_len, value_len;
3175
3176 /* Skip over any leading const. */
3177 if (strstr(vname, "const ") == vname)
3178 vname += 6;
3179
3180 name_len = strlen(names->name);
3181 value_len = strlen(vname);
3182
3183 /* Translate any C++ scoping to Python. */
3184 while ((cp = strstr(vname, "::")) != NULL)
3185 {
3186 char *new_vname = sipMalloc(value_len);
3187 size_t pos = cp - vname;
3188
3189 memcpy(new_vname, vname, pos);
3190 new_vname[pos] = '.';
3191 strcpy(new_vname + pos + 1, cp + 2);
3192
3193 if (vname != values->name)
3194 free(vname);
3195
3196 vname = new_vname;
3197 vname_on_heap = TRUE;
3198 --value_len;
3199 }
3200
3201 while ((cp = strstr(dst, names->name)) != NULL)
3202 {
3203 char *new_dst = sipMalloc(strlen(dst) - name_len + value_len + 1);
3204
3205 memcpy(new_dst, dst, cp - dst);
3206 memcpy(new_dst + (cp - dst), vname, value_len);
3207 strcpy(new_dst + (cp - dst) + value_len, cp + name_len);
3208
3209 free(dst);
3210 dst = new_dst;
3211 }
3212
3213 if (vname_on_heap)
3214 free(vname);
3215
3216 names = names->next;
3217 values = values->next;
3218 }
3219
3220 return dst;
3221 }
3222
3223
3224 /*
3225 * Search for a name in a class scope and return the corresponding type.
3226 */
searchClassScope(sipSpec * pt,classDef * c_scope,scopedNameDef * snd,argDef * ad)3227 static void searchClassScope(sipSpec *pt, classDef *c_scope,
3228 scopedNameDef *snd, argDef *ad)
3229 {
3230 mroDef *mro;
3231
3232 for (mro = c_scope->mro; mro != NULL; mro = mro->next)
3233 {
3234 searchScope(pt, mro->cd, snd, ad);
3235
3236 if (ad->atype != no_type)
3237 break;
3238 }
3239 }
3240
3241
3242 /*
3243 * Search for a name in a scope and return the corresponding type.
3244 */
searchScope(sipSpec * pt,classDef * scope,scopedNameDef * snd,argDef * ad)3245 static void searchScope(sipSpec *pt, classDef *scope, scopedNameDef *snd,
3246 argDef *ad)
3247 {
3248 scopedNameDef *tmpsnd;
3249
3250 /* Append the name to the scope and see if it exists. */
3251 tmpsnd = copyScopedName(classFQCName(scope));
3252 appendScopedName(&tmpsnd, copyScopedName(snd));
3253
3254 nameLookup(pt, scope->iff->module, tmpsnd, ad);
3255
3256 freeScopedName(tmpsnd);
3257 }
3258
3259
3260 /*
3261 * Look up a name and return the corresponding type.
3262 */
nameLookup(sipSpec * pt,moduleDef * context,scopedNameDef * snd,argDef * ad)3263 static void nameLookup(sipSpec *pt, moduleDef *context, scopedNameDef *snd,
3264 argDef *ad)
3265 {
3266 searchMappedTypes(pt, context, snd, ad);
3267 if (ad->atype != no_type)
3268 return;
3269
3270 searchTypedefs(pt, snd, ad);
3271 if (ad->atype != no_type)
3272 return;
3273
3274 searchEnums(pt, snd, ad);
3275 if (ad->atype != no_type)
3276 return;
3277
3278 searchClasses(pt, context, snd, ad);
3279 }
3280
3281
3282 /*
3283 * Search the mapped types for a name and return the type.
3284 */
searchMappedTypes(sipSpec * pt,moduleDef * context,scopedNameDef * snd,argDef * ad)3285 static void searchMappedTypes(sipSpec *pt, moduleDef *context,
3286 scopedNameDef *snd, argDef *ad)
3287 {
3288 mappedTypeDef *mtd;
3289 scopedNameDef *oname;
3290
3291 /* Patch back to defined types so we can use sameBaseType(). */
3292 if (snd != NULL)
3293 {
3294 oname = ad->u.snd;
3295 ad->u.snd = snd;
3296 ad->atype = defined_type;
3297 }
3298 else
3299 {
3300 /* Avoid a compiler warning. */
3301 oname = NULL;
3302 }
3303
3304 for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next)
3305 if (sameBaseType(&mtd->type, ad))
3306 {
3307 /*
3308 * If we are building a consolidated module and this mapped type is
3309 * defined in a different module then see if that other module is
3310 * in a different branch of the module hierarchy.
3311 */
3312 if (isConsolidated(pt->module) && context != mtd->iff->module)
3313 {
3314 moduleListDef *mld;
3315
3316 for (mld = context->allimports; mld != NULL; mld = mld->next)
3317 if (mld->module == mtd->iff->module)
3318 break;
3319
3320 /* If it's in a different branch then we ignore it. */
3321 if (mld == NULL)
3322 continue;
3323 }
3324
3325 mtd = copyTemplateType(mtd, ad);
3326
3327 /* Copy the type. */
3328 ad->atype = mapped_type;
3329 ad->u.mtd = mtd;
3330
3331 /*
3332 * Copy the type hints if nothing was specified for this particular
3333 * context.
3334 */
3335 if (ad->typehint_in == NULL)
3336 ad->typehint_in = mtd->typehint_in;
3337
3338 if (ad->typehint_out == NULL)
3339 ad->typehint_out = mtd->typehint_out;
3340
3341 if (ad->typehint_value == NULL)
3342 ad->typehint_value = mtd->typehint_value;
3343
3344 return;
3345 }
3346
3347 /* Restore because we didn't find anything. */
3348 if (snd != NULL)
3349 {
3350 ad->u.snd = oname;
3351 ad->atype = no_type;
3352 }
3353 }
3354
3355
3356 /*
3357 * If a mapped type is based on a template then create a copy that keeps the
3358 * original types of the template arguments.
3359 */
copyTemplateType(mappedTypeDef * mtd,argDef * ad)3360 static mappedTypeDef *copyTemplateType(mappedTypeDef *mtd, argDef *ad)
3361 {
3362 int a;
3363 signatureDef *src, *dst;
3364 mappedTypeDef *mtd_copy;
3365
3366 /* There is no need to do anything for non-template types. */
3367 if (mtd->type.atype != template_type)
3368 return mtd;
3369
3370 /* Retain the original types if there are any. */
3371 mtd_copy = mtd;
3372 src = &ad->u.td->types;
3373 dst = NULL;
3374
3375 for (a = 0; a < src->nrArgs; ++a)
3376 {
3377 typedefDef *tdd = src->args[a].original_type;
3378
3379 if (tdd != NULL)
3380 {
3381 /*
3382 * Create an appropriately deep copy now that we know it is needed
3383 * and if it hasn't already been done.
3384 */
3385 if (dst == NULL)
3386 {
3387 templateDef *td_copy;
3388
3389 mtd_copy = sipMalloc(sizeof (mappedTypeDef));
3390 *mtd_copy = *mtd;
3391
3392 td_copy = sipMalloc(sizeof (templateDef));
3393 *td_copy = *mtd->type.u.td;
3394 mtd_copy->type.u.td = td_copy;
3395
3396 dst = &td_copy->types;
3397 }
3398
3399 dst->args[a].original_type = tdd;
3400 }
3401 }
3402
3403 return mtd_copy;
3404 }
3405
3406
3407 /*
3408 * Search the typedefs for a name and return the type.
3409 */
searchTypedefs(sipSpec * pt,scopedNameDef * snd,argDef * ad)3410 void searchTypedefs(sipSpec *pt, scopedNameDef *snd, argDef *ad)
3411 {
3412 typedefDef *td;
3413
3414 for (td = pt->typedefs; td != NULL; td = td->next)
3415 {
3416 int res = compareScopedNames(td->fqname, snd);
3417
3418 if (res == 0)
3419 {
3420 int i;
3421
3422 /* Copy the type. */
3423 ad->atype = td->type.atype;
3424 ad->argflags |= td->type.argflags;
3425 ad->typehint_in = td->type.typehint_in;
3426 ad->typehint_out = td->type.typehint_out;
3427 ad->typehint_value = td->type.typehint_value;
3428 ad->u = td->type.u;
3429
3430 for (i = 0; i < td->type.nrderefs; ++i)
3431 {
3432 if (ad->nrderefs >= MAX_NR_DEREFS - 1)
3433 fatal("Internal error - increase the value of MAX_NR_DEREFS\n");
3434
3435 ad->derefs[ad->nrderefs++] = td->type.derefs[i];
3436 }
3437
3438 if (ad->original_type == NULL)
3439 ad->original_type = td;
3440
3441 break;
3442 }
3443
3444 /* The list is sorted so stop if we have gone too far. */
3445 if (res > 0)
3446 break;
3447 }
3448 }
3449
3450
3451 /*
3452 * Search the enums for a name and return the type.
3453 */
searchEnums(sipSpec * pt,scopedNameDef * snd,argDef * ad)3454 static void searchEnums(sipSpec *pt, scopedNameDef *snd, argDef *ad)
3455 {
3456 enumDef *ed;
3457
3458 for (ed = pt->enums; ed != NULL; ed = ed->next)
3459 {
3460 if (ed->fqcname == NULL)
3461 continue;
3462
3463 if (compareScopedNames(ed->fqcname, snd) == 0)
3464 {
3465 ad->atype = enum_type;
3466 ad->u.ed = ed;
3467
3468 break;
3469 }
3470 }
3471 }
3472
3473
3474 /*
3475 * Search the classes for one with a particular name and return it as a type.
3476 */
searchClasses(sipSpec * pt,moduleDef * context,scopedNameDef * cname,argDef * ad)3477 static void searchClasses(sipSpec *pt, moduleDef *context,
3478 scopedNameDef *cname, argDef *ad)
3479 {
3480 classDef *cd;
3481
3482 for (cd = pt->classes; cd != NULL; cd = cd->next)
3483 {
3484 /*
3485 * Ignore an external class unless it was declared in the same context
3486 * (ie. module) as the name is being used.
3487 */
3488 if (isExternal(cd) && cd->iff->module != context)
3489 continue;
3490
3491 if (compareScopedNames(classFQCName(cd), cname) == 0)
3492 {
3493 ad->atype = class_type;
3494 ad->u.cd = cd;
3495
3496 /*
3497 * Copy the type hints if nothing was specified for this particular
3498 * context.
3499 */
3500 if (ad->typehint_in == NULL)
3501 ad->typehint_in = cd->typehint_in;
3502
3503 if (ad->typehint_out == NULL)
3504 ad->typehint_out = cd->typehint_out;
3505
3506 if (ad->typehint_value == NULL)
3507 ad->typehint_value = cd->typehint_value;
3508
3509 break;
3510 }
3511 }
3512 }
3513
3514
3515 /*
3516 * Print an error message describing an undefined type to stderr and terminate.
3517 */
3518
fatalNoDefinedType(scopedNameDef * snd)3519 static void fatalNoDefinedType(scopedNameDef *snd)
3520 {
3521 fatalScopedName(snd);
3522 fatal(" is undefined\n");
3523 }
3524
3525
3526 /*
3527 * Make sure all interface files for a signature are used.
3528 */
ifaceFilesAreUsedBySignature(ifaceFileList ** used,signatureDef * sd,int need_types)3529 static void ifaceFilesAreUsedBySignature(ifaceFileList **used,
3530 signatureDef *sd, int need_types)
3531 {
3532 int a;
3533
3534 ifaceFileIsUsed(used, &sd->result, need_types);
3535
3536 for (a = 0; a < sd->nrArgs; ++a)
3537 ifaceFileIsUsed(used, &sd->args[a], need_types);
3538 }
3539
3540
3541 /*
3542 * Make sure all interface files for a function are used.
3543 */
ifaceFilesAreUsedByOverload(ifaceFileList ** used,overDef * od,int need_types)3544 static void ifaceFilesAreUsedByOverload(ifaceFileList **used, overDef *od,
3545 int need_types)
3546 {
3547 throwArgs *ta;
3548
3549 ifaceFilesAreUsedBySignature(used, &od->pysig, need_types);
3550
3551 if (od->cppsig != &od->pysig)
3552 ifaceFilesAreUsedBySignature(used, od->cppsig, need_types);
3553
3554 if ((ta = od->exceptions) != NULL)
3555 {
3556 int a;
3557
3558 for (a = 0; a < ta->nrArgs; ++a)
3559 {
3560 exceptionDef *xd = ta->args[a];
3561
3562 appendToIfaceFileList(used, xd->iff);
3563
3564 if (need_types)
3565 setNeedsException(xd);
3566 }
3567 }
3568 }
3569
3570
3571 /*
3572 * If a type has an interface file then add it to the the given list of used
3573 * interface files so that the header file is #included in the generated code.
3574 */
ifaceFileIsUsed(ifaceFileList ** used,argDef * ad,int need_types)3575 static void ifaceFileIsUsed(ifaceFileList **used, argDef *ad, int need_types)
3576 {
3577 ifaceFileDef *iff;
3578
3579 if ((iff = getIfaceFile(ad)) != NULL)
3580 {
3581 appendToIfaceFileList(used, iff);
3582
3583 /*
3584 * For mapped type templates we also need the template arguments.
3585 * These will be in the mapped type's used list (which itself will be
3586 * empty for non-template mapped types).
3587 */
3588 if (ad->atype == mapped_type)
3589 {
3590 ifaceFileList *iffl = iff->used;
3591
3592 for (iffl = iff->used; iffl != NULL; iffl = iffl->next)
3593 appendToIfaceFileList(used, iffl->iff);
3594 }
3595 }
3596
3597 if (need_types)
3598 setNeededType(ad);
3599 }
3600
3601
3602 /*
3603 * Return the interface file for an enum, or NULL if it doesn't have one.
3604 */
getIfaceFileForEnum(enumDef * ed)3605 static ifaceFileDef *getIfaceFileForEnum(enumDef *ed)
3606 {
3607 if (ed->fqcname != NULL)
3608 {
3609 if (ed->ecd != NULL)
3610 return ed->ecd->iff;
3611
3612 if (ed->emtd != NULL)
3613 return ed->emtd->iff;
3614 }
3615
3616 return NULL;
3617 }
3618
3619
3620 /*
3621 * Return the interface file for a type, or NULL if it doesn't have one.
3622 */
getIfaceFile(argDef * ad)3623 static ifaceFileDef *getIfaceFile(argDef *ad)
3624 {
3625 ifaceFileDef *iff;
3626
3627 switch (ad->atype)
3628 {
3629 case class_type:
3630 iff = ad->u.cd->iff;
3631 break;
3632
3633 case mapped_type:
3634 iff = ad->u.mtd->iff;
3635 break;
3636
3637 case enum_type:
3638 iff = getIfaceFileForEnum(ad->u.ed);
3639 break;
3640
3641 default:
3642 iff = NULL;
3643 }
3644
3645 return iff;
3646 }
3647
3648
3649 /*
3650 * Create the sorted array of numbered types for a module. For the main module
3651 * this will be every type defined in the module. For other modules this will
3652 * be every type needed by the main module.
3653 */
createSortedNumberedTypesTable(sipSpec * pt,moduleDef * mod)3654 static void createSortedNumberedTypesTable(sipSpec *pt, moduleDef *mod)
3655 {
3656 classDef *cd;
3657 mappedTypeDef *mtd;
3658 enumDef *ed;
3659 argDef *ad;
3660 int i;
3661
3662 /* Count the how many types there are. */
3663 mod->nr_needed_types = 0;
3664
3665 for (cd = pt->classes; cd != NULL; cd = cd->next)
3666 {
3667 if (cd->iff->module != mod)
3668 continue;
3669
3670 if (cd->iff->first_alt != cd->iff)
3671 continue;
3672
3673 if (generatingCodeForModule(pt, mod) || cd->iff->needed)
3674 if (!isHiddenNamespace(cd))
3675 mod->nr_needed_types++;
3676 }
3677
3678 for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next)
3679 {
3680 if (mtd->iff->module != mod)
3681 continue;
3682
3683 if (mtd->iff->first_alt != mtd->iff)
3684 continue;
3685
3686 if (generatingCodeForModule(pt, mod) || mtd->iff->needed)
3687 mod->nr_needed_types++;
3688 }
3689
3690 for (ed = pt->enums; ed != NULL; ed = ed->next)
3691 {
3692 if (ed->module != mod)
3693 continue;
3694
3695 if (ed->fqcname == NULL)
3696 continue;
3697
3698 if (ed->ecd != NULL && isTemplateClass(ed->ecd))
3699 continue;
3700
3701 if (ed->first_alt != ed)
3702 continue;
3703
3704 if (generatingCodeForModule(pt, mod) || needsEnum(ed))
3705 mod->nr_needed_types++;
3706 }
3707
3708 if (mod->nr_needed_types == 0)
3709 return;
3710
3711 /* Allocate and populate the table. */
3712 ad = mod->needed_types = sipCalloc(mod->nr_needed_types, sizeof (argDef));
3713
3714 for (cd = pt->classes; cd != NULL; cd = cd->next)
3715 {
3716 if (cd->iff->module != mod)
3717 continue;
3718
3719 if (cd->iff->first_alt != cd->iff)
3720 continue;
3721
3722 if (generatingCodeForModule(pt, mod) || cd->iff->needed)
3723 if (!isHiddenNamespace(cd))
3724 {
3725 ad->atype = class_type;
3726 ad->u.cd = cd;
3727 ad->name = cd->iff->name;
3728
3729 ++ad;
3730 }
3731 }
3732
3733 for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next)
3734 {
3735 if (mtd->iff->module != mod)
3736 continue;
3737
3738 if (mtd->iff->first_alt != mtd->iff)
3739 continue;
3740
3741 if (generatingCodeForModule(pt, mod) || mtd->iff->needed)
3742 {
3743 ad->atype = mapped_type;
3744 ad->u.mtd = mtd;
3745 ad->name = mtd->cname;
3746
3747 ++ad;
3748 }
3749 }
3750
3751 for (ed = pt->enums; ed != NULL; ed = ed->next)
3752 {
3753 if (ed->module != mod)
3754 continue;
3755
3756 if (ed->fqcname == NULL)
3757 continue;
3758
3759 if (ed->ecd != NULL && isTemplateClass(ed->ecd))
3760 continue;
3761
3762 if (ed->first_alt != ed)
3763 continue;
3764
3765 if (generatingCodeForModule(pt, mod) || needsEnum(ed))
3766 {
3767 ad->atype = enum_type;
3768 ad->u.ed = ed;
3769 ad->name = ed->cname;
3770
3771 ++ad;
3772 }
3773 }
3774
3775 /* Sort the table and assign type numbers. */
3776 qsort(mod->needed_types, mod->nr_needed_types, sizeof (argDef),
3777 compareTypes);
3778
3779 for (ad = mod->needed_types, i = 0; i < mod->nr_needed_types; ++i, ++ad)
3780 {
3781 switch (ad->atype)
3782 {
3783 case class_type:
3784 ad->u.cd->iff->ifacenr = i;
3785
3786 /* If we find a class called QObject, assume it's Qt. */
3787 if (strcmp(ad->name->text, "QObject") == 0)
3788 {
3789 if (pt->qobject_cd != NULL)
3790 fatal("QObject has been defined more than once\n");
3791
3792 pt->qobject_cd = ad->u.cd;
3793 }
3794
3795 break;
3796
3797 case mapped_type:
3798 ad->u.mtd->iff->ifacenr = i;
3799 break;
3800
3801 case enum_type:
3802 ad->u.ed->enumnr = i;
3803 break;
3804
3805 /* Suppress a compiler warning. */
3806 default:
3807 ;
3808 }
3809 }
3810 }
3811
3812
3813 /*
3814 * The qsort helper to compare two generated C/C++ type names.
3815 */
compareTypes(const void * t1,const void * t2)3816 static int compareTypes(const void *t1, const void *t2)
3817 {
3818 return strcmp(((argDef *)t1)->name->text, ((argDef *)t2)->name->text);
3819 }
3820
3821
3822 /*
3823 * Return the fully qualified C/C++ name for a generated type.
3824 */
getFQCNameOfType(argDef * ad)3825 scopedNameDef *getFQCNameOfType(argDef *ad)
3826 {
3827 scopedNameDef *snd;
3828
3829 switch (ad->atype)
3830 {
3831 case class_type:
3832 snd = classFQCName(ad->u.cd);
3833 break;
3834
3835 case mapped_type:
3836 snd = ad->u.mtd->iff->fqcname;
3837 break;
3838
3839 case enum_type:
3840 snd = ad->u.ed->fqcname;
3841 break;
3842
3843 default:
3844 /* Suppress a compiler warning. */
3845 snd = NULL;
3846 }
3847
3848 return snd;
3849 }
3850
3851
3852 /*
3853 * Return TRUE if we are generating code for a module, ie. we are a component
3854 * of a consolidated module, or the main module where there is no consolidated
3855 * module.
3856 */
generatingCodeForModule(sipSpec * pt,moduleDef * mod)3857 static int generatingCodeForModule(sipSpec *pt, moduleDef *mod)
3858 {
3859 if (isConsolidated(pt->module))
3860 return (pt->module == mod->container);
3861
3862 return (pt->module == mod);
3863 }
3864
3865
3866 /*
3867 * Check that any properties are valid.
3868 */
checkProperties(classDef * cd)3869 static void checkProperties(classDef *cd)
3870 {
3871 propertyDef *pd;
3872
3873 for (pd = cd->properties; pd != NULL; pd = pd->next)
3874 {
3875 if (findMethod(cd, pd->get) == NULL)
3876 fatal("Property %s.%s has no get method %s()\n", cd->pyname->text,
3877 pd->name->text, pd->get);
3878
3879 if (pd->set != NULL && findMethod(cd, pd->set) == NULL)
3880 fatal("Property %s.%s has no set method %s()\n", cd->pyname->text,
3881 pd->name->text, pd->set);
3882 }
3883 }
3884
3885
3886 /*
3887 * Return the method of a class with a given name.
3888 */
findMethod(classDef * cd,const char * name)3889 memberDef *findMethod(classDef *cd, const char *name)
3890 {
3891 memberDef *md;
3892
3893 for (md = cd->members; md != NULL; md = md->next)
3894 if (strcmp(md->pyname->text, name) == 0)
3895 break;
3896
3897 return md;
3898 }
3899