summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaExprObjC.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2011-06-12 15:46:16 +0000
committerdim <dim@FreeBSD.org>2011-06-12 15:46:16 +0000
commitc49018d9cce52d8c9f34b44865ec3ba8e89a1488 (patch)
treec5e9e10bc189de0058aa763c47b9920a8351b7df /lib/Sema/SemaExprObjC.cpp
parent110eaaceddcec790f7e6a5e3bf1261c9aa1e73ab (diff)
downloadFreeBSD-src-c49018d9cce52d8c9f34b44865ec3ba8e89a1488.zip
FreeBSD-src-c49018d9cce52d8c9f34b44865ec3ba8e89a1488.tar.gz
Vendor import of clang trunk r132879:
http://llvm.org/svn/llvm-project/cfe/trunk@132879
Diffstat (limited to 'lib/Sema/SemaExprObjC.cpp')
-rw-r--r--lib/Sema/SemaExprObjC.cpp119
1 files changed, 105 insertions, 14 deletions
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 2a262f0..cb5c1e0 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -119,7 +119,7 @@ ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
return new (Context) ObjCStringLiteral(S, Ty, AtLocs[0]);
}
-Expr *Sema::BuildObjCEncodeExpression(SourceLocation AtLoc,
+ExprResult Sema::BuildObjCEncodeExpression(SourceLocation AtLoc,
TypeSourceInfo *EncodedTypeInfo,
SourceLocation RParenLoc) {
QualType EncodedType = EncodedTypeInfo->getType();
@@ -127,6 +127,12 @@ Expr *Sema::BuildObjCEncodeExpression(SourceLocation AtLoc,
if (EncodedType->isDependentType())
StrTy = Context.DependentTy;
else {
+ if (!EncodedType->getAsArrayTypeUnsafe()) // Incomplete array is handled.
+ if (RequireCompleteType(AtLoc, EncodedType,
+ PDiag(diag::err_incomplete_type_objc_at_encode)
+ << EncodedTypeInfo->getTypeLoc().getSourceRange()))
+ return ExprError();
+
std::string Str;
Context.getObjCEncodingForType(EncodedType, Str);
@@ -235,10 +241,72 @@ ObjCMethodDecl *Sema::tryCaptureObjCSelf() {
return method;
}
+QualType Sema::getMessageSendResultType(QualType ReceiverType,
+ ObjCMethodDecl *Method,
+ bool isClassMessage, bool isSuperMessage) {
+ assert(Method && "Must have a method");
+ if (!Method->hasRelatedResultType())
+ return Method->getSendResultType();
+
+ // If a method has a related return type:
+ // - if the method found is an instance method, but the message send
+ // was a class message send, T is the declared return type of the method
+ // found
+ if (Method->isInstanceMethod() && isClassMessage)
+ return Method->getSendResultType();
+
+ // - if the receiver is super, T is a pointer to the class of the
+ // enclosing method definition
+ if (isSuperMessage) {
+ if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
+ if (ObjCInterfaceDecl *Class = CurMethod->getClassInterface())
+ return Context.getObjCObjectPointerType(
+ Context.getObjCInterfaceType(Class));
+ }
+
+ // - if the receiver is the name of a class U, T is a pointer to U
+ if (ReceiverType->getAs<ObjCInterfaceType>() ||
+ ReceiverType->isObjCQualifiedInterfaceType())
+ return Context.getObjCObjectPointerType(ReceiverType);
+ // - if the receiver is of type Class or qualified Class type,
+ // T is the declared return type of the method.
+ if (ReceiverType->isObjCClassType() ||
+ ReceiverType->isObjCQualifiedClassType())
+ return Method->getSendResultType();
+
+ // - if the receiver is id, qualified id, Class, or qualified Class, T
+ // is the receiver type, otherwise
+ // - T is the type of the receiver expression.
+ return ReceiverType;
+}
+
+void Sema::EmitRelatedResultTypeNote(const Expr *E) {
+ E = E->IgnoreParenImpCasts();
+ const ObjCMessageExpr *MsgSend = dyn_cast<ObjCMessageExpr>(E);
+ if (!MsgSend)
+ return;
+
+ const ObjCMethodDecl *Method = MsgSend->getMethodDecl();
+ if (!Method)
+ return;
+
+ if (!Method->hasRelatedResultType())
+ return;
+
+ if (Context.hasSameUnqualifiedType(Method->getResultType()
+ .getNonReferenceType(),
+ MsgSend->getType()))
+ return;
+
+ Diag(Method->getLocation(), diag::note_related_result_type_inferred)
+ << Method->isInstanceMethod() << Method->getSelector()
+ << MsgSend->getType();
+}
-bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
+bool Sema::CheckMessageArgumentTypes(QualType ReceiverType,
+ Expr **Args, unsigned NumArgs,
Selector Sel, ObjCMethodDecl *Method,
- bool isClassMessage,
+ bool isClassMessage, bool isSuperMessage,
SourceLocation lbrac, SourceLocation rbrac,
QualType &ReturnType, ExprValueKind &VK) {
if (!Method) {
@@ -262,7 +330,8 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
return false;
}
- ReturnType = Method->getSendResultType();
+ ReturnType = getMessageSendResultType(ReceiverType, Method, isClassMessage,
+ isSuperMessage);
VK = Expr::getValueKindForType(Method->getResultType());
unsigned NumNamedArgs = Sel.getNumArgs();
@@ -450,9 +519,12 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
ResTy = ResTy.getNonLValueExprType(Context);
Selector Sel = PP.getSelectorTable().getNullarySelector(Member);
ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel);
- if (DiagnosePropertyAccessorMismatch(PD, Getter, MemberLoc))
- ResTy = Getter->getResultType();
-
+ if (Getter &&
+ (Getter->hasRelatedResultType()
+ || DiagnosePropertyAccessorMismatch(PD, Getter, MemberLoc)))
+ ResTy = getMessageSendResultType(QualType(OPT, 0), Getter, false,
+ Super);
+
if (Super)
return Owned(new (Context) ObjCPropertyRefExpr(PD, ResTy,
VK_LValue, OK_ObjCProperty,
@@ -470,14 +542,18 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
// Check whether we can reference this property.
if (DiagnoseUseOfDecl(PD, MemberLoc))
return ExprError();
+
+ QualType T = PD->getType();
+ if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
+ T = getMessageSendResultType(QualType(OPT, 0), Getter, false, Super);
if (Super)
- return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(),
+ return Owned(new (Context) ObjCPropertyRefExpr(PD, T,
VK_LValue,
OK_ObjCProperty,
MemberLoc,
SuperLoc, SuperType));
else
- return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(),
+ return Owned(new (Context) ObjCPropertyRefExpr(PD, T,
VK_LValue,
OK_ObjCProperty,
MemberLoc,
@@ -534,7 +610,7 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
if (Getter || Setter) {
QualType PType;
if (Getter)
- PType = Getter->getSendResultType();
+ PType = getMessageSendResultType(QualType(OPT, 0), Getter, false, Super);
else {
ParmVarDecl *ArgDecl = *Setter->param_begin();
PType = ArgDecl->getType();
@@ -608,10 +684,14 @@ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
IdentifierInfo *receiverNamePtr = &receiverName;
ObjCInterfaceDecl *IFace = getObjCInterfaceDecl(receiverNamePtr,
receiverNameLoc);
+
+ bool IsSuper = false;
if (IFace == 0) {
// If the "receiver" is 'super' in a method, handle it as an expression-like
// property reference.
if (receiverNamePtr->isStr("super")) {
+ IsSuper = true;
+
if (ObjCMethodDecl *CurMethod = tryCaptureObjCSelf()) {
if (CurMethod->isInstanceMethod()) {
QualType T =
@@ -680,7 +760,9 @@ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
ExprValueKind VK = VK_LValue;
if (Getter) {
- PType = Getter->getSendResultType();
+ PType = getMessageSendResultType(Context.getObjCInterfaceType(IFace),
+ Getter, true,
+ receiverNamePtr->isStr("super"));
if (!getLangOptions().CPlusPlus &&
!PType.hasQualifiers() && PType->isVoidType())
VK = VK_RValue;
@@ -693,6 +775,13 @@ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
ExprObjectKind OK = (VK == VK_RValue ? OK_Ordinary : OK_ObjCProperty);
+ if (IsSuper)
+ return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter,
+ PType, VK, OK,
+ propertyNameLoc,
+ receiverNameLoc,
+ Context.getObjCInterfaceType(IFace)));
+
return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter,
PType, VK, OK,
propertyNameLoc,
@@ -949,8 +1038,9 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
unsigned NumArgs = ArgsIn.size();
Expr **Args = reinterpret_cast<Expr **>(ArgsIn.release());
- if (CheckMessageArgumentTypes(Args, NumArgs, Sel, Method, true,
- LBracLoc, RBracLoc, ReturnType, VK))
+ if (CheckMessageArgumentTypes(ReceiverType, Args, NumArgs, Sel, Method, true,
+ SuperLoc.isValid(), LBracLoc, RBracLoc,
+ ReturnType, VK))
return ExprError();
if (Method && !Method->getResultType()->isVoidType() &&
@@ -1232,7 +1322,8 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
ExprValueKind VK = VK_RValue;
bool ClassMessage = (ReceiverType->isObjCClassType() ||
ReceiverType->isObjCQualifiedClassType());
- if (CheckMessageArgumentTypes(Args, NumArgs, Sel, Method, ClassMessage,
+ if (CheckMessageArgumentTypes(ReceiverType, Args, NumArgs, Sel, Method,
+ ClassMessage, SuperLoc.isValid(),
LBracLoc, RBracLoc, ReturnType, VK))
return ExprError();
OpenPOWER on IntegriCloud