diff --git a/infer/src/llvm/lAst.ml b/infer/src/llvm/lAst.ml index 92d4cf050..b90d34d35 100644 --- a/infer/src/llvm/lAst.ml +++ b/infer/src/llvm/lAst.ml @@ -31,6 +31,7 @@ type typ = | Tptr of typ | Tvector of int * typ | Tarray of int * typ + | Tfunc of typ option * typ list | Tlabel | Tmetadata diff --git a/infer/src/llvm/lParser.mly b/infer/src/llvm/lParser.mly index 024f83316..d337377b3 100644 --- a/infer/src/llvm/lParser.mly +++ b/infer/src/llvm/lParser.mly @@ -188,7 +188,7 @@ metadata_value: func_def: | DEFINE ret_tp = ret_typ name = variable LPAREN - params = separated_list(COMMA, pair(typ, IDENT)) RPAREN attribute_group* + params = separated_list(COMMA, pair(first_class_typ, IDENT)) RPAREN attribute_group* annotated_instrs = block { FuncDef (name, ret_tp, params, annotated_instrs) } attribute_group: @@ -196,9 +196,16 @@ attribute_group: ret_typ: | VOID { None } - | tp = typ { Some tp } + | tp = first_class_typ { Some tp } typ: + | tp = func_typ { tp } + | tp = first_class_typ { tp } + +func_typ: + | ret_tp = ret_typ LPAREN param_tps = separated_list(COMMA, first_class_typ) RPAREN { Tfunc (ret_tp, param_tps) } + +first_class_typ: | tp = element_typ { tp } (*| X86_MMX { () }*) | tp = vector_typ { tp } diff --git a/infer/src/llvm/lTrans.ml b/infer/src/llvm/lTrans.ml index d3530ebbb..e11025165 100644 --- a/infer/src/llvm/lTrans.ml +++ b/infer/src/llvm/lTrans.ml @@ -30,6 +30,7 @@ let rec trans_typ : LAst.typ -> Sil.typ = function | Tptr tp -> Sil.Tptr (trans_typ tp, Sil.Pk_pointer) | Tvector (i, tp) | Tarray (i, tp) -> Sil.Tarray (trans_typ tp, Sil.Const (Sil.Cint (Sil.Int.of_int i))) + | Tfunc _ -> Sil.Tfun false | Tlabel -> raise (ImproperTypeError "Tried to generate Sil type from LLVM label type.") | Tmetadata -> raise (ImproperTypeError "Tried to generate Sil type from LLVM metadata type.")