Coccinelle release 0.2.5-rc7.
authorCoccinelle <cocci@diku.dk>
Thu, 17 Mar 2011 13:09:14 +0000 (14:09 +0100)
committerRene Rydhof Hansen <rrh@cs.aau.dk>
Thu, 17 Mar 2011 13:09:14 +0000 (14:09 +0100)
** Language:
- Make a very small attempt to parse C++ code, amounting to accepting
  identifiers containing ::, tilde, and template invocations.  Use the
  option -c++.  This is not likely to be very useful in practice.
- Added metavariable metavariable type.
- Add disjunctions on identifiers in some contexts
- Pretend that & indicates a pointer in -c++ mode
- Support for new

** Features:
- support transformations on variables (only) in declarations that declare
  multiple variables
- allow #endif XXX in C code
- relax_include_path now applied to non local includes too, in which case
  it tries to find a unique file with a suffix of the provided name.
  this is useful for directories that are intended to be symbolic links.
- support matching and removing #undef
- support for iteration in ocaml, requires use of -no_show_diff
- calls to likely and unlikely propagate test expression status to their
  arguments
- reuse typedefs and macros from complete parsing when reparsing the
  transformed code
- optimization for an if branch that is just { ... }
- spatch -control_flow_to_file file.c generates a file file.dot

** Bugfix:
- improved parsing of expressions to allow ... to the right of operators in
  more places
- Fix check_config for Python 2.7 on Fedora 14 (Reported-by: Michael Stefaniuc)
- Check for ocamlfind in configure (Reported-by: Paul E. McKenney)
- Postpone use of ocamlfind at runtime to report fewer errors
- Add support for Python 2.4 binding with the provided pycaml library

16 files changed:
changes.txt
docs/manual/main_grammar.pdf
docs/manual/manual.pdf
docs/manual/options.pdf
docs/manual/spatch_options.tex
engine/cocci_vs_c.ml
globals/config.ml.in
parsing_c/ast_c.ml
parsing_c/lexer_c.mll
parsing_c/parser_c.mly
parsing_c/parsing_hacks.ml
parsing_c/pretty_print_c.ml
parsing_c/test_parsing_c.ml
parsing_c/token_helpers.ml
parsing_c/type_annoter_c.ml
parsing_c/visitor_c.ml

index b8dfee8..011dd85 100644 (file)
@@ -22,6 +22,7 @@
 - Added metavariable metavariable type.
 - Add disjunctions on identifiers in some contexts
 - Pretend that & indicates a pointer in -c++ mode
+- Support for new
 
 ** Features:
 - support transformations on variables (only) in declarations that declare
@@ -37,6 +38,7 @@
 - reuse typedefs and macros from complete parsing when reparsing the
   transformed code
 - optimization for an if branch that is just { ... }
+- spatch -control_flow_to_file file.c generates a file file.dot
 
 ** Bugfix:
 - improved parsing of expressions to allow ... to the right of operators in
