SemaExprObjC.cpp revision fc2eff57d7497578e8f08a5ee520ad3886a51186
185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//===--- SemaExprObjC.cpp - Semantic Analysis for ObjC Expressions --------===//
285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//
385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//                     The LLVM Compiler Infrastructure
485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//
585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// This file is distributed under the University of Illinois Open Source
685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// License. See LICENSE.TXT for details.
785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//
885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//===----------------------------------------------------------------------===//
985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//
1085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//  This file implements semantic analysis for Objective-C expressions.
1185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//
1285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//===----------------------------------------------------------------------===//
1385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
142d88708cbe4e4ec5e04e4acb6bd7f5be68557379John McCall#include "clang/Sema/SemaInternal.h"
15e737f5041a36d0befb39ffeed8d50ba15916d3daDouglas Gregor#include "clang/Sema/Lookup.h"
165f1e0942a32657b625702aa52f82430d0120f424John McCall#include "clang/Sema/Scope.h"
1726743b20e4a8c2a986e6453f0c38beba0afef633John McCall#include "clang/Sema/ScopeInfo.h"
18e737f5041a36d0befb39ffeed8d50ba15916d3daDouglas Gregor#include "clang/Sema/Initialization.h"
192cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall#include "clang/Analysis/DomainSpecific/CocoaConventions.h"
2085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner#include "clang/AST/ASTContext.h"
2185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner#include "clang/AST/DeclObjC.h"
22f494b579b22f9950f5af021f0bf9879a91bb8b41Steve Naroff#include "clang/AST/ExprObjC.h"
23f85e193739c953358c865005855253af4f68a497John McCall#include "clang/AST/StmtVisitor.h"
242725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor#include "clang/AST/TypeLoc.h"
2539c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner#include "llvm/ADT/SmallString.h"
2661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff#include "clang/Lex/Preprocessor.h"
2761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
2885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattnerusing namespace clang;
2926743b20e4a8c2a986e6453f0c38beba0afef633John McCallusing namespace sema;
308d9ed7980405e91a12e33338a78fb99620adf553Argyrios Kyrtzidisusing llvm::makeArrayRef;
3185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
32f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCallExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
33f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                        Expr **strings,
34f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                        unsigned NumStrings) {
3539c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner  StringLiteral **Strings = reinterpret_cast<StringLiteral**>(strings);
3639c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner
37f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  // Most ObjC strings are formed out of a single piece.  However, we *can*
38f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  // have strings formed out of multiple @ strings with multiple pptokens in
39f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  // each one, e.g. @"foo" "bar" @"baz" "qux"   which need to be turned into one
40f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  // StringLiteral for ObjCStringLiteral to hold onto.
4139c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner  StringLiteral *S = Strings[0];
421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
43f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  // If we have a multi-part string, merge it all together.
44f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  if (NumStrings != 1) {
4585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    // Concatenate objc strings.
4639c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner    llvm::SmallString<128> StrBuf;
475f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    SmallVector<SourceLocation, 8> StrLocs;
481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
49726e168dc09fb23f53c7b004f8e919421ee91806Chris Lattner    for (unsigned i = 0; i != NumStrings; ++i) {
5039c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner      S = Strings[i];
511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
525cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor      // ObjC strings can't be wide or UTF.
535cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor      if (!S->isAscii()) {
54f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner        Diag(S->getLocStart(), diag::err_cfstring_literal_not_string_constant)
55f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner          << S->getSourceRange();
56f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner        return true;
57f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner      }
581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
592f4eaef37476ae6891ede8ba215d0f6fd093629bBenjamin Kramer      // Append the string.
602f4eaef37476ae6891ede8ba215d0f6fd093629bBenjamin Kramer      StrBuf += S->getString();
611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6239c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner      // Get the locations of the string tokens.
6339c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner      StrLocs.append(S->tokloc_begin(), S->tokloc_end());
6485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    }
651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6639c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner    // Create the aggregate string with the appropriate content and location
6739c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner    // information.
6865aa6885818d4b4eea2e5a9d12085b2398148662Jay Foad    S = StringLiteral::Create(Context, StrBuf,
695cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor                              StringLiteral::Ascii, /*Pascal=*/false,
702085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner                              Context.getPointerType(Context.CharTy),
7139c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner                              &StrLocs[0], StrLocs.size());
7285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  }
731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
74690398188ea5b428f06aa13c7d4ce6eb741ad4f9Chris Lattner  // Verify that this composite string is acceptable for ObjC strings.
75690398188ea5b428f06aa13c7d4ce6eb741ad4f9Chris Lattner  if (CheckObjCString(S))
7685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    return true;
77a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner
78a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  // Initialize the constant string interface lazily. This assumes
79d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff  // the NSString interface is seen in this translation unit. Note: We
80d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff  // don't use NSConstantString, since the runtime team considers this
81d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff  // interface private (even though it appears in the header files).
82a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  QualType Ty = Context.getObjCConstantStringInterface();
83a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  if (!Ty.isNull()) {
8414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    Ty = Context.getObjCObjectPointerType(Ty);
858a4377697161c5087e27cc40d6e0682f0cd1fa20Fariborz Jahanian  } else if (getLangOptions().NoConstantCFStrings) {
864c73307c74764ba99e1379677fe92af72f676531Fariborz Jahanian    IdentifierInfo *NSIdent=0;
874c73307c74764ba99e1379677fe92af72f676531Fariborz Jahanian    std::string StringClass(getLangOptions().ObjCConstantStringClass);
884c73307c74764ba99e1379677fe92af72f676531Fariborz Jahanian
894c73307c74764ba99e1379677fe92af72f676531Fariborz Jahanian    if (StringClass.empty())
904c73307c74764ba99e1379677fe92af72f676531Fariborz Jahanian      NSIdent = &Context.Idents.get("NSConstantString");
914c73307c74764ba99e1379677fe92af72f676531Fariborz Jahanian    else
924c73307c74764ba99e1379677fe92af72f676531Fariborz Jahanian      NSIdent = &Context.Idents.get(StringClass);
934c73307c74764ba99e1379677fe92af72f676531Fariborz Jahanian
948a4377697161c5087e27cc40d6e0682f0cd1fa20Fariborz Jahanian    NamedDecl *IF = LookupSingleName(TUScope, NSIdent, AtLocs[0],
958a4377697161c5087e27cc40d6e0682f0cd1fa20Fariborz Jahanian                                     LookupOrdinaryName);
968a4377697161c5087e27cc40d6e0682f0cd1fa20Fariborz Jahanian    if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) {
978a4377697161c5087e27cc40d6e0682f0cd1fa20Fariborz Jahanian      Context.setObjCConstantStringInterface(StrIF);
988a4377697161c5087e27cc40d6e0682f0cd1fa20Fariborz Jahanian      Ty = Context.getObjCConstantStringInterface();
998a4377697161c5087e27cc40d6e0682f0cd1fa20Fariborz Jahanian      Ty = Context.getObjCObjectPointerType(Ty);
1008a4377697161c5087e27cc40d6e0682f0cd1fa20Fariborz Jahanian    } else {
1018a4377697161c5087e27cc40d6e0682f0cd1fa20Fariborz Jahanian      // If there is no NSConstantString interface defined then treat this
1028a4377697161c5087e27cc40d6e0682f0cd1fa20Fariborz Jahanian      // as error and recover from it.
1038a4377697161c5087e27cc40d6e0682f0cd1fa20Fariborz Jahanian      Diag(S->getLocStart(), diag::err_no_nsconstant_string_class) << NSIdent
1048a4377697161c5087e27cc40d6e0682f0cd1fa20Fariborz Jahanian        << S->getSourceRange();
1058a4377697161c5087e27cc40d6e0682f0cd1fa20Fariborz Jahanian      Ty = Context.getObjCIdType();
1068a4377697161c5087e27cc40d6e0682f0cd1fa20Fariborz Jahanian    }
10713fd7e5111032f54b538dd66d035b0ccc1f82467Chris Lattner  } else {
108d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff    IdentifierInfo *NSIdent = &Context.Idents.get("NSString");
109c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor    NamedDecl *IF = LookupSingleName(TUScope, NSIdent, AtLocs[0],
110c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor                                     LookupOrdinaryName);
111a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner    if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) {
112a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner      Context.setObjCConstantStringInterface(StrIF);
113a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner      Ty = Context.getObjCConstantStringInterface();
11414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      Ty = Context.getObjCObjectPointerType(Ty);
115a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner    } else {
116d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff      // If there is no NSString interface defined then treat constant
117a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner      // strings as untyped objects and let the runtime figure it out later.
118a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner      Ty = Context.getObjCIdType();
119a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner    }
12013fd7e5111032f54b538dd66d035b0ccc1f82467Chris Lattner  }
1211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
122f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  return new (Context) ObjCStringLiteral(S, Ty, AtLocs[0]);
12385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
12485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
1253b5904ba83fc9b968b1cd6f1ce78d01bfd6e8686Argyrios KyrtzidisExprResult Sema::BuildObjCEncodeExpression(SourceLocation AtLoc,
12681d3466d037dc5844234c7a93dab21a6ad986e7dDouglas Gregor                                      TypeSourceInfo *EncodedTypeInfo,
127fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson                                      SourceLocation RParenLoc) {
12881d3466d037dc5844234c7a93dab21a6ad986e7dDouglas Gregor  QualType EncodedType = EncodedTypeInfo->getType();
129fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson  QualType StrTy;
1301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (EncodedType->isDependentType())
131fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson    StrTy = Context.DependentTy;
132fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson  else {
1336c91615e5d67d59e752037beb475c4b827431172Fariborz Jahanian    if (!EncodedType->getAsArrayTypeUnsafe() && //// Incomplete array is handled.
1346c91615e5d67d59e752037beb475c4b827431172Fariborz Jahanian        !EncodedType->isVoidType()) // void is handled too.
1353b5904ba83fc9b968b1cd6f1ce78d01bfd6e8686Argyrios Kyrtzidis      if (RequireCompleteType(AtLoc, EncodedType,
1363b5904ba83fc9b968b1cd6f1ce78d01bfd6e8686Argyrios Kyrtzidis                         PDiag(diag::err_incomplete_type_objc_at_encode)
1373b5904ba83fc9b968b1cd6f1ce78d01bfd6e8686Argyrios Kyrtzidis                             << EncodedTypeInfo->getTypeLoc().getSourceRange()))
1383b5904ba83fc9b968b1cd6f1ce78d01bfd6e8686Argyrios Kyrtzidis        return ExprError();
1393b5904ba83fc9b968b1cd6f1ce78d01bfd6e8686Argyrios Kyrtzidis
140fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson    std::string Str;
141fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson    Context.getObjCEncodingForType(EncodedType, Str);
142fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson
143fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson    // The type of @encode is the same as the type of the corresponding string,
144fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson    // which is an array type.
145fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson    StrTy = Context.CharTy;
146fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson    // A C++ string literal has a const-qualified element type (C++ 2.13.4p1).
1474b7a834e0fecddd9eaf1f4567867c718e4eebf50John McCall    if (getLangOptions().CPlusPlus || getLangOptions().ConstStrings)
148fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson      StrTy.addConst();
149fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson    StrTy = Context.getConstantArrayType(StrTy, llvm::APInt(32, Str.size()+1),
150fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson                                         ArrayType::Normal, 0);
151fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson  }
1521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15381d3466d037dc5844234c7a93dab21a6ad986e7dDouglas Gregor  return new (Context) ObjCEncodeExpr(StrTy, EncodedTypeInfo, AtLoc, RParenLoc);
154fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson}
155fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson
156f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCallExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
157f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                           SourceLocation EncodeLoc,
158f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                           SourceLocation LParenLoc,
159f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                           ParsedType ty,
160f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                           SourceLocation RParenLoc) {
161e8661906d49ef6c9694a9cc845ca62a85dbc016dArgyrios Kyrtzidis  // FIXME: Preserve type source info ?
16281d3466d037dc5844234c7a93dab21a6ad986e7dDouglas Gregor  TypeSourceInfo *TInfo;
16381d3466d037dc5844234c7a93dab21a6ad986e7dDouglas Gregor  QualType EncodedType = GetTypeFromParser(ty, &TInfo);
16481d3466d037dc5844234c7a93dab21a6ad986e7dDouglas Gregor  if (!TInfo)
16581d3466d037dc5844234c7a93dab21a6ad986e7dDouglas Gregor    TInfo = Context.getTrivialTypeSourceInfo(EncodedType,
16681d3466d037dc5844234c7a93dab21a6ad986e7dDouglas Gregor                                             PP.getLocForEndOfToken(LParenLoc));
16785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
16881d3466d037dc5844234c7a93dab21a6ad986e7dDouglas Gregor  return BuildObjCEncodeExpression(AtLoc, TInfo, RParenLoc);
16985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
17085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
171f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCallExprResult Sema::ParseObjCSelectorExpression(Selector Sel,
172f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                             SourceLocation AtLoc,
173f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                             SourceLocation SelLoc,
174f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                             SourceLocation LParenLoc,
175f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                             SourceLocation RParenLoc) {
1761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(Sel,
1776b308f6dc7d8f1581c52095f435c0e1284b111d8Fariborz Jahanian                             SourceRange(LParenLoc, RParenLoc), false, false);
1787ff22ded2221f442b1f8ff78172938d04ec8c926Fariborz Jahanian  if (!Method)
1797ff22ded2221f442b1f8ff78172938d04ec8c926Fariborz Jahanian    Method = LookupFactoryMethodInGlobalPool(Sel,
1807ff22ded2221f442b1f8ff78172938d04ec8c926Fariborz Jahanian                                          SourceRange(LParenLoc, RParenLoc));
1817ff22ded2221f442b1f8ff78172938d04ec8c926Fariborz Jahanian  if (!Method)
1827ff22ded2221f442b1f8ff78172938d04ec8c926Fariborz Jahanian    Diag(SelLoc, diag::warn_undeclared_selector) << Sel;
1834c91d89453c4a540d9ad697ceae89c8ef6049a6bFariborz Jahanian
1844c91d89453c4a540d9ad697ceae89c8ef6049a6bFariborz Jahanian  if (!Method ||
1854c91d89453c4a540d9ad697ceae89c8ef6049a6bFariborz Jahanian      Method->getImplementationControl() != ObjCMethodDecl::Optional) {
1864c91d89453c4a540d9ad697ceae89c8ef6049a6bFariborz Jahanian    llvm::DenseMap<Selector, SourceLocation>::iterator Pos
1874c91d89453c4a540d9ad697ceae89c8ef6049a6bFariborz Jahanian      = ReferencedSelectors.find(Sel);
1884c91d89453c4a540d9ad697ceae89c8ef6049a6bFariborz Jahanian    if (Pos == ReferencedSelectors.end())
1894c91d89453c4a540d9ad697ceae89c8ef6049a6bFariborz Jahanian      ReferencedSelectors.insert(std::make_pair(Sel, SelLoc));
1904c91d89453c4a540d9ad697ceae89c8ef6049a6bFariborz Jahanian  }
1913fe104154dd2e8ffb351142d74f308938b5c99bfFariborz Jahanian
192f85e193739c953358c865005855253af4f68a497John McCall  // In ARC, forbid the user from using @selector for
193f85e193739c953358c865005855253af4f68a497John McCall  // retain/release/autorelease/dealloc/retainCount.
194f85e193739c953358c865005855253af4f68a497John McCall  if (getLangOptions().ObjCAutoRefCount) {
195f85e193739c953358c865005855253af4f68a497John McCall    switch (Sel.getMethodFamily()) {
196f85e193739c953358c865005855253af4f68a497John McCall    case OMF_retain:
197f85e193739c953358c865005855253af4f68a497John McCall    case OMF_release:
198f85e193739c953358c865005855253af4f68a497John McCall    case OMF_autorelease:
199f85e193739c953358c865005855253af4f68a497John McCall    case OMF_retainCount:
200f85e193739c953358c865005855253af4f68a497John McCall    case OMF_dealloc:
201f85e193739c953358c865005855253af4f68a497John McCall      Diag(AtLoc, diag::err_arc_illegal_selector) <<
202f85e193739c953358c865005855253af4f68a497John McCall        Sel << SourceRange(LParenLoc, RParenLoc);
203f85e193739c953358c865005855253af4f68a497John McCall      break;
204f85e193739c953358c865005855253af4f68a497John McCall
205f85e193739c953358c865005855253af4f68a497John McCall    case OMF_None:
206f85e193739c953358c865005855253af4f68a497John McCall    case OMF_alloc:
207f85e193739c953358c865005855253af4f68a497John McCall    case OMF_copy:
20880cb6e69d9e85231588ae604e4bc2bc9a07389afNico Weber    case OMF_finalize:
209f85e193739c953358c865005855253af4f68a497John McCall    case OMF_init:
210f85e193739c953358c865005855253af4f68a497John McCall    case OMF_mutableCopy:
211f85e193739c953358c865005855253af4f68a497John McCall    case OMF_new:
212f85e193739c953358c865005855253af4f68a497John McCall    case OMF_self:
2139670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian    case OMF_performSelector:
214f85e193739c953358c865005855253af4f68a497John McCall      break;
215f85e193739c953358c865005855253af4f68a497John McCall    }
216f85e193739c953358c865005855253af4f68a497John McCall  }
217a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  QualType Ty = Context.getObjCSelType();
2186d5a1c28593443f3973ef38f8fa042d59182412dDaniel Dunbar  return new (Context) ObjCSelectorExpr(Ty, Sel, AtLoc, RParenLoc);
21985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
22085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
221f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCallExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,
222f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                             SourceLocation AtLoc,
223f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                             SourceLocation ProtoLoc,
224f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                             SourceLocation LParenLoc,
225f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                             SourceLocation RParenLoc) {
226c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  ObjCProtocolDecl* PDecl = LookupProtocol(ProtocolId, ProtoLoc);
22785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  if (!PDecl) {
2283c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId;
22985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    return true;
23085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  }
2311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
232a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  QualType Ty = Context.getObjCProtoType();
233a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  if (Ty.isNull())
23485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    return true;
23514108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  Ty = Context.getObjCObjectPointerType(Ty);
236a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  return new (Context) ObjCProtocolExpr(Ty, PDecl, AtLoc, RParenLoc);
23785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
23885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
23926743b20e4a8c2a986e6453f0c38beba0afef633John McCall/// Try to capture an implicit reference to 'self'.
24026743b20e4a8c2a986e6453f0c38beba0afef633John McCallObjCMethodDecl *Sema::tryCaptureObjCSelf() {
24126743b20e4a8c2a986e6453f0c38beba0afef633John McCall  // Ignore block scopes: we can capture through them.
24226743b20e4a8c2a986e6453f0c38beba0afef633John McCall  DeclContext *DC = CurContext;
24326743b20e4a8c2a986e6453f0c38beba0afef633John McCall  while (true) {
24426743b20e4a8c2a986e6453f0c38beba0afef633John McCall    if (isa<BlockDecl>(DC)) DC = cast<BlockDecl>(DC)->getDeclContext();
24526743b20e4a8c2a986e6453f0c38beba0afef633John McCall    else if (isa<EnumDecl>(DC)) DC = cast<EnumDecl>(DC)->getDeclContext();
24626743b20e4a8c2a986e6453f0c38beba0afef633John McCall    else break;
24726743b20e4a8c2a986e6453f0c38beba0afef633John McCall  }
24826743b20e4a8c2a986e6453f0c38beba0afef633John McCall
24926743b20e4a8c2a986e6453f0c38beba0afef633John McCall  // If we're not in an ObjC method, error out.  Note that, unlike the
25026743b20e4a8c2a986e6453f0c38beba0afef633John McCall  // C++ case, we don't require an instance method --- class methods
25126743b20e4a8c2a986e6453f0c38beba0afef633John McCall  // still have a 'self', and we really do still need to capture it!
25226743b20e4a8c2a986e6453f0c38beba0afef633John McCall  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(DC);
25326743b20e4a8c2a986e6453f0c38beba0afef633John McCall  if (!method)
25426743b20e4a8c2a986e6453f0c38beba0afef633John McCall    return 0;
25526743b20e4a8c2a986e6453f0c38beba0afef633John McCall
25626743b20e4a8c2a986e6453f0c38beba0afef633John McCall  ImplicitParamDecl *self = method->getSelfDecl();
25726743b20e4a8c2a986e6453f0c38beba0afef633John McCall  assert(self && "capturing 'self' in non-definition?");
25826743b20e4a8c2a986e6453f0c38beba0afef633John McCall
25926743b20e4a8c2a986e6453f0c38beba0afef633John McCall  // Mark that we're closing on 'this' in all the block scopes, if applicable.
26026743b20e4a8c2a986e6453f0c38beba0afef633John McCall  for (unsigned idx = FunctionScopes.size() - 1;
26126743b20e4a8c2a986e6453f0c38beba0afef633John McCall       isa<BlockScopeInfo>(FunctionScopes[idx]);
2626b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall       --idx) {
2636b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    BlockScopeInfo *blockScope = cast<BlockScopeInfo>(FunctionScopes[idx]);
2646b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    unsigned &captureIndex = blockScope->CaptureMap[self];
2656b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    if (captureIndex) break;
2666b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall
2676b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    bool nested = isa<BlockScopeInfo>(FunctionScopes[idx-1]);
2686b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    blockScope->Captures.push_back(
2696b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall              BlockDecl::Capture(self, /*byref*/ false, nested, /*copy*/ 0));
2706b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall    captureIndex = blockScope->Captures.size(); // +1
2716b5a61b6dc400027fd793dcadceeb9da944a37eaJohn McCall  }
27226743b20e4a8c2a986e6453f0c38beba0afef633John McCall
27326743b20e4a8c2a986e6453f0c38beba0afef633John McCall  return method;
27426743b20e4a8c2a986e6453f0c38beba0afef633John McCall}
27526743b20e4a8c2a986e6453f0c38beba0afef633John McCall
2765c16d635ff67fd8f083a704b7c82607ed49a8ba2Douglas Gregorstatic QualType stripObjCInstanceType(ASTContext &Context, QualType T) {
2775c16d635ff67fd8f083a704b7c82607ed49a8ba2Douglas Gregor  if (T == Context.getObjCInstanceType())
2785c16d635ff67fd8f083a704b7c82607ed49a8ba2Douglas Gregor    return Context.getObjCIdType();
2795c16d635ff67fd8f083a704b7c82607ed49a8ba2Douglas Gregor
2805c16d635ff67fd8f083a704b7c82607ed49a8ba2Douglas Gregor  return T;
2815c16d635ff67fd8f083a704b7c82607ed49a8ba2Douglas Gregor}
2825c16d635ff67fd8f083a704b7c82607ed49a8ba2Douglas Gregor
283926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas GregorQualType Sema::getMessageSendResultType(QualType ReceiverType,
284926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                        ObjCMethodDecl *Method,
285926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                    bool isClassMessage, bool isSuperMessage) {
286926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  assert(Method && "Must have a method");
287926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  if (!Method->hasRelatedResultType())
288926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    return Method->getSendResultType();
289926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
290926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  // If a method has a related return type:
291926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  //   - if the method found is an instance method, but the message send
292926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  //     was a class message send, T is the declared return type of the method
293926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  //     found
294926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  if (Method->isInstanceMethod() && isClassMessage)
2955c16d635ff67fd8f083a704b7c82607ed49a8ba2Douglas Gregor    return stripObjCInstanceType(Context, Method->getSendResultType());
296926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
297926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  //   - if the receiver is super, T is a pointer to the class of the
298926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  //     enclosing method definition
299926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  if (isSuperMessage) {
300926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
301926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor      if (ObjCInterfaceDecl *Class = CurMethod->getClassInterface())
302926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor        return Context.getObjCObjectPointerType(
303926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                        Context.getObjCInterfaceType(Class));
304926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  }
305926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
306926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  //   - if the receiver is the name of a class U, T is a pointer to U
307926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  if (ReceiverType->getAs<ObjCInterfaceType>() ||
308926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor      ReceiverType->isObjCQualifiedInterfaceType())
309926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    return Context.getObjCObjectPointerType(ReceiverType);
310926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  //   - if the receiver is of type Class or qualified Class type,
311926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  //     T is the declared return type of the method.
312926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  if (ReceiverType->isObjCClassType() ||
313926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor      ReceiverType->isObjCQualifiedClassType())
3145c16d635ff67fd8f083a704b7c82607ed49a8ba2Douglas Gregor    return stripObjCInstanceType(Context, Method->getSendResultType());
315926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
316926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  //   - if the receiver is id, qualified id, Class, or qualified Class, T
317926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  //     is the receiver type, otherwise
318926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  //   - T is the type of the receiver expression.
319926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  return ReceiverType;
320926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor}
321926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
322926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregorvoid Sema::EmitRelatedResultTypeNote(const Expr *E) {
323926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  E = E->IgnoreParenImpCasts();
324926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  const ObjCMessageExpr *MsgSend = dyn_cast<ObjCMessageExpr>(E);
325926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  if (!MsgSend)
326926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    return;
327926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
328926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  const ObjCMethodDecl *Method = MsgSend->getMethodDecl();
329926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  if (!Method)
330926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    return;
331926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
332926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  if (!Method->hasRelatedResultType())
333926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    return;
334926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
335926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  if (Context.hasSameUnqualifiedType(Method->getResultType()
336926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                                        .getNonReferenceType(),
337926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                     MsgSend->getType()))
338926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    return;
339926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
340e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor  if (!Context.hasSameUnqualifiedType(Method->getResultType(),
341e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor                                      Context.getObjCInstanceType()))
342e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor    return;
343e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor
344926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  Diag(Method->getLocation(), diag::note_related_result_type_inferred)
345926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    << Method->isInstanceMethod() << Method->getSelector()
346926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    << MsgSend->getType();
347926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor}
34826743b20e4a8c2a986e6453f0c38beba0afef633John McCall
349926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregorbool Sema::CheckMessageArgumentTypes(QualType ReceiverType,
350926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                     Expr **Args, unsigned NumArgs,
3511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                     Selector Sel, ObjCMethodDecl *Method,
352926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                     bool isClassMessage, bool isSuperMessage,
353637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar                                     SourceLocation lbrac, SourceLocation rbrac,
354f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall                                     QualType &ReturnType, ExprValueKind &VK) {
355637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar  if (!Method) {
3566660c8a4cc2115929d92be83bbc54c307002a321Daniel Dunbar    // Apply default argument promotion as for (C99 6.5.2.2p6).
35792e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor    for (unsigned i = 0; i != NumArgs; i++) {
35892e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor      if (Args[i]->isTypeDependent())
35992e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor        continue;
36092e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor
361429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley      ExprResult Result = DefaultArgumentPromotion(Args[i]);
362429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley      if (Result.isInvalid())
363429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley        return true;
364429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley      Args[i] = Result.take();
36592e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor    }
3666660c8a4cc2115929d92be83bbc54c307002a321Daniel Dunbar
367f85e193739c953358c865005855253af4f68a497John McCall    unsigned DiagID;
368f85e193739c953358c865005855253af4f68a497John McCall    if (getLangOptions().ObjCAutoRefCount)
369f85e193739c953358c865005855253af4f68a497John McCall      DiagID = diag::err_arc_method_not_found;
370f85e193739c953358c865005855253af4f68a497John McCall    else
371f85e193739c953358c865005855253af4f68a497John McCall      DiagID = isClassMessage ? diag::warn_class_method_not_found
372f85e193739c953358c865005855253af4f68a497John McCall                              : diag::warn_inst_method_not_found;
373819e74544a326b90d13aa73e6497b187c6545ff5John McCall    if (!getLangOptions().DebuggerSupport)
374819e74544a326b90d13aa73e6497b187c6545ff5John McCall      Diag(lbrac, DiagID)
375819e74544a326b90d13aa73e6497b187c6545ff5John McCall        << Sel << isClassMessage << SourceRange(lbrac, rbrac);
37648218c60d6b53b7880917d1366ee716dec2145caJohn McCall
37748218c60d6b53b7880917d1366ee716dec2145caJohn McCall    // In debuggers, we want to use __unknown_anytype for these
37848218c60d6b53b7880917d1366ee716dec2145caJohn McCall    // results so that clients can cast them.
37948218c60d6b53b7880917d1366ee716dec2145caJohn McCall    if (getLangOptions().DebuggerSupport) {
38048218c60d6b53b7880917d1366ee716dec2145caJohn McCall      ReturnType = Context.UnknownAnyTy;
38148218c60d6b53b7880917d1366ee716dec2145caJohn McCall    } else {
38248218c60d6b53b7880917d1366ee716dec2145caJohn McCall      ReturnType = Context.getObjCIdType();
38348218c60d6b53b7880917d1366ee716dec2145caJohn McCall    }
384f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall    VK = VK_RValue;
385637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar    return false;
386637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar  }
3871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
388926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  ReturnType = getMessageSendResultType(ReceiverType, Method, isClassMessage,
389926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                        isSuperMessage);
390f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  VK = Expr::getValueKindForType(Method->getResultType());
3911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
39291e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  unsigned NumNamedArgs = Sel.getNumArgs();
3934f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian  // Method might have more arguments than selector indicates. This is due
3944f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian  // to addition of c-style arguments in method.
3954f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian  if (Method->param_size() > Sel.getNumArgs())
3964f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian    NumNamedArgs = Method->param_size();
3974f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian  // FIXME. This need be cleaned up.
3984f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian  if (NumArgs < NumNamedArgs) {
399f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall    Diag(lbrac, diag::err_typecheck_call_too_few_args)
400f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall      << 2 << NumNamedArgs << NumArgs;
4014f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian    return false;
4024f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian  }
40391e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar
404312531a8cd69c562d5687bd69fd334be99d87320Chris Lattner  bool IsError = false;
40591e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  for (unsigned i = 0; i < NumNamedArgs; i++) {
40692e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor    // We can't do any type-checking on a type-dependent argument.
40792e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor    if (Args[i]->isTypeDependent())
40892e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor      continue;
40992e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor
41085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    Expr *argExpr = Args[i];
41192e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor
4125acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    ParmVarDecl *param = Method->param_begin()[i];
41385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    assert(argExpr && "CheckMessageArgumentTypes(): missing expression");
4141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4155acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    // Strip the unbridged-cast placeholder expression off unless it's
4165acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    // a consumed argument.
4175acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    if (argExpr->hasPlaceholderType(BuiltinType::ARCUnbridgedCast) &&
4185acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall        !param->hasAttr<CFConsumedAttr>())
4195acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      argExpr = stripARCUnbridgedCast(argExpr);
4205acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
421688fc9b9b4323a294f5bf4f8a83f7c365edec573Douglas Gregor    if (RequireCompleteType(argExpr->getSourceRange().getBegin(),
4225acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall                            param->getType(),
423688fc9b9b4323a294f5bf4f8a83f7c365edec573Douglas Gregor                            PDiag(diag::err_call_incomplete_argument)
424688fc9b9b4323a294f5bf4f8a83f7c365edec573Douglas Gregor                              << argExpr->getSourceRange()))
425688fc9b9b4323a294f5bf4f8a83f7c365edec573Douglas Gregor      return true;
426688fc9b9b4323a294f5bf4f8a83f7c365edec573Douglas Gregor
427745da3a5bb4ea35f93f50301e7fbbb7d78d3b6bbFariborz Jahanian    InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
4285acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall                                                                      param);
4293fa5cae9b3812cab9fab6c042c3329bb70a3d046John McCall    ExprResult ArgE = PerformCopyInitialization(Entity, lbrac, Owned(argExpr));
430688fc9b9b4323a294f5bf4f8a83f7c365edec573Douglas Gregor    if (ArgE.isInvalid())
431688fc9b9b4323a294f5bf4f8a83f7c365edec573Douglas Gregor      IsError = true;
432688fc9b9b4323a294f5bf4f8a83f7c365edec573Douglas Gregor    else
433688fc9b9b4323a294f5bf4f8a83f7c365edec573Douglas Gregor      Args[i] = ArgE.takeAs<Expr>();
43485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  }
43591e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar
43691e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  // Promote additional arguments to variadic methods.
43791e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  if (Method->isVariadic()) {
43892e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor    for (unsigned i = NumNamedArgs; i < NumArgs; ++i) {
43992e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor      if (Args[i]->isTypeDependent())
44092e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor        continue;
44192e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor
442429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley      ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], VariadicMethod, 0);
443429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley      IsError |= Arg.isInvalid();
444429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley      Args[i] = Arg.take();
44592e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor    }
44691e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  } else {
44791e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar    // Check for extra arguments to non-variadic methods.
44891e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar    if (NumArgs != NumNamedArgs) {
4491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      Diag(Args[NumNamedArgs]->getLocStart(),
450fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner           diag::err_typecheck_call_too_many_args)
451ccfa9639f8d09733bcf1c2572c5bd3daba5bd632Eric Christopher        << 2 /*method*/ << NumNamedArgs << NumArgs
452ccfa9639f8d09733bcf1c2572c5bd3daba5bd632Eric Christopher        << Method->getSourceRange()
453fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << SourceRange(Args[NumNamedArgs]->getLocStart(),
454fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner                       Args[NumArgs-1]->getLocEnd());
45591e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar    }
45691e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  }
4575272adfe7066c4847b7339a75777252de64e79c2Fariborz Jahanian  // diagnose nonnull arguments.
4585272adfe7066c4847b7339a75777252de64e79c2Fariborz Jahanian  for (specific_attr_iterator<NonNullAttr>
4595272adfe7066c4847b7339a75777252de64e79c2Fariborz Jahanian       i = Method->specific_attr_begin<NonNullAttr>(),
4605272adfe7066c4847b7339a75777252de64e79c2Fariborz Jahanian       e = Method->specific_attr_end<NonNullAttr>(); i != e; ++i) {
4615272adfe7066c4847b7339a75777252de64e79c2Fariborz Jahanian    CheckNonNullArguments(*i, Args, lbrac);
4625272adfe7066c4847b7339a75777252de64e79c2Fariborz Jahanian  }
46391e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar
4642725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  DiagnoseSentinelCalls(Method, lbrac, Args, NumArgs);
465312531a8cd69c562d5687bd69fd334be99d87320Chris Lattner  return IsError;
46685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
46785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
468c737acb8e86564becc5939d681089d1851e6be1aDouglas Gregorbool Sema::isSelfExpr(Expr *receiver) {
469f2d74cc083e1a83838acf99d2e1ca260d1c54742Fariborz Jahanian  // 'self' is objc 'self' in an objc method only.
470b460210fe0dec08971edfe33c294323cf79cb894Fariborz Jahanian  DeclContext *DC = CurContext;
471b460210fe0dec08971edfe33c294323cf79cb894Fariborz Jahanian  while (isa<BlockDecl>(DC))
472b460210fe0dec08971edfe33c294323cf79cb894Fariborz Jahanian    DC = DC->getParent();
473b460210fe0dec08971edfe33c294323cf79cb894Fariborz Jahanian  if (DC && !isa<ObjCMethodDecl>(DC))
474c737acb8e86564becc5939d681089d1851e6be1aDouglas Gregor    return false;
475f85e193739c953358c865005855253af4f68a497John McCall  receiver = receiver->IgnoreParenLValueCasts();
476f85e193739c953358c865005855253af4f68a497John McCall  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(receiver))
4776b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff    if (DRE->getDecl()->getIdentifier() == &Context.Idents.get("self"))
478c737acb8e86564becc5939d681089d1851e6be1aDouglas Gregor      return true;
479c737acb8e86564becc5939d681089d1851e6be1aDouglas Gregor  return false;
4806b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff}
4816b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff
482f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff// Helper method for ActOnClassMethod/ActOnInstanceMethod.
483f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff// Will search "local" class/category implementations for a method decl.
484175ba1e8180083927aabd7cc8137baa16be75646Fariborz Jahanian// If failed, then we search in class's root for an instance method.
485f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff// Returns 0 if no method is found.
4865609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve NaroffObjCMethodDecl *Sema::LookupPrivateClassMethod(Selector Sel,
487f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff                                          ObjCInterfaceDecl *ClassDecl) {
488f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff  ObjCMethodDecl *Method = 0;
4895609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff  // lookup in class and all superclasses
4905609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff  while (ClassDecl && !Method) {
49187018775ed689d0a67357cf767747166044b3a27Argyrios Kyrtzidis    if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation())
49217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis      Method = ImpDecl->getClassMethod(Sel);
4931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4945609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    // Look through local category implementations associated with the class.
4951cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis    if (!Method)
4961cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis      Method = ClassDecl->getCategoryClassMethod(Sel);
4971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4985609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    // Before we give up, check if the selector is an instance method.
4995609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    // But only in the root. This matches gcc's behaviour and what the
5005609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    // runtime expects.
5015609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    if (!Method && !ClassDecl->getSuperClass()) {
50217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis      Method = ClassDecl->lookupInstanceMethod(Sel);
5031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      // Look through local category implementations associated
5045609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      // with the root class.
5051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      if (!Method)
5065609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff        Method = LookupPrivateInstanceMethod(Sel, ClassDecl);
507f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff    }
5081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5095609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    ClassDecl = ClassDecl->getSuperClass();
510f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff  }
5115609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff  return Method;
5125609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff}
5135609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff
5145609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve NaroffObjCMethodDecl *Sema::LookupPrivateInstanceMethod(Selector Sel,
5155609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff                                              ObjCInterfaceDecl *ClassDecl) {
5165609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff  ObjCMethodDecl *Method = 0;
5175609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff  while (ClassDecl && !Method) {
5185609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    // If we have implementations in scope, check "private" methods.
51987018775ed689d0a67357cf767747166044b3a27Argyrios Kyrtzidis    if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation())
52017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis      Method = ImpDecl->getInstanceMethod(Sel);
5211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5225609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    // Look through local category implementations associated with the class.
5231cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis    if (!Method)
5241cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis      Method = ClassDecl->getCategoryInstanceMethod(Sel);
5255609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    ClassDecl = ClassDecl->getSuperClass();
526175ba1e8180083927aabd7cc8137baa16be75646Fariborz Jahanian  }
527f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff  return Method;
528f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff}
529f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff
5303c3b7f90a863af43fa63043d396553ecf205351cJohn McCall/// LookupMethodInType - Look up a method in an ObjCObjectType.
5313c3b7f90a863af43fa63043d396553ecf205351cJohn McCallObjCMethodDecl *Sema::LookupMethodInObjectType(Selector sel, QualType type,
5323c3b7f90a863af43fa63043d396553ecf205351cJohn McCall                                               bool isInstance) {
5333c3b7f90a863af43fa63043d396553ecf205351cJohn McCall  const ObjCObjectType *objType = type->castAs<ObjCObjectType>();
5343c3b7f90a863af43fa63043d396553ecf205351cJohn McCall  if (ObjCInterfaceDecl *iface = objType->getInterface()) {
5353c3b7f90a863af43fa63043d396553ecf205351cJohn McCall    // Look it up in the main interface (and categories, etc.)
5363c3b7f90a863af43fa63043d396553ecf205351cJohn McCall    if (ObjCMethodDecl *method = iface->lookupMethod(sel, isInstance))
5373c3b7f90a863af43fa63043d396553ecf205351cJohn McCall      return method;
5383c3b7f90a863af43fa63043d396553ecf205351cJohn McCall
5393c3b7f90a863af43fa63043d396553ecf205351cJohn McCall    // Okay, look for "private" methods declared in any
5403c3b7f90a863af43fa63043d396553ecf205351cJohn McCall    // @implementations we've seen.
5413c3b7f90a863af43fa63043d396553ecf205351cJohn McCall    if (isInstance) {
5423c3b7f90a863af43fa63043d396553ecf205351cJohn McCall      if (ObjCMethodDecl *method = LookupPrivateInstanceMethod(sel, iface))
5433c3b7f90a863af43fa63043d396553ecf205351cJohn McCall        return method;
5443c3b7f90a863af43fa63043d396553ecf205351cJohn McCall    } else {
5453c3b7f90a863af43fa63043d396553ecf205351cJohn McCall      if (ObjCMethodDecl *method = LookupPrivateClassMethod(sel, iface))
5463c3b7f90a863af43fa63043d396553ecf205351cJohn McCall        return method;
5473c3b7f90a863af43fa63043d396553ecf205351cJohn McCall    }
5483c3b7f90a863af43fa63043d396553ecf205351cJohn McCall  }
5493c3b7f90a863af43fa63043d396553ecf205351cJohn McCall
5503c3b7f90a863af43fa63043d396553ecf205351cJohn McCall  // Check qualifiers.
5513c3b7f90a863af43fa63043d396553ecf205351cJohn McCall  for (ObjCObjectType::qual_iterator
5523c3b7f90a863af43fa63043d396553ecf205351cJohn McCall         i = objType->qual_begin(), e = objType->qual_end(); i != e; ++i)
5533c3b7f90a863af43fa63043d396553ecf205351cJohn McCall    if (ObjCMethodDecl *method = (*i)->lookupMethod(sel, isInstance))
5543c3b7f90a863af43fa63043d396553ecf205351cJohn McCall      return method;
5553c3b7f90a863af43fa63043d396553ecf205351cJohn McCall
5563c3b7f90a863af43fa63043d396553ecf205351cJohn McCall  return 0;
5573c3b7f90a863af43fa63043d396553ecf205351cJohn McCall}
5583c3b7f90a863af43fa63043d396553ecf205351cJohn McCall
55961478065fbcafcf5295bb0fb796c9a92f2d861e0Fariborz Jahanian/// LookupMethodInQualifiedType - Lookups up a method in protocol qualifier
56061478065fbcafcf5295bb0fb796c9a92f2d861e0Fariborz Jahanian/// list of a qualified objective pointer type.
56161478065fbcafcf5295bb0fb796c9a92f2d861e0Fariborz JahanianObjCMethodDecl *Sema::LookupMethodInQualifiedType(Selector Sel,
56261478065fbcafcf5295bb0fb796c9a92f2d861e0Fariborz Jahanian                                              const ObjCObjectPointerType *OPT,
56361478065fbcafcf5295bb0fb796c9a92f2d861e0Fariborz Jahanian                                              bool Instance)
56461478065fbcafcf5295bb0fb796c9a92f2d861e0Fariborz Jahanian{
56561478065fbcafcf5295bb0fb796c9a92f2d861e0Fariborz Jahanian  ObjCMethodDecl *MD = 0;
56661478065fbcafcf5295bb0fb796c9a92f2d861e0Fariborz Jahanian  for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(),
56761478065fbcafcf5295bb0fb796c9a92f2d861e0Fariborz Jahanian       E = OPT->qual_end(); I != E; ++I) {
56861478065fbcafcf5295bb0fb796c9a92f2d861e0Fariborz Jahanian    ObjCProtocolDecl *PROTO = (*I);
56961478065fbcafcf5295bb0fb796c9a92f2d861e0Fariborz Jahanian    if ((MD = PROTO->lookupMethod(Sel, Instance))) {
57061478065fbcafcf5295bb0fb796c9a92f2d861e0Fariborz Jahanian      return MD;
57161478065fbcafcf5295bb0fb796c9a92f2d861e0Fariborz Jahanian    }
57261478065fbcafcf5295bb0fb796c9a92f2d861e0Fariborz Jahanian  }
57361478065fbcafcf5295bb0fb796c9a92f2d861e0Fariborz Jahanian  return 0;
57461478065fbcafcf5295bb0fb796c9a92f2d861e0Fariborz Jahanian}
57561478065fbcafcf5295bb0fb796c9a92f2d861e0Fariborz Jahanian
5767f81652f97a69ae8b514893a69c0245253687e55Chris Lattner/// HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an
5777f81652f97a69ae8b514893a69c0245253687e55Chris Lattner/// objective C interface.  This is a property reference expression.
57860d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Sema::
5797f81652f97a69ae8b514893a69c0245253687e55Chris LattnerHandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
5806326e05fe8c2ff92b65b4759a91e45fad5ef886fFariborz Jahanian                          Expr *BaseExpr, SourceLocation OpLoc,
5816326e05fe8c2ff92b65b4759a91e45fad5ef886fFariborz Jahanian                          DeclarationName MemberName,
5828ac2d449820fd0df00fcbde5bf82165c1f49854dFariborz Jahanian                          SourceLocation MemberLoc,
5838ac2d449820fd0df00fcbde5bf82165c1f49854dFariborz Jahanian                          SourceLocation SuperLoc, QualType SuperType,
5848ac2d449820fd0df00fcbde5bf82165c1f49854dFariborz Jahanian                          bool Super) {
5857f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  const ObjCInterfaceType *IFaceT = OPT->getInterfaceType();
5867f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  ObjCInterfaceDecl *IFace = IFaceT->getDecl();
587109ec1b05664e35e710785314c12552307f39a7dDouglas Gregor
588109ec1b05664e35e710785314c12552307f39a7dDouglas Gregor  if (MemberName.getNameKind() != DeclarationName::Identifier) {
589109ec1b05664e35e710785314c12552307f39a7dDouglas Gregor    Diag(MemberLoc, diag::err_invalid_property_name)
590109ec1b05664e35e710785314c12552307f39a7dDouglas Gregor      << MemberName << QualType(OPT, 0);
591109ec1b05664e35e710785314c12552307f39a7dDouglas Gregor    return ExprError();
592109ec1b05664e35e710785314c12552307f39a7dDouglas Gregor  }
593109ec1b05664e35e710785314c12552307f39a7dDouglas Gregor
5947f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
5957f81652f97a69ae8b514893a69c0245253687e55Chris Lattner
5968b1aba495744bea7093899a65f08c3987263061cFariborz Jahanian  if (IFace->isForwardDecl()) {
5978b1aba495744bea7093899a65f08c3987263061cFariborz Jahanian    Diag(MemberLoc, diag::err_property_not_found_forward_class)
5988b1aba495744bea7093899a65f08c3987263061cFariborz Jahanian         << MemberName << QualType(OPT, 0);
5998b1aba495744bea7093899a65f08c3987263061cFariborz Jahanian    Diag(IFace->getLocation(), diag::note_forward_class);
6008b1aba495744bea7093899a65f08c3987263061cFariborz Jahanian    return ExprError();
6018b1aba495744bea7093899a65f08c3987263061cFariborz Jahanian  }
6027f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  // Search for a declared property first.
6037f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  if (ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(Member)) {
6047f81652f97a69ae8b514893a69c0245253687e55Chris Lattner    // Check whether we can reference this property.
6057f81652f97a69ae8b514893a69c0245253687e55Chris Lattner    if (DiagnoseUseOfDecl(PD, MemberLoc))
6067f81652f97a69ae8b514893a69c0245253687e55Chris Lattner      return ExprError();
607926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
6088ac2d449820fd0df00fcbde5bf82165c1f49854dFariborz Jahanian    if (Super)
6093c3b7f90a863af43fa63043d396553ecf205351cJohn McCall      return Owned(new (Context) ObjCPropertyRefExpr(PD, Context.PseudoObjectTy,
610f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall                                                     VK_LValue, OK_ObjCProperty,
6118ac2d449820fd0df00fcbde5bf82165c1f49854dFariborz Jahanian                                                     MemberLoc,
6128ac2d449820fd0df00fcbde5bf82165c1f49854dFariborz Jahanian                                                     SuperLoc, SuperType));
6138ac2d449820fd0df00fcbde5bf82165c1f49854dFariborz Jahanian    else
6143c3b7f90a863af43fa63043d396553ecf205351cJohn McCall      return Owned(new (Context) ObjCPropertyRefExpr(PD, Context.PseudoObjectTy,
615f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall                                                     VK_LValue, OK_ObjCProperty,
6168ac2d449820fd0df00fcbde5bf82165c1f49854dFariborz Jahanian                                                     MemberLoc, BaseExpr));
6177f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  }
6187f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  // Check protocols on qualified interfaces.
6197f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(),
6207f81652f97a69ae8b514893a69c0245253687e55Chris Lattner       E = OPT->qual_end(); I != E; ++I)
6217f81652f97a69ae8b514893a69c0245253687e55Chris Lattner    if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(Member)) {
6227f81652f97a69ae8b514893a69c0245253687e55Chris Lattner      // Check whether we can reference this property.
6237f81652f97a69ae8b514893a69c0245253687e55Chris Lattner      if (DiagnoseUseOfDecl(PD, MemberLoc))
6247f81652f97a69ae8b514893a69c0245253687e55Chris Lattner        return ExprError();
625926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
6268ac2d449820fd0df00fcbde5bf82165c1f49854dFariborz Jahanian      if (Super)
6273c3b7f90a863af43fa63043d396553ecf205351cJohn McCall        return Owned(new (Context) ObjCPropertyRefExpr(PD,
6283c3b7f90a863af43fa63043d396553ecf205351cJohn McCall                                                       Context.PseudoObjectTy,
629f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall                                                       VK_LValue,
630f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall                                                       OK_ObjCProperty,
631f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall                                                       MemberLoc,
632f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall                                                       SuperLoc, SuperType));
6338ac2d449820fd0df00fcbde5bf82165c1f49854dFariborz Jahanian      else
6343c3b7f90a863af43fa63043d396553ecf205351cJohn McCall        return Owned(new (Context) ObjCPropertyRefExpr(PD,
6353c3b7f90a863af43fa63043d396553ecf205351cJohn McCall                                                       Context.PseudoObjectTy,
636f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall                                                       VK_LValue,
637f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall                                                       OK_ObjCProperty,
6388ac2d449820fd0df00fcbde5bf82165c1f49854dFariborz Jahanian                                                       MemberLoc,
6398ac2d449820fd0df00fcbde5bf82165c1f49854dFariborz Jahanian                                                       BaseExpr));
6407f81652f97a69ae8b514893a69c0245253687e55Chris Lattner    }
6417f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  // If that failed, look for an "implicit" property by seeing if the nullary
6427f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  // selector is implemented.
6437f81652f97a69ae8b514893a69c0245253687e55Chris Lattner
6447f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  // FIXME: The logic for looking up nullary and unary selectors should be
6457f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  // shared with the code in ActOnInstanceMessage.
6467f81652f97a69ae8b514893a69c0245253687e55Chris Lattner
6477f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  Selector Sel = PP.getSelectorTable().getNullarySelector(Member);
6487f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel);
64927569b0f3e1b27f609a2e104b39bad077850e210Fariborz Jahanian
65027569b0f3e1b27f609a2e104b39bad077850e210Fariborz Jahanian  // May be founf in property's qualified list.
65127569b0f3e1b27f609a2e104b39bad077850e210Fariborz Jahanian  if (!Getter)
65227569b0f3e1b27f609a2e104b39bad077850e210Fariborz Jahanian    Getter = LookupMethodInQualifiedType(Sel, OPT, true);
6537f81652f97a69ae8b514893a69c0245253687e55Chris Lattner
6547f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  // If this reference is in an @implementation, check for 'private' methods.
6557f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  if (!Getter)
65674b2756bc1f1f5f7c189996fe7e4cd3efef70263Fariborz Jahanian    Getter = IFace->lookupPrivateMethod(Sel);
6577f81652f97a69ae8b514893a69c0245253687e55Chris Lattner
6587f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  // Look through local category implementations associated with the class.
6597f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  if (!Getter)
6607f81652f97a69ae8b514893a69c0245253687e55Chris Lattner    Getter = IFace->getCategoryInstanceMethod(Sel);
6617f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  if (Getter) {
6627f81652f97a69ae8b514893a69c0245253687e55Chris Lattner    // Check if we can reference this property.
6637f81652f97a69ae8b514893a69c0245253687e55Chris Lattner    if (DiagnoseUseOfDecl(Getter, MemberLoc))
6647f81652f97a69ae8b514893a69c0245253687e55Chris Lattner      return ExprError();
6657f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  }
6667f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  // If we found a getter then this may be a valid dot-reference, we
6677f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  // will look for the matching setter, in case it is needed.
6687f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  Selector SetterSel =
6697f81652f97a69ae8b514893a69c0245253687e55Chris Lattner    SelectorTable::constructSetterName(PP.getIdentifierTable(),
6707f81652f97a69ae8b514893a69c0245253687e55Chris Lattner                                       PP.getSelectorTable(), Member);
6717f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel);
67227569b0f3e1b27f609a2e104b39bad077850e210Fariborz Jahanian
67327569b0f3e1b27f609a2e104b39bad077850e210Fariborz Jahanian  // May be founf in property's qualified list.
67427569b0f3e1b27f609a2e104b39bad077850e210Fariborz Jahanian  if (!Setter)
67527569b0f3e1b27f609a2e104b39bad077850e210Fariborz Jahanian    Setter = LookupMethodInQualifiedType(SetterSel, OPT, true);
67627569b0f3e1b27f609a2e104b39bad077850e210Fariborz Jahanian
6777f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  if (!Setter) {
6787f81652f97a69ae8b514893a69c0245253687e55Chris Lattner    // If this reference is in an @implementation, also check for 'private'
6797f81652f97a69ae8b514893a69c0245253687e55Chris Lattner    // methods.
68074b2756bc1f1f5f7c189996fe7e4cd3efef70263Fariborz Jahanian    Setter = IFace->lookupPrivateMethod(SetterSel);
6817f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  }
6827f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  // Look through local category implementations associated with the class.
6837f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  if (!Setter)
6847f81652f97a69ae8b514893a69c0245253687e55Chris Lattner    Setter = IFace->getCategoryInstanceMethod(SetterSel);
68527569b0f3e1b27f609a2e104b39bad077850e210Fariborz Jahanian
6867f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc))
6877f81652f97a69ae8b514893a69c0245253687e55Chris Lattner    return ExprError();
6887f81652f97a69ae8b514893a69c0245253687e55Chris Lattner
68999130e5a02e93282cb393d2cba0d3dffc10abc01Fariborz Jahanian  if (Getter || Setter) {
6908ac2d449820fd0df00fcbde5bf82165c1f49854dFariborz Jahanian    if (Super)
69112f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall      return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter,
6923c3b7f90a863af43fa63043d396553ecf205351cJohn McCall                                                     Context.PseudoObjectTy,
6933c3b7f90a863af43fa63043d396553ecf205351cJohn McCall                                                     VK_LValue, OK_ObjCProperty,
69412f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall                                                     MemberLoc,
69512f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall                                                     SuperLoc, SuperType));
6968ac2d449820fd0df00fcbde5bf82165c1f49854dFariborz Jahanian    else
69712f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall      return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter,
6983c3b7f90a863af43fa63043d396553ecf205351cJohn McCall                                                     Context.PseudoObjectTy,
6993c3b7f90a863af43fa63043d396553ecf205351cJohn McCall                                                     VK_LValue, OK_ObjCProperty,
70012f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall                                                     MemberLoc, BaseExpr));
7018ac2d449820fd0df00fcbde5bf82165c1f49854dFariborz Jahanian
7027f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  }
7037f81652f97a69ae8b514893a69c0245253687e55Chris Lattner
7047f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  // Attempt to correct for typos in property names.
705d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor  TypoCorrection Corrected = CorrectTypo(
706d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor      DeclarationNameInfo(MemberName, MemberLoc), LookupOrdinaryName, NULL,
707d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor      NULL, IFace, false, CTC_NoKeywords, OPT);
708d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor  if (ObjCPropertyDecl *Property =
709d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor      Corrected.getCorrectionDeclAs<ObjCPropertyDecl>()) {
710d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor    DeclarationName TypoResult = Corrected.getCorrection();
7117f81652f97a69ae8b514893a69c0245253687e55Chris Lattner    Diag(MemberLoc, diag::err_property_not_found_suggest)
712b9d4fc1f54924a7b242fb763192a40c19fa6103dChris Lattner      << MemberName << QualType(OPT, 0) << TypoResult
713b9d4fc1f54924a7b242fb763192a40c19fa6103dChris Lattner      << FixItHint::CreateReplacement(MemberLoc, TypoResult.getAsString());
7147f81652f97a69ae8b514893a69c0245253687e55Chris Lattner    Diag(Property->getLocation(), diag::note_previous_decl)
7157f81652f97a69ae8b514893a69c0245253687e55Chris Lattner      << Property->getDeclName();
7166326e05fe8c2ff92b65b4759a91e45fad5ef886fFariborz Jahanian    return HandleExprPropertyRefExpr(OPT, BaseExpr, OpLoc,
7176326e05fe8c2ff92b65b4759a91e45fad5ef886fFariborz Jahanian                                     TypoResult, MemberLoc,
7188ac2d449820fd0df00fcbde5bf82165c1f49854dFariborz Jahanian                                     SuperLoc, SuperType, Super);
7197f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  }
72041aadbc530f071fe5ccbfc2560899a4a2e74c057Fariborz Jahanian  ObjCInterfaceDecl *ClassDeclared;
72141aadbc530f071fe5ccbfc2560899a4a2e74c057Fariborz Jahanian  if (ObjCIvarDecl *Ivar =
72241aadbc530f071fe5ccbfc2560899a4a2e74c057Fariborz Jahanian      IFace->lookupInstanceVariable(Member, ClassDeclared)) {
72341aadbc530f071fe5ccbfc2560899a4a2e74c057Fariborz Jahanian    QualType T = Ivar->getType();
72441aadbc530f071fe5ccbfc2560899a4a2e74c057Fariborz Jahanian    if (const ObjCObjectPointerType * OBJPT =
72541aadbc530f071fe5ccbfc2560899a4a2e74c057Fariborz Jahanian        T->getAsObjCInterfacePointerType()) {
72641aadbc530f071fe5ccbfc2560899a4a2e74c057Fariborz Jahanian      const ObjCInterfaceType *IFaceT = OBJPT->getInterfaceType();
72741aadbc530f071fe5ccbfc2560899a4a2e74c057Fariborz Jahanian      if (ObjCInterfaceDecl *IFace = IFaceT->getDecl())
72841aadbc530f071fe5ccbfc2560899a4a2e74c057Fariborz Jahanian        if (IFace->isForwardDecl()) {
72941aadbc530f071fe5ccbfc2560899a4a2e74c057Fariborz Jahanian          Diag(MemberLoc, diag::err_property_not_as_forward_class)
7302a96bf5e66731bb54dff3e4aadfbbced83377530Fariborz Jahanian          << MemberName << IFace;
73141aadbc530f071fe5ccbfc2560899a4a2e74c057Fariborz Jahanian          Diag(IFace->getLocation(), diag::note_forward_class);
73241aadbc530f071fe5ccbfc2560899a4a2e74c057Fariborz Jahanian          return ExprError();
73341aadbc530f071fe5ccbfc2560899a4a2e74c057Fariborz Jahanian        }
73441aadbc530f071fe5ccbfc2560899a4a2e74c057Fariborz Jahanian    }
7356326e05fe8c2ff92b65b4759a91e45fad5ef886fFariborz Jahanian    Diag(MemberLoc,
7366326e05fe8c2ff92b65b4759a91e45fad5ef886fFariborz Jahanian         diag::err_ivar_access_using_property_syntax_suggest)
7376326e05fe8c2ff92b65b4759a91e45fad5ef886fFariborz Jahanian    << MemberName << QualType(OPT, 0) << Ivar->getDeclName()
7386326e05fe8c2ff92b65b4759a91e45fad5ef886fFariborz Jahanian    << FixItHint::CreateReplacement(OpLoc, "->");
7396326e05fe8c2ff92b65b4759a91e45fad5ef886fFariborz Jahanian    return ExprError();
74041aadbc530f071fe5ccbfc2560899a4a2e74c057Fariborz Jahanian  }
741b9d4fc1f54924a7b242fb763192a40c19fa6103dChris Lattner
7427f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  Diag(MemberLoc, diag::err_property_not_found)
7437f81652f97a69ae8b514893a69c0245253687e55Chris Lattner    << MemberName << QualType(OPT, 0);
74499130e5a02e93282cb393d2cba0d3dffc10abc01Fariborz Jahanian  if (Setter)
7457f81652f97a69ae8b514893a69c0245253687e55Chris Lattner    Diag(Setter->getLocation(), diag::note_getter_unavailable)
74699130e5a02e93282cb393d2cba0d3dffc10abc01Fariborz Jahanian          << MemberName << BaseExpr->getSourceRange();
7477f81652f97a69ae8b514893a69c0245253687e55Chris Lattner  return ExprError();
7487f81652f97a69ae8b514893a69c0245253687e55Chris Lattner}
7497f81652f97a69ae8b514893a69c0245253687e55Chris Lattner
7507f81652f97a69ae8b514893a69c0245253687e55Chris Lattner
7517f81652f97a69ae8b514893a69c0245253687e55Chris Lattner
75260d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Sema::
753eb483eb3ee80300f15d6d13573d82493c2194461Chris LattnerActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
754eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner                          IdentifierInfo &propertyName,
755eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner                          SourceLocation receiverNameLoc,
756eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner                          SourceLocation propertyNameLoc) {
7571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
758f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor  IdentifierInfo *receiverNamePtr = &receiverName;
759c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor  ObjCInterfaceDecl *IFace = getObjCInterfaceDecl(receiverNamePtr,
760c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor                                                  receiverNameLoc);
761926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
762926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  bool IsSuper = false;
763eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner  if (IFace == 0) {
764eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner    // If the "receiver" is 'super' in a method, handle it as an expression-like
765eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner    // property reference.
76626743b20e4a8c2a986e6453f0c38beba0afef633John McCall    if (receiverNamePtr->isStr("super")) {
767926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor      IsSuper = true;
768926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
76926743b20e4a8c2a986e6453f0c38beba0afef633John McCall      if (ObjCMethodDecl *CurMethod = tryCaptureObjCSelf()) {
770eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner        if (CurMethod->isInstanceMethod()) {
771eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner          QualType T =
772eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner            Context.getObjCInterfaceType(CurMethod->getClassInterface());
773eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner          T = Context.getObjCObjectPointerType(T);
774eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner
775eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner          return HandleExprPropertyRefExpr(T->getAsObjCInterfacePointerType(),
7766326e05fe8c2ff92b65b4759a91e45fad5ef886fFariborz Jahanian                                           /*BaseExpr*/0,
7776326e05fe8c2ff92b65b4759a91e45fad5ef886fFariborz Jahanian                                           SourceLocation()/*OpLoc*/,
7786326e05fe8c2ff92b65b4759a91e45fad5ef886fFariborz Jahanian                                           &propertyName,
7798ac2d449820fd0df00fcbde5bf82165c1f49854dFariborz Jahanian                                           propertyNameLoc,
7808ac2d449820fd0df00fcbde5bf82165c1f49854dFariborz Jahanian                                           receiverNameLoc, T, true);
781eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner        }
782eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner
783eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner        // Otherwise, if this is a class method, try dispatching to our
784eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner        // superclass.
785eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner        IFace = CurMethod->getClassInterface()->getSuperClass();
786eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner      }
78726743b20e4a8c2a986e6453f0c38beba0afef633John McCall    }
788eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner
789eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner    if (IFace == 0) {
790eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner      Diag(receiverNameLoc, diag::err_expected_ident_or_lparen);
791eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner      return ExprError();
792eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner    }
7938149a5786def747af783a9e3c22714bb7ab42b9cFariborz Jahanian  }
7941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
795eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner  // Search for a declared property first.
79661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  Selector Sel = PP.getSelectorTable().getNullarySelector(&propertyName);
79717945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  ObjCMethodDecl *Getter = IFace->lookupClassMethod(Sel);
79861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
79961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  // If this reference is in an @implementation, check for 'private' methods.
80061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  if (!Getter)
80161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
80261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff      if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
80387018775ed689d0a67357cf767747166044b3a27Argyrios Kyrtzidis        if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation())
80417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis          Getter = ImpDecl->getClassMethod(Sel);
80561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
80661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  if (Getter) {
80761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    // FIXME: refactor/share with ActOnMemberReference().
80861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    // Check if we can reference this property.
80961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    if (DiagnoseUseOfDecl(Getter, propertyNameLoc))
81061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff      return ExprError();
81161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  }
8121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
81361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  // Look for the matching setter, in case it is needed.
8141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Selector SetterSel =
8151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    SelectorTable::constructSetterName(PP.getIdentifierTable(),
816fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff                                       PP.getSelectorTable(), &propertyName);
8171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
81817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
81961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  if (!Setter) {
82061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    // If this reference is in an @implementation, also check for 'private'
82161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    // methods.
82261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
82361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff      if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
82487018775ed689d0a67357cf767747166044b3a27Argyrios Kyrtzidis        if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation())
82517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis          Setter = ImpDecl->getClassMethod(SetterSel);
82661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  }
82761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  // Look through local category implementations associated with the class.
8281cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis  if (!Setter)
8291cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis    Setter = IFace->getCategoryClassMethod(SetterSel);
83061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
83161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  if (Setter && DiagnoseUseOfDecl(Setter, propertyNameLoc))
83261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    return ExprError();
83361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
83461f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  if (Getter || Setter) {
835926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    if (IsSuper)
836926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter,
8373c3b7f90a863af43fa63043d396553ecf205351cJohn McCall                                                   Context.PseudoObjectTy,
8383c3b7f90a863af43fa63043d396553ecf205351cJohn McCall                                                   VK_LValue, OK_ObjCProperty,
839926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                                   propertyNameLoc,
840926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                                   receiverNameLoc,
841926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                          Context.getObjCInterfaceType(IFace)));
842926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
84312f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall    return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter,
8443c3b7f90a863af43fa63043d396553ecf205351cJohn McCall                                                   Context.PseudoObjectTy,
8453c3b7f90a863af43fa63043d396553ecf205351cJohn McCall                                                   VK_LValue, OK_ObjCProperty,
84612f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall                                                   propertyNameLoc,
84712f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall                                                   receiverNameLoc, IFace));
84861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  }
84961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  return ExprError(Diag(propertyNameLoc, diag::err_property_not_found)
85061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff                     << &propertyName << Context.getObjCInterfaceType(IFace));
85161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff}
85261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
85347bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas GregorSema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S,
8541569f95831a8c99e9f664137bf8f40e47ee3d90fDouglas Gregor                                               IdentifierInfo *Name,
85547bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor                                               SourceLocation NameLoc,
85647bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor                                               bool IsSuper,
8571569f95831a8c99e9f664137bf8f40e47ee3d90fDouglas Gregor                                               bool HasTrailingDot,
858b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall                                               ParsedType &ReceiverType) {
859b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ReceiverType = ParsedType();
8601569f95831a8c99e9f664137bf8f40e47ee3d90fDouglas Gregor
86147bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor  // If the identifier is "super" and there is no trailing dot, we're
86295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  // messaging super. If the identifier is "super" and there is a
86395f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  // trailing dot, it's an instance message.
86495f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor  if (IsSuper && S->isInObjcMethodScope())
86595f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor    return HasTrailingDot? ObjCInstanceMessage : ObjCSuperMessage;
86647bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor
86747bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor  LookupResult Result(*this, Name, NameLoc, LookupOrdinaryName);
86847bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor  LookupName(Result, S);
86947bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor
87047bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor  switch (Result.getResultKind()) {
87147bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor  case LookupResult::NotFound:
872ed46442adea496dfb01dbbe53ace583d5614e79aDouglas Gregor    // Normal name lookup didn't find anything. If we're in an
873ed46442adea496dfb01dbbe53ace583d5614e79aDouglas Gregor    // Objective-C method, look for ivars. If we find one, we're done!
87495f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor    // FIXME: This is a hack. Ivar lookup should be part of normal
87595f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor    // lookup.
876ed46442adea496dfb01dbbe53ace583d5614e79aDouglas Gregor    if (ObjCMethodDecl *Method = getCurMethodDecl()) {
877ed46442adea496dfb01dbbe53ace583d5614e79aDouglas Gregor      ObjCInterfaceDecl *ClassDeclared;
878ed46442adea496dfb01dbbe53ace583d5614e79aDouglas Gregor      if (Method->getClassInterface()->lookupInstanceVariable(Name,
879ed46442adea496dfb01dbbe53ace583d5614e79aDouglas Gregor                                                              ClassDeclared))
880ed46442adea496dfb01dbbe53ace583d5614e79aDouglas Gregor        return ObjCInstanceMessage;
881ed46442adea496dfb01dbbe53ace583d5614e79aDouglas Gregor    }
88295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor
88347bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor    // Break out; we'll perform typo correction below.
88447bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor    break;
88547bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor
88647bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor  case LookupResult::NotFoundInCurrentInstantiation:
88747bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor  case LookupResult::FoundOverloaded:
88847bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor  case LookupResult::FoundUnresolvedValue:
88947bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor  case LookupResult::Ambiguous:
89047bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor    Result.suppressDiagnostics();
89147bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor    return ObjCInstanceMessage;
89247bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor
89347bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor  case LookupResult::Found: {
8948348de33e92b8278a07a7573eb7ad3c166c02b0dFariborz Jahanian    // If the identifier is a class or not, and there is a trailing dot,
8958348de33e92b8278a07a7573eb7ad3c166c02b0dFariborz Jahanian    // it's an instance message.
8968348de33e92b8278a07a7573eb7ad3c166c02b0dFariborz Jahanian    if (HasTrailingDot)
8978348de33e92b8278a07a7573eb7ad3c166c02b0dFariborz Jahanian      return ObjCInstanceMessage;
89847bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor    // We found something. If it's a type, then we have a class
89947bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor    // message. Otherwise, it's an instance message.
90047bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor    NamedDecl *ND = Result.getFoundDecl();
9011569f95831a8c99e9f664137bf8f40e47ee3d90fDouglas Gregor    QualType T;
9021569f95831a8c99e9f664137bf8f40e47ee3d90fDouglas Gregor    if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(ND))
9031569f95831a8c99e9f664137bf8f40e47ee3d90fDouglas Gregor      T = Context.getObjCInterfaceType(Class);
9041569f95831a8c99e9f664137bf8f40e47ee3d90fDouglas Gregor    else if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
9051569f95831a8c99e9f664137bf8f40e47ee3d90fDouglas Gregor      T = Context.getTypeDeclType(Type);
9061569f95831a8c99e9f664137bf8f40e47ee3d90fDouglas Gregor    else
9071569f95831a8c99e9f664137bf8f40e47ee3d90fDouglas Gregor      return ObjCInstanceMessage;
9081569f95831a8c99e9f664137bf8f40e47ee3d90fDouglas Gregor
9091569f95831a8c99e9f664137bf8f40e47ee3d90fDouglas Gregor    //  We have a class message, and T is the type we're
9101569f95831a8c99e9f664137bf8f40e47ee3d90fDouglas Gregor    //  messaging. Build source-location information for it.
9111569f95831a8c99e9f664137bf8f40e47ee3d90fDouglas Gregor    TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
912b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall    ReceiverType = CreateParsedType(T, TSInfo);
9131569f95831a8c99e9f664137bf8f40e47ee3d90fDouglas Gregor    return ObjCClassMessage;
91447bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor  }
91547bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor  }
91647bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor
917aaf87162c5fbfbf320072da3a8e83392e1bbf041Douglas Gregor  // Determine our typo-correction context.
918aaf87162c5fbfbf320072da3a8e83392e1bbf041Douglas Gregor  CorrectTypoContext CTC = CTC_Expression;
919aaf87162c5fbfbf320072da3a8e83392e1bbf041Douglas Gregor  if (ObjCMethodDecl *Method = getCurMethodDecl())
920aaf87162c5fbfbf320072da3a8e83392e1bbf041Douglas Gregor    if (Method->getClassInterface() &&
921aaf87162c5fbfbf320072da3a8e83392e1bbf041Douglas Gregor        Method->getClassInterface()->getSuperClass())
922aaf87162c5fbfbf320072da3a8e83392e1bbf041Douglas Gregor      CTC = CTC_ObjCMessageReceiver;
923aaf87162c5fbfbf320072da3a8e83392e1bbf041Douglas Gregor
924d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor  if (TypoCorrection Corrected = CorrectTypo(Result.getLookupNameInfo(),
925d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor                                             Result.getLookupKind(), S, NULL,
926d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor                                             NULL, false, CTC)) {
927d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor    if (NamedDecl *ND = Corrected.getCorrectionDecl()) {
928aaf87162c5fbfbf320072da3a8e83392e1bbf041Douglas Gregor      // If we found a declaration, correct when it refers to an Objective-C
929aaf87162c5fbfbf320072da3a8e83392e1bbf041Douglas Gregor      // class.
9301569f95831a8c99e9f664137bf8f40e47ee3d90fDouglas Gregor      if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(ND)) {
931aaf87162c5fbfbf320072da3a8e83392e1bbf041Douglas Gregor        Diag(NameLoc, diag::err_unknown_receiver_suggest)
932d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor          << Name << Corrected.getCorrection()
933aaf87162c5fbfbf320072da3a8e83392e1bbf041Douglas Gregor          << FixItHint::CreateReplacement(SourceRange(NameLoc),
934aaf87162c5fbfbf320072da3a8e83392e1bbf041Douglas Gregor                                          ND->getNameAsString());
935aaf87162c5fbfbf320072da3a8e83392e1bbf041Douglas Gregor        Diag(ND->getLocation(), diag::note_previous_decl)
936d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor          << Corrected.getCorrection();
937aaf87162c5fbfbf320072da3a8e83392e1bbf041Douglas Gregor
9381569f95831a8c99e9f664137bf8f40e47ee3d90fDouglas Gregor        QualType T = Context.getObjCInterfaceType(Class);
9391569f95831a8c99e9f664137bf8f40e47ee3d90fDouglas Gregor        TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
940b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall        ReceiverType = CreateParsedType(T, TSInfo);
941aaf87162c5fbfbf320072da3a8e83392e1bbf041Douglas Gregor        return ObjCClassMessage;
942aaf87162c5fbfbf320072da3a8e83392e1bbf041Douglas Gregor      }
943d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor    } else if (Corrected.isKeyword() &&
944d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor               Corrected.getCorrectionAsIdentifierInfo()->isStr("super")) {
945aaf87162c5fbfbf320072da3a8e83392e1bbf041Douglas Gregor      // If we've found the keyword "super", this is a send to super.
94647bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor      Diag(NameLoc, diag::err_unknown_receiver_suggest)
947d8bba9c15230d2b1b3893e272106aa79efc50251Douglas Gregor        << Name << Corrected.getCorrection()
948aaf87162c5fbfbf320072da3a8e83392e1bbf041Douglas Gregor        << FixItHint::CreateReplacement(SourceRange(NameLoc), "super");
949aaf87162c5fbfbf320072da3a8e83392e1bbf041Douglas Gregor      return ObjCSuperMessage;
95047bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor    }
95147bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor  }
95247bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor
95347bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor  // Fall back: let the parser try to parse it as an instance message.
95447bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor  return ObjCInstanceMessage;
95547bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor}
95661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
95760d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Sema::ActOnSuperMessage(Scope *S,
9580fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor                                   SourceLocation SuperLoc,
9590fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor                                   Selector Sel,
9600fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor                                   SourceLocation LBracLoc,
961951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis                                   ArrayRef<SourceLocation> SelectorLocs,
9620fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor                                   SourceLocation RBracLoc,
9630fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor                                   MultiExprArg Args) {
9642725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  // Determine whether we are inside a method or not.
96526743b20e4a8c2a986e6453f0c38beba0afef633John McCall  ObjCMethodDecl *Method = tryCaptureObjCSelf();
966f95861a4ab6bbd6a975ed079dd70eb1cc22f4467Douglas Gregor  if (!Method) {
967f95861a4ab6bbd6a975ed079dd70eb1cc22f4467Douglas Gregor    Diag(SuperLoc, diag::err_invalid_receiver_to_message_super);
968f95861a4ab6bbd6a975ed079dd70eb1cc22f4467Douglas Gregor    return ExprError();
969f95861a4ab6bbd6a975ed079dd70eb1cc22f4467Douglas Gregor  }
9702725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor
971f95861a4ab6bbd6a975ed079dd70eb1cc22f4467Douglas Gregor  ObjCInterfaceDecl *Class = Method->getClassInterface();
972f95861a4ab6bbd6a975ed079dd70eb1cc22f4467Douglas Gregor  if (!Class) {
973f95861a4ab6bbd6a975ed079dd70eb1cc22f4467Douglas Gregor    Diag(SuperLoc, diag::error_no_super_class_message)
974f95861a4ab6bbd6a975ed079dd70eb1cc22f4467Douglas Gregor      << Method->getDeclName();
9752725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor    return ExprError();
97615faee19fdb9017dd6d08a690427b18c3b062c2dChris Lattner  }
9772725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor
978f95861a4ab6bbd6a975ed079dd70eb1cc22f4467Douglas Gregor  ObjCInterfaceDecl *Super = Class->getSuperClass();
9792725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  if (!Super) {
980f95861a4ab6bbd6a975ed079dd70eb1cc22f4467Douglas Gregor    // The current class does not have a superclass.
981e00909a6e997ec33d9baa5312e9d27b52a3da770Ted Kremenek    Diag(SuperLoc, diag::error_root_class_cannot_use_super)
982e00909a6e997ec33d9baa5312e9d27b52a3da770Ted Kremenek      << Class->getIdentifier();
9832725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor    return ExprError();
9842725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  }
9852725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor
986f95861a4ab6bbd6a975ed079dd70eb1cc22f4467Douglas Gregor  // We are in a method whose class has a superclass, so 'super'
987f95861a4ab6bbd6a975ed079dd70eb1cc22f4467Douglas Gregor  // is acting as a keyword.
988f95861a4ab6bbd6a975ed079dd70eb1cc22f4467Douglas Gregor  if (Method->isInstanceMethod()) {
9899a1ecf0522ccb7a45577f856150c15af0ee1df2aNico Weber    if (Sel.getMethodFamily() == OMF_dealloc)
9909a1ecf0522ccb7a45577f856150c15af0ee1df2aNico Weber      ObjCShouldCallSuperDealloc = false;
99180cb6e69d9e85231588ae604e4bc2bc9a07389afNico Weber    if (Sel.getMethodFamily() == OMF_finalize)
99280cb6e69d9e85231588ae604e4bc2bc9a07389afNico Weber      ObjCShouldCallSuperFinalize = false;
9939a1ecf0522ccb7a45577f856150c15af0ee1df2aNico Weber
994f95861a4ab6bbd6a975ed079dd70eb1cc22f4467Douglas Gregor    // Since we are in an instance method, this is an instance
995f95861a4ab6bbd6a975ed079dd70eb1cc22f4467Douglas Gregor    // message to the superclass instance.
996f95861a4ab6bbd6a975ed079dd70eb1cc22f4467Douglas Gregor    QualType SuperTy = Context.getObjCInterfaceType(Super);
997f95861a4ab6bbd6a975ed079dd70eb1cc22f4467Douglas Gregor    SuperTy = Context.getObjCObjectPointerType(SuperTy);
9989ae2f076ca5ab1feb3ba95629099ec2319833701John McCall    return BuildInstanceMessage(0, SuperTy, SuperLoc,
999f40f0d5a382395e0301d7dcbeaa2b8e90b8973b1Argyrios Kyrtzidis                                Sel, /*Method=*/0,
1000951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis                                LBracLoc, SelectorLocs, RBracLoc, move(Args));
10012725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  }
1002f95861a4ab6bbd6a975ed079dd70eb1cc22f4467Douglas Gregor
1003f95861a4ab6bbd6a975ed079dd70eb1cc22f4467Douglas Gregor  // Since we are in a class method, this is a class message to
1004f95861a4ab6bbd6a975ed079dd70eb1cc22f4467Douglas Gregor  // the superclass.
1005f95861a4ab6bbd6a975ed079dd70eb1cc22f4467Douglas Gregor  return BuildClassMessage(/*ReceiverTypeInfo=*/0,
1006f95861a4ab6bbd6a975ed079dd70eb1cc22f4467Douglas Gregor                           Context.getObjCInterfaceType(Super),
1007f40f0d5a382395e0301d7dcbeaa2b8e90b8973b1Argyrios Kyrtzidis                           SuperLoc, Sel, /*Method=*/0,
1008951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis                           LBracLoc, SelectorLocs, RBracLoc, move(Args));
10092725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor}
10102725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor
10112725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// \brief Build an Objective-C class message expression.
10122725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor///
10132725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// This routine takes care of both normal class messages and
10142725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// class messages to the superclass.
10152725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor///
10162725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// \param ReceiverTypeInfo Type source information that describes the
10172725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// receiver of this message. This may be NULL, in which case we are
10182725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// sending to the superclass and \p SuperLoc must be a valid source
10192725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// location.
10202725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor
10212725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// \param ReceiverType The type of the object receiving the
10222725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// message. When \p ReceiverTypeInfo is non-NULL, this is the same
10232725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// type as that refers to. For a superclass send, this is the type of
10242725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// the superclass.
10252725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor///
10262725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// \param SuperLoc The location of the "super" keyword in a
10272725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// superclass message.
10282725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor///
10292725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// \param Sel The selector to which the message is being sent.
10302725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor///
1031f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor/// \param Method The method that this class message is invoking, if
1032f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor/// already known.
1033f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor///
10342725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// \param LBracLoc The location of the opening square bracket ']'.
10352725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor///
10362725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// \param RBrac The location of the closing square bracket ']'.
10372725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor///
10382725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// \param Args The message arguments.
103960d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
10400fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor                                   QualType ReceiverType,
10410fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor                                   SourceLocation SuperLoc,
10420fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor                                   Selector Sel,
10430fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor                                   ObjCMethodDecl *Method,
10440fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor                                   SourceLocation LBracLoc,
1045951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis                                   ArrayRef<SourceLocation> SelectorLocs,
10460fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor                                   SourceLocation RBracLoc,
10470fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor                                   MultiExprArg ArgsIn) {
10480fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor  SourceLocation Loc = SuperLoc.isValid()? SuperLoc
10499497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor    : ReceiverTypeInfo->getTypeLoc().getSourceRange().getBegin();
10500fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor  if (LBracLoc.isInvalid()) {
10510fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor    Diag(Loc, diag::err_missing_open_square_message_send)
10520fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor      << FixItHint::CreateInsertion(Loc, "[");
10530fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor    LBracLoc = Loc;
10540fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor  }
10550fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor
105692e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor  if (ReceiverType->isDependentType()) {
105792e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor    // If the receiver type is dependent, we can't type-check anything
105892e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor    // at this point. Build a dependent expression.
105992e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor    unsigned NumArgs = ArgsIn.size();
106092e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor    Expr **Args = reinterpret_cast<Expr **>(ArgsIn.release());
106192e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor    assert(SuperLoc.isInvalid() && "Message to super with dependent type");
1062f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall    return Owned(ObjCMessageExpr::Create(Context, ReceiverType,
1063f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall                                         VK_RValue, LBracLoc, ReceiverTypeInfo,
1064951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis                                         Sel, SelectorLocs, /*Method=*/0,
10658d9ed7980405e91a12e33338a78fb99620adf553Argyrios Kyrtzidis                                         makeArrayRef(Args, NumArgs),RBracLoc));
106692e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor  }
106715faee19fdb9017dd6d08a690427b18c3b062c2dChris Lattner
10682725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  // Find the class to which we are sending this message.
10692725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  ObjCInterfaceDecl *Class = 0;
1070c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  const ObjCObjectType *ClassType = ReceiverType->getAs<ObjCObjectType>();
1071c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  if (!ClassType || !(Class = ClassType->getInterface())) {
10722725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor    Diag(Loc, diag::err_invalid_receiver_class_message)
10732725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor      << ReceiverType;
10742725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor    return ExprError();
10757c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff  }
10762725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  assert(Class && "We don't know which class we're messaging?");
107743bcdb2d4d8390aec89e75f4d232b1fb218a59c5Fariborz Jahanian  // objc++ diagnoses during typename annotation.
107843bcdb2d4d8390aec89e75f4d232b1fb218a59c5Fariborz Jahanian  if (!getLangOptions().CPlusPlus)
107943bcdb2d4d8390aec89e75f4d232b1fb218a59c5Fariborz Jahanian    (void)DiagnoseUseOfDecl(Class, Loc);
10802725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  // Find the method we are messaging.
1081f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor  if (!Method) {
1082f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor    if (Class->isForwardDecl()) {
1083f85e193739c953358c865005855253af4f68a497John McCall      if (getLangOptions().ObjCAutoRefCount) {
1084f85e193739c953358c865005855253af4f68a497John McCall        Diag(Loc, diag::err_arc_receiver_forward_class) << ReceiverType;
1085f85e193739c953358c865005855253af4f68a497John McCall      } else {
1086f85e193739c953358c865005855253af4f68a497John McCall        Diag(Loc, diag::warn_receiver_forward_class) << Class->getDeclName();
1087f85e193739c953358c865005855253af4f68a497John McCall      }
1088f85e193739c953358c865005855253af4f68a497John McCall
1089f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor      // A forward class used in messaging is treated as a 'Class'
1090f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor      Method = LookupFactoryMethodInGlobalPool(Sel,
1091f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor                                               SourceRange(LBracLoc, RBracLoc));
1092f85e193739c953358c865005855253af4f68a497John McCall      if (Method && !getLangOptions().ObjCAutoRefCount)
1093f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor        Diag(Method->getLocation(), diag::note_method_sent_forward_class)
1094f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor          << Method->getDeclName();
1095f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor    }
1096f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor    if (!Method)
1097f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor      Method = Class->lookupClassMethod(Sel);
10981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1099f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor    // If we have an implementation in scope, check "private" methods.
1100f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor    if (!Method)
1101f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor      Method = LookupPrivateClassMethod(Sel, Class);
11027c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff
1103f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor    if (Method && DiagnoseUseOfDecl(Method, Loc))
1104f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor      return ExprError();
1105f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor  }
11061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11072725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  // Check the argument types and determine the result type.
11082725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  QualType ReturnType;
1109f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  ExprValueKind VK = VK_RValue;
1110f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall
11112725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  unsigned NumArgs = ArgsIn.size();
11122725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  Expr **Args = reinterpret_cast<Expr **>(ArgsIn.release());
1113926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  if (CheckMessageArgumentTypes(ReceiverType, Args, NumArgs, Sel, Method, true,
1114926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                SuperLoc.isValid(), LBracLoc, RBracLoc,
1115926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                ReturnType, VK))
11162725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor    return ExprError();
11174df728e368fa1f65ffc57572fed613dcca5b4fe8Ted Kremenek
1118483dd2f55ee53bc765123ead3428aa4ad2682cf3Douglas Gregor  if (Method && !Method->getResultType()->isVoidType() &&
1119483dd2f55ee53bc765123ead3428aa4ad2682cf3Douglas Gregor      RequireCompleteType(LBracLoc, Method->getResultType(),
1120483dd2f55ee53bc765123ead3428aa4ad2682cf3Douglas Gregor                          diag::err_illegal_message_expr_incomplete_type))
1121483dd2f55ee53bc765123ead3428aa4ad2682cf3Douglas Gregor    return ExprError();
1122483dd2f55ee53bc765123ead3428aa4ad2682cf3Douglas Gregor
11232725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  // Construct the appropriate ObjCMessageExpr.
11242d6b0e94db30c0e2754d270753c6f75478e451bfDouglas Gregor  Expr *Result;
11252725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  if (SuperLoc.isValid())
1126f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall    Result = ObjCMessageExpr::Create(Context, ReturnType, VK, LBracLoc,
11272d6b0e94db30c0e2754d270753c6f75478e451bfDouglas Gregor                                     SuperLoc, /*IsInstanceSuper=*/false,
1128951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis                                     ReceiverType, Sel, SelectorLocs,
11298d9ed7980405e91a12e33338a78fb99620adf553Argyrios Kyrtzidis                                     Method, makeArrayRef(Args, NumArgs),
11308d9ed7980405e91a12e33338a78fb99620adf553Argyrios Kyrtzidis                                     RBracLoc);
11312d6b0e94db30c0e2754d270753c6f75478e451bfDouglas Gregor  else
1132f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall    Result = ObjCMessageExpr::Create(Context, ReturnType, VK, LBracLoc,
1133951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis                                     ReceiverTypeInfo, Sel, SelectorLocs,
11348d9ed7980405e91a12e33338a78fb99620adf553Argyrios Kyrtzidis                                     Method, makeArrayRef(Args, NumArgs),
11358d9ed7980405e91a12e33338a78fb99620adf553Argyrios Kyrtzidis                                     RBracLoc);
11362d6b0e94db30c0e2754d270753c6f75478e451bfDouglas Gregor  return MaybeBindToTemporary(Result);
113785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
113885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
11392725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor// ActOnClassMessage - used for both unary and keyword messages.
114085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// ArgExprs is optional - if it is present, the number of expressions
114185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// is obtained from Sel.getNumArgs().
114260d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Sema::ActOnClassMessage(Scope *S,
114377328d1bb92c2c46bc3e4badc4b4b97c517903b7Douglas Gregor                                   ParsedType Receiver,
114477328d1bb92c2c46bc3e4badc4b4b97c517903b7Douglas Gregor                                   Selector Sel,
114577328d1bb92c2c46bc3e4badc4b4b97c517903b7Douglas Gregor                                   SourceLocation LBracLoc,
1146951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis                                   ArrayRef<SourceLocation> SelectorLocs,
114777328d1bb92c2c46bc3e4badc4b4b97c517903b7Douglas Gregor                                   SourceLocation RBracLoc,
114877328d1bb92c2c46bc3e4badc4b4b97c517903b7Douglas Gregor                                   MultiExprArg Args) {
11492725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  TypeSourceInfo *ReceiverTypeInfo;
11502725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  QualType ReceiverType = GetTypeFromParser(Receiver, &ReceiverTypeInfo);
11512725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  if (ReceiverType.isNull())
11522725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor    return ExprError();
11531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11552725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  if (!ReceiverTypeInfo)
11562725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor    ReceiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType, LBracLoc);
11571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11582725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  return BuildClassMessage(ReceiverTypeInfo, ReceiverType,
1159f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor                           /*SuperLoc=*/SourceLocation(), Sel, /*Method=*/0,
1160951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis                           LBracLoc, SelectorLocs, RBracLoc, move(Args));
11612725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor}
116287d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff
11632725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// \brief Build an Objective-C instance message expression.
11642725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor///
11652725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// This routine takes care of both normal instance messages and
11662725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// instance messages to the superclass instance.
11672725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor///
11682725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// \param Receiver The expression that computes the object that will
11692725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// receive this message. This may be empty, in which case we are
11702725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// sending to the superclass instance and \p SuperLoc must be a valid
11712725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// source location.
11722725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor///
11732725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// \param ReceiverType The (static) type of the object receiving the
11742725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// message. When a \p Receiver expression is provided, this is the
11752725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// same type as that expression. For a superclass instance send, this
11762725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// is a pointer to the type of the superclass.
11772725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor///
11782725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// \param SuperLoc The location of the "super" keyword in a
11792725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// superclass instance message.
11802725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor///
11812725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// \param Sel The selector to which the message is being sent.
11822725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor///
1183f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor/// \param Method The method that this instance message is invoking, if
1184f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor/// already known.
1185f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor///
11862725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// \param LBracLoc The location of the opening square bracket ']'.
11872725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor///
11882725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// \param RBrac The location of the closing square bracket ']'.
11892725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor///
11902725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// \param Args The message arguments.
119160d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Sema::BuildInstanceMessage(Expr *Receiver,
1192f40f0d5a382395e0301d7dcbeaa2b8e90b8973b1Argyrios Kyrtzidis                                      QualType ReceiverType,
1193f40f0d5a382395e0301d7dcbeaa2b8e90b8973b1Argyrios Kyrtzidis                                      SourceLocation SuperLoc,
1194f40f0d5a382395e0301d7dcbeaa2b8e90b8973b1Argyrios Kyrtzidis                                      Selector Sel,
1195f40f0d5a382395e0301d7dcbeaa2b8e90b8973b1Argyrios Kyrtzidis                                      ObjCMethodDecl *Method,
1196f40f0d5a382395e0301d7dcbeaa2b8e90b8973b1Argyrios Kyrtzidis                                      SourceLocation LBracLoc,
1197951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis                                      ArrayRef<SourceLocation> SelectorLocs,
1198f40f0d5a382395e0301d7dcbeaa2b8e90b8973b1Argyrios Kyrtzidis                                      SourceLocation RBracLoc,
1199f40f0d5a382395e0301d7dcbeaa2b8e90b8973b1Argyrios Kyrtzidis                                      MultiExprArg ArgsIn) {
12000fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor  // The location of the receiver.
12010fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor  SourceLocation Loc = SuperLoc.isValid()? SuperLoc : Receiver->getLocStart();
12020fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor
12030fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor  if (LBracLoc.isInvalid()) {
12040fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor    Diag(Loc, diag::err_missing_open_square_message_send)
12050fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor      << FixItHint::CreateInsertion(Loc, "[");
12060fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor    LBracLoc = Loc;
12070fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor  }
12080fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor
12092725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  // If we have a receiver expression, perform appropriate promotions
12102725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  // and determine receiver type.
12112725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  if (Receiver) {
12125acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    if (Receiver->hasPlaceholderType()) {
12135acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      ExprResult result = CheckPlaceholderExpr(Receiver);
12145acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      if (result.isInvalid()) return ExprError();
12155acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      Receiver = result.take();
12165acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    }
12175acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
121892e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor    if (Receiver->isTypeDependent()) {
121992e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor      // If the receiver is type-dependent, we can't type-check anything
122092e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor      // at this point. Build a dependent expression.
122192e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor      unsigned NumArgs = ArgsIn.size();
122292e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor      Expr **Args = reinterpret_cast<Expr **>(ArgsIn.release());
122392e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor      assert(SuperLoc.isInvalid() && "Message to super with dependent type");
122492e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor      return Owned(ObjCMessageExpr::Create(Context, Context.DependentTy,
1225f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall                                           VK_RValue, LBracLoc, Receiver, Sel,
1226951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis                                           SelectorLocs, /*Method=*/0,
12278d9ed7980405e91a12e33338a78fb99620adf553Argyrios Kyrtzidis                                           makeArrayRef(Args, NumArgs),
12288d9ed7980405e91a12e33338a78fb99620adf553Argyrios Kyrtzidis                                           RBracLoc));
122992e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor    }
123092e986e0adb79e8a47f738bd608e6c97c547641dDouglas Gregor
12312725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor    // If necessary, apply function/array conversion to the receiver.
12322725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor    // C99 6.7.5.3p[7,8].
1233429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley    ExprResult Result = DefaultFunctionArrayLvalueConversion(Receiver);
1234429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley    if (Result.isInvalid())
1235429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley      return ExprError();
1236429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley    Receiver = Result.take();
12372725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor    ReceiverType = Receiver->getType();
12382725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  }
123904badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor
1240f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor  if (!Method) {
1241f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor    // Handle messages to id.
1242ba551983016ee3eac5421255d2ebe6723e61befbFariborz Jahanian    bool receiverIsId = ReceiverType->isObjCIdType();
12436b308f6dc7d8f1581c52095f435c0e1284b111d8Fariborz Jahanian    if (receiverIsId || ReceiverType->isBlockPointerType() ||
1244f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor        (Receiver && Context.isObjCNSObjectType(Receiver->getType()))) {
1245f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor      Method = LookupInstanceMethodInGlobalPool(Sel,
12466b308f6dc7d8f1581c52095f435c0e1284b111d8Fariborz Jahanian                                                SourceRange(LBracLoc, RBracLoc),
12476b308f6dc7d8f1581c52095f435c0e1284b111d8Fariborz Jahanian                                                receiverIsId);
1248f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor      if (!Method)
12492725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor        Method = LookupFactoryMethodInGlobalPool(Sel,
12506b308f6dc7d8f1581c52095f435c0e1284b111d8Fariborz Jahanian                                                 SourceRange(LBracLoc, RBracLoc),
12516b308f6dc7d8f1581c52095f435c0e1284b111d8Fariborz Jahanian                                                 receiverIsId);
1252f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor    } else if (ReceiverType->isObjCClassType() ||
1253f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor               ReceiverType->isObjCQualifiedClassType()) {
1254f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor      // Handle messages to Class.
1255759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian      // We allow sending a message to a qualified Class ("Class<foo>"), which
1256759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian      // is ok as long as one of the protocols implements the selector (if not, warn).
1257759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian      if (const ObjCObjectPointerType *QClassTy
1258759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian            = ReceiverType->getAsObjCQualifiedClassType()) {
1259759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian        // Search protocols for class methods.
1260759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian        Method = LookupMethodInQualifiedType(Sel, QClassTy, false);
1261759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian        if (!Method) {
1262759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian          Method = LookupMethodInQualifiedType(Sel, QClassTy, true);
1263759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian          // warn if instance method found for a Class message.
1264759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian          if (Method) {
1265759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian            Diag(Loc, diag::warn_instance_method_on_class_found)
1266759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian              << Method->getSelector() << Sel;
1267759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian            Diag(Method->getLocation(), diag::note_method_declared_at);
1268759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian          }
12696b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff        }
1270759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian      } else {
1271759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian        if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
1272759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian          if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) {
1273759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian            // First check the public methods in the class interface.
1274759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian            Method = ClassDecl->lookupClassMethod(Sel);
1275759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian
1276759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian            if (!Method)
1277759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian              Method = LookupPrivateClassMethod(Sel, ClassDecl);
1278759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian          }
1279759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian          if (Method && DiagnoseUseOfDecl(Method, Loc))
1280759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian            return ExprError();
1281759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian        }
1282759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian        if (!Method) {
1283759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian          // If not messaging 'self', look for any factory method named 'Sel'.
1284c737acb8e86564becc5939d681089d1851e6be1aDouglas Gregor          if (!Receiver || !isSelfExpr(Receiver)) {
1285759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian            Method = LookupFactoryMethodInGlobalPool(Sel,
1286759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian                                                SourceRange(LBracLoc, RBracLoc),
1287759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian                                                     true);
1288759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian            if (!Method) {
1289759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian              // If no class (factory) method was found, check if an _instance_
1290759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian              // method of the same name exists in the root class only.
1291759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian              Method = LookupInstanceMethodInGlobalPool(Sel,
12926b308f6dc7d8f1581c52095f435c0e1284b111d8Fariborz Jahanian                                               SourceRange(LBracLoc, RBracLoc),
1293759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian                                                        true);
1294759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian              if (Method)
1295759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian                  if (const ObjCInterfaceDecl *ID =
1296759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian                      dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) {
1297759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian                    if (ID->getSuperClass())
1298759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian                      Diag(Loc, diag::warn_root_inst_method_not_found)
1299759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian                      << Sel << SourceRange(LBracLoc, RBracLoc);
1300759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian                  }
1301759abb4d9ec14ae32104a9677b60f0542b60d1d8Fariborz Jahanian            }
130204badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor          }
130304badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor        }
130404badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor      }
130504badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor    } else {
1306f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor      ObjCInterfaceDecl* ClassDecl = 0;
1307f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor
1308f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor      // We allow sending a message to a qualified ID ("id<foo>"), which is ok as
1309f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor      // long as one of the protocols implements the selector (if not, warn).
1310f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor      if (const ObjCObjectPointerType *QIdTy
1311f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor                                   = ReceiverType->getAsObjCQualifiedIdType()) {
1312f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor        // Search protocols for instance methods.
131327569b0f3e1b27f609a2e104b39bad077850e210Fariborz Jahanian        Method = LookupMethodInQualifiedType(Sel, QIdTy, true);
131427569b0f3e1b27f609a2e104b39bad077850e210Fariborz Jahanian        if (!Method)
131527569b0f3e1b27f609a2e104b39bad077850e210Fariborz Jahanian          Method = LookupMethodInQualifiedType(Sel, QIdTy, false);
1316f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor      } else if (const ObjCObjectPointerType *OCIType
1317f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor                   = ReceiverType->getAsObjCInterfacePointerType()) {
1318f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor        // We allow sending a message to a pointer to an interface (an object).
1319f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor        ClassDecl = OCIType->getInterfaceDecl();
1320f85e193739c953358c865005855253af4f68a497John McCall
1321f85e193739c953358c865005855253af4f68a497John McCall        if (ClassDecl->isForwardDecl() && getLangOptions().ObjCAutoRefCount) {
1322f85e193739c953358c865005855253af4f68a497John McCall          Diag(Loc, diag::err_arc_receiver_forward_instance)
1323f85e193739c953358c865005855253af4f68a497John McCall            << OCIType->getPointeeType()
1324f85e193739c953358c865005855253af4f68a497John McCall            << (Receiver ? Receiver->getSourceRange() : SourceRange(SuperLoc));
1325f85e193739c953358c865005855253af4f68a497John McCall          return ExprError();
1326f85e193739c953358c865005855253af4f68a497John McCall        }
1327f85e193739c953358c865005855253af4f68a497John McCall
1328f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor        // FIXME: consider using LookupInstanceMethodInGlobalPool, since it will be
1329f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor        // faster than the following method (which can do *many* linear searches).
1330db9d2145f1d85f64dba2c9b92416621ce01090a6Sebastian Redl        // The idea is to add class info to MethodPool.
1331f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor        Method = ClassDecl->lookupInstanceMethod(Sel);
1332f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor
133327569b0f3e1b27f609a2e104b39bad077850e210Fariborz Jahanian        if (!Method)
1334f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor          // Search protocol qualifiers.
133527569b0f3e1b27f609a2e104b39bad077850e210Fariborz Jahanian          Method = LookupMethodInQualifiedType(Sel, OCIType, true);
133627569b0f3e1b27f609a2e104b39bad077850e210Fariborz Jahanian
133789ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian        const ObjCInterfaceDecl *forwardClass = 0;
1338f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor        if (!Method) {
1339f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor          // If we have implementations in scope, check "private" methods.
1340f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor          Method = LookupPrivateInstanceMethod(Sel, ClassDecl);
1341f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor
1342f85e193739c953358c865005855253af4f68a497John McCall          if (!Method && getLangOptions().ObjCAutoRefCount) {
1343f85e193739c953358c865005855253af4f68a497John McCall            Diag(Loc, diag::err_arc_may_not_respond)
1344f85e193739c953358c865005855253af4f68a497John McCall              << OCIType->getPointeeType() << Sel;
1345f85e193739c953358c865005855253af4f68a497John McCall            return ExprError();
1346f85e193739c953358c865005855253af4f68a497John McCall          }
1347f85e193739c953358c865005855253af4f68a497John McCall
1348c737acb8e86564becc5939d681089d1851e6be1aDouglas Gregor          if (!Method && (!Receiver || !isSelfExpr(Receiver))) {
1349f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor            // If we still haven't found a method, look in the global pool. This
1350f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor            // behavior isn't very desirable, however we need it for GCC
1351f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor            // compatibility. FIXME: should we deviate??
1352f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor            if (OCIType->qual_empty()) {
1353f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor              Method = LookupInstanceMethodInGlobalPool(Sel,
13548e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian                                                 SourceRange(LBracLoc, RBracLoc));
135589ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian              if (OCIType->getInterfaceDecl()->isForwardDecl())
135689ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian                forwardClass = OCIType->getInterfaceDecl();
13578e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian              if (Method && !forwardClass)
1358f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor                Diag(Loc, diag::warn_maynot_respond)
1359f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor                  << OCIType->getInterfaceDecl()->getIdentifier() << Sel;
1360f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor            }
1361f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor          }
1362f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor        }
13638e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian        if (Method && DiagnoseUseOfDecl(Method, Loc, forwardClass))
1364f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor          return ExprError();
1365f85e193739c953358c865005855253af4f68a497John McCall      } else if (!getLangOptions().ObjCAutoRefCount &&
1366f85e193739c953358c865005855253af4f68a497John McCall                 !Context.getObjCIdType().isNull() &&
1367f60946222721d9ba3c059563935c17b84703187aDouglas Gregor                 (ReceiverType->isPointerType() ||
1368f60946222721d9ba3c059563935c17b84703187aDouglas Gregor                  ReceiverType->isIntegerType())) {
1369f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor        // Implicitly convert integers and pointers to 'id' but emit a warning.
1370f85e193739c953358c865005855253af4f68a497John McCall        // But not in ARC.
1371f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor        Diag(Loc, diag::warn_bad_receiver_type)
1372f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor          << ReceiverType
1373f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor          << Receiver->getSourceRange();
1374f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor        if (ReceiverType->isPointerType())
1375429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley          Receiver = ImpCastExprToType(Receiver, Context.getObjCIdType(),
13761d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall                            CK_CPointerToObjCPointerCast).take();
1377404cd1669c3ba138a9ae0a619bd689cce5aae271John McCall        else {
1378404cd1669c3ba138a9ae0a619bd689cce5aae271John McCall          // TODO: specialized warning on null receivers?
1379404cd1669c3ba138a9ae0a619bd689cce5aae271John McCall          bool IsNull = Receiver->isNullPointerConstant(Context,
1380404cd1669c3ba138a9ae0a619bd689cce5aae271John McCall                                              Expr::NPC_ValueDependentIsNull);
1381429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley          Receiver = ImpCastExprToType(Receiver, Context.getObjCIdType(),
1382429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley                            IsNull ? CK_NullToPointer : CK_IntegralToPointer).take();
1383404cd1669c3ba138a9ae0a619bd689cce5aae271John McCall        }
1384f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor        ReceiverType = Receiver->getType();
13850bcc9bc6cd46757000245fb7b91302e6ec3478a1John McCall      } else {
1386429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley        ExprResult ReceiverRes;
1387429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley        if (getLangOptions().CPlusPlus)
13880bcc9bc6cd46757000245fb7b91302e6ec3478a1John McCall          ReceiverRes = PerformContextuallyConvertToObjCPointer(Receiver);
1389429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley        if (ReceiverRes.isUsable()) {
1390429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley          Receiver = ReceiverRes.take();
1391429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley          return BuildInstanceMessage(Receiver,
1392429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley                                      ReceiverType,
1393429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley                                      SuperLoc,
1394429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley                                      Sel,
1395429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley                                      Method,
1396429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley                                      LBracLoc,
1397951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis                                      SelectorLocs,
1398429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley                                      RBracLoc,
1399429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley                                      move(ArgsIn));
1400429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley        } else {
1401429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley          // Reject other random receiver types (e.g. structs).
1402429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley          Diag(Loc, diag::err_bad_receiver_type)
1403429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley            << ReceiverType << Receiver->getSourceRange();
1404429bb276991ff2dbc7c5b438828b9b7737cb15ebJohn Wiegley          return ExprError();
14053ba606199be8056ae83596260bd6fd5872942905Fariborz Jahanian        }
1406f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor      }
140704badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor    }
1408fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner  }
14091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14102725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  // Check the message arguments.
14112725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  unsigned NumArgs = ArgsIn.size();
14122725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  Expr **Args = reinterpret_cast<Expr **>(ArgsIn.release());
14132725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  QualType ReturnType;
1414f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  ExprValueKind VK = VK_RValue;
14152600503170c8366af2587408c50e2beedee5d1f1Fariborz Jahanian  bool ClassMessage = (ReceiverType->isObjCClassType() ||
14162600503170c8366af2587408c50e2beedee5d1f1Fariborz Jahanian                       ReceiverType->isObjCQualifiedClassType());
1417926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  if (CheckMessageArgumentTypes(ReceiverType, Args, NumArgs, Sel, Method,
1418926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                ClassMessage, SuperLoc.isValid(),
1419f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall                                LBracLoc, RBracLoc, ReturnType, VK))
14202725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor    return ExprError();
1421da59e09f1fd53350fcd949adbadd8148117f21b2Fariborz Jahanian
1422483dd2f55ee53bc765123ead3428aa4ad2682cf3Douglas Gregor  if (Method && !Method->getResultType()->isVoidType() &&
1423483dd2f55ee53bc765123ead3428aa4ad2682cf3Douglas Gregor      RequireCompleteType(LBracLoc, Method->getResultType(),
1424483dd2f55ee53bc765123ead3428aa4ad2682cf3Douglas Gregor                          diag::err_illegal_message_expr_incomplete_type))
1425483dd2f55ee53bc765123ead3428aa4ad2682cf3Douglas Gregor    return ExprError();
142604badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor
1427951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis  SourceLocation SelLoc = SelectorLocs.front();
1428951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis
1429f85e193739c953358c865005855253af4f68a497John McCall  // In ARC, forbid the user from sending messages to
1430f85e193739c953358c865005855253af4f68a497John McCall  // retain/release/autorelease/dealloc/retainCount explicitly.
1431f85e193739c953358c865005855253af4f68a497John McCall  if (getLangOptions().ObjCAutoRefCount) {
1432f85e193739c953358c865005855253af4f68a497John McCall    ObjCMethodFamily family =
1433f85e193739c953358c865005855253af4f68a497John McCall      (Method ? Method->getMethodFamily() : Sel.getMethodFamily());
1434f85e193739c953358c865005855253af4f68a497John McCall    switch (family) {
1435f85e193739c953358c865005855253af4f68a497John McCall    case OMF_init:
1436f85e193739c953358c865005855253af4f68a497John McCall      if (Method)
1437f85e193739c953358c865005855253af4f68a497John McCall        checkInitMethod(Method, ReceiverType);
1438f85e193739c953358c865005855253af4f68a497John McCall
1439f85e193739c953358c865005855253af4f68a497John McCall    case OMF_None:
1440f85e193739c953358c865005855253af4f68a497John McCall    case OMF_alloc:
1441f85e193739c953358c865005855253af4f68a497John McCall    case OMF_copy:
144280cb6e69d9e85231588ae604e4bc2bc9a07389afNico Weber    case OMF_finalize:
1443f85e193739c953358c865005855253af4f68a497John McCall    case OMF_mutableCopy:
1444f85e193739c953358c865005855253af4f68a497John McCall    case OMF_new:
1445f85e193739c953358c865005855253af4f68a497John McCall    case OMF_self:
1446f85e193739c953358c865005855253af4f68a497John McCall      break;
1447f85e193739c953358c865005855253af4f68a497John McCall
1448f85e193739c953358c865005855253af4f68a497John McCall    case OMF_dealloc:
1449f85e193739c953358c865005855253af4f68a497John McCall    case OMF_retain:
1450f85e193739c953358c865005855253af4f68a497John McCall    case OMF_release:
1451f85e193739c953358c865005855253af4f68a497John McCall    case OMF_autorelease:
1452f85e193739c953358c865005855253af4f68a497John McCall    case OMF_retainCount:
1453f85e193739c953358c865005855253af4f68a497John McCall      Diag(Loc, diag::err_arc_illegal_explicit_message)
1454951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis        << Sel << SelLoc;
1455f85e193739c953358c865005855253af4f68a497John McCall      break;
14569670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian
14579670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian    case OMF_performSelector:
14589670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian      if (Method && NumArgs >= 1) {
14599670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian        if (ObjCSelectorExpr *SelExp = dyn_cast<ObjCSelectorExpr>(Args[0])) {
14609670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian          Selector ArgSel = SelExp->getSelector();
14619670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian          ObjCMethodDecl *SelMethod =
14629670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian            LookupInstanceMethodInGlobalPool(ArgSel,
14639670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian                                             SelExp->getSourceRange());
14649670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian          if (!SelMethod)
14659670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian            SelMethod =
14669670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian              LookupFactoryMethodInGlobalPool(ArgSel,
14679670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian                                              SelExp->getSourceRange());
14689670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian          if (SelMethod) {
14699670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian            ObjCMethodFamily SelFamily = SelMethod->getMethodFamily();
14709670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian            switch (SelFamily) {
14719670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian              case OMF_alloc:
14729670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian              case OMF_copy:
14739670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian              case OMF_mutableCopy:
14749670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian              case OMF_new:
14759670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian              case OMF_self:
14769670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian              case OMF_init:
14779670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian                // Issue error, unless ns_returns_not_retained.
14789670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian                if (!SelMethod->hasAttr<NSReturnsNotRetainedAttr>()) {
14799670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian                  // selector names a +1 method
1480951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis                  Diag(SelLoc,
14819670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian                       diag::err_arc_perform_selector_retains);
14829670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian                  Diag(SelMethod->getLocation(), diag::note_method_declared_at);
14839670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian                }
14849670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian                break;
14859670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian              default:
14869670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian                // +0 call. OK. unless ns_returns_retained.
14879670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian                if (SelMethod->hasAttr<NSReturnsRetainedAttr>()) {
14889670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian                  // selector names a +1 method
1489951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis                  Diag(SelLoc,
14909670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian                       diag::err_arc_perform_selector_retains);
14919670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian                  Diag(SelMethod->getLocation(), diag::note_method_declared_at);
14929670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian                }
14939670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian                break;
14949670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian            }
14959670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian          }
14969670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian        } else {
14979670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian          // error (may leak).
1498951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis          Diag(SelLoc, diag::warn_arc_perform_selector_leaks);
14999670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian          Diag(Args[0]->getExprLoc(), diag::note_used_here);
15009670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian        }
15019670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian      }
15029670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian      break;
1503f85e193739c953358c865005855253af4f68a497John McCall    }
1504f85e193739c953358c865005855253af4f68a497John McCall  }
1505f85e193739c953358c865005855253af4f68a497John McCall
15062725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  // Construct the appropriate ObjCMessageExpr instance.
1507f85e193739c953358c865005855253af4f68a497John McCall  ObjCMessageExpr *Result;
15082725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  if (SuperLoc.isValid())
1509f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall    Result = ObjCMessageExpr::Create(Context, ReturnType, VK, LBracLoc,
15102d6b0e94db30c0e2754d270753c6f75478e451bfDouglas Gregor                                     SuperLoc,  /*IsInstanceSuper=*/true,
1511951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis                                     ReceiverType, Sel, SelectorLocs, Method,
15128d9ed7980405e91a12e33338a78fb99620adf553Argyrios Kyrtzidis                                     makeArrayRef(Args, NumArgs), RBracLoc);
15132d6b0e94db30c0e2754d270753c6f75478e451bfDouglas Gregor  else
1514f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall    Result = ObjCMessageExpr::Create(Context, ReturnType, VK, LBracLoc,
1515951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis                                     Receiver, Sel, SelectorLocs, Method,
15168d9ed7980405e91a12e33338a78fb99620adf553Argyrios Kyrtzidis                                     makeArrayRef(Args, NumArgs), RBracLoc);
1517f85e193739c953358c865005855253af4f68a497John McCall
1518f85e193739c953358c865005855253af4f68a497John McCall  if (getLangOptions().ObjCAutoRefCount) {
1519f85e193739c953358c865005855253af4f68a497John McCall    // In ARC, annotate delegate init calls.
1520f85e193739c953358c865005855253af4f68a497John McCall    if (Result->getMethodFamily() == OMF_init &&
1521c737acb8e86564becc5939d681089d1851e6be1aDouglas Gregor        (SuperLoc.isValid() || isSelfExpr(Receiver))) {
1522f85e193739c953358c865005855253af4f68a497John McCall      // Only consider init calls *directly* in init implementations,
1523f85e193739c953358c865005855253af4f68a497John McCall      // not within blocks.
1524f85e193739c953358c865005855253af4f68a497John McCall      ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(CurContext);
1525f85e193739c953358c865005855253af4f68a497John McCall      if (method && method->getMethodFamily() == OMF_init) {
1526f85e193739c953358c865005855253af4f68a497John McCall        // The implicit assignment to self means we also don't want to
1527f85e193739c953358c865005855253af4f68a497John McCall        // consume the result.
1528f85e193739c953358c865005855253af4f68a497John McCall        Result->setDelegateInitCall(true);
1529f85e193739c953358c865005855253af4f68a497John McCall        return Owned(Result);
1530f85e193739c953358c865005855253af4f68a497John McCall      }
1531f85e193739c953358c865005855253af4f68a497John McCall    }
1532f85e193739c953358c865005855253af4f68a497John McCall
1533f85e193739c953358c865005855253af4f68a497John McCall    // In ARC, check for message sends which are likely to introduce
1534f85e193739c953358c865005855253af4f68a497John McCall    // retain cycles.
1535f85e193739c953358c865005855253af4f68a497John McCall    checkRetainCycles(Result);
1536f85e193739c953358c865005855253af4f68a497John McCall  }
1537f85e193739c953358c865005855253af4f68a497John McCall
15382d6b0e94db30c0e2754d270753c6f75478e451bfDouglas Gregor  return MaybeBindToTemporary(Result);
15392725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor}
15402725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor
15412725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor// ActOnInstanceMessage - used for both unary and keyword messages.
15422725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor// ArgExprs is optional - if it is present, the number of expressions
15432725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor// is obtained from Sel.getNumArgs().
154460d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Sema::ActOnInstanceMessage(Scope *S,
154560d7b3a319d84d688752be3870615ac0f111fb16John McCall                                      Expr *Receiver,
154660d7b3a319d84d688752be3870615ac0f111fb16John McCall                                      Selector Sel,
154760d7b3a319d84d688752be3870615ac0f111fb16John McCall                                      SourceLocation LBracLoc,
1548951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis                                      ArrayRef<SourceLocation> SelectorLocs,
154960d7b3a319d84d688752be3870615ac0f111fb16John McCall                                      SourceLocation RBracLoc,
155060d7b3a319d84d688752be3870615ac0f111fb16John McCall                                      MultiExprArg Args) {
15512725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  if (!Receiver)
15522725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor    return ExprError();
155304badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor
15549ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  return BuildInstanceMessage(Receiver, Receiver->getType(),
1555f49bb082ebf6413b2d3cb956e9c78dbb8a978c58Douglas Gregor                              /*SuperLoc=*/SourceLocation(), Sel, /*Method=*/0,
1556951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis                              LBracLoc, SelectorLocs, RBracLoc, move(Args));
155785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
1558eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
1559f85e193739c953358c865005855253af4f68a497John McCallenum ARCConversionTypeClass {
15602cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  /// int, void, struct A
1561f85e193739c953358c865005855253af4f68a497John McCall  ACTC_none,
15622cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
15632cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  /// id, void (^)()
1564f85e193739c953358c865005855253af4f68a497John McCall  ACTC_retainable,
15652cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
15662cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  /// id*, id***, void (^*)(),
15672cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  ACTC_indirectRetainable,
15682cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
15692cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  /// void* might be a normal C type, or it might a CF type.
15702cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  ACTC_voidPtr,
15712cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
15722cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  /// struct A*
15732cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  ACTC_coreFoundation
1574f85e193739c953358c865005855253af4f68a497John McCall};
15752cf031d33ce6801dc11183a3cb48168f53fe06c4John McCallstatic bool isAnyRetainable(ARCConversionTypeClass ACTC) {
15762cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  return (ACTC == ACTC_retainable ||
15772cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall          ACTC == ACTC_coreFoundation ||
15782cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall          ACTC == ACTC_voidPtr);
15792cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall}
15802cf031d33ce6801dc11183a3cb48168f53fe06c4John McCallstatic bool isAnyCLike(ARCConversionTypeClass ACTC) {
15812cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  return ACTC == ACTC_none ||
15822cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall         ACTC == ACTC_voidPtr ||
15832cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall         ACTC == ACTC_coreFoundation;
15842cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall}
15852cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
1586f85e193739c953358c865005855253af4f68a497John McCallstatic ARCConversionTypeClass classifyTypeForARCConversion(QualType type) {
15872cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  bool isIndirect = false;
1588f85e193739c953358c865005855253af4f68a497John McCall
1589f85e193739c953358c865005855253af4f68a497John McCall  // Ignore an outermost reference type.
15902cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  if (const ReferenceType *ref = type->getAs<ReferenceType>()) {
1591f85e193739c953358c865005855253af4f68a497John McCall    type = ref->getPointeeType();
15922cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    isIndirect = true;
15932cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  }
1594f85e193739c953358c865005855253af4f68a497John McCall
1595f85e193739c953358c865005855253af4f68a497John McCall  // Drill through pointers and arrays recursively.
1596f85e193739c953358c865005855253af4f68a497John McCall  while (true) {
1597f85e193739c953358c865005855253af4f68a497John McCall    if (const PointerType *ptr = type->getAs<PointerType>()) {
1598f85e193739c953358c865005855253af4f68a497John McCall      type = ptr->getPointeeType();
15992cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
16002cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      // The first level of pointer may be the innermost pointer on a CF type.
16012cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      if (!isIndirect) {
16022cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall        if (type->isVoidType()) return ACTC_voidPtr;
16032cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall        if (type->isRecordType()) return ACTC_coreFoundation;
16042cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      }
1605f85e193739c953358c865005855253af4f68a497John McCall    } else if (const ArrayType *array = type->getAsArrayTypeUnsafe()) {
1606f85e193739c953358c865005855253af4f68a497John McCall      type = QualType(array->getElementType()->getBaseElementTypeUnsafe(), 0);
1607f85e193739c953358c865005855253af4f68a497John McCall    } else {
1608f85e193739c953358c865005855253af4f68a497John McCall      break;
1609f85e193739c953358c865005855253af4f68a497John McCall    }
16102cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    isIndirect = true;
1611f85e193739c953358c865005855253af4f68a497John McCall  }
1612f85e193739c953358c865005855253af4f68a497John McCall
16132cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  if (isIndirect) {
16142cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    if (type->isObjCARCBridgableType())
16152cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      return ACTC_indirectRetainable;
16162cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    return ACTC_none;
16172cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  }
16182cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
16192cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  if (type->isObjCARCBridgableType())
16202cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    return ACTC_retainable;
16212cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
16222cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  return ACTC_none;
1623f85e193739c953358c865005855253af4f68a497John McCall}
1624f85e193739c953358c865005855253af4f68a497John McCall
1625f85e193739c953358c865005855253af4f68a497John McCallnamespace {
16262cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  /// A result from the cast checker.
16272cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  enum ACCResult {
16282cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    /// Cannot be casted.
16292cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    ACC_invalid,
16302cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
16312cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    /// Can be safely retained or not retained.
16322cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    ACC_bottom,
16332cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
16342cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    /// Can be casted at +0.
16352cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    ACC_plusZero,
16362cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
16372cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    /// Can be casted at +1.
16382cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    ACC_plusOne
16392cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  };
16402cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  ACCResult merge(ACCResult left, ACCResult right) {
16412cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    if (left == right) return left;
16422cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    if (left == ACC_bottom) return right;
16432cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    if (right == ACC_bottom) return left;
16442cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    return ACC_invalid;
16452cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  }
16462cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
16472cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  /// A checker which white-lists certain expressions whose conversion
16482cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  /// to or from retainable type would otherwise be forbidden in ARC.
16492cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  class ARCCastChecker : public StmtVisitor<ARCCastChecker, ACCResult> {
16502cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    typedef StmtVisitor<ARCCastChecker, ACCResult> super;
16512cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
1652f85e193739c953358c865005855253af4f68a497John McCall    ASTContext &Context;
16532cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    ARCConversionTypeClass SourceClass;
16542cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    ARCConversionTypeClass TargetClass;
16552cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
16562cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    static bool isCFType(QualType type) {
16572cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      // Someday this can use ns_bridged.  For now, it has to do this.
16582cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      return type->isCARCBridgableType();
1659f85e193739c953358c865005855253af4f68a497John McCall    }
16602cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
16612cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  public:
16622cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    ARCCastChecker(ASTContext &Context, ARCConversionTypeClass source,
16632cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall                   ARCConversionTypeClass target)
16642cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      : Context(Context), SourceClass(source), TargetClass(target) {}
16652cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
16662cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    using super::Visit;
16672cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    ACCResult Visit(Expr *e) {
16682cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      return super::Visit(e->IgnoreParens());
1669f85e193739c953358c865005855253af4f68a497John McCall    }
16702cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
16712cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    ACCResult VisitStmt(Stmt *s) {
16722cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      return ACC_invalid;
16732cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    }
16742cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
16752cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    /// Null pointer constants can be casted however you please.
16762cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    ACCResult VisitExpr(Expr *e) {
16772cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      if (e->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull))
16782cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall        return ACC_bottom;
16792cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      return ACC_invalid;
16802cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    }
16812cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
16822cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    /// Objective-C string literals can be safely casted.
16832cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    ACCResult VisitObjCStringLiteral(ObjCStringLiteral *e) {
16842cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      // If we're casting to any retainable type, go ahead.  Global
16852cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      // strings are immune to retains, so this is bottom.
16862cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      if (isAnyRetainable(TargetClass)) return ACC_bottom;
16872cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
16882cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      return ACC_invalid;
1689f85e193739c953358c865005855253af4f68a497John McCall    }
16902cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
16912cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    /// Look through certain implicit and explicit casts.
16922cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    ACCResult VisitCastExpr(CastExpr *e) {
1693f85e193739c953358c865005855253af4f68a497John McCall      switch (e->getCastKind()) {
1694f85e193739c953358c865005855253af4f68a497John McCall        case CK_NullToPointer:
16952cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall          return ACC_bottom;
16962cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
1697f85e193739c953358c865005855253af4f68a497John McCall        case CK_NoOp:
1698f85e193739c953358c865005855253af4f68a497John McCall        case CK_LValueToRValue:
1699f85e193739c953358c865005855253af4f68a497John McCall        case CK_BitCast:
17002cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall        case CK_GetObjCProperty:
17011d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall        case CK_CPointerToObjCPointerCast:
17021d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall        case CK_BlockPointerToObjCPointerCast:
1703f85e193739c953358c865005855253af4f68a497John McCall        case CK_AnyPointerToBlockPointerCast:
1704f85e193739c953358c865005855253af4f68a497John McCall          return Visit(e->getSubExpr());
17052cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
1706f85e193739c953358c865005855253af4f68a497John McCall        default:
17072cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall          return ACC_invalid;
1708f85e193739c953358c865005855253af4f68a497John McCall      }
1709f85e193739c953358c865005855253af4f68a497John McCall    }
17102cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
17112cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    /// Look through unary extension.
17122cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    ACCResult VisitUnaryExtension(UnaryOperator *e) {
1713f85e193739c953358c865005855253af4f68a497John McCall      return Visit(e->getSubExpr());
1714f85e193739c953358c865005855253af4f68a497John McCall    }
17152cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
17162cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    /// Ignore the LHS of a comma operator.
17172cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    ACCResult VisitBinComma(BinaryOperator *e) {
1718f85e193739c953358c865005855253af4f68a497John McCall      return Visit(e->getRHS());
1719f85e193739c953358c865005855253af4f68a497John McCall    }
17202cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
17212cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    /// Conditional operators are okay if both sides are okay.
17222cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    ACCResult VisitConditionalOperator(ConditionalOperator *e) {
17232cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      ACCResult left = Visit(e->getTrueExpr());
17242cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      if (left == ACC_invalid) return ACC_invalid;
17252cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      return merge(left, Visit(e->getFalseExpr()));
1726f85e193739c953358c865005855253af4f68a497John McCall    }
17272cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
17282cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    /// Statement expressions are okay if their result expression is okay.
17292cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    ACCResult VisitStmtExpr(StmtExpr *e) {
1730f85e193739c953358c865005855253af4f68a497John McCall      return Visit(e->getSubStmt()->body_back());
1731f85e193739c953358c865005855253af4f68a497John McCall    }
17322cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
17332cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    /// Some declaration references are okay.
17342cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    ACCResult VisitDeclRefExpr(DeclRefExpr *e) {
17352cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      // References to global constants from system headers are okay.
17362cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      // These are things like 'kCFStringTransformToLatin'.  They are
17372cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      // can also be assumed to be immune to retains.
17382cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      VarDecl *var = dyn_cast<VarDecl>(e->getDecl());
17392cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      if (isAnyRetainable(TargetClass) &&
17402cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall          isAnyRetainable(SourceClass) &&
17412cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall          var &&
17422cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall          var->getStorageClass() == SC_Extern &&
17432cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall          var->getType().isConstQualified() &&
17442cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall          Context.getSourceManager().isInSystemHeader(var->getLocation())) {
17452cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall        return ACC_bottom;
17462cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      }
17472cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
17482cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      // Nothing else.
17492cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      return ACC_invalid;
1750f85e193739c953358c865005855253af4f68a497John McCall    }
1751f85e193739c953358c865005855253af4f68a497John McCall
17522cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    /// Some calls are okay.
17532cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    ACCResult VisitCallExpr(CallExpr *e) {
17542cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      if (FunctionDecl *fn = e->getDirectCallee())
17552cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall        if (ACCResult result = checkCallToFunction(fn))
17562cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall          return result;
17572cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
17582cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      return super::VisitCallExpr(e);
1759c8505ad9182c3ddcfda42bee250b2c32dd1f3219Fariborz Jahanian    }
17602cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
17612cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    ACCResult checkCallToFunction(FunctionDecl *fn) {
17622cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      // Require a CF*Ref return type.
17632cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      if (!isCFType(fn->getResultType()))
17642cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall        return ACC_invalid;
17652cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
17662cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      if (!isAnyRetainable(TargetClass))
17672cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall        return ACC_invalid;
17682cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
17692cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      // Honor an explicit 'not retained' attribute.
17702cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      if (fn->hasAttr<CFReturnsNotRetainedAttr>())
17712cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall        return ACC_plusZero;
17722cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
17732cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      // Honor an explicit 'retained' attribute, except that for
17742cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      // now we're not going to permit implicit handling of +1 results,
17752cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      // because it's a bit frightening.
17762cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      if (fn->hasAttr<CFReturnsRetainedAttr>())
17772cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall        return ACC_invalid; // ACC_plusOne if we start accepting this
17782cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
17792cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      // Recognize this specific builtin function, which is used by CFSTR.
17802cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      unsigned builtinID = fn->getBuiltinID();
17812cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      if (builtinID == Builtin::BI__builtin___CFStringMakeConstantString)
17822cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall        return ACC_bottom;
17832cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
17842cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      // Otherwise, don't do anything implicit with an unaudited function.
17852cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      if (!fn->hasAttr<CFAuditedTransferAttr>())
17862cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall        return ACC_invalid;
17872cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
17882cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      // Otherwise, it's +0 unless it follows the create convention.
17892cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      if (ento::coreFoundation::followsCreateRule(fn))
17902cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall        return ACC_invalid; // ACC_plusOne if we start accepting this
17912cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
17922cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      return ACC_plusZero;
17932cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    }
17942cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
17952cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    ACCResult VisitObjCMessageExpr(ObjCMessageExpr *e) {
17962cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      return checkCallToMethod(e->getMethodDecl());
17972cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    }
17982cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
17992cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    ACCResult VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *e) {
18002cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      ObjCMethodDecl *method;
18012cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      if (e->isExplicitProperty())
18022cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall        method = e->getExplicitProperty()->getGetterMethodDecl();
18032cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      else
18042cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall        method = e->getImplicitPropertyGetter();
18052cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      return checkCallToMethod(method);
18062cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    }
18072cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
18082cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    ACCResult checkCallToMethod(ObjCMethodDecl *method) {
18092cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      if (!method) return ACC_invalid;
18102cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
18112cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      // Check for message sends to functions returning CF types.  We
18122cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      // just obey the Cocoa conventions with these, even though the
18132cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      // return type is CF.
18142cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      if (!isAnyRetainable(TargetClass) || !isCFType(method->getResultType()))
18152cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall        return ACC_invalid;
18162cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
18172cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      // If the method is explicitly marked not-retained, it's +0.
18182cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      if (method->hasAttr<CFReturnsNotRetainedAttr>())
18192cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall        return ACC_plusZero;
18202cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
18212cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      // If the method is explicitly marked as returning retained, or its
18222cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      // selector follows a +1 Cocoa convention, treat it as +1.
18232cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      if (method->hasAttr<CFReturnsRetainedAttr>())
18242cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall        return ACC_plusOne;
18252cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
18262cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      switch (method->getSelector().getMethodFamily()) {
18272cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      case OMF_alloc:
18282cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      case OMF_copy:
18292cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      case OMF_mutableCopy:
18302cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      case OMF_new:
18312cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall        return ACC_plusOne;
18322cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
18332cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      default:
18342cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall        // Otherwise, treat it as +0.
18352cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall        return ACC_plusZero;
1836c8505ad9182c3ddcfda42bee250b2c32dd1f3219Fariborz Jahanian      }
1837af9751747b098d77052cb71f1e648f29cfbadcc1Fariborz Jahanian    }
18382cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  };
18391522a7c35e9872c5767721350fc8050be5b14fd2Fariborz Jahanian}
18401522a7c35e9872c5767721350fc8050be5b14fd2Fariborz Jahanian
18415acb0c98b363400f6ade0ae7250f0102224e806bJohn McCallstatic void
18425acb0c98b363400f6ade0ae7250f0102224e806bJohn McCalldiagnoseObjCARCConversion(Sema &S, SourceRange castRange,
18435acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall                          QualType castType, ARCConversionTypeClass castACTC,
18445acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall                          Expr *castExpr, ARCConversionTypeClass exprACTC,
18455acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall                          Sema::CheckedConversionKind CCK) {
18465acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  SourceLocation loc =
18475acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    (castRange.isValid() ? castRange.getBegin() : castExpr->getExprLoc());
18485acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
18495acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  if (S.makeUnavailableInSystemHeader(loc,
18505acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall                "converts between Objective-C and C pointers in -fobjc-arc"))
18515acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    return;
18525acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
18535acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  QualType castExprType = castExpr->getType();
18545acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
18555acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  unsigned srcKind = 0;
18565acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  switch (exprACTC) {
18575acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  case ACTC_none:
18585acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  case ACTC_coreFoundation:
18595acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  case ACTC_voidPtr:
18605acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    srcKind = (castExprType->isPointerType() ? 1 : 0);
18615acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    break;
18625acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  case ACTC_retainable:
18635acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    srcKind = (castExprType->isBlockPointerType() ? 2 : 3);
18645acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    break;
18655acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  case ACTC_indirectRetainable:
18665acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    srcKind = 4;
18675acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    break;
18685acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  }
18695acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
18705acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  // Check whether this could be fixed with a bridge cast.
18715acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  SourceLocation afterLParen = S.PP.getLocForEndOfToken(castRange.getBegin());
18725acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  SourceLocation noteLoc = afterLParen.isValid() ? afterLParen : loc;
18735acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
18745acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  // Bridge from an ARC type to a CF type.
18755acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  if (castACTC == ACTC_retainable && isAnyRetainable(exprACTC)) {
18765acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    S.Diag(loc, diag::err_arc_cast_requires_bridge)
18775acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      << unsigned(CCK == Sema::CCK_ImplicitConversion) // cast|implicit
18785acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      << 2 // of C pointer type
18795acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      << castExprType
18805acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      << unsigned(castType->isBlockPointerType()) // to ObjC|block type
18815acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      << castType
18825acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      << castRange
18835acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      << castExpr->getSourceRange();
18845acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
18855acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    S.Diag(noteLoc, diag::note_arc_bridge)
18865acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      << (CCK != Sema::CCK_CStyleCast ? FixItHint() :
18875acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall            FixItHint::CreateInsertion(afterLParen, "__bridge "));
18885acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    S.Diag(noteLoc, diag::note_arc_bridge_transfer)
18895acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      << castExprType
18905acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      << (CCK != Sema::CCK_CStyleCast ? FixItHint() :
18915acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall            FixItHint::CreateInsertion(afterLParen, "__bridge_transfer "));
18925acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
18935acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    return;
18945acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  }
18955acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
18965acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  // Bridge from a CF type to an ARC type.
18975acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  if (exprACTC == ACTC_retainable && isAnyRetainable(castACTC)) {
18985acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    S.Diag(loc, diag::err_arc_cast_requires_bridge)
18995acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      << unsigned(CCK == Sema::CCK_ImplicitConversion) // cast|implicit
19005acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      << unsigned(castExprType->isBlockPointerType()) // of ObjC|block type
19015acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      << castExprType
19025acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      << 2 // to C pointer type
19035acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      << castType
19045acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      << castRange
19055acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      << castExpr->getSourceRange();
19065acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
19075acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    S.Diag(noteLoc, diag::note_arc_bridge)
19085acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      << (CCK != Sema::CCK_CStyleCast ? FixItHint() :
19095acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall            FixItHint::CreateInsertion(afterLParen, "__bridge "));
19105acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    S.Diag(noteLoc, diag::note_arc_bridge_retained)
19115acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      << castType
19125acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      << (CCK != Sema::CCK_CStyleCast ? FixItHint() :
19135acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall            FixItHint::CreateInsertion(afterLParen, "__bridge_retained "));
19145acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
19155acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    return;
19165acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  }
19175acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
19185acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  S.Diag(loc, diag::err_arc_mismatched_cast)
19195acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    << (CCK != Sema::CCK_ImplicitConversion)
19205acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    << srcKind << castExprType << castType
19215acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    << castRange << castExpr->getSourceRange();
19225acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall}
19235acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
19245acb0c98b363400f6ade0ae7250f0102224e806bJohn McCallSema::ARCConversionResult
1925f85e193739c953358c865005855253af4f68a497John McCallSema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
1926af9751747b098d77052cb71f1e648f29cfbadcc1Fariborz Jahanian                             Expr *&castExpr, CheckedConversionKind CCK) {
1927f85e193739c953358c865005855253af4f68a497John McCall  QualType castExprType = castExpr->getType();
19282cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
19292cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  // For the purposes of the classification, we assume reference types
19302cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  // will bind to temporaries.
19312cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  QualType effCastType = castType;
19322cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  if (const ReferenceType *ref = castType->getAs<ReferenceType>())
19332cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    effCastType = ref->getPointeeType();
1934f85e193739c953358c865005855253af4f68a497John McCall
1935f85e193739c953358c865005855253af4f68a497John McCall  ARCConversionTypeClass exprACTC = classifyTypeForARCConversion(castExprType);
19362cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  ARCConversionTypeClass castACTC = classifyTypeForARCConversion(effCastType);
19376d09f01af70bbd58ddbccb0a22f5479782b31797Fariborz Jahanian  if (exprACTC == castACTC) {
19386d09f01af70bbd58ddbccb0a22f5479782b31797Fariborz Jahanian    // check for viablity and report error if casting an rvalue to a
19396d09f01af70bbd58ddbccb0a22f5479782b31797Fariborz Jahanian    // life-time qualifier.
1940fc2eff57d7497578e8f08a5ee520ad3886a51186Fariborz Jahanian    if ((castACTC == ACTC_retainable) &&
19416d09f01af70bbd58ddbccb0a22f5479782b31797Fariborz Jahanian        (CCK == CCK_CStyleCast || CCK == CCK_OtherCast) &&
1942fc2eff57d7497578e8f08a5ee520ad3886a51186Fariborz Jahanian        (castType != castExprType)) {
1943fc2eff57d7497578e8f08a5ee520ad3886a51186Fariborz Jahanian      const Type *DT = castType.getTypePtr();
1944fc2eff57d7497578e8f08a5ee520ad3886a51186Fariborz Jahanian      QualType QDT = castType;
1945fc2eff57d7497578e8f08a5ee520ad3886a51186Fariborz Jahanian      // We desugar some types but not others. We ignore those
1946fc2eff57d7497578e8f08a5ee520ad3886a51186Fariborz Jahanian      // that cannot happen in a cast; i.e. auto, and those which
1947fc2eff57d7497578e8f08a5ee520ad3886a51186Fariborz Jahanian      // should not be de-sugared; i.e typedef.
1948fc2eff57d7497578e8f08a5ee520ad3886a51186Fariborz Jahanian      if (const ParenType *PT = dyn_cast<ParenType>(DT))
1949fc2eff57d7497578e8f08a5ee520ad3886a51186Fariborz Jahanian        QDT = PT->desugar();
1950fc2eff57d7497578e8f08a5ee520ad3886a51186Fariborz Jahanian      else if (const TypeOfType *TP = dyn_cast<TypeOfType>(DT))
1951fc2eff57d7497578e8f08a5ee520ad3886a51186Fariborz Jahanian        QDT = TP->desugar();
1952fc2eff57d7497578e8f08a5ee520ad3886a51186Fariborz Jahanian      else if (const AttributedType *AT = dyn_cast<AttributedType>(DT))
1953fc2eff57d7497578e8f08a5ee520ad3886a51186Fariborz Jahanian        QDT = AT->desugar();
1954fc2eff57d7497578e8f08a5ee520ad3886a51186Fariborz Jahanian      if (QDT != castType &&
1955fc2eff57d7497578e8f08a5ee520ad3886a51186Fariborz Jahanian          QDT.getObjCLifetime() !=  Qualifiers::OCL_None) {
1956fc2eff57d7497578e8f08a5ee520ad3886a51186Fariborz Jahanian        SourceLocation loc =
1957fc2eff57d7497578e8f08a5ee520ad3886a51186Fariborz Jahanian          (castRange.isValid() ? castRange.getBegin()
1958fc2eff57d7497578e8f08a5ee520ad3886a51186Fariborz Jahanian                              : castExpr->getExprLoc());
1959fc2eff57d7497578e8f08a5ee520ad3886a51186Fariborz Jahanian        Diag(loc, diag::err_arc_nolifetime_behavior);
1960fc2eff57d7497578e8f08a5ee520ad3886a51186Fariborz Jahanian      }
19616d09f01af70bbd58ddbccb0a22f5479782b31797Fariborz Jahanian    }
19626d09f01af70bbd58ddbccb0a22f5479782b31797Fariborz Jahanian    return ACR_okay;
19636d09f01af70bbd58ddbccb0a22f5479782b31797Fariborz Jahanian  }
19646d09f01af70bbd58ddbccb0a22f5479782b31797Fariborz Jahanian
19655acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  if (isAnyCLike(exprACTC) && isAnyCLike(castACTC)) return ACR_okay;
19662cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
19672cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  // Allow all of these types to be cast to integer types (but not
19682cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  // vice-versa).
19692cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  if (castACTC == ACTC_none && castType->isIntegralType(Context))
19705acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    return ACR_okay;
1971f85e193739c953358c865005855253af4f68a497John McCall
1972f85e193739c953358c865005855253af4f68a497John McCall  // Allow casts between pointers to lifetime types (e.g., __strong id*)
1973f85e193739c953358c865005855253af4f68a497John McCall  // and pointers to void (e.g., cv void *). Casting from void* to lifetime*
1974f85e193739c953358c865005855253af4f68a497John McCall  // must be explicit.
19752cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  if (exprACTC == ACTC_indirectRetainable && castACTC == ACTC_voidPtr)
19765acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    return ACR_okay;
19772cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  if (castACTC == ACTC_indirectRetainable && exprACTC == ACTC_voidPtr &&
19782cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall      CCK != CCK_ImplicitConversion)
19795acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    return ACR_okay;
19802cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
19812cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  switch (ARCCastChecker(Context, exprACTC, castACTC).Visit(castExpr)) {
19822cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  // For invalid casts, fall through.
19832cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  case ACC_invalid:
19842cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    break;
19852cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
19862cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  // Do nothing for both bottom and +0.
19872cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  case ACC_bottom:
19882cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  case ACC_plusZero:
19895acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    return ACR_okay;
19902cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall
19912cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  // If the result is +1, consume it here.
19922cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  case ACC_plusOne:
19932cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    castExpr = ImplicitCastExpr::Create(Context, castExpr->getType(),
19942cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall                                        CK_ARCConsumeObject, castExpr,
19952cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall                                        0, VK_RValue);
19962cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall    ExprNeedsCleanups = true;
19975acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    return ACR_okay;
19982cf031d33ce6801dc11183a3cb48168f53fe06c4John McCall  }
19995acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
20005acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  // If this is a non-implicit cast from id or block type to a
20015acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  // CoreFoundation type, delay complaining in case the cast is used
20025acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  // in an acceptable context.
20035acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  if (exprACTC == ACTC_retainable && isAnyRetainable(castACTC) &&
20045acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      CCK != CCK_ImplicitConversion)
20055acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    return ACR_unbridged;
20065acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
20075acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  diagnoseObjCARCConversion(*this, castRange, castType, castACTC,
20085acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall                            castExpr, exprACTC, CCK);
20095acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  return ACR_okay;
20105acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall}
20115acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
20125acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall/// Given that we saw an expression with the ARCUnbridgedCastTy
20135acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall/// placeholder type, complain bitterly.
20145acb0c98b363400f6ade0ae7250f0102224e806bJohn McCallvoid Sema::diagnoseARCUnbridgedCast(Expr *e) {
20155acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  // We expect the spurious ImplicitCastExpr to already have been stripped.
20165acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  assert(!e->hasPlaceholderType(BuiltinType::ARCUnbridgedCast));
20175acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  CastExpr *realCast = cast<CastExpr>(e->IgnoreParens());
20185acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
20195acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  SourceRange castRange;
20205acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  QualType castType;
20215acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  CheckedConversionKind CCK;
20225acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
20235acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  if (CStyleCastExpr *cast = dyn_cast<CStyleCastExpr>(realCast)) {
20245acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    castRange = SourceRange(cast->getLParenLoc(), cast->getRParenLoc());
20255acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    castType = cast->getTypeAsWritten();
20265acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    CCK = CCK_CStyleCast;
20275acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  } else if (ExplicitCastExpr *cast = dyn_cast<ExplicitCastExpr>(realCast)) {
20285acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    castRange = cast->getTypeInfoAsWritten()->getTypeLoc().getSourceRange();
20295acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    castType = cast->getTypeAsWritten();
20305acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    CCK = CCK_OtherCast;
20315acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  } else {
20325acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    castType = cast->getType();
20335acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    CCK = CCK_ImplicitConversion;
2034f85e193739c953358c865005855253af4f68a497John McCall  }
20355acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
20365acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  ARCConversionTypeClass castACTC =
20375acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    classifyTypeForARCConversion(castType.getNonReferenceType());
20385acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
20395acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  Expr *castExpr = realCast->getSubExpr();
20405acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  assert(classifyTypeForARCConversion(castExpr->getType()) == ACTC_retainable);
20415acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
20425acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  diagnoseObjCARCConversion(*this, castRange, castType, castACTC,
20435acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall                            castExpr, ACTC_retainable, CCK);
20445acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall}
20455acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
20465acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall/// stripARCUnbridgedCast - Given an expression of ARCUnbridgedCast
20475acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall/// type, remove the placeholder cast.
20485acb0c98b363400f6ade0ae7250f0102224e806bJohn McCallExpr *Sema::stripARCUnbridgedCast(Expr *e) {
20495acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  assert(e->hasPlaceholderType(BuiltinType::ARCUnbridgedCast));
20505acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
20515acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  if (ParenExpr *pe = dyn_cast<ParenExpr>(e)) {
20525acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    Expr *sub = stripARCUnbridgedCast(pe->getSubExpr());
20535acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    return new (Context) ParenExpr(pe->getLParen(), pe->getRParen(), sub);
20545acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  } else if (UnaryOperator *uo = dyn_cast<UnaryOperator>(e)) {
20555acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    assert(uo->getOpcode() == UO_Extension);
20565acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    Expr *sub = stripARCUnbridgedCast(uo->getSubExpr());
20575acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    return new (Context) UnaryOperator(sub, UO_Extension, sub->getType(),
20585acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall                                   sub->getValueKind(), sub->getObjectKind(),
20595acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall                                       uo->getOperatorLoc());
20605acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  } else if (GenericSelectionExpr *gse = dyn_cast<GenericSelectionExpr>(e)) {
20615acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    assert(!gse->isResultDependent());
20625acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
20635acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    unsigned n = gse->getNumAssocs();
20645acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    SmallVector<Expr*, 4> subExprs(n);
20655acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    SmallVector<TypeSourceInfo*, 4> subTypes(n);
20665acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    for (unsigned i = 0; i != n; ++i) {
20675acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      subTypes[i] = gse->getAssocTypeSourceInfo(i);
20685acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      Expr *sub = gse->getAssocExpr(i);
20695acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      if (i == gse->getResultIndex())
20705acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall        sub = stripARCUnbridgedCast(sub);
20715acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall      subExprs[i] = sub;
2072f85e193739c953358c865005855253af4f68a497John McCall    }
20735acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall
20745acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    return new (Context) GenericSelectionExpr(Context, gse->getGenericLoc(),
20755acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall                                              gse->getControllingExpr(),
20765acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall                                              subTypes.data(), subExprs.data(),
20775acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall                                              n, gse->getDefaultLoc(),
20785acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall                                              gse->getRParenLoc(),
20795acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall                                       gse->containsUnexpandedParameterPack(),
20805acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall                                              gse->getResultIndex());
20815acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall  } else {
20825acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    assert(isa<ImplicitCastExpr>(e) && "bad form of unbridged cast!");
20835acb0c98b363400f6ade0ae7250f0102224e806bJohn McCall    return cast<ImplicitCastExpr>(e)->getSubExpr();
2084f85e193739c953358c865005855253af4f68a497John McCall  }
2085f85e193739c953358c865005855253af4f68a497John McCall}
2086f85e193739c953358c865005855253af4f68a497John McCall
20877a084ec568f8336ec6f10011d0118a6b19e253cbFariborz Jahanianbool Sema::CheckObjCARCUnavailableWeakConversion(QualType castType,
20887a084ec568f8336ec6f10011d0118a6b19e253cbFariborz Jahanian                                                 QualType exprType) {
20897a084ec568f8336ec6f10011d0118a6b19e253cbFariborz Jahanian  QualType canCastType =
20907a084ec568f8336ec6f10011d0118a6b19e253cbFariborz Jahanian    Context.getCanonicalType(castType).getUnqualifiedType();
20917a084ec568f8336ec6f10011d0118a6b19e253cbFariborz Jahanian  QualType canExprType =
20927a084ec568f8336ec6f10011d0118a6b19e253cbFariborz Jahanian    Context.getCanonicalType(exprType).getUnqualifiedType();
20937a084ec568f8336ec6f10011d0118a6b19e253cbFariborz Jahanian  if (isa<ObjCObjectPointerType>(canCastType) &&
20947a084ec568f8336ec6f10011d0118a6b19e253cbFariborz Jahanian      castType.getObjCLifetime() == Qualifiers::OCL_Weak &&
20957a084ec568f8336ec6f10011d0118a6b19e253cbFariborz Jahanian      canExprType->isObjCObjectPointerType()) {
20967a084ec568f8336ec6f10011d0118a6b19e253cbFariborz Jahanian    if (const ObjCObjectPointerType *ObjT =
20977a084ec568f8336ec6f10011d0118a6b19e253cbFariborz Jahanian        canExprType->getAs<ObjCObjectPointerType>())
20987a084ec568f8336ec6f10011d0118a6b19e253cbFariborz Jahanian      if (ObjT->getInterfaceDecl()->isArcWeakrefUnavailable())
20997a084ec568f8336ec6f10011d0118a6b19e253cbFariborz Jahanian        return false;
21007a084ec568f8336ec6f10011d0118a6b19e253cbFariborz Jahanian  }
21017a084ec568f8336ec6f10011d0118a6b19e253cbFariborz Jahanian  return true;
21027a084ec568f8336ec6f10011d0118a6b19e253cbFariborz Jahanian}
21037a084ec568f8336ec6f10011d0118a6b19e253cbFariborz Jahanian
21047e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall/// Look for an ObjCReclaimReturnedObject cast and destroy it.
21057e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCallstatic Expr *maybeUndoReclaimObject(Expr *e) {
21067e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall  // For now, we just undo operands that are *immediately* reclaim
21077e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall  // expressions, which prevents the vast majority of potential
21087e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall  // problems here.  To catch them all, we'd need to rebuild arbitrary
21097e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall  // value-propagating subexpressions --- we can't reliably rebuild
21107e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall  // in-place because of expression sharing.
21117e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall  if (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e))
211233e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall    if (ice->getCastKind() == CK_ARCReclaimReturnedObject)
21137e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall      return ice->getSubExpr();
21147e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall
21157e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall  return e;
21167e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall}
21177e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall
2118f85e193739c953358c865005855253af4f68a497John McCallExprResult Sema::BuildObjCBridgedCast(SourceLocation LParenLoc,
2119f85e193739c953358c865005855253af4f68a497John McCall                                      ObjCBridgeCastKind Kind,
2120f85e193739c953358c865005855253af4f68a497John McCall                                      SourceLocation BridgeKeywordLoc,
2121f85e193739c953358c865005855253af4f68a497John McCall                                      TypeSourceInfo *TSInfo,
2122f85e193739c953358c865005855253af4f68a497John McCall                                      Expr *SubExpr) {
21234906cf97fb6b7aebf5b1b8b99762f0f8fe1f15eaJohn McCall  ExprResult SubResult = UsualUnaryConversions(SubExpr);
21244906cf97fb6b7aebf5b1b8b99762f0f8fe1f15eaJohn McCall  if (SubResult.isInvalid()) return ExprError();
21254906cf97fb6b7aebf5b1b8b99762f0f8fe1f15eaJohn McCall  SubExpr = SubResult.take();
21264906cf97fb6b7aebf5b1b8b99762f0f8fe1f15eaJohn McCall
2127f85e193739c953358c865005855253af4f68a497John McCall  QualType T = TSInfo->getType();
2128f85e193739c953358c865005855253af4f68a497John McCall  QualType FromType = SubExpr->getType();
2129f85e193739c953358c865005855253af4f68a497John McCall
21301d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall  CastKind CK;
21311d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall
2132f85e193739c953358c865005855253af4f68a497John McCall  bool MustConsume = false;
2133f85e193739c953358c865005855253af4f68a497John McCall  if (T->isDependentType() || SubExpr->isTypeDependent()) {
2134f85e193739c953358c865005855253af4f68a497John McCall    // Okay: we'll build a dependent expression type.
21351d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall    CK = CK_Dependent;
2136f85e193739c953358c865005855253af4f68a497John McCall  } else if (T->isObjCARCBridgableType() && FromType->isCARCBridgableType()) {
2137f85e193739c953358c865005855253af4f68a497John McCall    // Casting CF -> id
21381d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall    CK = (T->isBlockPointerType() ? CK_AnyPointerToBlockPointerCast
21391d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall                                  : CK_CPointerToObjCPointerCast);
2140f85e193739c953358c865005855253af4f68a497John McCall    switch (Kind) {
2141f85e193739c953358c865005855253af4f68a497John McCall    case OBC_Bridge:
2142f85e193739c953358c865005855253af4f68a497John McCall      break;
2143f85e193739c953358c865005855253af4f68a497John McCall
2144f85e193739c953358c865005855253af4f68a497John McCall    case OBC_BridgeRetained:
2145f85e193739c953358c865005855253af4f68a497John McCall      Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)
2146f85e193739c953358c865005855253af4f68a497John McCall        << 2
2147f85e193739c953358c865005855253af4f68a497John McCall        << FromType
2148f85e193739c953358c865005855253af4f68a497John McCall        << (T->isBlockPointerType()? 1 : 0)
2149f85e193739c953358c865005855253af4f68a497John McCall        << T
2150f85e193739c953358c865005855253af4f68a497John McCall        << SubExpr->getSourceRange()
2151f85e193739c953358c865005855253af4f68a497John McCall        << Kind;
2152f85e193739c953358c865005855253af4f68a497John McCall      Diag(BridgeKeywordLoc, diag::note_arc_bridge)
2153f85e193739c953358c865005855253af4f68a497John McCall        << FixItHint::CreateReplacement(BridgeKeywordLoc, "__bridge");
2154f85e193739c953358c865005855253af4f68a497John McCall      Diag(BridgeKeywordLoc, diag::note_arc_bridge_transfer)
2155f85e193739c953358c865005855253af4f68a497John McCall        << FromType
2156f85e193739c953358c865005855253af4f68a497John McCall        << FixItHint::CreateReplacement(BridgeKeywordLoc,
2157f85e193739c953358c865005855253af4f68a497John McCall                                        "__bridge_transfer ");
2158f85e193739c953358c865005855253af4f68a497John McCall
2159f85e193739c953358c865005855253af4f68a497John McCall      Kind = OBC_Bridge;
2160f85e193739c953358c865005855253af4f68a497John McCall      break;
2161f85e193739c953358c865005855253af4f68a497John McCall
2162f85e193739c953358c865005855253af4f68a497John McCall    case OBC_BridgeTransfer:
2163f85e193739c953358c865005855253af4f68a497John McCall      // We must consume the Objective-C object produced by the cast.
2164f85e193739c953358c865005855253af4f68a497John McCall      MustConsume = true;
2165f85e193739c953358c865005855253af4f68a497John McCall      break;
2166f85e193739c953358c865005855253af4f68a497John McCall    }
2167f85e193739c953358c865005855253af4f68a497John McCall  } else if (T->isCARCBridgableType() && FromType->isObjCARCBridgableType()) {
2168f85e193739c953358c865005855253af4f68a497John McCall    // Okay: id -> CF
21691d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall    CK = CK_BitCast;
2170f85e193739c953358c865005855253af4f68a497John McCall    switch (Kind) {
2171f85e193739c953358c865005855253af4f68a497John McCall    case OBC_Bridge:
21727e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall      // Reclaiming a value that's going to be __bridge-casted to CF
21737e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall      // is very dangerous, so we don't do it.
21747e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall      SubExpr = maybeUndoReclaimObject(SubExpr);
2175f85e193739c953358c865005855253af4f68a497John McCall      break;
2176f85e193739c953358c865005855253af4f68a497John McCall
2177f85e193739c953358c865005855253af4f68a497John McCall    case OBC_BridgeRetained:
2178f85e193739c953358c865005855253af4f68a497John McCall      // Produce the object before casting it.
2179f85e193739c953358c865005855253af4f68a497John McCall      SubExpr = ImplicitCastExpr::Create(Context, FromType,
218033e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall                                         CK_ARCProduceObject,
2181f85e193739c953358c865005855253af4f68a497John McCall                                         SubExpr, 0, VK_RValue);
2182f85e193739c953358c865005855253af4f68a497John McCall      break;
2183f85e193739c953358c865005855253af4f68a497John McCall
2184f85e193739c953358c865005855253af4f68a497John McCall    case OBC_BridgeTransfer:
2185f85e193739c953358c865005855253af4f68a497John McCall      Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)
2186f85e193739c953358c865005855253af4f68a497John McCall        << (FromType->isBlockPointerType()? 1 : 0)
2187f85e193739c953358c865005855253af4f68a497John McCall        << FromType
2188f85e193739c953358c865005855253af4f68a497John McCall        << 2
2189f85e193739c953358c865005855253af4f68a497John McCall        << T
2190f85e193739c953358c865005855253af4f68a497John McCall        << SubExpr->getSourceRange()
2191f85e193739c953358c865005855253af4f68a497John McCall        << Kind;
2192f85e193739c953358c865005855253af4f68a497John McCall
2193f85e193739c953358c865005855253af4f68a497John McCall      Diag(BridgeKeywordLoc, diag::note_arc_bridge)
2194f85e193739c953358c865005855253af4f68a497John McCall        << FixItHint::CreateReplacement(BridgeKeywordLoc, "__bridge ");
2195f85e193739c953358c865005855253af4f68a497John McCall      Diag(BridgeKeywordLoc, diag::note_arc_bridge_retained)
2196f85e193739c953358c865005855253af4f68a497John McCall        << T
2197f85e193739c953358c865005855253af4f68a497John McCall        << FixItHint::CreateReplacement(BridgeKeywordLoc, "__bridge_retained ");
2198f85e193739c953358c865005855253af4f68a497John McCall
2199f85e193739c953358c865005855253af4f68a497John McCall      Kind = OBC_Bridge;
2200f85e193739c953358c865005855253af4f68a497John McCall      break;
2201f85e193739c953358c865005855253af4f68a497John McCall    }
2202f85e193739c953358c865005855253af4f68a497John McCall  } else {
2203f85e193739c953358c865005855253af4f68a497John McCall    Diag(LParenLoc, diag::err_arc_bridge_cast_incompatible)
2204f85e193739c953358c865005855253af4f68a497John McCall      << FromType << T << Kind
2205f85e193739c953358c865005855253af4f68a497John McCall      << SubExpr->getSourceRange()
2206f85e193739c953358c865005855253af4f68a497John McCall      << TSInfo->getTypeLoc().getSourceRange();
2207f85e193739c953358c865005855253af4f68a497John McCall    return ExprError();
2208f85e193739c953358c865005855253af4f68a497John McCall  }
2209f85e193739c953358c865005855253af4f68a497John McCall
22101d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall  Expr *Result = new (Context) ObjCBridgedCastExpr(LParenLoc, Kind, CK,
2211f85e193739c953358c865005855253af4f68a497John McCall                                                   BridgeKeywordLoc,
2212f85e193739c953358c865005855253af4f68a497John McCall                                                   TSInfo, SubExpr);
2213f85e193739c953358c865005855253af4f68a497John McCall
2214f85e193739c953358c865005855253af4f68a497John McCall  if (MustConsume) {
2215f85e193739c953358c865005855253af4f68a497John McCall    ExprNeedsCleanups = true;
221633e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall    Result = ImplicitCastExpr::Create(Context, T, CK_ARCConsumeObject, Result,
2217f85e193739c953358c865005855253af4f68a497John McCall                                      0, VK_RValue);
2218f85e193739c953358c865005855253af4f68a497John McCall  }
2219f85e193739c953358c865005855253af4f68a497John McCall
2220f85e193739c953358c865005855253af4f68a497John McCall  return Result;
2221f85e193739c953358c865005855253af4f68a497John McCall}
2222f85e193739c953358c865005855253af4f68a497John McCall
2223f85e193739c953358c865005855253af4f68a497John McCallExprResult Sema::ActOnObjCBridgedCast(Scope *S,
2224f85e193739c953358c865005855253af4f68a497John McCall                                      SourceLocation LParenLoc,
2225f85e193739c953358c865005855253af4f68a497John McCall                                      ObjCBridgeCastKind Kind,
2226f85e193739c953358c865005855253af4f68a497John McCall                                      SourceLocation BridgeKeywordLoc,
2227f85e193739c953358c865005855253af4f68a497John McCall                                      ParsedType Type,
2228f85e193739c953358c865005855253af4f68a497John McCall                                      SourceLocation RParenLoc,
2229f85e193739c953358c865005855253af4f68a497John McCall                                      Expr *SubExpr) {
2230f85e193739c953358c865005855253af4f68a497John McCall  TypeSourceInfo *TSInfo = 0;
2231f85e193739c953358c865005855253af4f68a497John McCall  QualType T = GetTypeFromParser(Type, &TSInfo);
2232f85e193739c953358c865005855253af4f68a497John McCall  if (!TSInfo)
2233f85e193739c953358c865005855253af4f68a497John McCall    TSInfo = Context.getTrivialTypeSourceInfo(T, LParenLoc);
2234f85e193739c953358c865005855253af4f68a497John McCall  return BuildObjCBridgedCast(LParenLoc, Kind, BridgeKeywordLoc, TSInfo,
2235f85e193739c953358c865005855253af4f68a497John McCall                              SubExpr);
2236f85e193739c953358c865005855253af4f68a497John McCall}
2237