1 //===--- SemaExprObjC.cpp - Semantic Analysis for ObjC Expressions --------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements semantic analysis for Objective-C expressions.
12 //===----------------------------------------------------------------------===//
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/DeclObjC.h"
17 #include "clang/AST/ExprObjC.h"
18 #include "clang/Basic/Diagnostic.h"
19 using namespace clang
;
21 Sema::ExprResult
Sema::ParseObjCStringLiteral(SourceLocation
*AtLocs
,
23 unsigned NumStrings
) {
24 SourceLocation AtLoc
= AtLocs
[0];
25 StringLiteral
* S
= static_cast<StringLiteral
*>(Strings
[0]);
27 // Concatenate objc strings.
28 StringLiteral
* ES
= static_cast<StringLiteral
*>(Strings
[NumStrings
-1]);
29 SourceLocation EndLoc
= ES
->getSourceRange().getEnd();
31 for (unsigned i
= 0; i
< NumStrings
; i
++)
32 Length
+= static_cast<StringLiteral
*>(Strings
[i
])->getByteLength();
33 char *strBuf
= new char [Length
];
36 for (unsigned i
= 0; i
< NumStrings
; i
++) {
37 S
= static_cast<StringLiteral
*>(Strings
[i
]);
40 memcpy(p
, S
->getStrData(), S
->getByteLength());
41 p
+= S
->getByteLength();
44 S
= new StringLiteral(strBuf
, Length
,
45 isWide
, Context
.getPointerType(Context
.CharTy
),
49 if (CheckBuiltinCFStringArgument(S
))
52 if (Context
.getObjCConstantStringInterface().isNull()) {
53 // Initialize the constant string interface lazily. This assumes
54 // the NSConstantString interface is seen in this translation unit.
55 IdentifierInfo
*NSIdent
= &Context
.Idents
.get("NSConstantString");
56 Decl
*IFace
= LookupDecl(NSIdent
, Decl::IDNS_Ordinary
, TUScope
);
57 ObjCInterfaceDecl
*strIFace
= dyn_cast_or_null
<ObjCInterfaceDecl
>(IFace
);
59 Context
.setObjCConstantStringInterface(strIFace
);
61 QualType t
= Context
.getObjCConstantStringInterface();
62 // If there is no NSConstantString interface defined then treat constant
63 // strings as untyped objects and let the runtime figure it out later.
64 if (t
== QualType()) {
65 t
= Context
.getObjCIdType();
67 t
= Context
.getPointerType(t
);
69 return new ObjCStringLiteral(S
, t
, AtLoc
);
72 Sema::ExprResult
Sema::ParseObjCEncodeExpression(SourceLocation AtLoc
,
73 SourceLocation EncodeLoc
,
74 SourceLocation LParenLoc
,
76 SourceLocation RParenLoc
) {
77 QualType EncodedType
= QualType::getFromOpaquePtr(Ty
);
79 QualType t
= Context
.getPointerType(Context
.CharTy
);
80 return new ObjCEncodeExpr(t
, EncodedType
, AtLoc
, RParenLoc
);
83 Sema::ExprResult
Sema::ParseObjCSelectorExpression(Selector Sel
,
85 SourceLocation SelLoc
,
86 SourceLocation LParenLoc
,
87 SourceLocation RParenLoc
) {
88 QualType t
= Context
.getObjCSelType();
89 return new ObjCSelectorExpr(t
, Sel
, AtLoc
, RParenLoc
);
92 Sema::ExprResult
Sema::ParseObjCProtocolExpression(IdentifierInfo
*ProtocolId
,
94 SourceLocation ProtoLoc
,
95 SourceLocation LParenLoc
,
96 SourceLocation RParenLoc
) {
97 ObjCProtocolDecl
* PDecl
= ObjCProtocols
[ProtocolId
];
99 Diag(ProtoLoc
, diag::err_undeclared_protocol
, ProtocolId
->getName());
103 QualType t
= Context
.getObjCProtoType();
106 t
= Context
.getPointerType(t
);
107 return new ObjCProtocolExpr(t
, PDecl
, AtLoc
, RParenLoc
);
110 bool Sema::CheckMessageArgumentTypes(Expr
**Args
, unsigned NumArgs
,
111 Selector Sel
, ObjCMethodDecl
*Method
,
112 const char *PrefixStr
,
113 SourceLocation lbrac
, SourceLocation rbrac
,
114 QualType
&ReturnType
) {
116 // Apply default argument promotion as for (C99 6.5.2.2p6).
117 for (unsigned i
= 0; i
!= NumArgs
; i
++)
118 DefaultArgumentPromotion(Args
[i
]);
120 Diag(lbrac
, diag::warn_method_not_found
, std::string(PrefixStr
),
121 Sel
.getName(), SourceRange(lbrac
, rbrac
));
122 ReturnType
= Context
.getObjCIdType();
125 ReturnType
= Method
->getResultType();
128 unsigned NumNamedArgs
= Sel
.getNumArgs();
129 assert(NumArgs
>= NumNamedArgs
&& "Too few arguments for selector!");
131 bool anyIncompatibleArgs
= false;
132 for (unsigned i
= 0; i
< NumNamedArgs
; i
++) {
133 Expr
*argExpr
= Args
[i
];
134 assert(argExpr
&& "CheckMessageArgumentTypes(): missing expression");
136 QualType lhsType
= Method
->getParamDecl(i
)->getType();
137 QualType rhsType
= argExpr
->getType();
139 // If necessary, apply function/array conversion. C99 6.7.5.3p[7,8].
140 if (lhsType
->isArrayType())
141 lhsType
= Context
.getArrayDecayedType(lhsType
);
142 else if (lhsType
->isFunctionType())
143 lhsType
= Context
.getPointerType(lhsType
);
145 AssignConvertType Result
=
146 CheckSingleAssignmentConstraints(lhsType
, argExpr
);
147 if (Args
[i
] != argExpr
) // The expression was converted.
148 Args
[i
] = argExpr
; // Make sure we store the converted expression.
150 anyIncompatibleArgs
|=
151 DiagnoseAssignmentResult(Result
, argExpr
->getLocStart(), lhsType
, rhsType
,
155 // Promote additional arguments to variadic methods.
156 if (Method
->isVariadic()) {
157 for (unsigned i
= NumNamedArgs
; i
< NumArgs
; ++i
)
158 DefaultArgumentPromotion(Args
[i
]);
160 // Check for extra arguments to non-variadic methods.
161 if (NumArgs
!= NumNamedArgs
) {
162 Diag(Args
[NumNamedArgs
]->getLocStart(),
163 diag::err_typecheck_call_too_many_args
,
164 Method
->getSourceRange(),
165 SourceRange(Args
[NumNamedArgs
]->getLocStart(),
166 Args
[NumArgs
-1]->getLocEnd()));
170 return anyIncompatibleArgs
;
173 // ActOnClassMessage - used for both unary and keyword messages.
174 // ArgExprs is optional - if it is present, the number of expressions
175 // is obtained from Sel.getNumArgs().
176 Sema::ExprResult
Sema::ActOnClassMessage(
178 IdentifierInfo
*receiverName
, Selector Sel
,
179 SourceLocation lbrac
, SourceLocation rbrac
, ExprTy
**Args
, unsigned NumArgs
)
181 assert(receiverName
&& "missing receiver class name");
183 Expr
**ArgExprs
= reinterpret_cast<Expr
**>(Args
);
184 ObjCInterfaceDecl
* ClassDecl
= 0;
185 bool isSuper
= false;
187 if (receiverName
== SuperID
&& getCurMethodDecl()) {
189 ClassDecl
= getCurMethodDecl()->getClassInterface()->getSuperClass();
191 return Diag(lbrac
, diag::error_no_super_class
,
192 getCurMethodDecl()->getClassInterface()->getName());
193 if (getCurMethodDecl()->isInstance()) {
194 QualType superTy
= Context
.getObjCInterfaceType(ClassDecl
);
195 superTy
= Context
.getPointerType(superTy
);
196 ExprResult ReceiverExpr
= new PredefinedExpr(SourceLocation(), superTy
,
197 PredefinedExpr::ObjCSuper
);
198 // We are really in an instance method, redirect.
199 return ActOnInstanceMessage(ReceiverExpr
.Val
, Sel
, lbrac
, rbrac
,
202 // We are sending a message to 'super' within a class method. Do nothing,
203 // the receiver will pass through as 'super' (how convenient:-).
205 ClassDecl
= getObjCInterfaceDecl(receiverName
);
207 // The following code allows for the following GCC-ism:
209 // typedef XCElementDisplayRect XCElementGraphicsRect;
211 // @implementation XCRASlice
212 // - whatever { // Note that XCElementGraphicsRect is a typedef name.
213 // _sGraphicsDelegate =[[XCElementGraphicsRect alloc] init];
216 // If necessary, the following lookup could move to getObjCInterfaceDecl().
218 Decl
*IDecl
= LookupDecl(receiverName
, Decl::IDNS_Ordinary
, 0, false);
219 if (TypedefDecl
*OCTD
= dyn_cast_or_null
<TypedefDecl
>(IDecl
)) {
220 const ObjCInterfaceType
*OCIT
;
221 OCIT
= OCTD
->getUnderlyingType()->getAsObjCInterfaceType();
223 ClassDecl
= OCIT
->getDecl();
226 assert(ClassDecl
&& "missing interface declaration");
227 ObjCMethodDecl
*Method
= 0;
229 Method
= ClassDecl
->lookupClassMethod(Sel
);
231 // If we have an implementation in scope, check "private" methods.
233 if (ObjCImplementationDecl
*ImpDecl
=
234 ObjCImplementations
[ClassDecl
->getIdentifier()])
235 Method
= ImpDecl
->getClassMethod(Sel
);
237 // Look through local category implementations associated with the class.
239 for (unsigned i
= 0; i
< ObjCCategoryImpls
.size() && !Method
; i
++) {
240 if (ObjCCategoryImpls
[i
]->getClassInterface() == ClassDecl
)
241 Method
= ObjCCategoryImpls
[i
]->getClassMethod(Sel
);
245 // Before we give up, check if the selector is an instance method.
247 Method
= ClassDecl
->lookupInstanceMethod(Sel
);
249 if (CheckMessageArgumentTypes(ArgExprs
, NumArgs
, Sel
, Method
, "+",
250 lbrac
, rbrac
, returnType
))
253 // If we have the ObjCInterfaceDecl* for the class that is receiving
254 // the message, use that to construct the ObjCMessageExpr. Otherwise
255 // pass on the IdentifierInfo* for the class.
256 // FIXME: need to do a better job handling 'super' usage within a class
257 // For now, we simply pass the "super" identifier through (which isn't
258 // consistent with instance methods.
260 return new ObjCMessageExpr(receiverName
, Sel
, returnType
, Method
,
261 lbrac
, rbrac
, ArgExprs
, NumArgs
);
263 return new ObjCMessageExpr(ClassDecl
, Sel
, returnType
, Method
,
264 lbrac
, rbrac
, ArgExprs
, NumArgs
);
267 // ActOnInstanceMessage - used for both unary and keyword messages.
268 // ArgExprs is optional - if it is present, the number of expressions
269 // is obtained from Sel.getNumArgs().
270 Sema::ExprResult
Sema::ActOnInstanceMessage(ExprTy
*receiver
, Selector Sel
,
271 SourceLocation lbrac
,
272 SourceLocation rbrac
,
273 ExprTy
**Args
, unsigned NumArgs
) {
274 assert(receiver
&& "missing receiver expression");
276 Expr
**ArgExprs
= reinterpret_cast<Expr
**>(Args
);
277 Expr
*RExpr
= static_cast<Expr
*>(receiver
);
280 QualType ReceiverCType
=
281 Context
.getCanonicalType(RExpr
->getType()).getUnqualifiedType();
283 // Handle messages to id.
284 if (ReceiverCType
== Context
.getCanonicalType(Context
.getObjCIdType()) ||
285 ReceiverCType
->getAsBlockPointerType()) {
286 ObjCMethodDecl
*Method
= LookupInstanceMethodInGlobalPool(
287 Sel
, SourceRange(lbrac
,rbrac
));
289 Method
= FactoryMethodPool
[Sel
].Method
;
290 if (CheckMessageArgumentTypes(ArgExprs
, NumArgs
, Sel
, Method
, "-",
291 lbrac
, rbrac
, returnType
))
293 return new ObjCMessageExpr(RExpr
, Sel
, returnType
, Method
, lbrac
, rbrac
,
297 // Handle messages to Class.
298 if (ReceiverCType
== Context
.getCanonicalType(Context
.getObjCClassType())) {
299 ObjCMethodDecl
*Method
= 0;
300 if (ObjCMethodDecl
*CurMeth
= getCurMethodDecl()) {
301 // If we have an implementation in scope, check "private" methods.
302 if (ObjCInterfaceDecl
*ClassDecl
= CurMeth
->getClassInterface())
303 if (ObjCImplementationDecl
*ImpDecl
=
304 ObjCImplementations
[ClassDecl
->getIdentifier()])
305 Method
= ImpDecl
->getClassMethod(Sel
);
308 Method
= FactoryMethodPool
[Sel
].Method
;
310 Method
= LookupInstanceMethodInGlobalPool(
311 Sel
, SourceRange(lbrac
,rbrac
));
312 if (CheckMessageArgumentTypes(ArgExprs
, NumArgs
, Sel
, Method
, "-",
313 lbrac
, rbrac
, returnType
))
315 return new ObjCMessageExpr(RExpr
, Sel
, returnType
, Method
, lbrac
, rbrac
,
319 ObjCMethodDecl
*Method
= 0;
320 ObjCInterfaceDecl
* ClassDecl
= 0;
322 // We allow sending a message to a qualified ID ("id<foo>"), which is ok as
323 // long as one of the protocols implements the selector (if not, warn).
324 if (ObjCQualifiedIdType
*QIT
= dyn_cast
<ObjCQualifiedIdType
>(ReceiverCType
)) {
326 for (unsigned i
= 0; i
< QIT
->getNumProtocols(); i
++) {
327 ObjCProtocolDecl
*PDecl
= QIT
->getProtocols(i
);
328 if (PDecl
&& (Method
= PDecl
->lookupInstanceMethod(Sel
)))
332 Diag(lbrac
, diag::warn_method_not_found_in_protocol
,
333 std::string("-"), Sel
.getName(),
334 RExpr
->getSourceRange());
335 } else if (const ObjCInterfaceType
*OCIReceiver
=
336 ReceiverCType
->getAsPointerToObjCInterfaceType()) {
337 // We allow sending a message to a pointer to an interface (an object).
339 ClassDecl
= OCIReceiver
->getDecl();
340 // FIXME: consider using LookupInstanceMethodInGlobalPool, since it will be
341 // faster than the following method (which can do *many* linear searches).
342 // The idea is to add class info to InstanceMethodPool.
343 Method
= ClassDecl
->lookupInstanceMethod(Sel
);
346 // Search protocol qualifiers.
347 for (ObjCQualifiedIdType::qual_iterator QI
= OCIReceiver
->qual_begin(),
348 E
= OCIReceiver
->qual_end(); QI
!= E
; ++QI
) {
349 if ((Method
= (*QI
)->lookupInstanceMethod(Sel
)))
354 if (!Method
&& !OCIReceiver
->qual_empty())
355 Diag(lbrac
, diag::warn_method_not_found_in_protocol
,
356 std::string("-"), Sel
.getName(),
357 SourceRange(lbrac
, rbrac
));
359 Diag(lbrac
, diag::error_bad_receiver_type
,
360 RExpr
->getType().getAsString(), RExpr
->getSourceRange());
365 // If we have an implementation in scope, check "private" methods.
367 if (ObjCImplementationDecl
*ImpDecl
=
368 ObjCImplementations
[ClassDecl
->getIdentifier()])
369 Method
= ImpDecl
->getInstanceMethod(Sel
);
370 // If we still haven't found a method, look in the global pool. This
371 // behavior isn't very desirable, however we need it for GCC
374 Method
= LookupInstanceMethodInGlobalPool(
375 Sel
, SourceRange(lbrac
,rbrac
));
377 if (CheckMessageArgumentTypes(ArgExprs
, NumArgs
, Sel
, Method
, "-",
378 lbrac
, rbrac
, returnType
))
380 return new ObjCMessageExpr(RExpr
, Sel
, returnType
, Method
, lbrac
, rbrac
,
384 //===----------------------------------------------------------------------===//
385 // ObjCQualifiedIdTypesAreCompatible - Compatibility testing for qualified id's.
386 //===----------------------------------------------------------------------===//
388 /// ProtocolCompatibleWithProtocol - return 'true' if 'lProto' is in the
389 /// inheritance hierarchy of 'rProto'.
390 static bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl
*lProto
,
391 ObjCProtocolDecl
*rProto
) {
392 if (lProto
== rProto
)
394 for (ObjCProtocolDecl::protocol_iterator PI
= rProto
->protocol_begin(),
395 E
= rProto
->protocol_end(); PI
!= E
; ++PI
)
396 if (ProtocolCompatibleWithProtocol(lProto
, *PI
))
401 /// ClassImplementsProtocol - Checks that 'lProto' protocol
402 /// has been implemented in IDecl class, its super class or categories (if
403 /// lookupCategory is true).
404 static bool ClassImplementsProtocol(ObjCProtocolDecl
*lProto
,
405 ObjCInterfaceDecl
*IDecl
,
407 bool RHSIsQualifiedID
= false) {
409 // 1st, look up the class.
410 const ObjCList
<ObjCProtocolDecl
> &Protocols
=
411 IDecl
->getReferencedProtocols();
413 for (ObjCList
<ObjCProtocolDecl
>::iterator PI
= Protocols
.begin(),
414 E
= Protocols
.end(); PI
!= E
; ++PI
) {
415 if (ProtocolCompatibleWithProtocol(lProto
, *PI
))
417 // This is dubious and is added to be compatible with gcc.
418 // In gcc, it is also allowed assigning a protocol-qualified 'id'
419 // type to a LHS object when protocol in qualified LHS is in list
420 // of protocols in the rhs 'id' object. This IMO, should be a bug.
421 // FIXME: Treat this as an extension, and flag this as an error when
422 // GCC extensions are not enabled.
423 if (RHSIsQualifiedID
&& ProtocolCompatibleWithProtocol(*PI
, lProto
))
427 // 2nd, look up the category.
429 for (ObjCCategoryDecl
*CDecl
= IDecl
->getCategoryList(); CDecl
;
430 CDecl
= CDecl
->getNextClassCategory()) {
431 for (ObjCCategoryDecl::protocol_iterator PI
= CDecl
->protocol_begin(),
432 E
= CDecl
->protocol_end(); PI
!= E
; ++PI
)
433 if (ProtocolCompatibleWithProtocol(lProto
, *PI
))
437 // 3rd, look up the super class(s)
438 if (IDecl
->getSuperClass())
440 ClassImplementsProtocol(lProto
, IDecl
->getSuperClass(), lookupCategory
,
446 /// ObjCQualifiedIdTypesAreCompatible - We know that one of lhs/rhs is an
447 /// ObjCQualifiedIDType.
448 bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs
, QualType rhs
,
450 // Allow id<P..> and an 'id' or void* type in all cases.
451 if (const PointerType
*PT
= lhs
->getAsPointerType()) {
452 QualType PointeeTy
= PT
->getPointeeType();
453 if (Context
.isObjCIdType(PointeeTy
) || PointeeTy
->isVoidType())
455 } else if (const PointerType
*PT
= rhs
->getAsPointerType()) {
456 QualType PointeeTy
= PT
->getPointeeType();
457 if (Context
.isObjCIdType(PointeeTy
) || PointeeTy
->isVoidType())
461 if (const ObjCQualifiedIdType
*lhsQID
= lhs
->getAsObjCQualifiedIdType()) {
462 const ObjCQualifiedIdType
*rhsQID
= rhs
->getAsObjCQualifiedIdType();
463 const ObjCQualifiedInterfaceType
*rhsQI
= 0;
467 // Not comparing two ObjCQualifiedIdType's?
468 if (!rhs
->isPointerType()) return false;
470 rtype
= rhs
->getAsPointerType()->getPointeeType();
471 rhsQI
= rtype
->getAsObjCQualifiedInterfaceType();
473 // If the RHS is a unqualified interface pointer "NSString*",
474 // make sure we check the class hierarchy.
475 if (const ObjCInterfaceType
*IT
= rtype
->getAsObjCInterfaceType()) {
476 ObjCInterfaceDecl
*rhsID
= IT
->getDecl();
477 for (unsigned i
= 0; i
!= lhsQID
->getNumProtocols(); ++i
) {
478 // when comparing an id<P> on lhs with a static type on rhs,
479 // see if static class implements all of id's protocols, directly or
480 // through its super class and categories.
481 if (!ClassImplementsProtocol(lhsQID
->getProtocols(i
), rhsID
, true))
489 ObjCQualifiedIdType::qual_iterator RHSProtoI
, RHSProtoE
;
490 if (rhsQI
) { // We have a qualified interface (e.g. "NSObject<Proto> *").
491 RHSProtoI
= rhsQI
->qual_begin();
492 RHSProtoE
= rhsQI
->qual_end();
493 } else if (rhsQID
) { // We have a qualified id (e.g. "id<Proto> *").
494 RHSProtoI
= rhsQID
->qual_begin();
495 RHSProtoE
= rhsQID
->qual_end();
500 for (unsigned i
=0; i
< lhsQID
->getNumProtocols(); i
++) {
501 ObjCProtocolDecl
*lhsProto
= lhsQID
->getProtocols(i
);
504 // when comparing an id<P> on lhs with a static type on rhs,
505 // see if static class implements all of id's protocols, directly or
506 // through its super class and categories.
507 for (; RHSProtoI
!= RHSProtoE
; ++RHSProtoI
) {
508 ObjCProtocolDecl
*rhsProto
= *RHSProtoI
;
509 if (ProtocolCompatibleWithProtocol(lhsProto
, rhsProto
) ||
510 compare
&& ProtocolCompatibleWithProtocol(rhsProto
, lhsProto
)) {
516 // If the RHS is a qualified interface pointer "NSString<P>*",
517 // make sure we check the class hierarchy.
518 if (const ObjCInterfaceType
*IT
= rtype
->getAsObjCInterfaceType()) {
519 ObjCInterfaceDecl
*rhsID
= IT
->getDecl();
520 for (unsigned i
= 0; i
!= lhsQID
->getNumProtocols(); ++i
) {
521 // when comparing an id<P> on lhs with a static type on rhs,
522 // see if static class implements all of id's protocols, directly or
523 // through its super class and categories.
524 if (ClassImplementsProtocol(lhsQID
->getProtocols(i
), rhsID
, true)) {
538 const ObjCQualifiedIdType
*rhsQID
= rhs
->getAsObjCQualifiedIdType();
539 assert(rhsQID
&& "One of the LHS/RHS should be id<x>");
541 if (!lhs
->isPointerType())
544 QualType ltype
= lhs
->getAsPointerType()->getPointeeType();
545 if (const ObjCQualifiedInterfaceType
*lhsQI
=
546 ltype
->getAsObjCQualifiedInterfaceType()) {
547 ObjCQualifiedIdType::qual_iterator LHSProtoI
= lhsQI
->qual_begin();
548 ObjCQualifiedIdType::qual_iterator LHSProtoE
= lhsQI
->qual_end();
549 for (; LHSProtoI
!= LHSProtoE
; ++LHSProtoI
) {
551 ObjCProtocolDecl
*lhsProto
= *LHSProtoI
;
552 for (unsigned j
= 0; j
< rhsQID
->getNumProtocols(); j
++) {
553 ObjCProtocolDecl
*rhsProto
= rhsQID
->getProtocols(j
);
554 if (ProtocolCompatibleWithProtocol(lhsProto
, rhsProto
) ||
555 compare
&& ProtocolCompatibleWithProtocol(rhsProto
, lhsProto
)) {
566 if (const ObjCInterfaceType
*IT
= ltype
->getAsObjCInterfaceType()) {
567 // for static type vs. qualified 'id' type, check that class implements
568 // all of 'id's protocols.
569 ObjCInterfaceDecl
*lhsID
= IT
->getDecl();
570 for (unsigned j
= 0; j
< rhsQID
->getNumProtocols(); j
++) {
571 ObjCProtocolDecl
*rhsProto
= rhsQID
->getProtocols(j
);
572 if (!ClassImplementsProtocol(rhsProto
, lhsID
, compare
, true))