[Lldb-commits] [lldb] r153363 - in /lldb/trunk: include/lldb/API/SBType.h include/lldb/Symbol/ClangASTContext.h scripts/Python/interface/SBType.i source/API/SBType.cpp source/Symbol/ClangASTContext.cpp test/functionalities/type_completion/ test/functionalities/type_completion/Makefile test/functionalities/type_completion/TestTypeCompletion.py test/functionalities/type_completion/main.cpp

Enrico Granata egranata at apple.com
Fri Mar 23 18:11:14 PDT 2012


Author: enrico
Date: Fri Mar 23 20:11:14 2012
New Revision: 153363

URL: http://llvm.org/viewvc/llvm-project?rev=153363&view=rev
Log:
Adding a new API call IsTypeComplete() to SBType. This call is meant to check if the type has been previously completed or not (which is mostly interesting from a performance point of view)

Adding a test case that checks that we do not complete types before due time. This should help us track cases similar to the cascading data formatters.

Added:
    lldb/trunk/test/functionalities/type_completion/
    lldb/trunk/test/functionalities/type_completion/Makefile
    lldb/trunk/test/functionalities/type_completion/TestTypeCompletion.py
    lldb/trunk/test/functionalities/type_completion/main.cpp
Modified:
    lldb/trunk/include/lldb/API/SBType.h
    lldb/trunk/include/lldb/Symbol/ClangASTContext.h
    lldb/trunk/scripts/Python/interface/SBType.i
    lldb/trunk/source/API/SBType.cpp
    lldb/trunk/source/Symbol/ClangASTContext.cpp

Modified: lldb/trunk/include/lldb/API/SBType.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBType.h?rev=153363&r1=153362&r2=153363&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBType.h (original)
+++ lldb/trunk/include/lldb/API/SBType.h Fri Mar 23 20:11:14 2012
@@ -134,6 +134,9 @@
     
     lldb::TypeClass
     GetTypeClass ();
+    
+    bool
+    IsTypeComplete ();
 
     // DEPRECATED: but needed for Xcode right now
     static bool

Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=153363&r1=153362&r2=153363&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Fri Mar 23 20:11:14 2012
@@ -128,6 +128,13 @@
                      lldb::clang_type_t clang_type);
 
     bool
+    IsCompleteType (lldb::clang_type_t clang_type);
+    
+    static bool
+    IsCompleteType (clang::ASTContext *ast,
+                    lldb::clang_type_t clang_type);
+    
+    bool
     GetCompleteDecl (clang::Decl *decl)
     {
         return ClangASTContext::GetCompleteDecl(getASTContext(), decl);

Modified: lldb/trunk/scripts/Python/interface/SBType.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBType.i?rev=153363&r1=153362&r2=153363&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBType.i (original)
+++ lldb/trunk/scripts/Python/interface/SBType.i Fri Mar 23 20:11:14 2012
@@ -199,6 +199,9 @@
     
     lldb::TemplateArgumentKind
     GetTemplateArgumentKind (uint32_t idx);
+    
+    bool
+    IsTypeComplete ();
 
     %pythoncode %{
         def template_arg_array(self):
@@ -239,7 +242,9 @@
 
         __swig_getmethods__["class"] = GetTypeClass
         if _newclass: x = property(GetTypeClass, None)
-
+        
+        __swig_getmethods__["is_complete"] = IsTypeComplete
+        if _newclass: is_complete = property(IsTypeComplete, None)
         %}
 
 };

Modified: lldb/trunk/source/API/SBType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBType.cpp?rev=153363&r1=153362&r2=153363&view=diff
==============================================================================
--- lldb/trunk/source/API/SBType.cpp (original)
+++ lldb/trunk/source/API/SBType.cpp Fri Mar 23 20:11:14 2012
@@ -426,6 +426,15 @@
     return sb_type_member;
 }
 
+bool
+SBType::IsTypeComplete()
+{
+    if (!IsValid())
+        return false;
+    
+    return ClangASTContext::IsCompleteType(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType());
+}
+
 const char*
 SBType::GetName()
 {

Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=153363&r1=153362&r2=153363&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Fri Mar 23 20:11:14 2012
@@ -78,7 +78,7 @@
 
 
 static bool
-GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type)
+GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type, bool allow_completion = true)
 {
     const clang::Type::TypeClass type_class = qual_type->getTypeClass();
     switch (type_class)
@@ -88,7 +88,7 @@
             const clang::ArrayType *array_type = dyn_cast<clang::ArrayType>(qual_type.getTypePtr());
             
             if (array_type)
-                return GetCompleteQualType (ast, array_type->getElementType());
+                return GetCompleteQualType (ast, array_type->getElementType(), allow_completion);
         }
         break;
             
