[Lldb-commits] [lldb] r218132 - Extend the member function discovery APIs to also support Objective-C as well as C++

Enrico Granata egranata at apple.com
Fri Sep 19 11:21:06 PDT 2014


Author: enrico
Date: Fri Sep 19 13:21:05 2014
New Revision: 218132

URL: http://llvm.org/viewvc/llvm-project?rev=218132&view=rev
Log:
Extend the member function discovery APIs to also support Objective-C as well as C++

For the Objective-C case, we do not have a "function type" notion, so we actually end up wrapping the clang ObjCMethodDecl in the Impl object, and ask function-y questions of it
In general, you can always ask for return type, number of arguments, and type of each argument using the TypeMemberFunction layer - but in the C++ case, you can also acquire a Type object for the function itself, which instead you can't do in the Objective-C case


Added:
    lldb/trunk/test/python_api/class_members/main.mm
      - copied, changed from r218130, lldb/trunk/test/python_api/class_members/main.cpp
Removed:
    lldb/trunk/test/python_api/class_members/main.cpp
Modified:
    lldb/trunk/include/lldb/API/SBType.h
    lldb/trunk/include/lldb/Symbol/ClangASTType.h
    lldb/trunk/include/lldb/Symbol/Type.h
    lldb/trunk/scripts/Python/interface/SBType.i
    lldb/trunk/source/API/SBType.cpp
    lldb/trunk/source/Symbol/ClangASTType.cpp
    lldb/trunk/source/Symbol/Type.cpp
    lldb/trunk/test/python_api/class_members/Makefile
    lldb/trunk/test/python_api/class_members/TestSBTypeClassMembers.py

Modified: lldb/trunk/include/lldb/API/SBType.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBType.h?rev=218132&r1=218131&r2=218132&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBType.h (original)
+++ lldb/trunk/include/lldb/API/SBType.h Fri Sep 19 13:21:05 2014
@@ -89,6 +89,15 @@ public:
     lldb::SBType
     GetType ();
     
+    lldb::SBType
+    GetReturnType ();
+    
+    uint32_t
+    GetNumberOfArguments ();
+    
+    lldb::SBType
+    GetArgumentTypeAtIndex (uint32_t);
+    
     lldb::MemberFunctionKind
     GetKind();
     

Modified: lldb/trunk/include/lldb/Symbol/ClangASTType.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTType.h?rev=218132&r1=218131&r2=218132&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTType.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTType.h Fri Sep 19 13:21:05 2014
@@ -162,7 +162,7 @@ public:
     GetNumberOfFunctionArguments () const;
     
     ClangASTType
-    GetFunctionArgumentAtIndex (const size_t index);
+    GetFunctionArgumentAtIndex (const size_t index) const;
     
     bool
     IsVariadicFunctionType () const;
@@ -329,7 +329,7 @@ public:
     GetFunctionArgumentCount () const;
 
     ClangASTType
-    GetFunctionArgumentTypeAtIndex (size_t idx);
+    GetFunctionArgumentTypeAtIndex (size_t idx) const;
 
     ClangASTType
     GetFunctionReturnType () const;
@@ -337,10 +337,8 @@ public:
     size_t
     GetNumMemberFunctions () const;
     
-    ClangASTType
-    GetMemberFunctionAtIndex (size_t idx,
-                              std::string& name,
-                              lldb::MemberFunctionKind& kind);
+    TypeMemberFunctionImpl
+    GetMemberFunctionAtIndex (size_t idx);
     
     ClangASTType
     GetLValueReferenceType () const;

Modified: lldb/trunk/include/lldb/Symbol/Type.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Type.h?rev=218132&r1=218131&r2=218132&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/Type.h (original)
+++ lldb/trunk/include/lldb/Symbol/Type.h Fri Sep 19 13:21:05 2014
@@ -816,6 +816,7 @@ class TypeMemberFunctionImpl
 public:
     TypeMemberFunctionImpl() :
         m_type(),
+        m_objc_method_decl(nullptr),
         m_name(),
         m_kind(lldb::eMemberFunctionKindUnknown)
     {
@@ -825,13 +826,25 @@ public:
                             const std::string& name,
                             const lldb::MemberFunctionKind& kind) :
         m_type(type),
+        m_objc_method_decl(nullptr),
         m_name(name),
         m_kind(kind)
     {
     }
     
+    TypeMemberFunctionImpl (clang::ObjCMethodDecl *method,
+                            const std::string& name,
+                            const lldb::MemberFunctionKind& kind) :
+    m_type(),
+    m_objc_method_decl(method),
+    m_name(name),
+    m_kind(kind)
+    {
+    }
+    
     TypeMemberFunctionImpl (const TypeMemberFunctionImpl& rhs) :
         m_type(rhs.m_type),
