Summary: This is the first of 3 stack diffs to replace the parser of types in the clang frontend. In this diff we remove the parser and the lexer and add a new module that does the translation from ast types to sil types. It is still incomplete, i.e. many c++ types are still not treated. However, all the types that we were previously treating in C and ObjC are treated and some C++ ones, such that the tests pass and we get good results in the apps. Sometimes one needs to translate a record type when we havent translated the record itself, so the translation of types and of records needs to be mutual recursive. I managed however to get them into different modules and achieve the mutual recursion using higher order functions.master
parent
a538998ed9
commit
8e547d197d
@ -1,146 +0,0 @@
|
|||||||
(*
|
|
||||||
* Copyright (c) 2013 - present Facebook, Inc.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the BSD style license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*)
|
|
||||||
|
|
||||||
(* Lexer to support a parser of types *)
|
|
||||||
{
|
|
||||||
|
|
||||||
open CTypes_parser
|
|
||||||
|
|
||||||
let line_number = ref 1
|
|
||||||
let parentheses = ref 0
|
|
||||||
|
|
||||||
let parsed_tokens = Buffer.create 1
|
|
||||||
let log lexbuf = Buffer.add_char parsed_tokens ' '; Buffer.add_string parsed_tokens (Lexing.lexeme lexbuf)
|
|
||||||
let reset_log () = Buffer.reset parsed_tokens
|
|
||||||
let get_log () = Buffer.contents parsed_tokens
|
|
||||||
|
|
||||||
let attr_par = ref 0
|
|
||||||
let attr_buf = Buffer.create 1
|
|
||||||
let reset_attr_buf () = Buffer.reset attr_buf
|
|
||||||
let log_attr_buf lexbuf =
|
|
||||||
Buffer.add_string parsed_tokens (Lexing.lexeme lexbuf);
|
|
||||||
Buffer.add_string attr_buf (Lexing.lexeme lexbuf)
|
|
||||||
let get_attr_buf () = Buffer.contents attr_buf
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
let lowerletter = ['a'-'z']
|
|
||||||
let upperletter = ['A'-'Z']
|
|
||||||
|
|
||||||
let underscore = '_'
|
|
||||||
let minus = '-'
|
|
||||||
let letter = lowerletter | upperletter
|
|
||||||
|
|
||||||
let digit = ['0'-'9']
|
|
||||||
let number = digit* | digit+ '.' digit* | digit* '.' digit+
|
|
||||||
let space = [' ' '\t']
|
|
||||||
|
|
||||||
let identifier = (letter | underscore) (letter | underscore | digit | ':')*
|
|
||||||
|
|
||||||
let anonymous_identifier = '(' 'a' 'n' 'o' 'n' 'y' 'm' 'o' 'u' 's' (letter | underscore | digit | ' ' | '.' | ':' | '/' | minus)* ')'
|
|
||||||
|
|
||||||
let nested_anonymous_identifier = (identifier ':' ':')+ (anonymous_identifier | identifier)
|
|
||||||
|
|
||||||
let nested_identifier = identifier (':' ':' identifier)+
|
|
||||||
|
|
||||||
let char = letter | digit
|
|
||||||
|
|
||||||
let hexa_digit = ['0'-'9' 'a'-'f']
|
|
||||||
let hexa = '0' 'x' hexa_digit*
|
|
||||||
|
|
||||||
let dir_sep = '/'
|
|
||||||
let dot = '.'
|
|
||||||
let extension = dot ('c' | 'h' | 'm')
|
|
||||||
let basename = (char | underscore | minus | dot )+
|
|
||||||
let filename = basename extension
|
|
||||||
let path = (dir_sep basename | basename)* filename
|
|
||||||
let attribute_digit = letter | underscore | digit | '(' | ')' | '\"' | ","
|
|
||||||
|
|
||||||
let newline = '\n'
|
|
||||||
|
|
||||||
rule token = parse
|
|
||||||
| space { log lexbuf; token lexbuf }
|
|
||||||
| newline { log lexbuf; incr line_number; token lexbuf }
|
|
||||||
| '.' { log lexbuf; DOT }
|
|
||||||
| ';' { log lexbuf; SEMICOLON }
|
|
||||||
| ':' { log lexbuf; COLON }
|
|
||||||
| ',' { log lexbuf; COMMA }
|
|
||||||
| '\'' { log lexbuf; SINGLE_QUOTE }
|
|
||||||
| '`' { log lexbuf; REV_QUOTE }
|
|
||||||
| '\"' { log lexbuf; DOUBLE_QUOTE }
|
|
||||||
| '^' { log lexbuf; CARRET }
|
|
||||||
| "class" { log lexbuf; CLASS }
|
|
||||||
| "struct" { log lexbuf; STRUCT }
|
|
||||||
| "union" { log lexbuf; UNION }
|
|
||||||
| "enum" { log lexbuf; ENUM }
|
|
||||||
| "unsigned" { log lexbuf; UNSIGNED }
|
|
||||||
| "signed" { log lexbuf; SIGNED }
|
|
||||||
| "void" { log lexbuf; VOID }
|
|
||||||
| "char" { log lexbuf; CHAR }
|
|
||||||
| "short" { log lexbuf; SHORT }
|
|
||||||
| "int" { log lexbuf; INT }
|
|
||||||
| "long" { log lexbuf; LONG }
|
|
||||||
| "_Bool" { log lexbuf; UND_BOOL }
|
|
||||||
| "__uint16_" { log lexbuf; UND_UND_UINT16_ }
|
|
||||||
| "__uint16_t" { log lexbuf; UND_UND_UINT16_T }
|
|
||||||
| "__uint32_" { log lexbuf; UND_UND_UINT32_ }
|
|
||||||
| "__uint32_t" { log lexbuf; UND_UND_UINT32_T }
|
|
||||||
| "__int32_t" { log lexbuf; UND_UND_INT32_T }
|
|
||||||
| "__int64_t" { log lexbuf; UND_UND_INT64_T }
|
|
||||||
| "__uint64_t" { log lexbuf; UND_UND_UINT64_T }
|
|
||||||
| "UInt8" { log lexbuf; UINT8 }
|
|
||||||
| "UInt16" { log lexbuf; UINT16 }
|
|
||||||
| "UInt32" { log lexbuf; UINT32 }
|
|
||||||
| "UInt64" { log lexbuf; UINT64 }
|
|
||||||
| "float" { log lexbuf; FLOAT }
|
|
||||||
| "double" { log lexbuf; DOUBLE }
|
|
||||||
| "volatile" { log lexbuf; VOLATILE }
|
|
||||||
| "*volatile" { log lexbuf; STARVOLATILE }
|
|
||||||
| "<builtin fn type>" { log lexbuf; BUILTIN_FN_TYPE}
|
|
||||||
| "inline" { log lexbuf; INLINE }
|
|
||||||
| "typename" { log lexbuf; TYPENAME }
|
|
||||||
| "const" { log lexbuf; CONST }
|
|
||||||
| "*const" { log lexbuf; STARCONST }
|
|
||||||
| "__strong" { log lexbuf; UND_UND_STRONG }
|
|
||||||
| "__unsafe_unretained" { log lexbuf; UND_UND_UNSAFE_UNRETAINED }
|
|
||||||
| "__weak" { log lexbuf; UND_UND_WEAK }
|
|
||||||
| "__autoreleasing" { log lexbuf; UND_UND_AUTORELEASING }
|
|
||||||
| "*__strong" { log lexbuf; STAR_UND_UND_STRONG }
|
|
||||||
| "*__unsafe_unretained" { log lexbuf; STAR_UND_UND_UNSAFE_UNRETAINED }
|
|
||||||
| "*__weak" { log lexbuf; STAR_UND_UND_WEAK }
|
|
||||||
| "*__autoreleasing" { log lexbuf; STAR_UND_UND_AUTORELEASING }
|
|
||||||
| "noexcept" { log lexbuf; NOEXCEPT }
|
|
||||||
| "restrict" { log lexbuf; RESTRICT }
|
|
||||||
| '%' { log lexbuf; PERCENT }
|
|
||||||
| '&' { log lexbuf; AMPERSAND }
|
|
||||||
| '!' { log lexbuf; EXCLAMATION }
|
|
||||||
| '=' { log lexbuf; EQUAL }
|
|
||||||
| '-' { log lexbuf; MINUS }
|
|
||||||
| '+' { log lexbuf; PLUS }
|
|
||||||
| '<' { log lexbuf; LEFT_CHEVRON }
|
|
||||||
| '>' { log lexbuf; RIGHT_CHEVRON }
|
|
||||||
| '(' { log lexbuf; incr parentheses; LEFT_PARENTHESIS }
|
|
||||||
| ')' { log lexbuf; decr parentheses; RIGHT_PARENTHESIS }
|
|
||||||
| '[' { log lexbuf; LEFT_SQBRACKET }
|
|
||||||
| ']' { log lexbuf; RIGHT_SQBRACKET }
|
|
||||||
| '{' { log lexbuf; LEFT_BRACE }
|
|
||||||
| '}' { log lexbuf; RIGHT_BRACE }
|
|
||||||
| '*' { log lexbuf; STAR }
|
|
||||||
| '|' { log lexbuf; PIPE }
|
|
||||||
| '/' { log lexbuf; SLASH }
|
|
||||||
| '\\' { log lexbuf; BACKSLASH }
|
|
||||||
| hexa as s { log lexbuf; HEXA (s) }
|
|
||||||
| number as n { log lexbuf; NUMBER n }
|
|
||||||
| identifier as s { log lexbuf; IDENT (s) }
|
|
||||||
| anonymous_identifier as s { log lexbuf; ANONYM_IDENT (s) }
|
|
||||||
| nested_identifier as s { log lexbuf; NESTED_IDENT (s) }
|
|
||||||
| nested_anonymous_identifier as s { log lexbuf; NESTED_ANONYM_IDENT (s) }
|
|
||||||
| eof { EOF }
|
|
||||||
|
|
@ -0,0 +1,169 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) 2013 - present Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*)
|
||||||
|
|
||||||
|
open CFrontend_utils
|
||||||
|
|
||||||
|
let custom_qual_type_to_sil_type type_pointer =
|
||||||
|
if Utils.string_is_prefix "custom" type_pointer then
|
||||||
|
let typ =
|
||||||
|
(match CTypes.get_name_from_type_pointer type_pointer with
|
||||||
|
| "custom_class_name", class_name -> Sil.Tvar (CTypes.mk_classname class_name)
|
||||||
|
| "custom_pointer_custom_class_name", class_name ->
|
||||||
|
Sil.Tptr (Sil.Tvar (CTypes.mk_classname class_name), Sil.Pk_pointer)
|
||||||
|
| "custom_struct_name", struct_name -> Sil.Tvar (CTypes.mk_structname struct_name)
|
||||||
|
| "custom_pointer_custom_struct_name", struct_name ->
|
||||||
|
Sil.Tptr (Sil.Tvar (CTypes.mk_structname struct_name), Sil.Pk_pointer)
|
||||||
|
| _ -> assert false) in
|
||||||
|
Some typ
|
||||||
|
else None
|
||||||
|
|
||||||
|
let get_builtin_objc_typename builtin_type =
|
||||||
|
match builtin_type with
|
||||||
|
| `ObjCId -> Sil.TN_csu (Sil.Struct, (Mangled.from_string CFrontend_config.objc_object))
|
||||||
|
| `ObjCClass -> Sil.TN_csu (Sil.Struct, (Mangled.from_string CFrontend_config.objc_class))
|
||||||
|
|
||||||
|
let get_builtin_objc_type builtin_type =
|
||||||
|
let typ = Sil.Tvar (get_builtin_objc_typename builtin_type) in
|
||||||
|
match builtin_type with
|
||||||
|
| `ObjCId -> typ
|
||||||
|
| `ObjCClass -> Sil.Tptr (typ, Sil.Pk_pointer)
|
||||||
|
|
||||||
|
|
||||||
|
let sil_type_of_builtin_type_kind builtin_type_kind =
|
||||||
|
match builtin_type_kind with
|
||||||
|
| `Void -> Sil.Tvoid
|
||||||
|
| `Bool -> Sil.Tint Sil.IBool
|
||||||
|
| `Char_U -> Sil.Tint Sil.IUChar
|
||||||
|
| `UChar -> Sil.Tint Sil.IUChar
|
||||||
|
| `WChar_U -> Sil.Tint Sil.IUChar
|
||||||
|
| `Char_S -> Sil.Tint Sil.IChar
|
||||||
|
| `SChar -> Sil.Tint Sil.ISChar
|
||||||
|
| `WChar_S
|
||||||
|
| `Char16
|
||||||
|
| `Char32 -> Sil.Tint Sil.IChar
|
||||||
|
| `UShort
|
||||||
|
| `Short -> Sil.Tint Sil.IShort
|
||||||
|
| `UInt
|
||||||
|
| `UInt128 -> Sil.Tint Sil.IUInt
|
||||||
|
| `ULong -> Sil.Tint Sil.IULong
|
||||||
|
| `ULongLong -> Sil.Tint Sil.IULongLong
|
||||||
|
| `Int
|
||||||
|
| `Int128 -> Sil.Tint Sil.IInt
|
||||||
|
| `Long -> Sil.Tint Sil.ILong
|
||||||
|
| `LongLong -> Sil.Tint Sil.ILongLong
|
||||||
|
| `Half -> Sil.Tint Sil.IShort (*?*)
|
||||||
|
| `Float -> Sil.Tfloat Sil.FFloat
|
||||||
|
| `Double -> Sil.Tfloat Sil.FDouble
|
||||||
|
| `LongDouble -> Sil.Tfloat Sil.FLongDouble
|
||||||
|
| `NullPtr -> Sil.Tint Sil.IInt
|
||||||
|
| `ObjCId -> get_builtin_objc_type `ObjCId
|
||||||
|
| `ObjCClass -> get_builtin_objc_type `ObjCClass
|
||||||
|
| _ -> Sil.Tvoid
|
||||||
|
|
||||||
|
let rec build_array_type translate_decl tenv type_ptr n =
|
||||||
|
let array_type = qual_type_ptr_to_sil_type translate_decl tenv type_ptr in
|
||||||
|
let exp = Sil.exp_int (Sil.Int.of_int64 (Int64.of_int n)) in
|
||||||
|
Sil.Tarray (array_type, exp)
|
||||||
|
|
||||||
|
and sil_type_of_c_type translate_decl tenv c_type =
|
||||||
|
let open Clang_ast_t in
|
||||||
|
match c_type with
|
||||||
|
| NoneType (type_info) -> Sil.Tvoid
|
||||||
|
| BuiltinType (type_info, builtin_type_kind) ->
|
||||||
|
sil_type_of_builtin_type_kind builtin_type_kind
|
||||||
|
| PointerType (type_info, type_ptr)
|
||||||
|
| ObjCObjectPointerType (type_info, type_ptr) ->
|
||||||
|
let typ = qual_type_ptr_to_sil_type translate_decl tenv type_ptr in
|
||||||
|
if Sil.typ_equal typ (get_builtin_objc_type `ObjCClass) then
|
||||||
|
typ
|
||||||
|
else Sil.Tptr (typ, Sil.Pk_pointer)
|
||||||
|
| ObjCObjectType (type_info, objc_object_type_info) ->
|
||||||
|
qual_type_ptr_to_sil_type translate_decl tenv objc_object_type_info.Clang_ast_t.base_type
|
||||||
|
| BlockPointerType (type_info, type_ptr) ->
|
||||||
|
let typ = qual_type_ptr_to_sil_type translate_decl tenv type_ptr in
|
||||||
|
Sil.Tptr (typ, Sil.Pk_pointer)
|
||||||
|
| IncompleteArrayType (type_info, type_ptr)
|
||||||
|
| DependentSizedArrayType (type_info, type_ptr)
|
||||||
|
| VariableArrayType (type_info, type_ptr) ->
|
||||||
|
build_array_type translate_decl tenv type_ptr (-1)
|
||||||
|
| ConstantArrayType (type_info, type_ptr, n) ->
|
||||||
|
build_array_type translate_decl tenv type_ptr n
|
||||||
|
| FunctionProtoType (type_info, function_type_info, _)
|
||||||
|
| FunctionNoProtoType (type_info, function_type_info) ->
|
||||||
|
Sil.Tfun false
|
||||||
|
| ParenType (type_info, type_ptr) ->
|
||||||
|
qual_type_ptr_to_sil_type translate_decl tenv type_ptr
|
||||||
|
| DecayedType (type_info, type_ptr) ->
|
||||||
|
qual_type_ptr_to_sil_type translate_decl tenv type_ptr
|
||||||
|
| RecordType (type_info, pointer)
|
||||||
|
| EnumType (type_info, pointer) ->
|
||||||
|
decl_ptr_to_sil_type translate_decl tenv pointer
|
||||||
|
| ElaboratedType (type_info) ->
|
||||||
|
(match type_info.Clang_ast_t.ti_desugared_type with
|
||||||
|
Some type_ptr -> qual_type_ptr_to_sil_type translate_decl tenv type_ptr
|
||||||
|
| None -> Sil.Tvoid)
|
||||||
|
| ObjCInterfaceType (type_info, pointer) ->
|
||||||
|
decl_ptr_to_sil_type translate_decl tenv pointer
|
||||||
|
| LValueReferenceType (type_info, type_ptr) ->
|
||||||
|
let typ = qual_type_ptr_to_sil_type translate_decl tenv type_ptr in
|
||||||
|
Sil.Tptr (typ, Sil.Pk_reference)
|
||||||
|
| AttributedType type_info ->
|
||||||
|
(match type_info.Clang_ast_t.ti_desugared_type with
|
||||||
|
| Some type_ptr ->
|
||||||
|
(match Clang_ast_main.PointerMap.find type_ptr !CFrontend_config.pointer_type_index with
|
||||||
|
| ObjCObjectPointerType (type_info', type_ptr') ->
|
||||||
|
let typ = qual_type_ptr_to_sil_type translate_decl tenv type_ptr' in
|
||||||
|
CTypes.sil_type_of_attr_pointer_type typ type_info.Clang_ast_t.ti_raw
|
||||||
|
| _ -> qual_type_ptr_to_sil_type translate_decl tenv type_ptr)
|
||||||
|
| None -> Sil.Tvoid)
|
||||||
|
| _ -> (* TypedefType, etc *)
|
||||||
|
let type_info = Clang_ast_proj.get_type_tuple c_type in
|
||||||
|
match type_info.Clang_ast_t.ti_desugared_type with
|
||||||
|
| Some typ -> qual_type_ptr_to_sil_type translate_decl tenv typ
|
||||||
|
| None -> Sil.Tvoid
|
||||||
|
|
||||||
|
and decl_ptr_to_sil_type translate_decl tenv decl_ptr =
|
||||||
|
let open Clang_ast_t in
|
||||||
|
try Clang_ast_main.PointerMap.find decl_ptr !CFrontend_config.sil_types_map
|
||||||
|
with Not_found ->
|
||||||
|
match Ast_utils.get_decl decl_ptr with
|
||||||
|
| Some (ObjCInterfaceDecl(decl_info, name_info, decl_list, decl_context_info, oidi)) ->
|
||||||
|
Sil.Tvar (CTypes.mk_classname name_info.Clang_ast_t.ni_name)
|
||||||
|
| Some (CXXRecordDecl _ as d)
|
||||||
|
| Some (RecordDecl _ as d) -> translate_decl tenv None d
|
||||||
|
| Some (EnumDecl(_, name_info, _, _, _, _, _) ) ->
|
||||||
|
Sil.Tvar (CTypes.mk_enumname name_info.Clang_ast_t.ni_name)
|
||||||
|
| Some _ ->
|
||||||
|
Printing.log_err "Warning: Wrong decl found for pointer %s "
|
||||||
|
(Clang_ast_j.string_of_pointer decl_ptr);
|
||||||
|
Sil.Tvoid
|
||||||
|
| None ->
|
||||||
|
Printing.log_err "Warning: Decl pointer %s not found."
|
||||||
|
(Clang_ast_j.string_of_pointer decl_ptr);
|
||||||
|
Sil.Tvoid
|
||||||
|
|
||||||
|
and qual_type_ptr_to_sil_type translate_decl tenv type_ptr =
|
||||||
|
try
|
||||||
|
Clang_ast_main.PointerMap.find type_ptr !CFrontend_config.sil_types_map
|
||||||
|
with Not_found ->
|
||||||
|
try
|
||||||
|
let c_type = Clang_ast_main.PointerMap.find type_ptr !CFrontend_config.pointer_type_index in
|
||||||
|
let sil_type = sil_type_of_c_type translate_decl tenv c_type in
|
||||||
|
Ast_utils.update_sil_types_map type_ptr sil_type;
|
||||||
|
sil_type
|
||||||
|
with Not_found ->
|
||||||
|
Printing.log_err "Warning: Type pointer %s not found."
|
||||||
|
(Clang_ast_j.string_of_pointer type_ptr);
|
||||||
|
Sil.Tvoid
|
||||||
|
|
||||||
|
and qual_type_to_sil_type translate_decl tenv qt =
|
||||||
|
let type_ptr = qt.Clang_ast_t.qt_type_ptr in
|
||||||
|
match custom_qual_type_to_sil_type type_ptr with
|
||||||
|
| Some typ -> typ
|
||||||
|
| None -> qual_type_ptr_to_sil_type translate_decl tenv type_ptr
|
@ -0,0 +1,17 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) 2013 - present Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*)
|
||||||
|
|
||||||
|
val get_builtin_objc_typename : [< `ObjCClass | `ObjCId ] -> Sil.typename
|
||||||
|
|
||||||
|
val get_builtin_objc_type : [< `ObjCClass | `ObjCId ] -> Sil.typ
|
||||||
|
|
||||||
|
val sil_type_of_builtin_type_kind : Clang_ast_t.builtin_type_kind -> Sil.typ
|
||||||
|
|
||||||
|
val qual_type_to_sil_type : (Sil.tenv -> string option -> Clang_ast_t.decl -> Sil.typ) ->
|
||||||
|
Sil.tenv -> Clang_ast_t.qual_type -> Sil.typ
|
@ -1,239 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013 - present Facebook, Inc.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the BSD style license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Parser for types in the ast of clang */
|
|
||||||
%{
|
|
||||||
|
|
||||||
%}
|
|
||||||
|
|
||||||
%token INLINE STATIC CONST STARCONST EXTERN VOID CHAR SHORT INT LONG FLOAT DOUBLE UND_BOOL VOLATILE STARVOLATILE CARRET
|
|
||||||
%token CLASS STRUCT UNION UND_UND_UINT16_ UND_UND_UINT16_T UND_UND_UINT32_ UND_UND_INT32_T UND_UND_UINT32_T
|
|
||||||
%token UND_UND_INT64_T UND_UND_UINT64_T UINT8 UINT16 UINT32 UINT64 UNSIGNED SIGNED ENUM BUILTIN_FN_TYPE TYPENAME
|
|
||||||
%token UND_UND_STRONG UND_UND_UNSAFE_RETAIN UND_UND_WEAK UND_UND_AUTORELEASING NOEXCEPT
|
|
||||||
%token STAR_UND_UND_STRONG STAR_UND_UND_UNSAFE_UNRETAINED UND_UND_UNSAFE_UNRETAINED STAR_UND_UND_WEAK STAR_UND_UND_AUTORELEASING
|
|
||||||
|
|
||||||
%token DOT SEMICOLON COLON COMMA SINGLE_QUOTE DOUBLE_QUOTE REV_QUOTE
|
|
||||||
%token PERCENT AMPERSAND EXCLAMATION EQUAL MINUS PLUS RESTRICT
|
|
||||||
%token LEFT_CHEVRON RIGHT_CHEVRON LEFT_PARENTHESIS RIGHT_PARENTHESIS LEFT_SQBRACKET RIGHT_SQBRACKET LEFT_BRACE RIGHT_BRACE
|
|
||||||
%token STAR PIPE SLASH BACKSLASH
|
|
||||||
|
|
||||||
%token <string> HEXA
|
|
||||||
%token <string> NUMBER
|
|
||||||
%token <string> IDENT
|
|
||||||
%token <string> ANONYM_IDENT
|
|
||||||
%token <string> NESTED_IDENT
|
|
||||||
%token <string> NESTED_ANONYM_IDENT
|
|
||||||
|
|
||||||
%token EOF
|
|
||||||
|
|
||||||
%start parse
|
|
||||||
%start pointer_clang_type
|
|
||||||
%start clang_func_type
|
|
||||||
|
|
||||||
%type <Sil.typ> pointer_clang_type
|
|
||||||
%type <Sil.typ> parse
|
|
||||||
%type <(Sil.typ * Sil.typ list)> clang_func_type
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
keyword:
|
|
||||||
| ENUM { "enum" }
|
|
||||||
| UNSIGNED { "unsigned" }
|
|
||||||
| SIGNED { "signed" }
|
|
||||||
| CLASS { "class" }
|
|
||||||
| STRUCT { "struct" }
|
|
||||||
| UNION { "union" }
|
|
||||||
| VOID { "void" }
|
|
||||||
| CHAR { "char" }
|
|
||||||
| SHORT { "short" }
|
|
||||||
| INT { "int" }
|
|
||||||
| LONG { "long" }
|
|
||||||
| TYPENAME { "typename" }
|
|
||||||
| NOEXCEPT { "noexcept" }
|
|
||||||
| CONST { "const" }
|
|
||||||
| STARCONST { "*const" }
|
|
||||||
| FLOAT { "float" }
|
|
||||||
| DOUBLE { "double" }
|
|
||||||
| VOLATILE { "volatile" }
|
|
||||||
| RESTRICT { "restrict" }
|
|
||||||
| STARVOLATILE { "*volatile" }
|
|
||||||
|
|
||||||
|
|
||||||
ident:
|
|
||||||
| IDENT { $1 }
|
|
||||||
;
|
|
||||||
|
|
||||||
anonym_ident:
|
|
||||||
| ANONYM_IDENT { $1 }
|
|
||||||
;
|
|
||||||
|
|
||||||
nested_ident:
|
|
||||||
| NESTED_IDENT { $1 }
|
|
||||||
;
|
|
||||||
|
|
||||||
nested_anonym_ident:
|
|
||||||
| NESTED_ANONYM_IDENT { $1 }
|
|
||||||
;
|
|
||||||
|
|
||||||
ident_csu:
|
|
||||||
| ident {$1}
|
|
||||||
| anonym_ident { $1 }
|
|
||||||
| nested_ident { $1 }
|
|
||||||
| nested_anonym_ident { $1 }
|
|
||||||
|
|
||||||
identk:
|
|
||||||
| ident { $1 }
|
|
||||||
| keyword { $1 }
|
|
||||||
;
|
|
||||||
|
|
||||||
csu_sil:
|
|
||||||
| CLASS { Sil.Class }
|
|
||||||
| STRUCT { Sil.Struct }
|
|
||||||
| UNION { Sil.Union }
|
|
||||||
;
|
|
||||||
|
|
||||||
arc_qualifier:
|
|
||||||
| UND_UND_STRONG { Sil.Pk_pointer }
|
|
||||||
| UND_UND_UNSAFE_UNRETAINED { Sil.Pk_objc_unsafe_unretained }
|
|
||||||
| UND_UND_WEAK { Sil.Pk_objc_weak }
|
|
||||||
| UND_UND_AUTORELEASING { Sil.Pk_objc_autoreleasing }
|
|
||||||
;
|
|
||||||
|
|
||||||
star_arc_qualifier:
|
|
||||||
| STAR_UND_UND_STRONG { Sil.Pk_pointer }
|
|
||||||
| STAR_UND_UND_UNSAFE_UNRETAINED { Sil.Pk_objc_unsafe_unretained }
|
|
||||||
| STAR_UND_UND_WEAK { Sil.Pk_objc_weak }
|
|
||||||
| STAR_UND_UND_AUTORELEASING { Sil.Pk_objc_autoreleasing }
|
|
||||||
;
|
|
||||||
|
|
||||||
number_list:
|
|
||||||
| { [] }
|
|
||||||
| NUMBER { [$1] } /* For dealing with an unspecified number of arguments */
|
|
||||||
| NUMBER COMMA number_list { $1::$3 }
|
|
||||||
;
|
|
||||||
|
|
||||||
pointer_clang_type_list:
|
|
||||||
| { [] }
|
|
||||||
| DOT DOT DOT { [] } /* For dealing with an unspecified number of arguments */
|
|
||||||
| pointer_clang_type { [$1]}
|
|
||||||
| pointer_clang_type COMMA pointer_clang_type_list { $1::$3 }
|
|
||||||
;
|
|
||||||
|
|
||||||
array_index:
|
|
||||||
| LEFT_SQBRACKET NUMBER RIGHT_SQBRACKET { Sil.Const (Sil.Cint((Sil.int_of_int64_kind (Int64.of_string $2) (Sil.IInt)))) }
|
|
||||||
;
|
|
||||||
|
|
||||||
block_type:
|
|
||||||
| pointer_clang_type LEFT_PARENTHESIS CARRET RIGHT_PARENTHESIS
|
|
||||||
LEFT_PARENTHESIS pointer_clang_type_list RIGHT_PARENTHESIS
|
|
||||||
{ Sil.Tfun false }
|
|
||||||
| pointer_clang_type LEFT_PARENTHESIS CARRET arc_qualifier RIGHT_PARENTHESIS
|
|
||||||
LEFT_PARENTHESIS pointer_clang_type_list RIGHT_PARENTHESIS
|
|
||||||
{ Sil.Tfun false }
|
|
||||||
| pointer_clang_type LEFT_PARENTHESIS CARRET CONST arc_qualifier RIGHT_PARENTHESIS
|
|
||||||
LEFT_PARENTHESIS pointer_clang_type_list RIGHT_PARENTHESIS
|
|
||||||
{ Sil.Tfun false }
|
|
||||||
| pointer_clang_type LEFT_PARENTHESIS CARRET CONST RIGHT_PARENTHESIS
|
|
||||||
LEFT_PARENTHESIS pointer_clang_type_list RIGHT_PARENTHESIS
|
|
||||||
{ Sil.Tfun false }
|
|
||||||
;
|
|
||||||
|
|
||||||
array_qualifier:
|
|
||||||
| CONST {}
|
|
||||||
| arc_qualifier {} /* Currently array do not deal with arc qualifiers */
|
|
||||||
;
|
|
||||||
|
|
||||||
template:
|
|
||||||
| LEFT_CHEVRON pointer_clang_type_list RIGHT_CHEVRON {}
|
|
||||||
| LEFT_CHEVRON number_list RIGHT_CHEVRON {}
|
|
||||||
;
|
|
||||||
|
|
||||||
/* Nested arrays must be translated inside-out. */
|
|
||||||
array_indices:
|
|
||||||
| array_index { [$1] }
|
|
||||||
| array_index array_indices { $1 :: $2 }
|
|
||||||
|
|
||||||
pointer_clang_type:
|
|
||||||
| pointer_clang_type array_indices { List.fold_left (fun t x -> Sil.Tarray (t, x)) $1 (List.rev $2) }
|
|
||||||
| pointer_clang_type LEFT_SQBRACKET RIGHT_SQBRACKET { Sil.Tptr($1, Sil.Pk_pointer) }
|
|
||||||
| pointer_clang_type STAR { Sil.Tptr($1, Sil.Pk_pointer) }
|
|
||||||
| pointer_clang_type AMPERSAND { Sil.Tptr($1, Sil.Pk_reference) }
|
|
||||||
| pointer_clang_type STARCONST arc_qualifier { Sil.Tptr($1, $3) }
|
|
||||||
| arc_qualifier pointer_clang_type { Sil.Tptr($2,$1) }
|
|
||||||
| pointer_clang_type STARCONST { Sil.Tptr($1, Sil.Pk_pointer) }
|
|
||||||
| pointer_clang_type STARVOLATILE { Sil.Tptr($1, Sil.Pk_pointer) }
|
|
||||||
| pointer_clang_type STAR RESTRICT { Sil.Tptr($1, Sil.Pk_pointer) }
|
|
||||||
| pointer_clang_type star_arc_qualifier { Sil.Tptr($1, $2) }
|
|
||||||
| clang_type { $1 }
|
|
||||||
| clang_type array_qualifier array_indices { List.fold_left (fun t x -> Sil.Tarray (t, x)) $1 (List.rev $3) }
|
|
||||||
| clang_type template { $1 }
|
|
||||||
| pointer_clang_type LEFT_PARENTHESIS STAR RIGHT_PARENTHESIS
|
|
||||||
LEFT_PARENTHESIS pointer_clang_type_list RIGHT_PARENTHESIS
|
|
||||||
{ Sil.Tptr(Sil.Tfun false, Sil.Pk_pointer) }
|
|
||||||
| pointer_clang_type LEFT_PARENTHESIS STAR RIGHT_PARENTHESIS
|
|
||||||
LEFT_PARENTHESIS pointer_clang_type_list RIGHT_PARENTHESIS NOEXCEPT
|
|
||||||
{ Sil.Tptr(Sil.Tfun false, Sil.Pk_pointer) }
|
|
||||||
| block_type { Sil.Tptr($1, Sil.Pk_pointer) }
|
|
||||||
| pointer_clang_type LEFT_PARENTHESIS pointer_clang_type_list RIGHT_PARENTHESIS
|
|
||||||
{ CFrontend_utils.Printing.log_err "WARNING: PARSING with TFun!\n";
|
|
||||||
Sil.Tfun false }
|
|
||||||
;
|
|
||||||
|
|
||||||
clang_type:
|
|
||||||
| UND_UND_UINT16_ { Sil.Tint Sil.IUInt }
|
|
||||||
| UND_UND_UINT16_T { Sil.Tint Sil.IUInt }
|
|
||||||
| UND_UND_UINT32_ { Sil.Tint Sil.IUInt }
|
|
||||||
| UND_UND_UINT32_T { Sil.Tint Sil.IUInt }
|
|
||||||
| UND_UND_UINT64_T { Sil.Tint Sil.IUInt }
|
|
||||||
| UND_UND_INT64_T { Sil.Tint Sil.IInt }
|
|
||||||
| UND_UND_INT32_T { Sil.Tint Sil.IInt }
|
|
||||||
| UINT8 { Sil.Tint Sil.IUInt }
|
|
||||||
| UINT16 { Sil.Tint Sil.IUInt }
|
|
||||||
| UINT32 { Sil.Tint Sil.IUInt }
|
|
||||||
| UINT64 { Sil.Tint Sil.IUInt }
|
|
||||||
| UNSIGNED INT { Sil.Tint Sil.IUInt }
|
|
||||||
| UNSIGNED LONG LONG { Sil.Tint Sil.IULongLong }
|
|
||||||
| UNSIGNED LONG { Sil.Tint Sil.IULong }
|
|
||||||
| UNSIGNED SHORT { Sil.Tint Sil.IUShort }
|
|
||||||
| FLOAT { Sil.Tfloat Sil.FFloat }
|
|
||||||
| DOUBLE { Sil.Tfloat Sil.FDouble }
|
|
||||||
| VOID { Sil.Tvoid }
|
|
||||||
| CHAR { Sil.Tint Sil.IChar }
|
|
||||||
| SIGNED CHAR { Sil.Tint Sil.ISChar }
|
|
||||||
| UNSIGNED CHAR { Sil.Tint Sil.IUChar }
|
|
||||||
| INT { Sil.Tint Sil.IInt }
|
|
||||||
| UND_BOOL { Sil.Tint Sil.IBool }
|
|
||||||
| SHORT { Sil.Tint Sil.IShort }
|
|
||||||
| LONG { Sil.Tint Sil.ILong }
|
|
||||||
| LONG LONG { Sil.Tint Sil.ILongLong }
|
|
||||||
| LONG DOUBLE { Sil.Tfloat Sil.FLongDouble }
|
|
||||||
| ENUM ident {Sil.Tvar (Sil.TN_enum (Mangled.from_string ("enum "^$2))) }
|
|
||||||
| BUILTIN_FN_TYPE { CFrontend_utils.Printing.log_err "WARNING: Parsing this with Tfun!\n";
|
|
||||||
Sil.Tfun false }
|
|
||||||
| CONST pointer_clang_type { $2 }
|
|
||||||
| CONST TYPENAME pointer_clang_type { $3 }
|
|
||||||
| VOLATILE pointer_clang_type { $2 }
|
|
||||||
| ident ANONYM_IDENT { CFrontend_utils.Printing.log_out " ...Found just an identifier modified with a protocol. Ignoring protocol!. Parsing as Named Type!\n";
|
|
||||||
Sil.Tvar (Sil.TN_typedef(Mangled.from_string $1))}
|
|
||||||
| ident { Sil.Tvar (Sil.TN_typedef(Mangled.from_string $1))}
|
|
||||||
| csu_sil ident_csu { let typename=Sil.TN_csu($1, Mangled.from_string $2) in
|
|
||||||
Sil.Tvar typename }
|
|
||||||
;
|
|
||||||
|
|
||||||
clang_type_list:
|
|
||||||
| clang_type COMMA clang_type_list {$1 :: $3}
|
|
||||||
| clang_type {[$1]}
|
|
||||||
|
|
||||||
clang_func_type:
|
|
||||||
| clang_type LEFT_PARENTHESIS clang_type_list RIGHT_PARENTHESIS
|
|
||||||
{($1, $3)}
|
|
||||||
|
|
||||||
|
|
||||||
parse:
|
|
||||||
| pointer_clang_type { $1 }
|
|
Loading…
Reference in new issue