📄 transform.c
字号:
{ best_thismod = hd; break; } /* * We don't use this one if it doesn't have virtual code and * there is an alternative, or if it does have virtual code and * there is already an alternative in the same module which * doesn't have virtual code. */ if ((vhd -> virtcode == NULL && (best != NULL || best_thismod != NULL)) || (vhd -> virtcode != NULL && best_thismod != NULL && best_thismod -> virtcode == NULL)) { virtHandlerDef *saved; /* * If the alternative is in the same module and we * have virtual code then give it to the alternative. * Note that there is a bug here. If there are three * handlers, the first without code and the second and * third with code then which code is transfered to the * first is down to luck. We should really only * transfer code to methods that are known to be * re-implementations - just having the same signature * isn't enough. */ if (best_thismod != NULL) { if (best_thismod -> virtcode == NULL && vhd -> virtcode != NULL) { best_thismod -> virtcode = vhd -> virtcode; resetIsDuplicateVH(best_thismod); } best = best_thismod; } /* Use the better one in place of this one. */ saved = vhd -> next; *vhd = *best; setIsDuplicateVH(vhd); vhd -> next = saved; } else vhd -> virthandlernr = mod -> nrvirthandlers++; }}/* * Add an overload that is automatically generated (typically by Qt's moc). */static void addAutoOverload(sipSpec *pt,classDef *autocd,overDef *autood){ classDef *cd; /* Find every class that has this one in its hierarchy. */ for (cd = pt -> classes; cd != NULL; cd = cd -> next) { mroDef *mro; if (cd == autocd) continue; for (mro = cd -> mro; mro != NULL; mro = mro -> next) if (mro -> cd == autocd) { memberDef *md; overDef *od; /* Another overload may already exist. */ for (md = cd -> members; md != NULL; md = md -> next) if (md -> pyname == autood -> common -> pyname) break; if (md == NULL) { md = sipMalloc(sizeof (memberDef)); md -> pyname = autood -> common -> pyname; md -> memberflags = autood -> common -> memberflags; md -> slot = autood -> common -> slot; md -> module = cd -> iff -> module; md -> next = cd -> members; cd -> members = md; } od = sipMalloc(sizeof (overDef)); *od = *autood; od -> common = md; od -> next = cd -> overs; cd -> overs = od; resetIsAutoGen(od); if (cd -> iff -> module == pt -> module) setIsUsedName(md -> pyname); break; } }}/* * Set the complete hierarchy for a class. */static void setHierarchy(sipSpec *pt,classDef *base,classDef *cd, classList **head){ mroDef **tailp = &cd -> mro; /* See if it has already been done. */ if (cd -> mro != NULL) return; if (cd -> ecd != NULL) setHierarchy(pt,base,cd -> ecd,head); if (cd -> iff -> type == class_iface) { classList *cl; /* The first thing is itself. */ appendToMRO(cd -> mro,&tailp,cd); if (cd -> convtosubcode != NULL) cd -> subbase = cd; /* Now do it's superclasses. */ for (cl = cd -> supers; cl != NULL; cl = cl -> next) { mroDef *mro; /* * Make sure the super-class's hierarchy has been done. */ setHierarchy(pt,base,cl -> cd,head); /* Append the super-classes hierarchy. */ for (mro = cl -> cd -> mro; mro != NULL; mro = mro -> next) { appendToMRO(cd -> mro,&tailp,mro -> cd); /* * If the super-class has a shadow then this * one should have one as well. */ if (hasShadow(mro -> cd)) setHasShadow(cd); /* * Ensure that the sub-class base class is the * furthest up the hierarchy. */ if (mro -> cd -> subbase != NULL) cd -> subbase = mro -> cd -> subbase; } } } /* * We can't have a shadow if the specification is incomplete, there is * a private dtor, there are no none-private ctors or there are private * abstract methods. */ if (isIncomplete(cd) || isPrivateDtor(cd) || !canCreate(cd)) resetHasShadow(cd); else { overDef *od; /* * Note that we should be able to provide better support for * abstract private methods than we do at the moment. */ for (od = cd->overs; od != NULL; od = od->next) if (isAbstract(od) && isPrivate(od)) { resetHasShadow(cd); /* * It also means we cannot create an instance * from Python. */ resetCanCreate(cd); break; } } /* Add it to the new list. */ appendToClassList(head,cd);}/* * Append a class definition to an mro list */static void appendToMRO(mroDef *head,mroDef ***tailp,classDef *cd){ mroDef *mro, *new; new = sipMalloc(sizeof (mroDef)); new -> cd = cd; new -> mroflags = 0; new -> next = NULL; /* See if it is a duplicate. */ for (mro = head; mro != NULL; mro = mro -> next) if (mro -> cd == cd) { setIsDuplicateSuper(new); if (!isDuplicateSuper(mro)) setHasDuplicateSuper(mro); break; } /* Append to the list and update the tail pointer. */ **tailp = new; *tailp = &new -> next;}/* * Get the base types for all typedefs. */static void transformTypedefs(sipSpec *pt){ typedefDef *td; for (td = pt -> typedefs; td != NULL; td = td -> next) getBaseType(pt, td->module, td -> ecd, &td -> type);}/* * Transform the data types for mapped types based on a template. */static void transformMappedTypes(sipSpec *pt){ mappedTypeDef *mt; for (mt = pt -> mappedtypes; mt != NULL; mt = mt -> next) { /* Nothing to do if this isn't template based. */ if (mt -> type.atype == template_type) resolveMappedTypeTypes(pt,mt); }}/* * Transform the data types for a list of ctors. */static void transformCtors(sipSpec *pt,classDef *cd){ ctorDef *ct; for (ct = cd -> ctors; ct != NULL; ct = ct -> next) resolveCtorTypes(pt,cd,ct);}/* * Transform the data type for a list of casts. */static void transformCasts(sipSpec *pt, classDef *cd){ argList *al; for (al = cd->casts; al != NULL; al = al->next) { getBaseType(pt, cd->iff->module, cd, &al->arg); if (al->arg.atype != class_type) { fatalScopedName(classFQCName(cd)); fatal(" operator cast must be to a class\n"); } }}/* * Add a default copy ctor is required. */static void addDefaultCopyCtor(classDef *cd){ ctorDef *copyct; mroDef *mro; /* See if there is a private copy ctor in the hierarchy. */ copyct = NULL; for (mro = cd -> mro; mro != NULL; mro = mro -> next) { ctorDef *ct; if (isDuplicateSuper(mro)) continue; for (ct = mro -> cd -> ctors; ct != NULL; ct = ct -> next) { argDef *ad = &ct -> pysig.args[0]; /* See if is a copy ctor. */ if (ct -> pysig.nrArgs != 1 || ad -> nrderefs != 0 || !isReference(ad) || ad -> atype != class_type || ad -> u.cd != mro -> cd) continue; /* Stop now if the copy ctor is private. */ if (isPrivateCtor(ct)) return; /* * Remember if it's in the class we are dealing with. */ if (mro == cd -> mro) copyct = ct; break; } } if (copyct == NULL) { ctorDef **tailp; /* Create a default public copy ctor. */ copyct = sipMalloc(sizeof (ctorDef)); copyct -> ctorflags = SECT_IS_PUBLIC; copyct -> pysig.nrArgs = 1; copyct -> pysig.args[0].atype = class_type; copyct -> pysig.args[0].u.cd = cd; copyct -> pysig.args[0].argflags = (ARG_IS_REF | ARG_IS_CONST | ARG_IN); copyct -> pysig.args[0].nrderefs = 0; copyct -> pysig.args[0].defval = NULL; copyct -> cppsig = ©ct -> pysig; copyct -> exceptions = NULL; copyct -> methodcode = NULL; copyct -> prehook = NULL; copyct -> posthook = NULL; copyct -> next = NULL; /* Append it to the list. */ for (tailp = &cd -> ctors; *tailp != NULL; tailp = &(*tailp) -> next) ; *tailp = copyct; }}/* * Transform the data types for a list of overloads. */static void transformOverloads(sipSpec *pt, classDef *scope, overDef *overs){ overDef *od; for (od = overs; od != NULL; od = od -> next) resolveFuncTypes(pt, od->common->module, scope, od);}/* * Transform the data types for the variables. */static void transformVariableList(sipSpec *pt){ varDef *vd; for (vd = pt -> vars; vd != NULL; vd = vd -> next) resolveVariableType(pt,vd);}/* * Set the list of visible member functions for a class. */static void getVisibleMembers(sipSpec *pt,classDef *cd){ mroDef *mro; cd -> visible = NULL; for (mro = cd -> mro; mro != NULL; mro = mro -> next) { memberDef *md; classDef *mrocd; if (isDuplicateSuper(mro)) continue; mrocd = mro -> cd; /* * If the base class is in the main module, see if it needs to * publish any protected enums. */ if (cd -> iff -> module == pt -> module) { enumDef *ed; for (ed = pt -> enums; ed != NULL; ed = ed -> next) { /* Skip unless we are the publisher. */ if (ed -> pcd != mrocd) continue; /* * If we are not in the main module then the * base class must take over as the publisher. */ if (mrocd -> iff -> module != pt -> module) ed -> pcd = cd; } } for (md = mrocd -> members; md != NULL; md = md -> next) { visibleList *vl; if (md -> slot != no_slot) { if (mrocd == cd) ifaceFilesAreUsedByMethod(pt, cd, md); continue; } /* * See if it is already in the list. This has the * desired side effect of eliminating any functions * that have an implementation closer to this class in * the hierarchy. This is the only reason to define * private functions. */ for (vl = cd -> visible; vl != NULL; vl = vl -> next) if (vl -> m -> pyname == md -> pyname) break; /* See if it is a new member function. */ if (vl == NULL) { overDef *od; vl = sipMalloc(sizeof (visibleList)); vl -> m = md; vl -> cd = mrocd; vl -> next = cd -> visible; addToUsedList(&cd->iff->used, mrocd->iff); cd -> visible = vl; for (od = mrocd -> overs; od != NULL; od = od -> next) if (od -> common == md) { if (isAbstract(od)) setIsAbstractClass(cd); ifaceFilesAreUsed(pt, cd->iff, od); /* See if we need the name. */ if (cd->iff->module != pt->module) continue; if (isProtected(od) || (isSignal(od) && pt->emitters)) setIsUsedName(md->pyname); } } } }}/* * Get all the virtuals for a particular class. */static void getVirtuals(sipSpec *pt,classDef *cd){ mroDef *mro; virtOverDef *vod; for (mro = cd -> mro; mro != NULL; mro = mro -> next) { if (isDuplicateSuper(mro)) continue; getClassVirtuals(cd,mro -> cd); } /* * Identify any re-implementations of virtuals. We have to do this for * all classes, not just those in the main module. */ for (vod = cd -> vmembers; vod != NULL; vod = vod -> next) { overDef *od; for (od = cd->overs; od != NULL; od = od->next) { if (isVirtual(od)) continue; if (strcmp(vod->o.cppname, od->cppname) == 0 && sameOverload(&vod->o, od)) { setIsVirtualReimp(od); break; } } /* * If this class is defined in the main module make sure we get * the API files for all the visible virtuals. */ if (cd->iff->module == pt->module) { /* Make sure we get the name. */ setIsUsedName(vod -> o.common -> pyname); ifaceFilesAreUsed(pt, cd->iff, &vod -> o); } }}/* * Get the list of visible virtual functions for a class. */static void getClassVirtuals(classDef *base,classDef *cd){ overDef *od; for (od = cd -> overs; od != NULL; od = od -> next) { virtOverDef **tailp, *vod; if (!isVirtual(od) || isPrivate(od)) continue; /* * See if a virtual of this name and signature is already in * the list. */ for (tailp = &base -> vmembers; (vod = *tailp) != NULL; tailp = &vod -> next) if (strcmp(vod -> o.cppname,od -> cppname) == 0 && sameOverload(&vod -> o,od)) break; if (vod == NULL) { /* * See if there is a non-virtual reimplementation * nearer in the class hierarchy. */ mroDef *mro; classDef *scope = NULL; overDef *eod; for (mro = base -> mro; mro -> cd != cd; mro = mro -> next) { if (isDuplicateSuper(mro)) continue; /* * Ignore classes that are on a different * branch of the class hierarchy. */ if (!isSubClass(mro -> cd,cd)) continue; for (eod = mro -> cd -> overs; eod != NULL; eod = eod -> next) if (strcmp(eod -> cppname,od -> cppname) == 0 && sameSignature(eod -> cppsig,od -> cppsig,TRUE) && isConst(eod) == isConst(od) && !isAbstract(eod)) { scope = mro -> cd; break; } if (scope != NULL) break; } vod = sipMalloc(sizeof (virtOverDef)); vod -> o = *od; vod -> scope = (scope != NULL ? scope : cd); vod -> next = NULL; *tailp = vod; /* * If there was a nearer reimplementation then we use * its protection and abstract flags. */ if (scope != NULL) { vod -> o.overflags &= ~(SECT_MASK | OVER_IS_ABSTRACT); vod -> o.overflags |= (SECT_MASK | OVER_IS_ABSTRACT) & eod -> overflags; } } }}/* * Return TRUE is a class is derived from another. */static int isSubClass(classDef *cc,classDef *pc){ mroDef *mro; /* * In other words, does the parent class appear in the child class's * MRO list. */ for (mro = cc -> mro; mro != NULL; mro = mro -> next) if (mro -> cd == pc) return TRUE; return FALSE;}/* * Resolve the types of a mapped type based on a template. */static void resolveMappedTypeTypes(sipSpec *pt,mappedTypeDef *mt){ int a; templateDef *td = mt -> type.u.td; for (a = 0; a < td -> types.nrArgs; ++a) { getBaseType(pt, mt->iff->module, NULL, &td->types.args[a]); ifaceFileIsUsed(pt, mt->iff, &td->types.args[a]); }}/* * Resolve the types of a ctor. */static void resolveCtorTypes(sipSpec *pt,classDef *scope,ctorDef *ct){ int a; /* Handle any C++ signature. */ if (ct->cppsig != NULL && ct->cppsig != &ct->pysig) for (a = 0; a < ct -> cppsig -> nrArgs; ++a) getBaseType(pt, scope->iff->module, scope, &ct->cppsig->args[a]); /* Handle the Python signature. */ for (a = 0; a < ct -> pysig.nrArgs; ++a) { argDef *ad = &ct -> pysig.args[a]; getBaseType(pt, scope->iff->module, scope, ad); if (!supportedType(scope,NULL,ad,FALSE) && (ct -> cppsig == &ct -> pysig || ct -> methodcode == NULL))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -