@@ -78,6 +78,10 @@ let smooth_expression lst =
7878
7979let currentFunctionName = ref " <outside any function>"
8080
81+ (* Set to true while parsing a typedef declaration's declarator list, so that
82+ declarator_no_init knows not to call add_identifier for typedef names. *)
83+ let is_typedef_decl = ref false
84+
8185let announceFunctionName ((n , decl , _ , _ ):name ) =
8286 ! Lexerhack. add_identifier n;
8387 (* Start a context that includes the parameter names and the whole body.
@@ -115,6 +119,7 @@ let applyPointer (ptspecs: attribute list list) (dt: decl_type)
115119 loop ptspecs
116120
117121let doDeclaration (loc : cabsloc ) (specs : spec_elem list ) (nl : init_name list ) : definition =
122+ is_typedef_decl := false ;
118123 if isTypedef specs then begin
119124 (* Tell the lexer about the new type names *)
120125 List. iter (fun ((n , _ , _ , _ ), _ ) -> ! Lexerhack. add_type n) nl;
@@ -123,14 +128,8 @@ let doDeclaration (loc: cabsloc) (specs: spec_elem list) (nl: init_name list) :
123128 if nl = [] then
124129 ONLYTYPEDEF (specs, loc)
125130 else begin
126- (* For NO_INIT declarators, add_identifier is called here after parsing.
127- For initialized declarators, it was already called in declarator_init_start
128- before the initializer was parsed (C11 6.2.1.7). *)
129- List. iter (fun ((n , _ , _ , _ ), init ) ->
130- match init with
131- | NO_INIT -> ! Lexerhack. add_identifier n
132- | _ -> ()
133- ) nl;
131+ (* add_identifier is called in declarator_no_init / declarator_init_start as each
132+ declarator is parsed (C11 6.2.1.7), so nothing to do here. *)
134133 DECDEF ((specs, nl), loc)
135134 end
136135
@@ -394,7 +393,7 @@ let transformOffsetOf (speclist, dtype) member =
394393
395394%type <Cabs. init_name > init_declarator
396395%type <Cabs. init_name list > init_declarator_list
397- %type <Cabs. name > declarator declarator_init_start
396+ %type <Cabs. name > declarator declarator_no_init declarator_init_start
398397%type <Cabs. name * expression option > field_decl
399398%type <(Cabs. name * expression option ) list > field_decl_list
400399%type <string * Cabs. decl_type > direct_decl
@@ -1042,11 +1041,23 @@ init_declarator_attr:
10421041
10431042;
10441043init_declarator : /* ISO 6.7 */
1045- declarator { ($1, NO_INIT) }
1044+ declarator_no_init { ($1, NO_INIT) }
10461045| declarator_init_start init_expression location
10471046 { let (n, d, a, l) = $1 in ((n, d, a, joinLoc l $3), $2) }
10481047;
10491048
1049+ /* (* Parses "declarator" (without initializer) and immediately adds the declared name
1050+ as a variable identifier in the lexer hack, for non-typedef declarations only,
1051+ so that subsequent declarators in the same declaration see the name as an
1052+ identifier, not as a type (C11 6.2.1.7: scope begins just after the completion
1053+ of its declarator). For typedef declarations (is_typedef_decl = true), the name
1054+ is registered later via add_type in doDeclaration. *) */
1055+ declarator_no_init :
1056+ declarator { let (n, _, _, _) = $1 in
1057+ if not !is_typedef_decl then !Lexerhack. add_identifier n;
1058+ $1 }
1059+ ;
1060+
10501061/* (* Parses "declarator =" and adds the declared name as a variable identifier
10511062 in the lexer hack, so that in the initializer the name shadows any typedef
10521063 with the same name (C11 6.2.1.7: scope begins just after the completion of the
@@ -1057,7 +1068,7 @@ declarator_init_start:
10571068
10581069decl_spec_list_common : /* ISO 6.7 */
10591070 /* ISO 6.7 .1 */
1060- | TYPEDEF decl_spec_list_opt { SpecTypedef :: $2, $1 }
1071+ | TYPEDEF decl_spec_list_opt { is_typedef_decl := true; SpecTypedef :: $2, $1 }
10611072| EXTERN decl_spec_list_opt { SpecStorage EXTERN :: $2, $1 }
10621073| STATIC decl_spec_list_opt { SpecStorage STATIC :: $2, $1 }
10631074| AUTO decl_spec_list_opt { SpecStorage AUTO :: $2, $1 }
0 commit comments