Branch data Line data Source code
1 : : /* Extensions to diagnostics::digraphs to support state graphs.
2 : : Copyright (C) 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 : : #define INCLUDE_ALGORITHM
22 : : #define INCLUDE_MAP
23 : : #define INCLUDE_SET
24 : : #define INCLUDE_STRING
25 : : #define INCLUDE_VECTOR
26 : : #include "config.h"
27 : : #include "system.h"
28 : : #include "coretypes.h"
29 : :
30 : : #include "diagnostics/state-graphs.h"
31 : : #include "selftest.h"
32 : :
33 : : using namespace diagnostics::state_graphs;
34 : :
35 : : const char * const node_kind_strs[] = {
36 : : "globals",
37 : : "code",
38 : : "function",
39 : : "stack",
40 : : "stack-frame",
41 : : "heap",
42 : : "thread-local",
43 : : "dynalloc-buffer",
44 : : "variable",
45 : : "field",
46 : : "padding",
47 : : "element",
48 : : "other",
49 : : };
50 : :
51 : : const char *
52 : 546 : diagnostics::state_graphs::node_kind_to_str (enum node_kind k)
53 : : {
54 : 546 : return node_kind_strs[static_cast<int> (k)];
55 : : }
56 : :
57 : : // struct state_node_ref
58 : :
59 : : enum node_kind
60 : 20 : state_node_ref::get_node_kind () const
61 : : {
62 : 20 : const char *value = get_attr ("kind");
63 : 20 : if (!value)
64 : : return node_kind::other;
65 : :
66 : 129 : for (size_t i = 0; i < ARRAY_SIZE (node_kind_strs); ++i)
67 : 129 : if (!strcmp (node_kind_strs[i], value))
68 : 16 : return static_cast<enum node_kind> (i);
69 : :
70 : : return node_kind::other;
71 : : }
72 : :
73 : : void
74 : 546 : state_node_ref::set_node_kind (enum node_kind k)
75 : : {
76 : 546 : set_attr ("kind", node_kind_to_str (k));
77 : 546 : }
78 : :
79 : : const char * const dynalloc_state_strs[] = {
80 : : "unknown",
81 : : "nonnull",
82 : : "unchecked",
83 : : "freed"
84 : : };
85 : :
86 : : enum node_dynalloc_state
87 : 8 : state_node_ref::get_dynalloc_state () const
88 : : {
89 : 8 : const char *value = get_attr ("dynalloc-state");
90 : 8 : if (!value)
91 : : return node_dynalloc_state::unknown;
92 : :
93 : 16 : for (size_t i = 0; i < ARRAY_SIZE (dynalloc_state_strs); ++i)
94 : 16 : if (!strcmp (dynalloc_state_strs[i], value))
95 : 4 : return static_cast<enum node_dynalloc_state> (i);
96 : :
97 : : return node_dynalloc_state::unknown;
98 : : }
99 : :
100 : : void
101 : 48 : state_node_ref::set_dynalloc_state (enum node_dynalloc_state s) const
102 : : {
103 : 96 : set_attr ("dynalloc-state",
104 : 48 : dynalloc_state_strs[static_cast <size_t> (s)]);
105 : 48 : }
106 : :
107 : : const char *
108 : 0 : state_node_ref::get_dynamic_extents () const
109 : : {
110 : 0 : return m_node.get_attr (STATE_NODE_PREFIX, "dynamic-extents");
111 : : }
112 : :
113 : : void
114 : 125 : state_node_ref::set_json_attr (const char *key,
115 : : std::unique_ptr<json::value> value) const
116 : : {
117 : 125 : m_node.set_json_attr (STATE_NODE_PREFIX, key, std::move (value));
118 : 125 : }
119 : :
120 : : #if CHECKING_P
121 : :
122 : : namespace diagnostics {
123 : : namespace selftest {
124 : :
125 : : static void
126 : 4 : test_node_attrs ()
127 : : {
128 : 4 : digraphs::digraph g;
129 : 4 : digraphs::node n (g, "a");
130 : 4 : state_node_ref node_ref (n);
131 : :
132 : 4 : ASSERT_EQ (node_ref.get_node_kind (), node_kind::other);
133 : 4 : node_ref.set_node_kind (node_kind::stack);
134 : 4 : ASSERT_EQ (node_ref.get_node_kind (), node_kind::stack);
135 : :
136 : 4 : ASSERT_EQ (node_ref.get_dynalloc_state (), node_dynalloc_state::unknown);
137 : 4 : node_ref.set_dynalloc_state (node_dynalloc_state::freed);
138 : 4 : ASSERT_EQ (node_ref.get_dynalloc_state (), node_dynalloc_state::freed);
139 : :
140 : 4 : ASSERT_EQ (node_ref.get_type (), nullptr);
141 : 4 : node_ref.set_type ("const char *");
142 : 4 : ASSERT_STREQ (node_ref.get_type (), "const char *");
143 : 4 : }
144 : :
145 : : /* Run all of the selftests within this file. */
146 : :
147 : : void
148 : 4 : state_graphs_cc_tests ()
149 : : {
150 : 4 : test_node_attrs ();
151 : 4 : }
152 : :
153 : : } // namespace diagnostics::selftest
154 : : } // namespace diagnostics
155 : :
156 : : #endif /* CHECKING_P */
|