%{
 
 #include <limits.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
 /* The second stage lexer.  Here we incorporate knowledge of the state
    of the parser to tailor the tokens that are returned.  */
 
+/*
+ * The lexer cannot distinguish whether a typedef'ed string is a TYPE or an
+ * IDENT. We need a hint from the parser to handle this accurately.
+ */
+bool dont_want_type_specifier;
+
 int
 yylex(void)
 {
                    goto repeat;
                  }
              }
-           if (!suppress_type_lookup)
+           if (!suppress_type_lookup && !dont_want_type_specifier)
              {
                if (find_symbol(yytext, SYM_TYPEDEF, 1))
                  token = TYPE;
 
 %{
 
 #include <assert.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
 #include "genksyms.h"
                    current_name = NULL;
                  }
                  $$ = $3;
+                 dont_want_type_specifier = false;
                }
        ;
 
                             is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
                  current_name = NULL;
                  $$ = $1;
+                 dont_want_type_specifier = true;
                }
        | init_declarator_list ',' init_declarator
                { struct string_list *decl = *$3;
                             is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
                  current_name = NULL;
                  $$ = $3;
+                 dont_want_type_specifier = true;
                }
        ;
 
                  remove_node($1);
                  $$ = $1;
                }
-       | type_specifier
+       | type_specifier        { dont_want_type_specifier = true; $$ = $1; }
        | type_qualifier
        ;
 
                    current_name = (*$1)->string;
                    $$ = $1;
                  }
-               }
-       | TYPE
-               { if (current_name != NULL) {
-                   error_with_pos("unexpected second declaration name");
-                   YYERROR;
-                 } else {
-                   current_name = (*$1)->string;
-                   $$ = $1;
-                 }
+                 dont_want_type_specifier = false;
                }
        | direct_declarator '(' parameter_declaration_clause ')'
                { $$ = $4; }
        ;
 
 direct_nested_declarator:
-       IDENT
-       | TYPE
+       IDENT   { $$ = $1; dont_want_type_specifier = false; }
        | direct_nested_declarator '(' parameter_declaration_clause ')'
                { $$ = $4; }
        | direct_nested_declarator '(' error ')'
 
 parameter_declaration_list:
        parameter_declaration
+               { $$ = $1; dont_want_type_specifier = false; }
        | parameter_declaration_list ',' parameter_declaration
-               { $$ = $3; }
+               { $$ = $3; dont_want_type_specifier = false; }
        ;
 
 parameter_declaration:
        ptr_operator abstract_declarator
                { $$ = $2 ? $2 : $1; }
        | direct_abstract_declarator
+               { $$ = $1; dont_want_type_specifier = false; }
        ;
 
 direct_abstract_declarator:
                  remove_node($1);
                  $$ = $1;
                }
-       /* This wasn't really a typedef name but an identifier that
-          shadows one.  */
-       | TYPE
-               { remove_node($1);
-                 $$ = $1;
-               }
        | direct_abstract_declarator '(' parameter_declaration_clause ')'
                { $$ = $4; }
        | direct_abstract_declarator '(' error ')'
 
 member_declaration:
        decl_specifier_seq_opt member_declarator_list_opt ';'
-               { $$ = $3; }
+               { $$ = $3; dont_want_type_specifier = false; }
        | error ';'
-               { $$ = $2; }
+               { $$ = $2; dont_want_type_specifier = false; }
        ;
 
 member_declarator_list_opt:
 
 member_declarator_list:
        member_declarator
-       | member_declarator_list ',' member_declarator  { $$ = $3; }
+               { $$ = $1; dont_want_type_specifier = true; }
+       | member_declarator_list ',' member_declarator
+               { $$ = $3; dont_want_type_specifier = true; }
        ;
 
 member_declarator: