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 2015/05/09 19:50:01 UTC

[04/11] lucy-clownfish git commit: Don't cache short_sym and full_sym in CFCSymbol

Don't cache short_sym and full_sym in CFCSymbol


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

Branch: refs/heads/master
Commit: 5cb287264020628edf8c48c7ed53a9a2743fb598
Parents: 5057507
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Sat Jul 26 22:17:28 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Thu May 7 21:13:59 2015 +0200

----------------------------------------------------------------------
 compiler/perl/lib/Clownfish/CFC.xs | 93 ++++++++++++++++++++-------------
 compiler/perl/t/051-symbol.t       | 10 ++--
 compiler/perl/t/300-variable.t     |  6 ++-
 compiler/src/CFCBindClass.c        | 24 +++++----
 compiler/src/CFCBindFunction.c     |  6 ++-
 compiler/src/CFCBindFunction.h     |  3 +-
 compiler/src/CFCCHtml.c            |  3 +-
 compiler/src/CFCCMan.c             |  3 +-
 compiler/src/CFCFunction.c         | 13 ++---
 compiler/src/CFCFunction.h         |  8 +--
 compiler/src/CFCPerl.c             |  3 +-
 compiler/src/CFCPerlConstructor.c  |  5 +-
 compiler/src/CFCPerlConstructor.h  |  2 +-
 compiler/src/CFCSymbol.c           | 27 +++++-----
 compiler/src/CFCSymbol.h           | 11 ++--
 compiler/src/CFCTestSymbol.c       | 12 ++++-
 compiler/src/CFCTestVariable.c     | 17 +++++-
 compiler/src/CFCVariable.c         | 34 +++++++-----
 compiler/src/CFCVariable.h         | 12 ++---
 19 files changed, 182 insertions(+), 110 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5cb28726/compiler/perl/lib/Clownfish/CFC.xs
----------------------------------------------------------------------
diff --git a/compiler/perl/lib/Clownfish/CFC.xs b/compiler/perl/lib/Clownfish/CFC.xs
index 5d40ae1..e636aa7 100644
--- a/compiler/perl/lib/Clownfish/CFC.xs
+++ b/compiler/perl/lib/Clownfish/CFC.xs
@@ -670,6 +670,27 @@ resolve_types(self)
 PPCODE:
     CFCFunction_resolve_types(self);
 
+SV*
+_various_function_syms(self, klass)
+    CFCFunction *self;
+    CFCClass    *klass;
+ALIAS:
+    short_func_sym = 1
+    full_func_sym  = 2
+CODE:
+    char *buf;
+    switch (ix) {
+        case 1:
+            buf = CFCFunction_short_func_sym(self, klass);
+            break;
+        case 2:
+            buf = CFCFunction_full_func_sym(self, klass);
+            break;
+        default: croak("Unexpected ix: %d", (int)ix);
+    }
+    RETVAL = S_sv_eat_c_string(buf);
+OUTPUT: RETVAL
+
 void
 _set_or_get(self, ...)
     CFCFunction *self;
@@ -679,8 +700,6 @@ ALIAS:
     get_docucomment    = 6
     inline             = 8
     void               = 10
-    full_func_sym      = 12
-    short_func_sym     = 14
 PPCODE:
 {
     START_SET_OR_GET_SWITCH
@@ -706,16 +725,6 @@ PPCODE:
         case 10:
             retval = newSViv(CFCFunction_void(self));
             break;
-        case 12: {
-                const char *full_sym = CFCFunction_full_func_sym(self);
-                retval = newSVpv(full_sym, strlen(full_sym));
-            }
-            break;
-        case 14: {
-                const char *short_sym = CFCFunction_short_func_sym(self);
-                retval = newSVpv(short_sym, strlen(short_sym));
-            }
-            break;
     END_SET_OR_GET_SWITCH
 }
 
@@ -1309,6 +1318,27 @@ CODE:
     RETVAL = CFCSymbol_equals(self, other);
 OUTPUT: RETVAL
 
+SV*
+_various_syms(self, klass)
+    CFCSymbol *self;
+    CFCClass  *klass;
+ALIAS:
+    short_sym = 1
+    full_sym  = 2
+CODE:
+    char *buf;
+    switch (ix) {
+        case 1:
+            buf = CFCSymbol_short_sym(self, klass);
+            break;
+        case 2:
+            buf = CFCSymbol_full_sym(self, klass);
+            break;
+        default: croak("Unexpected ix: %d", (int)ix);
+    }
+    RETVAL = S_sv_eat_c_string(buf);
+OUTPUT: RETVAL
+
 void
 _set_or_get(self, ...)
     CFCSymbol *self;
