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