+        m_objc_method_decl(rhs.m_objc_method_decl),
         m_name(rhs.m_name),
         m_kind(rhs.m_kind)
     {
@@ -849,14 +862,28 @@ public:
     ClangASTType
     GetType () const;
     
+    ClangASTType
+    GetReturnType () const;
+    
+    size_t
+    GetNumArguments () const;
+    
+    ClangASTType
+    GetArgumentAtIndex (size_t idx) const;
+    
     lldb::MemberFunctionKind
     GetKind () const;
     
     bool
     GetDescription (Stream& stream);
+    
+protected:
+    std::string
+    GetPrintableTypeName ();
 
 private:
     ClangASTType m_type;
+    clang::ObjCMethodDecl *m_objc_method_decl;
     ConstString m_name;
     lldb::MemberFunctionKind m_kind;
 };

Modified: lldb/trunk/scripts/Python/interface/SBType.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBType.i?rev=218132&r1=218131&r2=218132&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBType.i (original)
+++ lldb/trunk/scripts/Python/interface/SBType.i Fri Sep 19 13:21:05 2014
@@ -86,6 +86,15 @@ public:
     lldb::SBType
     GetType ();
     
+    lldb::SBType
+    GetReturnType ();
+    
+    uint32_t
+    GetNumberOfArguments ();
+    
+    lldb::SBType
+    GetArgumentTypeAtIndex (uint32_t);
+    
     lldb::MemberFunctionKind
     GetKind();
     

Modified: lldb/trunk/source/API/SBType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBType.cpp?rev=218132&r1=218131&r2=218132&view=diff
==============================================================================
--- lldb/trunk/source/API/SBType.cpp (original)
+++ lldb/trunk/source/API/SBType.cpp Fri Sep 19 13:21:05 2014
@@ -267,12 +267,7 @@ SBType::GetMemberFunctionAtIndex (uint32
 {
     SBTypeMemberFunction sb_func_type;
     if (IsValid())
-    {
-        lldb::MemberFunctionKind kind;
-        std::string name;
-        ClangASTType func_type(m_opaque_sp->GetClangASTType(true).GetMemberFunctionAtIndex(idx,name,kind));
-        sb_func_type.reset(new TypeMemberFunctionImpl(func_type,name,kind));
-    }
+        sb_func_type.reset(new TypeMemberFunctionImpl(m_opaque_sp->GetClangASTType(true).GetMemberFunctionAtIndex(idx)));
     return sb_func_type;
 }
 
@@ -754,7 +749,36 @@ SBTypeMemberFunction::GetType ()
         sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetType())));
     }
     return sb_type;
-    
+}
+
+lldb::SBType
+SBTypeMemberFunction::GetReturnType ()
+{
+    SBType sb_type;
+    if (m_opaque_sp)
+    {
+        sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetReturnType())));
+    }
+    return sb_type;
+}
+
+uint32_t
+SBTypeMemberFunction::GetNumberOfArguments ()
+{
+    if (m_opaque_sp)
+        return m_opaque_sp->GetNumArguments();
+    return 0;
+}
+
+lldb::SBType
+SBTypeMemberFunction::GetArgumentTypeAtIndex (uint32_t i)
+{
+    SBType sb_type;
+    if (m_opaque_sp)
+    {
+        sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetArgumentAtIndex(i))));
+    }
+    return sb_type;
 }
 
 lldb::MemberFunctionKind

Modified: lldb/trunk/source/Symbol/ClangASTType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTType.cpp?rev=218132&r1=218131&r2=218132&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTType.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTType.cpp Fri Sep 19 13:21:05 2014
@@ -516,7 +516,7 @@ ClangASTType::GetNumberOfFunctionArgumen
 }
 
 ClangASTType
