[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