| /* 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. */ |