LCOV - code coverage report
Current view: top level - gcc - graphviz.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 85.0 % 80 68
Test Date: 2025-07-05 13:26:22 Functions: 77.8 % 9 7
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Helper code for graphviz output.
       2                 :             :    Copyright (C) 2019-2025 Free Software Foundation, Inc.
       3                 :             :    Contributed by David Malcolm <dmalcolm@redhat.com>.
       4                 :             : 
       5                 :             : This file is part of GCC.
       6                 :             : 
       7                 :             : GCC is free software; you can redistribute it and/or modify it
       8                 :             : under the terms of the GNU General Public License as published by
       9                 :             : the Free Software Foundation; either version 3, or (at your option)
      10                 :             : any later version.
      11                 :             : 
      12                 :             : GCC is distributed in the hope that it will be useful, but
      13                 :             : WITHOUT ANY WARRANTY; without even the implied warranty of
      14                 :             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15                 :             : General Public License for more details.
      16                 :             : 
      17                 :             : You should have received a copy of the GNU General Public License
      18                 :             : along with GCC; see the file COPYING3.  If not see
      19                 :             : <http://www.gnu.org/licenses/>.  */
      20                 :             : 
      21                 :             : #ifndef GCC_GRAPHVIZ_H
      22                 :             : #define GCC_GRAPHVIZ_H
      23                 :             : 
      24                 :             : #include "pretty-print.h" /* for ATTRIBUTE_GCC_PPDIAG.  */
      25                 :             : 
      26                 :             : namespace xml { class node; }
      27                 :             : 
      28                 :             : namespace dot {
      29                 :             : 
      30                 :             : /* A class for writing .dot output to a pretty_printer with
      31                 :             :    indentation to show nesting.  */
      32                 :             : 
      33                 :             : class writer {
      34                 :             : public:
      35                 :             :   writer (pretty_printer &pp);
      36                 :             : 
      37                 :        1260 :   void indent () { m_indent++; }
      38                 :        1260 :   void outdent () { m_indent--; }
      39                 :             : 
      40                 :             :   void write_indent ();
      41                 :             : 
      42                 :         193 :   void write_character (char ch)
      43                 :             :   {
      44                 :         193 :     pp_character (&m_pp, ch);
      45                 :         125 :   }
      46                 :         263 :   void write_string (const char *str)
      47                 :             :   {
      48                 :         263 :     pp_string (&m_pp, str);
      49                 :         155 :   }
      50                 :          60 :   void write_newline ()
      51                 :             :   {
      52                 :          60 :     pp_newline (&m_pp);
      53                 :             :   }
      54                 :             : 
      55                 :       58927 :   pretty_printer *get_pp () const { return &m_pp; }
      56                 :             : 
      57                 :             :  private:
      58                 :             :   pretty_printer &m_pp;
      59                 :             :   int m_indent;
      60                 :             : };
      61                 :             : 
      62                 :             : // An AST for the dot language
      63                 :             : // See https://graphviz.org/doc/info/lang.html
      64                 :             : 
      65                 :             : // Forward decls
      66                 :             : 
      67                 :             : struct id;
      68                 :             : struct node_id;
      69                 :             : struct port;
      70                 :             : struct kv_pair;
      71                 :             : struct graph;
      72                 :             : struct attr_list;
      73                 :             : struct stmt_list;
      74                 :             : struct stmt;
      75                 :             :   struct node_stmt;
      76                 :             :   struct attr_stmt;
      77                 :             :   struct kv_stmt;
      78                 :             :   struct edge_stmt;
      79                 :             :   struct subgraph;
      80                 :             : 
      81                 :             : // Decls
      82                 :             : 
      83                 :         437 : struct ast_node
      84                 :             : {
      85                 :         263 :   virtual ~ast_node () {}
      86                 :             :   virtual void print (writer &w) const = 0;
      87                 :             : 
      88                 :             :   void dump () const;
      89                 :             : };
      90                 :             : 
      91                 :         198 : struct id : public ast_node
      92                 :             : {
      93                 :             :   enum class kind
      94                 :             :   {
      95                 :             :     identifier,
      96                 :             :     quoted,
      97                 :             :     html
      98                 :             :   };
      99                 :             : 
     100                 :             :   id (std::string str);
     101                 :             : 
     102                 :             :   /* For HTML labels: see https://graphviz.org/doc/info/shapes.html#html  */
     103                 :             :   id (const xml::node &n);
     104                 :             : 
     105                 :             :   void print (writer &w) const final override;
     106                 :             : 
     107                 :             :   static bool is_identifier_p (const char *);
     108                 :             : 
     109                 :             :   std::string m_str;
     110                 :             :   enum kind m_kind;
     111                 :             : };
     112                 :             : 
     113                 :             : /* ID '=' ID */
     114                 :             : 
     115                 :             : struct kv_pair : ast_node
     116                 :             : {
     117                 :          31 :   kv_pair (id key, id value)
     118                 :          62 :   : m_key (std::move (key)),
     119                 :          31 :     m_value (std::move (value))
     120                 :             :   {
     121                 :          31 :   }
     122                 :             : 
     123                 :             :   void print (writer &w) const final override;
     124                 :             : 
     125                 :             :   id m_key;
     126                 :             :   id m_value;
     127                 :             : };
     128                 :             : 
     129                 :             : /* attr_list: '[' [ a_list ] ']' [ attr_list ] */
     130                 :             : 
     131                 :          38 : struct attr_list : public ast_node
     132                 :             : {
     133                 :             :   void print (writer &w) const;
     134                 :          31 :   void add (id key, id value)
     135                 :             :   {
     136                 :          31 :     m_kvs.push_back ({std::move (key), std::move (value)});
     137                 :          31 :   }
     138                 :             : 
     139                 :             :   std::vector<kv_pair> m_kvs;
     140                 :             : };
     141                 :             : 
     142                 :             : /* stmt_list : [ stmt [ ';' ] stmt_list ] */
     143                 :             : 
     144                 :           5 : struct stmt_list : public ast_node
     145                 :             : {
     146                 :             :   void print (writer &w) const final override;
     147                 :          31 :   void add_stmt (std::unique_ptr<stmt> s)
     148                 :             :   {
     149                 :          31 :     m_stmts.push_back (std::move (s));
     150                 :             :   }
     151                 :             :   void add_edge (node_id src_id, node_id dst_id);
     152                 :             :   void add_attr (id key, id value);
     153                 :             : 
     154                 :             :   std::vector<std::unique_ptr<stmt>> m_stmts;
     155                 :             : };
     156                 :             : 
     157                 :             : /* graph : [ strict ] (graph | digraph) [ ID ] '{' stmt_list '}'  */
     158                 :             : 
     159                 :             : struct graph : public ast_node
     160                 :             : {
     161                 :           5 :   graph ()
     162                 :           5 :   : m_id (nullptr)
     163                 :             :   {
     164                 :             :   }
     165                 :             : 
     166                 :           4 :   graph (id id_)
     167                 :           4 :   : m_id (std::make_unique<id> (std::move (id_)))
     168                 :             :   {
     169                 :             :   }
     170                 :             : 
     171                 :             :   void print (writer &w) const final override;
     172                 :             : 
     173                 :          30 :   void add_stmt (std::unique_ptr<stmt> s)
     174                 :             :   {
     175                 :          30 :     m_stmt_list.add_stmt (std::move (s));
     176                 :          30 :   }
     177                 :             : 
     178                 :             :   std::unique_ptr<id> m_id; // optional
     179                 :             :   stmt_list m_stmt_list;
     180                 :             : };
     181                 :             : 
     182                 :             : /* Abstract base class.
     183                 :             :      stmt : node_stmt
     184                 :             :           | edge_stmt
     185                 :             :           | attr_stmt
     186                 :             :           | ID '=' ID ("kv_stmt")
     187                 :             :           | subgraph  */
     188                 :             : 
     189                 :          39 : struct stmt
     190                 :             : {
     191                 :             :   virtual ~stmt () {}
     192                 :             :   virtual void print (writer &w) const = 0;
     193                 :             : };
     194                 :             : 
     195                 :          38 : struct stmt_with_attr_list : public stmt
     196                 :             : {
     197                 :             :   void set_attr (id key, id value)
     198                 :             :   {
     199                 :             :     m_attrs.add (std::move (key), std::move (value));
     200                 :             :   }
     201                 :             :   void set_label (dot::id label);
     202                 :             : 
     203                 :             :   attr_list m_attrs;
     204                 :             : };
     205                 :             : 
     206                 :             : struct node_stmt : public stmt_with_attr_list
     207                 :             : {
     208                 :          21 :   node_stmt (id id_)
     209                 :          21 :   : m_id (id_)
     210                 :             :   {
     211                 :             :   }
     212                 :             : 
     213                 :             :   void print (writer &w) const final override;
     214                 :             : 
     215                 :             :   id m_id;
     216                 :             : };
     217                 :             : 
     218                 :             : struct attr_stmt : public stmt_with_attr_list
     219                 :             : {
     220                 :             :   enum class kind { graph, node, edge };
     221                 :             : 
     222                 :           5 :   attr_stmt (enum kind kind_)
     223                 :           5 :   : m_kind (kind_)
     224                 :             :   {
     225                 :             :   }
     226                 :             : 
     227                 :             :   void print (writer &w) const final override;
     228                 :             : 
     229                 :             :   enum kind m_kind;
     230                 :             : };
     231                 :             : 
     232                 :             : /* "ID '=' ID" as a stmt.  */
     233                 :             : 
     234                 :             : struct kv_stmt : public stmt
     235                 :             : {
     236                 :           0 :   kv_stmt (kv_pair kv)
     237                 :           0 :   : m_kv (std::move (kv))
     238                 :             :   {}
     239                 :             : 
     240                 :             :   void print (writer &w) const final override;
     241                 :             : 
     242                 :             :   kv_pair m_kv;
     243                 :             : };
     244                 :             : 
     245                 :             : /* node_id : ID [ port ] */
     246                 :             : 
     247                 :             : enum class compass_pt
     248                 :             : {
     249                 :             :  n, ne, e, se, s, sw, w, nw, c
     250                 :             :  /* "_" clashes with intl macro */
     251                 :             : };
     252                 :             : 
     253                 :             : /* port : ':' ID [ ':' compass_pt ]
     254                 :             :         | ':' compass_pt
     255                 :             : */
     256                 :             : 
     257                 :             : struct port : public ast_node
     258                 :             : {
     259                 :          26 :   port (id id_)
     260                 :          26 :   : m_id (std::make_unique<id> (std::move (id_))),
     261                 :          26 :     m_compass_pt (nullptr)
     262                 :             :   {
     263                 :             :   }
     264                 :             : 
     265                 :             :   port (enum compass_pt compass_pt_)
     266                 :             :   : m_id (nullptr),
     267                 :             :     m_compass_pt (std::make_unique<compass_pt> (compass_pt_))
     268                 :             :   {
     269                 :             :   }
     270                 :             : 
     271                 :           0 :   port (id id_,
     272                 :             :         enum compass_pt compass_pt_)
     273                 :           0 :   : m_id (std::make_unique<id> (std::move (id_))),
     274                 :           0 :     m_compass_pt (std::make_unique<compass_pt> (compass_pt_))
     275                 :             :   {
     276                 :           0 :   }
     277                 :             : 
     278                 :          76 :   port (const port &other)
     279                 :          76 :   : m_id (nullptr),
     280                 :          76 :     m_compass_pt (nullptr)
     281                 :             :   {
     282                 :          76 :     if (other.m_id)
     283                 :          76 :       m_id = std::make_unique<id> (*other.m_id);
     284                 :          76 :     if (other.m_compass_pt)
     285                 :           0 :       m_compass_pt = std::make_unique<enum compass_pt> (*other.m_compass_pt);
     286                 :          76 :   }
     287                 :             : 
     288                 :             :   void print (writer &w) const final override;
     289                 :             : 
     290                 :             :   std::unique_ptr<id> m_id; // would be std::optional
     291                 :             :   std::unique_ptr<enum compass_pt> m_compass_pt; // would be std::optional
     292                 :             : };
     293                 :             : 
     294                 :             : struct node_id : public ast_node
     295                 :             : {
     296                 :           8 :   node_id (id id_)
     297                 :           8 :   : m_id (id_),
     298                 :           4 :     m_port (nullptr)
     299                 :             :   {
     300                 :             :   }
     301                 :          26 :   node_id (id id_, port port_)
     302                 :          26 :   : m_id (id_),
     303                 :          26 :     m_port (std::make_unique<port> (std::move (port_)))
     304                 :             :   {
     305                 :          26 :   }
     306                 :          62 :   node_id (const node_id &other)
     307                 :          62 :   : m_id (other.m_id),
     308                 :          62 :     m_port (nullptr)
     309                 :             :   {
     310                 :          62 :     if (other.m_port)
     311                 :          50 :       m_port = std::make_unique<port> (*other.m_port);
     312                 :          62 :   }
     313                 :             : 
     314                 :             :   void print (writer &w) const final override;
     315                 :             : 
     316                 :             :   id m_id;
     317                 :             :   std::unique_ptr<port> m_port; // would be std::optional
     318                 :             : };
     319                 :             : 
     320                 :             : /* The full grammar for edge_stmt is:
     321                 :             :      edge_stmt  : (node_id | subgraph) edgeRHS [ attr_list ]
     322                 :             :      edgeRHS    : edgeop (node_id | subgraph) [ edgeRHS ]
     323                 :             :    This class support the subsets where all are "node_id", rather than
     324                 :             :    "subgraph", and doesn't yet support "port" giving effectively:
     325                 :             :       node_id (edgeop node_id)+ [ attr_list]
     326                 :             :  */
     327                 :             : 
     328                 :             : struct edge_stmt : public stmt_with_attr_list
     329                 :             : {
     330                 :          12 :   edge_stmt (node_id src_id, node_id dst_id)
     331                 :          12 :   {
     332                 :          12 :     m_node_ids.push_back (std::move (src_id));
     333                 :          12 :     m_node_ids.push_back (std::move (dst_id));
     334                 :          12 :   }
     335                 :             : 
     336                 :             :   void print (writer &w) const final override;
     337                 :             : 
     338                 :             :   std::vector<node_id> m_node_ids; // should have 2 or more elements
     339                 :             : };
     340                 :             : 
     341                 :             : /* [ subgraph [ ID ] ] '{' stmt_list '}' */
     342                 :             : 
     343                 :             : struct subgraph : public stmt
     344                 :             : {
     345                 :           1 :   subgraph (id id_)
     346                 :           1 :   : m_id (id_)
     347                 :             :   {
     348                 :             :   }
     349                 :             : 
     350                 :             :   void print (writer &w) const final override;
     351                 :             : 
     352                 :             :   void add_stmt (std::unique_ptr<stmt> s)
     353                 :             :   {
     354                 :             :     m_stmt_list.add_stmt (std::move (s));
     355                 :             :   }
     356                 :           0 :   void add_attr (id key, id value)
     357                 :             :   {
     358                 :           0 :     m_stmt_list.add_stmt
     359                 :           0 :       (std::make_unique <kv_stmt> (kv_pair (std::move (key),
     360                 :           0 :                                             std::move (value))));
     361                 :           0 :   }
     362                 :             : 
     363                 :             :   id m_id;
     364                 :             :   stmt_list m_stmt_list;
     365                 :             : };
     366                 :             : 
     367                 :             : extern std::unique_ptr<xml::node>
     368                 :             : make_svg_from_graph (const graph &g);
     369                 :             : 
     370                 :             : } // namespace dot
     371                 :             : 
     372                 :             : /* A class for writing .dot output to a pretty_printer with
     373                 :             :    indentation to show nesting.  */
     374                 :             : 
     375                 :             : class graphviz_out : public dot::writer {
     376                 :             :  public:
     377                 :             :   graphviz_out (pretty_printer *pp);
     378                 :             : 
     379                 :             :   void print (const char *fmt, ...)
     380                 :             :     ATTRIBUTE_GCC_PPDIAG(2,3);
     381                 :             :   void println (const char *fmt, ...)
     382                 :             :     ATTRIBUTE_GCC_PPDIAG(2,3);
     383                 :             : 
     384                 :             :   void begin_tr ();
     385                 :             :   void end_tr ();
     386                 :             : 
     387                 :             :   void begin_td ();
     388                 :             :   void end_td ();
     389                 :             : 
     390                 :             :   void begin_trtd ();
     391                 :             :   void end_tdtr ();
     392                 :             : };
     393                 :             : 
     394                 :             : #endif /* GCC_GRAPHVIZ_H */
        

Generated by: LCOV version 2.1-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.