public Tuple<AST.Env, AST.FuncDef> GetFuncDef(AST.Env env)
        {
            // Get storage class specifier and base type from declaration specifiers.
            Tuple<AST.Env, AST.Decln.SCS, AST.ExprType> r_specs = this.specs.GetSCSType(env);
            env = r_specs.Item1;
            AST.Decln.SCS scs = r_specs.Item2;
            AST.ExprType base_type = r_specs.Item3;

            // Get function name and function type from declarator.
            Tuple<String, AST.ExprType> r_declr = this.declr.GetNameAndType(env, base_type);
            String name = r_declr.Item1;
            AST.ExprType type = r_declr.Item2;

            AST.TFunction func_type;
            if (type.kind == AST.ExprType.Kind.FUNCTION) {
                func_type = (AST.TFunction)type;
            } else {
                throw new InvalidOperationException($"{name} is not a function.");
            }

            switch (scs) {
                case AST.Decln.SCS.AUTO:
                case AST.Decln.SCS.EXTERN:
                case AST.Decln.SCS.STATIC:
                    env = env.PushEntry(AST.Env.EntryKind.GLOBAL, name, type);
                    break;
                case AST.Decln.SCS.TYPEDEF:
                default:
                    throw new InvalidOperationException("Invalid storage class specifier for function definition.");
            }

            env = env.SetCurrentFunction(func_type);

            Tuple<AST.Env, AST.Stmt> r_stmt = this.stmt.GetStmt(env);
            env = r_stmt.Item1;
            AST.Stmt stmt = r_stmt.Item2;

            env = env.SetCurrentFunction(new AST.TEmptyFunction());

            return Tuple.Create(env, new AST.FuncDef(name, scs, func_type, stmt));
        }