-ClangASTType::GetFunctionArgumentAtIndex (const size_t index)
+ClangASTType::GetFunctionArgumentAtIndex (const size_t index) const
 {
     if (IsValid())
     {
@@ -1714,7 +1714,7 @@ ClangASTType::GetFunctionArgumentCount (
 }
 
 ClangASTType
-ClangASTType::GetFunctionArgumentTypeAtIndex (size_t idx)
+ClangASTType::GetFunctionArgumentTypeAtIndex (size_t idx) const
 {
     if (IsValid())
     {
@@ -1759,8 +1759,45 @@ ClangASTType::GetNumMemberFunctions () c
                     const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
                     if (cxx_record_decl)
                         num_functions = std::distance(cxx_record_decl->method_begin(), cxx_record_decl->method_end());
-                    break;
                 }
+                break;
+                
+            case clang::Type::ObjCObjectPointer:
+                if (GetCompleteType())
+                {
+                    const clang::ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
+                    if (objc_class_type)
+                    {
+                        clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
+                        if (class_interface_decl)
+                            num_functions = std::distance(class_interface_decl->meth_begin(), class_interface_decl->meth_end());
+                    }
+                }
+                break;
+                
+            case clang::Type::ObjCObject:
+            case clang::Type::ObjCInterface:
+                if (GetCompleteType())
+                {
+                    const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+                    if (objc_class_type)
+                    {
+                        clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                        if (class_interface_decl)
+                            num_functions = std::distance(class_interface_decl->meth_begin(), class_interface_decl->meth_end());
+                    }
+                }
+                break;
+                
+                
+            case clang::Type::Typedef:
+                return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumMemberFunctions();
+                
+            case clang::Type::Elaborated:
+                return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetNumMemberFunctions();
+                
+            case clang::Type::Paren:
+                return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetNumMemberFunctions();
                 
             default:
                 break;
@@ -1769,11 +1806,13 @@ ClangASTType::GetNumMemberFunctions () c
     return num_functions;
 }
 
-ClangASTType
-ClangASTType::GetMemberFunctionAtIndex (size_t idx,
-                                        std::string& name,
-                                        lldb::MemberFunctionKind& kind)
+TypeMemberFunctionImpl
+ClangASTType::GetMemberFunctionAtIndex (size_t idx)
 {
+    std::string name("");
+    MemberFunctionKind kind(MemberFunctionKind::eMemberFunctionKindUnknown);
+    ClangASTType type{};
+    clang::ObjCMethodDecl *method_decl(nullptr);
     if (IsValid())
     {
         clang::QualType qual_type(GetCanonicalQualType());
@@ -1807,18 +1846,94 @@ ClangASTType::GetMemberFunctionAtIndex (
                                     kind = lldb::eMemberFunctionKindDestructor;
                                 else
                                     kind = lldb::eMemberFunctionKindInstanceMethod;
-                                return ClangASTType(m_ast,method_decl->getType().getAsOpaquePtr());
+                                type = ClangASTType(m_ast,method_decl->getType().getAsOpaquePtr());
                             }
                         }
                     }
                 }
+                break;
+                
+            case clang::Type::ObjCObjectPointer:
+                if (GetCompleteType())
+                {
+                    const clang::ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
+                    if (objc_class_type)
+                    {
+                        clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
+                        if (class_interface_decl)
+                        {
+                            auto method_iter = class_interface_decl->meth_begin();
+                            auto method_end = class_interface_decl->meth_end();
+                            if (idx < static_cast<size_t>(std::distance(method_iter, method_end)))
+                            {
+                                std::advance(method_iter, idx);
+                                method_decl = method_iter->getCanonicalDecl();
+                                if (method_decl)
+                                {
+                                    name = method_decl->getSelector().getAsString();
+                                    if (method_decl->isClassMethod())
+                                        kind = lldb::eMemberFunctionKindStaticMethod;
+                                    else
+                                        kind = lldb::eMemberFunctionKindInstanceMethod;
+                                }
+                            }
+                        }
+                    }
+                }
+                break;
+                
+            case clang::Type::ObjCObject:
+            case clang::Type::ObjCInterface:
+                if (GetCompleteType())
+                {
+                    const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+                    if (objc_class_type)
+                    {
+                        clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                        if (class_interface_decl)
+                        {
+                            auto method_iter = class_interface_decl->meth_begin();
+                            auto method_end = class_interface_decl->meth_end();
+                            if (idx < static_cast<size_t>(std::distance(method_iter, method_end)))
+                            {
+                                std::advance(method_iter, idx);
+                                method_decl = method_iter->getCanonicalDecl();
+                                if (method_decl)
+                                {
+                                    name = method_decl->getSelector().getAsString();
+                                    if (method_decl->isClassMethod())
+                                        kind = lldb::eMemberFunctionKindStaticMethod;
+                                    else
+                                        kind = lldb::eMemberFunctionKindInstanceMethod;
+                                }
+                            }
+                        }
+                    }
+                }
+                break;
+
+            case clang::Type::Typedef:
+                return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetMemberFunctionAtIndex(idx);
+                
+            case clang::Type::Elaborated:
+                return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetMemberFunctionAtIndex(idx);
+                
+            case clang::Type::Paren:
+                return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetMemberFunctionAtIndex(idx);
                 
             default:
                 break;
         }
     }
     
