Start tracking types in expressions.
diff --git a/libacc/acc.cpp b/libacc/acc.cpp
index 60546f1..e43728e 100644
--- a/libacc/acc.cpp
+++ b/libacc/acc.cpp
@@ -55,6 +55,70 @@
 
 namespace acc {
 
+// Subset of STL vector.
+template<class E> class Vector {
+    public:
+    Vector() {
+        mpBase = 0;
+        mUsed = 0;
+        mSize = 0;
+    }
+
+    ~Vector() {
+        if (mpBase) {
+            for(size_t i = 0; i < mUsed; i++)  {
+                mpBase[mUsed].~E();
+            }
+            free(mpBase);
+        }
+    }
+
+    inline E& operator[](size_t i) {
+        return mpBase[i];
+    }
+
+    inline E& front() {
+        return mpBase[0];
+    }
+
+    inline E& back() {
+        return mpBase[mUsed - 1];
+    }
+
+    void pop_back() {
+        mUsed -= 1;
+        mpBase[mUsed].~E();
+    }
+
+    void push_back(const E& item) {
+        * ensure(1) = item;
+    }
+
+    size_t size() {
+        return mUsed;
+    }
+
+private:
+    E* ensure(int n) {
+        size_t newUsed = mUsed + n;
+        if (newUsed > mSize) {
+            size_t newSize = mSize * 2 + 10;
+            if (newSize < newUsed) {
+                newSize = newUsed;
+            }
+            mpBase = (E*) realloc(mpBase, sizeof(E) * newSize);
+            mSize = newSize;
+        }
+        E* result = mpBase + mUsed;
+        mUsed = newUsed;
+        return result;
+    }
+
+    E* mpBase;
+    size_t mUsed;
+    size_t mSize;
+};
+
 class ErrorSink {
 public:
     void error(const char *fmt, ...) {
@@ -68,7 +132,18 @@
 };
 
 class Compiler : public ErrorSink {
-    struct Type;
+    typedef int tokenid_t;
+    enum TypeTag {
+        TY_INT, TY_CHAR, TY_VOID, TY_FLOAT, TY_DOUBLE,
+        TY_POINTER, TY_FUNC, TY_PARAM
+    };
+
+    struct Type {
+        TypeTag tag;
+        tokenid_t id; // For function arguments
+        Type* pHead;
+        Type* pTail;
+    };
 
     class CodeBuf {
         char* ind; // Output code pointer
@@ -178,6 +253,7 @@
         CodeGenerator() {
             mErrorSink = 0;
             pCodeBuf = 0;
+            pushType();
         }
         virtual ~CodeGenerator() {}
 
@@ -219,13 +295,13 @@
                                   int localVariableSize) = 0;
 
         /* load immediate value to R0 */
-        virtual void li(int i) = 0;
+        virtual void li(int i, Type* pType) = 0;
 
         /* load floating point immediate value to R0 */
-        virtual void lif(float f) = 0;
+        virtual void lif(float f, Type* pType) = 0;
 
         /* load double-precision floating point immediate value to R0 */
-        virtual void lid(double d) = 0;
+        virtual void lid(double d, Type* pType) = 0;
 
         /* Jump to a target, and return the address of the word that
          * holds the target data, in case it needs to be fixed up later.
@@ -281,7 +357,7 @@
          * argument, addressed relative to FP.
          * else it is an absolute global address.
          */
-        virtual void leaR0(int ea) = 0;
+        virtual void leaR0(int ea, Type* pPointerType) = 0;
 
         /* Store R0 to a variable.
          * If ea <= LOCAL, then this is a local variable, or an
@@ -298,7 +374,12 @@
          * should be post-incremented or post-decremented, based
          * on the value of op.
          */
-        virtual void loadR0(int ea, bool isIncDec, int op) = 0;
+        virtual void loadR0(int ea, bool isIncDec, int op, Type* pType) = 0;
+
+        /**
+         * Convert R0 to the given type.
+         */
+        virtual void convertR0(Type* pType) = 0;
 
         /* Emit code to adjust the stack for a function call. Return the
          * label for the address of the instruction that adjusts the
@@ -326,19 +407,19 @@
          * a chain. The address will be patched later.
          * Return the address of the word that has to be patched.
          */
-        virtual int callForward(int symbol) = 0;
+        virtual int callForward(int symbol, Type* pFunc) = 0;
 
         /* Call a function using PC-relative addressing. t is the PC-relative
          * address of the function. It has already been adjusted for the
          * architectural jump offset, so just store it as-is.
          */
-        virtual void callRelative(int t) = 0;
+        virtual void callRelative(int t, Type* pFunc) = 0;
 
         /* Call a function pointer. L is the number of bytes the arguments
          * take on the stack. The address of the function is stored at
          * location SP + l.
          */
-        virtual void callIndirect(int l) = 0;
+        virtual void callIndirect(int l, Type* pFunc) = 0;
 
         /* Adjust SP after returning from a function call. l is the
          * number of bytes of arguments stored on the stack. isIndirect
@@ -416,7 +497,40 @@
                 error("code generator assertion failed.");
             }
         }
+
+        void setR0Type(Type* pType) {
+            mExpressionStack.back() = pType;
+        }
+
+        Type* getR0Type() {
+            return mExpressionStack.back();
+        }
+
+        Type* getTOSType() {
+            return mExpressionStack[mExpressionStack.size()-2];
+        }
+
+        void pushType() {
+            mExpressionStack.push_back(NULL);
+        }
+
+        void popType() {
+            mExpressionStack.pop_back();
+        }
+
+        bool bitsSame(Type* pA, Type* pB) {
+            return collapseType(pA->tag) == collapseType(pB->tag);
+        }
+
+        TypeTag collapseType(TypeTag tag) {
+            static const TypeTag collapsedTag[] = {
+                    TY_INT, TY_INT, TY_VOID, TY_FLOAT, TY_DOUBLE, TY_INT,
+                    TY_VOID, TY_VOID};
+            return collapsedTag[tag];
+        }
+
     private:
+        Vector<Type*> mExpressionStack;
         CodeBuf* pCodeBuf;
         ErrorSink* mErrorSink;
     };
@@ -483,7 +597,7 @@
         }
 
         /* load immediate value */
-        virtual void li(int t) {
+        virtual void li(int t, Type* pType) {
             LOG_API("li(%d);\n", t);
             if (t >= 0 && t < 255) {
                  o4(0xE3A00000 + t); // mov    r0, #0
@@ -496,18 +610,20 @@
                   o4(t);          // .L3:   .word 0
                                   // .L99:
             }
+            setR0Type(pType);
         }
 
-        virtual void lif(float f) {
+        virtual void lif(float f, Type* pType) {
             union { float f; int i; } converter;
             converter.f = f;
-            li(converter.i);
+            li(converter.i, pType);
         }
 
-        virtual void lid(double d) {
+        virtual void lid(double d, Type* pType) {
             union { double d; int i[2]; } converter;
             converter.d = d;
-            assert(false);
+            error("lid: unimplemented");
+            setR0Type(pType);
         }
 
         virtual int gjmp(int t) {
@@ -557,6 +673,7 @@
                 error("Unknown comparison op %d", op);
                 break;
             }
+            popType();
         }
 
         virtual void genOp(int op) {
@@ -601,6 +718,7 @@
                 error("Unimplemented op %d\n", op);
                 break;
             }
+            popType();
         }
 
         virtual void gUnaryCmp(int op) {
@@ -641,6 +759,7 @@
             LOG_API("pushR0();\n");
             o4(0xE92D0001);  // stmfd   sp!,{r0}
             mStackUse += 4;
+            pushType();
             LOG_STACK("pushR0: %d\n", mStackUse);
         }
 
@@ -657,9 +776,10 @@
                     o4(0xE5C10000); // strb r0, [r1]
                     break;
                 default:
-                    assert(false);
+                    error("storeR0ToTOS: unimplemented type");
                     break;
             }
+            popType();
         }
 
         virtual void loadR0FromR0(Type* pPointerType) {
@@ -673,12 +793,13 @@
                     o4(0xE5D00000); // ldrb r0, [r0]
                     break;
                 default:
-                    assert(false);
+                    error("loadR0FromR0: unimplemented type");
                     break;
             }
+            setR0Type(pPointerType->pHead);
         }
 
-        virtual void leaR0(int ea) {
+        virtual void leaR0(int ea, Type* pPointerType) {
             LOG_API("leaR0(%d);\n", ea);
             if (ea < LOCAL) {
                 // Local, fp relative
@@ -697,6 +818,7 @@
                 o4(ea);         // .L1:   .word 0
                                 // .L99:
             }
+            setR0Type(pPointerType);
         }
 
         virtual void storeR0(int ea) {
@@ -720,7 +842,7 @@
             }
         }
 
-        virtual void loadR0(int ea, bool isIncDec, int op) {
+        virtual void loadR0(int ea, bool isIncDec, int op, Type* pType) {
             LOG_API("loadR0(%d, %d, %d);\n", ea, isIncDec, op);
             if (ea < LOCAL) {
                 // Local, fp relative
@@ -765,6 +887,14 @@
                     o4(0xE5821000); // str r1, [r2]
                }
             }
+            setR0Type(pType);
+        }
+
+        virtual void convertR0(Type* pType){
+            if (bitsSame(pType, getR0Type())) {
+                return;
+            }
+            error("Incompatible types");
         }
 
         virtual int beginFunctionCallArguments() {
@@ -809,14 +939,16 @@
                       mStackUse, mStackAlignmentAdjustment);
         }
 
