factor the code that handles "expr.field" when expr is a
pointer to an objc interface out to a method in SemaExprObjC.
This is *much* uglier than it should be due to grossness in
LookupMemberExpr :(
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@100957 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 3250870..9892159 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -3845,6 +3845,13 @@
ObjCMethodDecl *LookupPrivateInstanceMethod(Selector Sel,
ObjCInterfaceDecl *ClassDecl);
+ Action::OwningExprResult
+ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
+ Expr *&BaseExpr, bool &IsArrow,
+ DeclarationName MemberName,
+ SourceLocation MemberLoc, SourceLocation OpLoc,
+ CXXScopeSpec &SS, DeclPtrTy ObjCImpDecl);
+
virtual OwningExprResult ActOnClassPropertyRefExpr(
IdentifierInfo &receiverName,
IdentifierInfo &propertyName,
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 6820449..c350bb9 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -3140,105 +3140,12 @@
}
// Handle Objective-C property access, which is "Obj.property" where Obj is a
// pointer to a (potentially qualified) interface type.
- const ObjCObjectPointerType *OPT;
- if (!IsArrow && (OPT = BaseType->getAsObjCInterfacePointerType())) {
- const ObjCInterfaceType *IFaceT = OPT->getInterfaceType();
- ObjCInterfaceDecl *IFace = IFaceT->getDecl();
- IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
-
- // Search for a declared property first.
- if (ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(Member)) {
- // Check whether we can reference this property.
- if (DiagnoseUseOfDecl(PD, MemberLoc))
- return ExprError();
- QualType ResTy = PD->getType();
- Selector Sel = PP.getSelectorTable().getNullarySelector(Member);
- ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel);
- if (DiagnosePropertyAccessorMismatch(PD, Getter, MemberLoc))
- ResTy = Getter->getResultType();
- return Owned(new (Context) ObjCPropertyRefExpr(PD, ResTy,
- MemberLoc, BaseExpr));
- }
- // Check protocols on qualified interfaces.
- for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(),
- E = OPT->qual_end(); I != E; ++I)
- if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(Member)) {
- // Check whether we can reference this property.
- if (DiagnoseUseOfDecl(PD, MemberLoc))
- return ExprError();
-
- return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(),
- MemberLoc, BaseExpr));
- }
- // If that failed, look for an "implicit" property by seeing if the nullary
- // selector is implemented.
-
- // FIXME: The logic for looking up nullary and unary selectors should be
- // shared with the code in ActOnInstanceMessage.
-
- Selector Sel = PP.getSelectorTable().getNullarySelector(Member);
- ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel);
-
- // If this reference is in an @implementation, check for 'private' methods.
- if (!Getter)
- Getter = IFace->lookupPrivateInstanceMethod(Sel);
-
- // Look through local category implementations associated with the class.
- if (!Getter)
- Getter = IFace->getCategoryInstanceMethod(Sel);
- if (Getter) {
- // Check if we can reference this property.
- if (DiagnoseUseOfDecl(Getter, MemberLoc))
- return ExprError();
- }
- // If we found a getter then this may be a valid dot-reference, we
- // will look for the matching setter, in case it is needed.
- Selector SetterSel =
- SelectorTable::constructSetterName(PP.getIdentifierTable(),
- PP.getSelectorTable(), Member);
- ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel);
- if (!Setter) {
- // If this reference is in an @implementation, also check for 'private'
- // methods.
- Setter = IFace->lookupPrivateInstanceMethod(SetterSel);
- }
- // Look through local category implementations associated with the class.
- if (!Setter)
- Setter = IFace->getCategoryInstanceMethod(SetterSel);
-
- if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc))
- return ExprError();
-
- if (Getter) {
- QualType PType;
- PType = Getter->getResultType();
- return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(Getter, PType,
- Setter, MemberLoc, BaseExpr));
- }
-
- // Attempt to correct for typos in property names.
- LookupResult Res(*this, R.getLookupName(), R.getNameLoc(),
- LookupOrdinaryName);
- if (CorrectTypo(Res, 0, 0, IFace, false, OPT) &&
- Res.getAsSingle<ObjCPropertyDecl>()) {
- Diag(R.getNameLoc(), diag::err_property_not_found_suggest)
- << MemberName << BaseType << Res.getLookupName()
- << FixItHint::CreateReplacement(R.getNameLoc(),
- Res.getLookupName().getAsString());
- ObjCPropertyDecl *Property = Res.getAsSingle<ObjCPropertyDecl>();
- Diag(Property->getLocation(), diag::note_previous_decl)
- << Property->getDeclName();
-
- return LookupMemberExpr(Res, BaseExpr, IsArrow, OpLoc, SS,
- ObjCImpDecl);
- }
- Diag(MemberLoc, diag::err_property_not_found)
- << MemberName << BaseType;
- if (Setter && !Getter)
- Diag(Setter->getLocation(), diag::note_getter_unavailable)
- << MemberName << BaseExpr->getSourceRange();
- return ExprError();
- }
+ if (!IsArrow)
+ if (const ObjCObjectPointerType *OPT =
+ BaseType->getAsObjCInterfacePointerType())
+ return HandleExprPropertyRefExpr(OPT, BaseExpr, IsArrow,
+ MemberName, MemberLoc,
+ OpLoc, SS, ObjCImpDecl);
// Handle the following exceptional case (*Obj).isa.
if (!IsArrow &&
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index a05687e..86d6938 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "Sema.h"
+#include "Lookup.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/ExprObjC.h"
@@ -289,6 +290,114 @@
return Method;
}
+/// HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an
+/// objective C interface. This is a property reference expression.
+Action::OwningExprResult Sema::
+HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
+ Expr *&BaseExpr, bool &IsArrow,
+ DeclarationName MemberName,
+ SourceLocation MemberLoc, SourceLocation OpLoc,
+ CXXScopeSpec &SS, DeclPtrTy ObjCImpDecl) {
+ assert(!IsArrow && "Should only be called with '.' expressions");
+ const ObjCInterfaceType *IFaceT = OPT->getInterfaceType();
+ ObjCInterfaceDecl *IFace = IFaceT->getDecl();
+ IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
+
+ // Search for a declared property first.
+ if (ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(Member)) {
+ // Check whether we can reference this property.
+ if (DiagnoseUseOfDecl(PD, MemberLoc))
+ return ExprError();
+ QualType ResTy = PD->getType();
+ Selector Sel = PP.getSelectorTable().getNullarySelector(Member);
+ ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel);
+ if (DiagnosePropertyAccessorMismatch(PD, Getter, MemberLoc))
+ ResTy = Getter->getResultType();
+ return Owned(new (Context) ObjCPropertyRefExpr(PD, ResTy,
+ MemberLoc, BaseExpr));
+ }
+ // Check protocols on qualified interfaces.
+ for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(),
+ E = OPT->qual_end(); I != E; ++I)
+ if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(Member)) {
+ // Check whether we can reference this property.
+ if (DiagnoseUseOfDecl(PD, MemberLoc))
+ return ExprError();
+
+ return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(),
+ MemberLoc, BaseExpr));
+ }
+ // If that failed, look for an "implicit" property by seeing if the nullary
+ // selector is implemented.
+
+ // FIXME: The logic for looking up nullary and unary selectors should be
+ // shared with the code in ActOnInstanceMessage.
+
+ Selector Sel = PP.getSelectorTable().getNullarySelector(Member);
+ ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel);
+
+ // If this reference is in an @implementation, check for 'private' methods.
+ if (!Getter)
+ Getter = IFace->lookupPrivateInstanceMethod(Sel);
+
+ // Look through local category implementations associated with the class.
+ if (!Getter)
+ Getter = IFace->getCategoryInstanceMethod(Sel);
+ if (Getter) {
+ // Check if we can reference this property.
+ if (DiagnoseUseOfDecl(Getter, MemberLoc))
+ return ExprError();
+ }
+ // If we found a getter then this may be a valid dot-reference, we
+ // will look for the matching setter, in case it is needed.
+ Selector SetterSel =
+ SelectorTable::constructSetterName(PP.getIdentifierTable(),
+ PP.getSelectorTable(), Member);
+ ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel);
+ if (!Setter) {
+ // If this reference is in an @implementation, also check for 'private'
+ // methods.
+ Setter = IFace->lookupPrivateInstanceMethod(SetterSel);
+ }
+ // Look through local category implementations associated with the class.
+ if (!Setter)
+ Setter = IFace->getCategoryInstanceMethod(SetterSel);
+
+ if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc))
+ return ExprError();
+
+ if (Getter) {
+ QualType PType;
+ PType = Getter->getResultType();
+ return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(Getter, PType,
+ Setter, MemberLoc, BaseExpr));
+ }
+
+ // Attempt to correct for typos in property names.
+ LookupResult Res(*this, MemberName, MemberLoc, LookupOrdinaryName);
+ if (CorrectTypo(Res, 0, 0, IFace, false, OPT) &&
+ Res.getAsSingle<ObjCPropertyDecl>()) {
+ Diag(MemberLoc, diag::err_property_not_found_suggest)
+ << MemberName << QualType(OPT, 0) << Res.getLookupName()
+ << FixItHint::CreateReplacement(MemberLoc,
+ Res.getLookupName().getAsString());
+ ObjCPropertyDecl *Property = Res.getAsSingle<ObjCPropertyDecl>();
+ Diag(Property->getLocation(), diag::note_previous_decl)
+ << Property->getDeclName();
+
+ return LookupMemberExpr(Res, BaseExpr, IsArrow, OpLoc, SS, ObjCImpDecl);
+ }
+ Diag(MemberLoc, diag::err_property_not_found)
+ << MemberName << QualType(OPT, 0);
+ if (Setter && !Getter)
+ Diag(Setter->getLocation(), diag::note_getter_unavailable)
+ << MemberName << BaseExpr->getSourceRange();
+ return ExprError();
+
+}
+
+
+
Action::OwningExprResult Sema::ActOnClassPropertyRefExpr(
IdentifierInfo &receiverName,
IdentifierInfo &propertyName,