Coverage Report

Created: 2023-09-30 09:22

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
Line
Count
Source (jump to first uncovered line)
1
//===-- ObjCLanguage.h ------------------------------------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_OBJCLANGUAGE_H
10
#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_OBJCLANGUAGE_H
11
12
#include <cstring>
13
#include <vector>
14
15
#include "Plugins/Language/ClangCommon/ClangHighlighter.h"
16
#include "lldb/Target/Language.h"
17
#include "lldb/Utility/ConstString.h"
18
#include "lldb/lldb-private.h"
19
20
namespace lldb_private {
21
22
class ObjCLanguage : public Language {
23
  ClangHighlighter m_highlighter;
24
25
public:
26
  class MethodName {
27
  public:
28
    /// The static factory method for creating a MethodName.
29
    ///
30
    /// \param[in] name
31
    ///   The name of the method.
32
    ///
33
    /// \param[in] strict
34
    ///   Control whether or not the name parser is strict about +/- in the
35
    ///   front of the name.
36
    ///
37
    /// \return If the name failed to parse as a valid Objective-C method name,
38
    /// returns std::nullopt. Otherwise returns a const MethodName.
39
    static std::optional<const MethodName> Create(llvm::StringRef name,
40
                                                  bool strict);
41
42
    /// Determines if this method is a class method
43
    ///
44
    /// \return Returns true if the method is a class method. False otherwise.
45
6.48M
    bool IsClassMethod() const { return m_type == eTypeClassMethod; }
46
47
    /// Determines if this method is an instance method
48
    ///
49
    /// \return Returns true if the method is an instance method. False
50
    /// otherwise.
51
5.58M
    bool IsInstanceMethod() const { return m_type == eTypeInstanceMethod; }
52
53
    /// Returns the full name of the method.
54
    ///
55
    /// This includes the class name, the category name (if applicable), and the
56
    /// selector name.
57
    ///
58
    /// \return The name of the method in the form of a const std::string
59
    /// reference.
60
8
    const std::string &GetFullName() const { return m_full; }
61
62
    /// Creates a variation of this method without the category.
63
    /// If this method has no category, it returns an empty string.
64
    ///
65
    /// Example:
66
    ///   Full name: "+[NSString(my_additions) myStringWithCString:]"
67
    ///   becomes "+[NSString myStringWithCString:]"
68
    ///
69
    /// \return The method name without the category or an empty string if there
70
    /// was no category to begin with.
71
    std::string GetFullNameWithoutCategory() const;
72
73
    /// Returns a reference to the class name.
74
    ///
75
    /// Example:
76
    ///   Full name: "+[NSString(my_additions) myStringWithCString:]"
77
    ///   will give you "NSString"
78
    ///
79
    /// \return A StringRef to the class name of this method.
80
    llvm::StringRef GetClassName() const;
81
82
    /// Returns a reference to the class name with the category.
83
    ///
84
    /// Example:
85
    ///   Full name: "+[NSString(my_additions) myStringWithCString:]"
86
    ///   will give you "NSString(my_additions)"
87
    ///
88
    /// Note: If your method has no category, this will give the same output as
89
    /// `GetClassName`.
90
    ///
91
    /// \return A StringRef to the class name (including the category) of this
92
    /// method. If there was no category, returns the same as `GetClassName`.
93
    llvm::StringRef GetClassNameWithCategory() const;
94
95
    /// Returns a reference to the category name.
96
    ///
97
    /// Example:
98
    ///   Full name: "+[NSString(my_additions) myStringWithCString:]"
99
    ///   will give you "my_additions"
100
    /// \return A StringRef to the category name of this method. If no category
101
    /// is present, the StringRef is empty.
102
    llvm::StringRef GetCategory() const;
103
104
    /// Returns a reference to the selector name.
105
    ///
106
    /// Example:
107
    ///   Full name: "+[NSString(my_additions) myStringWithCString:]"
108
    ///   will give you "myStringWithCString:"
109
    /// \return A StringRef to the selector of this method.
110
    llvm::StringRef GetSelector() const;
111
112
  protected:
113
    enum Type { eTypeUnspecified, eTypeClassMethod, eTypeInstanceMethod };
114
115
    MethodName(llvm::StringRef name, Type type)
116
6.49M
        : m_full(name.str()), m_type(type) {}
117
118
    const std::string m_full;
119
    Type m_type;
120
  };
121
122
1.13k
  ObjCLanguage() = default;
123
124
0
  ~ObjCLanguage() override = default;
125
126
370k
  lldb::LanguageType GetLanguageType() const override {
127
370k
    return lldb::eLanguageTypeObjC;
128
370k
  }
129
130
  // Get all possible names for a method. Examples:
131
  // If method_name is "+[NSString(my_additions) myStringWithCString:]"
132
  //   variant_names[0] => "+[NSString myStringWithCString:]"
133
  // If name is specified without the leading '+' or '-' like
134
  // "[NSString(my_additions) myStringWithCString:]"
135
  //  variant_names[0] => "+[NSString(my_additions) myStringWithCString:]"
136
  //  variant_names[1] => "-[NSString(my_additions) myStringWithCString:]"
137
  //  variant_names[2] => "+[NSString myStringWithCString:]"
138
  //  variant_names[3] => "-[NSString myStringWithCString:]"
139
  // Also returns the FunctionNameType of each possible name.
140
  std::vector<Language::MethodNameVariant>
141
  GetMethodNameVariants(ConstString method_name) const override;
142
143
  bool SymbolNameFitsToLanguage(Mangled mangled) const override;
144
145
  lldb::TypeCategoryImplSP GetFormatters() override;
146
147
  std::vector<FormattersMatchCandidate>
148
  GetPossibleFormattersMatches(ValueObject &valobj,
149
                               lldb::DynamicValueType use_dynamic) override;
150
151
  std::unique_ptr<TypeScavenger> GetTypeScavenger() override;
152
153
  std::pair<llvm::StringRef, llvm::StringRef>
154
  GetFormatterPrefixSuffix(llvm::StringRef type_hint) override;
155
156
  bool IsNilReference(ValueObject &valobj) override;
157
158
34
  llvm::StringRef GetNilReferenceSummaryString() override { return "nil"; }
159
160
  bool IsSourceFile(llvm::StringRef file_path) const override;
161
162
1.54k
  const Highlighter *GetHighlighter() const override { return &m_highlighter; }
163
164
  // Static Functions
165
  static void Initialize();
166
167
  static void Terminate();
168
169
  static lldb_private::Language *CreateInstance(lldb::LanguageType language);
170
171
4.66k
  static llvm::StringRef GetPluginNameStatic() { return "objc"; }
172
173
179k
  static bool IsPossibleObjCMethodName(const char *name) {
174
179k
    if (!name)
175
0
      return false;
176
179k
    bool starts_right = (name[0] == '+' || 
name[0] == '-'173k
) &&
name[1] == '['44.2k
;
177
179k
    bool ends_right = (name[strlen(name) - 1] == ']');
178
179k
    return (starts_right && 
ends_right44.2k
);
179
179k
  }
180
181
14.0k
  static bool IsPossibleObjCSelector(const char *name) {
182
14.0k
    if (!name)
183
0
      return false;
184
185
14.0k
    if (strchr(name, ':') == nullptr)
186
6.16k
      return true;
187
7.92k
    else if (name[strlen(name) - 1] == ':')
188
6.80k
      return true;
189
1.12k
    else
190
1.12k
      return false;
191
14.0k
  }
192
193
8
  llvm::StringRef GetInstanceVariableName() override { return "self"; }
194
195
  // PluginInterface protocol
196
703
  llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
197
};
198
199
} // namespace lldb_private
200
201
#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_OBJCLANGUAGE_H