*)
-(* Yoann Padioleau, Julia Lawall
- *
- * Copyright (C) 2006, 2007, 2008 Ecole des Mines de Nantes
- * Copyright (C) 2009, 2010 DIKU, INRIA, LIP6
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License (GPL)
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * file license.txt for more details.
- *
- * This file was part of Coccinelle.
- *)
-
open Common
module A = Ast_cocci
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
val optional_qualifier_flag : (bool -> tin -> 'x tout) -> (tin -> 'x tout)
val value_format_flag: (bool -> tin -> 'x tout) -> (tin -> 'x tout)
-
end
(*****************************************************************************)
| _, ((B.Sequence _,_),_)
| _, ((B.StatementExpr _,_),_)
| _, ((B.Constructor _,_),_)
+ | _, ((B.New _,_),_)
+ | _, ((B.Delete _,_),_)
-> fail
fail
and (ident: info_ident -> (A.ident, string * Ast_c.info) matcher) =
- fun infoidb ida ((idb, iib)) -> (* (idb, iib) as ib *)
+ fun infoidb ida ((idb, iib) as ib) -> (* (idb, iib) as ib *)
let check_constraints constraints idb =
let meta_id_val l x = Ast_c.MetaIdVal(x,l) in
match constraints with
| DontKnow -> failwith "MetaLocalFunc, need more semantic info about id"
)
+ (* not clear why disj things are needed, after disjdistr? *)
+ | A.DisjId ias ->
+ ias +> List.fold_left (fun acc ia -> acc >|+|> (ident infoidb ia ib)) fail
+
| A.OptIdent _ | A.UniqueIdent _ ->
failwith "not handling Opt/Unique for ident"
)))
| _, (B.DeclList (xs, iiptvirgb::iifakestart::iisto)) ->
- if X.mode =*= PatternMode
+ let indexify l =
+ let rec loop n = function
+ [] -> []
+ | x::xs -> (n,x)::(loop (n+1) xs) in
+ loop 0 l in
+ let rec repln n vl cur = function
+ [] -> []
+ | x::xs ->
+ if n = cur then vl :: xs else x :: (repln n vl (cur+1) xs) in
+ if X.mode =*= PatternMode || A.get_safe_decl decla
then
- xs +> List.fold_left (fun acc var ->
- acc >||> (
+ (indexify xs) +> List.fold_left (fun acc (n,var) ->
+ (* consider all possible matches *)
+ acc >||> (function tin -> (
X.tokenf_mck mckstart iifakestart >>= (fun mckstart iifakestart ->
onedecl allminus decla (var, iiptvirgb, iisto) >>=
(fun decla (var, iiptvirgb, iisto) ->
return (
(mckstart, allminus, decla),
- (B.DeclList ([var], iiptvirgb::iifakestart::iisto))
- )))))
+ (* adjust the variable that was chosen *)
+ (B.DeclList (repln n var 0 xs,
+ iiptvirgb::iifakestart::iisto))
+ )))) tin))
fail
else
- failwith "More that one variable in decl. Have to split to transform."
+ failwith "More that one variable in decl. Have to split to transform. Check that there is no transformation on the type or the ;"
| A.MacroDecl (sa,lpa,eas,rpa,enda), B.MacroDecl ((sb,ebs),ii) ->
let (iisb, lpb, rpb, iiendb, iifakestart, 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;
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;
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;
(* 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;
B.v_attr = attrs;
B.v_type_bis = typbbis;
}, iivirg) ->
-
tokenf ptvirga iiptvirgb >>= (fun ptvirga iiptvirgb ->
fullType typa typb >>= (fun typa typb ->
ident_cpp DontKnow ida nameidb >>= (fun ida nameidb ->
(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;
)))))
| 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;
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;
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;
| 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;
) >>= (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;
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;
(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) ->
)
+ | _, (B.NoType, ii) -> fail
| _, (B.TypeOfExpr e, ii) -> fail
| _, (B.TypeOfType e, ii) -> fail
let ok = return ((),()) in
let rec loop = function
+ | _, (qua, (B.NoType, _)) ->
+ failwith "compatible_type: matching with NoType"
| Type_cocci.BaseType a, (qua, (B.BaseType b,ii)) ->
compatible_base_type a None b
| _, F.EndStatement _ | _, F.CaseNode _
| _, F.TrueNode | _, F.FalseNode | _, F.AfterNode
| _, F.FallThroughNode | _, F.LoopFallThroughNode
- | _, F.InLoopNode
- -> fail2()
+ | _, F.InLoopNode -> fail2()
(* really ? diff between pattern.ml and transformation.ml *)
| _, F.Fake -> fail2()
)))
else fail
+ | A.Undef(undefa,ida), F.DefineHeader ((idb, ii), B.Undef) ->
+ let (defineb, iidb, ieol) = tuple_of_list3 ii in
+ ident DontKnow ida (idb, iidb) >>= (fun ida (idb, iidb) ->
+ tokenf undefa defineb >>= (fun undefa defineb ->
+ return (
+ A.Undef(undefa,ida),
+ F.DefineHeader ((idb,[defineb;iidb;ieol]),B.Undef)
+ ))
+ )
| A.DefineHeader(definea,ida,params), F.DefineHeader ((idb, ii), defkind) ->
(F.Label (_, _, _)|F.Break (_, _)|F.Continue (_, _)|F.Default (_, _)|
F.Case (_, _)|F.Include _|F.Goto _|F.ExprStatement _|
F.DefineType _|F.DefineExpr _|F.DefineTodo|
- F.DefineHeader (_, _)|F.ReturnExpr (_, _)|F.Return (_, _)|F.MacroIterHeader (_, _)|
+ F.DefineHeader (_, _)|F.ReturnExpr (_, _)|F.Return (_, _)|
+ F.MacroIterHeader (_, _)|
F.SwitchHeader (_, _)|F.ForHeader (_, _)|F.DoWhileTail _|F.DoHeader (_, _)|
F.WhileHeader (_, _)|F.Else _|F.IfHeader (_, _)|
F.SeqEnd (_, _)|F.SeqStart (_, _, _)|