aboutsummaryrefslogtreecommitdiffstats
path: root/cparser
diff options
context:
space:
mode:
Diffstat (limited to 'cparser')
-rw-r--r--cparser/C.mli3
-rw-r--r--cparser/Cabs.v2
-rw-r--r--cparser/Ceval.ml4
-rw-r--r--cparser/Cleanup.ml8
-rw-r--r--cparser/Cprint.ml3
-rw-r--r--cparser/Elab.ml36
-rw-r--r--cparser/Lexer.mll2
-rw-r--r--cparser/Machine.ml52
-rw-r--r--cparser/Machine.mli5
-rw-r--r--cparser/Parser.vy4
-rw-r--r--cparser/Rename.ml7
-rw-r--r--cparser/StructPassing.ml11
-rw-r--r--cparser/deLexer.ml1
-rw-r--r--cparser/pre_parser.mly3
14 files changed, 127 insertions, 14 deletions
diff --git a/cparser/C.mli b/cparser/C.mli
index 763a9277..cccf744b 100644
--- a/cparser/C.mli
+++ b/cparser/C.mli
@@ -87,8 +87,11 @@ type attributes = attribute list
type storage =
| Storage_default (* used for toplevel names without explicit storage *)
+ | Storage_thread_local
| Storage_extern
| Storage_static
+ | Storage_thread_local_extern
+ | Storage_thread_local_static
| Storage_auto (* used for block-scoped names without explicit storage *)
| Storage_register
diff --git a/cparser/Cabs.v b/cparser/Cabs.v
index accb95a0..ab908be3 100644
--- a/cparser/Cabs.v
+++ b/cparser/Cabs.v
@@ -55,7 +55,7 @@ Inductive typeSpecifier := (* Merge all specifiers into one type *)
| Tenum : option string -> option (list (string * option expression * loc)) -> list attribute -> typeSpecifier
with storage :=
- AUTO | STATIC | EXTERN | REGISTER | TYPEDEF
+ AUTO | STATIC | EXTERN | REGISTER | TYPEDEF | THREAD_LOCAL
with cvspec :=
| CV_CONST | CV_VOLATILE | CV_RESTRICT
diff --git a/cparser/Ceval.ml b/cparser/Ceval.ml
index 14f61e06..b216ebc8 100644
--- a/cparser/Ceval.ml
+++ b/cparser/Ceval.ml
@@ -355,7 +355,9 @@ and is_constant_lval env e =
begin match Env.find_ident env id with
| Env.II_ident(sto, _) ->
begin match sto with
- | Storage_default | Storage_extern | Storage_static -> true
+ | Storage_default | Storage_extern | Storage_static
+ | Storage_thread_local | Storage_thread_local_extern | Storage_thread_local_static
+ -> true
| Storage_auto | Storage_register -> false
end
| Env.II_enum _ -> false (* should not happen *)
diff --git a/cparser/Cleanup.ml b/cparser/Cleanup.ml
index 62b00e04..74959cbb 100644
--- a/cparser/Cleanup.ml
+++ b/cparser/Cleanup.ml
@@ -127,14 +127,14 @@ let add_enum e =
*)
let visible_decl (sto, id, ty, init) =
- sto = Storage_default &&
+ (sto = Storage_default || sto = Storage_thread_local) &&
match ty with TFun _ -> false | _ -> true
let visible_fundef f =
match f.fd_storage with
- | Storage_default -> not f.fd_inline
- | Storage_extern -> true
- | Storage_static -> false
+ | Storage_default | Storage_thread_local -> not f.fd_inline
+ | Storage_extern | Storage_thread_local_extern -> true
+ | Storage_static | Storage_thread_local_static -> false
| Storage_auto | Storage_register -> assert false
let rec add_init_globdecls accu = function
diff --git a/cparser/Cprint.ml b/cparser/Cprint.ml
index 93377989..dddc8f73 100644
--- a/cparser/Cprint.ml
+++ b/cparser/Cprint.ml
@@ -362,6 +362,9 @@ let storage pp = function
| Storage_default -> ()
| Storage_extern -> fprintf pp "extern "
| Storage_static -> fprintf pp "static "
+ | Storage_thread_local -> fprintf pp "_Thread_local"
+ | Storage_thread_local_extern -> fprintf pp "extern _Thread_local"
+ | Storage_thread_local_static -> fprintf pp "static _Thread_local"
| Storage_auto -> () (* used only in blocks, where it can be omitted *)
| Storage_register -> fprintf pp "register "
diff --git a/cparser/Elab.ml b/cparser/Elab.ml
index a5b87e2e..594453b8 100644
--- a/cparser/Elab.ml
+++ b/cparser/Elab.ml
@@ -153,6 +153,9 @@ let name_of_storage_class = function
| Storage_default -> "<default>"
| Storage_extern -> "'extern'"
| Storage_static -> "'static'"
+ | Storage_thread_local -> "'_Thread_local'"
+ | Storage_thread_local_extern -> "'_Thread_local extern'"
+ | Storage_thread_local_static -> "'_Thread_local static'"
| Storage_auto -> "'auto'"
| Storage_register -> "'register'"
@@ -178,15 +181,29 @@ let combine_toplevel_definitions loc env s old_sto old_ty sto ty =
| Storage_static,Storage_static
| Storage_extern,Storage_extern
| Storage_default,Storage_default -> sto
- | _,Storage_static ->
+ | Storage_thread_local_static,Storage_thread_local_static
+ | Storage_thread_local_extern,Storage_thread_local_extern
+ | Storage_thread_local,Storage_thread_local -> sto
+ | _,Storage_static | _,Storage_thread_local_static ->
error loc "static declaration of '%s' follows non-static declaration" s;
sto
| Storage_static,_ -> Storage_static (* Static stays static *)
- | Storage_extern,_ -> if is_function_type env new_ty then Storage_extern else sto
+ | Storage_thread_local_static,_ -> Storage_thread_local_static (* Thread-local static stays static *)
+ | (Storage_extern|Storage_thread_local_extern),_ -> if is_function_type env new_ty then Storage_extern else sto
| Storage_default,Storage_extern ->
if is_global_defined s && is_function_type env ty then
warning loc Extern_after_definition "this extern declaration follows a non-extern definition and is ignored";
Storage_extern
+ | Storage_thread_local,Storage_thread_local_extern ->
+ if is_global_defined s && is_function_type env ty then
+ warning loc Extern_after_definition "this extern declaration follows a non-extern definition and is ignored";
+ Storage_extern
+ | Storage_thread_local, Storage_default ->
+ error loc "Non thread-local declaration follows thread-local";
+ sto
+ | Storage_default, (Storage_thread_local|Storage_thread_local_extern) ->
+ error loc "Thread-local declaration follows non thread-local";
+ sto
| _,Storage_extern -> old_sto
(* "auto" and "register" don't appear in toplevel definitions.
Normally this was checked earlier. Generate error message
@@ -654,13 +671,26 @@ let rec elab_specifier ?(only = false) loc env specifier =
restrict := cv = CV_RESTRICT;
attr := add_attributes (elab_cvspec env cv) !attr
| SpecStorage st ->
- if !sto <> Storage_default && st <> TYPEDEF then
+ if !sto <> Storage_default && st <> TYPEDEF && st <> THREAD_LOCAL then
error loc "multiple storage classes in declaration specifier";
begin match st with
| AUTO -> sto := Storage_auto
| STATIC -> sto := Storage_static
| EXTERN -> sto := Storage_extern
| REGISTER -> sto := Storage_register
+ | THREAD_LOCAL ->
+ sto := (match !sto with
+ | Storage_static | Storage_thread_local_static ->
+ Storage_thread_local_static
+ | Storage_extern | Storage_thread_local_extern ->
+ Storage_thread_local_extern
+ | Storage_default | Storage_thread_local ->
+ Storage_thread_local
+ | Storage_auto|Storage_register ->
+ error loc "_Thread_local on auto or register variable";
+ !sto
+ )
+
| TYPEDEF ->
if !typedef then
error loc "multiple uses of 'typedef'";
diff --git a/cparser/Lexer.mll b/cparser/Lexer.mll
index 42980d30..7a2974eb 100644
--- a/cparser/Lexer.mll
+++ b/cparser/Lexer.mll
@@ -74,6 +74,7 @@ let () =
("goto", fun loc -> GOTO loc);
("if", fun loc -> IF loc);
("inline", fun loc -> INLINE loc);
+ ("_Thread_local", fun loc -> THREAD_LOCAL loc);
("_Noreturn", fun loc -> NORETURN loc);
("int", fun loc -> INT loc);
("long", fun loc -> LONG loc);
@@ -545,6 +546,7 @@ and singleline_comment = parse
| Pre_parser.IF loc -> loop (Parser.IF_ loc)
| Pre_parser.INC loc -> loop (Parser.INC loc)
| Pre_parser.INLINE loc -> loop (Parser.INLINE loc)
+ | Pre_parser.THREAD_LOCAL loc -> loop (Parser.THREAD_LOCAL loc)
| Pre_parser.INT loc -> loop (Parser.INT loc)
| Pre_parser.LBRACE loc -> loop (Parser.LBRACE loc)
| Pre_parser.LBRACK loc -> loop (Parser.LBRACK loc)
diff --git a/cparser/Machine.ml b/cparser/Machine.ml
index c47ec594..4ce63970 100644
--- a/cparser/Machine.ml
+++ b/cparser/Machine.ml
@@ -19,6 +19,7 @@
type struct_passing_style =
| SP_ref_callee (* by reference, callee takes copy *)
| SP_ref_caller (* by reference, caller takes copy *)
+ | SP_value32_ref_callee (* by value if <= 32 bits, by ref_callee otherwise *)
| SP_split_args (* by value, as a sequence of ints *)
type struct_return_style =
@@ -61,6 +62,7 @@ type t = {
supports_unaligned_accesses: bool;
struct_passing_style: struct_passing_style;
struct_return_style : struct_return_style;
+ has_non_trapping_loads : bool;
}
let ilp32ll64 = {
@@ -96,6 +98,7 @@ let ilp32ll64 = {
supports_unaligned_accesses = false;
struct_passing_style = SP_ref_callee;
struct_return_style = SR_ref;
+ has_non_trapping_loads = false;
}
let i32lpll64 = {
@@ -131,6 +134,7 @@ let i32lpll64 = {
supports_unaligned_accesses = false;
struct_passing_style = SP_ref_callee;
struct_return_style = SR_ref;
+ has_non_trapping_loads = false;
}
let il32pll64 = {
@@ -166,6 +170,7 @@ let il32pll64 = {
supports_unaligned_accesses = false;
struct_passing_style = SP_ref_callee;
struct_return_style = SR_ref;
+ has_non_trapping_loads = false;
}
(* Canned configurations for some ABIs *)
@@ -238,6 +243,52 @@ let rv64 =
struct_passing_style = SP_ref_callee; (* Wrong *)
struct_return_style = SR_ref } (* to check *)
+let kvxbase =
+ { name = "kvx";
+ char_signed = true;
+ wchar_signed = true;
+ sizeof_ptr = 8;
+ sizeof_short = 2;
+ sizeof_int = 4;
+ sizeof_long = 8;
+ sizeof_longlong = 8;
+ sizeof_float = 4;
+ sizeof_double = 8;
+ sizeof_longdouble = 8;
+ sizeof_void = None; (* What is this for ? *)
+ sizeof_fun = None; (* What is this for ? *)
+ sizeof_wchar = 4;
+ sizeof_size_t = 8;
+ sizeof_ptrdiff_t = 8;
+ sizeof_intreg = 8; (* What is this for ? *)
+ alignof_ptr = 8;
+ alignof_short = 2;
+ alignof_int = 4;
+ alignof_long = 8;
+ alignof_longlong = 8;
+ alignof_float = 4;
+ alignof_double = 8;
+ alignof_longdouble = 8;
+ alignof_void = None; (* what is this for ? *)
+ alignof_fun = None; (* what is this for ? *)
+ bigendian = false;
+ bitfields_msb_first = false; (* TO CHECK *)
+ supports_unaligned_accesses = true;
+ struct_passing_style = SP_value32_ref_callee;
+ struct_return_style = SR_int1to4;
+ has_non_trapping_loads = false;
+}
+
+let kvxcos =
+ { kvxbase with has_non_trapping_loads = true;
+}
+
+let kvxmbr =
+ { kvxbase with has_non_trapping_loads = true;
+}
+
+let kvxelf = kvxmbr
+
let aarch64 =
{ i32lpll64 with name = "aarch64";
struct_passing_style = SP_ref_callee; (* Wrong *)
@@ -292,6 +343,7 @@ let undef = {
supports_unaligned_accesses = false;
struct_passing_style = SP_ref_callee;
struct_return_style = SR_ref;
+ has_non_trapping_loads = false;
}
(* The current configuration. Must be initialized before use. *)
diff --git a/cparser/Machine.mli b/cparser/Machine.mli
index f9d347b9..9e6063ba 100644
--- a/cparser/Machine.mli
+++ b/cparser/Machine.mli
@@ -18,6 +18,7 @@
type struct_passing_style =
| SP_ref_callee (* by reference, callee takes copy *)
| SP_ref_caller (* by reference, caller takes copy *)
+ | SP_value32_ref_callee (* by value if <= 32 bits, by ref_callee otherwise *)
| SP_split_args (* by value, as a sequence of ints *)
type struct_return_style =
@@ -60,6 +61,7 @@ type t = {
supports_unaligned_accesses: bool;
struct_passing_style: struct_passing_style;
struct_return_style: struct_return_style;
+ has_non_trapping_loads: bool;
}
(* The current configuration *)
@@ -87,6 +89,9 @@ val arm_littleendian : t
val arm_bigendian : t
val rv32 : t
val rv64 : t
+val kvxmbr : t
+val kvxcos : t
+val kvxelf : t
val aarch64 : t
val aarch64_apple : t
diff --git a/cparser/Parser.vy b/cparser/Parser.vy
index f1abe3d9..6c39719c 100644
--- a/cparser/Parser.vy
+++ b/cparser/Parser.vy
@@ -33,7 +33,7 @@ Require Cabs.
LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN
%token<Cabs.loc> LPAREN RPAREN LBRACK RBRACK LBRACE RBRACE DOT COMMA
- SEMICOLON ELLIPSIS TYPEDEF EXTERN STATIC RESTRICT AUTO REGISTER INLINE
+ SEMICOLON ELLIPSIS TYPEDEF EXTERN STATIC RESTRICT AUTO REGISTER INLINE THREAD_LOCAL
NORETURN CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID
STRUCT UNION ENUM UNDERSCORE_BOOL PACKED ALIGNAS ATTRIBUTE ASM
@@ -403,6 +403,8 @@ storage_class_specifier:
{ (Cabs.AUTO, loc) }
| loc = REGISTER
{ (Cabs.REGISTER, loc) }
+| loc = THREAD_LOCAL
+ { (Cabs.THREAD_LOCAL, loc) }
(* 6.7.2 *)
type_specifier:
diff --git a/cparser/Rename.ml b/cparser/Rename.ml
index 96424bf8..e1b3537e 100644
--- a/cparser/Rename.ml
+++ b/cparser/Rename.ml
@@ -258,13 +258,16 @@ let rec reserve_public env = function
match dcl.gdesc with
| Gdecl(sto, id, _, _) ->
begin match sto with
- | Storage_default | Storage_extern -> enter_public env id
+ | Storage_default | Storage_thread_local
+ | Storage_extern | Storage_thread_local_extern ->
+ enter_public env id
| Storage_static -> env
| _ -> assert false
end
| Gfundef f ->
begin match f.fd_storage with
- | Storage_default | Storage_extern -> enter_public env f.fd_name
+ | Storage_default | Storage_extern
+ -> enter_public env f.fd_name
| Storage_static -> env
| _ -> assert false
end
diff --git a/cparser/StructPassing.ml b/cparser/StructPassing.ml
index f1f481d0..629d7bc3 100644
--- a/cparser/StructPassing.ml
+++ b/cparser/StructPassing.ml
@@ -69,7 +69,16 @@ let classify_param env ty =
match !struct_passing_style with
| SP_ref_callee -> Param_unchanged
| SP_ref_caller -> Param_ref_caller
- | _ ->
+ | SP_value32_ref_callee ->
+ (match sizeof env ty, alignof env ty with
+ | Some sz, Some al ->
+ if (sz <= 4) then
+ Param_flattened ((sz+3)/4, sz, al) (* FIXME - why (sz+3)/4 ? *)
+ else
+ Param_unchanged
+ | _, _ -> Param_unchanged (* when parsing prototype with incomplete structure definition *)
+ )
+ | SP_split_args ->
match sizeof env ty, alignof env ty with
| Some sz, Some al ->
Param_flattened ((sz + 3) / 4, sz, al)
diff --git a/cparser/deLexer.ml b/cparser/deLexer.ml
index e3ab3291..3f84d847 100644
--- a/cparser/deLexer.ml
+++ b/cparser/deLexer.ml
@@ -31,6 +31,7 @@ let delex (symbol : string) : string =
| "BUILTIN_VA_ARG" -> "__builtin_va_arg"
| "CONST" -> "const"
| "INLINE" -> "inline"
+ | "THREAD_LOCAL" -> "_Thread_local"
| "PACKED" -> "__packed__"
| "RESTRICT" -> "restrict"
| "SIGNED" -> "signed"
diff --git a/cparser/pre_parser.mly b/cparser/pre_parser.mly
index cffbd192..f99fef62 100644
--- a/cparser/pre_parser.mly
+++ b/cparser/pre_parser.mly
@@ -55,7 +55,7 @@
COLON AND MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN SUB_ASSIGN LEFT_ASSIGN
RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN LPAREN RPAREN LBRACK RBRACK
LBRACE RBRACE DOT COMMA SEMICOLON ELLIPSIS TYPEDEF EXTERN STATIC RESTRICT
- AUTO REGISTER INLINE NORETURN CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE
+ AUTO REGISTER INLINE THREAD_LOCAL NORETURN CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE
UNDERSCORE_BOOL CONST VOLATILE VOID STRUCT UNION ENUM CASE DEFAULT IF ELSE
SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN BUILTIN_VA_ARG ALIGNOF
ATTRIBUTE ALIGNAS PACKED ASM BUILTIN_OFFSETOF STATIC_ASSERT
@@ -432,6 +432,7 @@ storage_class_specifier_no_typedef:
| STATIC
| AUTO
| REGISTER
+| THREAD_LOCAL
{}
(* [declaration_specifier_no_type] matches declaration specifiers