@@ -103,6 +103,9 @@
                 {
                     if (tag_decl->getDefinition())
                         return true;
+                    
+                    if (!allow_completion)
+                        return false;
 
                     if (tag_decl->hasExternalLexicalStorage())
                     {
@@ -137,6 +140,9 @@
                     if (class_interface_decl->getDefinition())
                         return true;
                     
+                    if (!allow_completion)
+                        return false;
+                    
                     if (class_interface_decl->hasExternalLexicalStorage())
                     {
                         if (ast)
@@ -156,10 +162,10 @@
         break;
 
     case clang::Type::Typedef:
-        return GetCompleteQualType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType());
+        return GetCompleteQualType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType(), allow_completion);
     
     case clang::Type::Elaborated:
-        return GetCompleteQualType (ast, cast<ElaboratedType>(qual_type)->getNamedType());
+        return GetCompleteQualType (ast, cast<ElaboratedType>(qual_type)->getNamedType(), allow_completion);
 
     default:
         break;
@@ -168,7 +174,6 @@
     return true;
 }
 
-
 static AccessSpecifier
 ConvertAccessTypeToAccessSpecifier (AccessType access)
 {
@@ -6338,6 +6343,22 @@
 }
 
 bool
+ClangASTContext::IsCompleteType (clang::ASTContext *ast, lldb::clang_type_t clang_type)
+{
+    if (clang_type == NULL)
+        return false;
+    
+    return GetCompleteQualType (ast, clang::QualType::getFromOpaquePtr(clang_type), false); // just check but don't let it actually complete
+}
+
+
+bool
+ClangASTContext::IsCompleteType (clang_type_t clang_type)
+{   
+    return ClangASTContext::IsCompleteType (getASTContext(), clang_type);
+}
+
+bool
 ClangASTContext::GetCompleteDecl (clang::ASTContext *ast,
                                   clang::Decl *decl)
 {

Added: lldb/trunk/test/functionalities/type_completion/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/type_completion/Makefile?rev=153363&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/type_completion/Makefile (added)
+++ lldb/trunk/test/functionalities/type_completion/Makefile Fri Mar 23 20:11:14 2012
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/test/functionalities/type_completion/TestTypeCompletion.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/type_completion/TestTypeCompletion.py?rev=153363&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/type_completion/TestTypeCompletion.py (added)
+++ lldb/trunk/test/functionalities/type_completion/TestTypeCompletion.py Fri Mar 23 20:11:14 2012
@@ -0,0 +1,139 @@
+"""
+Check that types only get completed when necessary.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+
+class TypeCompletionTestCase(TestBase):
+
+    mydir = os.path.join("functionalities", "type_completion")
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    def test_with_dsym_and_run_command(self):
+        """Check that types only get completed when necessary."""
+        self.buildDsym()
+        self.type_completion_commands()
+
+    def test_with_dwarf_and_run_command(self):
+        """Check that types only get completed when necessary."""
+        self.buildDwarf()
+        self.type_completion_commands()
+
+    def setUp(self):
+        # Call super's setUp().
+        TestBase.setUp(self)
+        # Find the line number to break at.
+        self.line = line_number('main.cpp', '// Set break point at this line.')
+
+    def type_completion_commands(self):
+        """Check that types only get completed when necessary."""
+        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
+                    BREAKPOINT_CREATED,
+            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d" %
+                        self.line)
+
+        self.runCmd("run", RUN_SUCCEEDED)
+
+        # The stop reason of the thread should be breakpoint.
+        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+            substrs = ['stopped',
+                       'stop reason = breakpoint'])
+
+        # This is the function to remove the custom formats in order to have a
+        # clean slate for the next test case.
+        def cleanup():
+            self.runCmd('type category enable gnu-libstdc++', check=False)
+
+        self.runCmd('type category disable gnu-libstdc++', check=False)
+
+        # Execute the cleanup function during test case tear down.
+        self.addTearDownHook(cleanup)
+
+        p_vector = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('p')
+        p_type = p_vector.GetType()
+        self.assertFalse(p_type.IsTypeComplete(), 'vector<T> complete but it should not be')
+
+        self.runCmd("next")
+        self.runCmd("next")
+
+        p_vector = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('p')
+        p_type = p_vector.GetType()
+        self.assertFalse(p_type.IsTypeComplete(), 'vector<T> complete but it should not be')
+
+        self.runCmd("next")
+        self.runCmd("next")
+
+        self.runCmd("frame variable p --show-types")
+
+        p_vector = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('p')
+        p_type = p_vector.GetType()
+        self.assertTrue(p_type.IsTypeComplete(), 'vector<T> should now be complete')
+        name_address_type = p_type.GetTemplateArgumentType(0)
+        self.assertTrue(name_address_type.IsValid(), 'NameAndAddress should be valid')
+        self.assertFalse(name_address_type.IsTypeComplete(), 'NameAndAddress complete but it should not be')
+
+        self.runCmd("next")
+        self.runCmd("next")
+
+        self.runCmd("frame variable guy --show-types")
+
+        p_vector = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('p')
+        p_type = p_vector.GetType()
+        self.assertTrue(p_type.IsTypeComplete(), 'vector<T> should now be complete')
+        name_address_type = p_type.GetTemplateArgumentType(0)
+        self.assertTrue(name_address_type.IsValid(), 'NameAndAddress should be valid')
+        self.assertTrue(name_address_type.IsTypeComplete(), 'NameAndAddress should now be complete')
+        field0 = name_address_type.GetFieldAtIndex(0)
+        if self.TraceOn():
+             print 'field0: ' + str(field0)
+        self.assertTrue(field0.IsValid(), 'NameAndAddress::m_name should be valid')
+        string = field0.GetType().GetPointeeType()
+        if self.TraceOn():
+             print 'string: ' + str(string)
+        self.assertTrue(string.IsValid(), 'std::string should be valid')
+        self.assertFalse(string.IsTypeComplete(), 'std::string complete but it should not be')
+
+        self.runCmd("next")
+        self.runCmd("next")
+
+        p_vector = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('p')
+        p_type = p_vector.GetType()
+        self.assertTrue(p_type.IsTypeComplete(), 'vector<T> should now be complete')
+        name_address_type = p_type.GetTemplateArgumentType(0)
+        self.assertTrue(name_address_type.IsValid(), 'NameAndAddress should be valid')
+        self.assertTrue(name_address_type.IsTypeComplete(), 'NameAndAddress should now be complete')
+        field0 = name_address_type.GetFieldAtIndex(0)
+        if self.TraceOn():
+             print 'field0: ' + str(field0)
+        self.assertTrue(field0.IsValid(), 'NameAndAddress::m_name should be valid')
+        string = field0.GetType().GetPointeeType()
+        if self.TraceOn():
+             print 'string: ' + str(string)
+        self.assertTrue(string.IsValid(), 'std::string should be valid')
+        self.assertFalse(string.IsTypeComplete(), 'std::string complete but it should not be')
+
+        self.runCmd('type category enable gnu-libstdc++', check=False)
+        self.runCmd('frame variable guy --show-types')
+
+        p_vector = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('p')
+        p_type = p_vector.GetType()
+        self.assertTrue(p_type.IsTypeComplete(), 'vector<T> should now be complete')
+        name_address_type = p_type.GetTemplateArgumentType(0)
+        self.assertTrue(name_address_type.IsValid(), 'NameAndAddress should be valid')
+        self.assertTrue(name_address_type.IsTypeComplete(), 'NameAndAddress should now be complete')
+        field0 = name_address_type.GetFieldAtIndex(0)
+        self.assertTrue(field0.IsValid(), 'NameAndAddress::m_name should be valid')
+        string = field0.GetType().GetPointeeType()
+        self.assertTrue(string.IsValid(), 'std::string should be valid')
+        self.assertTrue(string.IsTypeComplete(), 'std::string should now be complete')
+
+if __name__ == '__main__':
+    import atexit
+    lldb.SBDebugger.Initialize()
+    atexit.register(lambda: lldb.SBDebugger.Terminate())
+    unittest2.main()

Added: lldb/trunk/test/functionalities/type_completion/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/type_completion/main.cpp?rev=153363&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/type_completion/main.cpp (added)
+++ lldb/trunk/test/functionalities/type_completion/main.cpp Fri Mar 23 20:11:14 2012
@@ -0,0 +1,52 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <string>
+#include <vector>
+#include <iostream>
+
+class NameAndAddress
+	{
+	public:
+		std::string& GetName() { return *m_name; }
+		std::string& GetAddress() { return *m_address; }
+		NameAndAddress(const char* N, const char* A) : m_name(new std::string(N)), m_address(new std::string(A))
+		{
+		}
+		~NameAndAddress()
+		{
+		}
+		
+	private:
+		std::string* m_name;
+		std::string* m_address;
+};
+
+typedef std::vector<NameAndAddress> People;
+
+int main (int argc, const char * argv[])
+{
+	People p;
+	p.push_back(NameAndAddress("Enrico","123 Main Street"));
+	p.push_back(NameAndAddress("Foo","10710 Johnson Avenue")); // Set break point at this line.
+	p.push_back(NameAndAddress("Arpia","6956 Florey Street"));
+	p.push_back(NameAndAddress("Apple","1 Infinite Loop"));
+	p.push_back(NameAndAddress("Richard","9500 Gilman Drive"));
+	p.push_back(NameAndAddress("Bar","3213 Windsor Rd"));
+
+	for (int j = 0; j<p.size(); j++)
+	{
+		NameAndAddress guy = p[j];
+		std::cout << "Person " << j << " is named " << guy.GetName() << " and lives at " << guy.GetAddress() << std::endl;
+	}
+
+	return 0;
+	
+}
+





More information about the lldb-commits mailing list