File: ReflectionContextInterface.h

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (152 lines) | stat: -rw-r--r-- 6,887 bytes parent folder | download
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
//===-- ReflectionContextInterface.h ----------------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_SwiftReflectionContextInterface_h_
#define liblldb_SwiftReflectionContextInterface_h_

#include <mutex>

#include "lldb/lldb-types.h"
#include "swift/ABI/ObjectFile.h"
#include "swift/Remote/RemoteAddress.h"
#include "swift/RemoteInspection/TypeRef.h"
#include <optional>
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Memory.h"
#include "LockGuarded.h"

namespace swift {
namespace Demangle {
class Demangler;
} // namespace Demangle
namespace reflection {
struct DescriptorFinder;
class RecordTypeInfo;
class TypeInfo;
} // namespace reflection
namespace remote {
class MemoryReader;
struct TypeInfoProvider;
} // namespace remote
} // namespace swift

namespace lldb_private {
struct SwiftMetadataCache;

/// Returned by \ref ForEachSuperClassType. Not every user of \p
/// ForEachSuperClassType needs all of these. By returning this
/// object we call into the runtime only when needed.
/// Using function objects to avoid instantiating ReflectionContext in this
/// header.
struct SuperClassType {
  std::function<const swift::reflection::RecordTypeInfo *()>
      get_record_type_info;
  std::function<const swift::reflection::TypeRef *()> get_typeref;
};

/// An abstract interface to swift::reflection::ReflectionContext
/// objects of varying pointer sizes.  This class encapsulates all
/// traffic to ReflectionContext and abstracts the detail that
/// ReflectionContext is a template that needs to be specialized for
/// a specific pointer width.
class ReflectionContextInterface {
public:
  /// Return a reflection context.
  static std::unique_ptr<ReflectionContextInterface> CreateReflectionContext(
      uint8_t pointer_size, std::shared_ptr<swift::remote::MemoryReader> reader,
      bool objc_interop, SwiftMetadataCache *swift_metadata_cache);

  virtual ~ReflectionContextInterface() = default;

  virtual std::optional<uint32_t> AddImage(
      llvm::function_ref<std::pair<swift::remote::RemoteRef<void>, uint64_t>(
          swift::ReflectionSectionKind)>
          find_section,
      llvm::SmallVector<llvm::StringRef, 1> likely_module_names = {}) = 0;
  virtual std::optional<uint32_t>
  AddImage(swift::remote::RemoteAddress image_start,
           llvm::SmallVector<llvm::StringRef, 1> likely_module_names = {}) = 0;
  virtual std::optional<uint32_t>
  ReadELF(swift::remote::RemoteAddress ImageStart,
          std::optional<llvm::sys::MemoryBlock> FileBuffer,
          llvm::SmallVector<llvm::StringRef, 1> likely_module_names = {}) = 0;
  virtual const swift::reflection::TypeRef *GetTypeRefOrNull(
      llvm::StringRef mangled_type_name,
      swift::reflection::DescriptorFinder *descriptor_finder) = 0;
  virtual const swift::reflection::TypeRef *GetTypeRefOrNull(
      swift::Demangle::Demangler &dem, swift::Demangle::NodePointer node,
      swift::reflection::DescriptorFinder *descriptor_finder) = 0;
  virtual const swift::reflection::TypeInfo *GetClassInstanceTypeInfo(
      const swift::reflection::TypeRef *type_ref,
      swift::remote::TypeInfoProvider *provider,
      swift::reflection::DescriptorFinder *descriptor_finder) = 0;
  virtual const swift::reflection::TypeInfo *
  GetTypeInfo(const swift::reflection::TypeRef *type_ref,
              swift::remote::TypeInfoProvider *provider,
              swift::reflection::DescriptorFinder *descriptor_finder) = 0;
  virtual const swift::reflection::TypeInfo *GetTypeInfoFromInstance(
      lldb::addr_t instance, swift::remote::TypeInfoProvider *provider,
      swift::reflection::DescriptorFinder *descriptor_finder) = 0;
  virtual swift::remote::MemoryReader &GetReader() = 0;
  virtual const swift::reflection::TypeRef *LookupSuperclass(
      const swift::reflection::TypeRef *tr,
      swift::reflection::DescriptorFinder *descriptor_finder) = 0;
  virtual bool
  ForEachSuperClassType(swift::remote::TypeInfoProvider *tip,
                        swift::reflection::DescriptorFinder *descriptor_finder,
                        lldb::addr_t pointer,
                        std::function<bool(SuperClassType)> fn) = 0;

  /// Traverses the superclass hierarchy using the typeref, as opposed to the
  /// other version of the function that uses the instance's pointer. This
  /// version is useful when reflection metadata has been stripped from the
  /// binary (for example, when debugging embedded Swift programs).
  virtual bool
  ForEachSuperClassType(swift::remote::TypeInfoProvider *tip,
                        swift::reflection::DescriptorFinder *descriptor_finder,
                        const swift::reflection::TypeRef *tr,
                        std::function<bool(SuperClassType)> fn) = 0;

  virtual std::optional<std::pair<const swift::reflection::TypeRef *,
                                  swift::remote::RemoteAddress>>
  ProjectExistentialAndUnwrapClass(
      swift::remote::RemoteAddress existential_addess,
      const swift::reflection::TypeRef &existential_tr,
      swift::reflection::DescriptorFinder *descriptor_finder) = 0;
  virtual std::optional<int32_t> ProjectEnumValue(
      swift::remote::RemoteAddress enum_addr,
      const swift::reflection::TypeRef *enum_type_ref,
      swift::remote::TypeInfoProvider *provider,
      swift::reflection::DescriptorFinder *descriptor_finder) = 0;
  virtual const swift::reflection::TypeRef *ReadTypeFromMetadata(
      lldb::addr_t metadata_address,
      swift::reflection::DescriptorFinder *descriptor_finder,
      bool skip_artificial_subclasses = false) = 0;
  virtual const swift::reflection::TypeRef *ReadTypeFromInstance(
      lldb::addr_t instance_address,
      swift::reflection::DescriptorFinder *descriptor_finder,
      bool skip_artificial_subclasses = false) = 0;
  virtual std::optional<bool> IsValueInlinedInExistentialContainer(
      swift::remote::RemoteAddress existential_address) = 0;
  virtual const swift::reflection::TypeRef *ApplySubstitutions(
      const swift::reflection::TypeRef *type_ref,
      swift::reflection::GenericArgumentMap substitutions,
      swift::reflection::DescriptorFinder *descriptor_finder) = 0;
  virtual swift::remote::RemoteAbsolutePointer
  StripSignedPointer(swift::remote::RemoteAbsolutePointer pointer) = 0;
};

using ThreadSafeReflectionContext = LockGuarded<ReflectionContextInterface>;
} // namespace lldb_private
#endif