Repository: lucy-clownfish
Updated Branches:
  refs/heads/master c8f1158d0 -> d00b1e7c0


Omit empty ivars struct

Empty structures are a GCC extension.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/b498b46c
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/b498b46c
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/b498b46c

Branch: refs/heads/master
Commit: b498b46cb6bdf6ec67d0f25bc261bd72236f2b10
Parents: c8f1158
Author: Nick Wellnhofer <[email protected]>
Authored: Tue Aug 19 18:12:08 2014 +0200
Committer: Nick Wellnhofer <[email protected]>
Committed: Tue Aug 19 18:12:08 2014 +0200

----------------------------------------------------------------------
 compiler/src/CFCBindClass.c | 73 ++++++++++++++++++++++++++++++----------
 1 file changed, 55 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/b498b46c/compiler/src/CFCBindClass.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCBindClass.c b/compiler/src/CFCBindClass.c
index 86caeac..5f2ef24 100644
--- a/compiler/src/CFCBindClass.c
+++ b/compiler/src/CFCBindClass.c
@@ -45,6 +45,11 @@ S_to_c_header_inert(CFCBindClass *self);
 static char*
 S_to_c_header_dynamic(CFCBindClass *self);
 
+// Count the number of member variables declared in ancestor classes
+// outside this package.
+static int
+S_count_non_package_members(CFCBindClass *self);
+
 // Create the definition for the instantiable object struct.
 static char*
 S_struct_definition(CFCBindClass *self);
@@ -403,6 +408,25 @@ CFCBindClass_to_c_data(CFCBindClass *self) {
     return code;
 }
 
+// Count the number of member variables declared in ancestor classes
+// outside this package.
+static int
+S_count_non_package_members(CFCBindClass *self) {
+    CFCClass  *const client = self->client;
+    CFCParcel *parcel       = CFCClass_get_parcel(client);
+    CFCClass  *ancestor     = CFCClass_get_parent(client);
+    int num_non_package_members = 0;
+
+    while (ancestor && CFCClass_get_parcel(ancestor) == parcel) {
+        ancestor = CFCClass_get_parent(ancestor);
+    }
+    if (ancestor) {
+        num_non_package_members = CFCClass_num_member_vars(ancestor);
+    }
+
+    return num_non_package_members;
+}
+
 // Create the definition for the instantiable object struct.
 static char*
 S_struct_definition(CFCBindClass *self) {
@@ -419,27 +443,24 @@ S_struct_definition(CFCBindClass *self) {
         struct_sym = CFCClass_full_ivars_struct(client);
     }
 
-    // Count the number of member variables declared in ancestor classes
-    // outside this package so that we can skip over them.
-    int num_non_package_members = 0;
-    CFCParcel *parcel = CFCClass_get_parcel(client);
-    CFCClass *ancestor = CFCClass_get_parent(client);
-    while (ancestor && CFCClass_get_parcel(ancestor) == parcel) {
-        ancestor = CFCClass_get_parent(ancestor);
-    }
-    if (ancestor) {
-        num_non_package_members = CFCClass_num_member_vars(ancestor);
-    }
-
     // Add all member variables declared by classes in this package.
     CFCVariable **member_vars = CFCClass_member_vars(client);
+    int num_non_package_members = S_count_non_package_members(self);
     for (int i = num_non_package_members; member_vars[i] != NULL; i++) {
         const char *member_dec = CFCVariable_local_declaration(member_vars[i]);
         member_decs = CFCUtil_cat(member_decs, "\n    ", member_dec, NULL);
     }
 
-    char pattern[] = "struct %s {%s\n};\n";
-    char *struct_def = CFCUtil_sprintf(pattern, struct_sym, member_decs);
+    char *struct_def;
+
+    if (member_decs[0] == '\0') {
+        // Don't define empty struct.
+        struct_def = CFCUtil_strdup("");
+    }
+    else {
+        char pattern[] = "struct %s {%s\n};\n";
+        struct_def = CFCUtil_sprintf(pattern, struct_sym, member_decs);
+    }
 
     FREEMEM(member_decs);
     return struct_def;
@@ -501,8 +522,23 @@ CFCBindClass_spec_def(CFCBindClass *self) {
                                                 class_var)
                               : CFCUtil_strdup("NULL");
 
-    const char *ivars_or_not = strcmp(prefix, "cfish_") == 0
-                               ? struct_sym : ivars_struct;
+    char *ivars_size = NULL;
+
+    if (strcmp(prefix, "cfish_") == 0) {
+        ivars_size = CFCUtil_sprintf("sizeof(%s)", struct_sym);
+    }
+    else {
+        int num_non_package_members = S_count_non_package_members(self);
+        int num_members             = CFCClass_num_member_vars(client);
+
+        if (num_non_package_members == num_members) {
+            // No members in this package.
+            ivars_size = CFCUtil_strdup("0");
+        }
+        else {
+            ivars_size = CFCUtil_sprintf("sizeof(%s)", ivars_struct);
+        }
+    }
     const char *ivars_offset_name = CFCClass_full_ivars_offset(client);
 
     char pattern[] =
@@ -510,7 +546,7 @@ CFCBindClass_spec_def(CFCBindClass *self) {
         "        &%s, /* class */\n"
         "        %s, /* parent */\n"
         "        \"%s\", /* name */\n"
-        "        sizeof(%s), /* ivars_size */\n"
+        "        %s, /* ivars_size */\n"
         "        &%s, /* ivars_offset_ptr */\n"
         "        %d, /* num_novel */\n"
         "        %d, /* num_overridden */\n"
@@ -521,7 +557,7 @@ CFCBindClass_spec_def(CFCBindClass *self) {
         "    }";
     char *code
         = CFCUtil_sprintf(pattern, class_var, parent_ref, class_name,
-                          ivars_or_not, ivars_offset_name, num_novel,
+                          ivars_size, ivars_offset_name, num_novel,
                           num_overridden, num_inherited, novel_ms_var,
                           overridden_ms_var, inherited_ms_var);
 
@@ -529,6 +565,7 @@ CFCBindClass_spec_def(CFCBindClass *self) {
     FREEMEM(novel_ms_var);
     FREEMEM(overridden_ms_var);
     FREEMEM(inherited_ms_var);
+    FREEMEM(ivars_size);
     return code;
 }
 

Reply via email to