LCOV - code coverage report
Current view: top level - gcc - attribs.h (source / functions) Hit Total Coverage
Test: gcc.info Lines: 39 41 95.1 %
Date: 2023-07-19 08:18:47 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /* Declarations and definitions dealing with attribute handling.
       2             :    Copyright (C) 2013-2023 Free Software Foundation, Inc.
       3             : 
       4             : This file is part of GCC.
       5             : 
       6             : GCC is free software; you can redistribute it and/or modify it under
       7             : the terms of the GNU General Public License as published by the Free
       8             : Software Foundation; either version 3, or (at your option) any later
       9             : version.
      10             : 
      11             : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14             : for more details.
      15             : 
      16             : You should have received a copy of the GNU General Public License
      17             : along with GCC; see the file COPYING3.  If not see
      18             : <http://www.gnu.org/licenses/>.  */
      19             : 
      20             : #ifndef GCC_ATTRIBS_H
      21             : #define GCC_ATTRIBS_H
      22             : 
      23             : extern const struct attribute_spec *lookup_attribute_spec (const_tree);
      24             : extern void free_attr_data ();
      25             : extern void init_attributes (void);
      26             : 
      27             : /* Process the attributes listed in ATTRIBUTES and install them in *NODE,
      28             :    which is either a DECL (including a TYPE_DECL) or a TYPE.  If a DECL,
      29             :    it should be modified in place; if a TYPE, a copy should be created
      30             :    unless ATTR_FLAG_TYPE_IN_PLACE is set in FLAGS.  FLAGS gives further
      31             :    information, in the form of a bitwise OR of flags in enum attribute_flags
      32             :    from tree.h.  Depending on these flags, some attributes may be
      33             :    returned to be applied at a later stage (for example, to apply
      34             :    a decl attribute to the declaration rather than to its type).  */
      35             : extern tree decl_attributes (tree *, tree, int, tree = NULL_TREE);
      36             : 
      37             : extern bool cxx11_attribute_p (const_tree);
      38             : extern tree get_attribute_name (const_tree);
      39             : extern tree get_attribute_namespace (const_tree);
      40             : extern void apply_tm_attr (tree, tree);
      41             : extern tree make_attribute (const char *, const char *, tree);
      42             : extern bool attribute_ignored_p (tree);
      43             : extern bool attribute_ignored_p (const attribute_spec *const);
      44             : 
      45             : extern struct scoped_attributes* register_scoped_attributes (const struct attribute_spec *,
      46             :                                                              const char *,
      47             :                                                              bool = false);
      48             : 
      49             : extern char *sorted_attr_string (tree);
      50             : extern bool common_function_versions (tree, tree);
      51             : extern tree make_dispatcher_decl (const tree);
      52             : extern bool is_function_default_version (const tree);
      53             : extern void handle_ignored_attributes_option (vec<char *> *);
      54             : 
      55             : /* Return a type like TTYPE except that its TYPE_ATTRIBUTES
      56             :    is ATTRIBUTE.
      57             : 
      58             :    Such modified types already made are recorded so that duplicates
      59             :    are not made.  */
      60             : 
      61             : extern tree build_type_attribute_variant (tree, tree);
      62             : extern tree build_decl_attribute_variant (tree, tree);
      63             : extern tree build_type_attribute_qual_variant (tree, tree, int);
      64             : 
      65             : extern bool simple_cst_list_equal (const_tree, const_tree);
      66             : extern bool attribute_value_equal (const_tree, const_tree);
      67             : 
      68             : /* Return 0 if the attributes for two types are incompatible, 1 if they
      69             :    are compatible, and 2 if they are nearly compatible (which causes a
      70             :    warning to be generated).  */
      71             : extern int comp_type_attributes (const_tree, const_tree);
      72             : 
      73             : extern tree affects_type_identity_attributes (tree, bool = true);
      74             : extern tree restrict_type_identity_attributes_to (tree, tree);
      75             : 
      76             : /* Default versions of target-overridable functions.  */
      77             : extern tree merge_decl_attributes (tree, tree);
      78             : extern tree merge_type_attributes (tree, tree);
      79             : 
      80             : /* Remove any instances of attribute ATTR_NAME in LIST and return the
      81             :    modified list.  */
      82             : 
      83             : extern tree remove_attribute (const char *, tree);
      84             : 
      85             : /* Similarly but also with specific attribute namespace.  */
      86             : 
      87             : extern tree remove_attribute (const char *, const char *, tree);
      88             : 
      89             : /* Given two attributes lists, return a list of their union.  */
      90             : 
      91             : extern tree merge_attributes (tree, tree);
      92             : 
      93             : /* Duplicate all attributes with name NAME in ATTR list to *ATTRS if
      94             :    they are missing there.  */
      95             : 
      96             : extern void duplicate_one_attribute (tree *, tree, const char *);
      97             : 
      98             : /* Duplicate all attributes from user DECL to the corresponding
      99             :    builtin that should be propagated.  */
     100             : 
     101             : extern void copy_attributes_to_builtin (tree);
     102             : 
     103             : /* Given two Windows decl attributes lists, possibly including
     104             :    dllimport, return a list of their union .  */
     105             : extern tree merge_dllimport_decl_attributes (tree, tree);
     106             : 
     107             : /* Handle a "dllimport" or "dllexport" attribute.  */
     108             : extern tree handle_dll_attribute (tree *, tree, tree, int, bool *);
     109             : 
     110             : extern int attribute_list_equal (const_tree, const_tree);
     111             : extern int attribute_list_contained (const_tree, const_tree);
     112             : 
     113             : /* The backbone of lookup_attribute().  ATTR_LEN is the string length
     114             :    of ATTR_NAME, and LIST is not NULL_TREE.
     115             : 
     116             :    The function is called from lookup_attribute in order to optimize
     117             :    for size.  */
     118             : extern tree private_lookup_attribute (const char *attr_name, size_t attr_len,
     119             :                                       tree list);
     120             : extern tree private_lookup_attribute (const char *attr_ns,
     121             :                                       const char *attr_name,
     122             :                                       size_t attr_ns_len, size_t attr_len,
     123             :                                       tree list);
     124             : 
     125             : extern unsigned decls_mismatched_attributes (tree, tree, tree,
     126             :                                              const char* const[],
     127             :                                              pretty_printer*);
     128             : 
     129             : extern void maybe_diag_alias_attributes (tree, tree);
     130             : 
     131             : /* For a given string S of length L, strip leading and trailing '_' characters
     132             :    so that we have a canonical form of attribute names.  NB: This function may
     133             :    change S and L.  */
     134             : 
     135             : template <typename T>
     136             : inline bool
     137 10173062870 : canonicalize_attr_name (const char *&s, T &l)
     138             : {
     139 10173062870 :   if (l > 4 && s[0] == '_' && s[1] == '_' && s[l - 1] == '_' && s[l - 2] == '_')
     140             :     {
     141    25570680 :       s += 2;
     142    25570680 :       l -= 4;
     143    25570680 :       return true;
     144             :     }
     145             :   return false;
     146             : }
     147             : 
     148             : /* For a given IDENTIFIER_NODE, strip leading and trailing '_' characters
     149             :    so that we have a canonical form of attribute names.  */
     150             : 
     151             : inline tree
     152    35938517 : canonicalize_attr_name (tree attr_name)
     153             : {
     154    35938517 :   size_t l = IDENTIFIER_LENGTH (attr_name);
     155    35938517 :   const char *s = IDENTIFIER_POINTER (attr_name);
     156             : 
     157    35938517 :   if (canonicalize_attr_name (s, l))
     158    25570680 :     return get_identifier_with_length (s, l);
     159             : 
     160             :   return attr_name;
     161             : }
     162             : 
     163             : /* Compare attribute identifiers ATTR1 and ATTR2 with length ATTR1_LEN and
     164             :    ATTR2_LEN.  */
     165             : 
     166             : inline bool
     167    89035373 : cmp_attribs (const char *attr1, size_t attr1_len,
     168             :              const char *attr2, size_t attr2_len)
     169             : {
     170     8715505 :   return attr1_len == attr2_len && strncmp (attr1, attr2, attr1_len) == 0;
     171             : }
     172             : 
     173             : /* Compare attribute identifiers ATTR1 and ATTR2.  */
     174             : 
     175             : inline bool
     176             : cmp_attribs (const char *attr1, const char *attr2)
     177             : {
     178             :   return cmp_attribs (attr1, strlen (attr1), attr2, strlen (attr2));
     179             : }
     180             : 
     181             : /* Given an identifier node IDENT and a string ATTR_NAME, return true
     182             :    if the identifier node is a valid attribute name for the string.  */
     183             : 
     184             : inline bool
     185    89034172 : is_attribute_p (const char *attr_name, const_tree ident)
     186             : {
     187    89034172 :   return cmp_attribs (attr_name, strlen (attr_name),
     188    89034172 :                       IDENTIFIER_POINTER (ident), IDENTIFIER_LENGTH (ident));
     189             : }
     190             : 
     191             : /* Given an attribute ATTR and a string ATTR_NS, return true
     192             :    if the attribute namespace is valid for the string.  ATTR_NS "" stands
     193             :    for standard attribute (NULL get_attribute_namespace) or "gnu"
     194             :    namespace.  */
     195             : 
     196             : inline bool
     197      860600 : is_attribute_namespace_p (const char *attr_ns, const_tree attr)
     198             : {
     199      860600 :   tree ident = get_attribute_namespace (attr);
     200      860600 :   if (attr_ns == NULL)
     201           0 :     return ident == NULL_TREE;
     202      860600 :   if (attr_ns[0])
     203           0 :     return ident && is_attribute_p (attr_ns, ident);
     204      860600 :   return ident == NULL_TREE || is_attribute_p ("gnu", ident);
     205             : }
     206             : 
     207             : /* Given an attribute name ATTR_NAME and a list of attributes LIST,
     208             :    return a pointer to the attribute's list element if the attribute
     209             :    is part of the list, or NULL_TREE if not found.  If the attribute
     210             :    appears more than once, this only returns the first occurrence; the
     211             :    TREE_CHAIN of the return value should be passed back in if further
     212             :    occurrences are wanted.  ATTR_NAME must be in the form 'text' (not
     213             :    '__text__').  */
     214             : 
     215             : inline tree
     216  9620034949 : lookup_attribute (const char *attr_name, tree list)
     217             : {
     218  9620034949 :   if (CHECKING_P && attr_name[0] != '_')
     219             :     {
     220  9620034943 :       size_t attr_len = strlen (attr_name);
     221  9620034943 :       gcc_checking_assert (!canonicalize_attr_name (attr_name, attr_len));
     222             :     }
     223             :   /* In most cases, list is NULL_TREE.  */
     224  9620034949 :   if (list == NULL_TREE)
     225             :     return NULL_TREE;
     226             :   else
     227             :     {
     228  1952967466 :       size_t attr_len = strlen (attr_name);
     229             :       /* Do the strlen() before calling the out-of-line implementation.
     230             :          In most cases attr_name is a string constant, and the compiler
     231             :          will optimize the strlen() away.  */
     232  1952967466 :       return private_lookup_attribute (attr_name, attr_len, list);
     233             :     }
     234             : }
     235             : 
     236             : /* Similar to lookup_attribute, but also match the attribute namespace.
     237             :    ATTR_NS "" stands for either standard attribute or "gnu" namespace.  */
     238             : 
     239             : inline tree
     240   258544705 : lookup_attribute (const char *attr_ns, const char *attr_name, tree list)
     241             : {
     242   258544705 :   if (CHECKING_P && attr_name[0] != '_')
     243             :     {
     244   258544705 :       size_t attr_len = strlen (attr_name);
     245   258544705 :       gcc_checking_assert (!canonicalize_attr_name (attr_name, attr_len));
     246             :     }
     247   258544705 :   if (CHECKING_P && attr_ns && attr_ns[0] != '_')
     248             :     {
     249   258544705 :       size_t attr_ns_len = strlen (attr_ns);
     250   258544705 :       gcc_checking_assert (!canonicalize_attr_name (attr_ns, attr_ns_len));
     251             :     }
     252             :   /* In most cases, list is NULL_TREE.  */
     253   258544705 :   if (list == NULL_TREE)
     254             :     return NULL_TREE;
     255             :   else
     256             :     {
     257       31815 :       size_t attr_ns_len = attr_ns ? strlen (attr_ns) : 0;
     258       31815 :       size_t attr_len = strlen (attr_name);
     259             :       /* Do the strlen() before calling the out-of-line implementation.
     260             :          In most cases attr_name is a string constant, and the compiler
     261             :          will optimize the strlen() away.  */
     262       31815 :       return private_lookup_attribute (attr_ns, attr_name,
     263       31815 :                                        attr_ns_len, attr_len, list);
     264             :     }
     265             : }
     266             : 
     267             : /* Given an attribute name ATTR_NAME and a list of attributes LIST,
     268             :    return a pointer to the attribute's list first element if the attribute
     269             :    starts with ATTR_NAME.  ATTR_NAME must be in the form 'text' (not
     270             :    '__text__').  */
     271             : 
     272             : inline tree
     273             : lookup_attribute_by_prefix (const char *attr_name, tree list)
     274             : {
     275             :   gcc_checking_assert (attr_name[0] != '_');
     276             :   /* In most cases, list is NULL_TREE.  */
     277             :   if (list == NULL_TREE)
     278             :     return NULL_TREE;
     279             :   else
     280             :     {
     281             :       size_t attr_len = strlen (attr_name);
     282             :       while (list)
     283             :         {
     284             :           tree name = get_attribute_name (list);
     285             :           size_t ident_len = IDENTIFIER_LENGTH (name);
     286             : 
     287             :           if (attr_len > ident_len)
     288             :             {
     289             :               list = TREE_CHAIN (list);
     290             :               continue;
     291             :             }
     292             : 
     293             :           const char *p = IDENTIFIER_POINTER (name);
     294             :           gcc_checking_assert (attr_len == 0 || p[0] != '_'
     295             :                                || (ident_len > 1 && p[1] != '_'));
     296             :           if (strncmp (attr_name, p, attr_len) == 0)
     297             :             break;
     298             : 
     299             :           list = TREE_CHAIN (list);
     300             :         }
     301             : 
     302             :       return list;
     303             :     }
     304             : }
     305             : 
     306             : /* Description of a function argument declared with attribute access.
     307             :    Used as an "iterator" over all such arguments in a function declaration
     308             :    or call.  */
     309             : 
     310             : struct attr_access
     311             : {
     312             :   /* The beginning and end of the internal string representation.  */
     313             :   const char *str, *end;
     314             :   /* The attribute pointer argument.  */
     315             :   tree ptr;
     316             :   /* For a declaration, a TREE_CHAIN of VLA bound expressions stored
     317             :      in TREE_VALUE and their positions in the argument list (stored
     318             :      in TREE_PURPOSE).  Each expression may be a PARM_DECL or some
     319             :      other DECL (for ordinary variables), or an EXPR for other
     320             :      expressions (e.g., funcion calls).  */
     321             :   tree size;
     322             : 
     323             :   /* The zero-based position of each of the formal function arguments.
     324             :      For the optional SIZARG, UINT_MAX when not specified.  For VLAs
     325             :      with multiple variable bounds, SIZARG is the position corresponding
     326             :      to the most significant bound in the argument list.  Positions of
     327             :      subsequent bounds are in the TREE_PURPOSE field of the SIZE chain.  */
     328             :   unsigned ptrarg;
     329             :   unsigned sizarg;
     330             :   /* For internal specifications only, the constant minimum size of
     331             :      the array, zero if not specified, and HWI_M1U for the unspecified
     332             :      VLA [*] notation.  Meaningless for external (explicit) access
     333             :      specifications.  */
     334             :   unsigned HOST_WIDE_INT minsize;
     335             : 
     336             :   /* The access mode.  */
     337             :   access_mode mode;
     338             : 
     339             :   /* Set for an attribute added internally rather than by an explicit
     340             :      declaration. */
     341             :   bool internal_p;
     342             :   /* Set for the T[static MINSIZE] array notation for nonzero MINSIZE
     343             :      less than HWI_M1U.  */
     344             :   bool static_p;
     345             : 
     346             :   /* Return the number of specified VLA bounds.  */
     347             :   unsigned vla_bounds (unsigned *) const;
     348             : 
     349             :   /* Return internal representation as STRING_CST.  */
     350             :   tree to_internal_string () const;
     351             : 
     352             :   /* Return the human-readable representation of the external attribute
     353             :      specification (as it might appear in the source code) as STRING_CST.  */
     354             :   tree to_external_string () const;
     355             : 
     356             :   /* Return argument of array type formatted as a readable string.  */
     357             :   std::string array_as_string (tree) const;
     358             : 
     359             :   /* Return the access mode corresponding to the character code.  */
     360             :   static access_mode from_mode_char (char);
     361             : 
     362             :   /* Reset front end-specific attribute access data from attributes.  */
     363             :   static void free_lang_data (tree);
     364             : 
     365             :   /* The character codes corresponding to all the access modes.  */
     366             :   static constexpr char mode_chars[5] = { '-', 'r', 'w', 'x', '^' };
     367             : 
     368             :   /* The strings corresponding to just the external access modes.  */
     369             :   static constexpr char mode_names[4][11] =
     370             :     {
     371             :      "none", "read_only", "write_only", "read_write"
     372             :     };
     373             : };
     374             : 
     375             : inline access_mode
     376             : attr_access::from_mode_char (char c)
     377             : {
     378             :   switch (c)
     379             :     {
     380             :     case mode_chars[access_none]: return access_none;
     381             :     case mode_chars[access_read_only]: return access_read_only;
     382             :     case mode_chars[access_write_only]: return access_write_only;
     383             :     case mode_chars[access_read_write]: return access_read_write;
     384             :     case mode_chars[access_deferred]: return access_deferred;
     385             :     }
     386             :   gcc_unreachable ();
     387             : }
     388             : 
     389             : /* Used to define rdwr_map below.  */
     390             : struct rdwr_access_hash: int_hash<int, -1> { };
     391             : 
     392             : /* A mapping between argument number corresponding to attribute access
     393             :    mode (read_only, write_only, or read_write) and operands.  */
     394             : struct attr_access;
     395             : typedef hash_map<rdwr_access_hash, attr_access> rdwr_map;
     396             : 
     397             : extern void init_attr_rdwr_indices (rdwr_map *, tree);
     398             : extern attr_access *get_parm_access (rdwr_map &, tree,
     399             :                                      tree = current_function_decl);
     400             : 
     401             : #endif // GCC_ATTRIBS_H

Generated by: LCOV version 1.16