You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by nw...@apache.org on 2014/08/19 20:11:59 UTC

[1/2] git commit: Omit empty ivars struct

Repository: lucy-clownfish
Updated Branches:
  refs/heads/solaris_fixes [created] 0709cab66


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/solaris_fixes
Commit: b498b46cb6bdf6ec67d0f25bc261bd72236f2b10
Parents: c8f1158
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Tue Aug 19 18:12:08 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
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;
 }
 


[2/2] git commit: Regenerate charmonizer.c with Solaris fixes

Posted by nw...@apache.org.
Regenerate charmonizer.c with Solaris fixes


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

Branch: refs/heads/solaris_fixes
Commit: 0709cab66dae8d00f7c670edad8f2301defe044d
Parents: b498b46
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Tue Aug 19 18:14:11 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Tue Aug 19 20:02:57 2014 +0200

----------------------------------------------------------------------
 compiler/common/charmonizer.c | 97 +++++++++++++++++++++++++++++---------
 runtime/common/charmonizer.c  | 97 +++++++++++++++++++++++++++++---------
 2 files changed, 152 insertions(+), 42 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0709cab6/compiler/common/charmonizer.c
----------------------------------------------------------------------
diff --git a/compiler/common/charmonizer.c b/compiler/common/charmonizer.c
index e040cb7..d5d9392 100644
--- a/compiler/common/charmonizer.c
+++ b/compiler/common/charmonizer.c
@@ -94,6 +94,7 @@ chaz_SharedLib_export_filename(chaz_SharedLib *lib);
 #define CHAZ_CFLAGS_STYLE_POSIX  1
 #define CHAZ_CFLAGS_STYLE_GNU    2
 #define CHAZ_CFLAGS_STYLE_MSVC   3
+#define CHAZ_CFLAGS_STYLE_SUN_C  4
 
 typedef struct chaz_CFlags chaz_CFlags;
 
@@ -256,6 +257,9 @@ chaz_CC_gcc_version(void);
 int
 chaz_CC_msvc_version_num(void);
 
+int
+chaz_CC_sun_c_version_num(void);
+
 const char*
 chaz_CC_link_command(void);
 
