Index: lldb/source/Symbol/ClangASTContext.cpp =================================================================== --- lldb/source/Symbol/ClangASTContext.cpp +++ lldb/source/Symbol/ClangASTContext.cpp @@ -8435,9 +8435,11 @@ const bool isInstance = (property_attributes & ObjCPropertyDecl::OBJC_PR_class) == 0; - if (!getter_sel.isNull() && - !(isInstance ? class_interface_decl->lookupInstanceMethod(getter_sel) - : class_interface_decl->lookupClassMethod(getter_sel))) { + clang::ObjCMethodDecl *getter = nullptr; + if (!getter_sel.isNull()) + getter = isInstance ? class_interface_decl->lookupInstanceMethod(getter_sel) + : class_interface_decl->lookupClassMethod(getter_sel); + if (!getter_sel.isNull() && !getter) { const bool isVariadic = false; const bool isPropertyAccessor = false; const bool isSynthesizedAccessorStub = false; @@ -8447,28 +8449,31 @@ clang::ObjCMethodDecl::None; const bool HasRelatedResultType = false; - clang::ObjCMethodDecl *getter = clang::ObjCMethodDecl::Create( + getter = clang::ObjCMethodDecl::Create( *clang_ast, clang::SourceLocation(), clang::SourceLocation(), getter_sel, ClangUtil::GetQualType(property_clang_type_to_access), nullptr, class_interface_decl, isInstance, isVariadic, isPropertyAccessor, isSynthesizedAccessorStub, isImplicitlyDeclared, isDefined, impControl, HasRelatedResultType); - if (getter && metadata) - ClangASTContext::SetMetadata(clang_ast, getter, *metadata); - if (getter) { - getter->setMethodParams(*clang_ast, + if (metadata) + ClangASTContext::SetMetadata(clang_ast, getter, *metadata); + getter->setMethodParams(*clang_ast, llvm::ArrayRef(), llvm::ArrayRef()); - class_interface_decl->addDecl(getter); } } + if (getter) { + getter->setPropertyAccessor(true); + property_decl->setGetterMethodDecl(getter); + } - if (!setter_sel.isNull() && - !(isInstance ? class_interface_decl->lookupInstanceMethod(setter_sel) - : class_interface_decl->lookupClassMethod(setter_sel))) { + clang::ObjCMethodDecl *setter = nullptr; + setter = isInstance ? class_interface_decl->lookupInstanceMethod(setter_sel) + : class_interface_decl->lookupClassMethod(setter_sel); + if (!setter_sel.isNull() && !setter) { clang::QualType result_type = clang_ast->VoidTy; const bool isVariadic = false; const bool isPropertyAccessor = true; @@ -8479,24 +8484,24 @@ clang::ObjCMethodDecl::None; const bool HasRelatedResultType = false; - clang::ObjCMethodDecl *setter = clang::ObjCMethodDecl::Create( + setter = clang::ObjCMethodDecl::Create( *clang_ast, clang::SourceLocation(), clang::SourceLocation(), setter_sel, result_type, nullptr, class_interface_decl, isInstance, isVariadic, isPropertyAccessor, isSynthesizedAccessorStub, isImplicitlyDeclared, isDefined, impControl, HasRelatedResultType); - if (setter && metadata) - ClangASTContext::SetMetadata(clang_ast, setter, *metadata); + if (setter) { + if (metadata) + ClangASTContext::SetMetadata(clang_ast, setter, *metadata); - llvm::SmallVector params; + llvm::SmallVector params; - params.push_back(clang::ParmVarDecl::Create( - *clang_ast, setter, clang::SourceLocation(), clang::SourceLocation(), - nullptr, // anonymous - ClangUtil::GetQualType(property_clang_type_to_access), nullptr, - clang::SC_Auto, nullptr)); + params.push_back(clang::ParmVarDecl::Create( + *clang_ast, setter, clang::SourceLocation(), clang::SourceLocation(), + nullptr, // anonymous + ClangUtil::GetQualType(property_clang_type_to_access), nullptr, + clang::SC_Auto, nullptr)); - if (setter) { setter->setMethodParams(*clang_ast, llvm::ArrayRef(params), llvm::ArrayRef()); @@ -8504,6 +8509,10 @@ class_interface_decl->addDecl(setter); } } + if (setter) { + setter->setPropertyAccessor(true); + property_decl->setSetterMethodDecl(setter); + } return true; } @@ -8939,16 +8948,22 @@ s << type->GetName().AsCString() << "\n"; - if (clang::TagDecl *tag_decl = - GetAsTagDecl(type->GetFullCompilerType())) + CompilerType full_type = type->GetFullCompilerType(); + if (clang::TagDecl *tag_decl = GetAsTagDecl(full_type)) { tag_decl->dump(s.AsRawOstream()); - else if (clang::TypedefNameDecl *typedef_decl = - GetAsTypedefDecl(type->GetFullCompilerType())) + continue; + } + if (clang::TypedefNameDecl *typedef_decl = GetAsTypedefDecl(full_type)) { typedef_decl->dump(s.AsRawOstream()); - else { - GetCanonicalQualType(type->GetFullCompilerType().GetOpaqueQualType()) - .dump(s.AsRawOstream()); + continue; } + if (auto *objc_obj = llvm::dyn_cast( + ClangUtil::GetQualType(full_type).getTypePtr())) + if (clang::ObjCInterfaceDecl *interface_decl = objc_obj->getInterface()) { + interface_decl->dump(s.AsRawOstream()); + continue; + } + GetCanonicalQualType(full_type.GetOpaqueQualType()).dump(s.AsRawOstream()); } } Index: lldb/test/Shell/SymbolFile/DWARF/clang-ast-from-dwarf-objc-property.m =================================================================== --- /dev/null +++ lldb/test/Shell/SymbolFile/DWARF/clang-ast-from-dwarf-objc-property.m @@ -0,0 +1,29 @@ +// REQUIRES: system-darwin +// +// RUN: %clang_host -g -c -o %t.o %s +// RUN: lldb-test symbols -dump-clang-ast %t.o | FileCheck %s + +__attribute__((objc_root_class)) +@interface Root +@property (readonly) int ro_number; +@property int rw_number; +@property (readonly, getter=custom_getter) int manual; +- (int)custom_getter; +@property (class, readonly) int class_property; +@end + +Root *obj; + +// CHECK: |-ObjCPropertyDecl {{.*}} ro_number 'int' readonly +// CHECK: | `-getter ObjCMethod [[READONLY:0x[0-9a-f]+]] 'ro_number' +// CHECK: |-ObjCMethodDecl [[READONLY]] {{.*}} implicit - ro_number 'int' +// CHECK: |-ObjCPropertyDecl {{.*}} rw_number 'int' assign readwrite +// CHECK: | |-getter ObjCMethod {{.*}} 'rw_number' +// CHECK: | `-setter ObjCMethod {{.*}} 'setRw_number:' +// CHECK: |-ObjCPropertyDecl {{.*}} manual 'int' readonly +// CHECK: | `-getter ObjCMethod [[CUSTOM:0x[0-9a-f]+]] 'custom_getter' +// CHECK: |-ObjCMethodDecl [[CUSTOM]] {{.*}} - custom_getter 'int' +// CHECK: |-ObjCPropertyDecl {{.*}} class_property 'int' readonly class +// CHECK: | `-getter ObjCMethod [[CLASS:0x[0-9a-f]+]] 'class_property' +// CHECK: `-ObjCMethodDecl [[CLASS]] {{.*}} + class_property 'int' + Index: lldb/test/Shell/SymbolFile/DWARF/clang-ast-from-dwarf-unamed-and-anon-structs.cpp =================================================================== --- lldb/test/Shell/SymbolFile/DWARF/clang-ast-from-dwarf-unamed-and-anon-structs.cpp +++ lldb/test/Shell/SymbolFile/DWARF/clang-ast-from-dwarf-unamed-and-anon-structs.cpp @@ -1,6 +1,6 @@ // UNSUPPORTED: system-windows // -// Test to verify we are corectly generating anonymous flags when parsing +// Test to verify we are correctly generating anonymous flags when parsing // anonymous class and unnamed structs from DWARF to the a clang AST node. // RUN: %clangxx_host -g -c -o %t.o %s Index: lldb/test/Shell/SymbolFile/DWARF/lit.local.cfg =================================================================== --- lldb/test/Shell/SymbolFile/DWARF/lit.local.cfg +++ lldb/test/Shell/SymbolFile/DWARF/lit.local.cfg @@ -1 +1 @@ -config.suffixes = ['.cpp', '.s', '.test', '.ll'] +config.suffixes = ['.cpp', '.m', '.s', '.test', '.ll'] Index: lldb/tools/lldb-test/lldb-test.cpp =================================================================== --- lldb/tools/lldb-test/lldb-test.cpp +++ lldb/tools/lldb-test/lldb-test.cpp @@ -623,7 +623,7 @@ return make_string_error("Module has no symbol file."); llvm::Expected type_system_or_err = - symfile->GetTypeSystemForLanguage(eLanguageTypeC_plus_plus); + symfile->GetTypeSystemForLanguage(eLanguageTypeObjC_plus_plus); if (!type_system_or_err) return make_string_error("Can't retrieve ClangASTContext");