diff options
Diffstat (limited to 'gcc/diagnostics/logical-locations.h')
-rw-r--r-- | gcc/diagnostics/logical-locations.h | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/gcc/diagnostics/logical-locations.h b/gcc/diagnostics/logical-locations.h new file mode 100644 index 0000000..b52a9b4 --- /dev/null +++ b/gcc/diagnostics/logical-locations.h @@ -0,0 +1,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. */ |