-    return ClangASTType();
+    if (kind == eMemberFunctionKindUnknown)
+        return TypeMemberFunctionImpl();
+    if (method_decl)
+        return TypeMemberFunctionImpl(method_decl, name, kind);
+    if (type)
+        return TypeMemberFunctionImpl(type, name, kind);
+    
+    return TypeMemberFunctionImpl();
 }
 
 ClangASTType

Modified: lldb/trunk/source/Symbol/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Type.cpp?rev=218132&r1=218131&r2=218132&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/Type.cpp (original)
+++ lldb/trunk/source/Symbol/Type.cpp Fri Sep 19 13:21:05 2014
@@ -31,6 +31,7 @@
 #include "llvm/ADT/StringRef.h"
 
 #include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -1297,6 +1298,7 @@ TypeMemberFunctionImpl::operator = (cons
     if (this != &rhs)
     {
         m_type = rhs.m_type;
+        m_objc_method_decl = rhs.m_objc_method_decl;
         m_name = rhs.m_name;
         m_kind = rhs.m_kind;
     }
@@ -1327,6 +1329,21 @@ TypeMemberFunctionImpl::GetKind () const
     return m_kind;
 }
 
+std::string
+TypeMemberFunctionImpl::GetPrintableTypeName ()
+{
+    if (m_type)
+        return m_type.GetTypeName().AsCString("<unknown>");
+    if (m_objc_method_decl)
+    {
+        if (m_objc_method_decl->getClassInterface())
+        {
+            return m_objc_method_decl->getClassInterface()->getName();
+        }
+    }
+    return "<unknown>";
+}
+
 bool
 TypeMemberFunctionImpl::GetDescription (Stream& stream)
 {
@@ -1334,25 +1351,58 @@ TypeMemberFunctionImpl::GetDescription (
         case lldb::eMemberFunctionKindUnknown:
             return false;
         case lldb::eMemberFunctionKindConstructor:
-            stream.Printf("constructor for %s", m_type.GetTypeName().AsCString());
+            stream.Printf("constructor for %s", GetPrintableTypeName().c_str());
             break;
         case lldb::eMemberFunctionKindDestructor:
-            stream.Printf("destructor for %s", m_type.GetTypeName().AsCString());
+            stream.Printf("destructor for %s",  GetPrintableTypeName().c_str());
             break;
         case lldb::eMemberFunctionKindInstanceMethod:
             stream.Printf("instance method %s of type %s",
                           m_name.AsCString(),
-                          m_type.GetTypeName().AsCString());
+                          GetPrintableTypeName().c_str());
             break;
         case lldb::eMemberFunctionKindStaticMethod:
             stream.Printf("static method %s of type %s",
                           m_name.AsCString(),
-                          m_type.GetTypeName().AsCString());
+                          GetPrintableTypeName().c_str());
             break;
     }
     return true;
 }
 
+ClangASTType
+TypeMemberFunctionImpl::GetReturnType () const
+{
+    if (m_type)
+        return m_type.GetFunctionReturnType();
+    if (m_objc_method_decl)
+        return ClangASTType(&m_objc_method_decl->getASTContext(),m_objc_method_decl->getReturnType().getAsOpaquePtr());
+    return ClangASTType();
+}
+
+size_t
+TypeMemberFunctionImpl::GetNumArguments () const
+{
+    if (m_type)
+        return m_type.GetNumberOfFunctionArguments();
+    if (m_objc_method_decl)
+        return m_objc_method_decl->param_size();
+    return 0;
+}
+
+ClangASTType
+TypeMemberFunctionImpl::GetArgumentAtIndex (size_t idx) const
+{
+    if (m_type)
+        return m_type.GetFunctionArgumentAtIndex (idx);
+    if (m_objc_method_decl)
+    {
+        if (idx < m_objc_method_decl->param_size())
+            return ClangASTType(&m_objc_method_decl->getASTContext(), m_objc_method_decl->parameters()[idx]->getOriginalType().getAsOpaquePtr());
+    }
+    return ClangASTType();
+}
+
 TypeEnumMemberImpl::TypeEnumMemberImpl (const clang::EnumConstantDecl* enum_member_decl,
                                         const lldb_private::ClangASTType& integer_type) :
     m_integer_type_sp(),

Modified: lldb/trunk/test/python_api/class_members/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/class_members/Makefile?rev=218132&r1=218131&r2=218132&view=diff
==============================================================================
--- lldb/trunk/test/python_api/class_members/Makefile (original)
+++ lldb/trunk/test/python_api/class_members/Makefile Fri Sep 19 13:21:05 2014
@@ -1,5 +1,5 @@
 LEVEL = ../../make
 
