This revision was automatically updated to reflect the committed changes.
bulbazord marked an inline comment as done.
Closed by commit rG915256388f86: [lldb] Refactor ObjCLanguage::MethodName 
(authored by bulbazord).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D149914/new/

https://reviews.llvm.org/D149914

Files:
  lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
  lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
  lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
  lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
  lldb/unittests/Language/ObjC/ObjCLanguageTest.cpp

Index: lldb/unittests/Language/ObjC/ObjCLanguageTest.cpp
===================================================================
--- lldb/unittests/Language/ObjC/ObjCLanguageTest.cpp
+++ lldb/unittests/Language/ObjC/ObjCLanguageTest.cpp
@@ -42,53 +42,51 @@
 
   // First, be strict
   for (const auto &test : strict_cases) {
-    ObjCLanguage::MethodName method(test.input, /*strict = */ true);
-    EXPECT_TRUE(method.IsValid(/*strict = */ true));
-    EXPECT_EQ(
-        test.full_name_sans_category,
-        method.GetFullNameWithoutCategory(/*empty_if_no_category = */ true)
-            .GetStringRef());
-    EXPECT_EQ(test.class_name, method.GetClassName().GetStringRef());
+    std::optional<const ObjCLanguage::MethodName> method =
+        ObjCLanguage::MethodName::Create(test.input, /*strict = */ true);
+    EXPECT_TRUE(method.has_value());
+    EXPECT_EQ(test.full_name_sans_category,
+              method->GetFullNameWithoutCategory());
+    EXPECT_EQ(test.class_name, method->GetClassName());
     EXPECT_EQ(test.class_name_with_category,
-              method.GetClassNameWithCategory().GetStringRef());
-    EXPECT_EQ(test.category, method.GetCategory().GetStringRef());
-    EXPECT_EQ(test.selector, method.GetSelector().GetStringRef());
+              method->GetClassNameWithCategory());
+    EXPECT_EQ(test.category, method->GetCategory());
+    EXPECT_EQ(test.selector, method->GetSelector());
   }
 
   // We should make sure strict parsing does not accept lax cases
   for (const auto &test : lax_cases) {
-    ObjCLanguage::MethodName method(test.input, /*strict = */ true);
-    EXPECT_FALSE(method.IsValid(/*strict = */ true));
+    std::optional<const ObjCLanguage::MethodName> method =
+        ObjCLanguage::MethodName::Create(test.input, /*strict = */ true);
+    EXPECT_FALSE(method.has_value());
   }
 
   // All strict cases should work when not lax
   for (const auto &test : strict_cases) {
-    ObjCLanguage::MethodName method(test.input, /*strict = */ false);
-    EXPECT_TRUE(method.IsValid(/*strict = */ false));
-    EXPECT_EQ(
-        test.full_name_sans_category,
-        method.GetFullNameWithoutCategory(/*empty_if_no_category = */ true)
-            .GetStringRef());
-    EXPECT_EQ(test.class_name, method.GetClassName().GetStringRef());
+    std::optional<const ObjCLanguage::MethodName> method =
+        ObjCLanguage::MethodName::Create(test.input, /*strict = */ false);
+    EXPECT_TRUE(method.has_value());
+    EXPECT_EQ(test.full_name_sans_category,
+              method->GetFullNameWithoutCategory());
+    EXPECT_EQ(test.class_name, method->GetClassName());
     EXPECT_EQ(test.class_name_with_category,
-              method.GetClassNameWithCategory().GetStringRef());
-    EXPECT_EQ(test.category, method.GetCategory().GetStringRef());
-    EXPECT_EQ(test.selector, method.GetSelector().GetStringRef());
+              method->GetClassNameWithCategory());
+    EXPECT_EQ(test.category, method->GetCategory());
+    EXPECT_EQ(test.selector, method->GetSelector());
   }
 
   // Make sure non-strict parsing works
   for (const auto &test : lax_cases) {
-    ObjCLanguage::MethodName method(test.input, /*strict = */ false);
-    EXPECT_TRUE(method.IsValid(/*strict = */ false));
-    EXPECT_EQ(
-        test.full_name_sans_category,
-        method.GetFullNameWithoutCategory(/*empty_if_no_category = */ true)
-            .GetStringRef());
-    EXPECT_EQ(test.class_name, method.GetClassName().GetStringRef());
+    std::optional<const ObjCLanguage::MethodName> method =
+        ObjCLanguage::MethodName::Create(test.input, /*strict = */ false);
+    EXPECT_TRUE(method.has_value());
+    EXPECT_EQ(test.full_name_sans_category,
+              method->GetFullNameWithoutCategory());
+    EXPECT_EQ(test.class_name, method->GetClassName());
     EXPECT_EQ(test.class_name_with_category,
-              method.GetClassNameWithCategory().GetStringRef());
-    EXPECT_EQ(test.category, method.GetCategory().GetStringRef());
-    EXPECT_EQ(test.selector, method.GetSelector().GetStringRef());
+              method->GetClassNameWithCategory());
+    EXPECT_EQ(test.category, method->GetCategory());
+    EXPECT_EQ(test.selector, method->GetSelector());
   }
 }
 
