Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

* lang_cpp/parsing/parsing_hacks_typedef.ml: fix bug

  • Loading branch information...
commit 64a241395295d8241082feb8e1d70d8b645fe88c 1 parent 5903c67
@aryx aryx authored
View
57 lang_cpp/parsing/parsing_hacks_typedef.ml
@@ -1,7 +1,7 @@
(* Yoann Padioleau
*
* Copyright (C) 2002-2008 Yoann Padioleau
- * Copyright (C) 2011 Facebook
+ * Copyright (C) 2011, 2014 Facebook
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License (GPL)
@@ -12,7 +12,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* file license.txt for more details.
*)
-
open Common
module TV = Token_views_cpp
@@ -31,23 +30,20 @@ open Parsing_hacks_lib
* This file gathers parsing heuristics related to the typedefs.
* C is not context-free sensitive; it requires to know when
* an ident corresponds to a typedef or ident. This normally means that
- * we must call cpp on the file and have the lexer and parser cooperates
+ * we must call cpp on the file and have the lexer and parser cooperate
* to remember what is what. In lang_cpp/ we want to parse as-is,
* which means we need to infer back whether an identifier is
* a typedef or not.
*
* In this module we use a view that is more convenient for
* typedefs detection. We got rid of:
- * - template arguments,
- * - qualifiers,
- * - differences between & and *,
+ * - template arguments (see find_template_commentize())
+ * - qualifiers (see find_qualifier_commentize)
+ * - differences between & and * (filter_for_typedef() below)
* - differences between TIdent and TOperator,
* - const, volatile, restrict keywords
* - TODO merge multiple ** or *& or whatever
*
- * See find_template_commentize() and find_qualifier_commentize() in
- * parsing_hacks_cpp.ml
- *
* todo? at the same time certain tokens like const are strong
* signals towards a typedef ident, so maybe could do a first
* pass first which use those tokens?
@@ -57,15 +53,6 @@ open Parsing_hacks_lib
(* Helpers *)
(*****************************************************************************)
-(*
-let is_top_or_struct = function
- | TV.InTopLevel
- | TV.InClassStruct _
- | TV.InStructAnon
- -> true
- | _ -> false
-*)
-
let look_like_multiplication tok =
match tok with
| TEq _ | TAssign _
@@ -182,8 +169,9 @@ let find_typedefs xxs =
match xs with
| [] -> ()
- (* those identifiers (called tags) must not be transformed in typedefs *)
- | {t=(Tstruct _ | Tunion _ | Tenum _ | Tclass _);_}::{t=TIdent _}::xs ->
+ (* struct x ...
+ * those identifiers (called tags) must not be transformed in typedefs *)
+ | {t=(Tstruct _ | Tunion _ | Tenum _ | Tclass _)}::{t=TIdent _}::xs ->
aux xs
(* xx yy *)
@@ -191,16 +179,14 @@ let find_typedefs xxs =
change_tok tok1 (TIdent_Typedef (s, i1));
aux xs
- (* xx * yy with a token before like ., return, etc that probably mean
- * it's a mulitplication
+ (* xx * yy with a token before like ., return, etc
+ * probably mean it's a mulitplication
*)
| {t=tok_before}::{t=TIdent (s,i1)}::{t=TMul _}::{t=TIdent _}::xs
when look_like_multiplication tok_before ->
aux xs
- (* { xx * yy, probably declaration
- * TODO if first declaration in file?
- *)
+ (* { xx * yy, probably declaration *)
| {t=tok_before}::({t=TIdent (s,i1)} as tok1)::{t=TMul _}::{t=TIdent _}::xs
when look_like_declaration tok_before ->
change_tok tok1 (TIdent_Typedef (s, i1));
@@ -214,9 +200,7 @@ let find_typedefs xxs =
aux xs
(* xx * yy
- *
- * could be a multiplication too, so cf rule before and guard
- * with InParameter.
+ * could be a multiplication too, so need InParameter guard/
*)
| ({t=TIdent (s,i1);where=InParameter::_} as tok1)::{t=TMul _}
::{t=TIdent _}::xs
@@ -224,16 +208,14 @@ let find_typedefs xxs =
change_tok tok1 (TIdent_Typedef (s, i1));
aux xs
-
(* xx ** yy
- * TODO: could be a multiplication too, but with less probability
+ * TODO? could be a multiplication too, but with less probability
*)
| ({t=TIdent (s,i1)} as tok1)::{t=TMul _}::{t=TMul _}::{t=TIdent _}::xs ->
change_tok tok1 (TIdent_Typedef (s, i1));
aux xs
-
(* (xx) yy and not a if/while before (, and yy can also be a constant *)
| {t=tok1}::{t=TOPar info1}::({t=TIdent(s, i1)} as tok3)::{t=TCPar info2}
::{t = TIdent (_,_) | TInt _ | TString _ | TFloat _ }::xs
@@ -257,16 +239,19 @@ let find_typedefs xxs =
change_tok tok3 (TIdent_Typedef (s, i1));
aux xs
- (* xx* [,)] *)
- | ({t=TIdent(s, i1)} as tok1)::{t=TMul _}::{t=(TComma _| TCPar _)}::xs ->
+ (* xx* [,)]
+ * don't forget to recurse by reinjecting the comma or closing paren
+ *)
+ | ({t=TIdent(s, i1)} as tok1)::{t=TMul _}
+ ::({t=(TComma _| TCPar _)} as x)::xs ->
change_tok tok1 (TIdent_Typedef (s, i1));
- aux xs
+ aux (x::xs)
(* xx** [,)] *)
| ({t=TIdent(s, i1)} as tok1)::{t=TMul _}::{t=TMul _}
- ::{t=(TComma _| TCPar _)}::xs ->
+ ::({t=(TComma _| TCPar _)} as x)::xs ->
change_tok tok1 (TIdent_Typedef (s, i1));
- aux xs
+ aux (x::xs)
(* [(,] xx [),] where InParameter *)
| {t=(TOPar _ | TComma _)}::({t=TIdent (s, i1); where=InParameter::_} as tok1)
View
15 lang_cpp/parsing/token_views_context.ml
@@ -33,6 +33,9 @@ let is_braceised = function
| Braceised _ -> true
| BToken _ -> false
+(*****************************************************************************)
+(* Argument vs Parameter *)
+(*****************************************************************************)
let look_like_argument tok_before xs =
@@ -82,7 +85,7 @@ let look_like_argument tok_before xs =
| Tok {t=(Tnew _ )} -> true
| Tok {t= tok} when TH.is_binary_operator_except_star tok -> true
| Tok {t=(TInc _ | TDec _)} -> true
- | Tok {t = (TDot _ | TPtrOp _ | TPtrOpStar _ | TDotStar _);_} -> true
+ | Tok {t = (TDot _ | TPtrOp _ | TPtrOpStar _ | TDotStar _)} -> true
| Tok {t = (TOCro _)} -> true
| Tok {t = (TWhy _ | TBang _)} -> true
| _ -> aux xs
@@ -171,6 +174,7 @@ let look_like_parameter tok_before xs =
xxs +> List.exists aux1 || aux xs
+
let look_like_only_idents xs =
xs +> List.for_all (function
| Tok {t=(TComma _ | TIdent _)} -> true
@@ -224,7 +228,7 @@ let set_context_tag_multi groups =
(* struct/union/class x : ... { } *)
| BToken ({t= tokstruct; _})::BToken ({t=TIdent _; _})
- ::BToken ({t=TCol _;_})::xs when TH.is_classkey_keyword tokstruct ->
+ ::BToken ({t=TCol _})::xs when TH.is_classkey_keyword tokstruct ->
(try
let (before, elem, after) = Common2.split_when is_braceised xs in
@@ -243,7 +247,7 @@ let set_context_tag_multi groups =
*)
(* C++: class Foo : ... { *)
- | Tok{t=Tclass _ | Tstruct _;_}::Tok{t=TIdent(s,_);_}
+ | Tok{t=Tclass _ | Tstruct _}::Tok{t=TIdent(s,_)}
::Tok{t= TCol ii}::xs
->
let (before, braces, after) =
@@ -298,7 +302,7 @@ let set_context_tag_multi groups =
(* ) { and the closing } is in column zero, then certainly a function *)
(*TODO1 col 0 not valid anymore with c++ nestedness of method *)
- | BToken ({t=TCPar _;_})::(Braceised (body, tok1, Some tok2))::xs
+ | BToken ({t=TCPar _})::(Braceised (body, tok1, Some tok2))::xs
when tok1.col <> 0 && tok2.col = 0 ->
body +> List.iter (iter_token_brace (fun tok ->
tok.where <- InFunction::tok.where;
@@ -395,6 +399,9 @@ let set_context_tag_multi groups =
);
aux xs
in
+ groups +> TV.iter_token_multi (fun tok ->
+ tok.TV.where <- [TV.InTopLevel];
+ );
aux groups
(*****************************************************************************)
View
3  project.el
@@ -102,7 +102,7 @@
(join-string
(list
"-debugger"
- (case 7
+ (case 203
(0 "-tokens_php /home/pad/pfff/tests/php/parsing/heredoc4.php")
@@ -135,6 +135,7 @@
(200 "-parse_cpp /home/pad/pfff/tests/cpp/foo.h")
(201 "-parse_cpp /tmp/test.cpp")
+ (203 "-parse_cpp /home/pad/pfff/tests/c/parsing/typedef_proto.c")
(300 "-pfff_gephi_dependencies /home/pad/pfff /tmp/pfff.gexf")
(400 "-dump_cmt2 /home/pad/pfff/tests/ml/cmt/foo.cmt")
Please sign in to comment.
Something went wrong with that request. Please try again.