@@ -1325,8 +1355,6 @@ ALIAS:
     private            = 20
     parcel             = 22
     local              = 24
-    short_sym          = 26
-    full_sym           = 28
 PPCODE:
 {
     START_SET_OR_GET_SWITCH
@@ -1387,16 +1415,6 @@ PPCODE:
         case 24:
             retval = newSViv(CFCSymbol_local(self));
             break;
-        case 26: {
-                const char *short_sym = CFCSymbol_short_sym(self);
-                retval = newSVpvn(short_sym, strlen(short_sym));
-            }
-            break;
-        case 28: {
-                const char *full_sym = CFCSymbol_full_sym(self);
-                retval = newSVpvn(full_sym, strlen(full_sym));
-            }
-            break;
     END_SET_OR_GET_SWITCH
 }
 
@@ -1825,13 +1843,21 @@ resolve_type(self)
 PPCODE:
     CFCVariable_resolve_type(self);
 
+SV*
+global_c(self, klass)
+    CFCVariable *self;
+    CFCClass    *klass;
+CODE:
+    char *global_c = CFCVariable_global_c(self, klass);
+    RETVAL = S_sv_eat_c_string(global_c);
+OUTPUT: RETVAL
+
 void
 _set_or_get(self, ...)
     CFCVariable *self;
 ALIAS:
     get_type          = 2
     local_c           = 4
-    global_c          = 6
     local_declaration = 8
 PPCODE:
 {
@@ -1846,11 +1872,6 @@ PPCODE:
                 retval = newSVpvn(local_c, strlen(local_c));
             }
             break;
