1 //===-- ObjCLanguage.h ------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef liblldb_ObjCLanguage_h_
11 #define liblldb_ObjCLanguage_h_
12 
13 // C Includes
14 // C++ Includes
15 #include <cstring>
16 #include <vector>
17 
18 // Other libraries and framework includes
19 // Project includes
20 #include "lldb/Core/ConstString.h"
21 #include "lldb/Target/Language.h"
22 #include "lldb/lldb-private.h"
23 
24 namespace lldb_private {
25 
26 class ObjCLanguage : public Language {
27 public:
28   class MethodName {
29   public:
30     enum Type { eTypeUnspecified, eTypeClassMethod, eTypeInstanceMethod };
31 
32     MethodName()
33         : m_full(), m_class(), m_category(), m_selector(),
34           m_type(eTypeUnspecified), m_category_is_valid(false) {}
35 
36     MethodName(const char *name, bool strict)
37         : m_full(), m_class(), m_category(), m_selector(),
38           m_type(eTypeUnspecified), m_category_is_valid(false) {
39       SetName(name, strict);
40     }
41     MethodName(llvm::StringRef name, bool strict)
42         : m_full(), m_class(), m_category(), m_selector(),
43           m_type(eTypeUnspecified), m_category_is_valid(false) {
44       SetName(name, strict);
45     }
46 
47     void Clear();
48 
49     bool IsValid(bool strict) const {
50       // If "strict" is true, the name must have everything specified including
51       // the leading "+" or "-" on the method name
52       if (strict && m_type == eTypeUnspecified)
53         return false;
54       // Other than that, m_full will only be filled in if the objective C
55       // name is valid.
56       return (bool)m_full;
57     }
58 
59     bool HasCategory() { return !GetCategory().IsEmpty(); }
60 
61     Type GetType() const { return m_type; }
62 
63     const ConstString &GetFullName() const { return m_full; }
64 
65     ConstString GetFullNameWithoutCategory(bool empty_if_no_category);
66 
67     bool SetName(const char *name, bool strict);
68     bool SetName(llvm::StringRef name, bool strict);
69 
70     const ConstString &GetClassName();
71 
72     const ConstString &GetClassNameWithCategory();
73 
74     const ConstString &GetCategory();
75 
76     const ConstString &GetSelector();
77 
78     // Get all possible names for a method. Examples:
79     // If name is "+[NSString(my_additions) myStringWithCString:]"
80     //  names[0] => "+[NSString(my_additions) myStringWithCString:]"
81     //  names[1] => "+[NSString myStringWithCString:]"
82     // If name is specified without the leading '+' or '-' like
83     // "[NSString(my_additions) myStringWithCString:]"
84     //  names[0] => "+[NSString(my_additions) myStringWithCString:]"
85     //  names[1] => "-[NSString(my_additions) myStringWithCString:]"
86     //  names[2] => "+[NSString myStringWithCString:]"
87     //  names[3] => "-[NSString myStringWithCString:]"
88     size_t GetFullNames(std::vector<ConstString> &names, bool append);
89 
90   protected:
91     ConstString
92         m_full; // Full name:   "+[NSString(my_additions) myStringWithCString:]"
93     ConstString m_class; // Class name:  "NSString"
94     ConstString
95         m_class_category;   // Class with category: "NSString(my_additions)"
96     ConstString m_category; // Category:    "my_additions"
97     ConstString m_selector; // Selector:    "myStringWithCString:"
98     Type m_type;
99     bool m_category_is_valid;
100   };
101 
102   ObjCLanguage() = default;
103 
104   ~ObjCLanguage() override = default;
105 
106   lldb::LanguageType GetLanguageType() const override {
107     return lldb::eLanguageTypeObjC;
108   }
109 
110   lldb::TypeCategoryImplSP GetFormatters() override;
111 
112   std::vector<ConstString>
113   GetPossibleFormattersMatches(ValueObject &valobj,
114                                lldb::DynamicValueType use_dynamic) override;
115 
116   std::unique_ptr<TypeScavenger> GetTypeScavenger() override;
117 
118   bool GetFormatterPrefixSuffix(ValueObject &valobj, ConstString type_hint,
119                                 std::string &prefix,
120                                 std::string &suffix) override;
121 
122   bool IsNilReference(ValueObject &valobj) override;
123 
124   //------------------------------------------------------------------
125   // Static Functions
126   //------------------------------------------------------------------
127   static void Initialize();
128 
129   static void Terminate();
130 
131   static lldb_private::Language *CreateInstance(lldb::LanguageType language);
132 
133   static lldb_private::ConstString GetPluginNameStatic();
134 
135   static bool IsPossibleObjCMethodName(const char *name) {
136     if (!name)
137       return false;
138     bool starts_right = (name[0] == '+' || name[0] == '-') && name[1] == '[';
139     bool ends_right = (name[strlen(name) - 1] == ']');
140     return (starts_right && ends_right);
141   }
142 
143   static bool IsPossibleObjCSelector(const char *name) {
144     if (!name)
145       return false;
146 
147     if (strchr(name, ':') == nullptr)
148       return true;
149     else if (name[strlen(name) - 1] == ':')
150       return true;
151     else
152       return false;
153   }
154 
155   //------------------------------------------------------------------
156   // PluginInterface protocol
157   //------------------------------------------------------------------
158   ConstString GetPluginName() override;
159 
160   uint32_t GetPluginVersion() override;
161 };
162 
163 } // namespace lldb_private
164 
165 #endif // liblldb_ObjCLanguage_h_
166