-        virtual int callForward(int symbol) {
+        virtual int callForward(int symbol, Type* pFunc) {
             LOG_API("callForward(%d);\n", symbol);
+            setR0Type(pFunc->pHead);
             // Forward calls are always short (local)
             return o4(0xEB000000 | encodeAddress(symbol));
         }
 
-        virtual void callRelative(int t) {
+        virtual void callRelative(int t, Type* pFunc) {
             LOG_API("callRelative(%d);\n", t);
+            setR0Type(pFunc->pHead);
             int abs = t + getPC() + jumpOffset();
             LOG_API("abs=%d (0x%08x)\n", abs, abs);
             if (t >= - (1 << 25) && t < (1 << 25)) {
@@ -831,8 +963,9 @@
            }
         }
 
-        virtual void callIndirect(int l) {
+        virtual void callIndirect(int l, Type* pFunc) {
             LOG_API("callIndirect(%d);\n", l);
+            setR0Type(pFunc->pHead);
             int argCount = l >> 2;
             int poppedArgs = argCount > 4 ? 4 : argCount;
             int adjustedL = l - (poppedArgs << 2) + mStackAlignmentAdjustment;
@@ -1031,20 +1164,23 @@
         }
 
         /* load immediate value */
-        virtual void li(int i) {
+        virtual void li(int i, Type* pType) {
             oad(0xb8, i); /* mov $xx, %eax */
+            setR0Type(pType);
         }
 
-        virtual void lif(float f) {
+        virtual void lif(float f, Type* pType) {
             union { float f; int i; } converter;
             converter.f = f;
-            assert(false);
+            setR0Type(pType);
+            error("unimplemented: lif");
         }
 
-        virtual void lid(double d) {
+        virtual void lid(double d, Type* pType) {
             union { double d; int i[2]; } converter;
             converter.d = d;
-            assert(false);
+            setR0Type(pType);
+            error("unimplemented: lid");
         }
 
         virtual int gjmp(int t) {
@@ -1061,10 +1197,11 @@
             int t = decodeOp(op);
             o(0x59); /* pop %ecx */
             o(0xc139); /* cmp %eax,%ecx */
-            li(0);
+            li(0, NULL);
             o(0x0f); /* setxx %al */
             o(t + 0x90);
             o(0xc0);
+            popType();
         }
 
         virtual void genOp(int op) {
@@ -1072,13 +1209,14 @@
             o(decodeOp(op));
             if (op == OP_MOD)
                 o(0x92); /* xchg %edx, %eax */
+            popType();
         }
 
         virtual void gUnaryCmp(int op) {
             oad(0xb9, 0); /* movl $0, %ecx */
             int t = decodeOp(op);
             o(0xc139); /* cmp %eax,%ecx */
-            li(0);
+            li(0, NULL);
             o(0x0f); /* setxx %al */
             o(t + 0x90);
             o(0xc0);
@@ -1091,11 +1229,13 @@
 
         virtual void pushR0() {
             o(0x50); /* push %eax */
+            pushType();
         }
 
         virtual void storeR0ToTOS(Type* pPointerType) {
             assert(pPointerType->tag == TY_POINTER);
             o(0x59); /* pop %ecx */
+            popType();
             switch (pPointerType->pHead->tag) {
                 case TY_INT:
                     o(0x0189); /* movl %eax/%al, (%ecx) */
@@ -1104,7 +1244,7 @@
                     o(0x0188); /* movl %eax/%al, (%ecx) */
                     break;
                 default:
-                    assert(false);
+                    error("storeR0ToTOS: unsupported type");
                     break;
             }
         }
@@ -1119,21 +1259,23 @@
                     o(0xbe0f); /* movsbl (%eax), %eax */
                     break;
                 default:
-                    assert(false);
+                    error("loadR0FromR0: unsupported type");
                     break;
             }
             ob(0); /* add zero in code */
+            setR0Type(pPointerType->pHead);
         }
 
-        virtual void leaR0(int ea) {
+        virtual void leaR0(int ea, Type* pPointerType) {
             gmov(10, ea); /* leal EA, %eax */
+            setR0Type(pPointerType);
         }
 
         virtual void storeR0(int ea) {
             gmov(6, ea); /* mov %eax, EA */
         }
 
-        virtual void loadR0(int ea, bool isIncDec, int op) {
+        virtual void loadR0(int ea, bool isIncDec, int op, Type* pType) {
             gmov(8, ea); /* mov EA, %eax */
             if (isIncDec) {
                 /* Implement post-increment or post decrement.
@@ -1141,6 +1283,15 @@
                 gmov(0, ea); /* 83 ADD */
                 o(decodeOp(op));
             }
+            setR0Type(pType);
+        }
+
+        virtual void convertR0(Type* pType){
+            if (bitsSame(pType, getR0Type())) {
+                return;
+            }
+            error("convertR0: unsupported conversion %d <- %d", pType->tag,
+                  getR0Type()->tag);
         }
 
         virtual int beginFunctionCallArguments() {
@@ -1155,15 +1306,18 @@
             * (int*) a = l;
         }
 
-        virtual int callForward(int symbol) {
+        virtual int callForward(int symbol, Type* pFunc) {
+            setR0Type(pFunc->pHead);
             return psym(0xe8, symbol); /* call xxx */
         }
 
-        virtual void callRelative(int t) {
+        virtual void callRelative(int t, Type* pFunc) {
+            setR0Type(pFunc->pHead);
             psym(0xe8, t); /* call xxx */
         }
 
-        virtual void callIndirect(int l) {
+        virtual void callIndirect(int l, Type* pFunc) {
+            setR0Type(pFunc->pHead);
             oad(0x2494ff, l); /* call *xxx(%esp) */
         }
 
@@ -1321,19 +1475,19 @@
         }
 
         /* load immediate value */
-        virtual void li(int t) {
+        virtual void li(int t, Type* pType) {
             fprintf(stderr, "li(%d)\n", t);
-            mpBase->li(t);
+            mpBase->li(t, pType);
         }
 
-        virtual void lif(float f) {
+        virtual void lif(float f, Type* pType) {
             fprintf(stderr, "lif(%g)\n", f);
-            mpBase->lif(f);
+            mpBase->lif(f, pType);
         }
 
-        virtual void lid(double d) {
+        virtual void lid(double d, Type* pType) {
             fprintf(stderr, "lid(%g)\n", d);
-            mpBase->lid(d);
+            mpBase->lid(d, pType);
         }
 
         virtual int gjmp(int t) {
@@ -1385,9 +1539,9 @@
             mpBase->loadR0FromR0(pPointerType);
         }
 
-        virtual void leaR0(int ea) {
+        virtual void leaR0(int ea, Type* pPointerType) {
             fprintf(stderr, "leaR0(%d)\n", ea);
-            mpBase->leaR0(ea);
+            mpBase->leaR0(ea, pPointerType);
         }
 
         virtual void storeR0(int ea) {
@@ -1395,9 +1549,14 @@
             mpBase->storeR0(ea);
         }
 
-        virtual void loadR0(int ea, bool isIncDec, int op) {
+        virtual void loadR0(int ea, bool isIncDec, int op, Type* pType) {
             fprintf(stderr, "loadR0(%d, %d, %d)\n", ea, isIncDec, op);
-            mpBase->loadR0(ea, isIncDec, op);
+            mpBase->loadR0(ea, isIncDec, op, pType);
+        }
+
+        virtual void convertR0(Type* pType){
+            fprintf(stderr, "convertR0(pType)\n");
+            mpBase->convertR0(pType);
         }
 
         virtual int beginFunctionCallArguments() {
@@ -1416,20 +1575,20 @@
             mpBase->endFunctionCallArguments(a, l);
         }
 
-        virtual int callForward(int symbol) {
-            int result = mpBase->callForward(symbol);
+        virtual int callForward(int symbol, Type* pFunc) {
+            int result = mpBase->callForward(symbol, pFunc);
             fprintf(stderr, "callForward(%d) = %d\n", symbol, result);
             return result;
         }
 
-        virtual void callRelative(int t) {
+        virtual void callRelative(int t, Type* pFunc) {
             fprintf(stderr, "callRelative(%d)\n", t);
-            mpBase->callRelative(t);
+            mpBase->callRelative(t, pFunc);
         }
 
-        virtual void callIndirect(int l) {
+        virtual void callIndirect(int l, Type* pFunc) {
             fprintf(stderr, "callIndirect(%d)\n", l);
-            mpBase->callIndirect(l);
+            mpBase->callIndirect(l, pFunc);
         }
 
         virtual void adjustStackAfterCall(int l, bool isIndirect) {
@@ -1474,71 +1633,6 @@
 
 #endif // PROVIDE_TRACE_CODEGEN
 
-
-    // Subset of STL vector.
-    template<class E> class Vector {
-        public:
-        Vector() {
-            mpBase = 0;
-            mUsed = 0;
-            mSize = 0;
-        }
-
-        ~Vector() {
-            if (mpBase) {
-                for(size_t i = 0; i < mUsed; i++)  {
-                    mpBase[mUsed].~E();
-                }
-                free(mpBase);
-            }
-        }
-
-        inline E& operator[](size_t i) {
-            return mpBase[i];
-        }
-
-        inline E& front() {
-            return mpBase[0];
-        }
-
-        inline E& back() {
-            return mpBase[mUsed - 1];
-        }
-
-        void pop_back() {
-            mUsed -= 1;
-            mpBase[mUsed].~E();
-        }
-
-        void push_back(const E& item) {
-            * ensure(1) = item;
-        }
-
-        size_t size() {
-            return mUsed;
-        }
-
-    private:
-        E* ensure(int n) {
-            size_t newUsed = mUsed + n;
-            if (newUsed > mSize) {
-                size_t newSize = mSize * 2 + 10;
-                if (newSize < newUsed) {
-                    newSize = newUsed;
-                }
-                mpBase = (E*) realloc(mpBase, sizeof(E) * newSize);
-                mSize = newSize;
-            }
-            E* result = mpBase + mUsed;
-            mUsed = newUsed;
-            return result;
-        }
-
-        E* mpBase;
-        size_t mUsed;
-        size_t mSize;
-    };
-
     class Arena {
     public:
         // Used to record a given allocation amount.
@@ -1658,7 +1752,6 @@
         Vector<Chunk> mData;
     };
 
-    typedef int tokenid_t;
     struct VariableInfo;
 
     struct Token {
@@ -2066,6 +2159,7 @@
     double tokd;     // floating point constant value
     int tokl;         // token operator level
     intptr_t rsym; // return symbol
+    Type* pReturnType; // type of the current function's return.
     intptr_t loc; // local variable index
     char* glo;  // global variable index
     String mTokenString;
@@ -2088,6 +2182,7 @@
     Type* mkpVoid;       // void
     Type* mkpFloat;
     Type* mkpDouble;
+    Type* mkpIntFn;
     Type* mkpIntPtr;
     Type* mkpCharPtr;
     Type* mkpPtrIntFn;
@@ -2608,7 +2703,7 @@
 
     bool acceptStringLiteral() {
         if (tok == '"') {
-            pGen->li((int) glo);
+            pGen->li((int) glo, mkpCharPtr);
             // This while loop merges multiple adjacent string constants.
             while (tok == '"') {
                 while (ch != '"' && ch != EOF) {
@@ -2645,11 +2740,11 @@
             t = tok;
             next();
             if (t == TOK_NUM) {
-                pGen->li(a);
+                pGen->li(a, mkpInt);
             } else if (t == TOK_NUM_FLOAT) {
-                pGen->lif(ad);
+                pGen->lif(ad, mkpFloat);
             } else if (t == TOK_NUM_DOUBLE) {
-                pGen->lid(ad);
+                pGen->lid(ad, mkpDouble);
             } else if (c == 2) {
                 /* -, +, !, ~ */
                 unary(false);
@@ -2693,7 +2788,9 @@
                 // Else we fall through to the function call below, with
                 // t == 0 to trigger an indirect function call. Hack!
             } else if (t == '&') {
-                pGen->leaR0((int) VI(tok)->pAddress);
+                VariableInfo* pVI = VI(tok);
+                pGen->leaR0((int) pVI->pAddress,
+                            createPtrType(pVI->pType, mLocalArena));
                 next();
             } else if (t == EOF ) {
                 error("Unexpected EOF.");
@@ -2705,12 +2802,13 @@
                     mGlobals.add(t);
                     // printf("Adding new global function %s\n", nameof(t));
                 }
-
-                n = (intptr_t) VI(t)->pAddress;
+                VariableInfo* pVI = VI(t);
+                n = (intptr_t) pVI->pAddress;
                 /* forward reference: try dlsym */
                 if (!n) {
                     n = (intptr_t) dlsym(RTLD_DEFAULT, nameof(t));
-                    VI(t)->pAddress = (void*) n;
+                    pVI->pType = mkpIntFn;
+                    pVI->pAddress = (void*) n;
                 }
                 if ((tok == '=') & allowAssignment) {
                     /* assignment */
@@ -2722,7 +2820,7 @@
                     if (!n) {
                         error("Undefined variable %s", nameof(t));
                     }
-                    pGen->loadR0(n, tokl == 11, tokc);
+                    pGen->loadR0(n, tokl == 11, tokc, pVI->pType);
                     if (tokl == 11) {
                         next();
                     }
@@ -2731,13 +2829,12 @@
         }
 
         /* function call */
-        if (tok == '(') {
+        if (accept('(')) {
             if (n == 1)
                 pGen->pushR0();
 
             /* push args and invert order */
             a = pGen->beginFunctionCallArguments();
-            next();
             int l = 0;
             while (tok != ')' && tok != EOF) {
                 expr();
@@ -2754,11 +2851,13 @@
             if (!n) {
                 /* forward reference */
                 VariableInfo* pVI = VI(t);
-                pVI->pForward = (void*) pGen->callForward((int) pVI->pForward);
+                pVI->pForward = (void*) pGen->callForward((int) pVI->pForward,
+                                                          pVI->pType);
             } else if (n == 1) {
-                pGen->callIndirect(l);
+                pGen->callIndirect(l, mkpPtrIntFn->pHead);
             } else {
-                pGen->callRelative(n - codeBuf.getPC() - pGen->jumpOffset());
+                pGen->callRelative(n - codeBuf.getPC() - pGen->jumpOffset(),
+                                   VI(t)->pType);
             }
             pGen->adjustStackAfterCall(l, n == 1);
         }
@@ -2796,10 +2895,10 @@
             /* && and || output code generation */
             if (a && level > 8) {
                 a = pGen->gtst(t == OP_LOGICAL_OR, a);
-                pGen->li(t != OP_LOGICAL_OR);
+                pGen->li(t != OP_LOGICAL_OR, mkpInt);
                 pGen->gjmp(5); /* jmp $ + 5 (sizeof li, FIXME for ARM) */
                 pGen->gsym(a);
-                pGen->li(t == OP_LOGICAL_OR);
+                pGen->li(t == OP_LOGICAL_OR, mkpInt);
             }
         }
     }
@@ -2876,8 +2975,10 @@
             }
         } else {
             if (accept(TOK_RETURN)) {
-                if (tok != ';')
+                if (tok != ';') {
                     expr();
+                    pGen->convertR0(pReturnType);
+                }
                 rsym = pGen->gjmp(rsym); /* jmp */
             } else if (accept(TOK_BREAK)) {
                 *(int *) l = pGen->gjmp(*(int *) l);
@@ -2887,18 +2988,6 @@
         }
     }
 
-    enum TypeTag {
-        TY_INT, TY_CHAR, TY_VOID, TY_FLOAT, TY_DOUBLE,
-        TY_POINTER, TY_FUNC, TY_PARAM
-    };
-
-    struct Type {
-        TypeTag tag;
-        tokenid_t id; // For function arguments
-        Type* pHead;
-        Type* pTail;
-    };
-
     bool typeEqual(Type* a, Type* b) {
         if (a == b) {
             return true;
@@ -3356,6 +3445,7 @@
                         argCount++;
                     }
                     rsym = loc = 0;
+                    pReturnType = pDecl->pHead;
                     a = pGen->functionEntry(argCount);
                     block(0, true);
                     pGen->gsym(rsym);
@@ -3502,11 +3592,10 @@
         mkpVoid = createType(TY_VOID, NULL, NULL, mGlobalArena);
         mkpFloat = createType(TY_FLOAT, NULL, NULL, mGlobalArena);
         mkpDouble = createType(TY_DOUBLE, NULL, NULL, mGlobalArena);
+        mkpIntFn =  createType(TY_FUNC, mkpInt, NULL, mGlobalArena);
         mkpIntPtr = createPtrType(mkpInt, mGlobalArena);
         mkpCharPtr = createPtrType(mkpChar, mGlobalArena);
-        mkpPtrIntFn = createPtrType(
-                  createType(TY_FUNC, mkpInt, NULL, mGlobalArena),
-                  mGlobalArena);
+        mkpPtrIntFn = createPtrType(mkpIntFn, mGlobalArena);
     }
 
     void checkForUndefinedForwardReferences() {