+#ifdef CY_OBJECTIVEC
+const char *Meta::Encode(CYPool &pool) const {
+ return "#";
+}
+
+const char *Selector::Encode(CYPool &pool) const {
+ return ":";
+}
+#endif
+
+const char *Bits::Encode(CYPool &pool) const {
+ return pool.strcat("b", pool.itoa(size), NULL);
+}
+
+const char *Pointer::Encode(CYPool &pool) const {
+ return pool.strcat("^", type.Encode(pool), NULL);
+}
+
+const char *Array::Encode(CYPool &pool) const {
+ return pool.strcat("[", pool.itoa(size), type.Encode(pool), "]", NULL);
+}
+
+#ifdef CY_OBJECTIVEC
+const char *Object::Encode(CYPool &pool) const {
+ return name == NULL ? "@" : pool.strcat("@\"", name, "\"", NULL);
+}
+#endif
+
+const char *Enum::Encode(CYPool &pool) const {
+ return type.Encode(pool);
+}
+
+const char *Aggregate::Encode(CYPool &pool) const {
+ bool reference(signature.count == _not(size_t));
+ return pool.strcat(overlap ? "(" : "{",
+ name == NULL ? "?" : name,
+ reference ? "" : "=",
+ reference ? "" : Unparse(pool, &signature),
+ overlap ? ")" : "}", NULL);
+}
+
+const char *Function::Encode(CYPool &pool) const {
+ return "?";
+}
+
+#ifdef CY_OBJECTIVEC
+const char *Block::Encode(CYPool &pool) const {
+ return "@?";
+}
+#endif
+
+const char *Unparse(CYPool &pool, const struct Type *type) {
+ const char *base(type->Encode(pool));
+ if (type->flags == 0)
+ return base;
+
+ #define iovec_(base, size) \
+ (struct iovec) {const_cast<char *>(base), size}
+
+ size_t size(strlen(base));
+ char buffer[7 + size];
+ size_t offset(0);
+
+ if ((type->flags & JOC_TYPE_INOUT) != 0)
+ buffer[offset++] = 'N';
+ if ((type->flags & JOC_TYPE_IN) != 0)
+ buffer[offset++] = 'n';
+ if ((type->flags & JOC_TYPE_BYCOPY) != 0)
+ buffer[offset++] = 'O';
+ if ((type->flags & JOC_TYPE_OUT) != 0)
+ buffer[offset++] = 'o';
+ if ((type->flags & JOC_TYPE_BYREF) != 0)
+ buffer[offset++] = 'R';
+ if ((type->flags & JOC_TYPE_CONST) != 0)
+ buffer[offset++] = 'r';
+ if ((type->flags & JOC_TYPE_ONEWAY) != 0)
+ buffer[offset++] = 'V';
+
+ memcpy(buffer + offset, base, size);
+ return pool.strmemdup(buffer, offset + size);