LCOV - code coverage report
Current view: top level - gcc/c - c-objc-common.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 96.5 % 200 193
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 17 17
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Some code common to C and ObjC front ends.
       2              :    Copyright (C) 2001-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              : #include "config.h"
      21              : #include "system.h"
      22              : #include "coretypes.h"
      23              : #include "c-tree.h"
      24              : #include "intl.h"
      25              : #include "c-family/c-pretty-print.h"
      26              : #include "tree-core.h"
      27              : #include "tree-pretty-print.h"
      28              : #include "tree-pretty-print-markup.h"
      29              : #include "gimple-pretty-print.h"
      30              : #include "langhooks.h"
      31              : #include "c-objc-common.h"
      32              : #include "c-family/c-type-mismatch.h"
      33              : #include "stringpool.h"
      34              : #include "attribs.h"
      35              : #include "dwarf2.h"
      36              : 
      37              : static bool c_tree_printer (pretty_printer *, text_info *, const char *,
      38              :                             int, bool, bool, bool, bool *, pp_token_list &);
      39              : 
      40              : /* Info for C language features which can be queried through
      41              :    __has_{feature,extension}.  */
      42              : 
      43              : struct c_feature_info
      44              : {
      45              :   const char *ident;
      46              :   const int *enable_flag;
      47              : };
      48              : 
      49              : static const c_feature_info c_feature_table[] =
      50              : {
      51              :   { "c_alignas", &flag_isoc11 },
      52              :   { "c_alignof", &flag_isoc11 },
      53              :   { "c_atomic", &flag_isoc11 },
      54              :   { "c_generic_selections", &flag_isoc11 },
      55              :   { "c_static_assert", &flag_isoc11 },
      56              :   { "c_thread_local", &flag_isoc11 },
      57              :   { "cxx_binary_literals", &flag_isoc23 }
      58              : };
      59              : 
      60              : /* Register features specific to the C language.  */
      61              : 
      62              : void
      63        24832 : c_register_features ()
      64              : {
      65       198656 :   for (unsigned i = 0; i < ARRAY_SIZE (c_feature_table); i++)
      66              :     {
      67       173824 :       const c_feature_info *info = c_feature_table + i;
      68       173824 :       const bool feat_p = !info->enable_flag || *info->enable_flag;
      69       173824 :       c_common_register_feature (info->ident, feat_p);
      70              :     }
      71        24832 : }
      72              : 
      73              : bool
      74        12727 : c_missing_noreturn_ok_p (tree decl)
      75              : {
      76              :   /* A missing noreturn is ok for the `main' function.  */
      77        12727 :   if (!MAIN_NAME_P (DECL_ASSEMBLER_NAME (decl)))
      78              :     return false;
      79              : 
      80         6821 :   return flag_hosted
      81         6821 :     || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl))) == integer_type_node;
      82              : }
      83              : 
      84              : /* Called from check_global_declaration.  */
      85              : 
      86              : bool
      87        14726 : c_warn_unused_global_decl (const_tree decl)
      88              : {
      89        14726 :   if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))
      90              :     return false;
      91          519 :   if (DECL_IN_SYSTEM_HEADER (decl))
      92              :     return false;
      93              : 
      94              :   return true;
      95              : }
      96              : 
      97              : /* Initialization common to C and Objective-C front ends.  */
      98              : bool
      99       110763 : c_objc_common_init (void)
     100              : {
     101       110763 :   c_init_decl_processing ();
     102              : 
     103       110763 :   return c_common_init ();
     104              : }
     105              : 
     106              : /* Decide whether it's worth saying that TYPE is also known as some other
     107              :    type.  Return the other type if so, otherwise return TYPE.  */
     108              : 
     109              : static tree
     110        84364 : get_aka_type (tree type)
     111              : {
     112        84364 :   if (type == error_mark_node)
     113              :     return type;
     114              : 
     115        84349 :   tree result;
     116        84349 :   if (typedef_variant_p (type))
     117              :     {
     118              :       /* Saying that "foo" is also known as "struct foo" or
     119              :          "struct <anonymous>" is unlikely to be useful, since users of
     120              :          structure-like types would already know that they're structures.
     121              :          The same applies to unions and enums; in general, printing the
     122              :          tag is only useful if it has a different name.  */
     123         7001 :       tree orig_type = DECL_ORIGINAL_TYPE (TYPE_NAME (type));
     124         7001 :       tree_code code = TREE_CODE (orig_type);
     125         7001 :       tree orig_id = TYPE_IDENTIFIER (orig_type);
     126         7001 :       if ((code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
     127         7001 :           && (!orig_id || TYPE_IDENTIFIER (type) == orig_id))
     128              :         return type;
     129              : 
     130         6583 :       if (!user_facing_original_type_p (type))
     131              :         return type;
     132              : 
     133         6470 :       result = get_aka_type (orig_type);
     134              :     }
     135        77348 :   else if (TREE_CODE (type) == ENUMERAL_TYPE)
     136              :     return type;
     137              :   else
     138              :     {
     139        77043 :       tree canonical = TYPE_CANONICAL (type);
     140        77043 :       if (canonical && TREE_CODE (type) != TREE_CODE (canonical))
     141              :         return canonical;
     142              : 
     143              :       /* Recursive calls might choose a middle ground between TYPE
     144              :          (which has no typedefs stripped) and CANONICAL (which has
     145              :          all typedefs stripped).  So try to reuse TYPE or CANONICAL if
     146              :          convenient, but be prepared to create a new type if necessary.  */
     147        77043 :       switch (TREE_CODE (type))
     148              :         {
     149         6195 :         case POINTER_TYPE:
     150         6195 :         case REFERENCE_TYPE:
     151         6195 :           {
     152         6195 :             tree target_type = get_aka_type (TREE_TYPE (type));
     153              : 
     154         6195 :             if (target_type == TREE_TYPE (type))
     155              :               return type;
     156              : 
     157          656 :             if (canonical && target_type == TREE_TYPE (canonical))
     158              :               return canonical;
     159              : 
     160          200 :             result = (TREE_CODE (type) == POINTER_TYPE
     161          200 :                       ? build_pointer_type (target_type)
     162            0 :                       : build_reference_type (target_type));
     163              :             break;
     164              :           }
     165              : 
     166        22649 :         case ARRAY_TYPE:
     167        22649 :           {
     168        22649 :             tree element_type = get_aka_type (TREE_TYPE (type));
     169        22649 :             tree index_type = (TYPE_DOMAIN (type)
     170        22649 :                                ? get_aka_type (TYPE_DOMAIN (type))
     171              :                                : NULL_TREE);
     172              : 
     173        22649 :             if (element_type == TREE_TYPE (type)
     174        38645 :                 && index_type == TYPE_DOMAIN (type))
     175              :               return type;
     176              : 
     177         6653 :             if (canonical
     178         6525 :                 && element_type == TREE_TYPE (canonical)
     179        13167 :                 && index_type == TYPE_DOMAIN (canonical))
     180              :               return canonical;
     181              : 
     182          278 :             result = build_array_type (element_type, index_type,
     183          139 :                                        TYPE_TYPELESS_STORAGE (type));
     184          139 :             break;
     185              :           }
     186              : 
     187         2003 :         case FUNCTION_TYPE:
     188         2003 :           {
     189         2003 :             tree return_type = get_aka_type (TREE_TYPE (type));
     190              : 
     191         2003 :             tree args = TYPE_ARG_TYPES (type);
     192         2003 :             if (args == error_mark_node)
     193         1768 :               return type;
     194              : 
     195         2003 :             auto_vec<tree, 32> arg_types;
     196         2003 :             bool type_ok_p = true;
     197         3789 :             while (args && args != void_list_node)
     198              :               {
     199         1786 :                 tree arg_type = get_aka_type (TREE_VALUE (args));
     200         1786 :                 arg_types.safe_push (arg_type);
     201         1786 :                 type_ok_p &= (arg_type == TREE_VALUE (args));
     202         1786 :                 args = TREE_CHAIN (args);
     203              :               }
     204              : 
     205         2003 :             if (type_ok_p && return_type == TREE_TYPE (type))
     206         1768 :               return type;
     207              : 
     208          235 :             unsigned int i;
     209          235 :             tree arg_type;
     210          880 :             FOR_EACH_VEC_ELT_REVERSE (arg_types, i, arg_type)
     211          410 :               args = tree_cons (NULL_TREE, arg_type, args);
     212          235 :             result = build_function_type (return_type, args);
     213          235 :             break;
     214         2003 :           }
     215              : 
     216        46196 :         default:
     217        55699 :           return canonical ? canonical : type;
     218              :         }
     219              :     }
     220              :   /* For tagged types ignore attributes because they will otherwise
     221              :      be ignored later causing a warning inside diagnostics which leads
     222              :      to an ICE.  */
     223         7044 :   if (RECORD_OR_UNION_TYPE_P (type) || TREE_CODE (type) == ENUMERAL_TYPE)
     224          315 :     return build_qualified_type (result, TYPE_QUALS (type));
     225         6729 :   return build_type_attribute_qual_variant (result, TYPE_ATTRIBUTES (type),
     226        13458 :                                             TYPE_QUALS (type));
     227              : }
     228              : 
     229              : /* Print T to CPP.  */
     230              : 
     231              : static void
     232        23557 : print_type (c_pretty_printer *cpp, tree t, bool *quoted,
     233              :             const char *highlight_color = nullptr)
     234              : {
     235        23557 :   if (t == error_mark_node)
     236              :     {
     237            0 :       pp_string (cpp, _("{erroneous}"));
     238            0 :       return;
     239              :     }
     240              : 
     241        23557 :   if (!pp_show_highlight_colors (cpp))
     242          447 :     highlight_color = nullptr;
     243              : 
     244        23557 :   gcc_assert (TYPE_P (t));
     245        23557 :   struct obstack *ob = pp_buffer (cpp)->m_obstack;
     246        23557 :   char *p = (char *) obstack_base (ob);
     247              :   /* Remember the end of the initial dump.  */
     248        23557 :   int len = obstack_object_size (ob);
     249              : 
     250        23557 :   tree name = TYPE_NAME (t);
     251        23557 :   if (name && TREE_CODE (name) == TYPE_DECL && DECL_NAME (name))
     252         7108 :     pp_identifier (cpp, lang_hooks.decl_printable_name (name, 2));
     253              :   else
     254        16449 :     cpp->type_id (t);
     255              : 
     256              :   /* If we're printing a type that involves typedefs, also print the
     257              :      stripped version.  But sometimes the stripped version looks
     258              :      exactly the same, so we don't want it after all.  To avoid
     259              :      printing it in that case, we play ugly obstack games.  */
     260        23557 :   tree aka_type = get_aka_type (t);
     261        23557 :   if (aka_type != t)
     262              :     {
     263         6047 :       const bool show_color = pp_show_color (cpp);
     264         6047 :       c_pretty_printer cpp2;
     265              :       /* Print the stripped version into a temporary printer.  */
     266         6047 :       cpp2.type_id (aka_type);
     267         6047 :       struct obstack *ob2 = pp_buffer (&cpp2)->m_obstack;
     268              :       /* Get the stripped version from the temporary printer.  */
     269         6047 :       const char *aka = (char *) obstack_base (ob2);
     270         6047 :       int aka_len = obstack_object_size (ob2);
     271         6047 :       int type1_len = obstack_object_size (ob) - len;
     272              : 
     273              :       /* If they are identical, bail out.  */
     274         6047 :       if (aka_len == type1_len && memcmp (p + len, aka, aka_len) == 0)
     275          182 :         return;
     276              : 
     277              :       /* They're not, print the stripped version now.  */
     278         5865 :       if (*quoted)
     279         5649 :         pp_end_quote (cpp, show_color);
     280         5865 :       pp_c_whitespace (cpp);
     281         5865 :       pp_left_brace (cpp);
     282         5865 :       pp_c_ws_string (cpp, _("aka"));
     283         5865 :       pp_c_whitespace (cpp);
     284         5865 :       pp_string (cpp, colorize_stop (show_color));
     285         5865 :       if (*quoted)
     286         5649 :         pp_begin_quote (cpp, show_color);
     287         5865 :       if (highlight_color)
     288          361 :         pp_string (cpp, colorize_start (show_color, highlight_color));
     289         5865 :       cpp->type_id (aka_type);
     290         5865 :       if (*quoted)
     291         5649 :         pp_end_quote (cpp, show_color);
     292         5865 :       pp_right_brace (cpp);
     293              :       /* No further closing quotes are needed.  */
     294         5865 :       *quoted = false;
     295         6047 :     }
     296              : }
     297              : 
     298              : /* Implementation of pp_markup::element_quoted_type::print_type
     299              :    for C/ObjC.  */
     300              : 
     301              : void
     302         5445 : pp_markup::element_quoted_type::print_type (pp_markup::context &ctxt)
     303              : {
     304         5445 :   auto pp = ctxt.m_pp.clone ();
     305         5445 :   c_pretty_printer *cpp = (c_pretty_printer *)pp.get ();
     306         5445 :   cpp->set_padding (pp_none);
     307         5445 :   ::print_type (cpp, m_type, &ctxt.m_quoted, m_highlight_color);
     308         5445 :   pp_string (&ctxt.m_pp, pp_formatted_text (cpp));
     309         5445 : }
     310              : 
     311              : /* Called during diagnostic message formatting process to print a
     312              :    source-level entity onto BUFFER.  The meaning of the format specifiers
     313              :    is as follows:
     314              :    %D: a general decl,
     315              :    %E: an identifier or expression,
     316              :    %F: a function declaration,
     317              :    %T: a type.
     318              :    %V: a list of type qualifiers from a tree.
     319              :    %v: an explicit list of type qualifiers
     320              :    %#v: an explicit list of type qualifiers of a function type.
     321              : 
     322              :    Please notice when called, the `%' part was already skipped by the
     323              :    diagnostic machinery.  */
     324              : static bool
     325        64187 : c_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
     326              :                 int precision, bool wide, bool set_locus, bool hash,
     327              :                 bool *quoted, pp_token_list &)
     328              : {
     329        64187 :   tree t = NULL_TREE;
     330              :   // FIXME: the next cast should be a dynamic_cast, when it is permitted.
     331        64187 :   c_pretty_printer *cpp = (c_pretty_printer *) pp;
     332        64187 :   pp->set_padding (pp_none);
     333              : 
     334        64187 :   if (precision != 0 || wide)
     335              :     return false;
     336              : 
     337        64187 :   if (*spec != 'v')
     338              :     {
     339        63982 :       t = va_arg (*text->m_args_ptr, tree);
     340        63982 :       if (set_locus)
     341         1629 :         text->set_location (0, DECL_SOURCE_LOCATION (t),
     342              :                             SHOW_RANGE_WITH_CARET);
     343              :     }
     344              : 
     345        64187 :   switch (*spec)
     346              :     {
     347        15375 :     case 'D':
     348        15375 :       if (VAR_P (t) && DECL_HAS_DEBUG_EXPR_P (t))
     349              :         {
     350           42 :           t = DECL_DEBUG_EXPR (t);
     351           42 :           if (!DECL_P (t))
     352              :             {
     353           42 :               cpp->expression (t);
     354           42 :               return true;
     355              :             }
     356              :         }
     357              :       /* FALLTHRU */
     358              : 
     359        15408 :     case 'F':
     360        15408 :       if (DECL_NAME (t))
     361              :         {
     362        14892 :           pp_identifier (cpp, lang_hooks.decl_printable_name (t, 2));
     363        14892 :           if (TREE_CODE (t) == FUNCTION_DECL)
     364              :             {
     365         8062 :               pp_c_function_target_version (cpp, t);
     366         8062 :               pp_c_function_target_clones (cpp, t);
     367              :             }
     368        14892 :           return true;
     369              :         }
     370          516 :       break;
     371              : 
     372        17667 :     case 'T':
     373        17667 :       print_type (cpp, t, quoted);
     374        17667 :       return true;
     375              : 
     376        30865 :     case 'E':
     377        30865 :       if (TREE_CODE (t) == IDENTIFIER_NODE)
     378         5197 :         pp_identifier (cpp, IDENTIFIER_POINTER (t));
     379              :       else
     380        25668 :         cpp->expression (t);
     381              :       return true;
     382              : 
     383            0 :     case 'V':
     384            0 :       pp_c_type_qualifier_list (cpp, t);
     385            0 :       return true;
     386              : 
     387          205 :     case 'v':
     388          205 :       pp_c_cv_qualifiers (cpp, va_arg (*text->m_args_ptr, int), hash);
     389          205 :       return true;
     390              : 
     391              :     default:
     392              :       return false;
     393              :     }
     394              : 
     395          516 :   pp_string (cpp, _("({anonymous})"));
     396          516 :   return true;
     397              : }
     398              : 
     399              : /* C-specific implementation of range_label::get_text () vfunc for
     400              :    range_label_for_type_mismatch.  */
     401              : 
     402              : label_text
     403          445 : range_label_for_type_mismatch::get_text (unsigned /*range_idx*/) const
     404              : {
     405          445 :   if (m_labelled_type == NULL_TREE)
     406            0 :     return label_text::borrow (NULL);
     407              : 
     408          445 :   c_pretty_printer cpp;
     409          445 :   bool quoted = false;
     410          445 :   print_type (&cpp, m_labelled_type, &quoted);
     411          445 :   return label_text::take (xstrdup (pp_formatted_text (&cpp)));
     412          445 : }
     413              : 
     414              : 
     415              : /* In C and ObjC, all decls have "C" linkage.  */
     416              : bool
     417     15810665 : has_c_linkage (const_tree decl ATTRIBUTE_UNUSED)
     418              : {
     419     15810665 :   return true;
     420              : }
     421              : 
     422              : void
     423       110970 : c_initialize_diagnostics (diagnostics::context *context)
     424              : {
     425       110970 :   context->set_pretty_printer (std::make_unique<c_pretty_printer> ());
     426       110970 :   c_common_diagnostics_set_defaults (context);
     427       110970 :   context->set_format_decoder (&c_tree_printer);
     428       110970 : }
     429              : 
     430              : int
     431     15607648 : c_types_compatible_p (tree x, tree y)
     432              : {
     433     15607648 :   return comptypes (TYPE_MAIN_VARIANT (x), TYPE_MAIN_VARIANT (y));
     434              : }
     435              : 
     436              : /* Determine if the type is a variably modified type for the backend.  */
     437              : 
     438              : bool
     439     11200437 : c_var_mod_p (tree x, tree fn ATTRIBUTE_UNUSED)
     440              : {
     441     11200437 :   return C_TYPE_VARIABLY_MODIFIED (x);
     442              : }
     443              : 
     444              : /* Special routine to get the alias set of T for C.  */
     445              : 
     446              : alias_set_type
     447    195445369 : c_get_alias_set (tree t)
     448              : {
     449    195445369 :   return c_common_get_alias_set (t);
     450              : }
     451              : 
     452              : /* In C there are no invisible parameters like in C++ (this, in-charge, VTT,
     453              :    etc.).  */
     454              : 
     455              : int
     456     41592879 : maybe_adjust_arg_pos_for_attribute (const_tree)
     457              : {
     458     41592879 :   return 0;
     459              : }
     460              : 
     461              : /* In C, no expression is dependent.  */
     462              : 
     463              : bool
     464           35 : instantiation_dependent_expression_p (tree)
     465              : {
     466           35 :   return false;
     467              : }
     468              : 
     469              : /* Return -1 if dwarf ATTR shouldn't be added for TYPE, or the attribute
     470              :    value otherwise.  */
     471              : int
     472       123065 : c_type_dwarf_attribute (const_tree type, int attr)
     473              : {
     474       123065 :   if (type == NULL_TREE)
     475              :     return -1;
     476              : 
     477       123065 :   switch (attr)
     478              :     {
     479         6165 :     case DW_AT_export_symbols:
     480         6165 :       if (RECORD_OR_UNION_TYPE_P (type) && TYPE_NAME (type) == NULL_TREE)
     481         6163 :         return 1;
     482              :       break;
     483              : 
     484              :     default:
     485              :       break;
     486              :     }
     487              : 
     488              :   return -1;
     489              : }
        

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.