@@ -1792,6 +1796,9 @@ chaz_CFlags_enable_optimization(chaz_CFlags *flags) {
     else if (flags->style == CHAZ_CFLAGS_STYLE_GNU) {
         string = "-O2";
     }
+    else if (flags->style == CHAZ_CFLAGS_STYLE_SUN_C) {
+        string = "-xO4";
+    }
     else {
         /* POSIX */
         string = "-O 1";
@@ -1801,7 +1808,8 @@ chaz_CFlags_enable_optimization(chaz_CFlags *flags) {
 
 void
 chaz_CFlags_enable_debugging(chaz_CFlags *flags) {
-    if (flags->style == CHAZ_CFLAGS_STYLE_GNU) {
+    if (flags->style == CHAZ_CFLAGS_STYLE_GNU
+        || flags->style == CHAZ_CFLAGS_STYLE_SUN_C) {
         chaz_CFlags_append(flags, "-g");
     }
 }
@@ -1814,6 +1822,9 @@ chaz_CFlags_disable_strict_aliasing(chaz_CFlags *flags) {
     else if (flags->style == CHAZ_CFLAGS_STYLE_GNU) {
         chaz_CFlags_append(flags, "-fno-strict-aliasing");
     }
+    else if (flags->style == CHAZ_CFLAGS_STYLE_SUN_C) {
+        chaz_CFlags_append(flags, "-xalias_level=any");
+    }
     else {
         chaz_Util_die("Don't know how to disable strict aliasing with '%s'",
                       chaz_CC_get_cc());
@@ -1829,6 +1840,9 @@ chaz_CFlags_set_warnings_as_errors(chaz_CFlags *flags) {
     else if (flags->style == CHAZ_CFLAGS_STYLE_GNU) {
         string = "-Werror";
     }
+    else if (flags->style == CHAZ_CFLAGS_STYLE_SUN_C) {
+        string = "-errwarn=%all";
+    }
     else {
         chaz_Util_die("Don't know how to set warnings as errors with '%s'",
                       chaz_CC_get_cc());
@@ -1859,6 +1873,9 @@ chaz_CFlags_compile_shared_library(chaz_CFlags *flags) {
             return;
         }
     }
+    else if (flags->style == CHAZ_CFLAGS_STYLE_SUN_C) {
+        string = "-KPIC";
+    }
     else {
         return;
     }
@@ -1867,9 +1884,16 @@ chaz_CFlags_compile_shared_library(chaz_CFlags *flags) {
 
 void
 chaz_CFlags_hide_symbols(chaz_CFlags *flags) {
-    if (flags->style == CHAZ_CFLAGS_STYLE_GNU
-        && strcmp(chaz_OS_shared_lib_ext(), ".dll") != 0) {
-        chaz_CFlags_append(flags, "-fvisibility=hidden");
+    if (flags->style == CHAZ_CFLAGS_STYLE_GNU) {
+        if (strcmp(chaz_OS_shared_lib_ext(), ".dll") != 0) {
+            chaz_CFlags_append(flags, "-fvisibility=hidden");
+        }
+    }
+    else if (flags->style == CHAZ_CFLAGS_STYLE_SUN_C) {
+        if (chaz_CC_sun_c_version_num() >= 0x550) {
+            /* Sun Studio 8. */
+            chaz_CFlags_append(flags, "-xldscope=hidden");
+        }
     }
 }
 
@@ -1887,6 +1911,9 @@ chaz_CFlags_link_shared_library(chaz_CFlags *flags) {
             string = "-shared";
         }
     }
+    else if (flags->style == CHAZ_CFLAGS_STYLE_SUN_C) {
+        string = "-G";
+    }
     else {
         chaz_Util_die("Don't know how to link a shared library with '%s'",
                       chaz_CC_get_cc());
@@ -1897,25 +1924,31 @@ chaz_CFlags_link_shared_library(chaz_CFlags *flags) {
 void
 chaz_CFlags_set_shared_library_version(chaz_CFlags *flags,
                                        chaz_SharedLib *lib) {
-    const char *shlib_ext = chaz_OS_shared_lib_ext();
-    char       *string;
-
-    if (flags->style != CHAZ_CFLAGS_STYLE_GNU
-        || strcmp(shlib_ext, ".dll") == 0) {
-        return;
-    }
+    if (flags->style == CHAZ_CFLAGS_STYLE_GNU) {
+        const char *shlib_ext = chaz_OS_shared_lib_ext();
 
-    if (strcmp(chaz_OS_shared_lib_ext(), ".dylib") == 0) {
-        const char *version = chaz_SharedLib_get_version(lib);
-        string = chaz_Util_join(" ", "-current_version", version, NULL);
+        if (strcmp(shlib_ext, ".dylib") == 0) {
+            const char *version = chaz_SharedLib_get_version(lib);
+            char *string
+                = chaz_Util_join(" ", "-current_version", version, NULL);
+            chaz_CFlags_append(flags, string);
+            free(string);
+        }
+        else if (strcmp(shlib_ext, ".so") == 0) {
+            char *soname = chaz_SharedLib_major_version_filename(lib);
+            char *string = chaz_Util_join("", "-Wl,-soname,", soname, NULL);
+            chaz_CFlags_append(flags, string);
+            free(string);
+            free(soname);
+        }
     }
-    else {
+    else if (flags->style == CHAZ_CFLAGS_STYLE_SUN_C) {
         char *soname = chaz_SharedLib_major_version_filename(lib);
-        string = chaz_Util_join("", "-Wl,-soname,", soname, NULL);
+        char *string = chaz_Util_join(" ", "-h", soname, NULL);
+        chaz_CFlags_append(flags, string);
+        free(string);
         free(soname);
     }
-    chaz_CFlags_append(flags, string);
-    free(string);
 }
 
 void
@@ -2026,6 +2059,7 @@ static struct {
     int       intval___GNUC_PATCHLEVEL__;
     int       intval__MSC_VER;
     int       intval___clang__;
+    int       intval___SUNPRO_C;
     chaz_CFlags *extra_cflags;
     chaz_CFlags *temp_cflags;
 } chaz_CC = {
@@ -2078,6 +2112,9 @@ chaz_CC_init(const char *compiler_command, const char *compiler_flags) {
     else if (chaz_CC.intval__MSC_VER) {
         chaz_CC.cflags_style = CHAZ_CFLAGS_STYLE_MSVC;
     }
+    else if (chaz_CC.intval___SUNPRO_C) {
+        chaz_CC.cflags_style = CHAZ_CFLAGS_STYLE_SUN_C;
+    }
     else {
         chaz_CC.cflags_style = CHAZ_CFLAGS_STYLE_POSIX;
     }
@@ -2126,8 +2163,9 @@ chaz_CC_detect_known_compilers(void) {
                 chaz_CC.intval___GNUC_MINOR__,
                 chaz_CC.intval___GNUC_PATCHLEVEL__);
     }
-    chaz_CC.intval__MSC_VER  = chaz_CC_detect_macro("_MSC_VER");
-    chaz_CC.intval___clang__ = chaz_CC_detect_macro("__clang__");
+    chaz_CC.intval__MSC_VER   = chaz_CC_detect_macro("_MSC_VER");
+    chaz_CC.intval___clang__  = chaz_CC_detect_macro("__clang__");
+    chaz_CC.intval___SUNPRO_C = chaz_CC_detect_macro("__SUNPRO_C");
 }
 
 void
@@ -2338,6 +2376,11 @@ chaz_CC_msvc_version_num(void) {
     return chaz_CC.intval__MSC_VER;
 }
 
+int
+chaz_CC_sun_c_version_num(void) {
+    return chaz_CC.intval___SUNPRO_C;
+}
+
 const char*
 chaz_CC_link_command() {
     if (chaz_CC.intval__MSC_VER) {
@@ -6635,7 +6678,7 @@ chaz_LargeFiles_probe_unbuff(void) {
             break;
         }
     }
-};
+}
 
 
 /***************************************************************************/
@@ -6906,6 +6949,18 @@ chaz_SymbolVisibility_run(void) {
     chaz_ConfWriter_start_module("SymbolVisibility");
     chaz_CFlags_set_warnings_as_errors(temp_cflags);
 
+    /* Sun C. */
+    if (!can_control_visibility) {
+        char export_sun[] = "__global";
+        sprintf(code_buf, chaz_SymbolVisibility_symbol_exporting_code,
+                export_sun);
+        if (chaz_CC_test_compile(code_buf)) {
+            can_control_visibility = true;
+            chaz_ConfWriter_add_def("EXPORT", export_sun);
+            chaz_ConfWriter_add_def("IMPORT", export_sun);
+        }
+    }
+
     /* Windows. */
     if (!can_control_visibility) {
         char export_win[] = "__declspec(dllexport)";

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0709cab6/runtime/common/charmonizer.c
----------------------------------------------------------------------
diff --git a/runtime/common/charmonizer.c b/runtime/common/charmonizer.c
index 8e138ba..08f431d 100644
--- a/runtime/common/charmonizer.c
+++ b/runtime/common/charmonizer.c
@@ -94,6 +94,7 @@ chaz_SharedLib_export_filename(chaz_SharedLib *lib);
 #define CHAZ_CFLAGS_STYLE_POSIX  1
 #define CHAZ_CFLAGS_STYLE_GNU    2
 #define CHAZ_CFLAGS_STYLE_MSVC   3
+#define CHAZ_CFLAGS_STYLE_SUN_C  4
 
 typedef struct chaz_CFlags chaz_CFlags;
 
@@ -256,6 +257,9 @@ chaz_CC_gcc_version(void);
 int
 chaz_CC_msvc_version_num(void);
 
+int
+chaz_CC_sun_c_version_num(void);
+
 const char*
 chaz_CC_link_command(void);
 
@@ -1792,6 +1796,9 @@ chaz_CFlags_enable_optimization(chaz_CFlags *flags) {
     else if (flags->style == CHAZ_CFLAGS_STYLE_GNU) {
         string = "-O2";
     }
+    else if (flags->style == CHAZ_CFLAGS_STYLE_SUN_C) {
+        string = "-xO4";
+    }
     else {
         /* POSIX */
         string = "-O 1";
@@ -1801,7 +1808,8 @@ chaz_CFlags_enable_optimization(chaz_CFlags *flags) {
 
 void
 chaz_CFlags_enable_debugging(chaz_CFlags *flags) {
-    if (flags->style == CHAZ_CFLAGS_STYLE_GNU) {
+    if (flags->style == CHAZ_CFLAGS_STYLE_GNU
+        || flags->style == CHAZ_CFLAGS_STYLE_SUN_C) {
         chaz_CFlags_append(flags, "-g");
     }
 }
@@ -1814,6 +1822,9 @@ chaz_CFlags_disable_strict_aliasing(chaz_CFlags *flags) {
     else if (flags->style == CHAZ_CFLAGS_STYLE_GNU) {
         chaz_CFlags_append(flags, "-fno-strict-aliasing");
     }
+    else if (flags->style == CHAZ_CFLAGS_STYLE_SUN_C) {
+        chaz_CFlags_append(flags, "-xalias_level=any");
+    }
     else {
         chaz_Util_die("Don't know how to disable strict aliasing with '%s'",
                       chaz_CC_get_cc());
@@ -1829,6 +1840,9 @@ chaz_CFlags_set_warnings_as_errors(chaz_CFlags *flags) {
     else if (flags->style == CHAZ_CFLAGS_STYLE_GNU) {
         string = "-Werror";
     }
+    else if (flags->style == CHAZ_CFLAGS_STYLE_SUN_C) {
+        string = "-errwarn=%all";
+    }
     else {
         chaz_Util_die("Don't know how to set warnings as errors with '%s'",
                       chaz_CC_get_cc());
@@ -1859,6 +1873,9 @@ chaz_CFlags_compile_shared_library(chaz_CFlags *flags) {
             return;
         }
     }
+    else if (flags->style == CHAZ_CFLAGS_STYLE_SUN_C) {
+        string = "-KPIC";
+    }
     else {
         return;
     }
@@ -1867,9 +1884,16 @@ chaz_CFlags_compile_shared_library(chaz_CFlags *flags) {
 
 void
 chaz_CFlags_hide_symbols(chaz_CFlags *flags) {
-    if (flags->style == CHAZ_CFLAGS_STYLE_GNU
-        && strcmp(chaz_OS_shared_lib_ext(), ".dll") != 0) {
-        chaz_CFlags_append(flags, "-fvisibility=hidden");
+    if (flags->style == CHAZ_CFLAGS_STYLE_GNU) {
+        if (strcmp(chaz_OS_shared_lib_ext(), ".dll") != 0) {
+            chaz_CFlags_append(flags, "-fvisibility=hidden");
+        }
+    }
+    else if (flags->style == CHAZ_CFLAGS_STYLE_SUN_C) {
+        if (chaz_CC_sun_c_version_num() >= 0x550) {
+            /* Sun Studio 8. */
+            chaz_CFlags_append(flags, "-xldscope=hidden");
+        }
     }
 }
 
@@ -1887,6 +1911,9 @@ chaz_CFlags_link_shared_library(chaz_CFlags *flags) {
             string = "-shared";
         }
     }
+    else if (flags->style == CHAZ_CFLAGS_STYLE_SUN_C) {
+        string = "-G";
+    }
     else {
         chaz_Util_die("Don't know how to link a shared library with '%s'",
                       chaz_CC_get_cc());
@@ -1897,25 +1924,31 @@ chaz_CFlags_link_shared_library(chaz_CFlags *flags) {
 void
 chaz_CFlags_set_shared_library_version(chaz_CFlags *flags,
                                        chaz_SharedLib *lib) {
-    const char *shlib_ext = chaz_OS_shared_lib_ext();
-    char       *string;
-
-    if (flags->style != CHAZ_CFLAGS_STYLE_GNU
-        || strcmp(shlib_ext, ".dll") == 0) {
-        return;
-    }
+    if (flags->style == CHAZ_CFLAGS_STYLE_GNU) {
+        const char *shlib_ext = chaz_OS_shared_lib_ext();
 
-    if (strcmp(chaz_OS_shared_lib_ext(), ".dylib") == 0) {
-        const char *version = chaz_SharedLib_get_version(lib);
-        string = chaz_Util_join(" ", "-current_version", version, NULL);
+        if (strcmp(shlib_ext, ".dylib") == 0) {
+            const char *version = chaz_SharedLib_get_version(lib);
+            char *string
+                = chaz_Util_join(" ", "-current_version", version, NULL);
+            chaz_CFlags_append(flags, string);
+            free(string);
+        }
+        else if (strcmp(shlib_ext, ".so") == 0) {
+            char *soname = chaz_SharedLib_major_version_filename(lib);
+            char *string = chaz_Util_join("", "-Wl,-soname,", soname, NULL);
+            chaz_CFlags_append(flags, string);
+            free(string);
+            free(soname);
+        }
     }
-    else {
+    else if (flags->style == CHAZ_CFLAGS_STYLE_SUN_C) {
         char *soname = chaz_SharedLib_major_version_filename(lib);
-        string = chaz_Util_join("", "-Wl,-soname,", soname, NULL);
+        char *string = chaz_Util_join(" ", "-h", soname, NULL);
+        chaz_CFlags_append(flags, string);
+        free(string);
         free(soname);
     }
-    chaz_CFlags_append(flags, string);
-    free(string);
 }
 
 void
@@ -2026,6 +2059,7 @@ static struct {
     int       intval___GNUC_PATCHLEVEL__;
     int       intval__MSC_VER;
     int       intval___clang__;
+    int       intval___SUNPRO_C;
     chaz_CFlags *extra_cflags;
     chaz_CFlags *temp_cflags;
 } chaz_CC = {
@@ -2078,6 +2112,9 @@ chaz_CC_init(const char *compiler_command, const char *compiler_flags) {
     else if (chaz_CC.intval__MSC_VER) {
         chaz_CC.cflags_style = CHAZ_CFLAGS_STYLE_MSVC;
     }
+    else if (chaz_CC.intval___SUNPRO_C) {
+        chaz_CC.cflags_style = CHAZ_CFLAGS_STYLE_SUN_C;
+    }
     else {
         chaz_CC.cflags_style = CHAZ_CFLAGS_STYLE_POSIX;
     }
@@ -2126,8 +2163,9 @@ chaz_CC_detect_known_compilers(void) {
                 chaz_CC.intval___GNUC_MINOR__,
                 chaz_CC.intval___GNUC_PATCHLEVEL__);
     }
-    chaz_CC.intval__MSC_VER  = chaz_CC_detect_macro("_MSC_VER");
-    chaz_CC.intval___clang__ = chaz_CC_detect_macro("__clang__");
+    chaz_CC.intval__MSC_VER   = chaz_CC_detect_macro("_MSC_VER");
+    chaz_CC.intval___clang__  = chaz_CC_detect_macro("__clang__");
+    chaz_CC.intval___SUNPRO_C = chaz_CC_detect_macro("__SUNPRO_C");
 }
 
 void
@@ -2338,6 +2376,11 @@ chaz_CC_msvc_version_num(void) {
     return chaz_CC.intval__MSC_VER;
 }
 
+int
+chaz_CC_sun_c_version_num(void) {
+    return chaz_CC.intval___SUNPRO_C;
+}
+
 const char*
 chaz_CC_link_command() {
     if (chaz_CC.intval__MSC_VER) {
@@ -6635,7 +6678,7 @@ chaz_LargeFiles_probe_unbuff(void) {
             break;
         }
     }
-};
+}
 
 
 /***************************************************************************/
@@ -6906,6 +6949,18 @@ chaz_SymbolVisibility_run(void) {
     chaz_ConfWriter_start_module("SymbolVisibility");
     chaz_CFlags_set_warnings_as_errors(temp_cflags);
 
+    /* Sun C. */
+    if (!can_control_visibility) {
+        char export_sun[] = "__global";
+        sprintf(code_buf, chaz_SymbolVisibility_symbol_exporting_code,
+                export_sun);
+        if (chaz_CC_test_compile(code_buf)) {
+            can_control_visibility = true;
+            chaz_ConfWriter_add_def("EXPORT", export_sun);
+            chaz_ConfWriter_add_def("IMPORT", export_sun);
+        }
+    }
+
     /* Windows. */
     if (!can_control_visibility) {
         char export_win[] = "__declspec(dllexport)";