📄 transform.c
字号:
if (!sameScopedName(a1 -> u.snd,a2 -> u.snd)) return FALSE; break; case mapped_type: if (a1 -> u.mtd != a2 -> u.mtd) return FALSE; break; } /* Must be the same if we've got this far. */ return TRUE;}/* * Return TRUE if two scoped names are the same. */int sameScopedName(scopedNameDef *snd1,scopedNameDef *snd2){ while (snd1 != NULL && snd2 != NULL && strcmp(snd1 -> name,snd2 -> name) == 0) { snd1 = snd1 -> next; snd2 = snd2 -> next; } return (snd1 == NULL && snd2 == NULL);}/* * Add an explicit scope to the default value of an argument if possible. */static void scopeDefaultValue(sipSpec *pt,classDef *cd,argDef *ad){ valueDef *vd, **tailp, *newvd; /* * We do a quick check to see if we need to do anything. This means * we can limit the times we need to copy the default value. It needs * to be copied because it will be shared by class versions that have * been created on the fly and it may need to be scoped differently for * each of those versions. */ for (vd = ad -> defval; vd != NULL; vd = vd -> next) if (vd -> vtype == scoped_value && vd -> u.vscp -> next == NULL) break; if (vd == NULL) return; /* * It's not certain that we will do anything, but we assume we will and * start copying. */ newvd = NULL; tailp = &newvd; for (vd = ad -> defval; vd != NULL; vd = vd -> next) { mroDef *mro; scopedNameDef *origname; valueDef *new; /* Make the copy. */ new = sipMalloc(sizeof (valueDef)); *new = *vd; *tailp = new; tailp = &new -> next; /* * Skip this part of the expression if it isn't a named value * or it already has a scope. */ if (vd -> vtype != scoped_value || vd -> u.vscp -> next != NULL) continue; /* * Search the class hierarchy for an enum value with the same * name. If we don't find one, leave it as it is (the compiler * will find out if this is a problem). */ origname = vd -> u.vscp; for (mro = cd -> mro; mro != NULL; mro = mro -> next) { enumDef *ed; if (isDuplicateSuper(mro)) continue; for (ed = pt -> enums; ed != NULL; ed = ed -> next) { enumMemberDef *emd; if (ed -> ecd != mro -> cd) continue; for (emd = ed -> members; emd != NULL; emd = emd -> next) if (strcmp(emd -> cname,origname -> name) == 0) { scopedNameDef *snd; /* * Take the scope from the * class that the enum was * defined in. */ snd = copyScopedName(mro -> cd -> iff -> fqcname); appendScopedName(&snd,origname); new -> u.vscp = snd; /* Nothing more to do. */ break; } if (emd != NULL) break; } if (ed != NULL) break; } } ad -> defval = newvd;}/* * Make sure a type is a base type. */static void getBaseType(sipSpec *pt, moduleDef *mod, classDef *defscope, argDef *type){ /* Loop until we've got to a base type. */ while (type -> atype == defined_type) { scopedNameDef *snd = type -> u.snd; type -> atype = no_type; if (defscope != NULL) searchScope(pt,defscope,snd,type); if (type -> atype == no_type) searchMappedTypes(pt,snd,type); if (type -> atype == no_type) searchTypedefs(pt,snd,type); if (type -> atype == no_type) searchEnums(pt,snd,type); if (type -> atype == no_type) searchClasses(pt, mod, snd, type); if (type -> atype == no_type) fatalNoDefinedType(snd); } /* Get the base of type of any slot arguments. */ if (type -> atype == slotcon_type || type -> atype == slotdis_type) { int sa; for (sa = 0; sa < type -> u.sa -> nrArgs; ++sa) getBaseType(pt, mod, defscope, &type->u.sa->args[sa]); } /* See if the type refers to an instantiated template. */ if (type->atype == template_type) { classDef *cd; for (cd = pt->classes; cd != NULL; cd = cd->next) if (cd->td != NULL && sameScopedName(cd->td->fqname, type->u.td->fqname) && sameSignature(&cd->td->types, &type->u.td->types, TRUE)) { type->atype = class_type; type->u.cd = cd; break; } } /* Replace the base type if it has been mapped. */ if (type -> atype == struct_type || type -> atype == template_type) { searchMappedTypes(pt,NULL,type); /* * If we still have a template then see if we need to * automatically instantiate it. */ if (type->atype == template_type) { mappedTypeTmplDef *mtt; for (mtt = pt->mappedtypetemplates; mtt != NULL; mtt = mtt->next) if (sameScopedName(type->u.td->fqname, mtt->mt->type.u.td->fqname) && sameTemplateSignature(&type->u.td->types, &mtt->mt->type.u.td->types, TRUE)) { type->u.mtd = instantiateMappedTypeTemplate(pt, mod, mtt, type); type->atype = mapped_type; break; } } }}/* * Instantiate a mapped type template and return it. */static mappedTypeDef *instantiateMappedTypeTemplate(sipSpec *pt, moduleDef *mod, mappedTypeTmplDef *mtt, argDef *type){ scopedNameDef *type_names, *type_values; mappedTypeDef *mtd; type_names = type_values = NULL; appendTypeStrings(type->u.td->fqname, &mtt->mt->type.u.td->types, &type->u.td->types, &mtt->sig, &type_names, &type_values); mtd = allocMappedType(type); mtd->iff = findIfaceFile(pt, mod, type->u.td->fqname, mappedtype_iface, type); mtd->iff->module = mod; mtd->hdrcode = templateCode(pt, &mtd->iff->used, mtt->mt->hdrcode, type_names, type_values); mtd->convfromcode = templateCode(pt, &mtd->iff->used, mtt->mt->convfromcode, type_names, type_values); mtd->convtocode = templateCode(pt, &mtd->iff->used, mtt->mt->convtocode, type_names, type_values); mtd->next = pt->mappedtypes; pt->mappedtypes = mtd; if (type_names != NULL) freeScopedName(type_names); if (type_values != NULL) freeScopedName(type_values); return mtd;}/* * Search for a name in a scope and return the corresponding type. */static void searchScope(sipSpec *pt,classDef *scope,scopedNameDef *snd, argDef *ad){ scopedNameDef *tmpsnd = NULL; mroDef *mro; for (mro = scope -> mro; mro != NULL; mro = mro -> next) { if (isDuplicateSuper(mro)) continue; /* Append the name to the scope and see if it exists. */ tmpsnd = copyScopedName(classFQCName(mro -> cd)); appendScopedName(&tmpsnd,copyScopedName(snd)); searchMappedTypes(pt,tmpsnd,ad); if (ad -> atype != no_type) break; searchTypedefs(pt,tmpsnd,ad); if (ad -> atype != no_type) break; searchEnums(pt,tmpsnd,ad); if (ad -> atype != no_type) break; searchClasses(pt, scope, tmpsnd, ad); if (ad -> atype != no_type) break; freeScopedName(tmpsnd); tmpsnd = NULL; } if (tmpsnd != NULL) freeScopedName(tmpsnd);}/* * Search the mapped types for a name and return the type. */static void searchMappedTypes(sipSpec *pt,scopedNameDef *snd,argDef *ad){ mappedTypeDef *mtd; scopedNameDef *oname; /* Patch back to defined types so we can use sameBaseType(). */ if (snd != NULL) { oname = ad -> u.snd; ad -> u.snd = snd; ad -> atype = defined_type; } for (mtd = pt -> mappedtypes; mtd != NULL; mtd = mtd -> next) if (sameBaseType(ad,&mtd -> type)) { /* Copy the type. */ ad -> atype = mapped_type; ad -> u.mtd = mtd; return; } /* Restore because we didn't find anything. */ if (snd != NULL) { ad -> u.snd = oname; ad -> atype = no_type; }}/* * Search the typedefs for a name and return the type. */static void searchTypedefs(sipSpec *pt,scopedNameDef *snd,argDef *ad){ typedefDef *td; for (td = pt -> typedefs; td != NULL; td = td -> next) if (sameScopedName(td -> fqname,snd)) { /* Copy the type. */ ad -> atype = td -> type.atype; ad -> argflags |= td -> type.argflags; ad -> nrderefs += td -> type.nrderefs; ad -> u = td -> type.u; break; }}/* * Search the enums for a name and return the type. */static void searchEnums(sipSpec *pt,scopedNameDef *snd,argDef *ad){ enumDef *ed; for (ed = pt -> enums; ed != NULL; ed = ed -> next) { if (ed -> fqcname == NULL) continue; if (sameScopedName(ed -> fqcname,snd)) { ad -> atype = enum_type; ad -> u.ed = ed; break; } }}/* * Search the classes for a name and return the type. */static void searchClasses(sipSpec *pt, moduleDef *mod, scopedNameDef *snd, argDef *ad){ classDef *cd; for (cd = pt -> classes; cd != NULL; cd = cd -> next) if ((cd->iff->module == mod || !isExternal(cd)) && sameScopedName(classFQCName(cd), snd)) { ad -> atype = class_type; ad -> u.cd = cd; break; }}/* * Print an error message describing an undefined type to stderr and terminate. */static void fatalNoDefinedType(scopedNameDef *snd){ fatalScopedName(snd); fatal(" is undefined\n");}/* * Make sure all external interface files for all other functions of a module * are used. */static void ifaceFilesAreUsedFromOther(sipSpec *pt, signatureDef *sd){ int a; ifaceFileDef *iff; if ((iff = getIfaceFile(&sd->result)) != NULL && iff->module != pt->module) addToUsedList(&pt->used, iff); for (a = 0; a < sd->nrArgs; ++a) if ((iff = getIfaceFile(&sd->args[a])) != NULL && iff->module != pt->module) addToUsedList(&pt->used, iff);}/* * Make sure all interface files for all overloads of a method are used. */static void ifaceFilesAreUsedByMethod(sipSpec *pt, classDef *cd, memberDef *md){ overDef *od; for (od = cd -> overs; od != NULL; od = od -> next) if (od -> common == md) ifaceFilesAreUsed(pt, cd->iff, od);}/* * Make sure all interface files for a signature are used. */static void ifaceFilesAreUsed(sipSpec *pt, ifaceFileDef *iff, overDef *od){ int a; ifaceFileIsUsed(pt, iff, &od->pysig.result); for (a = 0; a < od -> pysig.nrArgs; ++a) ifaceFileIsUsed(pt, iff, &od->pysig.args[a]);}/* * If a type has an interface file then add it to the appropriate list of used * interface files so that the header file is #included in the generated code. */static void ifaceFileIsUsed(sipSpec *pt, ifaceFileDef *iff, argDef *ad){ ifaceFileDef *usediff; if ((usediff = getIfaceFile(ad)) != NULL && usediff != iff) { ifaceFileList *iffl, **used; used = (iff != NULL ? &iff->used : &pt->used); iffl = addToUsedList(used, usediff); /* * If the type is a protected enum then its scoping shadow * class is needed in the generated header file. */ if (ad->atype == enum_type && isProtectedEnum(ad->u.ed)) iffl->header = TRUE; }}/* * Return the interface file for a type, or NULL if it doesn't have one. */static ifaceFileDef *getIfaceFile(argDef *ad){ ifaceFileDef *iff; switch (ad -> atype) { case class_type: iff = ad -> u.cd -> iff; break; case mapped_type: iff = ad -> u.mtd -> iff; break; case enum_type: if (ad -> u.ed -> fqcname != NULL && ad -> u.ed -> ecd != NULL) { iff = ad -> u.ed -> ecd -> iff; break; } /* Drop through. */ default: iff = NULL; } return iff;}/* * Position a class so that it is after all its super-classes. */static void positionClass(classDef *cd){ classList *cl; /* See if it has already been done. */ if (cd -> node -> ordered) return; for (cl = cd -> supers; cl != NULL; cl = cl -> next) { nodeDef **ndp, *nd1, *nd2, *rp; /* Ignore super-classes from different modules. */ if (cl -> cd -> iff -> module != cd -> iff -> module) continue; /* Make sure the super-class is positioned. */ positionClass(cl -> cd); /* * Find ancestors of the two that are siblings (ie. they have a * common parent). */ rp = &cd -> iff -> module -> root; for (nd1 = cd -> node; nd1 != rp; nd1 = nd1 -> parent) { for (nd2 = cl -> cd -> node; nd2 != rp; nd2 = nd2 -> parent) if (nd1 -> parent == nd2 -> parent) break; if (nd2 != rp) break; } /* * The first node must appear after the second in the common * parent's list of children. */ for (ndp = &nd1 -> parent -> child; *ndp != NULL; ndp = &(*ndp) -> next) { nodeDef *nd = *ndp; if (nd == nd2) break; if (nd == nd1) { /* Remove this one from the list. */ *ndp = nd -> next; /* Find the super-class ancestor. */ while (*ndp != nd2) ndp = &(*ndp) -> next; /* * Put this one back after the super-class * ancestor. */ nd -> next = (*ndp) -> next; (*ndp) -> next = nd; break; } } } cd -> node -> ordered = TRUE;}/* * Make sure a class is in the namespace tree. */static void addNodeToParent(nodeDef *root,classDef *cd){ nodeDef *nd, *parent; /* Skip classes already in the tree. */ if (cd -> node != NULL) return; /* Add this child to the parent. */ nd = sipMalloc(sizeof (nodeDef)); nd -> ordered = FALSE; nd -> cd = cd; nd -> child = NULL; /* Get the address of the parent node. */ if (cd -> ecd == NULL) parent = root; else { /* Make sure the parent is in the tree. */ addNodeToParent(root,cd -> ecd); parent = cd -> ecd -> node; } nd -> parent = parent; /* Insert this at the head of the parent's children. */ nd -> next = parent -> child; parent -> child = nd; /* Remember where we are in the tree. */ cd -> node = nd;}/* * Assign the module specific class number for a class and all it's children. */static void assignClassNrs(sipSpec *pt,moduleDef *mod,nodeDef *nd){ classDef *cd; nodeDef *cnd; /* Assign the class if it's not the root. */ if ((cd = nd -> cd) != NULL) { cd -> classnr = mod -> nrclasses++; /* * If we find a class defined in the main module called * QObject, assume it's Qt. */ if (mod == pt -> module && strcmp(classBaseName(cd),"QObject") == 0) pt -> qobjclass = cd -> classnr; } /* Assign all it's children. */ for (cnd = nd -> child; cnd != NULL; cnd = cnd -> next) assignClassNrs(pt,mod,cnd);}/* * Assign the module specific enum number for all named enums. */static void assignEnumNrs(sipSpec *pt){ enumDef *ed; for (ed = pt -> enums; ed != NULL; ed = ed -> next) if (ed -> fqcname != NULL) ed -> enumnr = ed -> module -> nrenums++;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -