From 353f442efb4a6e7930dd4316d4f4cdeda81b59f2 Mon Sep 17 00:00:00 2001 From: Rohan Jacob-Rao Date: Fri, 7 Aug 2015 15:32:48 -0700 Subject: [PATCH] Parse debug annotations and add them to AST. --- infer/src/llvm/lAst.ml | 6 +++++- infer/src/llvm/lLexer.mll | 1 + infer/src/llvm/lParser.mly | 14 +++++++++++--- infer/src/llvm/lTrans.ml | 12 ++++++------ 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/infer/src/llvm/lAst.ml b/infer/src/llvm/lAst.ml index 0675d638b..92d4cf050 100644 --- a/infer/src/llvm/lAst.ml +++ b/infer/src/llvm/lAst.ml @@ -43,7 +43,11 @@ type instr = | Alloc of variable * typ * int (* return variable, element type, number of elements *) | Binop -type func_def = FuncDef of variable * typ option * (typ * string) list * instr list +type annotation = Annotation of int + +type annotated_instr = instr * annotation option + +type func_def = FuncDef of variable * typ option * (typ * string) list * annotated_instr list type prog = Prog of func_def list diff --git a/infer/src/llvm/lLexer.mll b/infer/src/llvm/lLexer.mll index 96b6d7286..64d872558 100644 --- a/infer/src/llvm/lLexer.mll +++ b/infer/src/llvm/lLexer.mll @@ -166,6 +166,7 @@ rule token = parse | '%' (nonneg_int as i) { NUMBERED_LOCAL (int_of_string i) } | id as str { IDENT str } + | "!dbg" { DEBUG_ANNOTATION } | '!' (id as str) { NAMED_METADATA str } | '!' (nonneg_int as i) { NUMBERED_METADATA (int_of_string i) } | '!' '{' [^ '\n']* '}' { METADATA_NODE } diff --git a/infer/src/llvm/lParser.mly b/infer/src/llvm/lParser.mly index c36f58073..26f7a6d3e 100644 --- a/infer/src/llvm/lParser.mly +++ b/infer/src/llvm/lParser.mly @@ -135,6 +135,7 @@ %token NUMBERED_LOCAL %token IDENT +%token DEBUG_ANNOTATION %token NAMED_METADATA %token NUMBERED_METADATA %token METADATA_NODE @@ -175,8 +176,9 @@ metadata_var: | NUMBERED_METADATA { () } func_def: - | DEFINE ret_tp = ret_typ name = variable LPAREN params = - separated_list(COMMA, pair(typ, IDENT)) RPAREN list(attribute_group) instrs = block { FuncDef (name, ret_tp, params, instrs) } + | DEFINE ret_tp = ret_typ name = variable LPAREN + params = separated_list(COMMA, pair(typ, IDENT)) RPAREN list(attribute_group) + annotated_instrs = block { FuncDef (name, ret_tp, params, annotated_instrs) } attribute_group: | i = ATTRIBUTE_GROUP { i } @@ -214,7 +216,13 @@ ptr_typ: | tp = typ STAR { tp } block: - | LBRACE instrs = list(instr) RBRACE { instrs } + | LBRACE annotated_instrs = list(annotated_instr) RBRACE { annotated_instrs } + +annotated_instr: + | instruction=instr anno=annotation? { (instruction, anno) } + +annotation: + | COMMA DEBUG_ANNOTATION i=NUMBERED_METADATA { Annotation i } instr: (* terminator instructions *) diff --git a/infer/src/llvm/lTrans.ml b/infer/src/llvm/lTrans.ml index 43c7c88ec..d3530ebbb 100644 --- a/infer/src/llvm/lTrans.ml +++ b/infer/src/llvm/lTrans.ml @@ -34,12 +34,12 @@ let rec trans_typ : LAst.typ -> Sil.typ = function | Tmetadata -> raise (ImproperTypeError "Tried to generate Sil type from LLVM metadata type.") (* Generate list of SIL instructions and list of local variables *) -let rec trans_instrs (cfg : Cfg.cfg) (procdesc : Cfg.Procdesc.t) - : LAst.instr list -> Sil.instr list * (Mangled.t * Sil.typ) list = function +let rec trans_annotated_instrs (cfg : Cfg.cfg) (procdesc : Cfg.Procdesc.t) + : LAst.annotated_instr list -> Sil.instr list * (Mangled.t * Sil.typ) list = function | [] -> ([], []) | h :: t -> - let (sil_instrs, locals) = trans_instrs cfg procdesc t in - begin match h with + let (sil_instrs, locals) = trans_annotated_instrs cfg procdesc t in + begin match fst h with | Ret None -> (sil_instrs, locals) | Ret (Some (tp, exp)) -> let procname = Cfg.Procdesc.get_proc_name procdesc in @@ -68,7 +68,7 @@ let rec trans_instrs (cfg : Cfg.cfg) (procdesc : Cfg.Procdesc.t) (* Update CFG and call graph with new function definition *) let trans_func_def (cfg : Cfg.cfg) (cg: Cg.t) : LAst.func_def -> unit = function - FuncDef (func_name, ret_tp_opt, params, instrs) -> + FuncDef (func_name, ret_tp_opt, params, annotated_instrs) -> let (proc_attrs : Sil.proc_attributes) = let open Sil in { access = Sil.Default; @@ -109,7 +109,7 @@ let trans_func_def (cfg : Cfg.cfg) (cg: Cg.t) : LAst.func_def -> unit = function (* link all nodes in a chain for now *) | [] -> Cfg.Node.set_succs_exn start_node [exit_node] [exit_node] | nd :: nds -> Cfg.Node.set_succs_exn start_node [nd] [exit_node]; link_nodes nd nds in - let (sil_instrs, locals) = trans_instrs cfg procdesc instrs in + let (sil_instrs, locals) = trans_annotated_instrs cfg procdesc annotated_instrs in let nodes = Utils.list_map (node_of_sil_instr cfg procdesc) sil_instrs in Cfg.Procdesc.set_start_node procdesc start_node; Cfg.Procdesc.set_exit_node procdesc exit_node;