Updated Clang to take an enhancement to the way

we handle Objective-C method calls.  Currently,
LLDB treats the result of an Objective-C method
as unknown if the type information doesn't have
the method's signature.  Now Clang can cast the
result to id if it isn't explicitly cast.

I also added a test case for this, as well as a
fix for a type import problem that this feature
exposed.

llvm-svn: 146756
This commit is contained in:
Sean Callanan 2011-12-16 21:06:35 +00:00
parent 300237f00c
commit bb12004c38
7 changed files with 81 additions and 16 deletions

View File

@ -48,6 +48,11 @@ public:
clang::ASTContext *src_ctx,
clang::Decl *decl);
lldb::clang_type_t
DeportType (clang::ASTContext *dst_ctx,
clang::ASTContext *src_ctx,
lldb::clang_type_t type);
clang::Decl *
DeportDecl (clang::ASTContext *dst_ctx,
clang::ASTContext *src_ctx,

View File

@ -21,8 +21,8 @@ our ($llvm_clang_basename, $llvm_clang_dirname) = fileparse ($llvm_clang_outfile
our $llvm_configuration = $ENV{LLVM_CONFIGURATION};
our $llvm_revision = "145552";
our $clang_revision = "145552";
our $llvm_revision = "146622";
our $clang_revision = "146622";
our $SRCROOT = "$ENV{SRCROOT}";
our $llvm_dstroot_zip = "$SRCROOT/llvm.zip";

View File

@ -1,13 +1,13 @@
Index: lib/AST/RecordLayoutBuilder.cpp
===================================================================
--- lib/AST/RecordLayoutBuilder.cpp (revision 145552)
--- lib/AST/RecordLayoutBuilder.cpp (revision 146622)
+++ lib/AST/RecordLayoutBuilder.cpp (working copy)
@@ -2049,6 +2049,10 @@
@@ -2062,6 +2062,10 @@
// as soon as we begin to parse the definition. That definition is
// not a complete definition (which is what isDefinition() tests)
// until we *finish* parsing the definition.
+
+ if (D->hasExternalLexicalStorage())
+ if (D->hasExternalLexicalStorage() && !D->getDefinition())
+ getExternalSource()->CompleteType(const_cast<RecordDecl*>(D));
+
D = D->getDefinition();

View File

@ -1,6 +1,6 @@
Index: lib/AST/ASTImporter.cpp
===================================================================
--- lib/AST/ASTImporter.cpp (revision 145552)
--- lib/AST/ASTImporter.cpp (revision 146622)
+++ lib/AST/ASTImporter.cpp (working copy)
@@ -2300,7 +2300,8 @@
@ -14,9 +14,9 @@ Index: lib/AST/ASTImporter.cpp
// function.
Index: lib/AST/Decl.cpp
===================================================================
--- lib/AST/Decl.cpp (revision 145552)
--- lib/AST/Decl.cpp (revision 146622)
+++ lib/AST/Decl.cpp (working copy)
@@ -2420,8 +2420,14 @@
@@ -2421,8 +2421,14 @@
ExternalASTSource::Deserializing TheFields(Source);
SmallVector<Decl*, 64> Decls;
@ -35,9 +35,9 @@ Index: lib/AST/Decl.cpp
Index: include/clang/AST/DeclBase.h
===================================================================
--- include/clang/AST/DeclBase.h (revision 145552)
--- include/clang/AST/DeclBase.h (revision 146622)
+++ include/clang/AST/DeclBase.h (working copy)
@@ -824,6 +824,12 @@
@@ -836,6 +836,12 @@
/// storage that contains additional declarations that are visible
/// in this context.
mutable unsigned ExternalVisibleStorage : 1;
@ -50,7 +50,7 @@ Index: include/clang/AST/DeclBase.h
/// \brief Pointer to the data structure used to lookup declarations
/// within this context (or a DependentStoredDeclsMap if this is a
@@ -851,8 +857,8 @@
@@ -863,8 +869,8 @@
DeclContext(Decl::Kind K)
: DeclKind(K), ExternalLexicalStorage(false),
@ -61,7 +61,7 @@ Index: include/clang/AST/DeclBase.h
public:
~DeclContext();
@@ -1356,6 +1362,14 @@
@@ -1368,6 +1374,14 @@
ExternalVisibleStorage = ES;
}

View File

@ -444,9 +444,9 @@ ClangExpressionDeclMap::AddPersistentVariable
ASTContext *context(target->GetScratchClangASTContext()->getASTContext());
TypeFromUser user_type(m_ast_importer->CopyType(context,
parser_type.GetASTContext(),
parser_type.GetOpaqueQualType()),
TypeFromUser user_type(m_ast_importer->DeportType(context,
parser_type.GetASTContext(),
parser_type.GetOpaqueQualType()),
context);
if (!user_type.GetOpaqueQualType())

View File

@ -71,6 +71,39 @@ ClangASTImporter::CopyDecl (clang::ASTContext *dst_ast,
return NULL;
}
lldb::clang_type_t
ClangASTImporter::DeportType (clang::ASTContext *dst_ctx,
clang::ASTContext *src_ctx,
lldb::clang_type_t type)
{
lldb::clang_type_t result = CopyType(dst_ctx, src_ctx, type);
if (!result)
return NULL;
QualType qual_type = QualType::getFromOpaquePtr(type);
if (const TagType *tag_type = qual_type->getAs<TagType>())
{
TagDecl *tag_decl = tag_type->getDecl();
const TagType *result_tag_type = QualType::getFromOpaquePtr(result)->getAs<TagType>();
TagDecl *result_tag_decl = result_tag_type->getDecl();
if (tag_decl)
{
MinionSP minion_sp (GetMinion (dst_ctx, src_ctx));
minion_sp->ImportDefinition(tag_decl);
ASTContextMetadataSP to_context_md = GetContextMetadata(dst_ctx);
to_context_md->m_origins.erase(result_tag_decl);
}
}
return result;
}
clang::Decl *
ClangASTImporter::DeportDecl (clang::ASTContext *dst_ctx,
clang::ASTContext *src_ctx,
@ -398,7 +431,7 @@ clang::Decl
if (to_interface_decl->isForwardDecl())
to_interface_decl->completedForwardDecl();
to_interface_decl->setExternallyCompleted();
if (log)

View File

@ -52,6 +52,16 @@ class FoundationTestCase2(TestBase):
self.buildDwarf()
self.MyString_dump()
def test_NSError_po_with_dsym(self):
"""Test that po of the result of an unknown method doesn't require a cast."""
self.buildDsym()
self.NSError_po()
def test_NSError_po_with_dwarf(self):
"""Test that po of the result of an unknown method doesn't require a cast."""
self.buildDsym()
self.NSError_po()
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
@ -177,6 +187,23 @@ class FoundationTestCase2(TestBase):
patterns = ["\(MyString\) \$.* = ", "\(MyBase\)", "\(NSObject\)", "\(Class\)"])
self.runCmd("process continue")
def NSError_po(self):
"""Test that po of the result of an unknown method doesn't require a cast."""
exe = os.path.join(os.getcwd(), "a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
line = self.lines[4]
self.expect("breakpoint set -f main.m -l %d" % line, BREAKPOINT_CREATED,
substrs = ["Breakpoint created:",
"file ='main.m', line = %d, locations = 1" % line])
self.runCmd("run", RUN_SUCCEEDED)
self.expect("po [NSError errorWithDomain:@\"Hello\" code:35 userInfo:nil]",
patterns = ["\(id\) \$.* = ", "Error Domain=Hello", "Code=35", "be completed."])
self.runCmd("process continue")
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()