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;
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<clang::ParmVarDecl *>(),
llvm::ArrayRef<clang::SourceLocation>());
-
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;
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<clang::ParmVarDecl *, 1> params;
+ llvm::SmallVector<clang::ParmVarDecl *, 1> 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<clang::ParmVarDecl *>(params),
llvm::ArrayRef<clang::SourceLocation>());
class_interface_decl->addDecl(setter);
}
}
+ if (setter) {
+ setter->setPropertyAccessor(true);
+ property_decl->setSetterMethodDecl(setter);
+ }
return true;
}
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<clang::ObjCObjectType>(
+ 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());
}
}
--- /dev/null
+// 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'
+