LCOV - code coverage report
Current view: top level - gcc - attribs.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 96.9 % 65 63
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 11 11
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.