diff options
author | Xavier Leroy <xavier.leroy@college-de-france.fr> | 2019-02-12 11:49:23 +0100 |
---|---|---|
committer | Xavier Leroy <xavierleroy@users.noreply.github.com> | 2019-02-25 17:15:36 +0100 |
commit | d7dfc21c20f55b705e3e749c2c7b31f9a4611c39 (patch) | |
tree | ee0b6e0ad06941260244deba916e553d68f882e5 | |
parent | 0616171c89d3db651b6842338fdf2da9da885aa1 (diff) | |
download | compcert-d7dfc21c20f55b705e3e749c2c7b31f9a4611c39.tar.gz compcert-d7dfc21c20f55b705e3e749c2c7b31f9a4611c39.zip |
Distinguish object-related and name-related attributes
This is a second step towards mimicking GCC/Clang's handling of attributes.
This commit introduces a distinction between
- Object-related attributes, such as "section", which apply to the object (function, variable) being defined;
- Name-related attributes, such as "aligned", which apply to the name (object, struct/union member, struct/union/enum tag) being defined.
In particular, "aligned" is now attached to "struct" and "union" definitions, while it used to be "floated up" before.
The C11 _Alignas modifier is treated like an object-related attribute, so that
```
struct s { ... };
_Alignas(64) struct s x;
```
correctly associates the alignment with "x" and not with "struct s", where it would be ignored because it was not part of the original definition of s.
-rw-r--r-- | cfrontend/C2C.ml | 5 | ||||
-rw-r--r-- | cparser/Cutil.ml | 7 | ||||
-rw-r--r-- | cparser/Cutil.mli | 5 | ||||
-rw-r--r-- | cparser/Elab.ml | 20 |
4 files changed, 24 insertions, 13 deletions
diff --git a/cfrontend/C2C.ml b/cfrontend/C2C.ml index d6bf76f3..d70c4dad 100644 --- a/cfrontend/C2C.ml +++ b/cfrontend/C2C.ml @@ -315,8 +315,9 @@ let attributes = [ ("noinline",Cutil.Attr_function); (* name-related *) ("aligned", Cutil.Attr_name); - ("section", Cutil.Attr_name); - ("unused", Cutil.Attr_name) + (* object-related *) + ("section", Cutil.Attr_object); + ("unused", Cutil.Attr_object) ] diff --git a/cparser/Cutil.ml b/cparser/Cutil.ml index b926e84a..25329694 100644 --- a/cparser/Cutil.ml +++ b/cparser/Cutil.ml @@ -95,7 +95,10 @@ let rec remove_custom_attributes (names: string list) (al: attributes) = (* Classification of attributes *) type attribute_class = - | Attr_name (* Attribute applies to the names being declared *) + | Attr_object (* Attribute applies to the object being declared + (function, global variable, local variable) *) + | Attr_name (* Attribute applies to the name being declared + (object, struct/union member, struct/union/enum tag *) | Attr_type (* Attribute applies to types *) | Attr_struct (* Attribute applies to struct, union and enum *) | Attr_function (* Attribute applies to function types and decls *) @@ -111,7 +114,7 @@ let declare_attributes l = let class_of_attribute = function | AConst | AVolatile | ARestrict -> Attr_type - | AAlignas _ -> Attr_name + | AAlignas _ -> Attr_object | Attr(name, args) -> try Hashtbl.find attr_class (normalize_attrname name) with Not_found -> Attr_unknown diff --git a/cparser/Cutil.mli b/cparser/Cutil.mli index a99bf3af..400a6319 100644 --- a/cparser/Cutil.mli +++ b/cparser/Cutil.mli @@ -64,7 +64,10 @@ val has_std_alignas : Env.t -> typ -> bool (* Do the attributes of the type contain the C11 _Alignas attribute *) type attribute_class = - | Attr_name (* Attribute applies to the names being declared *) + | Attr_object (* Attribute applies to the object being declared + (function, global variable, local variable) *) + | Attr_name (* Attribute applies to the name being declared + (object, struct/union member, struct/union/enum tag *) | Attr_type (* Attribute applies to types *) | Attr_struct (* Attribute applies to struct, union and enum *) | Attr_function (* Attribute applies to function types and decls *) diff --git a/cparser/Elab.ml b/cparser/Elab.ml index 8f42fe0a..46bc63a9 100644 --- a/cparser/Elab.ml +++ b/cparser/Elab.ml @@ -656,15 +656,19 @@ let rec elab_specifier ?(only = false) loc env specifier = restrict_check ty; (!sto, !inline, !noreturn ,!typedef, add_attributes_type !attr ty, env) in - (* As done in CIL, partition !attr into struct-related attributes, + (* Partition !attr into name- and struct-related attributes, which are returned, and other attributes, which are left in !attr. - The returned struct-related attributes are applied to the + The returned name-or-struct-related attributes are applied to the struct/union/enum being defined. - The leftover non-struct-related attributes will be applied + The leftover attributes (e.g. object attributes) will be applied to the variable being defined. *) - let get_struct_attrs () = + let get_definition_attrs () = let (ta, nta) = - List.partition (fun a -> class_of_attribute a = Attr_struct) !attr in + List.partition + (fun a -> match class_of_attribute a with + | Attr_struct | Attr_name -> true + | _ -> false) + !attr in attr := nta; ta in @@ -723,7 +727,7 @@ let rec elab_specifier ?(only = false) loc env specifier = | [Cabs.Tstruct_union(STRUCT, id, optmembers, a)] -> let a' = - add_attributes (get_struct_attrs()) (elab_attributes env a) in + add_attributes (get_definition_attrs()) (elab_attributes env a) in let (id', env') = elab_struct_or_union only Struct loc id optmembers a' env in let ty = TStruct(id', !attr) in @@ -732,7 +736,7 @@ let rec elab_specifier ?(only = false) loc env specifier = | [Cabs.Tstruct_union(UNION, id, optmembers, a)] -> let a' = - add_attributes (get_struct_attrs()) (elab_attributes env a) in + add_attributes (get_definition_attrs()) (elab_attributes env a) in let (id', env') = elab_struct_or_union only Union loc id optmembers a' env in let ty = TUnion(id', !attr) in @@ -741,7 +745,7 @@ let rec elab_specifier ?(only = false) loc env specifier = | [Cabs.Tenum(id, optmembers, a)] -> let a' = - add_attributes (get_struct_attrs()) (elab_attributes env a) in + add_attributes (get_definition_attrs()) (elab_attributes env a) in let (id', env') = elab_enum only loc id optmembers a' env in let ty = TEnum (id', !attr) in |