permit multiline comments and strings in macros
[bpt/coccinelle.git] / parsing_c / ast_c.ml
index 014ba52..251d35f 100644 (file)
@@ -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
@@ -337,7 +340,7 @@ and expression = (expressionbis * exp_info ref (* semantic: *)) wrap3
   | ParenExpr of expression
 
   (* for C++: *)
-  | New of argument
+  | New of (argument wrap2 (* , *) list) option * argument
   | Delete of expression
 
   (* cppext: IfdefExpr TODO *)
@@ -380,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
@@ -466,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.
   *)
@@ -477,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
@@ -517,6 +522,8 @@ and declaration =
   (* cppext: *)
     (* 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 * v_init) option;
@@ -606,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
@@ -685,6 +692,9 @@ and toplevel =
 
   | FinalDef of info (* EOF *)
 
+  (* c++ *)
+  | Namespace of toplevel list * il
+
 (* ------------------------------------------------------------------------- *)
 and program = toplevel list
 
@@ -823,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;
   }
 
@@ -985,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
@@ -1023,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;
   }
 
@@ -1043,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;
   }
 
@@ -1068,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));
   }
 
@@ -1086,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));
   }
 
@@ -1119,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)
 
 
 
@@ -1175,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
       )
@@ -1216,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 =
@@ -1234,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
+