-CXX_SOURCES := main.cpp
+OBJCXX_SOURCES := main.mm
 
 include $(LEVEL)/Makefile.rules

Modified: lldb/trunk/test/python_api/class_members/TestSBTypeClassMembers.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/class_members/TestSBTypeClassMembers.py?rev=218132&r1=218131&r2=218132&view=diff
==============================================================================
--- lldb/trunk/test/python_api/class_members/TestSBTypeClassMembers.py (original)
+++ lldb/trunk/test/python_api/class_members/TestSBTypeClassMembers.py Fri Sep 19 13:21:05 2014
@@ -37,7 +37,7 @@ class SBTypeMemberFunctionsTest(TestBase
         # We'll use the test method name as the exe_name.
         self.exe_name = self.testMethodName
         # Find the line number to break at.
-        self.source = 'main.cpp'
+        self.source = 'main.mm'
         self.line = line_number(self.source, '// set breakpoint here')
 
     def type_api(self, exe_name):
@@ -76,6 +76,15 @@ class SBTypeMemberFunctionsTest(TestBase
         self.assertTrue(Base.GetMemberFunctionAtIndex(2).GetType().GetFunctionArgumentTypes().GetSize() == 0, "Base::dat takes no arguments")
         self.assertTrue(Base.GetMemberFunctionAtIndex(1).GetType().GetFunctionArgumentTypes().GetTypeAtIndex(1).GetName() == "char", "Base::bar takes a second 'char' argument")
         self.assertTrue(Base.GetMemberFunctionAtIndex(1).GetName() == "bar", "Base::bar not found")
+        
+        variable = frame0.FindVariable("thingy")
+        Thingy = variable.GetType()
+        
+        self.assertTrue(Thingy.GetNumberOfMemberFunctions() == 2, "Thingy declares two methods")
+        
+        self.assertTrue(Thingy.GetMemberFunctionAtIndex(0).GetReturnType().GetName() == "id", "Thingy::init returns an id")
+        self.assertTrue(Thingy.GetMemberFunctionAtIndex(1).GetNumberOfArguments() == 2, "Thingy::foo takes two arguments")
+        self.assertTrue(Thingy.GetMemberFunctionAtIndex(1).GetArgumentTypeAtIndex(0).GetName() == "int", "Thingy::foo takes an int")
 
 if __name__ == '__main__':
     import atexit

Removed: lldb/trunk/test/python_api/class_members/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/class_members/main.cpp?rev=218131&view=auto
==============================================================================
--- lldb/trunk/test/python_api/class_members/main.cpp (original)
+++ lldb/trunk/test/python_api/class_members/main.cpp (removed)
@@ -1,28 +0,0 @@
-//===-- main.cpp ------------------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-class Base {
-public:
-    int foo(int x, int y) { return 1; }
-    char bar(int x, char y) { return 2; }
-    void dat() {}
-    static int sfunc(char, int, float) { return 3; }
-};
-
-class Derived: public Base {
-protected:
-    int dImpl() { return 1; }
-public:
-    float baz(float b) { return b + 1.0; }
-};
-
-int main() {
-    Derived d;
-    return 0; // set breakpoint here
-}

Copied: lldb/trunk/test/python_api/class_members/main.mm (from r218130, lldb/trunk/test/python_api/class_members/main.cpp)
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/class_members/main.mm?p2=lldb/trunk/test/python_api/class_members/main.mm&p1=lldb/trunk/test/python_api/class_members/main.cpp&r1=218130&r2=218132&rev=218132&view=diff
==============================================================================
--- lldb/trunk/test/python_api/class_members/main.cpp (original)
+++ lldb/trunk/test/python_api/class_members/main.mm Fri Sep 19 13:21:05 2014
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#import <Foundation/Foundation.h>
+
 class Base {
 public:
     int foo(int x, int y) { return 1; }
@@ -22,7 +24,24 @@ public:
     float baz(float b) { return b + 1.0; }
 };
 
+ at interface Thingy: NSObject {
+}
+- (id)init;
+- (id)fooWithBar: (int)bar andBaz:(id)baz;
+ at end
+
+ at implementation Thingy {
+}
+- (id)init {
+    return (self = [super init]);
+}
+- (id)fooWithBar: (int)bar andBaz:(id)baz {
+    return nil;
+}
+ at end
+
 int main() {
     Derived d;
+    Thingy *thingy = [[Thingy alloc] init];
     return 0; // set breakpoint here
 }





More information about the lldb-commits mailing list