From dba806ca25b5bc53b744e2c1c2d72fa3d6cd8e05 Mon Sep 17 00:00:00 2001 From: xleroy Date: Mon, 5 May 2014 08:27:22 +0000 Subject: Support for old-style K&R function definitions. git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@2478 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e --- cparser/Elab.ml | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'cparser/Elab.ml') diff --git a/cparser/Elab.ml b/cparser/Elab.ml index 780cf09..d19b988 100644 --- a/cparser/Elab.ml +++ b/cparser/Elab.ml @@ -1874,6 +1874,46 @@ let elab_fundef env spec name body loc = emit_elab loc (Gfundef fn); env1 +let elab_kr_fundef env spec name params defs body loc = + (* Check that the declarations only declare parameters *) + let check_one_decl (Init_name(Name(s, dty, attrs, loc'), ie)) = + if not (List.mem s params) then + error loc' "Declaration of '%s' which is not a function parameter" s; + if ie <> NO_INIT then + error loc' "Illegal initialization of function parameter '%s'" s in + let check_decl = function + | DECDEF((spec', name_init_list), loc') -> + List.iter check_one_decl name_init_list + | d -> + (* Should never be produced by the parser *) + fatal_error (get_definitionloc d) + "Illegal declaration of function parameter" in + List.iter check_decl defs; + (* Convert old-style K&R function definition to modern prototyped form *) + let rec convert_param param = function + | [] -> + (* Parameter is not declared, defaults to "int" in ISO C90, + is an error in ISO C99. Just emit a warning. *) + warning loc "Type of '%s' defaults to 'int'" param; + PARAM([SpecType Tint], Some param, JUSTBASE, [], loc) + | DECDEF((spec', name_init_list), loc') :: defs -> + let rec convert = function + | [] -> convert_param param defs + | Init_name(Name(s, dty, attrs, loc''), ie) :: l -> + if s = param + then PARAM(spec', Some param, dty, attrs, loc'') + else convert l + in convert name_init_list + | _ -> + assert false (* checked earlier *) in + let params' = + List.map (fun p -> convert_param p defs) params in + let name' = + let (Name(s, dty, attr, loc')) = name in + Name(s, PROTO(dty, (params', false)), attr, loc') in + (* Elaborate the prototyped form *) + elab_fundef env spec name' body loc + let rec elab_definition (local: bool) (env: Env.t) (def: Cabs.definition) : decl list * Env.t = match def with @@ -1883,6 +1923,12 @@ let rec elab_definition (local: bool) (env: Env.t) (def: Cabs.definition) let env1 = elab_fundef env spec name body loc in ([], env1) + (* "int f(x, y) double y; { ... }" *) + | KRFUNDEF(spec, name, params, defs, body, loc) -> + if local then error loc "local definition of a function"; + let env1 = elab_kr_fundef env spec name params defs body loc in + ([], env1) + (* "int x = 12, y[10], *z" *) | DECDEF(init_name_group, loc) -> let ((dl, env1), sto, tydef) = -- cgit v1.2.3