aboutsummaryrefslogtreecommitdiffstats
path: root/cparser/Cutil.ml
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@inria.fr>2017-02-03 14:12:32 +0100
committerXavier Leroy <xavier.leroy@inria.fr>2017-02-03 14:12:32 +0100
commit3babd253e1d194549294c282e1b0c60097b26b07 (patch)
treef6a4ed3152aafdac8474350c31a9e7a5fcdb20c6 /cparser/Cutil.ml
parent47c82de6010935d11c3d64f6d06c2061c34dc091 (diff)
downloadcompcert-kvx-3babd253e1d194549294c282e1b0c60097b26b07.tar.gz
compcert-kvx-3babd253e1d194549294c282e1b0c60097b26b07.zip
Refactor the classification of attributes
Introduce Cutil.class_of_attribute to return the class of the given attribute: one among Attr_type attribute related to types (e.g. "aligned") Attr_struct attribute related to struct/union/enum types (e.g. "packed") Attr_function attribute related to function types (e.g. "noreturn") Attr_name attribute related to variable and function declarations (e.g. "section") Attr_unknown attribute was not declared Cutil.declare_attribute is used to associate a class to a custom attribute. Standard attributes (const, volatile, _Alignas, etc) are Attr_type. cfronted/C2C.ml: declare the few attributes that CompCert honors currently. cparser/GCC.ml: a bigger list of attributes taken from GCC, for reference only.
Diffstat (limited to 'cparser/Cutil.ml')
-rw-r--r--cparser/Cutil.ml44
1 files changed, 32 insertions, 12 deletions
diff --git a/cparser/Cutil.ml b/cparser/Cutil.ml
index 21e6f71e..44d16ea1 100644
--- a/cparser/Cutil.ml
+++ b/cparser/Cutil.ml
@@ -37,6 +37,15 @@ module IdentMap = Map.Make(Ident)
(* Operations on attributes *)
+(* Normalize the name of an attribute, removing starting and trailing '__' *)
+
+let re_normalize_attrname = Str.regexp "^__\\(.*\\)__$"
+
+let normalize_attrname a =
+ if Str.string_match re_normalize_attrname a 0
+ then Str.matched_group 1 a
+ else a
+
(* Lists of attributes are kept sorted in increasing order *)
let rec add_attributes (al1: attributes) (al2: attributes) =
@@ -83,23 +92,34 @@ let rec remove_custom_attributes (names: string list) (al: attributes) =
| a :: tl ->
a :: remove_custom_attributes names tl
-(* Is an attribute a ISO C standard attribute? *)
+(* Classification of attributes *)
-let attr_is_standard = function
- | AConst | AVolatile | ARestrict -> true
- | AAlignas _ | Attr _ -> false
+type attribute_class =
+ | Attr_name (* Attribute applies to the names being declared *)
+ | Attr_type (* Attribute applies to types *)
+ | Attr_struct (* Attribute applies to struct, union and enum *)
+ | Attr_function (* Attribute applies to function types and decls *)
+ | Attr_unknown (* Unknown attribute *)
+
+let attr_class : (string, attribute_class) Hashtbl.t = Hashtbl.create 32
-(* Is an attribute type-related (true) or variable-related (false)? *)
+let declare_attribute name cls =
+ Hashtbl.replace attr_class (normalize_attrname name) cls
-let attr_is_type_related = function
- | AConst | AVolatile | ARestrict | AAlignas _ -> true
- | Attr(_, _) -> false
+let declare_attributes l =
+ List.iter (fun (n,c) -> declare_attribute n c) l
-(* Is an attribute related to structs, unions and enum (true) or not (false)? *)
+let class_of_attribute = function
+ | AConst | AVolatile | ARestrict | AAlignas _ -> Attr_type
+ | Attr(name, args) ->
+ try Hashtbl.find attr_class (normalize_attrname name)
+ with Not_found -> Attr_unknown
-let attr_is_struct_related = function
- | Attr(("packed" | "__packed__"), _) -> true
- | _ -> false
+(* Is an attribute a ISO C standard attribute? *)
+
+let attr_is_standard = function
+ | AConst | AVolatile | ARestrict -> true
+ | AAlignas _ | Attr _ -> false
(* Is an attribute applicable to a whole array (true) or only to
array elements (false)? *)