index f415fd4..fa23684 100644 (file)
Binary files a/docs/manual/main_grammar.pdf and b/docs/manual/main_grammar.pdf differ
index 2753c4e..76d44bb 100644 (file)
Binary files a/docs/manual/manual.pdf and b/docs/manual/manual.pdf differ
index 4b9da5e..bd235e7 100644 (file)
Binary files a/docs/manual/options.pdf and b/docs/manual/options.pdf differ
index 8247ed2..09fe72e 100644 (file)
@@ -132,6 +132,13 @@ $\langle$file$\rangle$:$\langle$function$\rangle$}{ Print a control-flow
 graph for all of the functions in a file or for a specific function in a
 file.  This requires {\tt dot} (http://www.graphviz.org/) and {\tt gv}.}
 
+\rare{-control\_flow\_to\_file $\langle$file$\rangle$,
+  -control\_flow\_to\_file
+  $\langle$file$\rangle$:$\langle$function$\rangle$}{ Like -control\_flow
+  but just puts the dot output in a file in the {\em current} directory.
+  For PATH/file.c, this produces file:xxx.dot for each (selected) function
+  xxx in PATH/file.c.}
+
 \rare{-type\_c $\langle$file$\rangle$}{ Parse a C file and pretty-print a
 version including type information.}
 
index 468db18..fa0e1fe 100644 (file)
@@ -503,7 +503,7 @@ let one_initialisation_to_affectation x =
   match var with
   | Some (name, iniopt) ->
       (match iniopt with
-      | Some (iini, (B.InitExpr e, ii_empty2)) ->
+      | B.ValInit (iini, (B.InitExpr e, ii_empty2)) ->
          let local =
            match local with
              Ast_c.NotLocalDecl -> Ast_c.NotLocalVar
@@ -1361,6 +1361,7 @@ let rec (expression: (A.expression, Ast_c.expression) matcher) =
   | _, ((B.StatementExpr _,_),_)
   | _, ((B.Constructor _,_),_)
   | _, ((B.New _,_),_)
+  | _, ((B.Delete _,_),_)
     -> fail
 
 
@@ -1790,7 +1791,7 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) ->
   *)
 
  | A.TyDecl (tya0, ptvirga),
-   ({B.v_namei = Some (nameidb, None);
+   ({B.v_namei = Some (nameidb, B.NoInit);
      B.v_type = typb0;
      B.v_storage = (B.StoTypedef, inl);
      B.v_local = local;
@@ -1854,7 +1855,7 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) ->
 
                      return (
                      (A.TyDecl (tya0, ptvirga)) +> A.rewrap decla,
-                     (({B.v_namei = Some (nameidb, None);
+                     (({B.v_namei = Some (nameidb, B.NoInit);
                         B.v_type = typb0;
                         B.v_storage = (B.StoTypedef, inl);
                         B.v_local = local;
@@ -1883,7 +1884,7 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) ->
 
                    return (
                      (A.TyDecl (tya0, ptvirga)) +> A.rewrap decla,
-                     (({B.v_namei = Some (nameidb, None);
+                     (({B.v_namei = Some (nameidb, B.NoInit);
                         B.v_type = typb0;
                         B.v_storage = (B.StoTypedef, inl);
                         B.v_local = local;
@@ -1915,7 +1916,7 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) ->
 
     (* could handle iso here but handled in standard.iso *)
    | A.UnInit (stoa, typa, ida, ptvirga),
-     ({B.v_namei = Some (nameidb, None);
+     ({B.v_namei = Some (nameidb, B.NoInit);
        B.v_type = typb;
        B.v_storage = stob;
        B.v_local = local;
@@ -1929,7 +1930,7 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) ->
         (fun stoa (stob, iistob) ->
          return (
            (A.UnInit (stoa, typa, ida, ptvirga)) +>  A.rewrap decla,
-           (({B.v_namei = Some (nameidb, None);
+           (({B.v_namei = Some (nameidb, B.NoInit);
               B.v_type = typb;
               B.v_storage = stob;
               B.v_local = local;
@@ -1940,7 +1941,7 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) ->
          )))))
 
    | A.Init (stoa, typa, ida, eqa, inia, ptvirga),
-     ({B.v_namei = Some(nameidb, Some (iieqb, inib));
+     ({B.v_namei = Some(nameidb, B.ValInit (iieqb, inib));
        B.v_type = typb;
        B.v_storage = stob;
        B.v_local = local;
@@ -1957,7 +1958,7 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) ->
        initialiser inia inib >>= (fun inia inib ->
          return (
            (A.Init (stoa, typa, ida, eqa, inia, ptvirga)) +> A.rewrap decla,
-           (({B.v_namei = Some(nameidb, Some (iieqb, inib));
+           (({B.v_namei = Some(nameidb, B.ValInit (iieqb, inib));
               B.v_type = typb;
               B.v_storage = stob;
               B.v_local = local;
@@ -1967,6 +1968,16 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) ->
            iiptvirgb,iistob)
          )))))))
 
+   | A.Init (stoa, typa, ida, eqa, inia, ptvirga),
+     ({B.v_namei = Some(nameidb, B.ConstrInit _);
+       B.v_type = typb;
+       B.v_storage = stob;
+       B.v_local = local;
+       B.v_attr = attrs;
+       B.v_type_bis = typbbis;
+     },iivirg)
+       -> fail (* C++ constructor declaration not supported in SmPL *)
+
    (* do iso-by-absence here ? allow typedecl and var ? *)
    | A.TyDecl (typa, ptvirga),
      ({B.v_namei = None; B.v_type = typb;
@@ -1994,7 +2005,7 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) ->
 
 
    | A.Typedef (stoa, typa, ida, ptvirga),
-     ({B.v_namei = Some (nameidb, None);
+     ({B.v_namei = Some (nameidb, B.NoInit);
        B.v_type = typb;
        B.v_storage = (B.StoTypedef,inline);
        B.v_local = local;
@@ -2047,7 +2058,7 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) ->
        ) >>= (fun ida nameidb ->
          return (
            (A.Typedef (stoa, typa, ida, ptvirga)) +> A.rewrap decla,
-           (({B.v_namei = Some (nameidb, None);
+           (({B.v_namei = Some (nameidb, B.NoInit);
               B.v_type = typb;
               B.v_storage = (B.StoTypedef,inline);
               B.v_local = local;
@@ -2403,7 +2414,7 @@ and (struct_field: (A.declaration, B.field) matcher) = fun fa fb ->
           let iisto = [] in
           let stob = B.NoSto, false in
           let fake_var =
-            ({B.v_namei = Some (nameidb, None);
+            ({B.v_namei = Some (nameidb, B.NoInit);
               B.v_type = typb;
               B.v_storage = stob;
               B.v_local = Ast_c.NotLocalDecl;
@@ -2418,7 +2429,7 @@ and (struct_field: (A.declaration, B.field) matcher) = fun fa fb ->
             (fun fa (var,iiptvirgb,iisto) ->
 
               match fake_var with
-              | ({B.v_namei = Some (nameidb, None);
+              | ({B.v_namei = Some (nameidb, B.NoInit);
                   B.v_type = typb;
                   B.v_storage = stob;
                 }, iivirg) ->
index 13d843a..148728e 100644 (file)
@@ -1,4 +1,4 @@
-let version = "0.2.5-rc6"
+let version = "0.2.5-rc7"
 
 let path =
   try (Sys.getenv "COCCINELLE_HOME")
index 431d107..c4d7254 100644 (file)
@@ -337,10 +337,11 @@ and expression = (expressionbis * exp_info ref (* semantic: *)) wrap3
 
   (* for C++: *)
   | New of argument
+  | Delete of expression
 
   (* cppext: IfdefExpr TODO *)
 
-  (* cppext: normmally just expression *)
+  (* cppext: normally just expression *)
   and argument = (expression, weird_argument) Common.either
    and weird_argument =
        | ArgType of parameterType
@@ -516,7 +517,7 @@ and declaration =
   | MacroDecl of (string * argument wrap2 list) wrap (* fakestart *)
 
      and onedecl =
-       { v_namei: (name * (info (* = *) * initialiser) option) option;
+       { v_namei: (name * v_init) option;
          v_type: fullType;
          (* semantic: set in type annotated and used in cocci_vs_c
           * when we transform some initialisation into affectation
@@ -526,6 +527,9 @@ and declaration =
          v_local: local_decl; (* cocci: *)
          v_attr: attribute list; (* gccext: *)
        }
+     and v_init =
+       NoInit | ValInit of info * initialiser
+     | ConstrInit of argument wrap2 (* , *) list wrap
      and storage       = storagebis * bool (* gccext: inline or not *)
      and storagebis    = NoSto | StoTypedef | Sto of storageClass
      and storageClass  = Auto  | Static | Register | Extern
index a45e120..fbad367 100644 (file)
@@ -170,7 +170,8 @@ let keyword_table = Common.hash_of_list [
  ]
 
 let cpp_keyword_table = Common.hash_of_list [
-  "new",   (fun ii -> Tnew ii) ]
+  "new",   (fun ii -> Tnew ii);
+  "delete",(fun ii -> Tdelete ii) ]
 
 let error_radix s =
   ("numeric " ^ s ^ " constant contains digits beyond the radix:")
@@ -685,6 +686,7 @@ rule token = parse
         TIdent (s, info)
       }
   | (letter | '$') (letter | digit | '$') *
+      ('<' (letter | '$' | '~') (letter | digit | '$' | '~') * '>') ?
     ("::~" (letter | '$') (letter | digit | '$') *
       ('<' (letter | '$' | '~') (letter | digit | '$' | '~') * '>') ?) +
 
@@ -700,7 +702,23 @@ rule token = parse
          raise
            (Lexical "~ and :: not allowed in C identifiers, try -c++ option")
       }
+  | ((letter | '$') (letter | digit | '$') *)
+      ('<' (letter | '$' | '~') (letter | digit | '$' | '~') * '>')
+
+      {
+        if !Flag.c_plus_plus
+       then
+         begin
+            let info = tokinfo lexbuf in
+            let s = tok lexbuf in
+            TypedefIdent (s, info)
+         end
+       else raise (Lexical "<> detected, try -c++ option")
+      }
+
+
   | (((letter | '$') (letter | digit | '$') *) as first)
+      ('<' (letter | '$' | '~') (letter | digit | '$' | '~') * '>') ?
     "::" (((letter | '$') (letter | digit | '$') *) as second)
       ('<' (letter | '$' | '~') (letter | digit | '$' | '~') * '>') ?
     ("::" ((letter | '$') (letter | digit | '$') *)
@@ -721,6 +739,24 @@ rule token = parse
            (Lexical "~ and :: not allowed in C identifiers, try -c++ option")
       }
 
+   | "::" ((letter | '$') (letter | digit | '$') *)
+      ('<' (letter | '$' | '~') (letter | digit | '$' | '~') * '>') ?
+    ("::" ((letter | '$') (letter | digit | '$') *)
+      ('<' (letter | '$' | '~') (letter | digit | '$' | '~') * '>') ?) *
+
+      {
+        if !Flag.c_plus_plus
+       then
+         begin
+            let info = tokinfo lexbuf in
+            let s = tok lexbuf in
+           TIdent (s, info)
+         end
+       else
+         raise
+           (Lexical "~ and :: not allowed in C identifiers, try -c++ option")
+      }
+
 
   (* ----------------------------------------------------------------------- *)
   (* C constant *)
index 75dde11..54e22c3 100644 (file)
@@ -436,7 +436,7 @@ let mk_string_wrap (s,info) = (s, [info])
        Tstruct Tunion Tenum
        Tbreak Telse Tswitch Tcase Tcontinue Tfor Tdo Tif  Twhile Treturn
        Tgoto Tdefault
-       Tsizeof Tnew
+       Tsizeof Tnew Tdelete TOParCplusplusInit
 
 /*(* C99 *)*/
 %token <Ast_c.info>
@@ -738,15 +738,38 @@ unary_expr:
  | Tsizeof unary_expr              { mk_e(SizeOfExpr ($2))    [$1] }
  | Tsizeof topar2 type_name tcpar2 { mk_e(SizeOfType ($3))    [$1;$2;$4] }
  | Tnew new_argument               { mk_e(New $2)             [$1] }
+ | Tdelete cast_expr               { mk_e(Delete $2)          [$1] }
 
 new_argument:
- | postfix_expr { Left $1 }
- | decl_spec
-     { let ((returnType,hasreg), iihasreg) = fixDeclSpecForParam $1 in
+ | TIdent TOPar argument_list_ne TCPar
+     { let fn = mk_e(Ident (RegularName (mk_string_wrap $1))) [] in
+       Left (mk_e(FunCall (fn, $3)) [$2;$4]) }
+ | TIdent TOPar TCPar
+     { let fn = mk_e(Ident (RegularName (mk_string_wrap $1))) [] in
+       Left(mk_e(FunCall (fn, [])) [$2;$3]) }
+ | TypedefIdent TOPar argument_list_ne TCPar
+     { let fn = mk_e(Ident (RegularName (mk_string_wrap $1))) [] in
+       Left (mk_e(FunCall (fn, $3)) [$2;$4]) }
+ | TypedefIdent TOPar TCPar
+     { let fn = mk_e(Ident (RegularName (mk_string_wrap $1))) [] in
+       Left (mk_e(FunCall (fn, [])) [$2;$3]) }
+ | type_spec
+     { let ty = addTypeD ($1,nullDecl) in
+       let ((returnType,hasreg), iihasreg) = fixDeclSpecForParam ty in
        Right (ArgType { p_namei = None; p_type = returnType;
                        p_register = hasreg, iihasreg;
                      } )
      }
+ | new_argument TOCro expr TCCro
+     {
+       match $1 with
+        Left(e) -> Left(mk_e(ArrayAccess (e, $3)) [$2;$4])
+       | Right(ArgType(ty)) -> (* lots of hacks to make the right type *)
+          let fty = mk_ty (Array (Some $3, ty.Ast_c.p_type)) [$2;$4] in
+          let pty = { ty with p_type = fty } in
+          Right(ArgType pty)
+       | _ -> raise Impossible
+     } 
 
 unary_op:
  | TAnd   { GetRef,     $1 }
@@ -778,6 +801,7 @@ postfix_expr:
  | topar2 type_name tcpar2 TOBrace initialize_list gcc_comma_opt TCBrace
      { mk_e(Constructor ($2, List.rev $5)) ([$1;$3;$4;$7] ++ $6) }
 
+
 primary_expr:
  | identifier_cpp  { mk_e(Ident  ($1)) [] }
  | TInt
@@ -1298,14 +1322,9 @@ decl2:
        DeclList (
          ($2 +> List.map (fun ((((name,f),attrs), ini), iivirg) ->
            let s = str_of_name name in
-           let iniopt =
-             match ini with
-             | None -> None
-             | Some (ini, iini) -> Some (iini, ini)
-           in
           if fst (unwrap storage) =*= StoTypedef
           then LP.add_typedef s;
-           {v_namei = Some (name, iniopt);
+           {v_namei = Some (name, ini);
             v_type = f returnType;
             v_storage = unwrap storage;
             v_local = local;
@@ -1370,9 +1389,11 @@ decl_spec: decl_spec2    { dt "declspec" (); $1  }
 /*(* declarators (right part of type and variable) *)*/
 /*(*-----------------------------------------------------------------------*)*/
 init_declarator2:
- | declaratori                  { ($1, None) }
- | declaratori teq initialize   { ($1, Some ($3, $2)) }
-
+ | declaratori                  { ($1, NoInit) }
+ | declaratori teq initialize   { ($1, ValInit($2, $3)) }
+ /* C++ only */
+ | declaratori TOParCplusplusInit argument_list TCPar
+     { ($1, ConstrInit($3,[$2;$4])) }
 
 
 /*(*----------------------------*)*/
index 835fa8c..f9019e8 100644 (file)
@@ -81,12 +81,13 @@ let is_known_typdef =
  * because it would compute msg_typedef at compile time when
  * the flag debug_typedef is always false
  *)
-let msg_typedef s =
+let msg_typedef s =
   incr Stat.nTypedefInfer;
   msg_gen (!Flag_parsing_c.debug_typedef)
     is_known_typdef
     (fun s ->
-      pr2_cpp ("TYPEDEF: promoting: " ^ s)
+      (*pr2_cpp (Printf.sprintf "TYPEDEF: promoting(%d): %s" n s)*)
+      pr2_cpp (Printf.sprintf "TYPEDEF: promoting: %s" s)
     )
     s
 
@@ -1643,6 +1644,16 @@ let lookahead2 ~pass next before =
 
   match (next, before) with
 
+  (* c++ hacks *)
+  (* yy xx(   and in function *)
+  | TOPar i1::_,              TIdent(s,i2)::TypedefIdent _::_
+      when !Flag.c_plus_plus && (LP.current_context () = (LP.InFunction)) ->
+        pr2_cpp("constructed_object: "  ^s);
+        TOParCplusplusInit i1
+  | TypedefIdent(s,i)::TOPar i1::_,_
+      when !Flag.c_plus_plus && (LP.current_context () = (LP.InFunction)) ->
+       TIdent(s,i)
+
   (*-------------------------------------------------------------*)
   (* typedef inference, parse_typedef_fix3 *)
   (*-------------------------------------------------------------*)
@@ -1663,7 +1674,7 @@ let lookahead2 ~pass next before =
 
       LP.disable_typedef();
 
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 1; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (* xx yy *)
@@ -1672,7 +1683,7 @@ let lookahead2 ~pass next before =
         ->
          (* && not_annot s2 BUT lead to false positive*)
 
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 2; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
@@ -1680,7 +1691,7 @@ let lookahead2 ~pass next before =
   | (TIdent (s, i1)::Tinline i2::_  , _) when not_struct_enum before
       && ok_typedef s
       ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 3; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
@@ -1689,7 +1700,7 @@ let lookahead2 ~pass next before =
     when not_struct_enum before && (LP.current_context() =*= LP.InParameter)
       && ok_typedef s
       ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 4; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (* xx* [,)] *)
@@ -1699,7 +1710,7 @@ let lookahead2 ~pass next before =
         (* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
       && ok_typedef s
     ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 5; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
@@ -1710,7 +1721,7 @@ let lookahead2 ~pass next before =
       (* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
       && ok_typedef s
     ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 6; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
@@ -1722,7 +1733,7 @@ let lookahead2 ~pass next before =
       && ok_typedef s
       ->
 
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 7; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (* xx const *)
@@ -1732,7 +1743,7 @@ let lookahead2 ~pass next before =
       (* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
       ->
 
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 8; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
@@ -1743,14 +1754,14 @@ let lookahead2 ~pass next before =
       ->
       (* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
 
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 9; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
   (* ( const xx)  *)
   | (TIdent (s, i1)::TCPar _::_,  (Tconst _ | Tvolatile _|Trestrict _)::TOPar _::_) when
       ok_typedef s ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 10; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
@@ -1760,7 +1771,7 @@ let lookahead2 ~pass next before =
     when not_struct_enum before
       && ok_typedef s
     ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 11; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (* [(,] xx [   AND parameterdeclaration *)
@@ -1768,7 +1779,7 @@ let lookahead2 ~pass next before =
       when (LP.current_context() =*= LP.InParameter)
       && ok_typedef s
      ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 12; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (*------------------------------------------------------------*)
@@ -1781,7 +1792,7 @@ let lookahead2 ~pass next before =
      (Tregister _|Tstatic _  |Tvolatile _|Tconst _|Trestrict _)::_) when
       pointer ptr && ok_typedef s
         ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 13; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (*  TODO  xx * yy ; AND in start of compound element  *)
@@ -1793,7 +1804,7 @@ let lookahead2 ~pass next before =
       && pointer ptr && ok_typedef s
       ->
 
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 14; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
@@ -1804,7 +1815,7 @@ let lookahead2 ~pass next before =
     when not_struct_enum before && pointer ptr &&
       (LP.is_top_or_struct (LP.current_context ()))
       ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 15; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (*  xx * yy ,     AND in Toplevel  *)
@@ -1813,7 +1824,7 @@ let lookahead2 ~pass next before =
       && ok_typedef s && pointer ptr
       ->
 
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 16; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (*  xx * yy (     AND in Toplevel  *)
@@ -1822,7 +1833,7 @@ let lookahead2 ~pass next before =
       && (LP.is_top_or_struct (LP.current_context ()))
       && ok_typedef s && pointer ptr
       ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 17; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (* xx * yy [ *)
@@ -1832,7 +1843,7 @@ let lookahead2 ~pass next before =
       (LP.is_top_or_struct (LP.current_context ()))
       && ok_typedef s && pointer ptr
       ->
-      msg_typedef s;  LP.add_typedef_root s;
+      msg_typedef s 18;  LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (* u16: 10; in struct *)
@@ -1840,7 +1851,7 @@ let lookahead2 ~pass next before =
     when       (LP.is_top_or_struct (LP.current_context ()))
       && ok_typedef s
       ->
-      msg_typedef s;  LP.add_typedef_root s;
+      msg_typedef s 19;  LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
@@ -1853,7 +1864,7 @@ let lookahead2 ~pass next before =
       (take_safe 1 !passed_tok <> [Tenum]))
       &&
       !LP._lexer_hint = Some LP.Toplevel ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 20; LP.add_typedef_root s;
       TypedefIdent s
      *)
 
@@ -1862,7 +1873,7 @@ let lookahead2 ~pass next before =
     when not_struct_enum before
       && ok_typedef s && pointer ptr
       ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 21; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
@@ -1871,7 +1882,7 @@ let lookahead2 ~pass next before =
       when not_struct_enum before && (LP.current_context () =*= LP.InParameter)
       && ok_typedef s && pointer ptr
         ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 22; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
@@ -1880,7 +1891,7 @@ let lookahead2 ~pass next before =
      (TOBrace _| TPtVirg _)::_)  when not_struct_enum before
       && ok_typedef s & pointer ptr
         ->
-      msg_typedef s;  LP.add_typedef_root s;
+      msg_typedef s 23;  LP.add_typedef_root s;
       msg_maybe_dangereous_typedef s;
       TypedefIdent (s, i1)
 
@@ -1890,7 +1901,7 @@ let lookahead2 ~pass next before =
      (TOBrace _| TPtVirg _)::_) when
       ok_typedef s && pointer ptr
     ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 24; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
@@ -1900,7 +1911,7 @@ let lookahead2 ~pass next before =
         (* struct user_info_t sometimes *)
       && ok_typedef s && pointer ptr
         ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 25; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (*  xx ** yy *)  (* wrong ? *)
@@ -1909,7 +1920,7 @@ let lookahead2 ~pass next before =
         (* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
       && ok_typedef s
       ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 26; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (* xx *** yy *)
@@ -1918,7 +1929,7 @@ let lookahead2 ~pass next before =
       && ok_typedef s
         (* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
       ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 27; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (*  xx ** ) *)
@@ -1927,7 +1938,7 @@ let lookahead2 ~pass next before =
         (* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
       && ok_typedef s
       ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 28; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
@@ -1947,7 +1958,7 @@ let lookahead2 ~pass next before =
       && ok_typedef s
       ->
 
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 29; LP.add_typedef_root s;
       (*TOPar info*)
       TypedefIdent (s, i1)
 
@@ -1960,7 +1971,7 @@ let lookahead2 ~pass next before =
     when not (TH.is_stuff_taking_parenthized x)
       && ok_typedef s
         ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 30; LP.add_typedef_root s;
       (* TOPar info *)
       TypedefIdent (s, i1)
   *)
@@ -1969,7 +1980,7 @@ let lookahead2 ~pass next before =
     (TOPar info)::(TEq _ |TEqEq _)::_)
     when ok_typedef s
         ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 31; LP.add_typedef_root s;
       (* TOPar info *)
       TypedefIdent (s, i1)
 
@@ -1978,7 +1989,7 @@ let lookahead2 ~pass next before =
   | (TIdent (s, i1)::ptr::TCPar _::TIdent (s2, i2)::_ , (TOPar info)::_)
     when ok_typedef s && pointer ptr
         ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 32; LP.add_typedef_root s;
       (*TOPar info*)
       TypedefIdent (s,i1)
 
@@ -1988,7 +1999,7 @@ let lookahead2 ~pass next before =
       when (*s ==~ regexp_typedef && *) not (TH.is_stuff_taking_parenthized x)
       && ok_typedef s
         ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 33; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
@@ -2005,7 +2016,7 @@ let lookahead2 ~pass next before =
       when not_struct_enum before
       && ok_typedef s
         ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 34; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (* x* ( *y )(params),  function pointer 2 *)
@@ -2013,7 +2024,7 @@ let lookahead2 ~pass next before =
       when not_struct_enum before
       && ok_typedef s
         ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 35; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
index 80e8eea..66060d3 100644 (file)
@@ -145,7 +145,8 @@ let mk_pretty_printers
 
     | ParenExpr (e), [i1;i2] -> pr_elem i1; pp_expression e; pr_elem i2;
 
-    | New  (t),      [i1] -> pr_elem i1; pp_argument t
+    | New   (t),     [i1] -> pr_elem i1; pp_argument t
+    | Delete(t),     [i1] -> pr_elem i1; pp_expression t
 
     | (Ident (_) | Constant _ | FunCall (_,_) | CondExpr (_,_,_)
     | Sequence (_,_)
@@ -154,7 +155,7 @@ let mk_pretty_printers
     | ArrayAccess (_,_) | RecordAccess (_,_) | RecordPtAccess (_,_)
     | SizeOfExpr (_) | SizeOfType (_) | Cast (_,_)
     | StatementExpr (_) | Constructor _
-    | ParenExpr (_) | New (_)),_ -> raise Impossible
+    | ParenExpr (_) | New (_) | Delete (_)),_ -> raise Impossible
     );
 
     if !Flag_parsing_c.pretty_print_type_info
@@ -860,9 +861,12 @@ let mk_pretty_printers
            pp_type_with_ident
              (Some (s, iis)) (Some (storage, iisto))
              returnType attrs;
-           iniopt +> do_option (fun (iini, init) ->
-             pr_elem iini;
-              pp_init init);
+           (match iniopt with
+             Ast_c.NoInit -> ()
+           | Ast_c.ValInit(iini,init) -> pr_elem iini; pp_init init
+           | Ast_c.ConstrInit((init,[lp;rp])) ->
+               pr_elem lp; pp_arg_list init; pr_elem rp
+           | Ast_c.ConstrInit _ -> raise Impossible)
        | None -> pp_type returnType
        );
 
@@ -879,9 +883,12 @@ let mk_pretty_printers
            iivirg +> List.iter pr_elem;
            pp_type_with_ident_rest
              (Some (s, iis)) returnType attrs;
-           iniopt +> do_option (fun (iini, init) ->
-             pr_elem iini; pp_init init
-            );
+           (match iniopt with
+             Ast_c.NoInit -> ()
+           | Ast_c.ValInit(iini,init) -> pr_elem iini; pp_init init
+           | Ast_c.ConstrInit((init,[lp;rp])) ->
+               pr_elem lp; pp_arg_list init; pr_elem rp
+           | Ast_c.ConstrInit _ -> raise Impossible);
 
 
        | x -> raise Impossible
index fc0e980..9150a8a 100644 (file)
@@ -138,16 +138,18 @@ let local_test_cfg launchgv file =
   program +> List.iter (fun (e,_) ->
     let toprocess =
       match specific_func, e with
-      | None, _ -> true
+      | None, Ast_c.Definition (defbis,_) ->
+         Some (Ast_c.str_of_name (defbis.Ast_c.f_name))
       | Some s, Ast_c.Definition (defbis,_)  ->
-          s =$= Ast_c.str_of_name (defbis.Ast_c.f_name)
-      | _, _ -> false
+         let nm = Ast_c.str_of_name (defbis.Ast_c.f_name) in
+          if s =$= nm then Some nm else None
+      | _, _ -> None
     in
 
-    if toprocess
-    then
-      (* old: Flow_to_ast.test !Flag.show_flow def *)
-      (try
+    match toprocess with
+      None -> ()
+    | Some fn -> (* old: Flow_to_ast.test !Flag.show_flow def *)
+       try
           let flow = Ast_to_flow.ast_to_control_flow e in
           flow +> do_option (fun flow ->
             Ast_to_flow.deadcode_detection flow;
@@ -161,12 +163,16 @@ let local_test_cfg launchgv file =
 *)
               flow
             in
-           let filename = Filename.temp_file "output" ".dot" in
+           let filename =
+             if launchgv
+             then Filename.temp_file "output" ".dot"
+             else
+               let fl = Filename.chop_extension (Filename.basename file) in 
+               fl^":"^fn^".dot" in
             Ograph_extended.print_ograph_mutable flow' (filename) launchgv
           )
         with Ast_to_flow.Error (x) -> Ast_to_flow.report_error x
       )
-  )
 
 let test_cfg = local_test_cfg true
 
index 492c5cd..a8ecfa3 100644 (file)
@@ -359,6 +359,8 @@ let info_of_tok = function
   | Tinline              (i) -> i
   | Ttypeof              (i) -> i
   | Tnew                 (i) -> i
+  | Tdelete              (i) -> i
+  | TOParCplusplusInit   (i) -> i
 
   | EOF                  (i) -> i
 
@@ -510,10 +512,12 @@ let visitor_info_of_tok f = function
   | Tsizeof              (i) -> Tsizeof              (f i)
   | Tasm                 (i) -> Tasm                 (f i)
   | Tattribute           (i) -> Tattribute           (f i)
-  | TattributeNoarg      (i) -> TattributeNoarg           (f i)
+  | TattributeNoarg      (i) -> TattributeNoarg      (f i)
   | Tinline              (i) -> Tinline              (f i)
   | Ttypeof              (i) -> Ttypeof              (f i)
   | Tnew                 (i) -> Tnew                 (f i)
+  | Tdelete              (i) -> Tdelete              (f i)
+  | TOParCplusplusInit   (i) -> TOParCplusplusInit   (f i)
   | EOF                  (i) -> EOF                  (f i)
 
 
index b52b593..010f2ab 100644 (file)
@@ -945,6 +945,11 @@ let annotater_expr_visitor_subpart = (fun (k,bigf) expr ->
        pr2_once "Type annotater:not handling New";
        Type_c.noTypeHere (* TODO *)
 
+    | Delete e ->
+       k expr;
+       pr2_once "Type annotater:not handling Delete";
+       Type_c.noTypeHere (* TODO *)
+
   in
   Ast_c.set_type_expr expr ty
 
@@ -1085,9 +1090,13 @@ let rec visit_toplevel ~just_add_in_env ~depth elem =
 
                   if need_annotate_body then begin
                     (* int x = sizeof(x) is legal so need process ini *)
-                    iniopt +> Common.do_option (fun (info, ini) ->
-                      Visitor_c.vk_ini bigf ini
-                    );
+                   match iniopt with
+                     Ast_c.NoInit -> ()
+                   | Ast_c.ValInit(iini,init) -> Visitor_c.vk_ini bigf init
+                   | Ast_c.ConstrInit((args,_)) ->
+                       args +> List.iter (fun (e,ii) ->
+                         Visitor_c.vk_argument bigf e
+                       )
                   end
             );
           );
index b8f16dd..867b18e 100644 (file)
@@ -330,7 +330,8 @@ let rec vk_expr = fun bigf expr ->
 
     | ParenExpr (e) -> exprf e
 
-    | New  t -> vk_argument bigf t
+    | New  t   -> vk_argument bigf t
+    | Delete e -> vk_expr bigf e
 
 
   in exprf expr
@@ -519,10 +520,10 @@ and vk_onedecl = fun bigf onedecl ->
     attrs +> List.iter (vk_attribute bigf);
     var +> Common.do_option (fun (name, iniopt) ->
       vk_name bigf name;
-      iniopt +> Common.do_option (fun (info, ini) ->
-      iif [info];
-      vk_ini bigf ini;
-      );
+      (match iniopt with
+       Ast_c.NoInit -> ()
+      |        Ast_c.ValInit(iini,init) -> iif [iini]; vk_ini bigf init
+      |        Ast_c.ConstrInit((init,ii)) -> iif ii; vk_argument_list bigf init)
     )
   in f (k, bigf) onedecl
 
@@ -1058,6 +1059,7 @@ let rec vk_expr_s = fun bigf expr ->
       | ParenExpr (e) -> ParenExpr (exprf e)
 
       | New  t        -> New (vk_argument_s bigf t)
+      | Delete e      -> Delete (vk_expr_s bigf e)
 
     in
     (e', typ'), (iif ii)
@@ -1298,10 +1300,15 @@ and vk_decl_s = fun bigf d ->
     {v_namei =
       (var +> map_option (fun (name, iniopt) ->
         vk_name_s bigf name,
-        iniopt +> map_option (fun (info, init) ->
-          vk_info_s bigf info,
-          vk_ini_s bigf init
-        )));
+       (match iniopt with
+       Ast_c.NoInit -> iniopt
+      |        Ast_c.ValInit(iini,init) ->
+         Ast_c.ValInit(vk_info_s bigf iini,vk_ini_s bigf init)
+      |        Ast_c.ConstrInit((init,ii)) ->
+         let init =
+           init +> List.map (fun (e,ii) -> vk_argument_s bigf e, iif ii) in
+         Ast_c.ConstrInit((init, List.map (vk_info_s bigf) ii)))
+        ));
      v_type = vk_type_s bigf t;
     (* !!! dont go in semantic related stuff !!! *)
      v_type_bis = tbis;