-        case 6: {
-                const char *global_c = CFCVariable_global_c(self);
-                retval = newSVpvn(global_c, strlen(global_c));
-            }
-            break;
         case 8: {
                 const char *local_dec = CFCVariable_local_declaration(self);
                 retval = newSVpvn(local_dec, strlen(local_dec));
@@ -1928,12 +1949,13 @@ OUTPUT: RETVAL
 MODULE = Clownfish::CFC  PACKAGE = Clownfish::CFC::Binding::Core::Function
 
 SV*
-func_declaration(unused, func)
-    SV *unused;
+func_declaration(unused, func, klass)
+    SV          *unused;
     CFCFunction *func;
+    CFCClass    *klass;
 CODE:
     CHY_UNUSED_VAR(unused);
-    RETVAL = S_sv_eat_c_string(CFCBindFunc_func_declaration(func));
+    RETVAL = S_sv_eat_c_string(CFCBindFunc_func_declaration(func, klass));
 OUTPUT: RETVAL
 
 MODULE = Clownfish::CFC  PACKAGE = Clownfish::CFC::Binding::Core::Method
@@ -2179,10 +2201,11 @@ CODE:
 OUTPUT: RETVAL
 
 SV*
-xsub_def(self)
+xsub_def(self, klass)
     CFCPerlConstructor *self;
+    CFCClass           *klass;
 CODE:
-    RETVAL = S_sv_eat_c_string(CFCPerlConstructor_xsub_def(self));
+    RETVAL = S_sv_eat_c_string(CFCPerlConstructor_xsub_def(self, klass));
 OUTPUT: RETVAL
 
 MODULE = Clownfish   PACKAGE = Clownfish::CFC::Binding::Perl::Class

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5cb28726/compiler/perl/t/051-symbol.t
----------------------------------------------------------------------
diff --git a/compiler/perl/t/051-symbol.t b/compiler/perl/t/051-symbol.t
index 2a6e1be..14c5262 100644
--- a/compiler/perl/t/051-symbol.t
+++ b/compiler/perl/t/051-symbol.t
@@ -19,7 +19,7 @@ use warnings;
 use Test::More tests => 40;
 use Clownfish::CFC;
 
-my $parcel = Clownfish::CFC::Model::Parcel->new( name => 'Parcel' );
+my $parcel = Clownfish::CFC::Model::Parcel->new( name => 'Eep' );
 
 for (qw( foo 1Foo Foo_Bar 1FOOBAR )) {
     eval { my $thing = new_symbol( class_name => $_ ) };
@@ -74,8 +74,12 @@ my $eep = new_symbol(
     class_name => "Op::Ork",
     name       => 'ah_ah',
 );
-is( $eep->short_sym, "Ork_ah_ah",     "short_sym" );
-is( $eep->full_sym,  "eep_Ork_ah_ah", "full_sym" );
+my $ork = Clownfish::CFC::Model::Class->create(
+    parcel     => $parcel,
+    class_name => 'Op::Ork',
+);
+is( $eep->short_sym($ork), "Ork_ah_ah",     "short_sym" );
+is( $eep->full_sym($ork),  "eep_Ork_ah_ah", "full_sym" );
 
 sub new_symbol {
     return Clownfish::CFC::Model::Symbol->new(

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5cb28726/compiler/perl/t/300-variable.t
----------------------------------------------------------------------
diff --git a/compiler/perl/t/300-variable.t b/compiler/perl/t/300-variable.t
index e31a239..83c9273 100644
--- a/compiler/perl/t/300-variable.t
+++ b/compiler/perl/t/300-variable.t
@@ -71,6 +71,9 @@ is( $var->local_c, 'float foo[1]',
     "to_c appends array to var name rather than type specifier" );
 
 my $foo_class = $parser->parse("class Foo {}");
+my $lobclaw_class = $parser->parse(
+    "class Crustacean::Lobster::LobsterClaw nickname LobClaw {}",
+);
 $var = Clownfish::CFC::Model::Variable->new(
     parcel         => 'Neato',
     name           => 'foo',
@@ -79,7 +82,8 @@ $var = Clownfish::CFC::Model::Variable->new(
     class_nickname => 'LobClaw',
 );
 $var->resolve_type;
-is( $var->global_c, 'neato_Foo* neato_LobClaw_foo', "global_c" );
+is( $var->global_c($lobclaw_class), 'neato_Foo* neato_LobClaw_foo',
+    "global_c" );
 
 isa_ok(
     $parser->parse($_),

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5cb28726/compiler/src/CFCBindClass.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCBindClass.c b/compiler/src/CFCBindClass.c
index b5df350..0c9e18c 100644
--- a/compiler/src/CFCBindClass.c
+++ b/compiler/src/CFCBindClass.c
@@ -607,7 +607,7 @@ S_sub_declarations(CFCBindClass *self) {
     char *declarations = CFCUtil_strdup("");
     for (int i = 0; functions[i] != NULL; i++) {
         CFCFunction *func = functions[i];
-        char *dec = CFCBindFunc_func_declaration(func);
+        char *dec = CFCBindFunc_func_declaration(func, self->client);
         if (!CFCFunction_inline(func)) {
             declarations = CFCUtil_cat(declarations, PREFIX, "VISIBLE ", NULL);
         }
@@ -633,9 +633,10 @@ S_inert_var_declarations(CFCBindClass *self) {
     CFCVariable **inert_vars = CFCClass_inert_vars(self->client);
     char *declarations = CFCUtil_strdup("");
     for (int i = 0; inert_vars[i] != NULL; i++) {
-        const char *global_c = CFCVariable_global_c(inert_vars[i]);
+        char *global_c = CFCVariable_global_c(inert_vars[i], self->client);
         declarations = CFCUtil_cat(declarations, "extern ", PREFIX, "VISIBLE ",
                                    global_c, ";\n", NULL);
+        FREEMEM(global_c);
     }
     return declarations;
 }
@@ -717,18 +718,23 @@ S_short_names(CFCBindClass *self) {
     CFCFunction **functions = CFCClass_functions(client);
     for (int i = 0; functions[i] != NULL; i++) {
         CFCFunction *func = functions[i];
-        short_names = CFCUtil_cat(short_names, "  #define ",
-                                  CFCFunction_short_func_sym(func), " ",
-                                  CFCFunction_full_func_sym(func), "\n",
-                                  NULL);
+        char *short_sym = CFCFunction_short_func_sym(func, client);
+        char *full_sym  = CFCFunction_full_func_sym(func, client);
+        short_names = CFCUtil_cat(short_names, "  #define ", short_sym, " ",
+                                  full_sym, "\n", NULL);
+        FREEMEM(short_sym);
+        FREEMEM(full_sym);
     }
 
     CFCVariable **inert_vars = CFCClass_inert_vars(client);
     for (int i = 0; inert_vars[i] != NULL; i++) {
         CFCVariable *var = inert_vars[i];
-        short_names = CFCUtil_cat(short_names, "  #define ",
-                                  CFCVariable_short_sym(var), " ",
-                                  CFCVariable_full_sym(var), "\n", NULL);
+        char *short_sym = CFCVariable_short_sym(var, client);
+        char *full_sym  = CFCVariable_full_sym(var, client);
+        short_names = CFCUtil_cat(short_names, "  #define ", short_sym, " ",
+                                  full_sym, "\n", NULL);
+        FREEMEM(short_sym);
+        FREEMEM(full_sym);
     }
 
     if (!CFCClass_inert(client)) {

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5cb28726/compiler/src/CFCBindFunction.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCBindFunction.c b/compiler/src/CFCBindFunction.c
index ae71d84..b562906 100644
--- a/compiler/src/CFCBindFunction.c
+++ b/compiler/src/CFCBindFunction.c
@@ -17,23 +17,25 @@
 #include <stdio.h>
 #include <string.h>
 #include "CFCBindFunction.h"
+#include "CFCClass.h"
 #include "CFCUtil.h"
 #include "CFCFunction.h"
 #include "CFCParamList.h"
 #include "CFCType.h"
 
 char*
-CFCBindFunc_func_declaration(CFCFunction *func) {
+CFCBindFunc_func_declaration(CFCFunction *func, CFCClass *klass) {
     CFCType      *return_type    = CFCFunction_get_return_type(func);
     CFCParamList *param_list     = CFCFunction_get_param_list(func);
     const char   *ret_type_str   = CFCType_to_c(return_type);
-    const char   *full_func_sym  = CFCFunction_full_func_sym(func);
     const char   *param_list_str = CFCParamList_to_c(param_list);
     const char   *inline_prop    = CFCFunction_inline(func)
                                    ? "static CFISH_INLINE "
                                    : "";
+    char *full_func_sym = CFCFunction_full_func_sym(func, klass);
     char *buf = CFCUtil_sprintf("%s%s\n%s(%s);", inline_prop, ret_type_str,
                                 full_func_sym, param_list_str);
+    FREEMEM(full_func_sym);
     return buf;
 }
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5cb28726/compiler/src/CFCBindFunction.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCBindFunction.h b/compiler/src/CFCBindFunction.h
index 5297b01..a4f127b 100644
--- a/compiler/src/CFCBindFunction.h
+++ b/compiler/src/CFCBindFunction.h
@@ -24,12 +24,13 @@
 extern "C" {
 #endif
 
+struct CFCClass;
 struct CFCFunction;
 
 /** Return C code declaring the function's C implementation.
  */
 char*
-CFCBindFunc_func_declaration(struct CFCFunction *func);
+CFCBindFunc_func_declaration(struct CFCFunction *func, struct CFCClass *klass);
 
 #ifdef __cplusplus
 }

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5cb28726/compiler/src/CFCCHtml.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCCHtml.c b/compiler/src/CFCCHtml.c
index c1b7eb9..9cb680c 100644
--- a/compiler/src/CFCCHtml.c
+++ b/compiler/src/CFCCHtml.c
@@ -505,11 +505,12 @@ S_html_create_functions(CFCClass *klass) {
 
         CFCParcel  *parcel    = CFCSymbol_get_parcel((CFCSymbol*)func);
         const char *prefix    = CFCParcel_get_prefix(parcel);
-        const char *short_sym = CFCFunction_short_func_sym(func);
 
+        char *short_sym = CFCFunction_short_func_sym(func, klass);
         char *func_html = S_html_create_func(klass, func, prefix, short_sym);
         result = CFCUtil_cat(result, func_html, NULL);
         FREEMEM(func_html);
+        FREEMEM(short_sym);
     }
 
     if (result[0] != '\0') {

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5cb28726/compiler/src/CFCCMan.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCCMan.c b/compiler/src/CFCCMan.c
index 857a4d4..7ba5fc6 100644
--- a/compiler/src/CFCCMan.c
+++ b/compiler/src/CFCCMan.c
@@ -182,10 +182,11 @@ S_man_create_functions(CFCClass *klass) {
         const char *name = CFCFunction_get_name(func);
         result = CFCUtil_cat(result, ".TP\n.B ", name, "\n", NULL);
 
-        const char *full_func_sym = CFCFunction_full_func_sym(func);
+        char *full_func_sym = CFCFunction_full_func_sym(func, klass);
         char *function_man = S_man_create_func(klass, func, full_func_sym);
         result = CFCUtil_cat(result, function_man, NULL);
         FREEMEM(function_man);
+        FREEMEM(full_func_sym);
     }
 
     return result;

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5cb28726/compiler/src/CFCFunction.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCFunction.c b/compiler/src/CFCFunction.c
index 7f21f9b..d83115c 100644
--- a/compiler/src/CFCFunction.c
+++ b/compiler/src/CFCFunction.c
@@ -25,6 +25,7 @@
 #define CFC_NEED_CALLABLE_STRUCT_DEF
 #include "CFCCallable.h"
 #include "CFCFunction.h"
+#include "CFCClass.h"
 #include "CFCParcel.h"
 #include "CFCType.h"
 #include "CFCParamList.h"
@@ -124,14 +125,14 @@ CFCFunction_void(CFCFunction *self) {
     return CFCType_is_void(self->callable.return_type);
 }
 
-const char*
-CFCFunction_full_func_sym(CFCFunction *self) {
-    return CFCSymbol_full_sym((CFCSymbol*)self);
+char*
+CFCFunction_full_func_sym(CFCFunction *self, CFCClass *klass) {
+    return CFCSymbol_full_sym((CFCSymbol*)self, klass);
 }
 
-const char*
-CFCFunction_short_func_sym(CFCFunction *self) {
-    return CFCSymbol_short_sym((CFCSymbol*)self);
+char*
+CFCFunction_short_func_sym(CFCFunction *self, CFCClass *klass) {
+    return CFCSymbol_short_sym((CFCSymbol*)self, klass);
 }
 
 const char*

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5cb28726/compiler/src/CFCFunction.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCFunction.h b/compiler/src/CFCFunction.h
index 3c786ab..4ac17c5 100644
--- a/compiler/src/CFCFunction.h
+++ b/compiler/src/CFCFunction.h
@@ -89,13 +89,13 @@ CFCFunction_void(CFCFunction *self);
 
 /** A synonym for full_sym().
  */
-const char*
-CFCFunction_full_func_sym(CFCFunction *self);
+char*
+CFCFunction_full_func_sym(CFCFunction *self, struct CFCClass *klass);
 
 /** A synonym for short_sym().
  */
-const char*
-CFCFunction_short_func_sym(CFCFunction *self);
+char*
+CFCFunction_short_func_sym(CFCFunction *self, struct CFCClass *klass);
 
 const char*
 CFCFunction_get_name(CFCFunction *self);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5cb28726/compiler/src/CFCPerl.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPerl.c b/compiler/src/CFCPerl.c
index 68261d7..e8cd424 100644
--- a/compiler/src/CFCPerl.c
+++ b/compiler/src/CFCPerl.c
@@ -458,7 +458,8 @@ CFCPerl_write_bindings(CFCPerl *self) {
             CFCPerlSub *xsub = (CFCPerlSub*)constructors[j];
 
             // Add the XSUB function definition.
-            char *xsub_def = CFCPerlConstructor_xsub_def(constructors[j]);
+            char *xsub_def
+                = CFCPerlConstructor_xsub_def(constructors[j], klass);
             generated_xs = CFCUtil_cat(generated_xs, xsub_def, "\n",
                                        NULL);
             FREEMEM(xsub_def);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5cb28726/compiler/src/CFCPerlConstructor.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPerlConstructor.c b/compiler/src/CFCPerlConstructor.c
index a0cc170..cb7ebc8 100644
--- a/compiler/src/CFCPerlConstructor.c
+++ b/compiler/src/CFCPerlConstructor.c
@@ -88,12 +88,12 @@ CFCPerlConstructor_destroy(CFCPerlConstructor *self) {
 }
 
 char*
-CFCPerlConstructor_xsub_def(CFCPerlConstructor *self) {
+CFCPerlConstructor_xsub_def(CFCPerlConstructor *self, CFCClass *klass) {
     const char *c_name = self->sub.c_name;
     CFCParamList *param_list = self->sub.param_list;
     char         *name_list  = CFCPerlSub_arg_name_list((CFCPerlSub*)self);
     CFCVariable **arg_vars   = CFCParamList_get_variables(param_list);
-    const char   *func_sym   = CFCFunction_full_func_sym(self->init_func);
+    char *func_sym     = CFCFunction_full_func_sym(self->init_func, klass);
     char *arg_decls    = CFCPerlSub_arg_declarations((CFCPerlSub*)self);
     char *allot_params = CFCPerlSub_build_allot_params((CFCPerlSub*)self);
     CFCVariable *self_var       = arg_vars[0];
@@ -148,6 +148,7 @@ CFCPerlConstructor_xsub_def(CFCPerlConstructor *self) {
                           refcount_mods, func_sym, name_list);
 
     FREEMEM(refcount_mods);
+    FREEMEM(func_sym);
     FREEMEM(arg_decls);
     FREEMEM(allot_params);
     FREEMEM(name_list);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5cb28726/compiler/src/CFCPerlConstructor.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPerlConstructor.h b/compiler/src/CFCPerlConstructor.h
index 3de46b5..560a80a 100644
--- a/compiler/src/CFCPerlConstructor.h
+++ b/compiler/src/CFCPerlConstructor.h
@@ -53,7 +53,7 @@ CFCPerlConstructor_destroy(CFCPerlConstructor *self);
 /** Generate C code for the XSUB.
  */
 char*
-CFCPerlConstructor_xsub_def(CFCPerlConstructor *self);
+CFCPerlConstructor_xsub_def(CFCPerlConstructor *self, struct CFCClass *klass);
 
 #ifdef __cplusplus
 }

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5cb28726/compiler/src/CFCSymbol.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCSymbol.c b/compiler/src/CFCSymbol.c
index ddf5d62..dfb1150 100644
--- a/compiler/src/CFCSymbol.c
+++ b/compiler/src/CFCSymbol.c
@@ -24,6 +24,7 @@
 
 #define CFC_NEED_SYMBOL_STRUCT_DEF
 #include "CFCSymbol.h"
+#include "CFCClass.h"
 #include "CFCParcel.h"
 #include "CFCUtil.h"
 
@@ -169,13 +170,6 @@ CFCSymbol_init(CFCSymbol *self, struct CFCParcel *parcel,
     self->class_nickname = CFCUtil_strdup(real_nickname);
     self->name           = CFCUtil_strdup(name);
 
-    // Derive short_sym and full_sym.
-    char *nickname = self->class_nickname ? self->class_nickname : "";
-    self->short_sym = CFCUtil_sprintf("%s_%s", nickname, name);
-    self->full_sym
-        = CFCUtil_sprintf("%s%s", CFCParcel_get_prefix(self->parcel),
-                          self->short_sym);
-
     return self;
 }
 
@@ -186,8 +180,6 @@ CFCSymbol_destroy(CFCSymbol *self) {
     FREEMEM(self->class_name);
     FREEMEM(self->class_nickname);
     FREEMEM(self->name);
-    FREEMEM(self->short_sym);
-    FREEMEM(self->full_sym);
     CFCBase_destroy((CFCBase*)self);
 }
 
@@ -228,14 +220,19 @@ CFCSymbol_local(CFCSymbol *self) {
     return !strcmp(self->exposure, "local");
 }
 
-const char*
-CFCSymbol_full_sym(CFCSymbol *self) {
-    return self->full_sym;
+char*
+CFCSymbol_full_sym(CFCSymbol *self, CFCClass *klass) {
+    const char *prefix   = CFCClass_get_prefix(klass);
+    const char *nickname = CFCClass_get_nickname(klass);
+    char *full_sym = CFCUtil_sprintf("%s%s_%s", prefix, nickname, self->name);
+    return full_sym;
 }
 
-const char*
-CFCSymbol_short_sym(CFCSymbol *self) {
-    return self->short_sym;
+char*
+CFCSymbol_short_sym(CFCSymbol *self, CFCClass *klass) {
+    const char *nickname = CFCClass_get_nickname(klass);
+    char *short_sym = CFCUtil_sprintf("%s_%s", nickname, self->name);
+    return short_sym;
 }
 
 struct CFCParcel*

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5cb28726/compiler/src/CFCSymbol.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCSymbol.h b/compiler/src/CFCSymbol.h
index c47b405..7f57d52 100644
--- a/compiler/src/CFCSymbol.h
+++ b/compiler/src/CFCSymbol.h
@@ -29,6 +29,7 @@ extern "C" {
 #endif
 
 typedef struct CFCSymbol CFCSymbol;
+struct CFCClass;
 struct CFCParcel;
 
 #ifdef CFC_NEED_SYMBOL_STRUCT_DEF
@@ -41,8 +42,6 @@ struct CFCSymbol {
     char *class_name;
     char *class_nickname;
     char *name;
-    char *short_sym;
-    char *full_sym;
 };
 #endif
 
@@ -126,14 +125,14 @@ CFCSymbol_get_name(CFCSymbol *self);
 /** Returns the C representation for the symbol minus the parcel's prefix,
  * e.g.  "Lobster_average_lifespan".
  */
-const char*
-CFCSymbol_short_sym(CFCSymbol *self);
+char*
+CFCSymbol_short_sym(CFCSymbol *self, struct CFCClass *klass);
 
 /** Returns the fully qualified C representation for the symbol, e.g.
  * "crust_Lobster_average_lifespan".
  */
-const char*
-CFCSymbol_full_sym(CFCSymbol *self);
+char*
+CFCSymbol_full_sym(CFCSymbol *self, struct CFCClass *klass);
 
 /** Get the Symbol's all-lowercase prefix, delegating to `parcel`.
  */

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5cb28726/compiler/src/CFCTestSymbol.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCTestSymbol.c b/compiler/src/CFCTestSymbol.c
index f9f8c76..cfb1d67 100644
--- a/compiler/src/CFCTestSymbol.c
+++ b/compiler/src/CFCTestSymbol.c
@@ -16,9 +16,11 @@
 
 #define CFC_USE_TEST_MACROS
 #include "CFCBase.h"
+#include "CFCClass.h"
 #include "CFCParcel.h"
 #include "CFCSymbol.h"
 #include "CFCTest.h"
+#include "CFCUtil.h"
 
 #ifndef true
   #define true 1
@@ -135,13 +137,19 @@ S_run_tests(CFCTest *test) {
     {
         CFCParcel *eep_parcel = CFCParcel_new("Eep", NULL, NULL, NULL);
         CFCParcel_register(eep_parcel);
+        CFCClass *ork
+            = CFCClass_create(eep_parcel, NULL, "Op::Ork", NULL, NULL, NULL,
+                              NULL, NULL, false, false, false);
         CFCSymbol *eep
             = CFCSymbol_new(eep_parcel, "parcel", "Op::Ork", NULL, "ah_ah");
-        const char *short_sym = CFCSymbol_short_sym(eep);
+        char *short_sym = CFCSymbol_short_sym(eep, ork);
         STR_EQ(test, short_sym, "Ork_ah_ah", "short_sym");
-        const char *full_sym = CFCSymbol_full_sym(eep);
+        FREEMEM(short_sym);
+        char *full_sym = CFCSymbol_full_sym(eep, ork);
         STR_EQ(test, full_sym, "eep_Ork_ah_ah", "full_sym");
+        FREEMEM(full_sym);
         CFCBase_decref((CFCBase*)eep_parcel);
+        CFCBase_decref((CFCBase*)ork);
         CFCBase_decref((CFCBase*)eep);
     }
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5cb28726/compiler/src/CFCTestVariable.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCTestVariable.c b/compiler/src/CFCTestVariable.c
index a68cd73..91d75b5 100644
--- a/compiler/src/CFCTestVariable.c
+++ b/compiler/src/CFCTestVariable.c
@@ -22,8 +22,14 @@
 #include "CFCSymbol.h"
 #include "CFCTest.h"
 #include "CFCType.h"
+#include "CFCUtil.h"
 #include "CFCVariable.h"
 
+#ifndef true
+  #define true 1
+  #define false 0
+#endif
+
 static void
 S_run_tests(CFCTest *test);
 
@@ -73,11 +79,18 @@ S_run_tests(CFCTest *test) {
                               "Crustacean::Lobster::LobsterClaw", "LobClaw",
                               "foo", type, 0);
         CFCVariable_resolve_type(var);
-        STR_EQ(test, CFCVariable_global_c(var), "neato_Foo* neato_LobClaw_foo",
-               "global_c");
+        CFCClass *ork
+            = CFCClass_create(neato_parcel, NULL,
+                              "Crustacean::Lobster::LobsterClaw", "LobClaw",
+                              NULL, NULL, NULL, NULL, false, false, false);
+
+        char *global_c = CFCVariable_global_c(var, ork);
+        STR_EQ(test, global_c, "neato_Foo* neato_LobClaw_foo", "global_c");
+        FREEMEM(global_c);
 
         CFCBase_decref((CFCBase*)type);
         CFCBase_decref((CFCBase*)var);
+        CFCBase_decref((CFCBase*)ork);
     }
 
     {

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5cb28726/compiler/src/CFCVariable.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCVariable.c b/compiler/src/CFCVariable.c
index 534f0a7..69feba4 100644
--- a/compiler/src/CFCVariable.c
+++ b/compiler/src/CFCVariable.c
@@ -23,6 +23,7 @@
 #endif
 
 #define CFC_NEED_SYMBOL_STRUCT_DEF
+#include "CFCClass.h"
 #include "CFCSymbol.h"
 #include "CFCVariable.h"
 #include "CFCParcel.h"
@@ -114,8 +115,6 @@ S_generate_c_strings(CFCVariable *self) {
     const char *name = CFCVariable_get_name(self);
     self->local_c = CFCUtil_sprintf("%s %s%s", type_str, name, postfix);
     self->local_dec = CFCUtil_sprintf("%s;", self->local_c);
-    const char *full_sym = CFCVariable_full_sym(self);
-    self->global_c = CFCUtil_sprintf("%s %s%s", type_str, full_sym, postfix);
 }
 
 CFCType*
@@ -134,10 +133,21 @@ CFCVariable_local_c(CFCVariable *self) {
     return self->local_c;
 }
 
-const char*
-CFCVariable_global_c(CFCVariable *self) {
-    if (!self->global_c) { S_generate_c_strings(self); }
-    return self->global_c;
+char*
+CFCVariable_global_c(CFCVariable *self, CFCClass *klass) {
+    const char *type_str = CFCType_to_c(self->type);
+    const char *postfix  = "";
+    if (CFCType_is_composite(self->type)
+        && CFCType_get_array(self->type) != NULL
+       ) {
+        postfix = CFCType_get_array(self->type);
+    }
+
+    char *full_sym = CFCVariable_full_sym(self, klass);
+    char *global_c = CFCUtil_sprintf("%s %s%s", type_str, full_sym, postfix);
+
+    FREEMEM(full_sym);
+    return global_c;
 }
 
 const char*
@@ -151,13 +161,13 @@ CFCVariable_get_name(CFCVariable *self) {
     return CFCSymbol_get_name((CFCSymbol*)self);
 }
 
-const char*
-CFCVariable_short_sym(CFCVariable *self) {
-    return CFCSymbol_short_sym((CFCSymbol*)self);
+char*
+CFCVariable_short_sym(CFCVariable *self, CFCClass *klass) {
+    return CFCSymbol_short_sym((CFCSymbol*)self, klass);
 }
 
-const char*
-CFCVariable_full_sym(CFCVariable *self) {
-    return CFCSymbol_full_sym((CFCSymbol*)self);
+char*
+CFCVariable_full_sym(CFCVariable *self, CFCClass *klass) {
+    return CFCSymbol_full_sym((CFCSymbol*)self, klass);
 }
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5cb28726/compiler/src/CFCVariable.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCVariable.h b/compiler/src/CFCVariable.h
index d86d273..9ecff5e 100644
--- a/compiler/src/CFCVariable.h
+++ b/compiler/src/CFCVariable.h
@@ -85,8 +85,8 @@ CFCVariable_local_c(CFCVariable *self);
  *
  *     int32_t crust_Lobster_average_lifespan
  */
-const char*
-CFCVariable_global_c(CFCVariable *self);
+char*
+CFCVariable_global_c(CFCVariable *self, struct CFCClass *klass);
 
 /** Returns C code appropriate for declaring the variable in a local scope,
  * such as within a struct definition, or as an automatic variable within a C
@@ -100,11 +100,11 @@ CFCVariable_local_declaration(CFCVariable *self);
 const char*
 CFCVariable_get_name(CFCVariable *self);
 
-const char*
-CFCVariable_short_sym(CFCVariable *self);
+char*
+CFCVariable_short_sym(CFCVariable *self, struct CFCClass *klass);
 
-const char*
-CFCVariable_full_sym(CFCVariable *self);
+char*
+CFCVariable_full_sym(CFCVariable *self, struct CFCClass *klass);
 
 #ifdef __cplusplus
 }