aboutsummaryrefslogtreecommitdiff
path: root/gcc/logical-location.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/logical-location.h')
-rw-r--r--gcc/logical-location.h135
1 files changed, 115 insertions, 20 deletions
diff --git a/gcc/logical-location.h b/gcc/logical-location.h
index 000335c..dba9dc4 100644
--- a/gcc/logical-location.h
+++ b/gcc/logical-location.h
@@ -33,6 +33,7 @@ enum logical_location_kind
{
LOGICAL_LOCATION_KIND_UNKNOWN,
+ /* Kinds within executable code. */
LOGICAL_LOCATION_KIND_FUNCTION,
LOGICAL_LOCATION_KIND_MEMBER,
LOGICAL_LOCATION_KIND_MODULE,
@@ -40,41 +41,135 @@ enum logical_location_kind
LOGICAL_LOCATION_KIND_TYPE,
LOGICAL_LOCATION_KIND_RETURN_TYPE,
LOGICAL_LOCATION_KIND_PARAMETER,
- LOGICAL_LOCATION_KIND_VARIABLE
+ LOGICAL_LOCATION_KIND_VARIABLE,
+
+ /* Kinds within XML or HTML documents. */
+ LOGICAL_LOCATION_KIND_ELEMENT,
+ LOGICAL_LOCATION_KIND_ATTRIBUTE,
+ LOGICAL_LOCATION_KIND_TEXT,
+ LOGICAL_LOCATION_KIND_COMMENT,
+ LOGICAL_LOCATION_KIND_PROCESSING_INSTRUCTION,
+ LOGICAL_LOCATION_KIND_DTD,
+ LOGICAL_LOCATION_KIND_DECLARATION,
+
+ /* Kinds within JSON documents. */
+ LOGICAL_LOCATION_KIND_OBJECT,
+ LOGICAL_LOCATION_KIND_ARRAY,
+ LOGICAL_LOCATION_KIND_PROPERTY,
+ LOGICAL_LOCATION_KIND_VALUE
};
-/* Abstract base class for passing around logical locations in the
+/* We want to efficiently support passing around logical locations in the
diagnostics subsystem, such as:
- "within function 'foo'", or
- - "within method 'bar'",
- but *without* requiring knowledge of trees
- (see tree-logical-location.h for concrete subclasses relating to trees,
- and selftest-logical-location.h for a concrete subclass for selftests). */
+ - "within method 'bar'"
-class logical_location
+ 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_location, which is
+ a wrapper around a (const void *), and logical_location_manager which
+ is provided by the client and has vfunc hooks for interpreting
+ logical_location instances.
+
+ Every logical_location is associated with a logical_location_manager and
+ only has meaning in relation to that manager.
+
+ A "nullptr" within a logical_location means "no logical location".
+
+ See tree-logical-location.h for concrete subclasses relating to trees,
+ where the pointer is a const_tree.
+
+ See selftest-logical-location.h for a concrete subclass for selftests. */
+
+/* Abstract base class for giving meaning to logical_location values.
+ Typically there will just be one client-provided instance, of a
+ client-specific subclass. */
+
+class logical_location_manager
{
public:
- virtual ~logical_location () {}
-
- /* Get a string (or NULL) suitable for use by the SARIF logicalLocation
+ /* 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". */
+ 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;
+ };
+
+ virtual ~logical_location_manager () {}
+
+ /* vfuncs for interpreting logical_location values. */
+
+ /* 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 () const = 0;
+ virtual const char *get_short_name (key k) const = 0;
- /* Get a string (or NULL) suitable for use by the SARIF logicalLocation
+ /* 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 () const = 0;
+ virtual const char *get_name_with_scope (key k) const = 0;
- /* Get a string (or NULL) suitable for use by the SARIF logicalLocation
+ /* 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 () const = 0;
+ virtual const char *get_internal_name (key k) const = 0;
+
+ /* Get what kind of SARIF logicalLocation K is (if any). */
+ virtual enum logical_location_kind get_kind (key k) const = 0;
- /* Get what kind of SARIF logicalLocation this is (if any). */
- virtual enum logical_location_kind get_kind () 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 a string for this location in a form suitable for path output. */
- virtual label_text get_name_for_path_output () const = 0;
+ /* Get the parent logical_logical of K, if any, or nullptr. */
+ virtual key get_parent (key k) const = 0;
- bool function_p () const;
+ bool function_p (key k) const;
};
+/* A logical location is a key for a given logical_location_manager.
+
+ Note that there is no integration with GCC's garbage collector and thus
+ logical_location instances can't be long-lived. */
+
+typedef logical_location_manager::key logical_location;
+
#endif /* GCC_LOGICAL_LOCATION_H. */