Fix ObjCMethodDecl::findPropertyDecl for class properties.

This affects code completion and a few other things; hopefully the code completion
test is sufficient to catch regressions.

llvm-svn: 263295
This commit is contained in:
Jordan Rose 2016-03-11 21:14:40 +00:00
parent 60e53cdcb7
commit 31cf7d49db
2 changed files with 40 additions and 9 deletions

View File

@ -1234,23 +1234,29 @@ ObjCMethodDecl::findPropertyDecl(bool CheckOverrides) const {
if (NumArgs > 1) if (NumArgs > 1)
return nullptr; return nullptr;
if (!isInstanceMethod())
return nullptr;
if (isPropertyAccessor()) { if (isPropertyAccessor()) {
const ObjCContainerDecl *Container = cast<ObjCContainerDecl>(getParent()); const ObjCContainerDecl *Container = cast<ObjCContainerDecl>(getParent());
bool IsGetter = (NumArgs == 0); bool IsGetter = (NumArgs == 0);
bool IsInstance = isInstanceMethod();
/// Local function that attempts to find a matching property within the /// Local function that attempts to find a matching property within the
/// given Objective-C container. /// given Objective-C container.
auto findMatchingProperty = auto findMatchingProperty =
[&](const ObjCContainerDecl *Container) -> const ObjCPropertyDecl * { [&](const ObjCContainerDecl *Container) -> const ObjCPropertyDecl * {
if (IsInstance) {
for (const auto *I : Container->instance_properties()) { for (const auto *I : Container->instance_properties()) {
Selector NextSel = IsGetter ? I->getGetterName() Selector NextSel = IsGetter ? I->getGetterName()
: I->getSetterName(); : I->getSetterName();
if (NextSel == Sel) if (NextSel == Sel)
return I; return I;
}
} else {
for (const auto *I : Container->class_properties()) {
Selector NextSel = IsGetter ? I->getGetterName()
: I->getSetterName();
if (NextSel == Sel)
return I;
}
} }
return nullptr; return nullptr;

View File

@ -0,0 +1,25 @@
// Note: the run lines follow their respective tests, since line/column
// matter in this test.
@interface Base
@end
@interface Test : Base
/// Instance!
@property id instanceProp;
/// Class!
@property (class) id classProp;
@end
void test(Test *obj) {
[obj instanceProp];
[Test classProp];
}
// RUN: %clang_cc1 -fsyntax-only -code-completion-brief-comments -code-completion-at=%s:15:8 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
// CHECK-CC1: instanceProp : [#id#]instanceProp : Instance!
// CHECK-CC1: setInstanceProp: : [#void#]setInstanceProp:<#(id)#> : Instance!
// RUN: %clang_cc1 -fsyntax-only -code-completion-brief-comments -code-completion-at=%s:16:9 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
// CHECK-CC2: classProp : [#id#]classProp : Class!
// CHECK-CC2: setClassProp: : [#void#]setClassProp:<#(id)#> : Class!