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 = &copyct->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