ParseObjc.cpp revision 419563768ef4929a622d7c2b066856e82901bb91
1a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek//===--- ParseObjC.cpp - Objective C Parsing ------------------------------===//
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//  This file implements the Objective-C portions of the Parser interface.
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1419510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Parse/Parser.h"
150fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor#include "RAIIObjectsForParser.h"
1655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Parse/ParseDiagnostic.h"
1719510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h"
18f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall#include "clang/Sema/PrettyDeclStackTrace.h"
1919510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/Scope.h"
205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/ADT/SmallVector.h"
2108602359845e668194d111b794b8965358babfe6Fariborz Jahanian#include "llvm/ADT/StringExtras.h"
225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang;
235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
25891dca671a80c865c6def7259f170ba785e4faaaChris Lattner/// ParseObjCAtDirectives - Handle parts of the external-declaration production:
265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///       external-declaration: [C99 6.9]
275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// [OBJC]  objc-class-definition
2891fa0b7759b575045142abd6ee48c076297ad77bSteve Naroff/// [OBJC]  objc-class-declaration
2991fa0b7759b575045142abd6ee48c076297ad77bSteve Naroff/// [OBJC]  objc-alias-declaration
3091fa0b7759b575045142abd6ee48c076297ad77bSteve Naroff/// [OBJC]  objc-protocol-definition
3191fa0b7759b575045142abd6ee48c076297ad77bSteve Naroff/// [OBJC]  objc-method-definition
3291fa0b7759b575045142abd6ee48c076297ad77bSteve Naroff/// [OBJC]  '@' 'end'
3395ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz JahanianParser::DeclGroupPtrTy Parser::ParseObjCAtDirectives() {
345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation AtLoc = ConsumeToken(); // the "@"
351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
36c464ae8444edb6d07ea49b7a0eae1674c0fa1bb8Douglas Gregor  if (Tok.is(tok::code_completion)) {
37a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian    Actions.CodeCompleteObjCAtDirective(getCurScope());
387d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
397d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return DeclGroupPtrTy();
40c464ae8444edb6d07ea49b7a0eae1674c0fa1bb8Douglas Gregor  }
4195ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian
4295ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian  Decl *SingleDecl = 0;
43861cf3effdc0fbc97d401539bc3050da76b2476fSteve Naroff  switch (Tok.getObjCKeywordID()) {
445ffb14b7e88e587cd2f78dcc3a966a64108920f0Chris Lattner  case tok::objc_class:
455ffb14b7e88e587cd2f78dcc3a966a64108920f0Chris Lattner    return ParseObjCAtClassDeclaration(AtLoc);
467f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  case tok::objc_interface: {
470b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall    ParsedAttributes attrs(AttrFactory);
4895ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian    SingleDecl = ParseObjCAtInterfaceDeclaration(AtLoc, attrs);
4995ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian    break;
507f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  }
517f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  case tok::objc_protocol: {
520b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall    ParsedAttributes attrs(AttrFactory);
53bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas Gregor    return ParseObjCAtProtocolDeclaration(AtLoc, attrs);
547f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  }
555ffb14b7e88e587cd2f78dcc3a966a64108920f0Chris Lattner  case tok::objc_implementation:
56849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis    return ParseObjCAtImplementationDeclaration(AtLoc);
575ffb14b7e88e587cd2f78dcc3a966a64108920f0Chris Lattner  case tok::objc_end:
58140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian    return ParseObjCAtEndDeclaration(AtLoc);
595ffb14b7e88e587cd2f78dcc3a966a64108920f0Chris Lattner  case tok::objc_compatibility_alias:
6095ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian    SingleDecl = ParseObjCAtAliasDeclaration(AtLoc);
6195ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian    break;
625ffb14b7e88e587cd2f78dcc3a966a64108920f0Chris Lattner  case tok::objc_synthesize:
6395ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian    SingleDecl = ParseObjCPropertySynthesize(AtLoc);
6495ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian    break;
655ffb14b7e88e587cd2f78dcc3a966a64108920f0Chris Lattner  case tok::objc_dynamic:
6695ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian    SingleDecl = ParseObjCPropertyDynamic(AtLoc);
6795ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian    break;
681b257afbae854c6817f26b7d61c4fed8ff7aebadDouglas Gregor  case tok::objc_import:
694e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (getLangOpts().Modules)
7094ad28b31433058445a27db722f60402ee820beaDouglas Gregor      return ParseModuleImport(AtLoc);
7194ad28b31433058445a27db722f60402ee820beaDouglas Gregor
7294ad28b31433058445a27db722f60402ee820beaDouglas Gregor    // Fall through
7394ad28b31433058445a27db722f60402ee820beaDouglas Gregor
745ffb14b7e88e587cd2f78dcc3a966a64108920f0Chris Lattner  default:
755ffb14b7e88e587cd2f78dcc3a966a64108920f0Chris Lattner    Diag(AtLoc, diag::err_unexpected_at);
765ffb14b7e88e587cd2f78dcc3a966a64108920f0Chris Lattner    SkipUntil(tok::semi);
7795ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian    SingleDecl = 0;
7895ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian    break;
795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
8095ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian  return Actions.ConvertDeclToDeclGroup(SingleDecl);
815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// objc-class-declaration:
855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///    '@' 'class' identifier-list ';'
861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
8795ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz JahanianParser::DeclGroupPtrTy
8895ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz JahanianParser::ParseObjCAtClassDeclaration(SourceLocation atLoc) {
895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ConsumeToken(); // the identifier "class"
905f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<IdentifierInfo *, 8> ClassNames;
915f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<SourceLocation, 8> ClassLocs;
92c09cba67d0ad01e53e0fed07322e95dd281bcfd9Ted Kremenek
931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  while (1) {
95df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner    if (Tok.isNot(tok::identifier)) {
965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Diag(Tok, diag::err_expected_ident);
975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      SkipUntil(tok::semi);
9895ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian      return Actions.ConvertDeclToDeclGroup(0);
995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
1005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ClassNames.push_back(Tok.getIdentifierInfo());
101c09cba67d0ad01e53e0fed07322e95dd281bcfd9Ted Kremenek    ClassLocs.push_back(Tok.getLocation());
1025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ConsumeToken();
1031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
104df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner    if (Tok.isNot(tok::comma))
1055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      break;
1061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ConsumeToken();
1085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Consume the ';'.
1115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@class"))
11295ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian    return Actions.ConvertDeclToDeclGroup(0);
1131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
114c09cba67d0ad01e53e0fed07322e95dd281bcfd9Ted Kremenek  return Actions.ActOnForwardClassDeclaration(atLoc, ClassNames.data(),
115c09cba67d0ad01e53e0fed07322e95dd281bcfd9Ted Kremenek                                              ClassLocs.data(),
116c09cba67d0ad01e53e0fed07322e95dd281bcfd9Ted Kremenek                                              ClassNames.size());
1175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
119d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggenvoid Parser::CheckNestedObjCContexts(SourceLocation AtLoc)
120d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen{
121d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen  Sema::ObjCContainerKind ock = Actions.getObjCContainerKind();
122d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen  if (ock == Sema::OCK_None)
123d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen    return;
124d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen
125849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis  Decl *Decl = Actions.getObjCDeclContext();
126849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis  if (CurParsedObjCImpl) {
127849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis    CurParsedObjCImpl->finish(AtLoc);
128849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis  } else {
129849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis    Actions.ActOnAtEnd(getCurScope(), AtLoc);
130849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis  }
131d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen  Diag(AtLoc, diag::err_objc_missing_end)
132d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen      << FixItHint::CreateInsertion(AtLoc, "@end\n");
133d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen  if (Decl)
134d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen    Diag(Decl->getLocStart(), diag::note_objc_container_start)
135d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen        << (int) ock;
136d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen}
137d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen
138dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///
139dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///   objc-interface:
140dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     objc-class-interface-attributes[opt] objc-class-interface
141dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     objc-category-interface
142dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///
143dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///   objc-class-interface:
1441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///     '@' 'interface' identifier objc-superclass[opt]
145dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///       objc-protocol-refs[opt]
1461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///       objc-class-instance-variables[opt]
147dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///       objc-interface-decl-list
148dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     @end
149dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///
150dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///   objc-category-interface:
1511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///     '@' 'interface' identifier '(' identifier[opt] ')'
152dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///       objc-protocol-refs[opt]
153dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///       objc-interface-decl-list
154dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     @end
155dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///
156dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///   objc-superclass:
157dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     ':' identifier
158dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///
159dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///   objc-class-interface-attributes:
160dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     __attribute__((visibility("default")))
161dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     __attribute__((visibility("hidden")))
162dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     __attribute__((deprecated))
163dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     __attribute__((unavailable))
164dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     __attribute__((objc_exception)) - used by NSException on 64-bit
165b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard///     __attribute__((objc_root_class))
166dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///
167d64251fd56577dd5c78903454632361e094c6dc1Erik VerbruggenDecl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
1687f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                              ParsedAttributes &attrs) {
169861cf3effdc0fbc97d401539bc3050da76b2476fSteve Naroff  assert(Tok.isObjCAtKeyword(tok::objc_interface) &&
170dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff         "ParseObjCAtInterfaceDeclaration(): Expected @interface");
171d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen  CheckNestedObjCContexts(AtLoc);
172dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff  ConsumeToken(); // the "interface" identifier
1731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1743b49aca913dc0c1838321b9bb2dc9a4cb4681922Douglas Gregor  // Code completion after '@interface'.
1753b49aca913dc0c1838321b9bb2dc9a4cb4681922Douglas Gregor  if (Tok.is(tok::code_completion)) {
17623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteObjCInterfaceDecl(getCurScope());
1777d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
1787d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return 0;
1793b49aca913dc0c1838321b9bb2dc9a4cb4681922Douglas Gregor  }
1803b49aca913dc0c1838321b9bb2dc9a4cb4681922Douglas Gregor
181df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner  if (Tok.isNot(tok::identifier)) {
182dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff    Diag(Tok, diag::err_expected_ident); // missing class or category name.
183d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
184dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff  }
18563e963cdffca9530f920dbab58b9b4eecb2a582cFariborz Jahanian
186dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff  // We have a class or category name - consume it.
1877ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff  IdentifierInfo *nameId = Tok.getIdentifierInfo();
188dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff  SourceLocation nameLoc = ConsumeToken();
1895512ba538f3f6b0576623f680fa7d930fa085ccdFariborz Jahanian  if (Tok.is(tok::l_paren) &&
1905512ba538f3f6b0576623f680fa7d930fa085ccdFariborz Jahanian      !isKnownToBeTypeSpecifier(GetLookAheadToken(1))) { // we have a category.
1914a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor
1924a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    BalancedDelimiterTracker T(*this, tok::l_paren);
1934a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    T.consumeOpen();
1944a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor
1954a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    SourceLocation categoryLoc;
196dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff    IdentifierInfo *categoryId = 0;
19733ced0b8550f3e7169f326944731ee02e9338659Douglas Gregor    if (Tok.is(tok::code_completion)) {
19823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      Actions.CodeCompleteObjCInterfaceCategory(getCurScope(), nameId, nameLoc);
1997d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      cutOffParsing();
2007d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      return 0;
20133ced0b8550f3e7169f326944731ee02e9338659Douglas Gregor    }
20233ced0b8550f3e7169f326944731ee02e9338659Douglas Gregor
203527fe23f8cbc6a4da1737a547a2517bc92fa88c8Steve Naroff    // For ObjC2, the category name is optional (not an error).
204df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner    if (Tok.is(tok::identifier)) {
205dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff      categoryId = Tok.getIdentifierInfo();
206dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff      categoryLoc = ConsumeToken();
20705511fa6349ef0820a778f8c840d0b64e05e9aeeFariborz Jahanian    }
2084e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    else if (!getLangOpts().ObjC2) {
209527fe23f8cbc6a4da1737a547a2517bc92fa88c8Steve Naroff      Diag(Tok, diag::err_expected_ident); // missing category name.
210d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall      return 0;
211dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff    }
2124a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor
2134a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    T.consumeClose();
2144a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    if (T.getCloseLocation().isInvalid())
215d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall      return 0;
21613d05ac08974ccb41f7da7595d769c158f58fbd6Douglas Gregor
21713d05ac08974ccb41f7da7595d769c158f58fbd6Douglas Gregor    if (!attrs.empty()) { // categories don't support attributes.
21813d05ac08974ccb41f7da7595d769c158f58fbd6Douglas Gregor      Diag(nameLoc, diag::err_objc_no_attributes_on_category);
21913d05ac08974ccb41f7da7595d769c158f58fbd6Douglas Gregor      attrs.clear();
220dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff    }
22113d05ac08974ccb41f7da7595d769c158f58fbd6Douglas Gregor
2225512ba538f3f6b0576623f680fa7d930fa085ccdFariborz Jahanian    // Next, we need to check for any protocol references.
2235512ba538f3f6b0576623f680fa7d930fa085ccdFariborz Jahanian    SourceLocation LAngleLoc, EndProtoLoc;
2245f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    SmallVector<Decl *, 8> ProtocolRefs;
2255f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    SmallVector<SourceLocation, 8> ProtocolLocs;
2265512ba538f3f6b0576623f680fa7d930fa085ccdFariborz Jahanian    if (Tok.is(tok::less) &&
2275512ba538f3f6b0576623f680fa7d930fa085ccdFariborz Jahanian        ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true,
22871b0addffbdeed29cc062c962e236c34107755d6Argyrios Kyrtzidis                                    LAngleLoc, EndProtoLoc))
229d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall      return 0;
23005511fa6349ef0820a778f8c840d0b64e05e9aeeFariborz Jahanian
231d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    Decl *CategoryType =
232d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen    Actions.ActOnStartCategoryInterface(AtLoc,
2335512ba538f3f6b0576623f680fa7d930fa085ccdFariborz Jahanian                                        nameId, nameLoc,
2345512ba538f3f6b0576623f680fa7d930fa085ccdFariborz Jahanian                                        categoryId, categoryLoc,
2355512ba538f3f6b0576623f680fa7d930fa085ccdFariborz Jahanian                                        ProtocolRefs.data(),
2365512ba538f3f6b0576623f680fa7d930fa085ccdFariborz Jahanian                                        ProtocolRefs.size(),
2375512ba538f3f6b0576623f680fa7d930fa085ccdFariborz Jahanian                                        ProtocolLocs.data(),
2385512ba538f3f6b0576623f680fa7d930fa085ccdFariborz Jahanian                                        EndProtoLoc);
239e6f07f538fd0eddd6c087fcc01d4e4ff19129c71Fariborz Jahanian
240a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian    if (Tok.is(tok::l_brace))
241d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen      ParseObjCClassInstanceVariables(CategoryType, tok::objc_private, AtLoc);
242a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian
2432f64cfe19e8bf6b6ba1660e38da8c421440457feFariborz Jahanian    ParseObjCInterfaceDeclList(tok::objc_not_keyword, CategoryType);
2445512ba538f3f6b0576623f680fa7d930fa085ccdFariborz Jahanian    return CategoryType;
245dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff  }
246dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff  // Parse a class interface.
247dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff  IdentifierInfo *superClassId = 0;
248dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff  SourceLocation superClassLoc;
2497ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff
250df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner  if (Tok.is(tok::colon)) { // a super class is specified.
251dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff    ConsumeToken();
2523b49aca913dc0c1838321b9bb2dc9a4cb4681922Douglas Gregor
2533b49aca913dc0c1838321b9bb2dc9a4cb4681922Douglas Gregor    // Code completion of superclass names.
2543b49aca913dc0c1838321b9bb2dc9a4cb4681922Douglas Gregor    if (Tok.is(tok::code_completion)) {
25523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      Actions.CodeCompleteObjCSuperclass(getCurScope(), nameId, nameLoc);
2567d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      cutOffParsing();
2577d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      return 0;
2583b49aca913dc0c1838321b9bb2dc9a4cb4681922Douglas Gregor    }
2593b49aca913dc0c1838321b9bb2dc9a4cb4681922Douglas Gregor
260df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner    if (Tok.isNot(tok::identifier)) {
261dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff      Diag(Tok, diag::err_expected_ident); // missing super class name.
262d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall      return 0;
263dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff    }
264dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff    superClassId = Tok.getIdentifierInfo();
265dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff    superClassLoc = ConsumeToken();
266dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff  }
267dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff  // Next, we need to check for any protocol references.
2685f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<Decl *, 8> ProtocolRefs;
2695f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<SourceLocation, 8> ProtocolLocs;
27071b0addffbdeed29cc062c962e236c34107755d6Argyrios Kyrtzidis  SourceLocation LAngleLoc, EndProtoLoc;
27106036d3709955a53297b4cbe14e20db88f321470Chris Lattner  if (Tok.is(tok::less) &&
27271b0addffbdeed29cc062c962e236c34107755d6Argyrios Kyrtzidis      ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true,
27371b0addffbdeed29cc062c962e236c34107755d6Argyrios Kyrtzidis                                  LAngleLoc, EndProtoLoc))
274d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
2751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
276d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  Decl *ClsType =
277d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen    Actions.ActOnStartClassInterface(AtLoc, nameId, nameLoc,
27806036d3709955a53297b4cbe14e20db88f321470Chris Lattner                                     superClassId, superClassLoc,
279beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad                                     ProtocolRefs.data(), ProtocolRefs.size(),
28018df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor                                     ProtocolLocs.data(),
2817f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                     EndProtoLoc, attrs.getList());
2821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
283df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner  if (Tok.is(tok::l_brace))
284d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen    ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, AtLoc);
285dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff
2862f64cfe19e8bf6b6ba1660e38da8c421440457feFariborz Jahanian  ParseObjCInterfaceDeclList(tok::objc_interface, ClsType);
2875512ba538f3f6b0576623f680fa7d930fa085ccdFariborz Jahanian  return ClsType;
288dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff}
289dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff
290d0014540005f2a5ab837365db6bd40f479406758John McCall/// The Objective-C property callback.  This should be defined where
291d0014540005f2a5ab837365db6bd40f479406758John McCall/// it's used, but instead it's been lifted to here to support VS2005.
292d0014540005f2a5ab837365db6bd40f479406758John McCallstruct Parser::ObjCPropertyCallback : FieldCallback {
29399ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikieprivate:
29499ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie  virtual void anchor();
29599ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikiepublic:
296d0014540005f2a5ab837365db6bd40f479406758John McCall  Parser &P;
2975f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVectorImpl<Decl *> &Props;
298d0014540005f2a5ab837365db6bd40f479406758John McCall  ObjCDeclSpec &OCDS;
299d0014540005f2a5ab837365db6bd40f479406758John McCall  SourceLocation AtLoc;
30077bfb8b43ec3f7dee3a71f6e854b03ad29dab84fFariborz Jahanian  SourceLocation LParenLoc;
301d0014540005f2a5ab837365db6bd40f479406758John McCall  tok::ObjCKeywordKind MethodImplKind;
302d0014540005f2a5ab837365db6bd40f479406758John McCall
303a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian  ObjCPropertyCallback(Parser &P,
3045f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                       SmallVectorImpl<Decl *> &Props,
305d0014540005f2a5ab837365db6bd40f479406758John McCall                       ObjCDeclSpec &OCDS, SourceLocation AtLoc,
30677bfb8b43ec3f7dee3a71f6e854b03ad29dab84fFariborz Jahanian                       SourceLocation LParenLoc,
307d0014540005f2a5ab837365db6bd40f479406758John McCall                       tok::ObjCKeywordKind MethodImplKind) :
30877bfb8b43ec3f7dee3a71f6e854b03ad29dab84fFariborz Jahanian    P(P), Props(Props), OCDS(OCDS), AtLoc(AtLoc), LParenLoc(LParenLoc),
309d0014540005f2a5ab837365db6bd40f479406758John McCall    MethodImplKind(MethodImplKind) {
310d0014540005f2a5ab837365db6bd40f479406758John McCall  }
311d0014540005f2a5ab837365db6bd40f479406758John McCall
312dcdff46dd8e6d749283fe6c43adfcfe780c1d562Eli Friedman  void invoke(ParsingFieldDeclarator &FD) {
313d0014540005f2a5ab837365db6bd40f479406758John McCall    if (FD.D.getIdentifier() == 0) {
314d0014540005f2a5ab837365db6bd40f479406758John McCall      P.Diag(AtLoc, diag::err_objc_property_requires_field_name)
315d0014540005f2a5ab837365db6bd40f479406758John McCall        << FD.D.getSourceRange();
316dcdff46dd8e6d749283fe6c43adfcfe780c1d562Eli Friedman      return;
317d0014540005f2a5ab837365db6bd40f479406758John McCall    }
318d0014540005f2a5ab837365db6bd40f479406758John McCall    if (FD.BitfieldSize) {
319d0014540005f2a5ab837365db6bd40f479406758John McCall      P.Diag(AtLoc, diag::err_objc_property_bitfield)
320d0014540005f2a5ab837365db6bd40f479406758John McCall        << FD.D.getSourceRange();
321dcdff46dd8e6d749283fe6c43adfcfe780c1d562Eli Friedman      return;
322d0014540005f2a5ab837365db6bd40f479406758John McCall    }
323d0014540005f2a5ab837365db6bd40f479406758John McCall
324d0014540005f2a5ab837365db6bd40f479406758John McCall    // Install the property declarator into interfaceDecl.
325d0014540005f2a5ab837365db6bd40f479406758John McCall    IdentifierInfo *SelName =
326d0014540005f2a5ab837365db6bd40f479406758John McCall      OCDS.getGetterName() ? OCDS.getGetterName() : FD.D.getIdentifier();
327d0014540005f2a5ab837365db6bd40f479406758John McCall
328d0014540005f2a5ab837365db6bd40f479406758John McCall    Selector GetterSel =
329d0014540005f2a5ab837365db6bd40f479406758John McCall      P.PP.getSelectorTable().getNullarySelector(SelName);
330d0014540005f2a5ab837365db6bd40f479406758John McCall    IdentifierInfo *SetterName = OCDS.getSetterName();
331d0014540005f2a5ab837365db6bd40f479406758John McCall    Selector SetterSel;
332d0014540005f2a5ab837365db6bd40f479406758John McCall    if (SetterName)
333d0014540005f2a5ab837365db6bd40f479406758John McCall      SetterSel = P.PP.getSelectorTable().getSelector(1, &SetterName);
334d0014540005f2a5ab837365db6bd40f479406758John McCall    else
335d0014540005f2a5ab837365db6bd40f479406758John McCall      SetterSel = SelectorTable::constructSetterName(P.PP.getIdentifierTable(),
336d0014540005f2a5ab837365db6bd40f479406758John McCall                                                     P.PP.getSelectorTable(),
337d0014540005f2a5ab837365db6bd40f479406758John McCall                                                     FD.D.getIdentifier());
338d0014540005f2a5ab837365db6bd40f479406758John McCall    bool isOverridingProperty = false;
339d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    Decl *Property =
34077bfb8b43ec3f7dee3a71f6e854b03ad29dab84fFariborz Jahanian      P.Actions.ActOnProperty(P.getCurScope(), AtLoc, LParenLoc,
34177bfb8b43ec3f7dee3a71f6e854b03ad29dab84fFariborz Jahanian                              FD, OCDS,
342a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian                              GetterSel, SetterSel,
343d0014540005f2a5ab837365db6bd40f479406758John McCall                              &isOverridingProperty,
344d0014540005f2a5ab837365db6bd40f479406758John McCall                              MethodImplKind);
345d0014540005f2a5ab837365db6bd40f479406758John McCall    if (!isOverridingProperty)
346d0014540005f2a5ab837365db6bd40f479406758John McCall      Props.push_back(Property);
347d0014540005f2a5ab837365db6bd40f479406758John McCall
348f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman    FD.complete(Property);
349d0014540005f2a5ab837365db6bd40f479406758John McCall  }
350d0014540005f2a5ab837365db6bd40f479406758John McCall};
351d0014540005f2a5ab837365db6bd40f479406758John McCall
35299ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikievoid Parser::ObjCPropertyCallback::anchor() {
35399ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie}
35499ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
355dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///   objc-interface-decl-list:
356dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     empty
357dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     objc-interface-decl-list objc-property-decl [OBJC2]
358294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///     objc-interface-decl-list objc-method-requirement [OBJC2]
3593536b443bc50d58a79f14fca9b6842541a434854Steve Naroff///     objc-interface-decl-list objc-method-proto ';'
360dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     objc-interface-decl-list declaration
361dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     objc-interface-decl-list ';'
362dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///
363294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///   objc-method-requirement: [OBJC2]
364294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///     @required
365294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///     @optional
366294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///
3672f64cfe19e8bf6b6ba1660e38da8c421440457feFariborz Jahanianvoid Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,
3682f64cfe19e8bf6b6ba1660e38da8c421440457feFariborz Jahanian                                        Decl *CDecl) {
3695f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<Decl *, 32> allMethods;
3705f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<Decl *, 16> allProperties;
3715f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<DeclGroupPtrTy, 8> allTUVariables;
37200933591a2795d09dd1acff12a2d21bce7cb12c5Fariborz Jahanian  tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword;
3731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
374782f2f52b78d8ca785110398a7f7b56b830b9ac7Ted Kremenek  SourceRange AtEnd;
3752f64cfe19e8bf6b6ba1660e38da8c421440457feFariborz Jahanian
376294494e1cce92043562b4680c613df7fd028c02eSteve Naroff  while (1) {
377e82a10fbba9e33b253119c7c1e0a9801caef486dChris Lattner    // If this is a method prototype, parse it.
378df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner    if (Tok.is(tok::minus) || Tok.is(tok::plus)) {
379d30ec7076fef736754206ac87a4f2c67251cc4d8Fariborz Jahanian      if (Decl *methodPrototype =
380d30ec7076fef736754206ac87a4f2c67251cc4d8Fariborz Jahanian          ParseObjCMethodPrototype(MethodImplKind, false))
381d30ec7076fef736754206ac87a4f2c67251cc4d8Fariborz Jahanian        allMethods.push_back(methodPrototype);
3823536b443bc50d58a79f14fca9b6842541a434854Steve Naroff      // Consume the ';' here, since ParseObjCMethodPrototype() is re-used for
3833536b443bc50d58a79f14fca9b6842541a434854Steve Naroff      // method definitions.
3840db9f4dad563a335641f5b9d4a42504d638b6c85Argyrios Kyrtzidis      if (ExpectAndConsumeSemi(diag::err_expected_semi_after_method_proto)) {
3850db9f4dad563a335641f5b9d4a42504d638b6c85Argyrios Kyrtzidis        // We didn't find a semi and we error'ed out. Skip until a ';' or '@'.
3860db9f4dad563a335641f5b9d4a42504d638b6c85Argyrios Kyrtzidis        SkipUntil(tok::at, /*StopAtSemi=*/true, /*DontConsume=*/true);
3870db9f4dad563a335641f5b9d4a42504d638b6c85Argyrios Kyrtzidis        if (Tok.is(tok::semi))
3880db9f4dad563a335641f5b9d4a42504d638b6c85Argyrios Kyrtzidis          ConsumeToken();
3890db9f4dad563a335641f5b9d4a42504d638b6c85Argyrios Kyrtzidis      }
390294494e1cce92043562b4680c613df7fd028c02eSteve Naroff      continue;
391294494e1cce92043562b4680c613df7fd028c02eSteve Naroff    }
39205511fa6349ef0820a778f8c840d0b64e05e9aeeFariborz Jahanian    if (Tok.is(tok::l_paren)) {
39305511fa6349ef0820a778f8c840d0b64e05e9aeeFariborz Jahanian      Diag(Tok, diag::err_expected_minus_or_plus);
394d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall      ParseObjCMethodDecl(Tok.getLocation(),
395d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall                          tok::minus,
39690ba78c64d0c24cfbc1bf88728db9775d44d7f9fFariborz Jahanian                          MethodImplKind, false);
39705511fa6349ef0820a778f8c840d0b64e05e9aeeFariborz Jahanian      continue;
39805511fa6349ef0820a778f8c840d0b64e05e9aeeFariborz Jahanian    }
399e82a10fbba9e33b253119c7c1e0a9801caef486dChris Lattner    // Ignore excess semicolons.
400e82a10fbba9e33b253119c7c1e0a9801caef486dChris Lattner    if (Tok.is(tok::semi)) {
401294494e1cce92043562b4680c613df7fd028c02eSteve Naroff      ConsumeToken();
402e82a10fbba9e33b253119c7c1e0a9801caef486dChris Lattner      continue;
403e82a10fbba9e33b253119c7c1e0a9801caef486dChris Lattner    }
4041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
405bc662afa1cb9b61cb1e7808bb1463dd6291b8095Chris Lattner    // If we got to the end of the file, exit the loop.
406e82a10fbba9e33b253119c7c1e0a9801caef486dChris Lattner    if (Tok.is(tok::eof))
407e3a2ca7e30601cdd31c77a830f4cc487851e8096Fariborz Jahanian      break;
4081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
409b6ac2451bfed36206c5cec7217372c4299f67f2bDouglas Gregor    // Code completion within an Objective-C interface.
410b6ac2451bfed36206c5cec7217372c4299f67f2bDouglas Gregor    if (Tok.is(tok::code_completion)) {
41123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      Actions.CodeCompleteOrdinaryName(getCurScope(),
412849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis                            CurParsedObjCImpl? Sema::PCC_ObjCImplementation
413f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                             : Sema::PCC_ObjCInterface);
4147d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      return cutOffParsing();
415b6ac2451bfed36206c5cec7217372c4299f67f2bDouglas Gregor    }
416b6ac2451bfed36206c5cec7217372c4299f67f2bDouglas Gregor
417e82a10fbba9e33b253119c7c1e0a9801caef486dChris Lattner    // If we don't have an @ directive, parse it as a function definition.
418e82a10fbba9e33b253119c7c1e0a9801caef486dChris Lattner    if (Tok.isNot(tok::at)) {
4191fd80116b49782c367ff5d5f50a8b76dd8a5d7f7Chris Lattner      // The code below does not consume '}'s because it is afraid of eating the
4201fd80116b49782c367ff5d5f50a8b76dd8a5d7f7Chris Lattner      // end of a namespace.  Because of the way this code is structured, an
4211fd80116b49782c367ff5d5f50a8b76dd8a5d7f7Chris Lattner      // erroneous r_brace would cause an infinite loop if not handled here.
4221fd80116b49782c367ff5d5f50a8b76dd8a5d7f7Chris Lattner      if (Tok.is(tok::r_brace))
4231fd80116b49782c367ff5d5f50a8b76dd8a5d7f7Chris Lattner        break;
4242edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt      ParsedAttributesWithRange attrs(AttrFactory);
4257f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall      allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(attrs));
426e82a10fbba9e33b253119c7c1e0a9801caef486dChris Lattner      continue;
427e82a10fbba9e33b253119c7c1e0a9801caef486dChris Lattner    }
4281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
429e82a10fbba9e33b253119c7c1e0a9801caef486dChris Lattner    // Otherwise, we have an @ directive, eat the @.
430e82a10fbba9e33b253119c7c1e0a9801caef486dChris Lattner    SourceLocation AtLoc = ConsumeToken(); // the "@"
431c464ae8444edb6d07ea49b7a0eae1674c0fa1bb8Douglas Gregor    if (Tok.is(tok::code_completion)) {
432a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian      Actions.CodeCompleteObjCAtDirective(getCurScope());
4337d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      return cutOffParsing();
434c464ae8444edb6d07ea49b7a0eae1674c0fa1bb8Douglas Gregor    }
435c464ae8444edb6d07ea49b7a0eae1674c0fa1bb8Douglas Gregor
436a2449b2bf739545494241e189b59587d5ca5c2c1Chris Lattner    tok::ObjCKeywordKind DirectiveKind = Tok.getObjCKeywordID();
4371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
438a2449b2bf739545494241e189b59587d5ca5c2c1Chris Lattner    if (DirectiveKind == tok::objc_end) { // @end -> terminate list
439782f2f52b78d8ca785110398a7f7b56b830b9ac7Ted Kremenek      AtEnd.setBegin(AtLoc);
440782f2f52b78d8ca785110398a7f7b56b830b9ac7Ted Kremenek      AtEnd.setEnd(Tok.getLocation());
441e82a10fbba9e33b253119c7c1e0a9801caef486dChris Lattner      break;
442c3d43b783dfb1a1502aa8b31ab1985cf237b1f77Douglas Gregor    } else if (DirectiveKind == tok::objc_not_keyword) {
443c3d43b783dfb1a1502aa8b31ab1985cf237b1f77Douglas Gregor      Diag(Tok, diag::err_objc_unknown_at);
444c3d43b783dfb1a1502aa8b31ab1985cf237b1f77Douglas Gregor      SkipUntil(tok::semi);
445c3d43b783dfb1a1502aa8b31ab1985cf237b1f77Douglas Gregor      continue;
446bc662afa1cb9b61cb1e7808bb1463dd6291b8095Chris Lattner    }
4471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
448bc662afa1cb9b61cb1e7808bb1463dd6291b8095Chris Lattner    // Eat the identifier.
449bc662afa1cb9b61cb1e7808bb1463dd6291b8095Chris Lattner    ConsumeToken();
450bc662afa1cb9b61cb1e7808bb1463dd6291b8095Chris Lattner
451a2449b2bf739545494241e189b59587d5ca5c2c1Chris Lattner    switch (DirectiveKind) {
452a2449b2bf739545494241e189b59587d5ca5c2c1Chris Lattner    default:
453bc662afa1cb9b61cb1e7808bb1463dd6291b8095Chris Lattner      // FIXME: If someone forgets an @end on a protocol, this loop will
454bc662afa1cb9b61cb1e7808bb1463dd6291b8095Chris Lattner      // continue to eat up tons of stuff and spew lots of nonsense errors.  It
455bc662afa1cb9b61cb1e7808bb1463dd6291b8095Chris Lattner      // would probably be better to bail out if we saw an @class or @interface
456bc662afa1cb9b61cb1e7808bb1463dd6291b8095Chris Lattner      // or something like that.
457f6ed85533583dae18a44ddc4be6cfc4d68749e36Chris Lattner      Diag(AtLoc, diag::err_objc_illegal_interface_qual);
458bc662afa1cb9b61cb1e7808bb1463dd6291b8095Chris Lattner      // Skip until we see an '@' or '}' or ';'.
459a2449b2bf739545494241e189b59587d5ca5c2c1Chris Lattner      SkipUntil(tok::r_brace, tok::at);
460a2449b2bf739545494241e189b59587d5ca5c2c1Chris Lattner      break;
46146d545e355a4fea2a201652c3c8bbf22a13187a6Fariborz Jahanian
46246d545e355a4fea2a201652c3c8bbf22a13187a6Fariborz Jahanian    case tok::objc_implementation:
463df81c2c6ce37f4ae3c45dd01093b6274fa0b6692Fariborz Jahanian    case tok::objc_interface:
464d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen      Diag(AtLoc, diag::err_objc_missing_end)
465d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen          << FixItHint::CreateInsertion(AtLoc, "@end\n");
466d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen      Diag(CDecl->getLocStart(), diag::note_objc_container_start)
467d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen          << (int) Actions.getObjCContainerKind();
46846d545e355a4fea2a201652c3c8bbf22a13187a6Fariborz Jahanian      ConsumeToken();
46946d545e355a4fea2a201652c3c8bbf22a13187a6Fariborz Jahanian      break;
47046d545e355a4fea2a201652c3c8bbf22a13187a6Fariborz Jahanian
471a2449b2bf739545494241e189b59587d5ca5c2c1Chris Lattner    case tok::objc_required:
472a2449b2bf739545494241e189b59587d5ca5c2c1Chris Lattner    case tok::objc_optional:
473a2449b2bf739545494241e189b59587d5ca5c2c1Chris Lattner      // This is only valid on protocols.
474bc662afa1cb9b61cb1e7808bb1463dd6291b8095Chris Lattner      // FIXME: Should this check for ObjC2 being enabled?
475e82a10fbba9e33b253119c7c1e0a9801caef486dChris Lattner      if (contextKey != tok::objc_protocol)
476bc662afa1cb9b61cb1e7808bb1463dd6291b8095Chris Lattner        Diag(AtLoc, diag::err_objc_directive_only_in_protocol);
477a2449b2bf739545494241e189b59587d5ca5c2c1Chris Lattner      else
478bc662afa1cb9b61cb1e7808bb1463dd6291b8095Chris Lattner        MethodImplKind = DirectiveKind;
479a2449b2bf739545494241e189b59587d5ca5c2c1Chris Lattner      break;
4801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
481a2449b2bf739545494241e189b59587d5ca5c2c1Chris Lattner    case tok::objc_property:
4824e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie      if (!getLangOpts().ObjC2)
483b321c0c0ba957d78475e72cebde4028fdaa00f8fChris Lattner        Diag(AtLoc, diag::err_objc_properties_require_objc2);
484f6ed85533583dae18a44ddc4be6cfc4d68749e36Chris Lattner
485e82a10fbba9e33b253119c7c1e0a9801caef486dChris Lattner      ObjCDeclSpec OCDS;
48677bfb8b43ec3f7dee3a71f6e854b03ad29dab84fFariborz Jahanian      SourceLocation LParenLoc;
4871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      // Parse property attribute list, if any.
48877bfb8b43ec3f7dee3a71f6e854b03ad29dab84fFariborz Jahanian      if (Tok.is(tok::l_paren)) {
48977bfb8b43ec3f7dee3a71f6e854b03ad29dab84fFariborz Jahanian        LParenLoc = Tok.getLocation();
490a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian        ParseObjCPropertyAttribute(OCDS);
49177bfb8b43ec3f7dee3a71f6e854b03ad29dab84fFariborz Jahanian      }
4921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
493a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian      ObjCPropertyCallback Callback(*this, allProperties,
49477bfb8b43ec3f7dee3a71f6e854b03ad29dab84fFariborz Jahanian                                    OCDS, AtLoc, LParenLoc, MethodImplKind);
495bdd563ec391b0a83fc6d04b8a8ea3022aa702f74John McCall
496e82a10fbba9e33b253119c7c1e0a9801caef486dChris Lattner      // Parse all the comma separated declarators.
497f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman      ParsingDeclSpec DS(*this);
498bdd563ec391b0a83fc6d04b8a8ea3022aa702f74John McCall      ParseStructDeclaration(DS, Callback);
4991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5007da19ea50d4161fcda40d135735bcf450cabeb50John McCall      ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
501a2449b2bf739545494241e189b59587d5ca5c2c1Chris Lattner      break;
502f28b264437053fb0deacc9ba02b18a0966f7290aSteve Naroff    }
503294494e1cce92043562b4680c613df7fd028c02eSteve Naroff  }
504bc662afa1cb9b61cb1e7808bb1463dd6291b8095Chris Lattner
505bc662afa1cb9b61cb1e7808bb1463dd6291b8095Chris Lattner  // We break out of the big loop in two cases: when we see @end or when we see
506bc662afa1cb9b61cb1e7808bb1463dd6291b8095Chris Lattner  // EOF.  In the former case, eat the @end.  In the later case, emit an error.
507c464ae8444edb6d07ea49b7a0eae1674c0fa1bb8Douglas Gregor  if (Tok.is(tok::code_completion)) {
508a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian    Actions.CodeCompleteObjCAtDirective(getCurScope());
5097d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return cutOffParsing();
510d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen  } else if (Tok.isObjCAtKeyword(tok::objc_end)) {
511bc662afa1cb9b61cb1e7808bb1463dd6291b8095Chris Lattner    ConsumeToken(); // the "end" identifier
512d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen  } else {
513d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen    Diag(Tok, diag::err_objc_missing_end)
514d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen        << FixItHint::CreateInsertion(Tok.getLocation(), "\n@end\n");
515d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen    Diag(CDecl->getLocStart(), diag::note_objc_container_start)
516d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen        << (int) Actions.getObjCContainerKind();
517d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen    AtEnd.setBegin(Tok.getLocation());
518d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen    AtEnd.setEnd(Tok.getLocation());
519d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen  }
5201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
521a2449b2bf739545494241e189b59587d5ca5c2c1Chris Lattner  // Insert collected methods declarations into the @interface object.
522bc662afa1cb9b61cb1e7808bb1463dd6291b8095Chris Lattner  // This passes in an invalid SourceLocation for AtEndLoc when EOF is hit.
523a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian  Actions.ActOnAtEnd(getCurScope(), AtEnd,
5241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                     allMethods.data(), allMethods.size(),
525beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad                     allProperties.data(), allProperties.size(),
526beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad                     allTUVariables.data(), allTUVariables.size());
527294494e1cce92043562b4680c613df7fd028c02eSteve Naroff}
528294494e1cce92043562b4680c613df7fd028c02eSteve Naroff
529d0f97d1716a138a8d9e0df8e5af77334663723d8Fariborz Jahanian///   Parse property attribute declarations.
530d0f97d1716a138a8d9e0df8e5af77334663723d8Fariborz Jahanian///
531d0f97d1716a138a8d9e0df8e5af77334663723d8Fariborz Jahanian///   property-attr-decl: '(' property-attrlist ')'
532d0f97d1716a138a8d9e0df8e5af77334663723d8Fariborz Jahanian///   property-attrlist:
533d0f97d1716a138a8d9e0df8e5af77334663723d8Fariborz Jahanian///     property-attribute
534d0f97d1716a138a8d9e0df8e5af77334663723d8Fariborz Jahanian///     property-attrlist ',' property-attribute
535d0f97d1716a138a8d9e0df8e5af77334663723d8Fariborz Jahanian///   property-attribute:
536d0f97d1716a138a8d9e0df8e5af77334663723d8Fariborz Jahanian///     getter '=' identifier
537d0f97d1716a138a8d9e0df8e5af77334663723d8Fariborz Jahanian///     setter '=' identifier ':'
538d0f97d1716a138a8d9e0df8e5af77334663723d8Fariborz Jahanian///     readonly
539d0f97d1716a138a8d9e0df8e5af77334663723d8Fariborz Jahanian///     readwrite
540d0f97d1716a138a8d9e0df8e5af77334663723d8Fariborz Jahanian///     assign
541d0f97d1716a138a8d9e0df8e5af77334663723d8Fariborz Jahanian///     retain
542d0f97d1716a138a8d9e0df8e5af77334663723d8Fariborz Jahanian///     copy
543d0f97d1716a138a8d9e0df8e5af77334663723d8Fariborz Jahanian///     nonatomic
544f85e193739c953358c865005855253af4f68a497John McCall///     atomic
545f85e193739c953358c865005855253af4f68a497John McCall///     strong
546f85e193739c953358c865005855253af4f68a497John McCall///     weak
547f85e193739c953358c865005855253af4f68a497John McCall///     unsafe_unretained
548d0f97d1716a138a8d9e0df8e5af77334663723d8Fariborz Jahanian///
549a28948f34817476d02412fa204cae038e228c827Fariborz Jahanianvoid Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
5508ca329c00e72f301cbaaa42229b20a2f5bc793e5Chris Lattner  assert(Tok.getKind() == tok::l_paren);
5514a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_paren);
5524a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeOpen();
5531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
554cd9f4b31c4fe5b77b5519cc17b4583fab912bad1Chris Lattner  while (1) {
555ece8e71d12b6f4cb2dc501297afef126dab8ad74Steve Naroff    if (Tok.is(tok::code_completion)) {
55623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      Actions.CodeCompleteObjCPropertyFlags(getCurScope(), DS);
5577d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      return cutOffParsing();
558ece8e71d12b6f4cb2dc501297afef126dab8ad74Steve Naroff    }
559d0f97d1716a138a8d9e0df8e5af77334663723d8Fariborz Jahanian    const IdentifierInfo *II = Tok.getIdentifierInfo();
5601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
561f6ed85533583dae18a44ddc4be6cfc4d68749e36Chris Lattner    // If this is not an identifier at all, bail out early.
562f6ed85533583dae18a44ddc4be6cfc4d68749e36Chris Lattner    if (II == 0) {
5634a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor      T.consumeClose();
564f6ed85533583dae18a44ddc4be6cfc4d68749e36Chris Lattner      return;
565f6ed85533583dae18a44ddc4be6cfc4d68749e36Chris Lattner    }
5661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
567156b061e4918a5e7ecd8eb317975de0e6be2688bChris Lattner    SourceLocation AttrName = ConsumeToken(); // consume last attribute name
5681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
56992e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner    if (II->isStr("readonly"))
570e00da7c2f47d4a3d9615c1056a8a65e459113de3Chris Lattner      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_readonly);
57192e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner    else if (II->isStr("assign"))
572e00da7c2f47d4a3d9615c1056a8a65e459113de3Chris Lattner      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_assign);
573f85e193739c953358c865005855253af4f68a497John McCall    else if (II->isStr("unsafe_unretained"))
574f85e193739c953358c865005855253af4f68a497John McCall      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_unsafe_unretained);
57592e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner    else if (II->isStr("readwrite"))
576e00da7c2f47d4a3d9615c1056a8a65e459113de3Chris Lattner      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_readwrite);
57792e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner    else if (II->isStr("retain"))
578e00da7c2f47d4a3d9615c1056a8a65e459113de3Chris Lattner      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_retain);
579f85e193739c953358c865005855253af4f68a497John McCall    else if (II->isStr("strong"))
580f85e193739c953358c865005855253af4f68a497John McCall      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_strong);
58192e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner    else if (II->isStr("copy"))
582e00da7c2f47d4a3d9615c1056a8a65e459113de3Chris Lattner      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_copy);
58392e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner    else if (II->isStr("nonatomic"))
584e00da7c2f47d4a3d9615c1056a8a65e459113de3Chris Lattner      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nonatomic);
58545937ae10a0f70f74508165aab4f2b63e18ea747Fariborz Jahanian    else if (II->isStr("atomic"))
58645937ae10a0f70f74508165aab4f2b63e18ea747Fariborz Jahanian      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_atomic);
587f85e193739c953358c865005855253af4f68a497John McCall    else if (II->isStr("weak"))
588f85e193739c953358c865005855253af4f68a497John McCall      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_weak);
58992e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner    else if (II->isStr("getter") || II->isStr("setter")) {
59042499be29b620d2eae34beb0f4d0f9da5a9584daAnders Carlsson      bool IsSetter = II->getNameStart()[0] == 's';
59142499be29b620d2eae34beb0f4d0f9da5a9584daAnders Carlsson
592e00da7c2f47d4a3d9615c1056a8a65e459113de3Chris Lattner      // getter/setter require extra treatment.
59342499be29b620d2eae34beb0f4d0f9da5a9584daAnders Carlsson      unsigned DiagID = IsSetter ? diag::err_objc_expected_equal_for_setter :
59442499be29b620d2eae34beb0f4d0f9da5a9584daAnders Carlsson        diag::err_objc_expected_equal_for_getter;
59542499be29b620d2eae34beb0f4d0f9da5a9584daAnders Carlsson
59642499be29b620d2eae34beb0f4d0f9da5a9584daAnders Carlsson      if (ExpectAndConsume(tok::equal, DiagID, "", tok::r_paren))
597dd5b5f2bb73d037745940431b71eb98393d12d4fChris Lattner        return;
5981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5994ad9685b3e2d5e2923c9cda7baaf7973ef0b1c62Douglas Gregor      if (Tok.is(tok::code_completion)) {
60042499be29b620d2eae34beb0f4d0f9da5a9584daAnders Carlsson        if (IsSetter)
601a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian          Actions.CodeCompleteObjCPropertySetter(getCurScope());
6024ad9685b3e2d5e2923c9cda7baaf7973ef0b1c62Douglas Gregor        else
603a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian          Actions.CodeCompleteObjCPropertyGetter(getCurScope());
6047d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis        return cutOffParsing();
6054ad9685b3e2d5e2923c9cda7baaf7973ef0b1c62Douglas Gregor      }
6064ad9685b3e2d5e2923c9cda7baaf7973ef0b1c62Douglas Gregor
60742499be29b620d2eae34beb0f4d0f9da5a9584daAnders Carlsson
60842499be29b620d2eae34beb0f4d0f9da5a9584daAnders Carlsson      SourceLocation SelLoc;
60942499be29b620d2eae34beb0f4d0f9da5a9584daAnders Carlsson      IdentifierInfo *SelIdent = ParseObjCSelectorPiece(SelLoc);
61042499be29b620d2eae34beb0f4d0f9da5a9584daAnders Carlsson
61142499be29b620d2eae34beb0f4d0f9da5a9584daAnders Carlsson      if (!SelIdent) {
61242499be29b620d2eae34beb0f4d0f9da5a9584daAnders Carlsson        Diag(Tok, diag::err_objc_expected_selector_for_getter_setter)
61342499be29b620d2eae34beb0f4d0f9da5a9584daAnders Carlsson          << IsSetter;
6148ca329c00e72f301cbaaa42229b20a2f5bc793e5Chris Lattner        SkipUntil(tok::r_paren);
6158ca329c00e72f301cbaaa42229b20a2f5bc793e5Chris Lattner        return;
6168ca329c00e72f301cbaaa42229b20a2f5bc793e5Chris Lattner      }
6171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
61842499be29b620d2eae34beb0f4d0f9da5a9584daAnders Carlsson      if (IsSetter) {
6198ca329c00e72f301cbaaa42229b20a2f5bc793e5Chris Lattner        DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_setter);
62042499be29b620d2eae34beb0f4d0f9da5a9584daAnders Carlsson        DS.setSetterName(SelIdent);
6211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
622e0097db2848c463a534c18c235c6d3e53f2f1b87Fariborz Jahanian        if (ExpectAndConsume(tok::colon,
623e0097db2848c463a534c18c235c6d3e53f2f1b87Fariborz Jahanian                             diag::err_expected_colon_after_setter_name, "",
624156b061e4918a5e7ecd8eb317975de0e6be2688bChris Lattner                             tok::r_paren))
6258ca329c00e72f301cbaaa42229b20a2f5bc793e5Chris Lattner          return;
6268ca329c00e72f301cbaaa42229b20a2f5bc793e5Chris Lattner      } else {
6278ca329c00e72f301cbaaa42229b20a2f5bc793e5Chris Lattner        DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_getter);
62842499be29b620d2eae34beb0f4d0f9da5a9584daAnders Carlsson        DS.setGetterName(SelIdent);
6298ca329c00e72f301cbaaa42229b20a2f5bc793e5Chris Lattner      }
630e00da7c2f47d4a3d9615c1056a8a65e459113de3Chris Lattner    } else {
631a9500f05ba6c09bbd84d342236863833067cd816Chris Lattner      Diag(AttrName, diag::err_objc_expected_property_attr) << II;
632cd9f4b31c4fe5b77b5519cc17b4583fab912bad1Chris Lattner      SkipUntil(tok::r_paren);
633cd9f4b31c4fe5b77b5519cc17b4583fab912bad1Chris Lattner      return;
634cd9f4b31c4fe5b77b5519cc17b4583fab912bad1Chris Lattner    }
6351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
636156b061e4918a5e7ecd8eb317975de0e6be2688bChris Lattner    if (Tok.isNot(tok::comma))
637156b061e4918a5e7ecd8eb317975de0e6be2688bChris Lattner      break;
6381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
639156b061e4918a5e7ecd8eb317975de0e6be2688bChris Lattner    ConsumeToken();
640d0f97d1716a138a8d9e0df8e5af77334663723d8Fariborz Jahanian  }
6411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6424a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
643d0f97d1716a138a8d9e0df8e5af77334663723d8Fariborz Jahanian}
644d0f97d1716a138a8d9e0df8e5af77334663723d8Fariborz Jahanian
6453536b443bc50d58a79f14fca9b6842541a434854Steve Naroff///   objc-method-proto:
6461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///     objc-instance-method objc-method-decl objc-method-attributes[opt]
6473536b443bc50d58a79f14fca9b6842541a434854Steve Naroff///     objc-class-method objc-method-decl objc-method-attributes[opt]
648294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///
649294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///   objc-instance-method: '-'
650294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///   objc-class-method: '+'
651294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///
6524985aceceb9b9261b876b515d32726175c13a775Steve Naroff///   objc-method-attributes:         [OBJC2]
6534985aceceb9b9261b876b515d32726175c13a775Steve Naroff///     __attribute__((deprecated))
6544985aceceb9b9261b876b515d32726175c13a775Steve Naroff///
655a28948f34817476d02412fa204cae038e228c827Fariborz JahanianDecl *Parser::ParseObjCMethodPrototype(tok::ObjCKeywordKind MethodImplKind,
65690ba78c64d0c24cfbc1bf88728db9775d44d7f9fFariborz Jahanian                                       bool MethodDefinition) {
657df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner  assert((Tok.is(tok::minus) || Tok.is(tok::plus)) && "expected +/-");
658294494e1cce92043562b4680c613df7fd028c02eSteve Naroff
6591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  tok::TokenKind methodType = Tok.getKind();
660bef1185418705e16012b3dd50cd7c260c8d6b79cSteve Naroff  SourceLocation mLoc = ConsumeToken();
661a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian  Decl *MDecl = ParseObjCMethodDecl(mLoc, methodType, MethodImplKind,
66290ba78c64d0c24cfbc1bf88728db9775d44d7f9fFariborz Jahanian                                    MethodDefinition);
6633536b443bc50d58a79f14fca9b6842541a434854Steve Naroff  // Since this rule is used for both method declarations and definitions,
6642bd42fadafddc8acf744b57a970bdc96a077c617Steve Naroff  // the caller is (optionally) responsible for consuming the ';'.
665f28b264437053fb0deacc9ba02b18a0966f7290aSteve Naroff  return MDecl;
666294494e1cce92043562b4680c613df7fd028c02eSteve Naroff}
667294494e1cce92043562b4680c613df7fd028c02eSteve Naroff
668294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///   objc-selector:
669294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///     identifier
670294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///     one of
671294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///       enum struct union if else while do for switch case default
672294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///       break continue return goto asm sizeof typeof __alignof
673294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///       unsigned long const short volatile signed restrict _Complex
674294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///       in out inout bycopy byref oneway int char float double void _Bool
675294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///
6762fc5c2428ecb450a3256c8316b93b8655cb76a0fChris LattnerIdentifierInfo *Parser::ParseObjCSelectorPiece(SourceLocation &SelectorLoc) {
677be74740cc246ce08d42804a684385a42eb814edbFariborz Jahanian
678ff38491c18b060526d754765b952f4a497a89416Chris Lattner  switch (Tok.getKind()) {
679ff38491c18b060526d754765b952f4a497a89416Chris Lattner  default:
680ff38491c18b060526d754765b952f4a497a89416Chris Lattner    return 0;
681afbc68177cc11b8bfa47464b20e15d5f8fb21d4eFariborz Jahanian  case tok::ampamp:
682afbc68177cc11b8bfa47464b20e15d5f8fb21d4eFariborz Jahanian  case tok::ampequal:
683afbc68177cc11b8bfa47464b20e15d5f8fb21d4eFariborz Jahanian  case tok::amp:
684afbc68177cc11b8bfa47464b20e15d5f8fb21d4eFariborz Jahanian  case tok::pipe:
685afbc68177cc11b8bfa47464b20e15d5f8fb21d4eFariborz Jahanian  case tok::tilde:
686afbc68177cc11b8bfa47464b20e15d5f8fb21d4eFariborz Jahanian  case tok::exclaim:
687afbc68177cc11b8bfa47464b20e15d5f8fb21d4eFariborz Jahanian  case tok::exclaimequal:
688afbc68177cc11b8bfa47464b20e15d5f8fb21d4eFariborz Jahanian  case tok::pipepipe:
689afbc68177cc11b8bfa47464b20e15d5f8fb21d4eFariborz Jahanian  case tok::pipeequal:
690afbc68177cc11b8bfa47464b20e15d5f8fb21d4eFariborz Jahanian  case tok::caret:
691afbc68177cc11b8bfa47464b20e15d5f8fb21d4eFariborz Jahanian  case tok::caretequal: {
6923846ca29a8cc1d376a4b695194c29952dbbfb544Fariborz Jahanian    std::string ThisTok(PP.getSpelling(Tok));
693afbc68177cc11b8bfa47464b20e15d5f8fb21d4eFariborz Jahanian    if (isalpha(ThisTok[0])) {
694afbc68177cc11b8bfa47464b20e15d5f8fb21d4eFariborz Jahanian      IdentifierInfo *II = &PP.getIdentifierTable().get(ThisTok.data());
695afbc68177cc11b8bfa47464b20e15d5f8fb21d4eFariborz Jahanian      Tok.setKind(tok::identifier);
696afbc68177cc11b8bfa47464b20e15d5f8fb21d4eFariborz Jahanian      SelectorLoc = ConsumeToken();
697afbc68177cc11b8bfa47464b20e15d5f8fb21d4eFariborz Jahanian      return II;
698afbc68177cc11b8bfa47464b20e15d5f8fb21d4eFariborz Jahanian    }
699afbc68177cc11b8bfa47464b20e15d5f8fb21d4eFariborz Jahanian    return 0;
700afbc68177cc11b8bfa47464b20e15d5f8fb21d4eFariborz Jahanian  }
701afbc68177cc11b8bfa47464b20e15d5f8fb21d4eFariborz Jahanian
702ff38491c18b060526d754765b952f4a497a89416Chris Lattner  case tok::identifier:
703ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_asm:
704ff38491c18b060526d754765b952f4a497a89416Chris Lattner  case tok::kw_auto:
7059298d9655aed28b2d9f6cc65c81401b209f03fdcChris Lattner  case tok::kw_bool:
706ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_break:
707ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_case:
708ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_catch:
709ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_char:
710ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_class:
711ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_const:
712ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_const_cast:
713ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_continue:
714ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_default:
715ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_delete:
716ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_do:
717ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_double:
718ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_dynamic_cast:
719ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_else:
720ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_enum:
721ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_explicit:
722ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_export:
723ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_extern:
724ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_false:
725ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_float:
726ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_for:
727ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_friend:
728ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_goto:
729ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_if:
730ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_inline:
731ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_int:
732ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_long:
733ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_mutable:
734ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_namespace:
735ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_new:
736ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_operator:
737ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_private:
738ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_protected:
739ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_public:
740ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_register:
741ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_reinterpret_cast:
742ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_restrict:
743ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_return:
744ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_short:
745ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_signed:
746ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_sizeof:
747ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_static:
748ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_static_cast:
749ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_struct:
750ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_switch:
751ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_template:
752ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_this:
753ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_throw:
754ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_true:
755ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_try:
756ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_typedef:
757ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_typeid:
758ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_typename:
759ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_typeof:
760ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_union:
761ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_unsigned:
762ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_using:
763ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_virtual:
764ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_void:
765ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_volatile:
766ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_wchar_t:
767ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw_while:
768ff38491c18b060526d754765b952f4a497a89416Chris Lattner  case tok::kw__Bool:
769ff38491c18b060526d754765b952f4a497a89416Chris Lattner  case tok::kw__Complex:
770ef048ef393960728bdc82cd5c45035bde7013b6aAnders Carlsson  case tok::kw___alignof:
771ff38491c18b060526d754765b952f4a497a89416Chris Lattner    IdentifierInfo *II = Tok.getIdentifierInfo();
7724b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian    SelectorLoc = ConsumeToken();
773ff38491c18b060526d754765b952f4a497a89416Chris Lattner    return II;
774d064951b0dcc95f8604d0d69ae82d9ecbd38c796Fariborz Jahanian  }
775294494e1cce92043562b4680c613df7fd028c02eSteve Naroff}
776294494e1cce92043562b4680c613df7fd028c02eSteve Naroff
7770196cab54007ff072ec2642da8911c6b7e8d3fb5Fariborz Jahanian///  objc-for-collection-in: 'in'
7780196cab54007ff072ec2642da8911c6b7e8d3fb5Fariborz Jahanian///
779335a2d4122e41343fe11a775889b8bec5b14be60Fariborz Jahanianbool Parser::isTokIdentifier_in() const {
7803ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian  // FIXME: May have to do additional look-ahead to only allow for
7813ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian  // valid tokens following an 'in'; such as an identifier, unary operators,
7823ba5a0f90a03d5e13d02cbee9abd2a1ba01b18bcFariborz Jahanian  // '[' etc.
7834e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  return (getLangOpts().ObjC2 && Tok.is(tok::identifier) &&
7845ffb14b7e88e587cd2f78dcc3a966a64108920f0Chris Lattner          Tok.getIdentifierInfo() == ObjCTypeQuals[objc_in]);
7850196cab54007ff072ec2642da8911c6b7e8d3fb5Fariborz Jahanian}
7860196cab54007ff072ec2642da8911c6b7e8d3fb5Fariborz Jahanian
787a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek/// ParseObjCTypeQualifierList - This routine parses the objective-c's type
788e8b724d481c9547de2ee6f442be594b38ada452dChris Lattner/// qualifier list and builds their bitmask representation in the input
789e8b724d481c9547de2ee6f442be594b38ada452dChris Lattner/// argument.
790294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///
791294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///   objc-type-qualifiers:
792294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///     objc-type-qualifier
793294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///     objc-type-qualifiers objc-type-qualifier
794294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///
795b77cab97f17f946744c920629ca17271308d8ebfDouglas Gregorvoid Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS,
796cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall                                        Declarator::TheContext Context) {
797cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall  assert(Context == Declarator::ObjCParameterContext ||
798cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall         Context == Declarator::ObjCResultContext);
799cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall
800e8b724d481c9547de2ee6f442be594b38ada452dChris Lattner  while (1) {
801d32b0225e29fcafb2b2b2a4b1c51dcb1518af9c6Douglas Gregor    if (Tok.is(tok::code_completion)) {
802b77cab97f17f946744c920629ca17271308d8ebfDouglas Gregor      Actions.CodeCompleteObjCPassingType(getCurScope(), DS,
803cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall                          Context == Declarator::ObjCParameterContext);
8047d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      return cutOffParsing();
805d32b0225e29fcafb2b2b2a4b1c51dcb1518af9c6Douglas Gregor    }
806d32b0225e29fcafb2b2b2a4b1c51dcb1518af9c6Douglas Gregor
807cb53b361bce341c8591333c6997f62e480acc0b4Chris Lattner    if (Tok.isNot(tok::identifier))
808e8b724d481c9547de2ee6f442be594b38ada452dChris Lattner      return;
8091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
810e8b724d481c9547de2ee6f442be594b38ada452dChris Lattner    const IdentifierInfo *II = Tok.getIdentifierInfo();
811e8b724d481c9547de2ee6f442be594b38ada452dChris Lattner    for (unsigned i = 0; i != objc_NumQuals; ++i) {
812a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      if (II != ObjCTypeQuals[i])
813e8b724d481c9547de2ee6f442be594b38ada452dChris Lattner        continue;
8141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
815a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      ObjCDeclSpec::ObjCDeclQualifier Qual;
816e8b724d481c9547de2ee6f442be594b38ada452dChris Lattner      switch (i) {
817b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      default: llvm_unreachable("Unknown decl qualifier");
818a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      case objc_in:     Qual = ObjCDeclSpec::DQ_In; break;
819a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      case objc_out:    Qual = ObjCDeclSpec::DQ_Out; break;
820a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      case objc_inout:  Qual = ObjCDeclSpec::DQ_Inout; break;
821a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      case objc_oneway: Qual = ObjCDeclSpec::DQ_Oneway; break;
822a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      case objc_bycopy: Qual = ObjCDeclSpec::DQ_Bycopy; break;
823a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      case objc_byref:  Qual = ObjCDeclSpec::DQ_Byref; break;
824e8b724d481c9547de2ee6f442be594b38ada452dChris Lattner      }
825a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek      DS.setObjCDeclQualifier(Qual);
826e8b724d481c9547de2ee6f442be594b38ada452dChris Lattner      ConsumeToken();
827e8b724d481c9547de2ee6f442be594b38ada452dChris Lattner      II = 0;
828e8b724d481c9547de2ee6f442be594b38ada452dChris Lattner      break;
829e8b724d481c9547de2ee6f442be594b38ada452dChris Lattner    }
8301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
831e8b724d481c9547de2ee6f442be594b38ada452dChris Lattner    // If this wasn't a recognized qualifier, bail out.
832e8b724d481c9547de2ee6f442be594b38ada452dChris Lattner    if (II) return;
833e8b724d481c9547de2ee6f442be594b38ada452dChris Lattner  }
834e8b724d481c9547de2ee6f442be594b38ada452dChris Lattner}
835e8b724d481c9547de2ee6f442be594b38ada452dChris Lattner
836cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall/// Take all the decl attributes out of the given list and add
837cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall/// them to the given attribute set.
838cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCallstatic void takeDeclAttributes(ParsedAttributes &attrs,
839cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall                               AttributeList *list) {
840cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall  while (list) {
841cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall    AttributeList *cur = list;
842cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall    list = cur->getNext();
843cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall
844cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall    if (!cur->isUsedAsTypeAttr()) {
845cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall      // Clear out the next pointer.  We're really completely
846cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall      // destroying the internal invariants of the declarator here,
847cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall      // but it doesn't matter because we're done with it.
848cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall      cur->setNext(0);
849cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall      attrs.add(cur);
850cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall    }
851cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall  }
852cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall}
853cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall
854cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall/// takeDeclAttributes - Take all the decl attributes from the given
855cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall/// declarator and add them to the given list.
856cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCallstatic void takeDeclAttributes(ParsedAttributes &attrs,
857cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall                               Declarator &D) {
858cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall  // First, take ownership of all attributes.
859cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall  attrs.getPool().takeAllFrom(D.getAttributePool());
860cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall  attrs.getPool().takeAllFrom(D.getDeclSpec().getAttributePool());
861cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall
862cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall  // Now actually move the attributes over.
863cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall  takeDeclAttributes(attrs, D.getDeclSpec().getAttributes().getList());
864cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall  takeDeclAttributes(attrs, D.getAttributes());
865cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall  for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
866cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall    takeDeclAttributes(attrs,
867cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall                  const_cast<AttributeList*>(D.getTypeObject(i).getAttrs()));
868cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall}
869cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall
870e8b724d481c9547de2ee6f442be594b38ada452dChris Lattner///   objc-type-name:
871e8b724d481c9547de2ee6f442be594b38ada452dChris Lattner///     '(' objc-type-qualifiers[opt] type-name ')'
872e8b724d481c9547de2ee6f442be594b38ada452dChris Lattner///     '(' objc-type-qualifiers[opt] ')'
873e8b724d481c9547de2ee6f442be594b38ada452dChris Lattner///
874b77cab97f17f946744c920629ca17271308d8ebfDouglas GregorParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS,
875cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall                                     Declarator::TheContext context,
876cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall                                     ParsedAttributes *paramAttrs) {
877cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall  assert(context == Declarator::ObjCParameterContext ||
878cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall         context == Declarator::ObjCResultContext);
879cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall  assert((paramAttrs != 0) == (context == Declarator::ObjCParameterContext));
880cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall
881df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner  assert(Tok.is(tok::l_paren) && "expected (");
8821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8834a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_paren);
8844a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeOpen();
8854a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor
886e8904e992ca5e821b199c4577e8b5e5b17a33b1dChris Lattner  SourceLocation TypeStartLoc = Tok.getLocation();
8879735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian  ObjCDeclContextSwitch ObjCDC(*this);
8889735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian
88919d74e1494fe399f0e2a94e9419c095f8214851bFariborz Jahanian  // Parse type qualifiers, in, inout, etc.
890cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall  ParseObjCTypeQualifierList(DS, context);
8914fa7afd07421e7276d1717e4fdf43a5fdd65a622Steve Naroff
892b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType Ty;
893809070a886684cb5b92eb0e00a6581ab1fa6b17aDouglas Gregor  if (isTypeSpecifierQualifier()) {
894cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall    // Parse an abstract declarator.
895cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall    DeclSpec declSpec(AttrFactory);
896cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall    declSpec.setObjCQualifiers(&DS);
897cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall    ParseSpecifierQualifierList(declSpec);
8986d1de1b8663fe652903bda2927b885d1ec0f2613Fariborz Jahanian    declSpec.SetRangeEnd(Tok.getLocation());
899cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall    Declarator declarator(declSpec, context);
900cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall    ParseDeclarator(declarator);
901cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall
902cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall    // If that's not invalid, extract a type.
903cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall    if (!declarator.isInvalidType()) {
904cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall      TypeResult type = Actions.ActOnTypeName(getCurScope(), declarator);
905cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall      if (!type.isInvalid())
906cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall        Ty = type.get();
907cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall
908cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall      // If we're parsing a parameter, steal all the decl attributes
909cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall      // and add them to the decl spec.
910cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall      if (context == Declarator::ObjCParameterContext)
911cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall        takeDeclAttributes(*paramAttrs, declarator);
912cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall    }
913cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall  } else if (context == Declarator::ObjCResultContext &&
914cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall             Tok.is(tok::identifier)) {
915e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor    if (!Ident_instancetype)
916e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor      Ident_instancetype = PP.getIdentifierInfo("instancetype");
917e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor
918e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor    if (Tok.getIdentifierInfo() == Ident_instancetype) {
919e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor      Ty = Actions.ActOnObjCInstanceType(Tok.getLocation());
920e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor      ConsumeToken();
921e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor    }
922809070a886684cb5b92eb0e00a6581ab1fa6b17aDouglas Gregor  }
923e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor
9244a76b292c9c3f60a257636e21d76b6ce1c12f8c4Chris Lattner  if (Tok.is(tok::r_paren))
9254a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    T.consumeClose();
9264a76b292c9c3f60a257636e21d76b6ce1c12f8c4Chris Lattner  else if (Tok.getLocation() == TypeStartLoc) {
927e8904e992ca5e821b199c4577e8b5e5b17a33b1dChris Lattner    // If we didn't eat any tokens, then this isn't a type.
9281ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_type);
9294a76b292c9c3f60a257636e21d76b6ce1c12f8c4Chris Lattner    SkipUntil(tok::r_paren);
9304a76b292c9c3f60a257636e21d76b6ce1c12f8c4Chris Lattner  } else {
9314a76b292c9c3f60a257636e21d76b6ce1c12f8c4Chris Lattner    // Otherwise, we found *something*, but didn't get a ')' in the right
9324a76b292c9c3f60a257636e21d76b6ce1c12f8c4Chris Lattner    // place.  Emit an error then return what we have as the type.
9334a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    T.consumeClose();
934294494e1cce92043562b4680c613df7fd028c02eSteve Naroff  }
935f28b264437053fb0deacc9ba02b18a0966f7290aSteve Naroff  return Ty;
936294494e1cce92043562b4680c613df7fd028c02eSteve Naroff}
937294494e1cce92043562b4680c613df7fd028c02eSteve Naroff
938294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///   objc-method-decl:
939294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///     objc-selector
9404985aceceb9b9261b876b515d32726175c13a775Steve Naroff///     objc-keyword-selector objc-parmlist[opt]
941294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///     objc-type-name objc-selector
9424985aceceb9b9261b876b515d32726175c13a775Steve Naroff///     objc-type-name objc-keyword-selector objc-parmlist[opt]
943294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///
944294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///   objc-keyword-selector:
9451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///     objc-keyword-decl
946294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///     objc-keyword-selector objc-keyword-decl
947294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///
948294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///   objc-keyword-decl:
9497ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff///     objc-selector ':' objc-type-name objc-keyword-attributes[opt] identifier
9507ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff///     objc-selector ':' objc-keyword-attributes[opt] identifier
9517ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff///     ':' objc-type-name objc-keyword-attributes[opt] identifier
9527ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff///     ':' objc-keyword-attributes[opt] identifier
953294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///
9544985aceceb9b9261b876b515d32726175c13a775Steve Naroff///   objc-parmlist:
9554985aceceb9b9261b876b515d32726175c13a775Steve Naroff///     objc-parms objc-ellipsis[opt]
956294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///
9574985aceceb9b9261b876b515d32726175c13a775Steve Naroff///   objc-parms:
9584985aceceb9b9261b876b515d32726175c13a775Steve Naroff///     objc-parms , parameter-declaration
959294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///
9604985aceceb9b9261b876b515d32726175c13a775Steve Naroff///   objc-ellipsis:
961294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///     , ...
962294494e1cce92043562b4680c613df7fd028c02eSteve Naroff///
9637ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff///   objc-keyword-attributes:         [OBJC2]
9647ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff///     __attribute__((unused))
9657ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff///
966d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
9672ccccb3ff40c64927817a7e1ddf1da8c188ed224Douglas Gregor                                  tok::TokenKind mType,
96890ba78c64d0c24cfbc1bf88728db9775d44d7f9fFariborz Jahanian                                  tok::ObjCKeywordKind MethodImplKind,
96990ba78c64d0c24cfbc1bf88728db9775d44d7f9fFariborz Jahanian                                  bool MethodDefinition) {
9709257664568bf375b7790131a84d9a4fa30a5b7e3John McCall  ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
97154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
972e8f5a1710a7738deff40e10efcd05b1bd6af184fDouglas Gregor  if (Tok.is(tok::code_completion)) {
97323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus,
974a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian                                       /*ReturnType=*/ ParsedType());
9757d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
9767d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return 0;
977e8f5a1710a7738deff40e10efcd05b1bd6af184fDouglas Gregor  }
978e8f5a1710a7738deff40e10efcd05b1bd6af184fDouglas Gregor
979e8904e992ca5e821b199c4577e8b5e5b17a33b1dChris Lattner  // Parse the return type if present.
980b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType ReturnType;
981a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCDeclSpec DSRet;
982df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner  if (Tok.is(tok::l_paren))
983cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall    ReturnType = ParseObjCTypeName(DSRet, Declarator::ObjCResultContext, 0);
9841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9859e0493576af77dba1c48858c03e31a2897d0681eTed Kremenek  // If attributes exist before the method, parse them.
9860b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributes methodAttrs(AttrFactory);
9874e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().ObjC2)
9880b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall    MaybeParseGNUAttributes(methodAttrs);
9899e0493576af77dba1c48858c03e31a2897d0681eTed Kremenek
990e8f5a1710a7738deff40e10efcd05b1bd6af184fDouglas Gregor  if (Tok.is(tok::code_completion)) {
99123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus,
992a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian                                       ReturnType);
9937d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
9947d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return 0;
995e8f5a1710a7738deff40e10efcd05b1bd6af184fDouglas Gregor  }
996e8f5a1710a7738deff40e10efcd05b1bd6af184fDouglas Gregor
9979e0493576af77dba1c48858c03e31a2897d0681eTed Kremenek  // Now parse the selector.
998bef1185418705e16012b3dd50cd7c260c8d6b79cSteve Naroff  SourceLocation selLoc;
9992fc5c2428ecb450a3256c8316b93b8655cb76a0fChris Lattner  IdentifierInfo *SelIdent = ParseObjCSelectorPiece(selLoc);
1000e8904e992ca5e821b199c4577e8b5e5b17a33b1dChris Lattner
100184c431088693e216193094d1dbf327a01173f57fSteve Naroff  // An unnamed colon is valid.
100284c431088693e216193094d1dbf327a01173f57fSteve Naroff  if (!SelIdent && Tok.isNot(tok::colon)) { // missing selector name.
10031ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_selector_for_method)
10041ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner      << SourceRange(mLoc, Tok.getLocation());
1005d30ec7076fef736754206ac87a4f2c67251cc4d8Fariborz Jahanian    // Skip until we get a ; or @.
1006d30ec7076fef736754206ac87a4f2c67251cc4d8Fariborz Jahanian    SkipUntil(tok::at, true /*StopAtSemi*/, true /*don't consume*/);
1007d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
1008e8904e992ca5e821b199c4577e8b5e5b17a33b1dChris Lattner  }
10091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10105f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<DeclaratorChunk::ParamInfo, 8> CParamInfo;
1011df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner  if (Tok.isNot(tok::colon)) {
1012ff38491c18b060526d754765b952f4a497a89416Chris Lattner    // If attributes exist after the method, parse them.
10134e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (getLangOpts().ObjC2)
10140b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall      MaybeParseGNUAttributes(methodAttrs);
10151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1016ff38491c18b060526d754765b952f4a497a89416Chris Lattner    Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
1017d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    Decl *Result
10187f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian         = Actions.ActOnMethodDeclaration(getCurScope(), mLoc, Tok.getLocation(),
1019a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian                                          mType, DSRet, ReturnType,
1020926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                          selLoc, Sel, 0,
10214f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian                                          CParamInfo.data(), CParamInfo.size(),
10220b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall                                          methodAttrs.getList(), MethodImplKind,
10230b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall                                          false, MethodDefinition);
102454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    PD.complete(Result);
102554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    return Result;
1026ff38491c18b060526d754765b952f4a497a89416Chris Lattner  }
1027f28b264437053fb0deacc9ba02b18a0966f7290aSteve Naroff
10285f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<IdentifierInfo *, 12> KeyIdents;
102911d77169555480ee0a04c6e5bc390d8fde41175dArgyrios Kyrtzidis  SmallVector<SourceLocation, 12> KeyLocs;
10305f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<Sema::ObjCArgInfo, 12> ArgInfos;
10317f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian  ParseScope PrototypeScope(this,
10327f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian                            Scope::FunctionPrototypeScope|Scope::DeclScope);
10330b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall
10340b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  AttributePool allParamAttrs(AttrFactory);
1035ff38491c18b060526d754765b952f4a497a89416Chris Lattner  while (1) {
10360b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall    ParsedAttributes paramAttrs(AttrFactory);
1037f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    Sema::ObjCArgInfo ArgInfo;
10381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1039ff38491c18b060526d754765b952f4a497a89416Chris Lattner    // Each iteration parses a single keyword argument.
1040df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner    if (Tok.isNot(tok::colon)) {
1041ff38491c18b060526d754765b952f4a497a89416Chris Lattner      Diag(Tok, diag::err_expected_colon);
1042ff38491c18b060526d754765b952f4a497a89416Chris Lattner      break;
1043ff38491c18b060526d754765b952f4a497a89416Chris Lattner    }
1044ff38491c18b060526d754765b952f4a497a89416Chris Lattner    ConsumeToken(); // Eat the ':'.
10451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1046b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall    ArgInfo.Type = ParsedType();
1047e294d3fbaffcbc0cf5f16067ab31d2b2763d25e9Chris Lattner    if (Tok.is(tok::l_paren)) // Parse the argument type if present.
1048cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall      ArgInfo.Type = ParseObjCTypeName(ArgInfo.DeclSpec,
1049cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall                                       Declarator::ObjCParameterContext,
1050cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall                                       &paramAttrs);
1051e294d3fbaffcbc0cf5f16067ab31d2b2763d25e9Chris Lattner
1052ff38491c18b060526d754765b952f4a497a89416Chris Lattner    // If attributes exist before the argument name, parse them.
1053cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall    // Regardless, collect all the attributes we've parsed so far.
1054e294d3fbaffcbc0cf5f16067ab31d2b2763d25e9Chris Lattner    ArgInfo.ArgAttrs = 0;
10554e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (getLangOpts().ObjC2) {
10560b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall      MaybeParseGNUAttributes(paramAttrs);
10570b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall      ArgInfo.ArgAttrs = paramAttrs.getList();
10587f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    }
10597ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff
106040ed9a13f5b67b2941f5a9521616e57e9e31ba97Douglas Gregor    // Code completion for the next piece of the selector.
106140ed9a13f5b67b2941f5a9521616e57e9e31ba97Douglas Gregor    if (Tok.is(tok::code_completion)) {
106240ed9a13f5b67b2941f5a9521616e57e9e31ba97Douglas Gregor      KeyIdents.push_back(SelIdent);
106340ed9a13f5b67b2941f5a9521616e57e9e31ba97Douglas Gregor      Actions.CodeCompleteObjCMethodDeclSelector(getCurScope(),
106440ed9a13f5b67b2941f5a9521616e57e9e31ba97Douglas Gregor                                                 mType == tok::minus,
106540ed9a13f5b67b2941f5a9521616e57e9e31ba97Douglas Gregor                                                 /*AtParameterName=*/true,
106640ed9a13f5b67b2941f5a9521616e57e9e31ba97Douglas Gregor                                                 ReturnType,
106740ed9a13f5b67b2941f5a9521616e57e9e31ba97Douglas Gregor                                                 KeyIdents.data(),
106840ed9a13f5b67b2941f5a9521616e57e9e31ba97Douglas Gregor                                                 KeyIdents.size());
10697d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      cutOffParsing();
10707d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      return 0;
107140ed9a13f5b67b2941f5a9521616e57e9e31ba97Douglas Gregor    }
107240ed9a13f5b67b2941f5a9521616e57e9e31ba97Douglas Gregor
1073df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner    if (Tok.isNot(tok::identifier)) {
1074ff38491c18b060526d754765b952f4a497a89416Chris Lattner      Diag(Tok, diag::err_expected_ident); // missing argument name.
1075ff38491c18b060526d754765b952f4a497a89416Chris Lattner      break;
10764985aceceb9b9261b876b515d32726175c13a775Steve Naroff    }
10771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1078e294d3fbaffcbc0cf5f16067ab31d2b2763d25e9Chris Lattner    ArgInfo.Name = Tok.getIdentifierInfo();
1079e294d3fbaffcbc0cf5f16067ab31d2b2763d25e9Chris Lattner    ArgInfo.NameLoc = Tok.getLocation();
1080ff38491c18b060526d754765b952f4a497a89416Chris Lattner    ConsumeToken(); // Eat the identifier.
10811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1082e294d3fbaffcbc0cf5f16067ab31d2b2763d25e9Chris Lattner    ArgInfos.push_back(ArgInfo);
1083e294d3fbaffcbc0cf5f16067ab31d2b2763d25e9Chris Lattner    KeyIdents.push_back(SelIdent);
108411d77169555480ee0a04c6e5bc390d8fde41175dArgyrios Kyrtzidis    KeyLocs.push_back(selLoc);
1085e294d3fbaffcbc0cf5f16067ab31d2b2763d25e9Chris Lattner
10860b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall    // Make sure the attributes persist.
10870b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall    allParamAttrs.takeAllFrom(paramAttrs.getPool());
10880b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall
10891f5537aaac1e775aff1d523f2cc59a9a3bd6c946Douglas Gregor    // Code completion for the next piece of the selector.
10901f5537aaac1e775aff1d523f2cc59a9a3bd6c946Douglas Gregor    if (Tok.is(tok::code_completion)) {
10911f5537aaac1e775aff1d523f2cc59a9a3bd6c946Douglas Gregor      Actions.CodeCompleteObjCMethodDeclSelector(getCurScope(),
10921f5537aaac1e775aff1d523f2cc59a9a3bd6c946Douglas Gregor                                                 mType == tok::minus,
109340ed9a13f5b67b2941f5a9521616e57e9e31ba97Douglas Gregor                                                 /*AtParameterName=*/false,
10941f5537aaac1e775aff1d523f2cc59a9a3bd6c946Douglas Gregor                                                 ReturnType,
10951f5537aaac1e775aff1d523f2cc59a9a3bd6c946Douglas Gregor                                                 KeyIdents.data(),
10961f5537aaac1e775aff1d523f2cc59a9a3bd6c946Douglas Gregor                                                 KeyIdents.size());
10977d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      cutOffParsing();
10987d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      return 0;
10991f5537aaac1e775aff1d523f2cc59a9a3bd6c946Douglas Gregor    }
11001f5537aaac1e775aff1d523f2cc59a9a3bd6c946Douglas Gregor
1101ff38491c18b060526d754765b952f4a497a89416Chris Lattner    // Check for another keyword selector.
110211d77169555480ee0a04c6e5bc390d8fde41175dArgyrios Kyrtzidis    SelIdent = ParseObjCSelectorPiece(selLoc);
1103b648cf02f13ae74ec346f8d22933298f9977e4e0Ted Kremenek    if (!SelIdent && Tok.isNot(tok::colon))
1104b648cf02f13ae74ec346f8d22933298f9977e4e0Ted Kremenek      break;
110503ebd3b4af9e4ab8e14a3f136d8a28df463f54ecFariborz Jahanian    if (!SelIdent) {
110608602359845e668194d111b794b8965358babfe6Fariborz Jahanian      SourceLocation ColonLoc = Tok.getLocation();
110708602359845e668194d111b794b8965358babfe6Fariborz Jahanian      if (PP.getLocForEndOfToken(ArgInfo.NameLoc) == ColonLoc) {
110803ebd3b4af9e4ab8e14a3f136d8a28df463f54ecFariborz Jahanian        Diag(ArgInfo.NameLoc, diag::warn_missing_selector_name) << ArgInfo.Name;
110903ebd3b4af9e4ab8e14a3f136d8a28df463f54ecFariborz Jahanian        Diag(ArgInfo.NameLoc, diag::note_missing_selector_name) << ArgInfo.Name;
111003ebd3b4af9e4ab8e14a3f136d8a28df463f54ecFariborz Jahanian        Diag(ColonLoc, diag::note_force_empty_selector_name) << ArgInfo.Name;
111108602359845e668194d111b794b8965358babfe6Fariborz Jahanian      }
111208602359845e668194d111b794b8965358babfe6Fariborz Jahanian    }
1113ff38491c18b060526d754765b952f4a497a89416Chris Lattner    // We have a selector or a colon, continue parsing.
1114ff38491c18b060526d754765b952f4a497a89416Chris Lattner  }
11151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1116335eafa5be51f6440672a74c73d588af72e96732Steve Naroff  bool isVariadic = false;
111756242baaae6c45b24fbdd5bc56fe4ee516fa9e6bFariborz Jahanian  bool cStyleParamWarned = false;
1118ff38491c18b060526d754765b952f4a497a89416Chris Lattner  // Parse the (optional) parameter list.
1119df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner  while (Tok.is(tok::comma)) {
1120ff38491c18b060526d754765b952f4a497a89416Chris Lattner    ConsumeToken();
1121df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner    if (Tok.is(tok::ellipsis)) {
1122335eafa5be51f6440672a74c73d588af72e96732Steve Naroff      isVariadic = true;
11234985aceceb9b9261b876b515d32726175c13a775Steve Naroff      ConsumeToken();
1124ff38491c18b060526d754765b952f4a497a89416Chris Lattner      break;
11254985aceceb9b9261b876b515d32726175c13a775Steve Naroff    }
112656242baaae6c45b24fbdd5bc56fe4ee516fa9e6bFariborz Jahanian    if (!cStyleParamWarned) {
112756242baaae6c45b24fbdd5bc56fe4ee516fa9e6bFariborz Jahanian      Diag(Tok, diag::warn_cstyle_param);
112856242baaae6c45b24fbdd5bc56fe4ee516fa9e6bFariborz Jahanian      cStyleParamWarned = true;
112956242baaae6c45b24fbdd5bc56fe4ee516fa9e6bFariborz Jahanian    }
11300b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall    DeclSpec DS(AttrFactory);
1131ff38491c18b060526d754765b952f4a497a89416Chris Lattner    ParseDeclarationSpecifiers(DS);
11321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // Parse the declarator.
1133ff38491c18b060526d754765b952f4a497a89416Chris Lattner    Declarator ParmDecl(DS, Declarator::PrototypeContext);
1134ff38491c18b060526d754765b952f4a497a89416Chris Lattner    ParseDeclarator(ParmDecl);
11354f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian    IdentifierInfo *ParmII = ParmDecl.getIdentifier();
1136d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl);
11374f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian    CParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
11384f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian                                                    ParmDecl.getIdentifierLoc(),
11394f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian                                                    Param,
11404f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian                                                   0));
11414985aceceb9b9261b876b515d32726175c13a775Steve Naroff  }
11421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11439c4bb2c08989265411925a04252fd4f93c26e3b1Cameron Esfahani  // FIXME: Add support for optional parameter list...
1144e3a2ca7e30601cdd31c77a830f4cc487851e8096Fariborz Jahanian  // If attributes exist after the method, parse them.
11454e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().ObjC2)
11460b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall    MaybeParseGNUAttributes(methodAttrs);
11477f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian
1148a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian  if (KeyIdents.size() == 0)
1149d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
11507f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian
1151ff38491c18b060526d754765b952f4a497a89416Chris Lattner  Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(),
1152ff38491c18b060526d754765b952f4a497a89416Chris Lattner                                                   &KeyIdents[0]);
1153d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  Decl *Result
11547f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian       = Actions.ActOnMethodDeclaration(getCurScope(), mLoc, Tok.getLocation(),
1155a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian                                        mType, DSRet, ReturnType,
115611d77169555480ee0a04c6e5bc390d8fde41175dArgyrios Kyrtzidis                                        KeyLocs, Sel, &ArgInfos[0],
11574f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian                                        CParamInfo.data(), CParamInfo.size(),
11580b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall                                        methodAttrs.getList(),
115990ba78c64d0c24cfbc1bf88728db9775d44d7f9fFariborz Jahanian                                        MethodImplKind, isVariadic, MethodDefinition);
11607f53253223b29d77f1e9c5c0ce93a19932761b77Fariborz Jahanian
116154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  PD.complete(Result);
116254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  return Result;
1163294494e1cce92043562b4680c613df7fd028c02eSteve Naroff}
1164294494e1cce92043562b4680c613df7fd028c02eSteve Naroff
1165dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///   objc-protocol-refs:
1166dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     '<' identifier-list '>'
1167dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///
11687caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattnerbool Parser::
11695f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerParseObjCProtocolReferences(SmallVectorImpl<Decl *> &Protocols,
11705f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                            SmallVectorImpl<SourceLocation> &ProtocolLocs,
117171b0addffbdeed29cc062c962e236c34107755d6Argyrios Kyrtzidis                            bool WarnOnDeclarations,
117271b0addffbdeed29cc062c962e236c34107755d6Argyrios Kyrtzidis                            SourceLocation &LAngleLoc, SourceLocation &EndLoc) {
1173e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner  assert(Tok.is(tok::less) && "expected <");
11741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
117571b0addffbdeed29cc062c962e236c34107755d6Argyrios Kyrtzidis  LAngleLoc = ConsumeToken(); // the "<"
11761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11775f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<IdentifierLocPair, 8> ProtocolIdents;
11781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1179e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner  while (1) {
118055385fe3e723cd675001e45f42d61adde6b7f075Douglas Gregor    if (Tok.is(tok::code_completion)) {
118155385fe3e723cd675001e45f42d61adde6b7f075Douglas Gregor      Actions.CodeCompleteObjCProtocolReferences(ProtocolIdents.data(),
118255385fe3e723cd675001e45f42d61adde6b7f075Douglas Gregor                                                 ProtocolIdents.size());
11837d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      cutOffParsing();
11847d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      return true;
118555385fe3e723cd675001e45f42d61adde6b7f075Douglas Gregor    }
118655385fe3e723cd675001e45f42d61adde6b7f075Douglas Gregor
1187e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner    if (Tok.isNot(tok::identifier)) {
1188e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner      Diag(Tok, diag::err_expected_ident);
1189e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner      SkipUntil(tok::greater);
1190e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner      return true;
1191e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner    }
1192e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner    ProtocolIdents.push_back(std::make_pair(Tok.getIdentifierInfo(),
1193e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner                                       Tok.getLocation()));
119471b0addffbdeed29cc062c962e236c34107755d6Argyrios Kyrtzidis    ProtocolLocs.push_back(Tok.getLocation());
1195e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner    ConsumeToken();
11961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1197e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner    if (Tok.isNot(tok::comma))
1198e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner      break;
1199e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner    ConsumeToken();
1200e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner  }
12011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1202e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner  // Consume the '>'.
1203b707a4762fcc47c12b5f487856ba0781c9399295Nico Weber  if (ParseGreaterThanInTemplateList(EndLoc, /*ConsumeLastToken=*/true))
1204e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner    return true;
12051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1206e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner  // Convert the list of protocols identifiers into a list of protocol decls.
1207e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner  Actions.FindProtocolDeclaration(WarnOnDeclarations,
1208e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner                                  &ProtocolIdents[0], ProtocolIdents.size(),
1209e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner                                  Protocols);
1210e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner  return false;
1211e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner}
1212e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner
12139bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor/// \brief Parse the Objective-C protocol qualifiers that follow a typename
12149bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor/// in a decl-specifier-seq, starting at the '<'.
121546f936e055d763437accd1e5a1bc49e7e5dbc0a3Douglas Gregorbool Parser::ParseObjCProtocolQualifiers(DeclSpec &DS) {
12169bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor  assert(Tok.is(tok::less) && "Protocol qualifiers start with '<'");
12174e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  assert(getLangOpts().ObjC1 && "Protocol qualifiers only exist in Objective-C");
12189bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor  SourceLocation LAngleLoc, EndProtoLoc;
12195f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<Decl *, 8> ProtocolDecl;
12205f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<SourceLocation, 8> ProtocolLocs;
122146f936e055d763437accd1e5a1bc49e7e5dbc0a3Douglas Gregor  bool Result = ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false,
122246f936e055d763437accd1e5a1bc49e7e5dbc0a3Douglas Gregor                                            LAngleLoc, EndProtoLoc);
12239bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor  DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size(),
12249bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor                           ProtocolLocs.data(), LAngleLoc);
12259bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor  if (EndProtoLoc.isValid())
12269bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor    DS.SetRangeEnd(EndProtoLoc);
122746f936e055d763437accd1e5a1bc49e7e5dbc0a3Douglas Gregor  return Result;
12289bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor}
12299bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor
12309bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor
1231dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///   objc-class-instance-variables:
1232dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     '{' objc-instance-variable-decl-list[opt] '}'
1233dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///
1234dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///   objc-instance-variable-decl-list:
1235dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     objc-visibility-spec
1236dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     objc-instance-variable-decl ';'
1237dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     ';'
1238dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     objc-instance-variable-decl-list objc-visibility-spec
1239dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     objc-instance-variable-decl-list objc-instance-variable-decl ';'
1240dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     objc-instance-variable-decl-list ';'
1241dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///
1242dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///   objc-visibility-spec:
1243dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     @private
1244dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     @protected
1245dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     @public
1246ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff///     @package [OBJC2]
1247dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///
1248dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///   objc-instance-variable-decl:
12491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///     struct-declaration
1250dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///
1251d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl,
125283c481ade785a919ba21a33f9a8b1b21c1212fb3Fariborz Jahanian                                             tok::ObjCKeywordKind visibility,
125360fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff                                             SourceLocation atLoc) {
1254df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner  assert(Tok.is(tok::l_brace) && "expected {");
12555f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<Decl *, 32> AllIvarDecls;
1256a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian
12571a0d31a3d7f14ddc6370ba912c778aece6c12cf0Douglas Gregor  ParseScope ClassScope(this, Scope::DeclScope|Scope::ClassScope);
12583a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis  ObjCDeclContextSwitch ObjCDC(*this);
125972de6676bd30f9081ee4166bbe07b4c270258ce6Douglas Gregor
12604a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_brace);
12614a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeOpen();
12621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1263ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff  // While we still have something to read, read the instance variables.
1264df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
1265ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff    // Each iteration of this loop reads one objc-instance-variable-decl.
12661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1267ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff    // Check for extraneous top-level semicolon.
1268df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner    if (Tok.is(tok::semi)) {
12694b0e6f1da341510c1ad83eaf4c836f3134d0156aRichard Trieu      ConsumeExtraSemi(InstanceVariableList);
1270ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff      continue;
1271ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff    }
12721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1273ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff    // Set the default visibility to private.
1274df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner    if (Tok.is(tok::at)) { // parse objc-visibility-spec
1275ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff      ConsumeToken(); // eat the @ sign
1276c38c3e1e726630458154534227d74eda833d26a0Douglas Gregor
1277c38c3e1e726630458154534227d74eda833d26a0Douglas Gregor      if (Tok.is(tok::code_completion)) {
127823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        Actions.CodeCompleteObjCAtVisibility(getCurScope());
12797d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis        return cutOffParsing();
1280c38c3e1e726630458154534227d74eda833d26a0Douglas Gregor      }
1281c38c3e1e726630458154534227d74eda833d26a0Douglas Gregor
1282861cf3effdc0fbc97d401539bc3050da76b2476fSteve Naroff      switch (Tok.getObjCKeywordID()) {
1283ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff      case tok::objc_private:
1284ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff      case tok::objc_public:
1285ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff      case tok::objc_protected:
1286ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff      case tok::objc_package:
1287861cf3effdc0fbc97d401539bc3050da76b2476fSteve Naroff        visibility = Tok.getObjCKeywordID();
1288ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff        ConsumeToken();
12891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        continue;
1290ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff      default:
1291ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff        Diag(Tok, diag::err_objc_illegal_visibility_spec);
1292ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff        continue;
1293ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff      }
1294ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff    }
12951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1296c38c3e1e726630458154534227d74eda833d26a0Douglas Gregor    if (Tok.is(tok::code_completion)) {
129723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      Actions.CodeCompleteOrdinaryName(getCurScope(),
1298f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                       Sema::PCC_ObjCInstanceVariableList);
12997d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      return cutOffParsing();
1300c38c3e1e726630458154534227d74eda833d26a0Douglas Gregor    }
1301c38c3e1e726630458154534227d74eda833d26a0Douglas Gregor
1302bdd563ec391b0a83fc6d04b8a8ea3022aa702f74John McCall    struct ObjCIvarCallback : FieldCallback {
1303bdd563ec391b0a83fc6d04b8a8ea3022aa702f74John McCall      Parser &P;
1304d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall      Decl *IDecl;
1305bdd563ec391b0a83fc6d04b8a8ea3022aa702f74John McCall      tok::ObjCKeywordKind visibility;
13065f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner      SmallVectorImpl<Decl *> &AllIvarDecls;
1307bdd563ec391b0a83fc6d04b8a8ea3022aa702f74John McCall
1308d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall      ObjCIvarCallback(Parser &P, Decl *IDecl, tok::ObjCKeywordKind V,
13095f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                       SmallVectorImpl<Decl *> &AllIvarDecls) :
1310bdd563ec391b0a83fc6d04b8a8ea3022aa702f74John McCall        P(P), IDecl(IDecl), visibility(V), AllIvarDecls(AllIvarDecls) {
1311bdd563ec391b0a83fc6d04b8a8ea3022aa702f74John McCall      }
1312bdd563ec391b0a83fc6d04b8a8ea3022aa702f74John McCall
1313dcdff46dd8e6d749283fe6c43adfcfe780c1d562Eli Friedman      void invoke(ParsingFieldDeclarator &FD) {
1314a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian        P.Actions.ActOnObjCContainerStartDefinition(IDecl);
1315bdd563ec391b0a83fc6d04b8a8ea3022aa702f74John McCall        // Install the declarator into the interface decl.
1316d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall        Decl *Field
131723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor          = P.Actions.ActOnIvar(P.getCurScope(),
1318bdd563ec391b0a83fc6d04b8a8ea3022aa702f74John McCall                                FD.D.getDeclSpec().getSourceRange().getBegin(),
1319a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian                                FD.D, FD.BitfieldSize, visibility);
132010af87932fe4bffad539b24d512a33a1803daeaeFariborz Jahanian        P.Actions.ActOnObjCContainerFinishDefinition();
13210bd04596e4645ff145a046dfb3475f39674060d9Fariborz Jahanian        if (Field)
13220bd04596e4645ff145a046dfb3475f39674060d9Fariborz Jahanian          AllIvarDecls.push_back(Field);
1323f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman        FD.complete(Field);
1324bdd563ec391b0a83fc6d04b8a8ea3022aa702f74John McCall      }
1325bdd563ec391b0a83fc6d04b8a8ea3022aa702f74John McCall    } Callback(*this, interfaceDecl, visibility, AllIvarDecls);
1326d097be8f81fbf4ed96ac10bae18562dd8202666bFariborz Jahanian
1327e13594279a952537ac903325efff57e3edca79d9Chris Lattner    // Parse all the comma separated declarators.
1328f66a0dda541cd859a928193efba6dc5d7ba8fe54Eli Friedman    ParsingDeclSpec DS(*this);
1329bdd563ec391b0a83fc6d04b8a8ea3022aa702f74John McCall    ParseStructDeclaration(DS, Callback);
13301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1331df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner    if (Tok.is(tok::semi)) {
1332ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff      ConsumeToken();
1333ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff    } else {
1334ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff      Diag(Tok, diag::err_expected_semi_decl_list);
1335ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff      // Skip to end of block or statement
1336ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff      SkipUntil(tok::r_brace, true, true);
1337ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff    }
1338ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff  }
13394a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
13404a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor
1341a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian  Actions.ActOnObjCContainerStartDefinition(interfaceDecl);
13424a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  Actions.ActOnLastBitfield(T.getCloseLocation(), AllIvarDecls);
134310af87932fe4bffad539b24d512a33a1803daeaeFariborz Jahanian  Actions.ActOnObjCContainerFinishDefinition();
13448749be53f53384e7846502791ceda6c657228d07Steve Naroff  // Call ActOnFields() even if we don't have any decls. This is useful
13458749be53f53384e7846502791ceda6c657228d07Steve Naroff  // for code rewriting tools that need to be aware of the empty list.
134623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  Actions.ActOnFields(getCurScope(), atLoc, interfaceDecl,
134777b6de07be9186063c12928d2e9785a5d4eecbf6David Blaikie                      AllIvarDecls,
13484a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                      T.getOpenLocation(), T.getCloseLocation(), 0);
1349ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff  return;
13505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1351dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff
1352dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///   objc-protocol-declaration:
1353dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     objc-protocol-definition
1354dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     objc-protocol-forward-reference
1355dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///
1356dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///   objc-protocol-definition:
135717d26a6c1f2cb921d0000c337b4967699dc928fdJames Dennett///     \@protocol identifier
13581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///       objc-protocol-refs[opt]
13591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///       objc-interface-decl-list
136017d26a6c1f2cb921d0000c337b4967699dc928fdJames Dennett///     \@end
1361dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///
1362dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///   objc-protocol-forward-reference:
136317d26a6c1f2cb921d0000c337b4967699dc928fdJames Dennett///     \@protocol identifier-list ';'
1364dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///
136517d26a6c1f2cb921d0000c337b4967699dc928fdJames Dennett///   "\@protocol identifier ;" should be resolved as "\@protocol
13663536b443bc50d58a79f14fca9b6842541a434854Steve Naroff///   identifier-list ;": objc-interface-decl-list may not start with a
1367dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///   semicolon in the first alternative if objc-protocol-refs are omitted.
1368bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas GregorParser::DeclGroupPtrTy
1369bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas GregorParser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
1370bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas Gregor                                       ParsedAttributes &attrs) {
1371861cf3effdc0fbc97d401539bc3050da76b2476fSteve Naroff  assert(Tok.isObjCAtKeyword(tok::objc_protocol) &&
13727ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff         "ParseObjCAtProtocolDeclaration(): Expected @protocol");
13737ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff  ConsumeToken(); // the "protocol" identifier
13741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1375083128f6b13dfa4fc615a838c49b516d901b1ac0Douglas Gregor  if (Tok.is(tok::code_completion)) {
137623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteObjCProtocolDecl(getCurScope());
13777d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
1378bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas Gregor    return DeclGroupPtrTy();
1379083128f6b13dfa4fc615a838c49b516d901b1ac0Douglas Gregor  }
1380083128f6b13dfa4fc615a838c49b516d901b1ac0Douglas Gregor
1381df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner  if (Tok.isNot(tok::identifier)) {
13827ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff    Diag(Tok, diag::err_expected_ident); // missing protocol name.
1383bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas Gregor    return DeclGroupPtrTy();
13847ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff  }
13857ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff  // Save the protocol name, then consume it.
13867ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff  IdentifierInfo *protocolName = Tok.getIdentifierInfo();
13877ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff  SourceLocation nameLoc = ConsumeToken();
13881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1389df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner  if (Tok.is(tok::semi)) { // forward declaration of one protocol.
13907caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner    IdentifierLocPair ProtoInfo(protocolName, nameLoc);
13917ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff    ConsumeToken();
13921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return Actions.ActOnForwardProtocolDeclaration(AtLoc, &ProtoInfo, 1,
13937f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                                   attrs.getList());
13947ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff  }
13951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
139690ec96f3026480fa41057b05d58f338aed585f62Erik Verbruggen  CheckNestedObjCContexts(AtLoc);
139790ec96f3026480fa41057b05d58f338aed585f62Erik Verbruggen
1398df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner  if (Tok.is(tok::comma)) { // list of forward declarations.
13995f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    SmallVector<IdentifierLocPair, 8> ProtocolRefs;
14007caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner    ProtocolRefs.push_back(std::make_pair(protocolName, nameLoc));
14017caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner
14027ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff    // Parse the list of forward declarations.
14037ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff    while (1) {
14047ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff      ConsumeToken(); // the ','
1405df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner      if (Tok.isNot(tok::identifier)) {
14067ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff        Diag(Tok, diag::err_expected_ident);
14077ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff        SkipUntil(tok::semi);
1408bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas Gregor        return DeclGroupPtrTy();
14097ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff      }
14107caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner      ProtocolRefs.push_back(IdentifierLocPair(Tok.getIdentifierInfo(),
14117caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner                                               Tok.getLocation()));
14127ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff      ConsumeToken(); // the identifier
14131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1414df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner      if (Tok.isNot(tok::comma))
14157ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff        break;
14167ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff    }
14177ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff    // Consume the ';'.
14187ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff    if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@protocol"))
1419bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas Gregor      return DeclGroupPtrTy();
14201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1421e440eb8158e71deb1e4ab11618ae3d680aac6da1Steve Naroff    return Actions.ActOnForwardProtocolDeclaration(AtLoc,
14221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                                   &ProtocolRefs[0],
1423bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian                                                   ProtocolRefs.size(),
14247f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                                   attrs.getList());
14257caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner  }
14261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14277ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff  // Last, and definitely not least, parse a protocol declaration.
142871b0addffbdeed29cc062c962e236c34107755d6Argyrios Kyrtzidis  SourceLocation LAngleLoc, EndProtoLoc;
14297caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner
14305f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<Decl *, 8> ProtocolRefs;
14315f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<SourceLocation, 8> ProtocolLocs;
14327caeabd868d46cf4e68478c6e9136dae4e735d21Chris Lattner  if (Tok.is(tok::less) &&
143371b0addffbdeed29cc062c962e236c34107755d6Argyrios Kyrtzidis      ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, false,
143471b0addffbdeed29cc062c962e236c34107755d6Argyrios Kyrtzidis                                  LAngleLoc, EndProtoLoc))
1435bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas Gregor    return DeclGroupPtrTy();
14361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1437d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  Decl *ProtoType =
1438e13b9595dc1e2f4288bec34f3412359f648e84a5Chris Lattner    Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc,
1439beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad                                        ProtocolRefs.data(),
1440beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad                                        ProtocolRefs.size(),
144118df52bbb5d28ca082064d31ae7558dbdae52377Douglas Gregor                                        ProtocolLocs.data(),
14427f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                        EndProtoLoc, attrs.getList());
1443a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian
14442f64cfe19e8bf6b6ba1660e38da8c421440457feFariborz Jahanian  ParseObjCInterfaceDeclList(tok::objc_protocol, ProtoType);
1445bd9482d859a74bf2c45ef8b8aedec61c0e1c8374Douglas Gregor  return Actions.ConvertDeclToDeclGroup(ProtoType);
1446dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff}
1447dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff
1448dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///   objc-implementation:
1449dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     objc-class-implementation-prologue
1450dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     objc-category-implementation-prologue
1451dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///
1452dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///   objc-class-implementation-prologue:
1453dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     @implementation identifier objc-superclass[opt]
1454dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///       objc-class-instance-variables[opt]
1455dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///
1456dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///   objc-category-implementation-prologue:
1457dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff///     @implementation identifier ( identifier )
1458849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios KyrtzidisParser::DeclGroupPtrTy
1459849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios KyrtzidisParser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc) {
1460ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian  assert(Tok.isObjCAtKeyword(tok::objc_implementation) &&
1461ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian         "ParseObjCAtImplementationDeclaration(): Expected @implementation");
1462d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen  CheckNestedObjCContexts(AtLoc);
1463ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian  ConsumeToken(); // the "implementation" identifier
14641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14653b49aca913dc0c1838321b9bb2dc9a4cb4681922Douglas Gregor  // Code completion after '@implementation'.
14663b49aca913dc0c1838321b9bb2dc9a4cb4681922Douglas Gregor  if (Tok.is(tok::code_completion)) {
146723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteObjCImplementationDecl(getCurScope());
14687d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
1469849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis    return DeclGroupPtrTy();
14703b49aca913dc0c1838321b9bb2dc9a4cb4681922Douglas Gregor  }
14713b49aca913dc0c1838321b9bb2dc9a4cb4681922Douglas Gregor
1472df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner  if (Tok.isNot(tok::identifier)) {
1473ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian    Diag(Tok, diag::err_expected_ident); // missing class or category name.
1474849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis    return DeclGroupPtrTy();
1475ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian  }
1476ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian  // We have a class or category name - consume it.
1477ccb4f314248fb2202637d3290f2b17af5646da08Fariborz Jahanian  IdentifierInfo *nameId = Tok.getIdentifierInfo();
1478ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian  SourceLocation nameLoc = ConsumeToken(); // consume class or category name
1479849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis  Decl *ObjCImpDecl = 0;
14801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (Tok.is(tok::l_paren)) {
1482ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian    // we have a category implementation.
1483dec0984fce504a39a7f085774fb67cfd9957be58Jeffrey Yasskin    ConsumeParen();
1484ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian    SourceLocation categoryLoc, rparenLoc;
1485ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian    IdentifierInfo *categoryId = 0;
14861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
148733ced0b8550f3e7169f326944731ee02e9338659Douglas Gregor    if (Tok.is(tok::code_completion)) {
148823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      Actions.CodeCompleteObjCImplementationCategory(getCurScope(), nameId, nameLoc);
14897d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      cutOffParsing();
1490849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis      return DeclGroupPtrTy();
149133ced0b8550f3e7169f326944731ee02e9338659Douglas Gregor    }
149233ced0b8550f3e7169f326944731ee02e9338659Douglas Gregor
1493df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner    if (Tok.is(tok::identifier)) {
1494ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian      categoryId = Tok.getIdentifierInfo();
1495ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian      categoryLoc = ConsumeToken();
1496ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian    } else {
1497ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian      Diag(Tok, diag::err_expected_ident); // missing category name.
1498849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis      return DeclGroupPtrTy();
14991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
1500df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner    if (Tok.isNot(tok::r_paren)) {
1501ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian      Diag(Tok, diag::err_expected_rparen);
1502ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian      SkipUntil(tok::r_paren, false); // don't stop at ';'
1503849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis      return DeclGroupPtrTy();
1504ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian    }
1505ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian    rparenLoc = ConsumeParen();
1506849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis    ObjCImpDecl = Actions.ActOnStartCategoryImplementation(
1507d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen                                    AtLoc, nameId, nameLoc, categoryId,
15088f3fde00ad4d4f943321e338b914ae4740711c84Fariborz Jahanian                                    categoryLoc);
1509a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian
1510849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis  } else {
1511849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis    // We have a class implementation
1512849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis    SourceLocation superClassLoc;
1513849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis    IdentifierInfo *superClassId = 0;
1514849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis    if (Tok.is(tok::colon)) {
1515849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis      // We have a super class
1516849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis      ConsumeToken();
1517849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis      if (Tok.isNot(tok::identifier)) {
1518849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis        Diag(Tok, diag::err_expected_ident); // missing super class name.
1519849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis        return DeclGroupPtrTy();
1520849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis      }
1521849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis      superClassId = Tok.getIdentifierInfo();
1522849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis      superClassLoc = ConsumeToken(); // Consume super class name
1523ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian    }
1524849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis    ObjCImpDecl = Actions.ActOnStartClassImplementation(
1525849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis                                    AtLoc, nameId, nameLoc,
1526849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis                                    superClassId, superClassLoc);
1527849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis
1528849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis    if (Tok.is(tok::l_brace)) // we have ivars
1529849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis      ParseObjCClassInstanceVariables(ObjCImpDecl, tok::objc_private, AtLoc);
1530ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian  }
1531849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis  assert(ObjCImpDecl);
15321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1533849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis  SmallVector<Decl *, 8> DeclsInGroup;
1534a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian
1535849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis  {
1536849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis    ObjCImplParsingDataRAII ObjCImplParsing(*this, ObjCImpDecl);
1537849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis    while (!ObjCImplParsing.isFinished() && Tok.isNot(tok::eof)) {
1538849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis      ParsedAttributesWithRange attrs(AttrFactory);
15394e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith      MaybeParseCXX11Attributes(attrs);
1540849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis      MaybeParseMicrosoftAttributes(attrs);
1541849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis      if (DeclGroupPtrTy DGP = ParseExternalDeclaration(attrs)) {
1542849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis        DeclGroupRef DG = DGP.get();
1543849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis        DeclsInGroup.append(DG.begin(), DG.end());
1544849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis      }
1545849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis    }
1546849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis  }
1547849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis
1548644af7b50bd0541468b45c197f5b637e934d48a0Argyrios Kyrtzidis  return Actions.ActOnFinishObjCImplementation(ObjCImpDecl, DeclsInGroup);
15495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
155060fcceeedbfc8b4a99cb942e2bc5aeb9e2f92a1fSteve Naroff
1551140ab234c23f392d5422691c5de1ee3c15026defFariborz JahanianParser::DeclGroupPtrTy
1552140ab234c23f392d5422691c5de1ee3c15026defFariborz JahanianParser::ParseObjCAtEndDeclaration(SourceRange atEnd) {
1553ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian  assert(Tok.isObjCAtKeyword(tok::objc_end) &&
1554ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian         "ParseObjCAtEndDeclaration(): Expected @end");
1555ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian  ConsumeToken(); // the "end" identifier
1556849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis  if (CurParsedObjCImpl)
1557849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis    CurParsedObjCImpl->finish(atEnd);
15588697d308c1bdd50e5c45757ac11be701c26e9e97Fariborz Jahanian  else
1559782f2f52b78d8ca785110398a7f7b56b830b9ac7Ted Kremenek    // missing @implementation
1560d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen    Diag(atEnd.getBegin(), diag::err_expected_objc_container);
1561849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis  return DeclGroupPtrTy();
15625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1563e992af01d14e2e31037562c123af0a71ae1ed374Fariborz Jahanian
1564849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios KyrtzidisParser::ObjCImplParsingDataRAII::~ObjCImplParsingDataRAII() {
1565849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis  if (!Finished) {
1566849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis    finish(P.Tok.getLocation());
1567849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis    if (P.Tok.is(tok::eof)) {
1568849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis      P.Diag(P.Tok, diag::err_objc_missing_end)
1569849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis          << FixItHint::CreateInsertion(P.Tok.getLocation(), "\n@end\n");
1570849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis      P.Diag(Dcl->getLocStart(), diag::note_objc_container_start)
1571849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis          << Sema::OCK_Implementation;
1572849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis    }
1573849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis  }
1574849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis  P.CurParsedObjCImpl = 0;
1575849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis  assert(LateParsedObjCMethods.empty());
1576849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis}
1577d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen
1578849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidisvoid Parser::ObjCImplParsingDataRAII::finish(SourceRange AtEnd) {
1579849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis  assert(!Finished);
1580849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis  P.Actions.DefaultSynthesizeProperties(P.getCurScope(), Dcl);
1581849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis  for (size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
15826c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian    P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
15836c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian                               true/*Methods*/);
1584d64251fd56577dd5c78903454632361e094c6dc1Erik Verbruggen
1585849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis  P.Actions.ActOnAtEnd(P.getCurScope(), AtEnd);
158663e963cdffca9530f920dbab58b9b4eecb2a582cFariborz Jahanian
15876c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian  if (HasCFunction)
15886c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian    for (size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
15896c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian      P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
15906c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian                                 false/*c-functions*/);
15916c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian
1592849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis  /// \brief Clear and free the cached objc methods.
15932fea2242fe7e7c37df1e96316616febeaf4e29ebArgyrios Kyrtzidis  for (LateParsedObjCMethodContainer::iterator
15942fea2242fe7e7c37df1e96316616febeaf4e29ebArgyrios Kyrtzidis         I = LateParsedObjCMethods.begin(),
15952fea2242fe7e7c37df1e96316616febeaf4e29ebArgyrios Kyrtzidis         E = LateParsedObjCMethods.end(); I != E; ++I)
15962fea2242fe7e7c37df1e96316616febeaf4e29ebArgyrios Kyrtzidis    delete *I;
15972fea2242fe7e7c37df1e96316616febeaf4e29ebArgyrios Kyrtzidis  LateParsedObjCMethods.clear();
1598849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis
1599849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis  Finished = true;
16002fea2242fe7e7c37df1e96316616febeaf4e29ebArgyrios Kyrtzidis}
16012fea2242fe7e7c37df1e96316616febeaf4e29ebArgyrios Kyrtzidis
1602e992af01d14e2e31037562c123af0a71ae1ed374Fariborz Jahanian///   compatibility-alias-decl:
1603e992af01d14e2e31037562c123af0a71ae1ed374Fariborz Jahanian///     @compatibility_alias alias-name  class-name ';'
1604e992af01d14e2e31037562c123af0a71ae1ed374Fariborz Jahanian///
1605d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) {
1606e992af01d14e2e31037562c123af0a71ae1ed374Fariborz Jahanian  assert(Tok.isObjCAtKeyword(tok::objc_compatibility_alias) &&
1607e992af01d14e2e31037562c123af0a71ae1ed374Fariborz Jahanian         "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias");
1608e992af01d14e2e31037562c123af0a71ae1ed374Fariborz Jahanian  ConsumeToken(); // consume compatibility_alias
1609df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner  if (Tok.isNot(tok::identifier)) {
1610e992af01d14e2e31037562c123af0a71ae1ed374Fariborz Jahanian    Diag(Tok, diag::err_expected_ident);
1611d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
1612e992af01d14e2e31037562c123af0a71ae1ed374Fariborz Jahanian  }
1613243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  IdentifierInfo *aliasId = Tok.getIdentifierInfo();
1614243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  SourceLocation aliasLoc = ConsumeToken(); // consume alias-name
1615df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner  if (Tok.isNot(tok::identifier)) {
1616e992af01d14e2e31037562c123af0a71ae1ed374Fariborz Jahanian    Diag(Tok, diag::err_expected_ident);
1617d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
1618e992af01d14e2e31037562c123af0a71ae1ed374Fariborz Jahanian  }
1619243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  IdentifierInfo *classId = Tok.getIdentifierInfo();
1620243b64b0001172405ff803c61bdcaa8e98ec1552Fariborz Jahanian  SourceLocation classLoc = ConsumeToken(); // consume class-name;
1621e6bf90aec0044342ffccd13201b8a3a31a985a4bDouglas Gregor  ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
1622e6bf90aec0044342ffccd13201b8a3a31a985a4bDouglas Gregor                   "@compatibility_alias");
1623de01b7a6b4df27555ff7b25e51c0d3df29e3a0cfRichard Smith  return Actions.ActOnCompatibilityAlias(atLoc, aliasId, aliasLoc,
1624de01b7a6b4df27555ff7b25e51c0d3df29e3a0cfRichard Smith                                         classId, classLoc);
16255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
16265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1627ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian///   property-synthesis:
1628ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian///     @synthesize property-ivar-list ';'
1629ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian///
1630ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian///   property-ivar-list:
1631ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian///     property-ivar
1632ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian///     property-ivar-list ',' property-ivar
1633ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian///
1634ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian///   property-ivar:
1635ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian///     identifier
1636ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian///     identifier '=' identifier
1637ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian///
1638d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
1639ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian  assert(Tok.isObjCAtKeyword(tok::objc_synthesize) &&
1640ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian         "ParseObjCPropertyDynamic(): Expected '@synthesize'");
1641dec0984fce504a39a7f085774fb67cfd9957be58Jeffrey Yasskin  ConsumeToken(); // consume synthesize
16421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1643b328c4251a9d2db704b3bd46ec04884dc8e56332Douglas Gregor  while (true) {
1644322328b8a65ad2e45829eb06d245addb64037f6fDouglas Gregor    if (Tok.is(tok::code_completion)) {
1645a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian      Actions.CodeCompleteObjCPropertyDefinition(getCurScope());
16467d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      cutOffParsing();
16477d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      return 0;
1648322328b8a65ad2e45829eb06d245addb64037f6fDouglas Gregor    }
1649322328b8a65ad2e45829eb06d245addb64037f6fDouglas Gregor
1650b328c4251a9d2db704b3bd46ec04884dc8e56332Douglas Gregor    if (Tok.isNot(tok::identifier)) {
1651b328c4251a9d2db704b3bd46ec04884dc8e56332Douglas Gregor      Diag(Tok, diag::err_synthesized_property_name);
1652b328c4251a9d2db704b3bd46ec04884dc8e56332Douglas Gregor      SkipUntil(tok::semi);
1653d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall      return 0;
1654b328c4251a9d2db704b3bd46ec04884dc8e56332Douglas Gregor    }
1655b328c4251a9d2db704b3bd46ec04884dc8e56332Douglas Gregor
1656f624f8186d8fe474350051c6d3f00b2c204fbeaeFariborz Jahanian    IdentifierInfo *propertyIvar = 0;
1657f624f8186d8fe474350051c6d3f00b2c204fbeaeFariborz Jahanian    IdentifierInfo *propertyId = Tok.getIdentifierInfo();
1658f624f8186d8fe474350051c6d3f00b2c204fbeaeFariborz Jahanian    SourceLocation propertyLoc = ConsumeToken(); // consume property name
1659a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor    SourceLocation propertyIvarLoc;
1660df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner    if (Tok.is(tok::equal)) {
1661ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian      // property '=' ivar-name
1662ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian      ConsumeToken(); // consume '='
1663322328b8a65ad2e45829eb06d245addb64037f6fDouglas Gregor
1664322328b8a65ad2e45829eb06d245addb64037f6fDouglas Gregor      if (Tok.is(tok::code_completion)) {
1665a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian        Actions.CodeCompleteObjCPropertySynthesizeIvar(getCurScope(), propertyId);
16667d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis        cutOffParsing();
16677d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis        return 0;
1668322328b8a65ad2e45829eb06d245addb64037f6fDouglas Gregor      }
1669322328b8a65ad2e45829eb06d245addb64037f6fDouglas Gregor
1670df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner      if (Tok.isNot(tok::identifier)) {
1671ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian        Diag(Tok, diag::err_expected_ident);
1672ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian        break;
1673ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian      }
1674f624f8186d8fe474350051c6d3f00b2c204fbeaeFariborz Jahanian      propertyIvar = Tok.getIdentifierInfo();
1675a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor      propertyIvarLoc = ConsumeToken(); // consume ivar-name
1676ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian    }
1677a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian    Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, true,
1678a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor                                  propertyId, propertyIvar, propertyIvarLoc);
1679df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner    if (Tok.isNot(tok::comma))
1680ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian      break;
1681ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian    ConsumeToken(); // consume ','
1682ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian  }
1683e6bf90aec0044342ffccd13201b8a3a31a985a4bDouglas Gregor  ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@synthesize");
1684d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  return 0;
1685ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian}
1686ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian
1687ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian///   property-dynamic:
1688ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian///     @dynamic  property-list
1689ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian///
1690ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian///   property-list:
1691ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian///     identifier
1692ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian///     property-list ',' identifier
1693ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian///
1694d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
1695ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian  assert(Tok.isObjCAtKeyword(tok::objc_dynamic) &&
1696ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian         "ParseObjCPropertyDynamic(): Expected '@dynamic'");
1697dec0984fce504a39a7f085774fb67cfd9957be58Jeffrey Yasskin  ConsumeToken(); // consume dynamic
1698424b2a546dbd09cf70d43087771c7fff851ca158Douglas Gregor  while (true) {
1699424b2a546dbd09cf70d43087771c7fff851ca158Douglas Gregor    if (Tok.is(tok::code_completion)) {
1700a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian      Actions.CodeCompleteObjCPropertyDefinition(getCurScope());
17017d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      cutOffParsing();
17027d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      return 0;
1703424b2a546dbd09cf70d43087771c7fff851ca158Douglas Gregor    }
1704424b2a546dbd09cf70d43087771c7fff851ca158Douglas Gregor
1705424b2a546dbd09cf70d43087771c7fff851ca158Douglas Gregor    if (Tok.isNot(tok::identifier)) {
1706424b2a546dbd09cf70d43087771c7fff851ca158Douglas Gregor      Diag(Tok, diag::err_expected_ident);
1707424b2a546dbd09cf70d43087771c7fff851ca158Douglas Gregor      SkipUntil(tok::semi);
1708d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall      return 0;
1709424b2a546dbd09cf70d43087771c7fff851ca158Douglas Gregor    }
1710424b2a546dbd09cf70d43087771c7fff851ca158Douglas Gregor
1711c35b9e4e2efad727538c848cf30d4b0eb1031dc9Fariborz Jahanian    IdentifierInfo *propertyId = Tok.getIdentifierInfo();
1712c35b9e4e2efad727538c848cf30d4b0eb1031dc9Fariborz Jahanian    SourceLocation propertyLoc = ConsumeToken(); // consume property name
1713a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian    Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, false,
1714a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor                                  propertyId, 0, SourceLocation());
1715c35b9e4e2efad727538c848cf30d4b0eb1031dc9Fariborz Jahanian
1716df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner    if (Tok.isNot(tok::comma))
1717ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian      break;
1718ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian    ConsumeToken(); // consume ','
1719ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian  }
1720e6bf90aec0044342ffccd13201b8a3a31a985a4bDouglas Gregor  ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@dynamic");
1721d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  return 0;
1722ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian}
17231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1724397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian///  objc-throw-statement:
1725397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian///    throw expression[opt];
1726397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian///
172760d7b3a319d84d688752be3870615ac0f111fb16John McCallStmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) {
172860d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult Res;
1729397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian  ConsumeToken(); // consume throw
1730df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner  if (Tok.isNot(tok::semi)) {
173139f8f159c488a900e5958d5aab3e467af9ec8a2bFariborz Jahanian    Res = ParseExpression();
17320e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl    if (Res.isInvalid()) {
1733397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian      SkipUntil(tok::semi);
173443bc2a0973ffe404fabba6f8280cd6bad2c69fcbSebastian Redl      return StmtError();
1735397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian    }
1736397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian  }
173702418c7f0cb8bb83f1a1a1fad9bf6104efa83e0eTed Kremenek  // consume ';'
173802418c7f0cb8bb83f1a1a1fad9bf6104efa83e0eTed Kremenek  ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@throw");
17399ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  return Actions.ActOnObjCAtThrowStmt(atLoc, Res.take(), getCurScope());
1740397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian}
1741397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian
1742c385c90c68dfa376650e2facfbb444b2ec9bd110Fariborz Jahanian/// objc-synchronized-statement:
174378a677bbb5fa115fa0995b5783adeeefad67167eFariborz Jahanian///   @synchronized '(' expression ')' compound-statement
1744c385c90c68dfa376650e2facfbb444b2ec9bd110Fariborz Jahanian///
174560d7b3a319d84d688752be3870615ac0f111fb16John McCallStmtResult
174643bc2a0973ffe404fabba6f8280cd6bad2c69fcbSebastian RedlParser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
1747fa3ee8e6776634caf064ba5928ca7699d317a280Fariborz Jahanian  ConsumeToken(); // consume synchronized
1748fa3ee8e6776634caf064ba5928ca7699d317a280Fariborz Jahanian  if (Tok.isNot(tok::l_paren)) {
17491ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_lparen_after) << "@synchronized";
175043bc2a0973ffe404fabba6f8280cd6bad2c69fcbSebastian Redl    return StmtError();
1751fa3ee8e6776634caf064ba5928ca7699d317a280Fariborz Jahanian  }
175207524039dce5c820f111a1b3f772b4261f004b4aJohn McCall
175307524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  // The operand is surrounded with parentheses.
1754fa3ee8e6776634caf064ba5928ca7699d317a280Fariborz Jahanian  ConsumeParen();  // '('
175507524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  ExprResult operand(ParseExpression());
175607524039dce5c820f111a1b3f772b4261f004b4aJohn McCall
175707524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  if (Tok.is(tok::r_paren)) {
175807524039dce5c820f111a1b3f772b4261f004b4aJohn McCall    ConsumeParen();  // ')'
175907524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  } else {
176007524039dce5c820f111a1b3f772b4261f004b4aJohn McCall    if (!operand.isInvalid())
176107524039dce5c820f111a1b3f772b4261f004b4aJohn McCall      Diag(Tok, diag::err_expected_rparen);
176207524039dce5c820f111a1b3f772b4261f004b4aJohn McCall
176307524039dce5c820f111a1b3f772b4261f004b4aJohn McCall    // Skip forward until we see a left brace, but don't consume it.
176407524039dce5c820f111a1b3f772b4261f004b4aJohn McCall    SkipUntil(tok::l_brace, true, true);
1765fa3ee8e6776634caf064ba5928ca7699d317a280Fariborz Jahanian  }
176607524039dce5c820f111a1b3f772b4261f004b4aJohn McCall
176707524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  // Require a compound statement.
176878a677bbb5fa115fa0995b5783adeeefad67167eFariborz Jahanian  if (Tok.isNot(tok::l_brace)) {
176907524039dce5c820f111a1b3f772b4261f004b4aJohn McCall    if (!operand.isInvalid())
177007524039dce5c820f111a1b3f772b4261f004b4aJohn McCall      Diag(Tok, diag::err_expected_lbrace);
177143bc2a0973ffe404fabba6f8280cd6bad2c69fcbSebastian Redl    return StmtError();
177278a677bbb5fa115fa0995b5783adeeefad67167eFariborz Jahanian  }
17733ac438c383a4a9a73c76a05c76ec5d02f10a3c52Steve Naroff
177407524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  // Check the @synchronized operand now.
177507524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  if (!operand.isInvalid())
177607524039dce5c820f111a1b3f772b4261f004b4aJohn McCall    operand = Actions.ActOnObjCAtSynchronizedOperand(atLoc, operand.take());
177707524039dce5c820f111a1b3f772b4261f004b4aJohn McCall
177807524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  // Parse the compound statement within a new scope.
177907524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  ParseScope bodyScope(this, Scope::DeclScope);
178007524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  StmtResult body(ParseCompoundStatementBody());
178107524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  bodyScope.Exit();
178207524039dce5c820f111a1b3f772b4261f004b4aJohn McCall
178307524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  // If there was a semantic or parse error earlier with the
178407524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  // operand, fail now.
178507524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  if (operand.isInvalid())
178607524039dce5c820f111a1b3f772b4261f004b4aJohn McCall    return StmtError();
178707524039dce5c820f111a1b3f772b4261f004b4aJohn McCall
178807524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  if (body.isInvalid())
178907524039dce5c820f111a1b3f772b4261f004b4aJohn McCall    body = Actions.ActOnNullStmt(Tok.getLocation());
17900e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
179107524039dce5c820f111a1b3f772b4261f004b4aJohn McCall  return Actions.ActOnObjCAtSynchronizedStmt(atLoc, operand.get(), body.get());
1792c385c90c68dfa376650e2facfbb444b2ec9bd110Fariborz Jahanian}
1793c385c90c68dfa376650e2facfbb444b2ec9bd110Fariborz Jahanian
1794397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian///  objc-try-catch-statement:
1795397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian///    @try compound-statement objc-catch-list[opt]
1796397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian///    @try compound-statement objc-catch-list[opt] @finally compound-statement
1797397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian///
1798397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian///  objc-catch-list:
1799397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian///    @catch ( parameter-declaration ) compound-statement
1800397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian///    objc-catch-list @catch ( catch-parameter-declaration ) compound-statement
1801397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian///  catch-parameter-declaration:
1802397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian///     parameter-declaration
1803397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian///     '...' [OBJC2]
1804397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian///
180560d7b3a319d84d688752be3870615ac0f111fb16John McCallStmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
1806397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian  bool catch_or_finally_seen = false;
180743bc2a0973ffe404fabba6f8280cd6bad2c69fcbSebastian Redl
1808397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian  ConsumeToken(); // consume try
1809df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner  if (Tok.isNot(tok::l_brace)) {
18101ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_lbrace);
181143bc2a0973ffe404fabba6f8280cd6bad2c69fcbSebastian Redl    return StmtError();
1812397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian  }
18134e28d9e2ba9ce237549b45cfd4136ec6536d1325Benjamin Kramer  StmtVector CatchStmts;
181460d7b3a319d84d688752be3870615ac0f111fb16John McCall  StmtResult FinallyStmt;
18158935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  ParseScope TryScope(this, Scope::DeclScope);
181660d7b3a319d84d688752be3870615ac0f111fb16John McCall  StmtResult TryBody(ParseCompoundStatementBody());
18178935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  TryScope.Exit();
18180e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl  if (TryBody.isInvalid())
1819bd49a647afd9cc534fef13cadf652d4e9c396e2bFariborz Jahanian    TryBody = Actions.ActOnNullStmt(Tok.getLocation());
1820a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl
1821df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner  while (Tok.is(tok::at)) {
18226b884508c3bc97cc9df9516adb92fbf88dd0a2e4Chris Lattner    // At this point, we need to lookahead to determine if this @ is the start
18236b884508c3bc97cc9df9516adb92fbf88dd0a2e4Chris Lattner    // of an @catch or @finally.  We don't want to consume the @ token if this
18246b884508c3bc97cc9df9516adb92fbf88dd0a2e4Chris Lattner    // is an @try or @encode or something else.
18256b884508c3bc97cc9df9516adb92fbf88dd0a2e4Chris Lattner    Token AfterAt = GetLookAheadToken(1);
18266b884508c3bc97cc9df9516adb92fbf88dd0a2e4Chris Lattner    if (!AfterAt.isObjCAtKeyword(tok::objc_catch) &&
18276b884508c3bc97cc9df9516adb92fbf88dd0a2e4Chris Lattner        !AfterAt.isObjCAtKeyword(tok::objc_finally))
18286b884508c3bc97cc9df9516adb92fbf88dd0a2e4Chris Lattner      break;
18290e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
1830161a9c5afaafb4d527b7efba9675a8b2cbbe32e0Fariborz Jahanian    SourceLocation AtCatchFinallyLoc = ConsumeToken();
1831cb53b361bce341c8591333c6997f62e480acc0b4Chris Lattner    if (Tok.isObjCAtKeyword(tok::objc_catch)) {
1832d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall      Decl *FirstPart = 0;
18333b1191d7eaf2f4984564e01ab84b6713a9d80e70Fariborz Jahanian      ConsumeToken(); // consume catch
1834df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner      if (Tok.is(tok::l_paren)) {
1835397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian        ConsumeParen();
1836e21dd6ffef4585fa43cd3586ed971217d65bf56cSteve Naroff        ParseScope CatchScope(this, Scope::DeclScope|Scope::AtCatchScope);
1837df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner        if (Tok.isNot(tok::ellipsis)) {
18380b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall          DeclSpec DS(AttrFactory);
1839397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian          ParseDeclarationSpecifiers(DS);
184017b6399f8461c5b7e1c6f367b0a0dde49f921240Argyrios Kyrtzidis          Declarator ParmDecl(DS, Declarator::ObjCCatchContext);
18417ba138abd329e591a8f6d5001f60dd7082f71b3bSteve Naroff          ParseDeclarator(ParmDecl);
18427ba138abd329e591a8f6d5001f60dd7082f71b3bSteve Naroff
18434e6c0d19b7c072758922cf80525a81aeefc6e64bDouglas Gregor          // Inform the actions module about the declarator, so it
18447ba138abd329e591a8f6d5001f60dd7082f71b3bSteve Naroff          // gets added to the current scope.
184523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor          FirstPart = Actions.ActOnObjCExceptionDecl(getCurScope(), ParmDecl);
184664515f31850024a263e8f55f81e9ea4b39925cfaSteve Naroff        } else
1847397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian          ConsumeToken(); // consume '...'
18481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
184993a259500186fa7270f66cb460c5f5728e5680aeSteve Naroff        SourceLocation RParenLoc;
18501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
185193a259500186fa7270f66cb460c5f5728e5680aeSteve Naroff        if (Tok.is(tok::r_paren))
185293a259500186fa7270f66cb460c5f5728e5680aeSteve Naroff          RParenLoc = ConsumeParen();
185393a259500186fa7270f66cb460c5f5728e5680aeSteve Naroff        else // Skip over garbage, until we get to ')'.  Eat the ')'.
185493a259500186fa7270f66cb460c5f5728e5680aeSteve Naroff          SkipUntil(tok::r_paren, true, false);
185593a259500186fa7270f66cb460c5f5728e5680aeSteve Naroff
185660d7b3a319d84d688752be3870615ac0f111fb16John McCall        StmtResult CatchBody(true);
1857c1b3ba5ae08316fe43e541c4fb02921fc3e80b21Chris Lattner        if (Tok.is(tok::l_brace))
1858c1b3ba5ae08316fe43e541c4fb02921fc3e80b21Chris Lattner          CatchBody = ParseCompoundStatementBody();
1859c1b3ba5ae08316fe43e541c4fb02921fc3e80b21Chris Lattner        else
1860c1b3ba5ae08316fe43e541c4fb02921fc3e80b21Chris Lattner          Diag(Tok, diag::err_expected_lbrace);
18610e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl        if (CatchBody.isInvalid())
18623b1191d7eaf2f4984564e01ab84b6713a9d80e70Fariborz Jahanian          CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
18638f5e3dd32e443768d9dbbad7191e123e6733750cDouglas Gregor
186460d7b3a319d84d688752be3870615ac0f111fb16John McCall        StmtResult Catch = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc,
18658f5e3dd32e443768d9dbbad7191e123e6733750cDouglas Gregor                                                              RParenLoc,
18668f5e3dd32e443768d9dbbad7191e123e6733750cDouglas Gregor                                                              FirstPart,
18679ae2f076ca5ab1feb3ba95629099ec2319833701John McCall                                                              CatchBody.take());
18688f5e3dd32e443768d9dbbad7191e123e6733750cDouglas Gregor        if (!Catch.isInvalid())
18698f5e3dd32e443768d9dbbad7191e123e6733750cDouglas Gregor          CatchStmts.push_back(Catch.release());
18708f5e3dd32e443768d9dbbad7191e123e6733750cDouglas Gregor
187164515f31850024a263e8f55f81e9ea4b39925cfaSteve Naroff      } else {
18721ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner        Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
18731ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner          << "@catch clause";
187443bc2a0973ffe404fabba6f8280cd6bad2c69fcbSebastian Redl        return StmtError();
1875397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian      }
1876397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian      catch_or_finally_seen = true;
18776b884508c3bc97cc9df9516adb92fbf88dd0a2e4Chris Lattner    } else {
18786b884508c3bc97cc9df9516adb92fbf88dd0a2e4Chris Lattner      assert(Tok.isObjCAtKeyword(tok::objc_finally) && "Lookahead confused?");
187964515f31850024a263e8f55f81e9ea4b39925cfaSteve Naroff      ConsumeToken(); // consume finally
18808935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor      ParseScope FinallyScope(this, Scope::DeclScope);
18810e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
188260d7b3a319d84d688752be3870615ac0f111fb16John McCall      StmtResult FinallyBody(true);
1883c1b3ba5ae08316fe43e541c4fb02921fc3e80b21Chris Lattner      if (Tok.is(tok::l_brace))
1884c1b3ba5ae08316fe43e541c4fb02921fc3e80b21Chris Lattner        FinallyBody = ParseCompoundStatementBody();
1885c1b3ba5ae08316fe43e541c4fb02921fc3e80b21Chris Lattner      else
1886c1b3ba5ae08316fe43e541c4fb02921fc3e80b21Chris Lattner        Diag(Tok, diag::err_expected_lbrace);
18870e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl      if (FinallyBody.isInvalid())
1888161a9c5afaafb4d527b7efba9675a8b2cbbe32e0Fariborz Jahanian        FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
18890e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl      FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
18909ae2f076ca5ab1feb3ba95629099ec2319833701John McCall                                                   FinallyBody.take());
1891397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian      catch_or_finally_seen = true;
1892397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian      break;
1893397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian    }
1894397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian  }
1895bd49a647afd9cc534fef13cadf652d4e9c396e2bFariborz Jahanian  if (!catch_or_finally_seen) {
1896397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian    Diag(atLoc, diag::err_missing_catch_finally);
189743bc2a0973ffe404fabba6f8280cd6bad2c69fcbSebastian Redl    return StmtError();
1898bd49a647afd9cc534fef13cadf652d4e9c396e2bFariborz Jahanian  }
18998f5e3dd32e443768d9dbbad7191e123e6733750cDouglas Gregor
19009ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  return Actions.ActOnObjCAtTryStmt(atLoc, TryBody.take(),
19013fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer                                    CatchStmts,
19029ae2f076ca5ab1feb3ba95629099ec2319833701John McCall                                    FinallyStmt.take());
1903397fcc117e5631db53879fbfcca66966088f3f07Fariborz Jahanian}
1904ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian
1905f85e193739c953358c865005855253af4f68a497John McCall/// objc-autoreleasepool-statement:
1906f85e193739c953358c865005855253af4f68a497John McCall///   @autoreleasepool compound-statement
1907f85e193739c953358c865005855253af4f68a497John McCall///
1908f85e193739c953358c865005855253af4f68a497John McCallStmtResult
1909f85e193739c953358c865005855253af4f68a497John McCallParser::ParseObjCAutoreleasePoolStmt(SourceLocation atLoc) {
1910f85e193739c953358c865005855253af4f68a497John McCall  ConsumeToken(); // consume autoreleasepool
1911f85e193739c953358c865005855253af4f68a497John McCall  if (Tok.isNot(tok::l_brace)) {
1912f85e193739c953358c865005855253af4f68a497John McCall    Diag(Tok, diag::err_expected_lbrace);
1913f85e193739c953358c865005855253af4f68a497John McCall    return StmtError();
1914f85e193739c953358c865005855253af4f68a497John McCall  }
1915f85e193739c953358c865005855253af4f68a497John McCall  // Enter a scope to hold everything within the compound stmt.  Compound
1916f85e193739c953358c865005855253af4f68a497John McCall  // statements can always hold declarations.
1917f85e193739c953358c865005855253af4f68a497John McCall  ParseScope BodyScope(this, Scope::DeclScope);
1918f85e193739c953358c865005855253af4f68a497John McCall
1919f85e193739c953358c865005855253af4f68a497John McCall  StmtResult AutoreleasePoolBody(ParseCompoundStatementBody());
1920f85e193739c953358c865005855253af4f68a497John McCall
1921f85e193739c953358c865005855253af4f68a497John McCall  BodyScope.Exit();
1922f85e193739c953358c865005855253af4f68a497John McCall  if (AutoreleasePoolBody.isInvalid())
1923f85e193739c953358c865005855253af4f68a497John McCall    AutoreleasePoolBody = Actions.ActOnNullStmt(Tok.getLocation());
1924f85e193739c953358c865005855253af4f68a497John McCall  return Actions.ActOnObjCAutoreleasePoolStmt(atLoc,
1925f85e193739c953358c865005855253af4f68a497John McCall                                                AutoreleasePoolBody.take());
1926f85e193739c953358c865005855253af4f68a497John McCall}
1927f85e193739c953358c865005855253af4f68a497John McCall
19286c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian/// StashAwayMethodOrFunctionBodyTokens -  Consume the tokens and store them
19296c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian/// for later parsing.
19306c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanianvoid Parser::StashAwayMethodOrFunctionBodyTokens(Decl *MDecl) {
19316c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian  LexedMethod* LM = new LexedMethod(this, MDecl);
19326c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian  CurParsedObjCImpl->LateParsedObjCMethods.push_back(LM);
19336c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian  CachedTokens &Toks = LM->Toks;
19349e5df312551bc92f0a6c908288effef2e2ed0ee7Fariborz Jahanian  // Begin by storing the '{' or 'try' or ':' token.
19356c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian  Toks.push_back(Tok);
19362eb362b50f34296c39d5ec3e5e1bd6a2c9a5877eFariborz Jahanian  if (Tok.is(tok::kw_try)) {
19372eb362b50f34296c39d5ec3e5e1bd6a2c9a5877eFariborz Jahanian    ConsumeToken();
1938dbd6945b7f4397f44fe6a1f1acf62ab6671e84f5Fariborz Jahanian    if (Tok.is(tok::colon)) {
1939dbd6945b7f4397f44fe6a1f1acf62ab6671e84f5Fariborz Jahanian      Toks.push_back(Tok);
1940dbd6945b7f4397f44fe6a1f1acf62ab6671e84f5Fariborz Jahanian      ConsumeToken();
1941dbd6945b7f4397f44fe6a1f1acf62ab6671e84f5Fariborz Jahanian      while (Tok.isNot(tok::l_brace)) {
1942dbd6945b7f4397f44fe6a1f1acf62ab6671e84f5Fariborz Jahanian        ConsumeAndStoreUntil(tok::l_paren, Toks, /*StopAtSemi=*/false);
1943dbd6945b7f4397f44fe6a1f1acf62ab6671e84f5Fariborz Jahanian        ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false);
1944dbd6945b7f4397f44fe6a1f1acf62ab6671e84f5Fariborz Jahanian      }
1945dbd6945b7f4397f44fe6a1f1acf62ab6671e84f5Fariborz Jahanian    }
19469e5df312551bc92f0a6c908288effef2e2ed0ee7Fariborz Jahanian    Toks.push_back(Tok); // also store '{'
19479e5df312551bc92f0a6c908288effef2e2ed0ee7Fariborz Jahanian  }
19489e5df312551bc92f0a6c908288effef2e2ed0ee7Fariborz Jahanian  else if (Tok.is(tok::colon)) {
19499e5df312551bc92f0a6c908288effef2e2ed0ee7Fariborz Jahanian    ConsumeToken();
19509e5df312551bc92f0a6c908288effef2e2ed0ee7Fariborz Jahanian    while (Tok.isNot(tok::l_brace)) {
19519e5df312551bc92f0a6c908288effef2e2ed0ee7Fariborz Jahanian      ConsumeAndStoreUntil(tok::l_paren, Toks, /*StopAtSemi=*/false);
19529e5df312551bc92f0a6c908288effef2e2ed0ee7Fariborz Jahanian      ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false);
19539e5df312551bc92f0a6c908288effef2e2ed0ee7Fariborz Jahanian    }
19542eb362b50f34296c39d5ec3e5e1bd6a2c9a5877eFariborz Jahanian    Toks.push_back(Tok); // also store '{'
19552eb362b50f34296c39d5ec3e5e1bd6a2c9a5877eFariborz Jahanian  }
19566c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian  ConsumeBrace();
19576c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian  // Consume everything up to (and including) the matching right brace.
19586c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian  ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
19592eb362b50f34296c39d5ec3e5e1bd6a2c9a5877eFariborz Jahanian  while (Tok.is(tok::kw_catch)) {
19602eb362b50f34296c39d5ec3e5e1bd6a2c9a5877eFariborz Jahanian    ConsumeAndStoreUntil(tok::l_brace, Toks, /*StopAtSemi=*/false);
19612eb362b50f34296c39d5ec3e5e1bd6a2c9a5877eFariborz Jahanian    ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
19622eb362b50f34296c39d5ec3e5e1bd6a2c9a5877eFariborz Jahanian  }
19636c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian}
19646c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian
19653536b443bc50d58a79f14fca9b6842541a434854Steve Naroff///   objc-method-def: objc-method-proto ';'[opt] '{' body '}'
1966ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian///
1967d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseObjCMethodDefinition() {
1968a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian  Decl *MDecl = ParseObjCMethodPrototype();
19691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1970f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  PrettyDeclStackTraceEntry CrashInfo(Actions, MDecl, Tok.getLocation(),
1971f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                      "parsing Objective-C method");
19721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1973ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian  // parse optional ';'
1974209a8c2fa23636f6d065d618e7078e164903f5cdFariborz Jahanian  if (Tok.is(tok::semi)) {
1975849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis    if (CurParsedObjCImpl) {
1976496e45ef3350fabc312c5a807d308c65c50af4dbTed Kremenek      Diag(Tok, diag::warn_semicolon_before_method_body)
1977849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor        << FixItHint::CreateRemoval(Tok.getLocation());
1978496e45ef3350fabc312c5a807d308c65c50af4dbTed Kremenek    }
1979ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian    ConsumeToken();
1980209a8c2fa23636f6d065d618e7078e164903f5cdFariborz Jahanian  }
1981ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian
1982409be835b68344e0de56f99ef9a1e12760bc69eeSteve Naroff  // We should have an opening brace now.
1983df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner  if (Tok.isNot(tok::l_brace)) {
1984da323adbb99cee19a203ead852d5d9bfebb23fb7Steve Naroff    Diag(Tok, diag::err_expected_method_body);
19851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1986409be835b68344e0de56f99ef9a1e12760bc69eeSteve Naroff    // Skip over garbage, until we get to '{'.  Don't eat the '{'.
1987409be835b68344e0de56f99ef9a1e12760bc69eeSteve Naroff    SkipUntil(tok::l_brace, true, true);
19881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1989409be835b68344e0de56f99ef9a1e12760bc69eeSteve Naroff    // If we didn't find the '{', bail out.
1990409be835b68344e0de56f99ef9a1e12760bc69eeSteve Naroff    if (Tok.isNot(tok::l_brace))
1991d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall      return 0;
1992ac00b7f4a933e60e2f0afd83092339160adc140cFariborz Jahanian  }
1993849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis
1994849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis  if (!MDecl) {
1995849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis    ConsumeBrace();
1996849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis    SkipUntil(tok::r_brace, /*StopAtSemi=*/false);
1997849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis    return 0;
1998849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis  }
1999849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis
2000140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian  // Allow the rest of sema to find private method decl implementations.
2001849639d8b548519cc5a00c0c9253f0c0d525060dArgyrios Kyrtzidis  Actions.AddAnyMethodToGlobalPool(MDecl);
2002c9b970996b8af41754a99a9cec15a9d401962ba1Fariborz Jahanian  assert (CurParsedObjCImpl
2003c9b970996b8af41754a99a9cec15a9d401962ba1Fariborz Jahanian          && "ParseObjCMethodDefinition - Method out of @implementation");
2004c9b970996b8af41754a99a9cec15a9d401962ba1Fariborz Jahanian  // Consume the tokens and store them for later parsing.
2005c9b970996b8af41754a99a9cec15a9d401962ba1Fariborz Jahanian  StashAwayMethodOrFunctionBodyTokens(MDecl);
200671c0a951d08dc7a2a057df8c15f22b36f6aa47c7Steve Naroff  return MDecl;
20075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
20085508518a2702b00be3b15a26d772bde968972f54Anders Carlsson
200960d7b3a319d84d688752be3870615ac0f111fb16John McCallStmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) {
20109a0c85e640a08174569a303db22981612f05d385Douglas Gregor  if (Tok.is(tok::code_completion)) {
201123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteObjCAtStatement(getCurScope());
20127d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
20139a0c85e640a08174569a303db22981612f05d385Douglas Gregor    return StmtError();
20145d8031687d086701b4dadaab3e0de1def448da9dChris Lattner  }
20155d8031687d086701b4dadaab3e0de1def448da9dChris Lattner
20165d8031687d086701b4dadaab3e0de1def448da9dChris Lattner  if (Tok.isObjCAtKeyword(tok::objc_try))
20176b884508c3bc97cc9df9516adb92fbf88dd0a2e4Chris Lattner    return ParseObjCTryStmt(AtLoc);
20185d8031687d086701b4dadaab3e0de1def448da9dChris Lattner
20195d8031687d086701b4dadaab3e0de1def448da9dChris Lattner  if (Tok.isObjCAtKeyword(tok::objc_throw))
202064515f31850024a263e8f55f81e9ea4b39925cfaSteve Naroff    return ParseObjCThrowStmt(AtLoc);
20215d8031687d086701b4dadaab3e0de1def448da9dChris Lattner
20225d8031687d086701b4dadaab3e0de1def448da9dChris Lattner  if (Tok.isObjCAtKeyword(tok::objc_synchronized))
202364515f31850024a263e8f55f81e9ea4b39925cfaSteve Naroff    return ParseObjCSynchronizedStmt(AtLoc);
2024f85e193739c953358c865005855253af4f68a497John McCall
2025f85e193739c953358c865005855253af4f68a497John McCall  if (Tok.isObjCAtKeyword(tok::objc_autoreleasepool))
2026f85e193739c953358c865005855253af4f68a497John McCall    return ParseObjCAutoreleasePoolStmt(AtLoc);
20275d8031687d086701b4dadaab3e0de1def448da9dChris Lattner
202860d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult Res(ParseExpressionWithLeadingAt(AtLoc));
20290e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl  if (Res.isInvalid()) {
203064515f31850024a263e8f55f81e9ea4b39925cfaSteve Naroff    // If the expression is invalid, skip ahead to the next semicolon. Not
203164515f31850024a263e8f55f81e9ea4b39925cfaSteve Naroff    // doing this opens us up to the possibility of infinite loops if
203264515f31850024a263e8f55f81e9ea4b39925cfaSteve Naroff    // ParseExpression does not consume any tokens.
203364515f31850024a263e8f55f81e9ea4b39925cfaSteve Naroff    SkipUntil(tok::semi);
203443bc2a0973ffe404fabba6f8280cd6bad2c69fcbSebastian Redl    return StmtError();
203564515f31850024a263e8f55f81e9ea4b39925cfaSteve Naroff  }
20365d8031687d086701b4dadaab3e0de1def448da9dChris Lattner
203764515f31850024a263e8f55f81e9ea4b39925cfaSteve Naroff  // Otherwise, eat the semicolon.
20389ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor  ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
2039419563768ef4929a622d7c2b066856e82901bb91Richard Smith  return Actions.ActOnExprStmt(Res);
204064515f31850024a263e8f55f81e9ea4b39925cfaSteve Naroff}
204164515f31850024a263e8f55f81e9ea4b39925cfaSteve Naroff
204260d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
20435508518a2702b00be3b15a26d772bde968972f54Anders Carlsson  switch (Tok.getKind()) {
20449a0c85e640a08174569a303db22981612f05d385Douglas Gregor  case tok::code_completion:
204523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteObjCAtExpression(getCurScope());
20467d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
20479a0c85e640a08174569a303db22981612f05d385Douglas Gregor    return ExprError();
20489a0c85e640a08174569a303db22981612f05d385Douglas Gregor
2049ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  case tok::minus:
2050ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  case tok::plus: {
2051ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    tok::TokenKind Kind = Tok.getKind();
2052ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    SourceLocation OpLoc = ConsumeToken();
2053ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2054ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    if (!Tok.is(tok::numeric_constant)) {
2055ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      const char *Symbol = 0;
2056ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      switch (Kind) {
2057ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      case tok::minus: Symbol = "-"; break;
2058ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      case tok::plus: Symbol = "+"; break;
2059ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      default: llvm_unreachable("missing unary operator case");
2060ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      }
2061ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      Diag(Tok, diag::err_nsnumber_nonliteral_unary)
2062ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek        << Symbol;
2063ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      return ExprError();
2064ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    }
2065ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2066ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    ExprResult Lit(Actions.ActOnNumericConstant(Tok));
2067ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    if (Lit.isInvalid()) {
20683fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer      return Lit;
2069ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    }
20708b8d9534f185743fb72c59d4e735794e6e0f4335Benjamin Kramer    ConsumeToken(); // Consume the literal token.
2071ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2072ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    Lit = Actions.ActOnUnaryOp(getCurScope(), OpLoc, Kind, Lit.take());
2073ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    if (Lit.isInvalid())
20743fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer      return Lit;
2075ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2076ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    return ParsePostfixExpressionSuffix(
2077ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek             Actions.BuildObjCNumericLiteral(AtLoc, Lit.take()));
2078ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  }
2079ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2080b3a99cd5bcaeff0c5ff6a60788b5eb68e52a3953Chris Lattner  case tok::string_literal:    // primary-expression: string-literal
2081b3a99cd5bcaeff0c5ff6a60788b5eb68e52a3953Chris Lattner  case tok::wide_string_literal:
20821d922960e083906a586609ac6978678147250177Sebastian Redl    return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
2083ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2084ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  case tok::char_constant:
2085ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    return ParsePostfixExpressionSuffix(ParseObjCCharacterLiteral(AtLoc));
2086ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2087ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  case tok::numeric_constant:
2088ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    return ParsePostfixExpressionSuffix(ParseObjCNumericLiteral(AtLoc));
2089ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2090ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  case tok::kw_true:  // Objective-C++, etc.
2091ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  case tok::kw___objc_yes: // c/c++/objc/objc++ __objc_yes
2092ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc, true));
2093ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  case tok::kw_false: // Objective-C++, etc.
2094ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  case tok::kw___objc_no: // c/c++/objc/objc++ __objc_no
2095ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc, false));
2096ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2097ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  case tok::l_square:
2098ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    // Objective-C array literal
2099ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    return ParsePostfixExpressionSuffix(ParseObjCArrayLiteral(AtLoc));
2100ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2101ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  case tok::l_brace:
2102ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    // Objective-C dictionary literal
2103ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    return ParsePostfixExpressionSuffix(ParseObjCDictionaryLiteral(AtLoc));
2104ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2105eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard  case tok::l_paren:
2106eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard    // Objective-C boxed expression
2107eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard    return ParsePostfixExpressionSuffix(ParseObjCBoxedExpr(AtLoc));
2108eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard
2109b3a99cd5bcaeff0c5ff6a60788b5eb68e52a3953Chris Lattner  default:
21104fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner    if (Tok.getIdentifierInfo() == 0)
21111d922960e083906a586609ac6978678147250177Sebastian Redl      return ExprError(Diag(AtLoc, diag::err_unexpected_at));
21122f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl
21134fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner    switch (Tok.getIdentifierInfo()->getObjCKeywordID()) {
21144fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner    case tok::objc_encode:
21151d922960e083906a586609ac6978678147250177Sebastian Redl      return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc));
21164fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner    case tok::objc_protocol:
21171d922960e083906a586609ac6978678147250177Sebastian Redl      return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc));
21184fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner    case tok::objc_selector:
21191d922960e083906a586609ac6978678147250177Sebastian Redl      return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc));
21206749ae1dbcc9e45ade21b05c6542a6354903ad77Fariborz Jahanian      default: {
21216749ae1dbcc9e45ade21b05c6542a6354903ad77Fariborz Jahanian        const char *str = 0;
21226749ae1dbcc9e45ade21b05c6542a6354903ad77Fariborz Jahanian        if (GetLookAheadToken(1).is(tok::l_brace)) {
21236749ae1dbcc9e45ade21b05c6542a6354903ad77Fariborz Jahanian          char ch = Tok.getIdentifierInfo()->getNameStart()[0];
21246749ae1dbcc9e45ade21b05c6542a6354903ad77Fariborz Jahanian          str =
21256749ae1dbcc9e45ade21b05c6542a6354903ad77Fariborz Jahanian            ch == 't' ? "try"
21266749ae1dbcc9e45ade21b05c6542a6354903ad77Fariborz Jahanian                      : (ch == 'f' ? "finally"
21276749ae1dbcc9e45ade21b05c6542a6354903ad77Fariborz Jahanian                                   : (ch == 'a' ? "autoreleasepool" : 0));
21286749ae1dbcc9e45ade21b05c6542a6354903ad77Fariborz Jahanian        }
21296749ae1dbcc9e45ade21b05c6542a6354903ad77Fariborz Jahanian        if (str) {
21306749ae1dbcc9e45ade21b05c6542a6354903ad77Fariborz Jahanian          SourceLocation kwLoc = Tok.getLocation();
21316749ae1dbcc9e45ade21b05c6542a6354903ad77Fariborz Jahanian          return ExprError(Diag(AtLoc, diag::err_unexpected_at) <<
21326749ae1dbcc9e45ade21b05c6542a6354903ad77Fariborz Jahanian                             FixItHint::CreateReplacement(kwLoc, str));
21336749ae1dbcc9e45ade21b05c6542a6354903ad77Fariborz Jahanian        }
21346749ae1dbcc9e45ade21b05c6542a6354903ad77Fariborz Jahanian        else
21356749ae1dbcc9e45ade21b05c6542a6354903ad77Fariborz Jahanian          return ExprError(Diag(AtLoc, diag::err_unexpected_at));
21366749ae1dbcc9e45ade21b05c6542a6354903ad77Fariborz Jahanian      }
21374fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner    }
21385508518a2702b00be3b15a26d772bde968972f54Anders Carlsson  }
21395508518a2702b00be3b15a26d772bde968972f54Anders Carlsson}
21405508518a2702b00be3b15a26d772bde968972f54Anders Carlsson
2141e23fb90712233bdfa04387e48b54a7168e23cb3eDmitri Gribenko/// \brief Parse the receiver of an Objective-C++ message send.
21426aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor///
21436aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor/// This routine parses the receiver of a message send in
21446aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor/// Objective-C++ either as a type or as an expression. Note that this
21456aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor/// routine must not be called to parse a send to 'super', since it
21466aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor/// has no way to return such a result.
21476aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor///
21486aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor/// \param IsExpr Whether the receiver was parsed as an expression.
21496aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor///
21506aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor/// \param TypeOrExpr If the receiver was parsed as an expression (\c
21516aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor/// IsExpr is true), the parsed expression. If the receiver was parsed
21526aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor/// as a type (\c IsExpr is false), the parsed type.
21536aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor///
21546aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor/// \returns True if an error occurred during parsing or semantic
21556aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor/// analysis, in which case the arguments do not have valid
21566aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor/// values. Otherwise, returns false for a successful parse.
21576aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor///
21586aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor///   objc-receiver: [C++]
21596aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor///     'super' [not parsed here]
21606aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor///     expression
21616aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor///     simple-type-specifier
21626aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor///     typename-specifier
21636aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregorbool Parser::ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr) {
21640fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor  InMessageExpressionRAIIObject InMessage(*this, true);
21650fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor
21666aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor  if (Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
21676aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor      Tok.is(tok::kw_typename) || Tok.is(tok::annot_cxxscope))
21686aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    TryAnnotateTypeOrScopeToken();
21696aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor
21707bf33401acf506b0039222834d7259acb80f6311Kaelyn Uhrain  if (!Actions.isSimpleTypeSpecifier(Tok.getKind())) {
21716aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    //   objc-receiver:
21726aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    //     expression
217360d7b3a319d84d688752be3870615ac0f111fb16John McCall    ExprResult Receiver = ParseExpression();
21746aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    if (Receiver.isInvalid())
21756aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor      return true;
21766aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor
21776aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    IsExpr = true;
21786aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    TypeOrExpr = Receiver.take();
21796aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    return false;
21806aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor  }
21816aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor
21826aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor  // objc-receiver:
21836aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor  //   typename-specifier
21846aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor  //   simple-type-specifier
21856aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor  //   expression (that starts with one of the above)
21860b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  DeclSpec DS(AttrFactory);
21876aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor  ParseCXXSimpleTypeSpecifier(DS);
21886aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor
21896aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor  if (Tok.is(tok::l_paren)) {
21906aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    // If we see an opening parentheses at this point, we are
21916aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    // actually parsing an expression that starts with a
21926aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    // function-style cast, e.g.,
21936aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    //
21946aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    //   postfix-expression:
21956aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    //     simple-type-specifier ( expression-list [opt] )
21966aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    //     typename-specifier ( expression-list [opt] )
21976aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    //
21986aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    // Parse the remainder of this case, then the (optional)
21996aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    // postfix-expression suffix, followed by the (optional)
22006aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    // right-hand side of the binary expression. We have an
22016aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    // instance method.
220260d7b3a319d84d688752be3870615ac0f111fb16John McCall    ExprResult Receiver = ParseCXXTypeConstructExpression(DS);
22036aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    if (!Receiver.isInvalid())
22049ae2f076ca5ab1feb3ba95629099ec2319833701John McCall      Receiver = ParsePostfixExpressionSuffix(Receiver.take());
22056aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    if (!Receiver.isInvalid())
22069ae2f076ca5ab1feb3ba95629099ec2319833701John McCall      Receiver = ParseRHSOfBinaryExpression(Receiver.take(), prec::Comma);
22076aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    if (Receiver.isInvalid())
22086aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor      return true;
22096aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor
22106aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    IsExpr = true;
22116aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    TypeOrExpr = Receiver.take();
22126aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    return false;
22136aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor  }
22146aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor
22156aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor  // We have a class message. Turn the simple-type-specifier or
22166aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor  // typename-specifier we parsed into a type and parse the
22176aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor  // remainder of the class message.
22186aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
221923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  TypeResult Type = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
22206aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor  if (Type.isInvalid())
22216aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    return true;
22226aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor
22236aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor  IsExpr = false;
2224b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  TypeOrExpr = Type.get().getAsOpaquePtr();
22256aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor  return false;
22266aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor}
22276aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor
22281b730e847ded503f2e615154035c083c4f94a067Douglas Gregor/// \brief Determine whether the parser is currently referring to a an
22291b730e847ded503f2e615154035c083c4f94a067Douglas Gregor/// Objective-C message send, using a simplified heuristic to avoid overhead.
22301b730e847ded503f2e615154035c083c4f94a067Douglas Gregor///
22311b730e847ded503f2e615154035c083c4f94a067Douglas Gregor/// This routine will only return true for a subset of valid message-send
22321b730e847ded503f2e615154035c083c4f94a067Douglas Gregor/// expressions.
22331b730e847ded503f2e615154035c083c4f94a067Douglas Gregorbool Parser::isSimpleObjCMessageExpression() {
22344e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  assert(Tok.is(tok::l_square) && getLangOpts().ObjC1 &&
22351b730e847ded503f2e615154035c083c4f94a067Douglas Gregor         "Incorrect start for isSimpleObjCMessageExpression");
22361b730e847ded503f2e615154035c083c4f94a067Douglas Gregor  return GetLookAheadToken(1).is(tok::identifier) &&
22371b730e847ded503f2e615154035c083c4f94a067Douglas Gregor         GetLookAheadToken(2).is(tok::identifier);
22381b730e847ded503f2e615154035c083c4f94a067Douglas Gregor}
22391b730e847ded503f2e615154035c083c4f94a067Douglas Gregor
22409497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregorbool Parser::isStartOfObjCClassMessageMissingOpenBracket() {
22414e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!getLangOpts().ObjC1 || !NextToken().is(tok::identifier) ||
22429497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor      InMessageExpression)
22439497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor    return false;
22449497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor
22459497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor
22469497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor  ParsedType Type;
22479497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor
22489497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor  if (Tok.is(tok::annot_typename))
22499497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor    Type = getTypeAnnotation(Tok);
22509497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor  else if (Tok.is(tok::identifier))
22519497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor    Type = Actions.getTypeName(*Tok.getIdentifierInfo(), Tok.getLocation(),
22529497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor                               getCurScope());
22539497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor  else
22549497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor    return false;
22559497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor
22569497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor  if (!Type.get().isNull() && Type.get()->isObjCObjectOrInterfaceType()) {
22579497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor    const Token &AfterNext = GetLookAheadToken(2);
22589497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor    if (AfterNext.is(tok::colon) || AfterNext.is(tok::r_square)) {
22599497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor      if (Tok.is(tok::identifier))
22609497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor        TryAnnotateTypeOrScopeToken();
22619497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor
22629497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor      return Tok.is(tok::annot_typename);
22639497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor    }
22649497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor  }
22659497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor
22669497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor  return false;
22679497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor}
22689497a73ad0d54859edbf48beb93ebb19a7ae50c9Douglas Gregor
22691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///   objc-message-expr:
22700ccb27ded12fd03eb6818a880f50901bb70254feFariborz Jahanian///     '[' objc-receiver objc-message-args ']'
22710ccb27ded12fd03eb6818a880f50901bb70254feFariborz Jahanian///
22722725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor///   objc-receiver: [C]
2273eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner///     'super'
22740ccb27ded12fd03eb6818a880f50901bb70254feFariborz Jahanian///     expression
22750ccb27ded12fd03eb6818a880f50901bb70254feFariborz Jahanian///     class-name
22760ccb27ded12fd03eb6818a880f50901bb70254feFariborz Jahanian///     type-name
22776aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor///
227860d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Parser::ParseObjCMessageExpression() {
2279699b66138ac307a32e238463e0eff513ff17d337Chris Lattner  assert(Tok.is(tok::l_square) && "'[' expected");
2280699b66138ac307a32e238463e0eff513ff17d337Chris Lattner  SourceLocation LBracLoc = ConsumeBracket(); // consume '['
2281699b66138ac307a32e238463e0eff513ff17d337Chris Lattner
22828e254cfe5a6ab4202c7fcc4b64bdd1ca0fe071acDouglas Gregor  if (Tok.is(tok::code_completion)) {
228323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteObjCMessageReceiver(getCurScope());
22847d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
22858e254cfe5a6ab4202c7fcc4b64bdd1ca0fe071acDouglas Gregor    return ExprError();
22868e254cfe5a6ab4202c7fcc4b64bdd1ca0fe071acDouglas Gregor  }
22878e254cfe5a6ab4202c7fcc4b64bdd1ca0fe071acDouglas Gregor
22880fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor  InMessageExpressionRAIIObject InMessage(*this, true);
22890fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor
22904e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().CPlusPlus) {
22916aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    // We completely separate the C and C++ cases because C++ requires
22926aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    // more complicated (read: slower) parsing.
22936aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor
22946aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    // Handle send to super.
22956aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    // FIXME: This doesn't benefit from the same typo-correction we
22966aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    // get in Objective-C.
22976aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    if (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_super &&
229823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        NextToken().isNot(tok::period) && getCurScope()->isInObjcMethodScope())
2299b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall      return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(),
2300b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall                                            ParsedType(), 0);
23016aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor
23026aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    // Parse the receiver, which is either a type or an expression.
23036aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    bool IsExpr;
2304304b752a450c0fc5968c20ba25446d0bb7c6f68dNick Lewycky    void *TypeOrExpr = NULL;
23056aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) {
23066aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor      SkipUntil(tok::r_square);
23076aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor      return ExprError();
23086aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    }
23096aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor
23106aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    if (IsExpr)
2311b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall      return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
2312b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall                                            ParsedType(),
23139ae2f076ca5ab1feb3ba95629099ec2319833701John McCall                                            static_cast<Expr*>(TypeOrExpr));
23146aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor
23156aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor    return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
2316b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall                              ParsedType::getFromOpaquePtr(TypeOrExpr),
2317b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall                                          0);
2318c59cb38810c63a806270385f79ea84e0203754eaChris Lattner  }
2319c59cb38810c63a806270385f79ea84e0203754eaChris Lattner
2320c59cb38810c63a806270385f79ea84e0203754eaChris Lattner  if (Tok.is(tok::identifier)) {
23211dbca6ea983231b4cab1a8f1edda8f6e13c21f12Douglas Gregor    IdentifierInfo *Name = Tok.getIdentifierInfo();
23221dbca6ea983231b4cab1a8f1edda8f6e13c21f12Douglas Gregor    SourceLocation NameLoc = Tok.getLocation();
2323b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall    ParsedType ReceiverType;
232423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    switch (Actions.getObjCMessageKind(getCurScope(), Name, NameLoc,
23251dbca6ea983231b4cab1a8f1edda8f6e13c21f12Douglas Gregor                                       Name == Ident_super,
23261569f95831a8c99e9f664137bf8f40e47ee3d90fDouglas Gregor                                       NextToken().is(tok::period),
23271569f95831a8c99e9f664137bf8f40e47ee3d90fDouglas Gregor                                       ReceiverType)) {
2328f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    case Sema::ObjCSuperMessage:
2329b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall      return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(),
2330b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall                                            ParsedType(), 0);
23312725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor
2332f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    case Sema::ObjCClassMessage:
23331569f95831a8c99e9f664137bf8f40e47ee3d90fDouglas Gregor      if (!ReceiverType) {
23342725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor        SkipUntil(tok::r_square);
23352725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor        return ExprError();
23362725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor      }
23372725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor
23381569f95831a8c99e9f664137bf8f40e47ee3d90fDouglas Gregor      ConsumeToken(); // the type name
23391569f95831a8c99e9f664137bf8f40e47ee3d90fDouglas Gregor
23401569f95831a8c99e9f664137bf8f40e47ee3d90fDouglas Gregor      return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
23419ae2f076ca5ab1feb3ba95629099ec2319833701John McCall                                            ReceiverType, 0);
23421dbca6ea983231b4cab1a8f1edda8f6e13c21f12Douglas Gregor
2343f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    case Sema::ObjCInstanceMessage:
23442725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor      // Fall through to parse an expression.
23451dbca6ea983231b4cab1a8f1edda8f6e13c21f12Douglas Gregor      break;
2346d2869925b5f10e00b13fbf3f41bbb17e4c9adbe0Fariborz Jahanian    }
2347699b66138ac307a32e238463e0eff513ff17d337Chris Lattner  }
2348eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner
2349eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner  // Otherwise, an arbitrary expression can be the receiver of a send.
235060d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult Res(ParseExpression());
23510e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl  if (Res.isInvalid()) {
23525c749428a9938d5e2e9564b1c9b7a9252c30ee27Chris Lattner    SkipUntil(tok::r_square);
23533fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer    return Res;
2354699b66138ac307a32e238463e0eff513ff17d337Chris Lattner  }
23551d922960e083906a586609ac6978678147250177Sebastian Redl
2356b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
2357b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall                                        ParsedType(), Res.take());
2358699b66138ac307a32e238463e0eff513ff17d337Chris Lattner}
23591d922960e083906a586609ac6978678147250177Sebastian Redl
23602725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// \brief Parse the remainder of an Objective-C message following the
23612725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// '[' objc-receiver.
23622725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor///
23632725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// This routine handles sends to super, class messages (sent to a
23642725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// class name), and instance messages (sent to an object), and the
23652725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// target is represented by \p SuperLoc, \p ReceiverType, or \p
23662725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// ReceiverExpr, respectively. Only one of these parameters may have
23672725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// a valid value.
23682725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor///
23692725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// \param LBracLoc The location of the opening '['.
23702725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor///
23712725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// \param SuperLoc If this is a send to 'super', the location of the
23722725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// 'super' keyword that indicates a send to the superclass.
23732725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor///
23742725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// \param ReceiverType If this is a class message, the type of the
23752725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// class we are sending a message to.
23762725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor///
23772725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// \param ReceiverExpr If this is an instance message, the expression
23782725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor/// used to compute the receiver object.
23791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
23800ccb27ded12fd03eb6818a880f50901bb70254feFariborz Jahanian///   objc-message-args:
23810ccb27ded12fd03eb6818a880f50901bb70254feFariborz Jahanian///     objc-selector
23820ccb27ded12fd03eb6818a880f50901bb70254feFariborz Jahanian///     objc-keywordarg-list
23830ccb27ded12fd03eb6818a880f50901bb70254feFariborz Jahanian///
23840ccb27ded12fd03eb6818a880f50901bb70254feFariborz Jahanian///   objc-keywordarg-list:
23850ccb27ded12fd03eb6818a880f50901bb70254feFariborz Jahanian///     objc-keywordarg
23860ccb27ded12fd03eb6818a880f50901bb70254feFariborz Jahanian///     objc-keywordarg-list objc-keywordarg
23870ccb27ded12fd03eb6818a880f50901bb70254feFariborz Jahanian///
23881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///   objc-keywordarg:
23890ccb27ded12fd03eb6818a880f50901bb70254feFariborz Jahanian///     selector-name[opt] ':' objc-keywordexpr
23900ccb27ded12fd03eb6818a880f50901bb70254feFariborz Jahanian///
23910ccb27ded12fd03eb6818a880f50901bb70254feFariborz Jahanian///   objc-keywordexpr:
23920ccb27ded12fd03eb6818a880f50901bb70254feFariborz Jahanian///     nonempty-expr-list
23930ccb27ded12fd03eb6818a880f50901bb70254feFariborz Jahanian///
23940ccb27ded12fd03eb6818a880f50901bb70254feFariborz Jahanian///   nonempty-expr-list:
23950ccb27ded12fd03eb6818a880f50901bb70254feFariborz Jahanian///     assignment-expression
23960ccb27ded12fd03eb6818a880f50901bb70254feFariborz Jahanian///     nonempty-expr-list , assignment-expression
23971d922960e083906a586609ac6978678147250177Sebastian Redl///
239860d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult
2399699b66138ac307a32e238463e0eff513ff17d337Chris LattnerParser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
24002725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor                                       SourceLocation SuperLoc,
2401b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall                                       ParsedType ReceiverType,
24021d922960e083906a586609ac6978678147250177Sebastian Redl                                       ExprArg ReceiverExpr) {
24030fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor  InMessageExpressionRAIIObject InMessage(*this, true);
24040fbda68b50ce17d7ad36ef7a5ed77518a5cd272eDouglas Gregor
2405c4df6d2c05c647a6a5770ba0c749782b6c023a3aSteve Naroff  if (Tok.is(tok::code_completion)) {
24062725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor    if (SuperLoc.isValid())
240770c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor      Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc, 0, 0,
240870c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor                                           false);
24092725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor    else if (ReceiverType)
241070c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor      Actions.CodeCompleteObjCClassMessage(getCurScope(), ReceiverType, 0, 0,
241170c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor                                           false);
2412c4df6d2c05c647a6a5770ba0c749782b6c023a3aSteve Naroff    else
24139ae2f076ca5ab1feb3ba95629099ec2319833701John McCall      Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr,
241470c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor                                              0, 0, false);
24157d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
24167d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return ExprError();
2417c4df6d2c05c647a6a5770ba0c749782b6c023a3aSteve Naroff  }
2418d3c6854153fd6bc6a412a29e4491dbd0a47bdb14Douglas Gregor
2419a65ff6c81f5b278000839988bb532114fd8c6797Fariborz Jahanian  // Parse objc-selector
24204b6c9051c6522894978c9ba6a819a659d102db36Fariborz Jahanian  SourceLocation Loc;
24212fc5c2428ecb450a3256c8316b93b8655cb76a0fChris Lattner  IdentifierInfo *selIdent = ParseObjCSelectorPiece(Loc);
242268d331a78e655d97294e94fcfa63f92cc1f40578Steve Naroff
24235f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<IdentifierInfo *, 12> KeyIdents;
2424951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis  SmallVector<SourceLocation, 12> KeyLocs;
24254e28d9e2ba9ce237549b45cfd4136ec6536d1325Benjamin Kramer  ExprVector KeyExprs;
242668d331a78e655d97294e94fcfa63f92cc1f40578Steve Naroff
2427df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner  if (Tok.is(tok::colon)) {
2428a65ff6c81f5b278000839988bb532114fd8c6797Fariborz Jahanian    while (1) {
2429a65ff6c81f5b278000839988bb532114fd8c6797Fariborz Jahanian      // Each iteration parses a single keyword argument.
243068d331a78e655d97294e94fcfa63f92cc1f40578Steve Naroff      KeyIdents.push_back(selIdent);
2431951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis      KeyLocs.push_back(Loc);
243237387c932855c6d58d70bdd705cd3a9fdcd2a931Steve Naroff
2433df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner      if (Tok.isNot(tok::colon)) {
2434a65ff6c81f5b278000839988bb532114fd8c6797Fariborz Jahanian        Diag(Tok, diag::err_expected_colon);
24354fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner        // We must manually skip to a ']', otherwise the expression skipper will
24364fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner        // stop at the ']' when it skips to the ';'.  We want it to skip beyond
24374fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner        // the enclosing expression.
24384fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner        SkipUntil(tok::r_square);
24391d922960e083906a586609ac6978678147250177Sebastian Redl        return ExprError();
2440a65ff6c81f5b278000839988bb532114fd8c6797Fariborz Jahanian      }
24411d922960e083906a586609ac6978678147250177Sebastian Redl
244268d331a78e655d97294e94fcfa63f92cc1f40578Steve Naroff      ConsumeToken(); // Eat the ':'.
24431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      ///  Parse the expression after ':'
244470c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor
244570c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor      if (Tok.is(tok::code_completion)) {
244670c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor        if (SuperLoc.isValid())
244770c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor          Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc,
244870c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor                                               KeyIdents.data(),
244970c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor                                               KeyIdents.size(),
245070c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor                                               /*AtArgumentEpression=*/true);
245170c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor        else if (ReceiverType)
245270c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor          Actions.CodeCompleteObjCClassMessage(getCurScope(), ReceiverType,
245370c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor                                               KeyIdents.data(),
245470c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor                                               KeyIdents.size(),
245570c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor                                               /*AtArgumentEpression=*/true);
245670c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor        else
245770c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor          Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr,
245870c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor                                                  KeyIdents.data(),
245970c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor                                                  KeyIdents.size(),
246070c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor                                                  /*AtArgumentEpression=*/true);
246170c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor
24627d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis        cutOffParsing();
246370c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor        return ExprError();
246470c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor      }
246570c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor
246660d7b3a319d84d688752be3870615ac0f111fb16John McCall      ExprResult Res(ParseAssignmentExpression());
24670e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl      if (Res.isInvalid()) {
24684fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner        // We must manually skip to a ']', otherwise the expression skipper will
24694fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner        // stop at the ']' when it skips to the ';'.  We want it to skip beyond
24704fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner        // the enclosing expression.
24714fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner        SkipUntil(tok::r_square);
24723fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer        return Res;
247337387c932855c6d58d70bdd705cd3a9fdcd2a931Steve Naroff      }
24741d922960e083906a586609ac6978678147250177Sebastian Redl
247537387c932855c6d58d70bdd705cd3a9fdcd2a931Steve Naroff      // We have a valid expression.
2476effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl      KeyExprs.push_back(Res.release());
24771d922960e083906a586609ac6978678147250177Sebastian Redl
2478d3c6854153fd6bc6a412a29e4491dbd0a47bdb14Douglas Gregor      // Code completion after each argument.
2479d3c6854153fd6bc6a412a29e4491dbd0a47bdb14Douglas Gregor      if (Tok.is(tok::code_completion)) {
24802725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor        if (SuperLoc.isValid())
248123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor          Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc,
24822725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor                                               KeyIdents.data(),
248370c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor                                               KeyIdents.size(),
248470c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor                                               /*AtArgumentEpression=*/false);
24852725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor        else if (ReceiverType)
248623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor          Actions.CodeCompleteObjCClassMessage(getCurScope(), ReceiverType,
2487d3c6854153fd6bc6a412a29e4491dbd0a47bdb14Douglas Gregor                                               KeyIdents.data(),
248870c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor                                               KeyIdents.size(),
248970c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor                                               /*AtArgumentEpression=*/false);
2490d3c6854153fd6bc6a412a29e4491dbd0a47bdb14Douglas Gregor        else
24919ae2f076ca5ab1feb3ba95629099ec2319833701John McCall          Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr,
2492d3c6854153fd6bc6a412a29e4491dbd0a47bdb14Douglas Gregor                                                  KeyIdents.data(),
249370c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor                                                  KeyIdents.size(),
249470c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor                                                /*AtArgumentEpression=*/false);
24957d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis        cutOffParsing();
249670c5ac70ace21b011dc2d4001bae26cdcf62ff8dDouglas Gregor        return ExprError();
2497d3c6854153fd6bc6a412a29e4491dbd0a47bdb14Douglas Gregor      }
2498d3c6854153fd6bc6a412a29e4491dbd0a47bdb14Douglas Gregor
249937387c932855c6d58d70bdd705cd3a9fdcd2a931Steve Naroff      // Check for another keyword selector.
25002fc5c2428ecb450a3256c8316b93b8655cb76a0fChris Lattner      selIdent = ParseObjCSelectorPiece(Loc);
2501df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner      if (!selIdent && Tok.isNot(tok::colon))
2502a65ff6c81f5b278000839988bb532114fd8c6797Fariborz Jahanian        break;
2503a65ff6c81f5b278000839988bb532114fd8c6797Fariborz Jahanian      // We have a selector or a colon, continue parsing.
2504a65ff6c81f5b278000839988bb532114fd8c6797Fariborz Jahanian    }
2505a65ff6c81f5b278000839988bb532114fd8c6797Fariborz Jahanian    // Parse the, optional, argument list, comma separated.
2506df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner    while (Tok.is(tok::comma)) {
250718df0eba838c7609d10edcb845ca6f35698e822cFariborz Jahanian      SourceLocation commaLoc = ConsumeToken(); // Eat the ','.
25081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      ///  Parse the expression after ','
250960d7b3a319d84d688752be3870615ac0f111fb16John McCall      ExprResult Res(ParseAssignmentExpression());
25100e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl      if (Res.isInvalid()) {
251118df0eba838c7609d10edcb845ca6f35698e822cFariborz Jahanian        if (Tok.is(tok::colon)) {
251218df0eba838c7609d10edcb845ca6f35698e822cFariborz Jahanian          Diag(commaLoc, diag::note_extra_comma_message_arg) <<
251318df0eba838c7609d10edcb845ca6f35698e822cFariborz Jahanian            FixItHint::CreateRemoval(commaLoc);
251418df0eba838c7609d10edcb845ca6f35698e822cFariborz Jahanian        }
25154fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner        // We must manually skip to a ']', otherwise the expression skipper will
25164fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner        // stop at the ']' when it skips to the ';'.  We want it to skip beyond
25174fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner        // the enclosing expression.
25184fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner        SkipUntil(tok::r_square);
25193fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer        return Res;
252049f109c786f99eb7468dac3976db083a65493444Steve Naroff      }
25210e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
252249f109c786f99eb7468dac3976db083a65493444Steve Naroff      // We have a valid expression.
2523effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl      KeyExprs.push_back(Res.release());
2524a65ff6c81f5b278000839988bb532114fd8c6797Fariborz Jahanian    }
2525a65ff6c81f5b278000839988bb532114fd8c6797Fariborz Jahanian  } else if (!selIdent) {
2526a65ff6c81f5b278000839988bb532114fd8c6797Fariborz Jahanian    Diag(Tok, diag::err_expected_ident); // missing selector name.
25271d922960e083906a586609ac6978678147250177Sebastian Redl
25284fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner    // We must manually skip to a ']', otherwise the expression skipper will
25294fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner    // stop at the ']' when it skips to the ';'.  We want it to skip beyond
25304fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner    // the enclosing expression.
25314fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner    SkipUntil(tok::r_square);
25321d922960e083906a586609ac6978678147250177Sebastian Redl    return ExprError();
2533a65ff6c81f5b278000839988bb532114fd8c6797Fariborz Jahanian  }
2534809872eca7f6c024e2ab41ddffbbeeae807bf5dcFariborz Jahanian
2535df19526177bc6d0a3ea4d1ae97497869f60563dbChris Lattner  if (Tok.isNot(tok::r_square)) {
2536809872eca7f6c024e2ab41ddffbbeeae807bf5dcFariborz Jahanian    if (Tok.is(tok::identifier))
2537809872eca7f6c024e2ab41ddffbbeeae807bf5dcFariborz Jahanian      Diag(Tok, diag::err_expected_colon);
2538809872eca7f6c024e2ab41ddffbbeeae807bf5dcFariborz Jahanian    else
2539809872eca7f6c024e2ab41ddffbbeeae807bf5dcFariborz Jahanian      Diag(Tok, diag::err_expected_rsquare);
25404fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner    // We must manually skip to a ']', otherwise the expression skipper will
25414fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner    // stop at the ']' when it skips to the ';'.  We want it to skip beyond
25424fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner    // the enclosing expression.
25434fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner    SkipUntil(tok::r_square);
25441d922960e083906a586609ac6978678147250177Sebastian Redl    return ExprError();
2545a65ff6c81f5b278000839988bb532114fd8c6797Fariborz Jahanian  }
25461d922960e083906a586609ac6978678147250177Sebastian Redl
2547699b66138ac307a32e238463e0eff513ff17d337Chris Lattner  SourceLocation RBracLoc = ConsumeBracket(); // consume ']'
25481d922960e083906a586609ac6978678147250177Sebastian Redl
254929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  unsigned nKeys = KeyIdents.size();
2550951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis  if (nKeys == 0) {
2551ff38491c18b060526d754765b952f4a497a89416Chris Lattner    KeyIdents.push_back(selIdent);
2552951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis    KeyLocs.push_back(Loc);
2553951376242c076c3f62dd78bf672909fc011991dbArgyrios Kyrtzidis  }
2554ff38491c18b060526d754765b952f4a497a89416Chris Lattner  Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]);
25551d922960e083906a586609ac6978678147250177Sebastian Redl
25562725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  if (SuperLoc.isValid())
255723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    return Actions.ActOnSuperMessage(getCurScope(), SuperLoc, Sel,
25584e28d9e2ba9ce237549b45cfd4136ec6536d1325Benjamin Kramer                                     LBracLoc, KeyLocs, RBracLoc, KeyExprs);
25592725ca8eb3354975ca77ed4b88ede7b60b216b9aDouglas Gregor  else if (ReceiverType)
256023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    return Actions.ActOnClassMessage(getCurScope(), ReceiverType, Sel,
25614e28d9e2ba9ce237549b45cfd4136ec6536d1325Benjamin Kramer                                     LBracLoc, KeyLocs, RBracLoc, KeyExprs);
25629ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  return Actions.ActOnInstanceMessage(getCurScope(), ReceiverExpr, Sel,
25634e28d9e2ba9ce237549b45cfd4136ec6536d1325Benjamin Kramer                                      LBracLoc, KeyLocs, RBracLoc, KeyExprs);
25640ccb27ded12fd03eb6818a880f50901bb70254feFariborz Jahanian}
25650ccb27ded12fd03eb6818a880f50901bb70254feFariborz Jahanian
256660d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
256760d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult Res(ParseStringLiteralExpression());
25683fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer  if (Res.isInvalid()) return Res;
25691d922960e083906a586609ac6978678147250177Sebastian Redl
2570b3a99cd5bcaeff0c5ff6a60788b5eb68e52a3953Chris Lattner  // @"foo" @"bar" is a valid concatenated string.  Eat any subsequent string
2571b3a99cd5bcaeff0c5ff6a60788b5eb68e52a3953Chris Lattner  // expressions.  At this point, we know that the only valid thing that starts
2572b3a99cd5bcaeff0c5ff6a60788b5eb68e52a3953Chris Lattner  // with '@' is an @"".
25735f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<SourceLocation, 4> AtLocs;
25744e28d9e2ba9ce237549b45cfd4136ec6536d1325Benjamin Kramer  ExprVector AtStrings;
2575b3a99cd5bcaeff0c5ff6a60788b5eb68e52a3953Chris Lattner  AtLocs.push_back(AtLoc);
2576effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl  AtStrings.push_back(Res.release());
25770e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
2578b3a99cd5bcaeff0c5ff6a60788b5eb68e52a3953Chris Lattner  while (Tok.is(tok::at)) {
2579b3a99cd5bcaeff0c5ff6a60788b5eb68e52a3953Chris Lattner    AtLocs.push_back(ConsumeToken()); // eat the @.
2580b3a99cd5bcaeff0c5ff6a60788b5eb68e52a3953Chris Lattner
258115faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl    // Invalid unless there is a string literal.
258297cf6eb380016db868866faf27a086cd55a316d4Chris Lattner    if (!isTokenStringLiteral())
258397cf6eb380016db868866faf27a086cd55a316d4Chris Lattner      return ExprError(Diag(Tok, diag::err_objc_concat_string));
2584b3a99cd5bcaeff0c5ff6a60788b5eb68e52a3953Chris Lattner
258560d7b3a319d84d688752be3870615ac0f111fb16John McCall    ExprResult Lit(ParseStringLiteralExpression());
25860e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl    if (Lit.isInvalid())
25873fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer      return Lit;
25880e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl
2589effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl    AtStrings.push_back(Lit.release());
2590b3a99cd5bcaeff0c5ff6a60788b5eb68e52a3953Chris Lattner  }
25911d922960e083906a586609ac6978678147250177Sebastian Redl
2592d32b94d4d685522d1552d3d1345ae9616d7f27abNico Weber  return Actions.ParseObjCStringLiteral(&AtLocs[0], AtStrings.data(),
2593d32b94d4d685522d1552d3d1345ae9616d7f27abNico Weber                                        AtStrings.size());
25945508518a2702b00be3b15a26d772bde968972f54Anders Carlsson}
2595f9bcf01f82dfd2688f81e57bcc6300c9b13c51a6Anders Carlsson
2596ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek/// ParseObjCBooleanLiteral -
2597ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek/// objc-scalar-literal : '@' boolean-keyword
2598ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek///                        ;
2599ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek/// boolean-keyword: 'true' | 'false' | '__objc_yes' | '__objc_no'
2600ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek///                        ;
2601ebcb57a8d298862c65043e88b2429591ab3c58d3Ted KremenekExprResult Parser::ParseObjCBooleanLiteral(SourceLocation AtLoc,
2602ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek                                           bool ArgValue) {
2603ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  SourceLocation EndLoc = ConsumeToken();             // consume the keyword.
2604ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  return Actions.ActOnObjCBoolLiteral(AtLoc, EndLoc, ArgValue);
2605ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek}
2606ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2607ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek/// ParseObjCCharacterLiteral -
2608ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek/// objc-scalar-literal : '@' character-literal
2609ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek///                        ;
2610ebcb57a8d298862c65043e88b2429591ab3c58d3Ted KremenekExprResult Parser::ParseObjCCharacterLiteral(SourceLocation AtLoc) {
2611ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  ExprResult Lit(Actions.ActOnCharacterConstant(Tok));
2612ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  if (Lit.isInvalid()) {
26133fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer    return Lit;
2614ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  }
26158b8d9534f185743fb72c59d4e735794e6e0f4335Benjamin Kramer  ConsumeToken(); // Consume the literal token.
2616d32b94d4d685522d1552d3d1345ae9616d7f27abNico Weber  return Actions.BuildObjCNumericLiteral(AtLoc, Lit.take());
2617ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek}
2618ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2619ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek/// ParseObjCNumericLiteral -
2620ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek/// objc-scalar-literal : '@' scalar-literal
2621ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek///                        ;
2622ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek/// scalar-literal : | numeric-constant			/* any numeric constant. */
2623ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek///                    ;
2624ebcb57a8d298862c65043e88b2429591ab3c58d3Ted KremenekExprResult Parser::ParseObjCNumericLiteral(SourceLocation AtLoc) {
2625ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  ExprResult Lit(Actions.ActOnNumericConstant(Tok));
2626ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  if (Lit.isInvalid()) {
26273fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer    return Lit;
2628ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  }
26298b8d9534f185743fb72c59d4e735794e6e0f4335Benjamin Kramer  ConsumeToken(); // Consume the literal token.
2630d32b94d4d685522d1552d3d1345ae9616d7f27abNico Weber  return Actions.BuildObjCNumericLiteral(AtLoc, Lit.take());
2631ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek}
2632ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2633eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard/// ParseObjCBoxedExpr -
2634eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard/// objc-box-expression:
2635eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard///       @( assignment-expression )
2636eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick BeardExprResult
2637eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick BeardParser::ParseObjCBoxedExpr(SourceLocation AtLoc) {
2638eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard  if (Tok.isNot(tok::l_paren))
2639eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard    return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@");
2640eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard
2641eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard  BalancedDelimiterTracker T(*this, tok::l_paren);
2642eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard  T.consumeOpen();
2643eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard  ExprResult ValueExpr(ParseAssignmentExpression());
2644eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard  if (T.consumeClose())
2645eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard    return ExprError();
2646edd27602f9cede4fee2c81c785b8f295c9d28752Argyrios Kyrtzidis
2647edd27602f9cede4fee2c81c785b8f295c9d28752Argyrios Kyrtzidis  if (ValueExpr.isInvalid())
2648edd27602f9cede4fee2c81c785b8f295c9d28752Argyrios Kyrtzidis    return ExprError();
2649edd27602f9cede4fee2c81c785b8f295c9d28752Argyrios Kyrtzidis
2650eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard  // Wrap the sub-expression in a parenthesized expression, to distinguish
2651eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard  // a boxed expression from a literal.
2652eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard  SourceLocation LPLoc = T.getOpenLocation(), RPLoc = T.getCloseLocation();
2653eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard  ValueExpr = Actions.ActOnParenExpr(LPLoc, RPLoc, ValueExpr.take());
2654d32b94d4d685522d1552d3d1345ae9616d7f27abNico Weber  return Actions.BuildObjCBoxedExpr(SourceRange(AtLoc, RPLoc),
2655d32b94d4d685522d1552d3d1345ae9616d7f27abNico Weber                                    ValueExpr.take());
2656eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard}
2657eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard
2658ebcb57a8d298862c65043e88b2429591ab3c58d3Ted KremenekExprResult Parser::ParseObjCArrayLiteral(SourceLocation AtLoc) {
26594e28d9e2ba9ce237549b45cfd4136ec6536d1325Benjamin Kramer  ExprVector ElementExprs;                   // array elements.
2660ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  ConsumeBracket(); // consume the l_square.
2661ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2662ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  while (Tok.isNot(tok::r_square)) {
2663ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    // Parse list of array element expressions (all must be id types).
2664ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    ExprResult Res(ParseAssignmentExpression());
2665ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    if (Res.isInvalid()) {
2666ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      // We must manually skip to a ']', otherwise the expression skipper will
2667ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      // stop at the ']' when it skips to the ';'.  We want it to skip beyond
2668ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      // the enclosing expression.
2669ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      SkipUntil(tok::r_square);
26703fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer      return Res;
2671ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    }
2672ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2673ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    // Parse the ellipsis that indicates a pack expansion.
2674ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    if (Tok.is(tok::ellipsis))
2675ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      Res = Actions.ActOnPackExpansion(Res.get(), ConsumeToken());
2676ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    if (Res.isInvalid())
2677ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      return true;
2678ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2679ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    ElementExprs.push_back(Res.release());
2680ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2681ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    if (Tok.is(tok::comma))
2682ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      ConsumeToken(); // Eat the ','.
2683ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    else if (Tok.isNot(tok::r_square))
2684ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek     return ExprError(Diag(Tok, diag::err_expected_rsquare_or_comma));
2685ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  }
2686ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  SourceLocation EndLoc = ConsumeBracket(); // location of ']'
26874e28d9e2ba9ce237549b45cfd4136ec6536d1325Benjamin Kramer  MultiExprArg Args(ElementExprs);
2688d32b94d4d685522d1552d3d1345ae9616d7f27abNico Weber  return Actions.BuildObjCArrayLiteral(SourceRange(AtLoc, EndLoc), Args);
2689ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek}
2690ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2691ebcb57a8d298862c65043e88b2429591ab3c58d3Ted KremenekExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) {
2692ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  SmallVector<ObjCDictionaryElement, 4> Elements; // dictionary elements.
2693ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  ConsumeBrace(); // consume the l_square.
2694ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  while (Tok.isNot(tok::r_brace)) {
2695ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    // Parse the comma separated key : value expressions.
2696ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    ExprResult KeyExpr;
2697ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    {
2698ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      ColonProtectionRAIIObject X(*this);
2699ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      KeyExpr = ParseAssignmentExpression();
2700ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      if (KeyExpr.isInvalid()) {
2701ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek        // We must manually skip to a '}', otherwise the expression skipper will
2702ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek        // stop at the '}' when it skips to the ';'.  We want it to skip beyond
2703ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek        // the enclosing expression.
2704ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek        SkipUntil(tok::r_brace);
27053fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer        return KeyExpr;
2706ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      }
2707ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    }
2708ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2709ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    if (Tok.is(tok::colon)) {
2710ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      ConsumeToken();
2711ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    } else {
2712ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      return ExprError(Diag(Tok, diag::err_expected_colon));
2713ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    }
2714ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2715ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    ExprResult ValueExpr(ParseAssignmentExpression());
2716ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    if (ValueExpr.isInvalid()) {
2717ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      // We must manually skip to a '}', otherwise the expression skipper will
2718ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      // stop at the '}' when it skips to the ';'.  We want it to skip beyond
2719ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      // the enclosing expression.
2720ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      SkipUntil(tok::r_brace);
27213fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer      return ValueExpr;
2722ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    }
2723ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2724ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    // Parse the ellipsis that designates this as a pack expansion.
2725ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    SourceLocation EllipsisLoc;
27264e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (Tok.is(tok::ellipsis) && getLangOpts().CPlusPlus)
2727ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      EllipsisLoc = ConsumeToken();
2728ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2729ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    // We have a valid expression. Collect it in a vector so we can
2730ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    // build the argument list.
2731ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    ObjCDictionaryElement Element = {
2732ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      KeyExpr.get(), ValueExpr.get(), EllipsisLoc, llvm::Optional<unsigned>()
2733ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    };
2734ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    Elements.push_back(Element);
2735ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2736ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    if (Tok.is(tok::comma))
2737ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      ConsumeToken(); // Eat the ','.
2738ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    else if (Tok.isNot(tok::r_brace))
2739ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek      return ExprError(Diag(Tok, diag::err_expected_rbrace_or_comma));
2740ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  }
2741ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  SourceLocation EndLoc = ConsumeBrace();
2742ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2743ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  // Create the ObjCDictionaryLiteral.
2744d32b94d4d685522d1552d3d1345ae9616d7f27abNico Weber  return Actions.BuildObjCDictionaryLiteral(SourceRange(AtLoc, EndLoc),
2745d32b94d4d685522d1552d3d1345ae9616d7f27abNico Weber                                            Elements.data(), Elements.size());
2746ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek}
2747ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek
2748f9bcf01f82dfd2688f81e57bcc6300c9b13c51a6Anders Carlsson///    objc-encode-expression:
2749e23fb90712233bdfa04387e48b54a7168e23cb3eDmitri Gribenko///      \@encode ( type-name )
275060d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult
27511d922960e083906a586609ac6978678147250177Sebastian RedlParser::ParseObjCEncodeExpression(SourceLocation AtLoc) {
2752861cf3effdc0fbc97d401539bc3050da76b2476fSteve Naroff  assert(Tok.isObjCAtKeyword(tok::objc_encode) && "Not an @encode expression!");
27531d922960e083906a586609ac6978678147250177Sebastian Redl
2754f9bcf01f82dfd2688f81e57bcc6300c9b13c51a6Anders Carlsson  SourceLocation EncLoc = ConsumeToken();
27551d922960e083906a586609ac6978678147250177Sebastian Redl
27564fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner  if (Tok.isNot(tok::l_paren))
27571d922960e083906a586609ac6978678147250177Sebastian Redl    return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@encode");
27581d922960e083906a586609ac6978678147250177Sebastian Redl
27594a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_paren);
27604a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeOpen();
27611d922960e083906a586609ac6978678147250177Sebastian Redl
2762809070a886684cb5b92eb0e00a6581ab1fa6b17aDouglas Gregor  TypeResult Ty = ParseTypeName();
27631d922960e083906a586609ac6978678147250177Sebastian Redl
27644a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
27651d922960e083906a586609ac6978678147250177Sebastian Redl
2766809070a886684cb5b92eb0e00a6581ab1fa6b17aDouglas Gregor  if (Ty.isInvalid())
2767809070a886684cb5b92eb0e00a6581ab1fa6b17aDouglas Gregor    return ExprError();
2768809070a886684cb5b92eb0e00a6581ab1fa6b17aDouglas Gregor
2769d32b94d4d685522d1552d3d1345ae9616d7f27abNico Weber  return Actions.ParseObjCEncodeExpression(AtLoc, EncLoc, T.getOpenLocation(),
2770d32b94d4d685522d1552d3d1345ae9616d7f27abNico Weber                                           Ty.get(), T.getCloseLocation());
2771f9bcf01f82dfd2688f81e57bcc6300c9b13c51a6Anders Carlsson}
277229b2cb1ff1a3dd78edd38e2f43ee7041d3e4ec3cAnders Carlsson
277329b2cb1ff1a3dd78edd38e2f43ee7041d3e4ec3cAnders Carlsson///     objc-protocol-expression
277417d26a6c1f2cb921d0000c337b4967699dc928fdJames Dennett///       \@protocol ( protocol-name )
277560d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult
27761d922960e083906a586609ac6978678147250177Sebastian RedlParser::ParseObjCProtocolExpression(SourceLocation AtLoc) {
277729b2cb1ff1a3dd78edd38e2f43ee7041d3e4ec3cAnders Carlsson  SourceLocation ProtoLoc = ConsumeToken();
27781d922960e083906a586609ac6978678147250177Sebastian Redl
27794fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner  if (Tok.isNot(tok::l_paren))
27801d922960e083906a586609ac6978678147250177Sebastian Redl    return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@protocol");
27811d922960e083906a586609ac6978678147250177Sebastian Redl
27824a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_paren);
27834a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeOpen();
27841d922960e083906a586609ac6978678147250177Sebastian Redl
27854fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner  if (Tok.isNot(tok::identifier))
27861d922960e083906a586609ac6978678147250177Sebastian Redl    return ExprError(Diag(Tok, diag::err_expected_ident));
27871d922960e083906a586609ac6978678147250177Sebastian Redl
2788390d50a725497e99247dc104a7d2c2a255d3af14Fariborz Jahanian  IdentifierInfo *protocolId = Tok.getIdentifierInfo();
27897d24e289bea2accaaed79c6ca3e5cdd0c204ddc1Argyrios Kyrtzidis  SourceLocation ProtoIdLoc = ConsumeToken();
27901d922960e083906a586609ac6978678147250177Sebastian Redl
27914a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
279229b2cb1ff1a3dd78edd38e2f43ee7041d3e4ec3cAnders Carlsson
2793d32b94d4d685522d1552d3d1345ae9616d7f27abNico Weber  return Actions.ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc,
2794d32b94d4d685522d1552d3d1345ae9616d7f27abNico Weber                                             T.getOpenLocation(), ProtoIdLoc,
2795d32b94d4d685522d1552d3d1345ae9616d7f27abNico Weber                                             T.getCloseLocation());
279629b2cb1ff1a3dd78edd38e2f43ee7041d3e4ec3cAnders Carlsson}
2797a0818e3cd7d59d05e6da41015033b5574c3d7893Fariborz Jahanian
2798a0818e3cd7d59d05e6da41015033b5574c3d7893Fariborz Jahanian///     objc-selector-expression
2799a0818e3cd7d59d05e6da41015033b5574c3d7893Fariborz Jahanian///       @selector '(' objc-keyword-selector ')'
280060d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) {
2801a0818e3cd7d59d05e6da41015033b5574c3d7893Fariborz Jahanian  SourceLocation SelectorLoc = ConsumeToken();
28021d922960e083906a586609ac6978678147250177Sebastian Redl
28034fef81d718ca1b91ce2adef52db91a35f86e9bbdChris Lattner  if (Tok.isNot(tok::l_paren))
28041d922960e083906a586609ac6978678147250177Sebastian Redl    return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@selector");
28051d922960e083906a586609ac6978678147250177Sebastian Redl
28065f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<IdentifierInfo *, 12> KeyIdents;
2807a0818e3cd7d59d05e6da41015033b5574c3d7893Fariborz Jahanian  SourceLocation sLoc;
2808458433d2f0f5c96a9e0d21decdd44bebccf20b11Douglas Gregor
28094a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_paren);
28104a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeOpen();
28114a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor
2812458433d2f0f5c96a9e0d21decdd44bebccf20b11Douglas Gregor  if (Tok.is(tok::code_completion)) {
2813458433d2f0f5c96a9e0d21decdd44bebccf20b11Douglas Gregor    Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents.data(),
2814458433d2f0f5c96a9e0d21decdd44bebccf20b11Douglas Gregor                                     KeyIdents.size());
28157d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
2816458433d2f0f5c96a9e0d21decdd44bebccf20b11Douglas Gregor    return ExprError();
2817458433d2f0f5c96a9e0d21decdd44bebccf20b11Douglas Gregor  }
2818458433d2f0f5c96a9e0d21decdd44bebccf20b11Douglas Gregor
28192fc5c2428ecb450a3256c8316b93b8655cb76a0fChris Lattner  IdentifierInfo *SelIdent = ParseObjCSelectorPiece(sLoc);
28205add7541726348b9d1c8e96ac5031b87c41acff0Chris Lattner  if (!SelIdent &&  // missing selector name.
28215add7541726348b9d1c8e96ac5031b87c41acff0Chris Lattner      Tok.isNot(tok::colon) && Tok.isNot(tok::coloncolon))
28221d922960e083906a586609ac6978678147250177Sebastian Redl    return ExprError(Diag(Tok, diag::err_expected_ident));
28231d922960e083906a586609ac6978678147250177Sebastian Redl
2824b62f6813406a03bf8a371c4e46c9fad51d102121Fariborz Jahanian  KeyIdents.push_back(SelIdent);
2825887407e71fd58de452361b77d72970e32b20ebe0Steve Naroff  unsigned nColons = 0;
2826887407e71fd58de452361b77d72970e32b20ebe0Steve Naroff  if (Tok.isNot(tok::r_paren)) {
2827a0818e3cd7d59d05e6da41015033b5574c3d7893Fariborz Jahanian    while (1) {
28285add7541726348b9d1c8e96ac5031b87c41acff0Chris Lattner      if (Tok.is(tok::coloncolon)) { // Handle :: in C++.
28295add7541726348b9d1c8e96ac5031b87c41acff0Chris Lattner        ++nColons;
28305add7541726348b9d1c8e96ac5031b87c41acff0Chris Lattner        KeyIdents.push_back(0);
28315add7541726348b9d1c8e96ac5031b87c41acff0Chris Lattner      } else if (Tok.isNot(tok::colon))
28321d922960e083906a586609ac6978678147250177Sebastian Redl        return ExprError(Diag(Tok, diag::err_expected_colon));
28331d922960e083906a586609ac6978678147250177Sebastian Redl
28345add7541726348b9d1c8e96ac5031b87c41acff0Chris Lattner      ++nColons;
28353b3e1a9e79703da067d23756e5624a4f487d6278Chris Lattner      ConsumeToken(); // Eat the ':' or '::'.
2836a0818e3cd7d59d05e6da41015033b5574c3d7893Fariborz Jahanian      if (Tok.is(tok::r_paren))
2837a0818e3cd7d59d05e6da41015033b5574c3d7893Fariborz Jahanian        break;
2838458433d2f0f5c96a9e0d21decdd44bebccf20b11Douglas Gregor
2839458433d2f0f5c96a9e0d21decdd44bebccf20b11Douglas Gregor      if (Tok.is(tok::code_completion)) {
2840458433d2f0f5c96a9e0d21decdd44bebccf20b11Douglas Gregor        Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents.data(),
2841458433d2f0f5c96a9e0d21decdd44bebccf20b11Douglas Gregor                                         KeyIdents.size());
28427d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis        cutOffParsing();
2843458433d2f0f5c96a9e0d21decdd44bebccf20b11Douglas Gregor        return ExprError();
2844458433d2f0f5c96a9e0d21decdd44bebccf20b11Douglas Gregor      }
2845458433d2f0f5c96a9e0d21decdd44bebccf20b11Douglas Gregor
2846a0818e3cd7d59d05e6da41015033b5574c3d7893Fariborz Jahanian      // Check for another keyword selector.
2847a0818e3cd7d59d05e6da41015033b5574c3d7893Fariborz Jahanian      SourceLocation Loc;
28482fc5c2428ecb450a3256c8316b93b8655cb76a0fChris Lattner      SelIdent = ParseObjCSelectorPiece(Loc);
2849b62f6813406a03bf8a371c4e46c9fad51d102121Fariborz Jahanian      KeyIdents.push_back(SelIdent);
28503b3e1a9e79703da067d23756e5624a4f487d6278Chris Lattner      if (!SelIdent && Tok.isNot(tok::colon) && Tok.isNot(tok::coloncolon))
2851a0818e3cd7d59d05e6da41015033b5574c3d7893Fariborz Jahanian        break;
2852a0818e3cd7d59d05e6da41015033b5574c3d7893Fariborz Jahanian    }
2853887407e71fd58de452361b77d72970e32b20ebe0Steve Naroff  }
28544a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
2855887407e71fd58de452361b77d72970e32b20ebe0Steve Naroff  Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]);
2856d32b94d4d685522d1552d3d1345ae9616d7f27abNico Weber  return Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc,
2857d32b94d4d685522d1552d3d1345ae9616d7f27abNico Weber                                             T.getOpenLocation(),
2858d32b94d4d685522d1552d3d1345ae9616d7f27abNico Weber                                             T.getCloseLocation());
285958065b2d8038a4e9a91ea4813bd1774c0f6efacbGabor Greif }
2860140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian
28616c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanianvoid Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) {
28626c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian  // MCDecl might be null due to error in method or c-function  prototype, etc.
28636c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian  Decl *MCDecl = LM.D;
28646c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian  bool skip = MCDecl &&
28656c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian              ((parseMethod && !Actions.isObjCMethodDecl(MCDecl)) ||
28666c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian              (!parseMethod && Actions.isObjCMethodDecl(MCDecl)));
28676c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian  if (skip)
28686c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian    return;
28696c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian
2870a24195aaf71cee202f92ea4bad50358f3d0b701fArgyrios Kyrtzidis  // Save the current token position.
2871a24195aaf71cee202f92ea4bad50358f3d0b701fArgyrios Kyrtzidis  SourceLocation OrigLoc = Tok.getLocation();
2872a24195aaf71cee202f92ea4bad50358f3d0b701fArgyrios Kyrtzidis
2873140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian  assert(!LM.Toks.empty() && "ParseLexedObjCMethodDef - Empty body!");
2874140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian  // Append the current token at the end of the new token stream so that it
2875140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian  // doesn't get lost.
2876140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian  LM.Toks.push_back(Tok);
2877140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian  PP.EnterTokenStream(LM.Toks.data(), LM.Toks.size(), true, false);
2878140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian
2879140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian  // Consume the previously pushed token.
2880140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian  ConsumeAnyToken();
2881140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian
28829e5df312551bc92f0a6c908288effef2e2ed0ee7Fariborz Jahanian  assert((Tok.is(tok::l_brace) || Tok.is(tok::kw_try) ||
28839e5df312551bc92f0a6c908288effef2e2ed0ee7Fariborz Jahanian          Tok.is(tok::colon)) &&
28849e5df312551bc92f0a6c908288effef2e2ed0ee7Fariborz Jahanian          "Inline objective-c method not starting with '{' or 'try' or ':'");
28856c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian  // Enter a scope for the method or c-fucntion body.
2886140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian  ParseScope BodyScope(this,
28876c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian                       parseMethod
28886c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian                       ? Scope::ObjCMethodScope|Scope::FnScope|Scope::DeclScope
28896c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian                       : Scope::FnScope|Scope::DeclScope);
2890140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian
28916c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian  // Tell the actions module that we have entered a method or c-function definition
28926c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian  // with the specified Declarator for the method/function.
28938c6cb462946b8be19167fad7ff21d4f9fbaebfefFariborz Jahanian  if (parseMethod)
28948c6cb462946b8be19167fad7ff21d4f9fbaebfefFariborz Jahanian    Actions.ActOnStartOfObjCMethodDef(getCurScope(), MCDecl);
28958c6cb462946b8be19167fad7ff21d4f9fbaebfefFariborz Jahanian  else
28968c6cb462946b8be19167fad7ff21d4f9fbaebfefFariborz Jahanian    Actions.ActOnStartOfFunctionDef(getCurScope(), MCDecl);
28972eb362b50f34296c39d5ec3e5e1bd6a2c9a5877eFariborz Jahanian  if (Tok.is(tok::kw_try))
28982eb362b50f34296c39d5ec3e5e1bd6a2c9a5877eFariborz Jahanian    MCDecl = ParseFunctionTryBlock(MCDecl, BodyScope);
28999e5df312551bc92f0a6c908288effef2e2ed0ee7Fariborz Jahanian  else {
29009e5df312551bc92f0a6c908288effef2e2ed0ee7Fariborz Jahanian    if (Tok.is(tok::colon))
29019e5df312551bc92f0a6c908288effef2e2ed0ee7Fariborz Jahanian      ParseConstructorInitializer(MCDecl);
29022eb362b50f34296c39d5ec3e5e1bd6a2c9a5877eFariborz Jahanian    MCDecl = ParseFunctionStatementBody(MCDecl, BodyScope);
29039e5df312551bc92f0a6c908288effef2e2ed0ee7Fariborz Jahanian  }
29046940972c33891ff5d2189fbf232dcdeee0e9daf8Fariborz Jahanian
2905a24195aaf71cee202f92ea4bad50358f3d0b701fArgyrios Kyrtzidis  if (Tok.getLocation() != OrigLoc) {
2906a24195aaf71cee202f92ea4bad50358f3d0b701fArgyrios Kyrtzidis    // Due to parsing error, we either went over the cached tokens or
2907a24195aaf71cee202f92ea4bad50358f3d0b701fArgyrios Kyrtzidis    // there are still cached tokens left. If it's the latter case skip the
2908a24195aaf71cee202f92ea4bad50358f3d0b701fArgyrios Kyrtzidis    // leftover tokens.
2909a24195aaf71cee202f92ea4bad50358f3d0b701fArgyrios Kyrtzidis    // Since this is an uncommon situation that should be avoided, use the
2910a24195aaf71cee202f92ea4bad50358f3d0b701fArgyrios Kyrtzidis    // expensive isBeforeInTranslationUnit call.
2911a24195aaf71cee202f92ea4bad50358f3d0b701fArgyrios Kyrtzidis    if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(),
2912a24195aaf71cee202f92ea4bad50358f3d0b701fArgyrios Kyrtzidis                                                     OrigLoc))
2913a24195aaf71cee202f92ea4bad50358f3d0b701fArgyrios Kyrtzidis      while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof))
2914a24195aaf71cee202f92ea4bad50358f3d0b701fArgyrios Kyrtzidis        ConsumeAnyToken();
2915a24195aaf71cee202f92ea4bad50358f3d0b701fArgyrios Kyrtzidis  }
2916a24195aaf71cee202f92ea4bad50358f3d0b701fArgyrios Kyrtzidis
29176c89eafc90f5c51a0bf185a993961170aee530c2Fariborz Jahanian  return;
2918140ab234c23f392d5422691c5de1ee3c15026defFariborz Jahanian}
2919