@@ -105,10 +103,12 @@
                                   "[]"};
 
   for (const auto &name : test_cases) {
-    ObjCLanguage::MethodName strict_method(name, /*strict = */ true);
-    EXPECT_FALSE(strict_method.IsValid(true));
+    std::optional<const ObjCLanguage::MethodName> strict_method =
+        ObjCLanguage::MethodName::Create(name, /*strict = */ false);
+    EXPECT_FALSE(strict_method.has_value());
 
-    ObjCLanguage::MethodName lax_method(name, /*strict = */ false);
-    EXPECT_FALSE(lax_method.IsValid(true));
+    std::optional<const ObjCLanguage::MethodName> lax_method =
+        ObjCLanguage::MethodName::Create(name, /*strict = */ false);
+    EXPECT_FALSE(lax_method.has_value());
   }
 }
Index: lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
@@ -287,15 +287,16 @@
           bool is_objc_method = false;
           if (cu_language == eLanguageTypeObjC ||
               cu_language == eLanguageTypeObjC_plus_plus) {
-            ObjCLanguage::MethodName objc_method(name, true);
-            if (objc_method.IsValid(true)) {
+            std::optional<const ObjCLanguage::MethodName> objc_method =
+                ObjCLanguage::MethodName::Create(name, true);
+            if (objc_method) {
               is_objc_method = true;
               ConstString class_name_with_category(
-                  objc_method.GetClassNameWithCategory());
-              ConstString objc_selector_name(objc_method.GetSelector());
+                  objc_method->GetClassNameWithCategory());
+              ConstString objc_selector_name(objc_method->GetSelector());
               ConstString objc_fullname_no_category_name(
-                  objc_method.GetFullNameWithoutCategory(true));
-              ConstString class_name_no_category(objc_method.GetClassName());
+                  objc_method->GetFullNameWithoutCategory().c_str());
+              ConstString class_name_no_category(objc_method->GetClassName());
               set.function_fullnames.Insert(ConstString(name), ref);
               if (class_name_with_category)
                 set.objc_class_selectors.Insert(class_name_with_category, ref);
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -980,10 +980,11 @@
   if (attrs.name) {
     bool type_handled = false;
     if (tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine) {
-      ObjCLanguage::MethodName objc_method(attrs.name.GetStringRef(), true);
-      if (objc_method.IsValid(true)) {
+      std::optional<const ObjCLanguage::MethodName> objc_method =
+          ObjCLanguage::MethodName::Create(attrs.name.GetStringRef(), true);
+      if (objc_method) {
         CompilerType class_opaque_type;
-        ConstString class_name(objc_method.GetClassName());
+        ConstString class_name(objc_method->GetClassName());
         if (class_name) {
           TypeSP complete_objc_class_type_sp(
               dwarf->FindCompleteObjCDefinitionTypeForDIE(DWARFDIE(),
@@ -2617,13 +2618,19 @@
   // Check if the property getter/setter were provided as full names.
   // We want basenames, so we extract them.
   if (prop_getter_name && prop_getter_name[0] == '-') {
-    ObjCLanguage::MethodName prop_getter_method(prop_getter_name, true);
-    prop_getter_name = prop_getter_method.GetSelector().GetCString();
+    std::optional<const ObjCLanguage::MethodName> prop_getter_method =
+        ObjCLanguage::MethodName::Create(prop_getter_name, true);
+    if (prop_getter_method)
+      prop_getter_name =
+          ConstString(prop_getter_method->GetSelector()).GetCString();
   }
 
   if (prop_setter_name && prop_setter_name[0] == '-') {
-    ObjCLanguage::MethodName prop_setter_method(prop_setter_name, true);
-    prop_setter_name = prop_setter_method.GetSelector().GetCString();
+    std::optional<const ObjCLanguage::MethodName> prop_setter_method =
+        ObjCLanguage::MethodName::Create(prop_setter_name, true);
+    if (prop_setter_method)
+      prop_setter_name =
+          ConstString(prop_setter_method->GetSelector()).GetCString();
   }
 
   // If the names haven't been provided, they need to be filled in.
Index: lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
===================================================================
--- lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
+++ lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
@@ -25,62 +25,98 @@
 public:
   class MethodName {
   public:
-    enum Type { eTypeUnspecified, eTypeClassMethod, eTypeInstanceMethod };
-
-    MethodName() : m_full(), m_class(), m_category(), m_selector() {}
-
-    MethodName(const char *name, bool strict)
-        : m_full(), m_class(), m_category(), m_selector(),
-          m_type(eTypeUnspecified), m_category_is_valid(false) {
-      SetName(name, strict);
-    }
-    MethodName(llvm::StringRef name, bool strict)
-        : m_full(), m_class(), m_category(), m_selector(),
-          m_type(eTypeUnspecified), m_category_is_valid(false) {
-      SetName(name, strict);
-    }
-
-    void Clear();
-
-    bool IsValid(bool strict) const {
-      // If "strict" is true, the name must have everything specified including
-      // the leading "+" or "-" on the method name
-      if (strict && m_type == eTypeUnspecified)
-        return false;
-      // Other than that, m_full will only be filled in if the objective C
-      // name is valid.
-      return (bool)m_full;
-    }
-
-    bool HasCategory() { return !GetCategory().IsEmpty(); }
-
-    Type GetType() const { return m_type; }
-
-    ConstString GetFullName() const { return m_full; }
+    /// The static factory method for creating a MethodName.
+    ///
+    /// \param[in] name
+    ///   The name of the method.
+    ///
+    /// \param[in] strict
+    ///   Control whether or not the name parser is strict about +/- in the
+    ///   front of the name.
+    ///
+    /// \return If the name failed to parse as a valid Objective-C method name,
+    /// returns std::nullopt. Otherwise returns a const MethodName.
+    static std::optional<const MethodName> Create(llvm::StringRef name,
+                                                  bool strict);
+
+    /// Determines if this method is a class method
+    ///
+    /// \return Returns true if the method is a class method. False otherwise.
+    bool IsClassMethod() const { return m_type == eTypeClassMethod; }
+
+    /// Determines if this method is an instance method
+    ///
+    /// \return Returns true if the method is an instance method. False
+    /// otherwise.
+    bool IsInstanceMethod() const { return m_type == eTypeInstanceMethod; }
+
+    /// Returns the full name of the method.
+    ///
+    /// This includes the class name, the category name (if applicable), and the
+    /// selector name.
+    ///
+    /// \return The name of the method in the form of a const std::string
+    /// reference.
+    const std::string &GetFullName() const { return m_full; }
+
+    /// Creates a variation of this method without the category.
+    /// If this method has no category, it returns an empty string.
+    ///
+    /// Example:
+    ///   Full name: "+[NSString(my_additions) myStringWithCString:]"
+    ///   becomes "+[NSString myStringWithCString:]"
+    ///
+    /// \return The method name without the category or an empty string if there
+    /// was no category to begin with.
+    std::string GetFullNameWithoutCategory() const;
+
+    /// Returns a reference to the class name.
+    ///
+    /// Example:
+    ///   Full name: "+[NSString(my_additions) myStringWithCString:]"
+    ///   will give you "NSString"
+    ///
+    /// \return A StringRef to the class name of this method.
+    llvm::StringRef GetClassName() const;
+
+    /// Returns a reference to the class name with the category.
+    ///
+    /// Example:
+    ///   Full name: "+[NSString(my_additions) myStringWithCString:]"
+    ///   will give you "NSString(my_additions)"
+    ///
+    /// Note: If your method has no category, this will give the same output as
+    /// `GetClassName`.
+    ///
+    /// \return A StringRef to the class name (including the category) of this
+    /// method. If there was no category, returns the same as `GetClassName`.
+    llvm::StringRef GetClassNameWithCategory() const;
+
+    /// Returns a reference to the category name.
+    ///
+    /// Example:
+    ///   Full name: "+[NSString(my_additions) myStringWithCString:]"
+    ///   will give you "my_additions"
+    /// \return A StringRef to the category name of this method. If no category
+    /// is present, the StringRef is empty.
+    llvm::StringRef GetCategory() const;
+
+    /// Returns a reference to the selector name.
+    ///
+    /// Example:
+    ///   Full name: "+[NSString(my_additions) myStringWithCString:]"
+    ///   will give you "myStringWithCString:"
+    /// \return A StringRef to the selector of this method.
+    llvm::StringRef GetSelector() const;
 
-    ConstString GetFullNameWithoutCategory(bool empty_if_no_category);
-
-    bool SetName(const char *name, bool strict);
-    bool SetName(llvm::StringRef name, bool strict);
-
-    ConstString GetClassName();
-
-    ConstString GetClassNameWithCategory();
-
-    ConstString GetCategory();
+  protected:
+    enum Type { eTypeUnspecified, eTypeClassMethod, eTypeInstanceMethod };
 
-    ConstString GetSelector();
+    MethodName(llvm::StringRef name, Type type)
+        : m_full(name.str()), m_type(type) {}
 
-  protected:
-    ConstString
-        m_full; // Full name:   "+[NSString(my_additions) myStringWithCString:]"
-    ConstString m_class; // Class name:  "NSString"
-    ConstString
-        m_class_category;   // Class with category: "NSString(my_additions)"
-    ConstString m_category; // Category:    "my_additions"
-    ConstString m_selector; // Selector:    "myStringWithCString:"
-    Type m_type = eTypeUnspecified;
-    bool m_category_is_valid = false;
+    const std::string m_full;
+    Type m_type;
   };
 
   ObjCLanguage() = default;
Index: lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
===================================================================
--- lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
+++ lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
@@ -60,201 +60,152 @@
   }
 }
 
-void ObjCLanguage::MethodName::Clear() {
-  m_full.Clear();
-  m_class.Clear();
-  m_category.Clear();
-  m_selector.Clear();
-  m_type = eTypeUnspecified;
-  m_category_is_valid = false;
-}
-
-bool ObjCLanguage::MethodName::SetName(llvm::StringRef name, bool strict) {
-  Clear();
+std::optional<const ObjCLanguage::MethodName>
+ObjCLanguage::MethodName::Create(llvm::StringRef name, bool strict) {
   if (name.empty())
-    return IsValid(strict);
-
-  // If "strict" is true. then the method must be specified with a '+' or '-'
-  // at the beginning. If "strict" is false, then the '+' or '-' can be omitted
-  bool valid_prefix = false;
-
-  if (name.size() > 1 && (name[0] == '+' || name[0] == '-')) {
-    valid_prefix = name[1] == '[';
-    if (name[0] == '+')
-      m_type = eTypeClassMethod;
-    else
-      m_type = eTypeInstanceMethod;
-  } else if (!strict) {
-    // "strict" is false, the name just needs to start with '['
-    valid_prefix = name[0] == '[';
-  }
-
-  if (valid_prefix) {
-    int name_len = name.size();
-    // Objective-C methods must have at least:
-    //      "-[" or "+[" prefix
-    //      One character for a class name
-    //      One character for the space between the class name
-    //      One character for the method name
-    //      "]" suffix
-    if (name_len >= (5 + (strict ? 1 : 0)) && name.back() == ']') {
-      m_full.SetString(name);
-    }
-  }
-  return IsValid(strict);
+    return std::nullopt;
+
+  // Objective-C method minimum requirements:
+  //  - If `strict` is true, must start with '-' or '+' (1 char)
+  //  - Must be followed by '[' (1 char)
+  //  - Must have at least one character for class name (1 char)
+  //  - Must have a space between class name and method name (1 char)
+  //  - Must have at least one character for  method name (1 char)
+  //  - Must be end with ']' (1 char)
+  //  This means that the minimum size is 5 characters (6 if `strict`)
+  //  e.g. [a a] (-[a a] or +[a a] if `strict`)
+
+  // We can check length and ending invariants first
+  if (name.size() < (5 + (strict ? 1 : 0)) || name.back() != ']')
+    return std::nullopt;
+
+  // Figure out type
+  Type type = eTypeUnspecified;
+  if (name.startswith("+["))
+    type = eTypeClassMethod;
+  else if (name.startswith("-["))
+    type = eTypeInstanceMethod;
+
+  // If there's no type and it's strict, this is invalid
+  if (strict && type == eTypeUnspecified)
+    return std::nullopt;
+
+  // If not strict and type unspecified, make sure we start with '['
+  if (type == eTypeUnspecified && name.front() != '[')
+    return std::nullopt;
+
+  // If we've gotten here, we're confident that this looks enough like an
+  // Objective-C method to treat it like one.
+  ObjCLanguage::MethodName method_name(name, type);
+  return method_name;
 }
 
-bool ObjCLanguage::MethodName::SetName(const char *name, bool strict) {
-  return SetName(llvm::StringRef(name), strict);
+llvm::StringRef ObjCLanguage::MethodName::GetClassName() const {
+  llvm::StringRef full = m_full;
+  const size_t class_start_pos = (full.front() == '[' ? 1 : 2);
+  const size_t paren_pos = full.find('(', class_start_pos);
+  // If there's a category we want to stop there
+  if (paren_pos != llvm::StringRef::npos)
+    return full.substr(class_start_pos, paren_pos - class_start_pos);
+
+  // Otherwise we find the space separating the class and method
+  const size_t space_pos = full.find(' ', class_start_pos);
+  return full.substr(class_start_pos, space_pos - class_start_pos);
 }
 
-ConstString ObjCLanguage::MethodName::GetClassName() {
-  if (!m_class) {
-    if (IsValid(false)) {
-      const char *full = m_full.GetCString();
-      const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
-      const char *paren_pos = strchr(class_start, '(');
-      if (paren_pos) {
-        m_class.SetCStringWithLength(class_start, paren_pos - class_start);
-      } else {
-        // No '(' was found in the full name, we can definitively say that our
-        // category was valid (and empty).
-        m_category_is_valid = true;
-        const char *space_pos = strchr(full, ' ');
-        if (space_pos) {
-          m_class.SetCStringWithLength(class_start, space_pos - class_start);
-          if (!m_class_category) {
-            // No category in name, so we can also fill in the m_class_category
-            m_class_category = m_class;
-          }
-        }
-      }
-    }
-  }
-  return m_class;
+llvm::StringRef ObjCLanguage::MethodName::GetClassNameWithCategory() const {
+  llvm::StringRef full = m_full;
+  const size_t class_start_pos = (full.front() == '[' ? 1 : 2);
+  const size_t space_pos = full.find(' ', class_start_pos);
+  return full.substr(class_start_pos, space_pos - class_start_pos);
 }
 
-ConstString ObjCLanguage::MethodName::GetClassNameWithCategory() {
-  if (!m_class_category) {
-    if (IsValid(false)) {
-      const char *full = m_full.GetCString();
-      const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
-      const char *space_pos = strchr(full, ' ');
-      if (space_pos) {
-        m_class_category.SetCStringWithLength(class_start,
-                                              space_pos - class_start);
-        // If m_class hasn't been filled in and the class with category doesn't
-        // contain a '(', then we can also fill in the m_class
-        if (!m_class && strchr(m_class_category.GetCString(), '(') == nullptr) {
-          m_class = m_class_category;
-          // No '(' was found in the full name, we can definitively say that
-          // our category was valid (and empty).
-          m_category_is_valid = true;
-        }
-      }
-    }
-  }
-  return m_class_category;
+llvm::StringRef ObjCLanguage::MethodName::GetSelector() const {
+  llvm::StringRef full = m_full;
+  const size_t space_pos = full.find(' ');
+  if (space_pos == llvm::StringRef::npos)
+    return llvm::StringRef();
+  const size_t closing_bracket = full.find(']', space_pos);
+  return full.substr(space_pos + 1, closing_bracket - space_pos - 1);
 }
 
-ConstString ObjCLanguage::MethodName::GetSelector() {
-  if (!m_selector) {
-    if (IsValid(false)) {
-      const char *full = m_full.GetCString();
-      const char *space_pos = strchr(full, ' ');
-      if (space_pos) {
-        ++space_pos; // skip the space
-        m_selector.SetCStringWithLength(space_pos, m_full.GetLength() -
-                                                       (space_pos - full) - 1);
-      }
-    }
-  }
-  return m_selector;
-}
+llvm::StringRef ObjCLanguage::MethodName::GetCategory() const {
+  llvm::StringRef full = m_full;
+  const size_t open_paren_pos = full.find('(');
+  const size_t close_paren_pos = full.find(')');
 
-ConstString ObjCLanguage::MethodName::GetCategory() {
-  if (!m_category_is_valid && !m_category) {
-    if (IsValid(false)) {
-      m_category_is_valid = true;
-      const char *full = m_full.GetCString();
-      const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
-      const char *open_paren_pos = strchr(class_start, '(');
-      if (open_paren_pos) {
-        ++open_paren_pos; // Skip the open paren
-        const char *close_paren_pos = strchr(open_paren_pos, ')');
-        if (close_paren_pos)
-          m_category.SetCStringWithLength(open_paren_pos,
-                                          close_paren_pos - open_paren_pos);
-      }
-    }
-  }
-  return m_category;
-}
+  if (open_paren_pos == llvm::StringRef::npos ||
+      close_paren_pos == llvm::StringRef::npos)
+    return llvm::StringRef();
 
-ConstString ObjCLanguage::MethodName::GetFullNameWithoutCategory(
-    bool empty_if_no_category) {
-  if (IsValid(false)) {
-    if (HasCategory()) {
-      StreamString strm;
-      if (m_type == eTypeClassMethod)
-        strm.PutChar('+');
-      else if (m_type == eTypeInstanceMethod)
-        strm.PutChar('-');
-      strm.Printf("[%s %s]", GetClassName().GetCString(),
-                  GetSelector().GetCString());
-      return ConstString(strm.GetString());
-    }
+  return full.substr(open_paren_pos + 1,
+                     close_paren_pos - (open_paren_pos + 1));
+}
 
-    if (!empty_if_no_category) {
-      // Just return the full name since it doesn't have a category
-      return GetFullName();
-    }
-  }
-  return ConstString();
+std::string ObjCLanguage::MethodName::GetFullNameWithoutCategory() const {
+  llvm::StringRef full = m_full;
+  const size_t open_paren_pos = full.find('(');
+  const size_t close_paren_pos = full.find(')');
+  if (open_paren_pos == llvm::StringRef::npos ||
+      close_paren_pos == llvm::StringRef::npos)
+    return std::string();
+
+  llvm::StringRef class_name = GetClassName();
+  llvm::StringRef selector_name = GetSelector();
+  std::string name_sans_category;
+
+  if (m_type == eTypeClassMethod)
+    name_sans_category += '+';
+  else if (m_type == eTypeInstanceMethod)
+    name_sans_category += '-';
+
+  name_sans_category += '[';
+  name_sans_category.append(class_name.data(), class_name.size());
+  name_sans_category += ' ';
+  name_sans_category.append(selector_name.data(), selector_name.size());
+  name_sans_category += ']';
+
+  return name_sans_category;
 }
 
 std::vector<Language::MethodNameVariant>
 ObjCLanguage::GetMethodNameVariants(ConstString method_name) const {
   std::vector<Language::MethodNameVariant> variant_names;
-  ObjCLanguage::MethodName objc_method(method_name.GetCString(), false);
-  if (!objc_method.IsValid(false)) {
+  std::optional<const ObjCLanguage::MethodName> objc_method =
+      ObjCLanguage::MethodName::Create(method_name.GetStringRef(), false);
+  if (!objc_method)
     return variant_names;
-  }
 
-  variant_names.emplace_back(objc_method.GetSelector(),
+  variant_names.emplace_back(ConstString(objc_method->GetSelector()),
                              lldb::eFunctionNameTypeSelector);
 
-  const bool is_class_method =
-      objc_method.GetType() == MethodName::eTypeClassMethod;
-  const bool is_instance_method =
-      objc_method.GetType() == MethodName::eTypeInstanceMethod;
-  ConstString name_sans_category =
-      objc_method.GetFullNameWithoutCategory(/*empty_if_no_category*/ true);
+  const std::string name_sans_category =
+      objc_method->GetFullNameWithoutCategory();
 
-  if (is_class_method || is_instance_method) {
-    if (name_sans_category)
-      variant_names.emplace_back(name_sans_category,
+  if (objc_method->IsClassMethod() || objc_method->IsInstanceMethod()) {
+    if (!name_sans_category.empty())
+      variant_names.emplace_back(ConstString(name_sans_category.c_str()),
                                  lldb::eFunctionNameTypeFull);
   } else {
     StreamString strm;
 
-    strm.Printf("+%s", objc_method.GetFullName().GetCString());
+    strm.Printf("+%s", objc_method->GetFullName().c_str());
     variant_names.emplace_back(ConstString(strm.GetString()),
                                lldb::eFunctionNameTypeFull);
     strm.Clear();
 
-    strm.Printf("-%s", objc_method.GetFullName().GetCString());
+    strm.Printf("-%s", objc_method->GetFullName().c_str());
     variant_names.emplace_back(ConstString(strm.GetString()),
                                lldb::eFunctionNameTypeFull);
     strm.Clear();
 
-    if (name_sans_category) {
-      strm.Printf("+%s", name_sans_category.GetCString());
+    if (!name_sans_category.empty()) {
+      strm.Printf("+%s", name_sans_category.c_str());
       variant_names.emplace_back(ConstString(strm.GetString()),
                                  lldb::eFunctionNameTypeFull);
       strm.Clear();
 
-      strm.Printf("-%s", name_sans_category.GetCString());
+      strm.Printf("-%s", name_sans_category.c_str());
       variant_names.emplace_back(ConstString(strm.GetString()),
                                  lldb::eFunctionNameTypeFull);
     }
@@ -1020,7 +971,7 @@
 
     friend class lldb_private::ObjCLanguage;
   };
-  
+
   class ObjCDebugInfoScavenger : public Language::ImageListTypeScavenger {
   public:
     CompilerType AdjustForInclusion(CompilerType &candidate) override {
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to