206 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_OBJCLANGUAGE_H10#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_OBJCLANGUAGE_H11 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 20namespace lldb_private {21 22class ObjCLanguage : public Language {23 ClangHighlighter m_highlighter;24 25public:26 class ObjCMethodName {27 public:28 /// The static factory method for creating a ObjCMethodName.29 ///30 /// \param[in] name31 /// The name of the method.32 ///33 /// \param[in] strict34 /// Control whether or not the name parser is strict about +/- in the35 /// 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 ObjCMethodName.39 static std::optional<const ObjCMethodName> Create(llvm::StringRef name,40 bool strict);41 42 /// Determines if this method is a class method43 ///44 /// \return Returns true if the method is a class method. False otherwise.45 bool IsClassMethod() const { return m_type == eTypeClassMethod; }46 47 /// Determines if this method is an instance method48 ///49 /// \return Returns true if the method is an instance method. False50 /// otherwise.51 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 the56 /// selector name.57 ///58 /// \return The name of the method in the form of a const std::string59 /// reference.60 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 there70 /// 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 as89 /// `GetClassName`.90 ///91 /// \return A StringRef to the class name (including the category) of this92 /// 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 category101 /// 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 ObjCMethodName(llvm::StringRef name, Type type)116 : m_full(name.str()), m_type(type) {}117 118 const std::string m_full;119 Type m_type;120 };121 122 ObjCLanguage() = default;123 124 ~ObjCLanguage() override = default;125 126 lldb::LanguageType GetLanguageType() const override {127 return lldb::eLanguageTypeObjC;128 }129 130 llvm::StringRef GetUserEntryPointName() const override { return "main"; }131 132 // Get all possible names for a method. Examples:133 // If method_name is "+[NSString(my_additions) myStringWithCString:]"134 // variant_names[0] => "+[NSString myStringWithCString:]"135 // If name is specified without the leading '+' or '-' like136 // "[NSString(my_additions) myStringWithCString:]"137 // variant_names[0] => "+[NSString(my_additions) myStringWithCString:]"138 // variant_names[1] => "-[NSString(my_additions) myStringWithCString:]"139 // variant_names[2] => "+[NSString myStringWithCString:]"140 // variant_names[3] => "-[NSString myStringWithCString:]"141 // Also returns the FunctionNameType of each possible name.142 std::vector<Language::MethodNameVariant>143 GetMethodNameVariants(ConstString method_name) const override;144 145 std::pair<lldb::FunctionNameType, std::optional<ConstString>>146 GetFunctionNameInfo(ConstString name) const override;147 148 bool SymbolNameFitsToLanguage(const Mangled &mangled) const override;149 150 lldb::TypeCategoryImplSP GetFormatters() override;151 152 std::vector<FormattersMatchCandidate>153 GetPossibleFormattersMatches(ValueObject &valobj,154 lldb::DynamicValueType use_dynamic) override;155 156 std::unique_ptr<TypeScavenger> GetTypeScavenger() override;157 158 std::pair<llvm::StringRef, llvm::StringRef>159 GetFormatterPrefixSuffix(llvm::StringRef type_hint) override;160 161 bool IsNilReference(ValueObject &valobj) override;162 163 llvm::StringRef GetNilReferenceSummaryString() override { return "nil"; }164 165 bool IsSourceFile(llvm::StringRef file_path) const override;166 167 const Highlighter *GetHighlighter() const override { return &m_highlighter; }168 169 // Static Functions170 static void Initialize();171 172 static void Terminate();173 174 static lldb_private::Language *CreateInstance(lldb::LanguageType language);175 176 static llvm::StringRef GetPluginNameStatic() { return "objc"; }177 178 static bool IsPossibleObjCMethodName(llvm::StringRef name);179 180 static bool IsPossibleObjCSelector(const char *name) {181 if (!name)182 return false;183 184 if (strchr(name, ':') == nullptr)185 return true;186 else if (name[strlen(name) - 1] == ':')187 return true;188 else189 return false;190 }191 192 llvm::StringRef GetInstanceVariableName() override { return "self"; }193 194 virtual std::optional<bool>195 GetBooleanFromString(llvm::StringRef str) const override;196 197 bool SupportsExceptionBreakpointsOnThrow() const override { return true; }198 199 // PluginInterface protocol200 llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }201};202 203} // namespace lldb_private204 205#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_OBJCLANGUAGE_H206