1292932Sdim//===-- ObjCLanguage.h ------------------------------------------*- C++ -*-===// 2292932Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6292932Sdim// 7292932Sdim//===----------------------------------------------------------------------===// 8292932Sdim 9292932Sdim#ifndef liblldb_ObjCLanguage_h_ 10292932Sdim#define liblldb_ObjCLanguage_h_ 11292932Sdim 12309124Sdim#include <cstring> 13292932Sdim#include <vector> 14292932Sdim 15344779Sdim#include "Plugins/Language/ClangCommon/ClangHighlighter.h" 16292932Sdim#include "lldb/Target/Language.h" 17321369Sdim#include "lldb/Utility/ConstString.h" 18314564Sdim#include "lldb/lldb-private.h" 19292932Sdim 20292932Sdimnamespace lldb_private { 21314564Sdim 22314564Sdimclass ObjCLanguage : public Language { 23344779Sdim ClangHighlighter m_highlighter; 24344779Sdim 25292932Sdimpublic: 26314564Sdim class MethodName { 27314564Sdim public: 28314564Sdim enum Type { eTypeUnspecified, eTypeClassMethod, eTypeInstanceMethod }; 29292932Sdim 30314564Sdim MethodName() 31314564Sdim : m_full(), m_class(), m_category(), m_selector(), 32314564Sdim m_type(eTypeUnspecified), m_category_is_valid(false) {} 33292932Sdim 34314564Sdim MethodName(const char *name, bool strict) 35314564Sdim : m_full(), m_class(), m_category(), m_selector(), 36314564Sdim m_type(eTypeUnspecified), m_category_is_valid(false) { 37314564Sdim SetName(name, strict); 38314564Sdim } 39314564Sdim MethodName(llvm::StringRef name, bool strict) 40314564Sdim : m_full(), m_class(), m_category(), m_selector(), 41314564Sdim m_type(eTypeUnspecified), m_category_is_valid(false) { 42314564Sdim SetName(name, strict); 43314564Sdim } 44292932Sdim 45314564Sdim void Clear(); 46292932Sdim 47314564Sdim bool IsValid(bool strict) const { 48314564Sdim // If "strict" is true, the name must have everything specified including 49314564Sdim // the leading "+" or "-" on the method name 50314564Sdim if (strict && m_type == eTypeUnspecified) 51314564Sdim return false; 52314564Sdim // Other than that, m_full will only be filled in if the objective C 53314564Sdim // name is valid. 54314564Sdim return (bool)m_full; 55314564Sdim } 56292932Sdim 57314564Sdim bool HasCategory() { return !GetCategory().IsEmpty(); } 58292932Sdim 59314564Sdim Type GetType() const { return m_type; } 60292932Sdim 61353358Sdim ConstString GetFullName() const { return m_full; } 62292932Sdim 63314564Sdim ConstString GetFullNameWithoutCategory(bool empty_if_no_category); 64292932Sdim 65314564Sdim bool SetName(const char *name, bool strict); 66314564Sdim bool SetName(llvm::StringRef name, bool strict); 67292932Sdim 68353358Sdim ConstString GetClassName(); 69292932Sdim 70353358Sdim ConstString GetClassNameWithCategory(); 71292932Sdim 72353358Sdim ConstString GetCategory(); 73292932Sdim 74353358Sdim ConstString GetSelector(); 75314564Sdim 76314564Sdim protected: 77292932Sdim ConstString 78314564Sdim m_full; // Full name: "+[NSString(my_additions) myStringWithCString:]" 79314564Sdim ConstString m_class; // Class name: "NSString" 80314564Sdim ConstString 81314564Sdim m_class_category; // Class with category: "NSString(my_additions)" 82314564Sdim ConstString m_category; // Category: "my_additions" 83314564Sdim ConstString m_selector; // Selector: "myStringWithCString:" 84314564Sdim Type m_type; 85314564Sdim bool m_category_is_valid; 86314564Sdim }; 87314564Sdim 88314564Sdim ObjCLanguage() = default; 89314564Sdim 90314564Sdim ~ObjCLanguage() override = default; 91314564Sdim 92314564Sdim lldb::LanguageType GetLanguageType() const override { 93314564Sdim return lldb::eLanguageTypeObjC; 94314564Sdim } 95314564Sdim 96353358Sdim // Get all possible names for a method. Examples: 97353358Sdim // If method_name is "+[NSString(my_additions) myStringWithCString:]" 98353358Sdim // variant_names[0] => "+[NSString myStringWithCString:]" 99353358Sdim // If name is specified without the leading '+' or '-' like 100353358Sdim // "[NSString(my_additions) myStringWithCString:]" 101353358Sdim // variant_names[0] => "+[NSString(my_additions) myStringWithCString:]" 102353358Sdim // variant_names[1] => "-[NSString(my_additions) myStringWithCString:]" 103353358Sdim // variant_names[2] => "+[NSString myStringWithCString:]" 104353358Sdim // variant_names[3] => "-[NSString myStringWithCString:]" 105353358Sdim std::vector<ConstString> 106353358Sdim GetMethodNameVariants(ConstString method_name) const override; 107353358Sdim 108314564Sdim lldb::TypeCategoryImplSP GetFormatters() override; 109314564Sdim 110314564Sdim std::vector<ConstString> 111314564Sdim GetPossibleFormattersMatches(ValueObject &valobj, 112314564Sdim lldb::DynamicValueType use_dynamic) override; 113314564Sdim 114314564Sdim std::unique_ptr<TypeScavenger> GetTypeScavenger() override; 115314564Sdim 116314564Sdim bool GetFormatterPrefixSuffix(ValueObject &valobj, ConstString type_hint, 117314564Sdim std::string &prefix, 118314564Sdim std::string &suffix) override; 119314564Sdim 120314564Sdim bool IsNilReference(ValueObject &valobj) override; 121314564Sdim 122344779Sdim bool IsSourceFile(llvm::StringRef file_path) const override; 123344779Sdim 124344779Sdim const Highlighter *GetHighlighter() const override { return &m_highlighter; } 125344779Sdim 126314564Sdim // Static Functions 127314564Sdim static void Initialize(); 128314564Sdim 129314564Sdim static void Terminate(); 130314564Sdim 131314564Sdim static lldb_private::Language *CreateInstance(lldb::LanguageType language); 132314564Sdim 133314564Sdim static lldb_private::ConstString GetPluginNameStatic(); 134314564Sdim 135314564Sdim static bool IsPossibleObjCMethodName(const char *name) { 136314564Sdim if (!name) 137314564Sdim return false; 138314564Sdim bool starts_right = (name[0] == '+' || name[0] == '-') && name[1] == '['; 139314564Sdim bool ends_right = (name[strlen(name) - 1] == ']'); 140314564Sdim return (starts_right && ends_right); 141314564Sdim } 142314564Sdim 143314564Sdim static bool IsPossibleObjCSelector(const char *name) { 144314564Sdim if (!name) 145314564Sdim return false; 146314564Sdim 147314564Sdim if (strchr(name, ':') == nullptr) 148314564Sdim return true; 149314564Sdim else if (name[strlen(name) - 1] == ':') 150314564Sdim return true; 151314564Sdim else 152314564Sdim return false; 153314564Sdim } 154314564Sdim 155314564Sdim // PluginInterface protocol 156314564Sdim ConstString GetPluginName() override; 157314564Sdim 158314564Sdim uint32_t GetPluginVersion() override; 159292932Sdim}; 160314564Sdim 161292932Sdim} // namespace lldb_private 162292932Sdim 163292932Sdim#endif // liblldb_ObjCLanguage_h_ 164