Skip to content

Instantly share code, notes, and snippets.

@dakcarto
Created December 22, 2016 20:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dakcarto/cdc9054c6125e054f5ec016b1dc76646 to your computer and use it in GitHub Desktop.
Save dakcarto/cdc9054c6125e054f5ec016b1dc76646 to your computer and use it in GitHub Desktop.
diff --git a/sipgen/gencode.c b/sipgen/gencode.c
index c5707ef..7b477a8 100644
--- a/sipgen/gencode.c
+++ b/sipgen/gencode.c
@@ -5913,15 +5913,20 @@ static void generateClassFunctions(sipSpec *pt, moduleDef *mod, classDef *cd,
else if (md->slot != no_slot)
generateSlot(mod, cd, NULL, md, fp);
- /* The cast function. */
- if (needsCastFunction(cd))
+ /*
+ * The cast function. Note that we used to try and work out if the cast
+ * function was really needed (eg. only for multiple inheritance) but there
+ * are subtle cases where, even for single inheritance, it is needed. We
+ * take the conservative approach and generate it for all derived classes.
+ */
+ if (cd->supers != NULL)
{
mroDef *mro;
prcode(fp,
"\n"
"\n"
-"/* Cast a pointer to a type somewhere in its multiple inheritance hierarchy. */\n"
+"/* Cast a pointer to a type somewhere in its inheritance hierarchy. */\n"
"extern \"C\" {static void *cast_%L(void *, const sipTypeDef *);}\n"
"static void *cast_%L(void *sipCppV, const sipTypeDef *targetType)\n"
"{\n"
@@ -5935,9 +5940,10 @@ static void generateClassFunctions(sipSpec *pt, moduleDef *mod, classDef *cd,
"\n"
);
- for (mro = cd->mro; mro != NULL; mro = mro->next)
+ /* Skip the the class itself. */
+ for (mro = cd->mro->next; mro != NULL; mro = mro->next)
{
- if (needsCast(mro) && !isDuplicateSuper(mro) && !hasDuplicateSuper(mro))
+ if (!isDuplicateSuper(mro) && !hasDuplicateSuper(mro))
{
prcode(fp,
" if (targetType == sipType_%C)\n"
@@ -10446,7 +10452,7 @@ static void generateTypeDefinition(sipSpec *pt, classDef *cd, FILE *fp)
" release_%L,\n"
, cd->iff);
- if (needsCastFunction(cd))
+ if (cd->supers != NULL)
prcode(fp,
" cast_%L,\n"
, cd->iff);
diff --git a/sipgen/sip.h b/sipgen/sip.h
index 562058d..a5ed8a4 100644
--- a/sipgen/sip.h
+++ b/sipgen/sip.h
@@ -205,7 +205,6 @@
#define CLASS2_TMPL_ARG 0x01 /* The class is a template argument. */
#define CLASS2_MIXIN 0x02 /* The class is a mixin. */
#define CLASS2_EXPORT_DERIVED 0x04 /* Export the derived class declaration. */
-#define CLASS2_NEEDS_CAST_FUNC 0x08 /* The class needs a cast function. */
#define isTemplateArg(cd) ((cd)->classflags2 & CLASS2_TMPL_ARG)
#define setTemplateArg(cd) ((cd)->classflags2 |= CLASS2_TMPL_ARG)
@@ -213,8 +212,6 @@
#define setMixin(cd) ((cd)->classflags2 |= CLASS2_MIXIN)
#define isExportDerived(cd) ((cd)->classflags2 & CLASS2_EXPORT_DERIVED)
#define setExportDerived(cd) ((cd)->classflags2 |= CLASS2_EXPORT_DERIVED)
-#define needsCastFunction(cd) ((cd)->classflags2 & CLASS2_NEEDS_CAST_FUNC)
-#define setNeedsCastFunction(cd) ((cd)->classflags2 |= CLASS2_NEEDS_CAST_FUNC)
/* Handle ctor flags. These are combined with the section flags. */
@@ -293,7 +290,6 @@
#define HIER_IS_DUPLICATE 0x0001 /* It is a super class duplicate. */
#define HIER_HAS_DUPLICATE 0x0002 /* It has a super class duplicate. */
#define HIER_BEING_SET 0x0004 /* The MRO is being set. */
-#define HIER_NEEDS_CAST 0x0008 /* The class needs an explicit cast. */
#define isDuplicateSuper(m) ((m)->mroflags & HIER_IS_DUPLICATE)
#define setIsDuplicateSuper(m) ((m)->mroflags |= HIER_IS_DUPLICATE)
@@ -302,8 +298,6 @@
#define hierBeingSet(m) ((m)->mroflags & HIER_BEING_SET)
#define setHierBeingSet(m) ((m)->mroflags |= HIER_BEING_SET)
#define resetHierBeingSet(m) ((m)->mroflags &= ~HIER_BEING_SET)
-#define needsCast(m) ((m)->mroflags & HIER_NEEDS_CAST)
-#define setNeedsCast(m) ((m)->mroflags |= HIER_NEEDS_CAST)
/* Handle overload flags. These are combined with the section flags. */
diff --git a/sipgen/transform.c b/sipgen/transform.c
index 775c98f..0d88af9 100644
--- a/sipgen/transform.c
+++ b/sipgen/transform.c
@@ -1237,24 +1237,11 @@ static void setHierarchy(sipSpec *pt, classDef *base, classDef *cd,
/* Make sure the super-class's hierarchy has been done. */
setHierarchy(pt, base, cl->cd, head);
- if (needsCastFunction(cl->cd))
- setNeedsCastFunction(cd);
-
/* Append the super-classes hierarchy. */
for (mro = cl->cd->mro; mro != NULL; mro = mro->next)
{
mroDef *new_mro = appendToMRO(cd->mro, &tailp, mro->cd);
- if (cl != cd->supers || needsCast(mro))
- {
- /*
- * It's not the class's first super-class so it will need a
- * cast function.
- */
- setNeedsCast(new_mro);
- setNeedsCastFunction(cd);
- }
-
if (isDeprecatedClass(mro->cd))
setIsDeprecatedClass(cd);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment