X-Git-Url: http://git.hcoop.net/bpt/coccinelle.git/blobdiff_plain/f59c9fb7f14038b6e15c3578d930f164a8df9c6c..HEAD:/parsing_c/ast_c.ml diff --git a/parsing_c/ast_c.ml b/parsing_c/ast_c.ml index 431d107..251d35f 100644 --- a/parsing_c/ast_c.ml +++ b/parsing_c/ast_c.ml @@ -100,6 +100,9 @@ type info = { (* set in comment_annotater_c.ml *) comments_tag: comments_around ref; + (* annotations on the token (mutable) *) + mutable annots_tag: Token_annot.annots + (* todo? token_info : sometimes useful to know what token it was *) } and il = info list @@ -172,7 +175,7 @@ and fullType = typeQualifier * typeC and typeC = typeCbis wrap (* todo reput wrap3 *) and typeCbis = - NoType (* for c++ only *) + NoType (* for c++ only, and for K&R C *) | BaseType of baseType | Pointer of fullType @@ -291,7 +294,8 @@ and attribute = attributebis wrap and expression = (expressionbis * exp_info ref (* semantic: *)) wrap3 and exp_info = exp_type option * test and exp_type = fullType (* Type_c.completed_and_simplified *) * local - and local = LocalVar of parse_info | NotLocalVar (* cocci: *) + and local = LocalVar of parse_info | StaticLocalVar of parse_info + | NotLocalVar (* cocci: *) and test = Test | NotTest (* cocci: *) and expressionbis = @@ -330,17 +334,18 @@ and expression = (expressionbis * exp_info ref (* semantic: *)) wrap3 (* gccext: *) | StatementExpr of compound wrap (* ( ) new scope *) - | Constructor of fullType * initialiser wrap2 (* , *) list + | Constructor of fullType * initialiser (* for unparser: *) | ParenExpr of expression (* for C++: *) - | New of argument + | New of (argument wrap2 (* , *) list) option * 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 @@ -378,7 +383,7 @@ and expression = (expressionbis * exp_info ref (* semantic: *)) wrap3 and arithOp = | Plus | Minus | Mul | Div | Mod | DecLeft | DecRight - | And | Or | Xor + | And | Or | Xor | Max | Min and logicalOp = | Inf | Sup | InfEq | SupEq @@ -464,6 +469,8 @@ and statement = statementbis wrap3 and exprStatement = expression option + and declOrExpr = ForDecl of declaration | ForExp of expression option wrap + (* for Switch, need check that all elements in the compound start * with a case:, otherwise unreachable code. *) @@ -475,7 +482,7 @@ and statement = statementbis wrap3 and iteration = | While of expression * statement | DoWhile of statement * expression - | For of exprStatement wrap * exprStatement wrap * exprStatement wrap * + | For of declOrExpr * exprStatement wrap * exprStatement wrap * statement (* cppext: *) | MacroIteration of string * argument wrap2 list * statement @@ -513,10 +520,13 @@ and statement = statementbis wrap3 and declaration = | DeclList of onedecl wrap2 (* , *) list wrap (* ; fakestart sto *) (* cppext: *) - | MacroDecl of (string * argument wrap2 list) wrap (* fakestart *) + (* bool is true if there is a ; at the end *) + | MacroDecl of (string * argument wrap2 list * bool) wrap (* fakestart *) + | MacroDeclInit of + (string * argument wrap2 list * initialiser) 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 +536,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 @@ -600,7 +613,7 @@ and define = string wrap (* #define s eol *) * (define_kind * define_val) | DefineFunction of definition | DefineInit of initialiser (* in practice only { } with possible ',' *) - (* TODO DefineMulti of define_val list *) + | DefineMulti of statement list | DefineText of string wrap | DefineEmpty @@ -679,6 +692,9 @@ and toplevel = | FinalDef of info (* EOF *) + (* c++ *) + | Namespace of toplevel list * il + (* ------------------------------------------------------------------------- *) and program = toplevel list @@ -705,8 +721,10 @@ and metavars_binding = (Ast_cocci.meta_name, metavar_binding_kind) assoc | MetaTypeVal of fullType | MetaInitVal of initialiser + | MetaInitListVal of initialiser wrap2 list | MetaDeclVal of declaration | MetaFieldVal of field + | MetaFieldListVal of field list | MetaStmtVal of statement (* Could also be in Lib_engine.metavars_binding2 with the ParenVal, @@ -815,6 +833,7 @@ let no_virt_pos = ({str="";charpos=0;line=0;column=0;file=""},-1) let fakeInfo pi = { pinfo = FakeTok ("",no_virt_pos); cocci_tag = ref emptyAnnot; + annots_tag = Token_annot.empty; comments_tag = ref emptyComments; } @@ -977,6 +996,11 @@ let compare_pos ii1 ii2 = let equal_posl (l1,c1) (l2,c2) = (l1 =|= l2) && (c1 =|= c2) +let compare_posl (l1,c1) (l2,c2) = + match l2 - l1 with + 0 -> c2 - c1 + | r -> r + let info_to_fixpos ii = match pinfo_of_info ii with OriginTok pi -> Ast_cocci.Real pi.Common.charpos @@ -1015,6 +1039,7 @@ let al_info tokenindex x = file = ""; str = str_of_info x}); cocci_tag = ref emptyAnnot; + annots_tag = Token_annot.empty; comments_tag = ref emptyComments; } @@ -1035,6 +1060,7 @@ let real_al_info x = file = ""; str = str_of_info x}); cocci_tag = ref emptyAnnot; + annots_tag = Token_annot.empty; comments_tag = ref emptyComments; } @@ -1060,12 +1086,14 @@ let al_info_cpp tokenindex x = file = ""; str = str_of_info x}); cocci_tag = ref emptyAnnot; + annots_tag = Token_annot.empty; comments_tag = ref (al_comments !(x.comments_tag)); } let semi_al_info_cpp x = { x with cocci_tag = ref emptyAnnot; + annots_tag = Token_annot.empty; comments_tag = ref (al_comments !(x.comments_tag)); } @@ -1078,6 +1106,7 @@ let real_al_info_cpp x = file = ""; str = str_of_info x}); cocci_tag = ref emptyAnnot; + annots_tag = Token_annot.empty; comments_tag = ref (al_comments !(x.comments_tag)); } @@ -1111,7 +1140,7 @@ let rec (unsplit_comma: ('a, il) either list -> 'a wrap2 list) = let empty_ii = [] in (e, empty_ii)::unsplit_comma xs | Right ii::_ -> - raise Impossible + raise (Impossible 59) @@ -1167,7 +1196,7 @@ let get_s_and_ii_of_name name = s, [iis] | CppConcatenatedName xs -> (match xs with - | [] -> raise Impossible + | [] -> raise (Impossible 60) | ((s,iis),noiiop)::xs -> s, iis ) @@ -1208,8 +1237,8 @@ let info_of_type ft = (* bugfix: because of string->name, the ii can be deeper *) let ii = get_local_ii_of_tybis_inlining_ii_of_name ty in match ii with - | ii::_ -> ii.pinfo - | [] -> failwith "type has no text; need to think again" + | ii::_ -> Some ii.pinfo + | [] -> None (* only Label and Goto have name *) let get_local_ii_of_st_inlining_ii_of_name st = @@ -1226,3 +1255,16 @@ let get_local_ii_of_st_inlining_ii_of_name st = let name_of_parameter param = param.p_namei +> Common.map_option (str_of_name) + +(* ------------------------------------------------------------------------- *) +(* Annotations on tokens *) +(* ------------------------------------------------------------------------- *) + +(* to put a given annotation on a token *) +let put_annot_info info key value = + info.annots_tag <- Token_annot.put_annot key value info.annots_tag + +(* to check if an annotation has such a token *) +let get_annot_info info key = + Token_annot.get_annot info.annots_tag key +