Branch data Line data Source code
1 : : /* Logical location support, without knowledge of "tree".
2 : : Copyright (C) 2022-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 under
8 : : the terms of the GNU General Public License as published by the Free
9 : : Software Foundation; either version 3, or (at your option) any later
10 : : version.
11 : :
12 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : : 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_LOGICAL_LOCATION_H
22 : : #define GCC_LOGICAL_LOCATION_H
23 : :
24 : : #include "label-text.h"
25 : :
26 : : /* An enum for discriminating between different kinds of logical location
27 : : for a diagnostic.
28 : :
29 : : Roughly corresponds to logicalLocation's "kind" property in SARIF v2.1.0
30 : : (section 3.33.7). */
31 : :
32 : : enum class logical_location_kind
33 : : {
34 : : unknown,
35 : :
36 : : /* Kinds within executable code. */
37 : : function,
38 : : member,
39 : : module_,
40 : : namespace_,
41 : : type,
42 : : return_type,
43 : : parameter,
44 : : variable,
45 : :
46 : : /* Kinds within XML or HTML documents. */
47 : : element,
48 : : attribute,
49 : : text,
50 : : comment,
51 : : processing_instruction,
52 : : dtd,
53 : : declaration,
54 : :
55 : : /* Kinds within JSON documents. */
56 : : object,
57 : : array,
58 : : property,
59 : : value
60 : : };
61 : :
62 : : /* We want to efficiently support passing around logical locations in the
63 : : diagnostics subsystem, such as:
64 : : - "within function 'foo'", or
65 : : - "within method 'bar'"
66 : :
67 : : However we want to do this *without* requiring knowledge of trees (or of
68 : : libgdiagnostics internals), and without requiring heap allocation of an
69 : : interface class when emitting a diagnostic.
70 : :
71 : : To do this, we split the implementation into logical_location, which is
72 : : a wrapper around a (const void *), and logical_location_manager which
73 : : is provided by the client and has vfunc hooks for interpreting
74 : : logical_location instances.
75 : :
76 : : Every logical_location is associated with a logical_location_manager and
77 : : only has meaning in relation to that manager.
78 : :
79 : : A "nullptr" within a logical_location means "no logical location".
80 : :
81 : : See tree-logical-location.h for concrete subclasses relating to trees,
82 : : where the pointer is a const_tree.
83 : :
84 : : See selftest-logical-location.h for a concrete subclass for selftests. */
85 : :
86 : : /* Abstract base class for giving meaning to logical_location values.
87 : : Typically there will just be one client-provided instance, of a
88 : : client-specific subclass. */
89 : :
90 : 341178 : class logical_location_manager
91 : : {
92 : : public:
93 : : /* Extrinsic state for identifying a specific logical location.
94 : : This will be our logical_location type.
95 : : This only makes sense with respect to a specific manager.
96 : : e.g. for a tree-based one it's a wrapper around "tree".
97 : : "nullptr" means "no logical location". */
98 : : class key
99 : : {
100 : : public:
101 : 877 : key () : m_ptr (nullptr) {}
102 : :
103 : 110124 : static key from_ptr (const void *ptr)
104 : : {
105 : 110124 : return key (ptr);
106 : : }
107 : :
108 : 8157 : operator bool () const
109 : : {
110 : 8157 : return m_ptr != nullptr;
111 : : }
112 : :
113 : : template <typename T>
114 : : T cast_to () const { return static_cast<T> (m_ptr); }
115 : :
116 : : bool
117 : 6240 : operator== (const key &other) const
118 : : {
119 : 6240 : return m_ptr == other.m_ptr;
120 : : }
121 : :
122 : : bool
123 : 85 : operator!= (const key &other) const
124 : : {
125 : 85 : return m_ptr != other.m_ptr;
126 : : }
127 : :
128 : : bool
129 : : operator< (const key &other) const
130 : : {
131 : : return m_ptr < other.m_ptr;
132 : : }
133 : :
134 : : private:
135 : 110052 : explicit key (const void *ptr) : m_ptr (ptr) {}
136 : :
137 : : const void *m_ptr;
138 : : };
139 : :
140 : 1664 : virtual ~logical_location_manager () {}
141 : :
142 : : /* vfuncs for interpreting logical_location values. */
143 : :
144 : : /* Get a string (or NULL) for K suitable for use by the SARIF logicalLocation
145 : : "name" property (SARIF v2.1.0 section 3.33.4). */
146 : : virtual const char *get_short_name (key k) const = 0;
147 : :
148 : : /* Get a string (or NULL) for K suitable for use by the SARIF logicalLocation
149 : : "fullyQualifiedName" property (SARIF v2.1.0 section 3.33.5). */
150 : : virtual const char *get_name_with_scope (key k) const = 0;
151 : :
152 : : /* Get a string (or NULL) for K suitable for use by the SARIF logicalLocation
153 : : "decoratedName" property (SARIF v2.1.0 section 3.33.6). */
154 : : virtual const char *get_internal_name (key k) const = 0;
155 : :
156 : : /* Get what kind of SARIF logicalLocation K is (if any). */
157 : : virtual enum logical_location_kind get_kind (key k) const = 0;
158 : :
159 : : /* Get a string for location K in a form suitable for path output. */
160 : : virtual label_text get_name_for_path_output (key k) const = 0;
161 : :
162 : : /* Get the parent logical_logical of K, if any, or nullptr. */
163 : : virtual key get_parent (key k) const = 0;
164 : :
165 : : bool function_p (key k) const;
166 : : };
167 : :
168 : : /* A logical location is a key for a given logical_location_manager.
169 : :
170 : : Note that there is no integration with GCC's garbage collector and thus
171 : : logical_location instances can't be long-lived. */
172 : :
173 : : typedef logical_location_manager::key logical_location;
174 : :
175 : : #endif /* GCC_LOGICAL_LOCATION_H. */
|