ParseObjc.cpp revision f13ca06e57ac094ed05ea08c26a499af1ba0ce88
1//===--- ParseObjC.cpp - Objective C Parsing ------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file implements the Objective-C portions of the Parser interface.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Parse/Parser.h"
15#include "clang/Parse/DeclSpec.h"
16#include "clang/Parse/Scope.h"
17#include "clang/Parse/ParseDiagnostic.h"
18#include "llvm/ADT/SmallVector.h"
19using namespace clang;
20
21
22/// ParseObjCAtDirectives - Handle parts of the external-declaration production:
23///       external-declaration: [C99 6.9]
24/// [OBJC]  objc-class-definition
25/// [OBJC]  objc-class-declaration
26/// [OBJC]  objc-alias-declaration
27/// [OBJC]  objc-protocol-definition
28/// [OBJC]  objc-method-definition
29/// [OBJC]  '@' 'end'
30Parser::DeclPtrTy Parser::ParseObjCAtDirectives() {
31  SourceLocation AtLoc = ConsumeToken(); // the "@"
32
33  if (Tok.is(tok::code_completion)) {
34    Actions.CodeCompleteObjCAtDirective(CurScope, ObjCImpDecl, false);
35    ConsumeCodeCompletionToken();
36  }
37
38  switch (Tok.getObjCKeywordID()) {
39  case tok::objc_class:
40    return ParseObjCAtClassDeclaration(AtLoc);
41  case tok::objc_interface:
42    return ParseObjCAtInterfaceDeclaration(AtLoc);
43  case tok::objc_protocol:
44    return ParseObjCAtProtocolDeclaration(AtLoc);
45  case tok::objc_implementation:
46    return ParseObjCAtImplementationDeclaration(AtLoc);
47  case tok::objc_end:
48    return ParseObjCAtEndDeclaration(AtLoc);
49  case tok::objc_compatibility_alias:
50    return ParseObjCAtAliasDeclaration(AtLoc);
51  case tok::objc_synthesize:
52    return ParseObjCPropertySynthesize(AtLoc);
53  case tok::objc_dynamic:
54    return ParseObjCPropertyDynamic(AtLoc);
55  default:
56    Diag(AtLoc, diag::err_unexpected_at);
57    SkipUntil(tok::semi);
58    return DeclPtrTy();
59  }
60}
61
62///
63/// objc-class-declaration:
64///    '@' 'class' identifier-list ';'
65///
66Parser::DeclPtrTy Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) {
67  ConsumeToken(); // the identifier "class"
68  llvm::SmallVector<IdentifierInfo *, 8> ClassNames;
69  llvm::SmallVector<SourceLocation, 8> ClassLocs;
70
71
72  while (1) {
73    if (Tok.isNot(tok::identifier)) {
74      Diag(Tok, diag::err_expected_ident);
75      SkipUntil(tok::semi);
76      return DeclPtrTy();
77    }
78    ClassNames.push_back(Tok.getIdentifierInfo());
79    ClassLocs.push_back(Tok.getLocation());
80    ConsumeToken();
81
82    if (Tok.isNot(tok::comma))
83      break;
84
85    ConsumeToken();
86  }
87
88  // Consume the ';'.
89  if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@class"))
90    return DeclPtrTy();
91
92  return Actions.ActOnForwardClassDeclaration(atLoc, ClassNames.data(),
93                                              ClassLocs.data(),
94                                              ClassNames.size());
95}
96
97///
98///   objc-interface:
99///     objc-class-interface-attributes[opt] objc-class-interface
100///     objc-category-interface
101///
102///   objc-class-interface:
103///     '@' 'interface' identifier objc-superclass[opt]
104///       objc-protocol-refs[opt]
105///       objc-class-instance-variables[opt]
106///       objc-interface-decl-list
107///     @end
108///
109///   objc-category-interface:
110///     '@' 'interface' identifier '(' identifier[opt] ')'
111///       objc-protocol-refs[opt]
112///       objc-interface-decl-list
113///     @end
114///
115///   objc-superclass:
116///     ':' identifier
117///
118///   objc-class-interface-attributes:
119///     __attribute__((visibility("default")))
120///     __attribute__((visibility("hidden")))
121///     __attribute__((deprecated))
122///     __attribute__((unavailable))
123///     __attribute__((objc_exception)) - used by NSException on 64-bit
124///
125Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
126  SourceLocation atLoc, AttributeList *attrList) {
127  assert(Tok.isObjCAtKeyword(tok::objc_interface) &&
128         "ParseObjCAtInterfaceDeclaration(): Expected @interface");
129  ConsumeToken(); // the "interface" identifier
130
131  // Code completion after '@interface'.
132  if (Tok.is(tok::code_completion)) {
133    Actions.CodeCompleteObjCInterfaceDecl(CurScope);
134    ConsumeCodeCompletionToken();
135  }
136
137  if (Tok.isNot(tok::identifier)) {
138    Diag(Tok, diag::err_expected_ident); // missing class or category name.
139    return DeclPtrTy();
140  }
141
142  // We have a class or category name - consume it.
143  IdentifierInfo *nameId = Tok.getIdentifierInfo();
144  SourceLocation nameLoc = ConsumeToken();
145  if (Tok.is(tok::l_paren) &&
146      !isKnownToBeTypeSpecifier(GetLookAheadToken(1))) { // we have a category.
147    SourceLocation lparenLoc = ConsumeParen();
148    SourceLocation categoryLoc, rparenLoc;
149    IdentifierInfo *categoryId = 0;
150    if (Tok.is(tok::code_completion)) {
151      Actions.CodeCompleteObjCInterfaceCategory(CurScope, nameId, nameLoc);
152      ConsumeCodeCompletionToken();
153    }
154
155    // For ObjC2, the category name is optional (not an error).
156    if (Tok.is(tok::identifier)) {
157      categoryId = Tok.getIdentifierInfo();
158      categoryLoc = ConsumeToken();
159    }
160    else if (!getLang().ObjC2) {
161      Diag(Tok, diag::err_expected_ident); // missing category name.
162      return DeclPtrTy();
163    }
164    if (Tok.isNot(tok::r_paren)) {
165      Diag(Tok, diag::err_expected_rparen);
166      SkipUntil(tok::r_paren, false); // don't stop at ';'
167      return DeclPtrTy();
168    }
169    rparenLoc = ConsumeParen();
170    // Next, we need to check for any protocol references.
171    SourceLocation LAngleLoc, EndProtoLoc;
172    llvm::SmallVector<DeclPtrTy, 8> ProtocolRefs;
173    llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
174    if (Tok.is(tok::less) &&
175        ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true,
176                                    LAngleLoc, EndProtoLoc))
177      return DeclPtrTy();
178
179    if (attrList) // categories don't support attributes.
180      Diag(Tok, diag::err_objc_no_attributes_on_category);
181
182    DeclPtrTy CategoryType =
183    Actions.ActOnStartCategoryInterface(atLoc,
184                                        nameId, nameLoc,
185                                        categoryId, categoryLoc,
186                                        ProtocolRefs.data(),
187                                        ProtocolRefs.size(),
188                                        ProtocolLocs.data(),
189                                        EndProtoLoc);
190    if (Tok.is(tok::l_brace))
191      ParseObjCClassInstanceVariables(CategoryType, tok::objc_private,
192                                      atLoc);
193
194    ParseObjCInterfaceDeclList(CategoryType, tok::objc_not_keyword);
195    return CategoryType;
196  }
197  // Parse a class interface.
198  IdentifierInfo *superClassId = 0;
199  SourceLocation superClassLoc;
200
201  if (Tok.is(tok::colon)) { // a super class is specified.
202    ConsumeToken();
203
204    // Code completion of superclass names.
205    if (Tok.is(tok::code_completion)) {
206      Actions.CodeCompleteObjCSuperclass(CurScope, nameId, nameLoc);
207      ConsumeCodeCompletionToken();
208    }
209
210    if (Tok.isNot(tok::identifier)) {
211      Diag(Tok, diag::err_expected_ident); // missing super class name.
212      return DeclPtrTy();
213    }
214    superClassId = Tok.getIdentifierInfo();
215    superClassLoc = ConsumeToken();
216  }
217  // Next, we need to check for any protocol references.
218  llvm::SmallVector<Action::DeclPtrTy, 8> ProtocolRefs;
219  llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
220  SourceLocation LAngleLoc, EndProtoLoc;
221  if (Tok.is(tok::less) &&
222      ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true,
223                                  LAngleLoc, EndProtoLoc))
224    return DeclPtrTy();
225
226  DeclPtrTy ClsType =
227    Actions.ActOnStartClassInterface(atLoc, nameId, nameLoc,
228                                     superClassId, superClassLoc,
229                                     ProtocolRefs.data(), ProtocolRefs.size(),
230                                     ProtocolLocs.data(),
231                                     EndProtoLoc, attrList);
232
233  if (Tok.is(tok::l_brace))
234    ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, atLoc);
235
236  ParseObjCInterfaceDeclList(ClsType, tok::objc_interface);
237  return ClsType;
238}
239
240/// The Objective-C property callback.  This should be defined where
241/// it's used, but instead it's been lifted to here to support VS2005.
242struct Parser::ObjCPropertyCallback : FieldCallback {
243  Parser &P;
244  DeclPtrTy IDecl;
245  llvm::SmallVectorImpl<DeclPtrTy> &Props;
246  ObjCDeclSpec &OCDS;
247  SourceLocation AtLoc;
248  tok::ObjCKeywordKind MethodImplKind;
249
250  ObjCPropertyCallback(Parser &P, DeclPtrTy IDecl,
251                       llvm::SmallVectorImpl<DeclPtrTy> &Props,
252                       ObjCDeclSpec &OCDS, SourceLocation AtLoc,
253                       tok::ObjCKeywordKind MethodImplKind) :
254    P(P), IDecl(IDecl), Props(Props), OCDS(OCDS), AtLoc(AtLoc),
255    MethodImplKind(MethodImplKind) {
256  }
257
258  DeclPtrTy invoke(FieldDeclarator &FD) {
259    if (FD.D.getIdentifier() == 0) {
260      P.Diag(AtLoc, diag::err_objc_property_requires_field_name)
261        << FD.D.getSourceRange();
262      return DeclPtrTy();
263    }
264    if (FD.BitfieldSize) {
265      P.Diag(AtLoc, diag::err_objc_property_bitfield)
266        << FD.D.getSourceRange();
267      return DeclPtrTy();
268    }
269
270    // Install the property declarator into interfaceDecl.
271    IdentifierInfo *SelName =
272      OCDS.getGetterName() ? OCDS.getGetterName() : FD.D.getIdentifier();
273
274    Selector GetterSel =
275      P.PP.getSelectorTable().getNullarySelector(SelName);
276    IdentifierInfo *SetterName = OCDS.getSetterName();
277    Selector SetterSel;
278    if (SetterName)
279      SetterSel = P.PP.getSelectorTable().getSelector(1, &SetterName);
280    else
281      SetterSel = SelectorTable::constructSetterName(P.PP.getIdentifierTable(),
282                                                     P.PP.getSelectorTable(),
283                                                     FD.D.getIdentifier());
284    bool isOverridingProperty = false;
285    DeclPtrTy Property =
286      P.Actions.ActOnProperty(P.CurScope, AtLoc, FD, OCDS,
287                              GetterSel, SetterSel, IDecl,
288                              &isOverridingProperty,
289                              MethodImplKind);
290    if (!isOverridingProperty)
291      Props.push_back(Property);
292
293    return Property;
294  }
295};
296
297///   objc-interface-decl-list:
298///     empty
299///     objc-interface-decl-list objc-property-decl [OBJC2]
300///     objc-interface-decl-list objc-method-requirement [OBJC2]
301///     objc-interface-decl-list objc-method-proto ';'
302///     objc-interface-decl-list declaration
303///     objc-interface-decl-list ';'
304///
305///   objc-method-requirement: [OBJC2]
306///     @required
307///     @optional
308///
309void Parser::ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl,
310                                        tok::ObjCKeywordKind contextKey) {
311  llvm::SmallVector<DeclPtrTy, 32> allMethods;
312  llvm::SmallVector<DeclPtrTy, 16> allProperties;
313  llvm::SmallVector<DeclGroupPtrTy, 8> allTUVariables;
314  tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword;
315
316  SourceRange AtEnd;
317
318  while (1) {
319    // If this is a method prototype, parse it.
320    if (Tok.is(tok::minus) || Tok.is(tok::plus)) {
321      DeclPtrTy methodPrototype =
322        ParseObjCMethodPrototype(interfaceDecl, MethodImplKind);
323      allMethods.push_back(methodPrototype);
324      // Consume the ';' here, since ParseObjCMethodPrototype() is re-used for
325      // method definitions.
326      ExpectAndConsume(tok::semi, diag::err_expected_semi_after_method_proto,
327                       "", tok::semi);
328      continue;
329    }
330    if (Tok.is(tok::l_paren)) {
331      Diag(Tok, diag::err_expected_minus_or_plus);
332      DeclPtrTy methodPrototype = ParseObjCMethodDecl(Tok.getLocation(),
333                                                      tok::minus,
334                                                      interfaceDecl,
335                                                      MethodImplKind);
336      continue;
337    }
338    // Ignore excess semicolons.
339    if (Tok.is(tok::semi)) {
340      ConsumeToken();
341      continue;
342    }
343
344    // If we got to the end of the file, exit the loop.
345    if (Tok.is(tok::eof))
346      break;
347
348    // Code completion within an Objective-C interface.
349    if (Tok.is(tok::code_completion)) {
350      Actions.CodeCompleteOrdinaryName(CurScope,
351                                  ObjCImpDecl? Action::CCC_ObjCImplementation
352                                             : Action::CCC_ObjCInterface);
353      ConsumeCodeCompletionToken();
354    }
355
356    // If we don't have an @ directive, parse it as a function definition.
357    if (Tok.isNot(tok::at)) {
358      // The code below does not consume '}'s because it is afraid of eating the
359      // end of a namespace.  Because of the way this code is structured, an
360      // erroneous r_brace would cause an infinite loop if not handled here.
361      if (Tok.is(tok::r_brace))
362        break;
363
364      // FIXME: as the name implies, this rule allows function definitions.
365      // We could pass a flag or check for functions during semantic analysis.
366      allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(0));
367      continue;
368    }
369
370    // Otherwise, we have an @ directive, eat the @.
371    SourceLocation AtLoc = ConsumeToken(); // the "@"
372    if (Tok.is(tok::code_completion)) {
373      Actions.CodeCompleteObjCAtDirective(CurScope, ObjCImpDecl, true);
374      ConsumeCodeCompletionToken();
375      break;
376    }
377
378    tok::ObjCKeywordKind DirectiveKind = Tok.getObjCKeywordID();
379
380    if (DirectiveKind == tok::objc_end) { // @end -> terminate list
381      AtEnd.setBegin(AtLoc);
382      AtEnd.setEnd(Tok.getLocation());
383      break;
384    } else if (DirectiveKind == tok::objc_not_keyword) {
385      Diag(Tok, diag::err_objc_unknown_at);
386      SkipUntil(tok::semi);
387      continue;
388    }
389
390    // Eat the identifier.
391    ConsumeToken();
392
393    switch (DirectiveKind) {
394    default:
395      // FIXME: If someone forgets an @end on a protocol, this loop will
396      // continue to eat up tons of stuff and spew lots of nonsense errors.  It
397      // would probably be better to bail out if we saw an @class or @interface
398      // or something like that.
399      Diag(AtLoc, diag::err_objc_illegal_interface_qual);
400      // Skip until we see an '@' or '}' or ';'.
401      SkipUntil(tok::r_brace, tok::at);
402      break;
403
404    case tok::objc_required:
405    case tok::objc_optional:
406      // This is only valid on protocols.
407      // FIXME: Should this check for ObjC2 being enabled?
408      if (contextKey != tok::objc_protocol)
409        Diag(AtLoc, diag::err_objc_directive_only_in_protocol);
410      else
411        MethodImplKind = DirectiveKind;
412      break;
413
414    case tok::objc_property:
415      if (!getLang().ObjC2)
416        Diag(AtLoc, diag::err_objc_propertoes_require_objc2);
417
418      ObjCDeclSpec OCDS;
419      // Parse property attribute list, if any.
420      if (Tok.is(tok::l_paren))
421        ParseObjCPropertyAttribute(OCDS, interfaceDecl,
422                                   allMethods.data(), allMethods.size());
423
424      ObjCPropertyCallback Callback(*this, interfaceDecl, allProperties,
425                                    OCDS, AtLoc, MethodImplKind);
426
427      // Parse all the comma separated declarators.
428      DeclSpec DS;
429      ParseStructDeclaration(DS, Callback);
430
431      ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list, "",
432                       tok::at);
433      break;
434    }
435  }
436
437  // We break out of the big loop in two cases: when we see @end or when we see
438  // EOF.  In the former case, eat the @end.  In the later case, emit an error.
439  if (Tok.is(tok::code_completion)) {
440    Actions.CodeCompleteObjCAtDirective(CurScope, ObjCImpDecl, true);
441    ConsumeCodeCompletionToken();
442  } else if (Tok.isObjCAtKeyword(tok::objc_end))
443    ConsumeToken(); // the "end" identifier
444  else
445    Diag(Tok, diag::err_objc_missing_end);
446
447  // Insert collected methods declarations into the @interface object.
448  // This passes in an invalid SourceLocation for AtEndLoc when EOF is hit.
449  Actions.ActOnAtEnd(CurScope, AtEnd, interfaceDecl,
450                     allMethods.data(), allMethods.size(),
451                     allProperties.data(), allProperties.size(),
452                     allTUVariables.data(), allTUVariables.size());
453}
454
455///   Parse property attribute declarations.
456///
457///   property-attr-decl: '(' property-attrlist ')'
458///   property-attrlist:
459///     property-attribute
460///     property-attrlist ',' property-attribute
461///   property-attribute:
462///     getter '=' identifier
463///     setter '=' identifier ':'
464///     readonly
465///     readwrite
466///     assign
467///     retain
468///     copy
469///     nonatomic
470///
471void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS, DeclPtrTy ClassDecl,
472                                        DeclPtrTy *Methods,
473                                        unsigned NumMethods) {
474  assert(Tok.getKind() == tok::l_paren);
475  SourceLocation LHSLoc = ConsumeParen(); // consume '('
476
477  while (1) {
478    if (Tok.is(tok::code_completion)) {
479      Actions.CodeCompleteObjCPropertyFlags(CurScope, DS);
480      ConsumeCodeCompletionToken();
481    }
482    const IdentifierInfo *II = Tok.getIdentifierInfo();
483
484    // If this is not an identifier at all, bail out early.
485    if (II == 0) {
486      MatchRHSPunctuation(tok::r_paren, LHSLoc);
487      return;
488    }
489
490    SourceLocation AttrName = ConsumeToken(); // consume last attribute name
491
492    if (II->isStr("readonly"))
493      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_readonly);
494    else if (II->isStr("assign"))
495      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_assign);
496    else if (II->isStr("readwrite"))
497      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_readwrite);
498    else if (II->isStr("retain"))
499      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_retain);
500    else if (II->isStr("copy"))
501      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_copy);
502    else if (II->isStr("nonatomic"))
503      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nonatomic);
504    else if (II->isStr("getter") || II->isStr("setter")) {
505      // getter/setter require extra treatment.
506      if (ExpectAndConsume(tok::equal, diag::err_objc_expected_equal, "",
507                           tok::r_paren))
508        return;
509
510      if (Tok.is(tok::code_completion)) {
511        if (II->getNameStart()[0] == 's')
512          Actions.CodeCompleteObjCPropertySetter(CurScope, ClassDecl,
513                                                 Methods, NumMethods);
514        else
515          Actions.CodeCompleteObjCPropertyGetter(CurScope, ClassDecl,
516                                                 Methods, NumMethods);
517        ConsumeCodeCompletionToken();
518      }
519
520      if (Tok.isNot(tok::identifier)) {
521        Diag(Tok, diag::err_expected_ident);
522        SkipUntil(tok::r_paren);
523        return;
524      }
525
526      if (II->getNameStart()[0] == 's') {
527        DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_setter);
528        DS.setSetterName(Tok.getIdentifierInfo());
529        ConsumeToken();  // consume method name
530
531        if (ExpectAndConsume(tok::colon,
532                             diag::err_expected_colon_after_setter_name, "",
533                             tok::r_paren))
534          return;
535      } else {
536        DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_getter);
537        DS.setGetterName(Tok.getIdentifierInfo());
538        ConsumeToken();  // consume method name
539      }
540    } else {
541      Diag(AttrName, diag::err_objc_expected_property_attr) << II;
542      SkipUntil(tok::r_paren);
543      return;
544    }
545
546    if (Tok.isNot(tok::comma))
547      break;
548
549    ConsumeToken();
550  }
551
552  MatchRHSPunctuation(tok::r_paren, LHSLoc);
553}
554
555///   objc-method-proto:
556///     objc-instance-method objc-method-decl objc-method-attributes[opt]
557///     objc-class-method objc-method-decl objc-method-attributes[opt]
558///
559///   objc-instance-method: '-'
560///   objc-class-method: '+'
561///
562///   objc-method-attributes:         [OBJC2]
563///     __attribute__((deprecated))
564///
565Parser::DeclPtrTy Parser::ParseObjCMethodPrototype(DeclPtrTy IDecl,
566                                          tok::ObjCKeywordKind MethodImplKind) {
567  assert((Tok.is(tok::minus) || Tok.is(tok::plus)) && "expected +/-");
568
569  tok::TokenKind methodType = Tok.getKind();
570  SourceLocation mLoc = ConsumeToken();
571
572  DeclPtrTy MDecl = ParseObjCMethodDecl(mLoc, methodType, IDecl,MethodImplKind);
573  // Since this rule is used for both method declarations and definitions,
574  // the caller is (optionally) responsible for consuming the ';'.
575  return MDecl;
576}
577
578///   objc-selector:
579///     identifier
580///     one of
581///       enum struct union if else while do for switch case default
582///       break continue return goto asm sizeof typeof __alignof
583///       unsigned long const short volatile signed restrict _Complex
584///       in out inout bycopy byref oneway int char float double void _Bool
585///
586IdentifierInfo *Parser::ParseObjCSelectorPiece(SourceLocation &SelectorLoc) {
587  switch (Tok.getKind()) {
588  default:
589    return 0;
590  case tok::identifier:
591  case tok::kw_asm:
592  case tok::kw_auto:
593  case tok::kw_bool:
594  case tok::kw_break:
595  case tok::kw_case:
596  case tok::kw_catch:
597  case tok::kw_char:
598  case tok::kw_class:
599  case tok::kw_const:
600  case tok::kw_const_cast:
601  case tok::kw_continue:
602  case tok::kw_default:
603  case tok::kw_delete:
604  case tok::kw_do:
605  case tok::kw_double:
606  case tok::kw_dynamic_cast:
607  case tok::kw_else:
608  case tok::kw_enum:
609  case tok::kw_explicit:
610  case tok::kw_export:
611  case tok::kw_extern:
612  case tok::kw_false:
613  case tok::kw_float:
614  case tok::kw_for:
615  case tok::kw_friend:
616  case tok::kw_goto:
617  case tok::kw_if:
618  case tok::kw_inline:
619  case tok::kw_int:
620  case tok::kw_long:
621  case tok::kw_mutable:
622  case tok::kw_namespace:
623  case tok::kw_new:
624  case tok::kw_operator:
625  case tok::kw_private:
626  case tok::kw_protected:
627  case tok::kw_public:
628  case tok::kw_register:
629  case tok::kw_reinterpret_cast:
630  case tok::kw_restrict:
631  case tok::kw_return:
632  case tok::kw_short:
633  case tok::kw_signed:
634  case tok::kw_sizeof:
635  case tok::kw_static:
636  case tok::kw_static_cast:
637  case tok::kw_struct:
638  case tok::kw_switch:
639  case tok::kw_template:
640  case tok::kw_this:
641  case tok::kw_throw:
642  case tok::kw_true:
643  case tok::kw_try:
644  case tok::kw_typedef:
645  case tok::kw_typeid:
646  case tok::kw_typename:
647  case tok::kw_typeof:
648  case tok::kw_union:
649  case tok::kw_unsigned:
650  case tok::kw_using:
651  case tok::kw_virtual:
652  case tok::kw_void:
653  case tok::kw_volatile:
654  case tok::kw_wchar_t:
655  case tok::kw_while:
656  case tok::kw__Bool:
657  case tok::kw__Complex:
658  case tok::kw___alignof:
659    IdentifierInfo *II = Tok.getIdentifierInfo();
660    SelectorLoc = ConsumeToken();
661    return II;
662  }
663}
664
665///  objc-for-collection-in: 'in'
666///
667bool Parser::isTokIdentifier_in() const {
668  // FIXME: May have to do additional look-ahead to only allow for
669  // valid tokens following an 'in'; such as an identifier, unary operators,
670  // '[' etc.
671  return (getLang().ObjC2 && Tok.is(tok::identifier) &&
672          Tok.getIdentifierInfo() == ObjCTypeQuals[objc_in]);
673}
674
675/// ParseObjCTypeQualifierList - This routine parses the objective-c's type
676/// qualifier list and builds their bitmask representation in the input
677/// argument.
678///
679///   objc-type-qualifiers:
680///     objc-type-qualifier
681///     objc-type-qualifiers objc-type-qualifier
682///
683void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS) {
684  while (1) {
685    if (Tok.isNot(tok::identifier))
686      return;
687
688    const IdentifierInfo *II = Tok.getIdentifierInfo();
689    for (unsigned i = 0; i != objc_NumQuals; ++i) {
690      if (II != ObjCTypeQuals[i])
691        continue;
692
693      ObjCDeclSpec::ObjCDeclQualifier Qual;
694      switch (i) {
695      default: assert(0 && "Unknown decl qualifier");
696      case objc_in:     Qual = ObjCDeclSpec::DQ_In; break;
697      case objc_out:    Qual = ObjCDeclSpec::DQ_Out; break;
698      case objc_inout:  Qual = ObjCDeclSpec::DQ_Inout; break;
699      case objc_oneway: Qual = ObjCDeclSpec::DQ_Oneway; break;
700      case objc_bycopy: Qual = ObjCDeclSpec::DQ_Bycopy; break;
701      case objc_byref:  Qual = ObjCDeclSpec::DQ_Byref; break;
702      }
703      DS.setObjCDeclQualifier(Qual);
704      ConsumeToken();
705      II = 0;
706      break;
707    }
708
709    // If this wasn't a recognized qualifier, bail out.
710    if (II) return;
711  }
712}
713
714///   objc-type-name:
715///     '(' objc-type-qualifiers[opt] type-name ')'
716///     '(' objc-type-qualifiers[opt] ')'
717///
718Parser::TypeTy *Parser::ParseObjCTypeName(ObjCDeclSpec &DS) {
719  assert(Tok.is(tok::l_paren) && "expected (");
720
721  SourceLocation LParenLoc = ConsumeParen();
722  SourceLocation TypeStartLoc = Tok.getLocation();
723
724  // Parse type qualifiers, in, inout, etc.
725  ParseObjCTypeQualifierList(DS);
726
727  TypeTy *Ty = 0;
728  if (isTypeSpecifierQualifier()) {
729    TypeResult TypeSpec = ParseTypeName();
730    if (!TypeSpec.isInvalid())
731      Ty = TypeSpec.get();
732  }
733
734  if (Tok.is(tok::r_paren))
735    ConsumeParen();
736  else if (Tok.getLocation() == TypeStartLoc) {
737    // If we didn't eat any tokens, then this isn't a type.
738    Diag(Tok, diag::err_expected_type);
739    SkipUntil(tok::r_paren);
740  } else {
741    // Otherwise, we found *something*, but didn't get a ')' in the right
742    // place.  Emit an error then return what we have as the type.
743    MatchRHSPunctuation(tok::r_paren, LParenLoc);
744  }
745  return Ty;
746}
747
748///   objc-method-decl:
749///     objc-selector
750///     objc-keyword-selector objc-parmlist[opt]
751///     objc-type-name objc-selector
752///     objc-type-name objc-keyword-selector objc-parmlist[opt]
753///
754///   objc-keyword-selector:
755///     objc-keyword-decl
756///     objc-keyword-selector objc-keyword-decl
757///
758///   objc-keyword-decl:
759///     objc-selector ':' objc-type-name objc-keyword-attributes[opt] identifier
760///     objc-selector ':' objc-keyword-attributes[opt] identifier
761///     ':' objc-type-name objc-keyword-attributes[opt] identifier
762///     ':' objc-keyword-attributes[opt] identifier
763///
764///   objc-parmlist:
765///     objc-parms objc-ellipsis[opt]
766///
767///   objc-parms:
768///     objc-parms , parameter-declaration
769///
770///   objc-ellipsis:
771///     , ...
772///
773///   objc-keyword-attributes:         [OBJC2]
774///     __attribute__((unused))
775///
776Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc,
777                                              tok::TokenKind mType,
778                                              DeclPtrTy IDecl,
779                                          tok::ObjCKeywordKind MethodImplKind) {
780  ParsingDeclRAIIObject PD(*this);
781
782  if (Tok.is(tok::code_completion)) {
783    Actions.CodeCompleteObjCMethodDecl(CurScope, mType == tok::minus,
784                                       /*ReturnType=*/0, IDecl);
785    ConsumeCodeCompletionToken();
786  }
787
788  // Parse the return type if present.
789  TypeTy *ReturnType = 0;
790  ObjCDeclSpec DSRet;
791  if (Tok.is(tok::l_paren))
792    ReturnType = ParseObjCTypeName(DSRet);
793
794  // If attributes exist before the method, parse them.
795  llvm::OwningPtr<AttributeList> MethodAttrs;
796  if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
797    MethodAttrs.reset(ParseGNUAttributes());
798
799  if (Tok.is(tok::code_completion)) {
800    Actions.CodeCompleteObjCMethodDecl(CurScope, mType == tok::minus,
801                                       ReturnType, IDecl);
802    ConsumeCodeCompletionToken();
803  }
804
805  // Now parse the selector.
806  SourceLocation selLoc;
807  IdentifierInfo *SelIdent = ParseObjCSelectorPiece(selLoc);
808
809  // An unnamed colon is valid.
810  if (!SelIdent && Tok.isNot(tok::colon)) { // missing selector name.
811    Diag(Tok, diag::err_expected_selector_for_method)
812      << SourceRange(mLoc, Tok.getLocation());
813    // Skip until we get a ; or {}.
814    SkipUntil(tok::r_brace);
815    return DeclPtrTy();
816  }
817
818  llvm::SmallVector<DeclaratorChunk::ParamInfo, 8> CParamInfo;
819  if (Tok.isNot(tok::colon)) {
820    // If attributes exist after the method, parse them.
821    if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
822      MethodAttrs.reset(addAttributeLists(MethodAttrs.take(),
823                                          ParseGNUAttributes()));
824
825    Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
826    DeclPtrTy Result
827         = Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(),
828                                          mType, IDecl, DSRet, ReturnType, Sel,
829                                          0,
830                                          CParamInfo.data(), CParamInfo.size(),
831                                          MethodAttrs.get(),
832                                          MethodImplKind);
833    PD.complete(Result);
834    return Result;
835  }
836
837  llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
838  llvm::SmallVector<Action::ObjCArgInfo, 12> ArgInfos;
839
840  while (1) {
841    Action::ObjCArgInfo ArgInfo;
842
843    // Each iteration parses a single keyword argument.
844    if (Tok.isNot(tok::colon)) {
845      Diag(Tok, diag::err_expected_colon);
846      break;
847    }
848    ConsumeToken(); // Eat the ':'.
849
850    ArgInfo.Type = 0;
851    if (Tok.is(tok::l_paren)) // Parse the argument type if present.
852      ArgInfo.Type = ParseObjCTypeName(ArgInfo.DeclSpec);
853
854    // If attributes exist before the argument name, parse them.
855    ArgInfo.ArgAttrs = 0;
856    if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
857      ArgInfo.ArgAttrs = ParseGNUAttributes();
858
859    if (Tok.isNot(tok::identifier)) {
860      Diag(Tok, diag::err_expected_ident); // missing argument name.
861      break;
862    }
863
864    ArgInfo.Name = Tok.getIdentifierInfo();
865    ArgInfo.NameLoc = Tok.getLocation();
866    ConsumeToken(); // Eat the identifier.
867
868    ArgInfos.push_back(ArgInfo);
869    KeyIdents.push_back(SelIdent);
870
871    // Check for another keyword selector.
872    SourceLocation Loc;
873    SelIdent = ParseObjCSelectorPiece(Loc);
874    if (!SelIdent && Tok.isNot(tok::colon))
875      break;
876    // We have a selector or a colon, continue parsing.
877  }
878
879  bool isVariadic = false;
880
881  // Parse the (optional) parameter list.
882  while (Tok.is(tok::comma)) {
883    ConsumeToken();
884    if (Tok.is(tok::ellipsis)) {
885      isVariadic = true;
886      ConsumeToken();
887      break;
888    }
889    DeclSpec DS;
890    ParseDeclarationSpecifiers(DS);
891    // Parse the declarator.
892    Declarator ParmDecl(DS, Declarator::PrototypeContext);
893    ParseDeclarator(ParmDecl);
894    IdentifierInfo *ParmII = ParmDecl.getIdentifier();
895    DeclPtrTy Param = Actions.ActOnParamDeclarator(CurScope, ParmDecl);
896    CParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
897                                                    ParmDecl.getIdentifierLoc(),
898                                                    Param,
899                                                   0));
900
901  }
902
903  // FIXME: Add support for optional parmameter list...
904  // If attributes exist after the method, parse them.
905  if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
906    MethodAttrs.reset(addAttributeLists(MethodAttrs.take(),
907                                        ParseGNUAttributes()));
908
909  if (KeyIdents.size() == 0)
910    return DeclPtrTy();
911  Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(),
912                                                   &KeyIdents[0]);
913  DeclPtrTy Result
914       = Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(),
915                                        mType, IDecl, DSRet, ReturnType, Sel,
916                                        &ArgInfos[0],
917                                        CParamInfo.data(), CParamInfo.size(),
918                                        MethodAttrs.get(),
919                                        MethodImplKind, isVariadic);
920  PD.complete(Result);
921
922  // Delete referenced AttributeList objects.
923  for (llvm::SmallVectorImpl<Action::ObjCArgInfo>::iterator
924       I = ArgInfos.begin(), E = ArgInfos.end(); I != E; ++I)
925    delete I->ArgAttrs;
926
927  return Result;
928}
929
930///   objc-protocol-refs:
931///     '<' identifier-list '>'
932///
933bool Parser::
934ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclPtrTy> &Protocols,
935                            llvm::SmallVectorImpl<SourceLocation> &ProtocolLocs,
936                            bool WarnOnDeclarations,
937                            SourceLocation &LAngleLoc, SourceLocation &EndLoc) {
938  assert(Tok.is(tok::less) && "expected <");
939
940  LAngleLoc = ConsumeToken(); // the "<"
941
942  llvm::SmallVector<IdentifierLocPair, 8> ProtocolIdents;
943
944  while (1) {
945    if (Tok.is(tok::code_completion)) {
946      Actions.CodeCompleteObjCProtocolReferences(ProtocolIdents.data(),
947                                                 ProtocolIdents.size());
948      ConsumeCodeCompletionToken();
949    }
950
951    if (Tok.isNot(tok::identifier)) {
952      Diag(Tok, diag::err_expected_ident);
953      SkipUntil(tok::greater);
954      return true;
955    }
956    ProtocolIdents.push_back(std::make_pair(Tok.getIdentifierInfo(),
957                                       Tok.getLocation()));
958    ProtocolLocs.push_back(Tok.getLocation());
959    ConsumeToken();
960
961    if (Tok.isNot(tok::comma))
962      break;
963    ConsumeToken();
964  }
965
966  // Consume the '>'.
967  if (Tok.isNot(tok::greater)) {
968    Diag(Tok, diag::err_expected_greater);
969    return true;
970  }
971
972  EndLoc = ConsumeAnyToken();
973
974  // Convert the list of protocols identifiers into a list of protocol decls.
975  Actions.FindProtocolDeclaration(WarnOnDeclarations,
976                                  &ProtocolIdents[0], ProtocolIdents.size(),
977                                  Protocols);
978  return false;
979}
980
981///   objc-class-instance-variables:
982///     '{' objc-instance-variable-decl-list[opt] '}'
983///
984///   objc-instance-variable-decl-list:
985///     objc-visibility-spec
986///     objc-instance-variable-decl ';'
987///     ';'
988///     objc-instance-variable-decl-list objc-visibility-spec
989///     objc-instance-variable-decl-list objc-instance-variable-decl ';'
990///     objc-instance-variable-decl-list ';'
991///
992///   objc-visibility-spec:
993///     @private
994///     @protected
995///     @public
996///     @package [OBJC2]
997///
998///   objc-instance-variable-decl:
999///     struct-declaration
1000///
1001void Parser::ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl,
1002                                             tok::ObjCKeywordKind visibility,
1003                                             SourceLocation atLoc) {
1004  assert(Tok.is(tok::l_brace) && "expected {");
1005  llvm::SmallVector<DeclPtrTy, 32> AllIvarDecls;
1006
1007  ParseScope ClassScope(this, Scope::DeclScope|Scope::ClassScope);
1008
1009  SourceLocation LBraceLoc = ConsumeBrace(); // the "{"
1010
1011  // While we still have something to read, read the instance variables.
1012  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
1013    // Each iteration of this loop reads one objc-instance-variable-decl.
1014
1015    // Check for extraneous top-level semicolon.
1016    if (Tok.is(tok::semi)) {
1017      Diag(Tok, diag::ext_extra_ivar_semi)
1018        << FixItHint::CreateRemoval(Tok.getLocation());
1019      ConsumeToken();
1020      continue;
1021    }
1022
1023    // Set the default visibility to private.
1024    if (Tok.is(tok::at)) { // parse objc-visibility-spec
1025      ConsumeToken(); // eat the @ sign
1026
1027      if (Tok.is(tok::code_completion)) {
1028        Actions.CodeCompleteObjCAtVisibility(CurScope);
1029        ConsumeCodeCompletionToken();
1030      }
1031
1032      switch (Tok.getObjCKeywordID()) {
1033      case tok::objc_private:
1034      case tok::objc_public:
1035      case tok::objc_protected:
1036      case tok::objc_package:
1037        visibility = Tok.getObjCKeywordID();
1038        ConsumeToken();
1039        continue;
1040      default:
1041        Diag(Tok, diag::err_objc_illegal_visibility_spec);
1042        continue;
1043      }
1044    }
1045
1046    if (Tok.is(tok::code_completion)) {
1047      Actions.CodeCompleteOrdinaryName(CurScope,
1048                                       Action::CCC_ObjCInstanceVariableList);
1049      ConsumeCodeCompletionToken();
1050    }
1051
1052    struct ObjCIvarCallback : FieldCallback {
1053      Parser &P;
1054      DeclPtrTy IDecl;
1055      tok::ObjCKeywordKind visibility;
1056      llvm::SmallVectorImpl<DeclPtrTy> &AllIvarDecls;
1057
1058      ObjCIvarCallback(Parser &P, DeclPtrTy IDecl, tok::ObjCKeywordKind V,
1059                       llvm::SmallVectorImpl<DeclPtrTy> &AllIvarDecls) :
1060        P(P), IDecl(IDecl), visibility(V), AllIvarDecls(AllIvarDecls) {
1061      }
1062
1063      DeclPtrTy invoke(FieldDeclarator &FD) {
1064        // Install the declarator into the interface decl.
1065        DeclPtrTy Field
1066          = P.Actions.ActOnIvar(P.CurScope,
1067                                FD.D.getDeclSpec().getSourceRange().getBegin(),
1068                                IDecl, FD.D, FD.BitfieldSize, visibility);
1069        if (Field)
1070          AllIvarDecls.push_back(Field);
1071        return Field;
1072      }
1073    } Callback(*this, interfaceDecl, visibility, AllIvarDecls);
1074
1075    // Parse all the comma separated declarators.
1076    DeclSpec DS;
1077    ParseStructDeclaration(DS, Callback);
1078
1079    if (Tok.is(tok::semi)) {
1080      ConsumeToken();
1081    } else {
1082      Diag(Tok, diag::err_expected_semi_decl_list);
1083      // Skip to end of block or statement
1084      SkipUntil(tok::r_brace, true, true);
1085    }
1086  }
1087  SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
1088  // Call ActOnFields() even if we don't have any decls. This is useful
1089  // for code rewriting tools that need to be aware of the empty list.
1090  Actions.ActOnFields(CurScope, atLoc, interfaceDecl,
1091                      AllIvarDecls.data(), AllIvarDecls.size(),
1092                      LBraceLoc, RBraceLoc, 0);
1093  return;
1094}
1095
1096///   objc-protocol-declaration:
1097///     objc-protocol-definition
1098///     objc-protocol-forward-reference
1099///
1100///   objc-protocol-definition:
1101///     @protocol identifier
1102///       objc-protocol-refs[opt]
1103///       objc-interface-decl-list
1104///     @end
1105///
1106///   objc-protocol-forward-reference:
1107///     @protocol identifier-list ';'
1108///
1109///   "@protocol identifier ;" should be resolved as "@protocol
1110///   identifier-list ;": objc-interface-decl-list may not start with a
1111///   semicolon in the first alternative if objc-protocol-refs are omitted.
1112Parser::DeclPtrTy Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
1113                                                      AttributeList *attrList) {
1114  assert(Tok.isObjCAtKeyword(tok::objc_protocol) &&
1115         "ParseObjCAtProtocolDeclaration(): Expected @protocol");
1116  ConsumeToken(); // the "protocol" identifier
1117
1118  if (Tok.is(tok::code_completion)) {
1119    Actions.CodeCompleteObjCProtocolDecl(CurScope);
1120    ConsumeCodeCompletionToken();
1121  }
1122
1123  if (Tok.isNot(tok::identifier)) {
1124    Diag(Tok, diag::err_expected_ident); // missing protocol name.
1125    return DeclPtrTy();
1126  }
1127  // Save the protocol name, then consume it.
1128  IdentifierInfo *protocolName = Tok.getIdentifierInfo();
1129  SourceLocation nameLoc = ConsumeToken();
1130
1131  if (Tok.is(tok::semi)) { // forward declaration of one protocol.
1132    IdentifierLocPair ProtoInfo(protocolName, nameLoc);
1133    ConsumeToken();
1134    return Actions.ActOnForwardProtocolDeclaration(AtLoc, &ProtoInfo, 1,
1135                                                   attrList);
1136  }
1137
1138  if (Tok.is(tok::comma)) { // list of forward declarations.
1139    llvm::SmallVector<IdentifierLocPair, 8> ProtocolRefs;
1140    ProtocolRefs.push_back(std::make_pair(protocolName, nameLoc));
1141
1142    // Parse the list of forward declarations.
1143    while (1) {
1144      ConsumeToken(); // the ','
1145      if (Tok.isNot(tok::identifier)) {
1146        Diag(Tok, diag::err_expected_ident);
1147        SkipUntil(tok::semi);
1148        return DeclPtrTy();
1149      }
1150      ProtocolRefs.push_back(IdentifierLocPair(Tok.getIdentifierInfo(),
1151                                               Tok.getLocation()));
1152      ConsumeToken(); // the identifier
1153
1154      if (Tok.isNot(tok::comma))
1155        break;
1156    }
1157    // Consume the ';'.
1158    if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@protocol"))
1159      return DeclPtrTy();
1160
1161    return Actions.ActOnForwardProtocolDeclaration(AtLoc,
1162                                                   &ProtocolRefs[0],
1163                                                   ProtocolRefs.size(),
1164                                                   attrList);
1165  }
1166
1167  // Last, and definitely not least, parse a protocol declaration.
1168  SourceLocation LAngleLoc, EndProtoLoc;
1169
1170  llvm::SmallVector<DeclPtrTy, 8> ProtocolRefs;
1171  llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
1172  if (Tok.is(tok::less) &&
1173      ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, false,
1174                                  LAngleLoc, EndProtoLoc))
1175    return DeclPtrTy();
1176
1177  DeclPtrTy ProtoType =
1178    Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc,
1179                                        ProtocolRefs.data(),
1180                                        ProtocolRefs.size(),
1181                                        ProtocolLocs.data(),
1182                                        EndProtoLoc, attrList);
1183  ParseObjCInterfaceDeclList(ProtoType, tok::objc_protocol);
1184  return ProtoType;
1185}
1186
1187///   objc-implementation:
1188///     objc-class-implementation-prologue
1189///     objc-category-implementation-prologue
1190///
1191///   objc-class-implementation-prologue:
1192///     @implementation identifier objc-superclass[opt]
1193///       objc-class-instance-variables[opt]
1194///
1195///   objc-category-implementation-prologue:
1196///     @implementation identifier ( identifier )
1197Parser::DeclPtrTy Parser::ParseObjCAtImplementationDeclaration(
1198  SourceLocation atLoc) {
1199  assert(Tok.isObjCAtKeyword(tok::objc_implementation) &&
1200         "ParseObjCAtImplementationDeclaration(): Expected @implementation");
1201  ConsumeToken(); // the "implementation" identifier
1202
1203  // Code completion after '@implementation'.
1204  if (Tok.is(tok::code_completion)) {
1205    Actions.CodeCompleteObjCImplementationDecl(CurScope);
1206    ConsumeCodeCompletionToken();
1207  }
1208
1209  if (Tok.isNot(tok::identifier)) {
1210    Diag(Tok, diag::err_expected_ident); // missing class or category name.
1211    return DeclPtrTy();
1212  }
1213  // We have a class or category name - consume it.
1214  IdentifierInfo *nameId = Tok.getIdentifierInfo();
1215  SourceLocation nameLoc = ConsumeToken(); // consume class or category name
1216
1217  if (Tok.is(tok::l_paren)) {
1218    // we have a category implementation.
1219    SourceLocation lparenLoc = ConsumeParen();
1220    SourceLocation categoryLoc, rparenLoc;
1221    IdentifierInfo *categoryId = 0;
1222
1223    if (Tok.is(tok::code_completion)) {
1224      Actions.CodeCompleteObjCImplementationCategory(CurScope, nameId, nameLoc);
1225      ConsumeCodeCompletionToken();
1226    }
1227
1228    if (Tok.is(tok::identifier)) {
1229      categoryId = Tok.getIdentifierInfo();
1230      categoryLoc = ConsumeToken();
1231    } else {
1232      Diag(Tok, diag::err_expected_ident); // missing category name.
1233      return DeclPtrTy();
1234    }
1235    if (Tok.isNot(tok::r_paren)) {
1236      Diag(Tok, diag::err_expected_rparen);
1237      SkipUntil(tok::r_paren, false); // don't stop at ';'
1238      return DeclPtrTy();
1239    }
1240    rparenLoc = ConsumeParen();
1241    DeclPtrTy ImplCatType = Actions.ActOnStartCategoryImplementation(
1242                                    atLoc, nameId, nameLoc, categoryId,
1243                                    categoryLoc);
1244    ObjCImpDecl = ImplCatType;
1245    PendingObjCImpDecl.push_back(ObjCImpDecl);
1246    return DeclPtrTy();
1247  }
1248  // We have a class implementation
1249  SourceLocation superClassLoc;
1250  IdentifierInfo *superClassId = 0;
1251  if (Tok.is(tok::colon)) {
1252    // We have a super class
1253    ConsumeToken();
1254    if (Tok.isNot(tok::identifier)) {
1255      Diag(Tok, diag::err_expected_ident); // missing super class name.
1256      return DeclPtrTy();
1257    }
1258    superClassId = Tok.getIdentifierInfo();
1259    superClassLoc = ConsumeToken(); // Consume super class name
1260  }
1261  DeclPtrTy ImplClsType = Actions.ActOnStartClassImplementation(
1262                                  atLoc, nameId, nameLoc,
1263                                  superClassId, superClassLoc);
1264
1265  if (Tok.is(tok::l_brace)) // we have ivars
1266    ParseObjCClassInstanceVariables(ImplClsType/*FIXME*/,
1267                                    tok::objc_private, atLoc);
1268  ObjCImpDecl = ImplClsType;
1269  PendingObjCImpDecl.push_back(ObjCImpDecl);
1270
1271  return DeclPtrTy();
1272}
1273
1274Parser::DeclPtrTy Parser::ParseObjCAtEndDeclaration(SourceRange atEnd) {
1275  assert(Tok.isObjCAtKeyword(tok::objc_end) &&
1276         "ParseObjCAtEndDeclaration(): Expected @end");
1277  DeclPtrTy Result = ObjCImpDecl;
1278  ConsumeToken(); // the "end" identifier
1279  if (ObjCImpDecl) {
1280    Actions.ActOnAtEnd(CurScope, atEnd, ObjCImpDecl);
1281    ObjCImpDecl = DeclPtrTy();
1282    PendingObjCImpDecl.pop_back();
1283  }
1284  else {
1285    // missing @implementation
1286    Diag(atEnd.getBegin(), diag::warn_expected_implementation);
1287  }
1288  return Result;
1289}
1290
1291Parser::DeclGroupPtrTy Parser::RetrievePendingObjCImpDecl() {
1292  if (PendingObjCImpDecl.empty())
1293    return Actions.ConvertDeclToDeclGroup(DeclPtrTy());
1294  DeclPtrTy ImpDecl = PendingObjCImpDecl.pop_back_val();
1295  Actions.ActOnAtEnd(CurScope, SourceRange(), ImpDecl);
1296  return Actions.ConvertDeclToDeclGroup(ImpDecl);
1297}
1298
1299///   compatibility-alias-decl:
1300///     @compatibility_alias alias-name  class-name ';'
1301///
1302Parser::DeclPtrTy Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) {
1303  assert(Tok.isObjCAtKeyword(tok::objc_compatibility_alias) &&
1304         "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias");
1305  ConsumeToken(); // consume compatibility_alias
1306  if (Tok.isNot(tok::identifier)) {
1307    Diag(Tok, diag::err_expected_ident);
1308    return DeclPtrTy();
1309  }
1310  IdentifierInfo *aliasId = Tok.getIdentifierInfo();
1311  SourceLocation aliasLoc = ConsumeToken(); // consume alias-name
1312  if (Tok.isNot(tok::identifier)) {
1313    Diag(Tok, diag::err_expected_ident);
1314    return DeclPtrTy();
1315  }
1316  IdentifierInfo *classId = Tok.getIdentifierInfo();
1317  SourceLocation classLoc = ConsumeToken(); // consume class-name;
1318  if (Tok.isNot(tok::semi)) {
1319    Diag(Tok, diag::err_expected_semi_after) << "@compatibility_alias";
1320    return DeclPtrTy();
1321  }
1322  return Actions.ActOnCompatiblityAlias(atLoc, aliasId, aliasLoc,
1323                                        classId, classLoc);
1324}
1325
1326///   property-synthesis:
1327///     @synthesize property-ivar-list ';'
1328///
1329///   property-ivar-list:
1330///     property-ivar
1331///     property-ivar-list ',' property-ivar
1332///
1333///   property-ivar:
1334///     identifier
1335///     identifier '=' identifier
1336///
1337Parser::DeclPtrTy Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
1338  assert(Tok.isObjCAtKeyword(tok::objc_synthesize) &&
1339         "ParseObjCPropertyDynamic(): Expected '@synthesize'");
1340  SourceLocation loc = ConsumeToken(); // consume synthesize
1341
1342  while (true) {
1343    if (Tok.is(tok::code_completion)) {
1344      Actions.CodeCompleteObjCPropertyDefinition(CurScope, ObjCImpDecl);
1345      ConsumeCodeCompletionToken();
1346    }
1347
1348    if (Tok.isNot(tok::identifier)) {
1349      Diag(Tok, diag::err_synthesized_property_name);
1350      SkipUntil(tok::semi);
1351      return DeclPtrTy();
1352    }
1353
1354    IdentifierInfo *propertyIvar = 0;
1355    IdentifierInfo *propertyId = Tok.getIdentifierInfo();
1356    SourceLocation propertyLoc = ConsumeToken(); // consume property name
1357    if (Tok.is(tok::equal)) {
1358      // property '=' ivar-name
1359      ConsumeToken(); // consume '='
1360
1361      if (Tok.is(tok::code_completion)) {
1362        Actions.CodeCompleteObjCPropertySynthesizeIvar(CurScope, propertyId,
1363                                                       ObjCImpDecl);
1364        ConsumeCodeCompletionToken();
1365      }
1366
1367      if (Tok.isNot(tok::identifier)) {
1368        Diag(Tok, diag::err_expected_ident);
1369        break;
1370      }
1371      propertyIvar = Tok.getIdentifierInfo();
1372      ConsumeToken(); // consume ivar-name
1373    }
1374    Actions.ActOnPropertyImplDecl(CurScope, atLoc, propertyLoc, true, ObjCImpDecl,
1375                                  propertyId, propertyIvar);
1376    if (Tok.isNot(tok::comma))
1377      break;
1378    ConsumeToken(); // consume ','
1379  }
1380  if (Tok.isNot(tok::semi)) {
1381    Diag(Tok, diag::err_expected_semi_after) << "@synthesize";
1382    SkipUntil(tok::semi);
1383  }
1384  else
1385    ConsumeToken(); // consume ';'
1386  return DeclPtrTy();
1387}
1388
1389///   property-dynamic:
1390///     @dynamic  property-list
1391///
1392///   property-list:
1393///     identifier
1394///     property-list ',' identifier
1395///
1396Parser::DeclPtrTy Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
1397  assert(Tok.isObjCAtKeyword(tok::objc_dynamic) &&
1398         "ParseObjCPropertyDynamic(): Expected '@dynamic'");
1399  SourceLocation loc = ConsumeToken(); // consume dynamic
1400  while (true) {
1401    if (Tok.is(tok::code_completion)) {
1402      Actions.CodeCompleteObjCPropertyDefinition(CurScope, ObjCImpDecl);
1403      ConsumeCodeCompletionToken();
1404    }
1405
1406    if (Tok.isNot(tok::identifier)) {
1407      Diag(Tok, diag::err_expected_ident);
1408      SkipUntil(tok::semi);
1409      return DeclPtrTy();
1410    }
1411
1412    IdentifierInfo *propertyId = Tok.getIdentifierInfo();
1413    SourceLocation propertyLoc = ConsumeToken(); // consume property name
1414    Actions.ActOnPropertyImplDecl(CurScope, atLoc, propertyLoc, false, ObjCImpDecl,
1415                                  propertyId, 0);
1416
1417    if (Tok.isNot(tok::comma))
1418      break;
1419    ConsumeToken(); // consume ','
1420  }
1421  if (Tok.isNot(tok::semi)) {
1422    Diag(Tok, diag::err_expected_semi_after) << "@dynamic";
1423    SkipUntil(tok::semi);
1424  }
1425  else
1426    ConsumeToken(); // consume ';'
1427  return DeclPtrTy();
1428}
1429
1430///  objc-throw-statement:
1431///    throw expression[opt];
1432///
1433Parser::OwningStmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) {
1434  OwningExprResult Res(Actions);
1435  ConsumeToken(); // consume throw
1436  if (Tok.isNot(tok::semi)) {
1437    Res = ParseExpression();
1438    if (Res.isInvalid()) {
1439      SkipUntil(tok::semi);
1440      return StmtError();
1441    }
1442  }
1443  // consume ';'
1444  ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@throw");
1445  return Actions.ActOnObjCAtThrowStmt(atLoc, move(Res), CurScope);
1446}
1447
1448/// objc-synchronized-statement:
1449///   @synchronized '(' expression ')' compound-statement
1450///
1451Parser::OwningStmtResult
1452Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
1453  ConsumeToken(); // consume synchronized
1454  if (Tok.isNot(tok::l_paren)) {
1455    Diag(Tok, diag::err_expected_lparen_after) << "@synchronized";
1456    return StmtError();
1457  }
1458  ConsumeParen();  // '('
1459  OwningExprResult Res(ParseExpression());
1460  if (Res.isInvalid()) {
1461    SkipUntil(tok::semi);
1462    return StmtError();
1463  }
1464  if (Tok.isNot(tok::r_paren)) {
1465    Diag(Tok, diag::err_expected_lbrace);
1466    return StmtError();
1467  }
1468  ConsumeParen();  // ')'
1469  if (Tok.isNot(tok::l_brace)) {
1470    Diag(Tok, diag::err_expected_lbrace);
1471    return StmtError();
1472  }
1473  // Enter a scope to hold everything within the compound stmt.  Compound
1474  // statements can always hold declarations.
1475  ParseScope BodyScope(this, Scope::DeclScope);
1476
1477  OwningStmtResult SynchBody(ParseCompoundStatementBody());
1478
1479  BodyScope.Exit();
1480  if (SynchBody.isInvalid())
1481    SynchBody = Actions.ActOnNullStmt(Tok.getLocation());
1482  return Actions.ActOnObjCAtSynchronizedStmt(atLoc, move(Res), move(SynchBody));
1483}
1484
1485///  objc-try-catch-statement:
1486///    @try compound-statement objc-catch-list[opt]
1487///    @try compound-statement objc-catch-list[opt] @finally compound-statement
1488///
1489///  objc-catch-list:
1490///    @catch ( parameter-declaration ) compound-statement
1491///    objc-catch-list @catch ( catch-parameter-declaration ) compound-statement
1492///  catch-parameter-declaration:
1493///     parameter-declaration
1494///     '...' [OBJC2]
1495///
1496Parser::OwningStmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
1497  bool catch_or_finally_seen = false;
1498
1499  ConsumeToken(); // consume try
1500  if (Tok.isNot(tok::l_brace)) {
1501    Diag(Tok, diag::err_expected_lbrace);
1502    return StmtError();
1503  }
1504  StmtVector CatchStmts(Actions);
1505  OwningStmtResult FinallyStmt(Actions);
1506  ParseScope TryScope(this, Scope::DeclScope);
1507  OwningStmtResult TryBody(ParseCompoundStatementBody());
1508  TryScope.Exit();
1509  if (TryBody.isInvalid())
1510    TryBody = Actions.ActOnNullStmt(Tok.getLocation());
1511
1512  while (Tok.is(tok::at)) {
1513    // At this point, we need to lookahead to determine if this @ is the start
1514    // of an @catch or @finally.  We don't want to consume the @ token if this
1515    // is an @try or @encode or something else.
1516    Token AfterAt = GetLookAheadToken(1);
1517    if (!AfterAt.isObjCAtKeyword(tok::objc_catch) &&
1518        !AfterAt.isObjCAtKeyword(tok::objc_finally))
1519      break;
1520
1521    SourceLocation AtCatchFinallyLoc = ConsumeToken();
1522    if (Tok.isObjCAtKeyword(tok::objc_catch)) {
1523      DeclPtrTy FirstPart;
1524      ConsumeToken(); // consume catch
1525      if (Tok.is(tok::l_paren)) {
1526        ConsumeParen();
1527        ParseScope CatchScope(this, Scope::DeclScope|Scope::AtCatchScope);
1528        if (Tok.isNot(tok::ellipsis)) {
1529          DeclSpec DS;
1530          ParseDeclarationSpecifiers(DS);
1531          // For some odd reason, the name of the exception variable is
1532          // optional. As a result, we need to use "PrototypeContext", because
1533          // we must accept either 'declarator' or 'abstract-declarator' here.
1534          Declarator ParmDecl(DS, Declarator::PrototypeContext);
1535          ParseDeclarator(ParmDecl);
1536
1537          // Inform the actions module about the declarator, so it
1538          // gets added to the current scope.
1539          FirstPart = Actions.ActOnObjCExceptionDecl(CurScope, ParmDecl);
1540        } else
1541          ConsumeToken(); // consume '...'
1542
1543        SourceLocation RParenLoc;
1544
1545        if (Tok.is(tok::r_paren))
1546          RParenLoc = ConsumeParen();
1547        else // Skip over garbage, until we get to ')'.  Eat the ')'.
1548          SkipUntil(tok::r_paren, true, false);
1549
1550        OwningStmtResult CatchBody(Actions, true);
1551        if (Tok.is(tok::l_brace))
1552          CatchBody = ParseCompoundStatementBody();
1553        else
1554          Diag(Tok, diag::err_expected_lbrace);
1555        if (CatchBody.isInvalid())
1556          CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
1557
1558        OwningStmtResult Catch = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc,
1559                                                              RParenLoc,
1560                                                              FirstPart,
1561                                                              move(CatchBody));
1562        if (!Catch.isInvalid())
1563          CatchStmts.push_back(Catch.release());
1564
1565      } else {
1566        Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
1567          << "@catch clause";
1568        return StmtError();
1569      }
1570      catch_or_finally_seen = true;
1571    } else {
1572      assert(Tok.isObjCAtKeyword(tok::objc_finally) && "Lookahead confused?");
1573      ConsumeToken(); // consume finally
1574      ParseScope FinallyScope(this, Scope::DeclScope);
1575
1576      OwningStmtResult FinallyBody(Actions, true);
1577      if (Tok.is(tok::l_brace))
1578        FinallyBody = ParseCompoundStatementBody();
1579      else
1580        Diag(Tok, diag::err_expected_lbrace);
1581      if (FinallyBody.isInvalid())
1582        FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
1583      FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
1584                                                   move(FinallyBody));
1585      catch_or_finally_seen = true;
1586      break;
1587    }
1588  }
1589  if (!catch_or_finally_seen) {
1590    Diag(atLoc, diag::err_missing_catch_finally);
1591    return StmtError();
1592  }
1593
1594  return Actions.ActOnObjCAtTryStmt(atLoc, move(TryBody),
1595                                    move_arg(CatchStmts),
1596                                    move(FinallyStmt));
1597}
1598
1599///   objc-method-def: objc-method-proto ';'[opt] '{' body '}'
1600///
1601Parser::DeclPtrTy Parser::ParseObjCMethodDefinition() {
1602  DeclPtrTy MDecl = ParseObjCMethodPrototype(ObjCImpDecl);
1603
1604  PrettyStackTraceActionsDecl CrashInfo(MDecl, Tok.getLocation(), Actions,
1605                                        PP.getSourceManager(),
1606                                        "parsing Objective-C method");
1607
1608  // parse optional ';'
1609  if (Tok.is(tok::semi)) {
1610    if (ObjCImpDecl) {
1611      Diag(Tok, diag::warn_semicolon_before_method_body)
1612        << FixItHint::CreateRemoval(Tok.getLocation());
1613    }
1614    ConsumeToken();
1615  }
1616
1617  // We should have an opening brace now.
1618  if (Tok.isNot(tok::l_brace)) {
1619    Diag(Tok, diag::err_expected_method_body);
1620
1621    // Skip over garbage, until we get to '{'.  Don't eat the '{'.
1622    SkipUntil(tok::l_brace, true, true);
1623
1624    // If we didn't find the '{', bail out.
1625    if (Tok.isNot(tok::l_brace))
1626      return DeclPtrTy();
1627  }
1628  SourceLocation BraceLoc = Tok.getLocation();
1629
1630  // Enter a scope for the method body.
1631  ParseScope BodyScope(this,
1632                       Scope::ObjCMethodScope|Scope::FnScope|Scope::DeclScope);
1633
1634  // Tell the actions module that we have entered a method definition with the
1635  // specified Declarator for the method.
1636  Actions.ActOnStartOfObjCMethodDef(CurScope, MDecl);
1637
1638  OwningStmtResult FnBody(ParseCompoundStatementBody());
1639
1640  // If the function body could not be parsed, make a bogus compoundstmt.
1641  if (FnBody.isInvalid())
1642    FnBody = Actions.ActOnCompoundStmt(BraceLoc, BraceLoc,
1643                                       MultiStmtArg(Actions), false);
1644
1645  // TODO: Pass argument information.
1646  Actions.ActOnFinishFunctionBody(MDecl, move(FnBody));
1647
1648  // Leave the function body scope.
1649  BodyScope.Exit();
1650
1651  return MDecl;
1652}
1653
1654Parser::OwningStmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) {
1655  if (Tok.is(tok::code_completion)) {
1656    Actions.CodeCompleteObjCAtStatement(CurScope);
1657    ConsumeCodeCompletionToken();
1658    return StmtError();
1659  }
1660
1661  if (Tok.isObjCAtKeyword(tok::objc_try))
1662    return ParseObjCTryStmt(AtLoc);
1663
1664  if (Tok.isObjCAtKeyword(tok::objc_throw))
1665    return ParseObjCThrowStmt(AtLoc);
1666
1667  if (Tok.isObjCAtKeyword(tok::objc_synchronized))
1668    return ParseObjCSynchronizedStmt(AtLoc);
1669
1670  OwningExprResult Res(ParseExpressionWithLeadingAt(AtLoc));
1671  if (Res.isInvalid()) {
1672    // If the expression is invalid, skip ahead to the next semicolon. Not
1673    // doing this opens us up to the possibility of infinite loops if
1674    // ParseExpression does not consume any tokens.
1675    SkipUntil(tok::semi);
1676    return StmtError();
1677  }
1678
1679  // Otherwise, eat the semicolon.
1680  ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
1681  return Actions.ActOnExprStmt(Actions.MakeFullExpr(Res));
1682}
1683
1684Parser::OwningExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
1685  switch (Tok.getKind()) {
1686  case tok::code_completion:
1687    Actions.CodeCompleteObjCAtExpression(CurScope);
1688    ConsumeCodeCompletionToken();
1689    return ExprError();
1690
1691  case tok::string_literal:    // primary-expression: string-literal
1692  case tok::wide_string_literal:
1693    return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
1694  default:
1695    if (Tok.getIdentifierInfo() == 0)
1696      return ExprError(Diag(AtLoc, diag::err_unexpected_at));
1697
1698    switch (Tok.getIdentifierInfo()->getObjCKeywordID()) {
1699    case tok::objc_encode:
1700      return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc));
1701    case tok::objc_protocol:
1702      return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc));
1703    case tok::objc_selector:
1704      return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc));
1705    default:
1706      return ExprError(Diag(AtLoc, diag::err_unexpected_at));
1707    }
1708  }
1709}
1710
1711/// \brirg Parse the receiver of an Objective-C++ message send.
1712///
1713/// This routine parses the receiver of a message send in
1714/// Objective-C++ either as a type or as an expression. Note that this
1715/// routine must not be called to parse a send to 'super', since it
1716/// has no way to return such a result.
1717///
1718/// \param IsExpr Whether the receiver was parsed as an expression.
1719///
1720/// \param TypeOrExpr If the receiver was parsed as an expression (\c
1721/// IsExpr is true), the parsed expression. If the receiver was parsed
1722/// as a type (\c IsExpr is false), the parsed type.
1723///
1724/// \returns True if an error occurred during parsing or semantic
1725/// analysis, in which case the arguments do not have valid
1726/// values. Otherwise, returns false for a successful parse.
1727///
1728///   objc-receiver: [C++]
1729///     'super' [not parsed here]
1730///     expression
1731///     simple-type-specifier
1732///     typename-specifier
1733bool Parser::ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr) {
1734  if (Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
1735      Tok.is(tok::kw_typename) || Tok.is(tok::annot_cxxscope))
1736    TryAnnotateTypeOrScopeToken();
1737
1738  if (!isCXXSimpleTypeSpecifier()) {
1739    //   objc-receiver:
1740    //     expression
1741    OwningExprResult Receiver = ParseExpression();
1742    if (Receiver.isInvalid())
1743      return true;
1744
1745    IsExpr = true;
1746    TypeOrExpr = Receiver.take();
1747    return false;
1748  }
1749
1750  // objc-receiver:
1751  //   typename-specifier
1752  //   simple-type-specifier
1753  //   expression (that starts with one of the above)
1754  DeclSpec DS;
1755  ParseCXXSimpleTypeSpecifier(DS);
1756
1757  if (Tok.is(tok::l_paren)) {
1758    // If we see an opening parentheses at this point, we are
1759    // actually parsing an expression that starts with a
1760    // function-style cast, e.g.,
1761    //
1762    //   postfix-expression:
1763    //     simple-type-specifier ( expression-list [opt] )
1764    //     typename-specifier ( expression-list [opt] )
1765    //
1766    // Parse the remainder of this case, then the (optional)
1767    // postfix-expression suffix, followed by the (optional)
1768    // right-hand side of the binary expression. We have an
1769    // instance method.
1770    OwningExprResult Receiver = ParseCXXTypeConstructExpression(DS);
1771    if (!Receiver.isInvalid())
1772      Receiver = ParsePostfixExpressionSuffix(move(Receiver));
1773    if (!Receiver.isInvalid())
1774      Receiver = ParseRHSOfBinaryExpression(move(Receiver), prec::Comma);
1775    if (Receiver.isInvalid())
1776      return true;
1777
1778    IsExpr = true;
1779    TypeOrExpr = Receiver.take();
1780    return false;
1781  }
1782
1783  // We have a class message. Turn the simple-type-specifier or
1784  // typename-specifier we parsed into a type and parse the
1785  // remainder of the class message.
1786  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
1787  TypeResult Type = Actions.ActOnTypeName(CurScope, DeclaratorInfo);
1788  if (Type.isInvalid())
1789    return true;
1790
1791  IsExpr = false;
1792  TypeOrExpr = Type.get();
1793  return false;
1794}
1795
1796/// \brief Determine whether the parser is currently referring to a an
1797/// Objective-C message send, using a simplified heuristic to avoid overhead.
1798///
1799/// This routine will only return true for a subset of valid message-send
1800/// expressions.
1801bool Parser::isSimpleObjCMessageExpression() {
1802  assert(Tok.is(tok::l_square) && getLang().ObjC1 &&
1803         "Incorrect start for isSimpleObjCMessageExpression");
1804  return GetLookAheadToken(1).is(tok::identifier) &&
1805         GetLookAheadToken(2).is(tok::identifier);
1806}
1807
1808///   objc-message-expr:
1809///     '[' objc-receiver objc-message-args ']'
1810///
1811///   objc-receiver: [C]
1812///     'super'
1813///     expression
1814///     class-name
1815///     type-name
1816///
1817Parser::OwningExprResult Parser::ParseObjCMessageExpression() {
1818  assert(Tok.is(tok::l_square) && "'[' expected");
1819  SourceLocation LBracLoc = ConsumeBracket(); // consume '['
1820
1821  if (Tok.is(tok::code_completion)) {
1822    Actions.CodeCompleteObjCMessageReceiver(CurScope);
1823    ConsumeCodeCompletionToken();
1824    SkipUntil(tok::r_square);
1825    return ExprError();
1826  }
1827
1828  if (getLang().CPlusPlus) {
1829    // We completely separate the C and C++ cases because C++ requires
1830    // more complicated (read: slower) parsing.
1831
1832    // Handle send to super.
1833    // FIXME: This doesn't benefit from the same typo-correction we
1834    // get in Objective-C.
1835    if (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_super &&
1836        NextToken().isNot(tok::period) && CurScope->isInObjcMethodScope())
1837      return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(), 0,
1838                                            ExprArg(Actions));
1839
1840    // Parse the receiver, which is either a type or an expression.
1841    bool IsExpr;
1842    void *TypeOrExpr;
1843    if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) {
1844      SkipUntil(tok::r_square);
1845      return ExprError();
1846    }
1847
1848    if (IsExpr)
1849      return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 0,
1850                                         OwningExprResult(Actions, TypeOrExpr));
1851
1852    return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
1853                                          TypeOrExpr, ExprArg(Actions));
1854  }
1855
1856  if (Tok.is(tok::identifier)) {
1857    IdentifierInfo *Name = Tok.getIdentifierInfo();
1858    SourceLocation NameLoc = Tok.getLocation();
1859    TypeTy *ReceiverType;
1860    switch (Actions.getObjCMessageKind(CurScope, Name, NameLoc,
1861                                       Name == Ident_super,
1862                                       NextToken().is(tok::period),
1863                                       ReceiverType)) {
1864    case Action::ObjCSuperMessage:
1865      return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(), 0,
1866                                            ExprArg(Actions));
1867
1868    case Action::ObjCClassMessage:
1869      if (!ReceiverType) {
1870        SkipUntil(tok::r_square);
1871        return ExprError();
1872      }
1873
1874      ConsumeToken(); // the type name
1875
1876      return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
1877                                            ReceiverType,
1878                                            ExprArg(Actions));
1879
1880    case Action::ObjCInstanceMessage:
1881      // Fall through to parse an expression.
1882      break;
1883    }
1884  }
1885
1886  // Otherwise, an arbitrary expression can be the receiver of a send.
1887  OwningExprResult Res(ParseExpression());
1888  if (Res.isInvalid()) {
1889    SkipUntil(tok::r_square);
1890    return move(Res);
1891  }
1892
1893  return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 0,
1894                                        move(Res));
1895}
1896
1897/// \brief Parse the remainder of an Objective-C message following the
1898/// '[' objc-receiver.
1899///
1900/// This routine handles sends to super, class messages (sent to a
1901/// class name), and instance messages (sent to an object), and the
1902/// target is represented by \p SuperLoc, \p ReceiverType, or \p
1903/// ReceiverExpr, respectively. Only one of these parameters may have
1904/// a valid value.
1905///
1906/// \param LBracLoc The location of the opening '['.
1907///
1908/// \param SuperLoc If this is a send to 'super', the location of the
1909/// 'super' keyword that indicates a send to the superclass.
1910///
1911/// \param ReceiverType If this is a class message, the type of the
1912/// class we are sending a message to.
1913///
1914/// \param ReceiverExpr If this is an instance message, the expression
1915/// used to compute the receiver object.
1916///
1917///   objc-message-args:
1918///     objc-selector
1919///     objc-keywordarg-list
1920///
1921///   objc-keywordarg-list:
1922///     objc-keywordarg
1923///     objc-keywordarg-list objc-keywordarg
1924///
1925///   objc-keywordarg:
1926///     selector-name[opt] ':' objc-keywordexpr
1927///
1928///   objc-keywordexpr:
1929///     nonempty-expr-list
1930///
1931///   nonempty-expr-list:
1932///     assignment-expression
1933///     nonempty-expr-list , assignment-expression
1934///
1935Parser::OwningExprResult
1936Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
1937                                       SourceLocation SuperLoc,
1938                                       TypeTy *ReceiverType,
1939                                       ExprArg ReceiverExpr) {
1940  if (Tok.is(tok::code_completion)) {
1941    if (SuperLoc.isValid())
1942      Actions.CodeCompleteObjCSuperMessage(CurScope, SuperLoc, 0, 0);
1943    else if (ReceiverType)
1944      Actions.CodeCompleteObjCClassMessage(CurScope, ReceiverType, 0, 0);
1945    else
1946      Actions.CodeCompleteObjCInstanceMessage(CurScope, ReceiverExpr.get(),
1947                                              0, 0);
1948    ConsumeCodeCompletionToken();
1949  }
1950
1951  // Parse objc-selector
1952  SourceLocation Loc;
1953  IdentifierInfo *selIdent = ParseObjCSelectorPiece(Loc);
1954
1955  SourceLocation SelectorLoc = Loc;
1956
1957  llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
1958  ExprVector KeyExprs(Actions);
1959
1960  if (Tok.is(tok::colon)) {
1961    while (1) {
1962      // Each iteration parses a single keyword argument.
1963      KeyIdents.push_back(selIdent);
1964
1965      if (Tok.isNot(tok::colon)) {
1966        Diag(Tok, diag::err_expected_colon);
1967        // We must manually skip to a ']', otherwise the expression skipper will
1968        // stop at the ']' when it skips to the ';'.  We want it to skip beyond
1969        // the enclosing expression.
1970        SkipUntil(tok::r_square);
1971        return ExprError();
1972      }
1973
1974      ConsumeToken(); // Eat the ':'.
1975      ///  Parse the expression after ':'
1976      OwningExprResult Res(ParseAssignmentExpression());
1977      if (Res.isInvalid()) {
1978        // We must manually skip to a ']', otherwise the expression skipper will
1979        // stop at the ']' when it skips to the ';'.  We want it to skip beyond
1980        // the enclosing expression.
1981        SkipUntil(tok::r_square);
1982        return move(Res);
1983      }
1984
1985      // We have a valid expression.
1986      KeyExprs.push_back(Res.release());
1987
1988      // Code completion after each argument.
1989      if (Tok.is(tok::code_completion)) {
1990        if (SuperLoc.isValid())
1991          Actions.CodeCompleteObjCSuperMessage(CurScope, SuperLoc,
1992                                               KeyIdents.data(),
1993                                               KeyIdents.size());
1994        else if (ReceiverType)
1995          Actions.CodeCompleteObjCClassMessage(CurScope, ReceiverType,
1996                                               KeyIdents.data(),
1997                                               KeyIdents.size());
1998        else
1999          Actions.CodeCompleteObjCInstanceMessage(CurScope, ReceiverExpr.get(),
2000                                                  KeyIdents.data(),
2001                                                  KeyIdents.size());
2002        ConsumeCodeCompletionToken();
2003      }
2004
2005      // Check for another keyword selector.
2006      selIdent = ParseObjCSelectorPiece(Loc);
2007      if (!selIdent && Tok.isNot(tok::colon))
2008        break;
2009      // We have a selector or a colon, continue parsing.
2010    }
2011    // Parse the, optional, argument list, comma separated.
2012    while (Tok.is(tok::comma)) {
2013      ConsumeToken(); // Eat the ','.
2014      ///  Parse the expression after ','
2015      OwningExprResult Res(ParseAssignmentExpression());
2016      if (Res.isInvalid()) {
2017        // We must manually skip to a ']', otherwise the expression skipper will
2018        // stop at the ']' when it skips to the ';'.  We want it to skip beyond
2019        // the enclosing expression.
2020        SkipUntil(tok::r_square);
2021        return move(Res);
2022      }
2023
2024      // We have a valid expression.
2025      KeyExprs.push_back(Res.release());
2026    }
2027  } else if (!selIdent) {
2028    Diag(Tok, diag::err_expected_ident); // missing selector name.
2029
2030    // We must manually skip to a ']', otherwise the expression skipper will
2031    // stop at the ']' when it skips to the ';'.  We want it to skip beyond
2032    // the enclosing expression.
2033    SkipUntil(tok::r_square);
2034    return ExprError();
2035  }
2036
2037  if (Tok.isNot(tok::r_square)) {
2038    if (Tok.is(tok::identifier))
2039      Diag(Tok, diag::err_expected_colon);
2040    else
2041      Diag(Tok, diag::err_expected_rsquare);
2042    // We must manually skip to a ']', otherwise the expression skipper will
2043    // stop at the ']' when it skips to the ';'.  We want it to skip beyond
2044    // the enclosing expression.
2045    SkipUntil(tok::r_square);
2046    return ExprError();
2047  }
2048
2049  SourceLocation RBracLoc = ConsumeBracket(); // consume ']'
2050
2051  unsigned nKeys = KeyIdents.size();
2052  if (nKeys == 0)
2053    KeyIdents.push_back(selIdent);
2054  Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]);
2055
2056  if (SuperLoc.isValid())
2057    return Actions.ActOnSuperMessage(CurScope, SuperLoc, Sel,
2058                                     LBracLoc, SelectorLoc, RBracLoc,
2059                                     Action::MultiExprArg(Actions,
2060                                                          KeyExprs.take(),
2061                                                          KeyExprs.size()));
2062  else if (ReceiverType)
2063    return Actions.ActOnClassMessage(CurScope, ReceiverType, Sel,
2064                                     LBracLoc, SelectorLoc, RBracLoc,
2065                                     Action::MultiExprArg(Actions,
2066                                                          KeyExprs.take(),
2067                                                          KeyExprs.size()));
2068  return Actions.ActOnInstanceMessage(CurScope, move(ReceiverExpr), Sel,
2069                                      LBracLoc, SelectorLoc, RBracLoc,
2070                                      Action::MultiExprArg(Actions,
2071                                                           KeyExprs.take(),
2072                                                           KeyExprs.size()));
2073}
2074
2075Parser::OwningExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
2076  OwningExprResult Res(ParseStringLiteralExpression());
2077  if (Res.isInvalid()) return move(Res);
2078
2079  // @"foo" @"bar" is a valid concatenated string.  Eat any subsequent string
2080  // expressions.  At this point, we know that the only valid thing that starts
2081  // with '@' is an @"".
2082  llvm::SmallVector<SourceLocation, 4> AtLocs;
2083  ExprVector AtStrings(Actions);
2084  AtLocs.push_back(AtLoc);
2085  AtStrings.push_back(Res.release());
2086
2087  while (Tok.is(tok::at)) {
2088    AtLocs.push_back(ConsumeToken()); // eat the @.
2089
2090    // Invalid unless there is a string literal.
2091    if (!isTokenStringLiteral())
2092      return ExprError(Diag(Tok, diag::err_objc_concat_string));
2093
2094    OwningExprResult Lit(ParseStringLiteralExpression());
2095    if (Lit.isInvalid())
2096      return move(Lit);
2097
2098    AtStrings.push_back(Lit.release());
2099  }
2100
2101  return Owned(Actions.ParseObjCStringLiteral(&AtLocs[0], AtStrings.take(),
2102                                              AtStrings.size()));
2103}
2104
2105///    objc-encode-expression:
2106///      @encode ( type-name )
2107Parser::OwningExprResult
2108Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) {
2109  assert(Tok.isObjCAtKeyword(tok::objc_encode) && "Not an @encode expression!");
2110
2111  SourceLocation EncLoc = ConsumeToken();
2112
2113  if (Tok.isNot(tok::l_paren))
2114    return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@encode");
2115
2116  SourceLocation LParenLoc = ConsumeParen();
2117
2118  TypeResult Ty = ParseTypeName();
2119
2120  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
2121
2122  if (Ty.isInvalid())
2123    return ExprError();
2124
2125  return Owned(Actions.ParseObjCEncodeExpression(AtLoc, EncLoc, LParenLoc,
2126                                                 Ty.get(), RParenLoc));
2127}
2128
2129///     objc-protocol-expression
2130///       @protocol ( protocol-name )
2131Parser::OwningExprResult
2132Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) {
2133  SourceLocation ProtoLoc = ConsumeToken();
2134
2135  if (Tok.isNot(tok::l_paren))
2136    return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@protocol");
2137
2138  SourceLocation LParenLoc = ConsumeParen();
2139
2140  if (Tok.isNot(tok::identifier))
2141    return ExprError(Diag(Tok, diag::err_expected_ident));
2142
2143  IdentifierInfo *protocolId = Tok.getIdentifierInfo();
2144  ConsumeToken();
2145
2146  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
2147
2148  return Owned(Actions.ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc,
2149                                                   LParenLoc, RParenLoc));
2150}
2151
2152///     objc-selector-expression
2153///       @selector '(' objc-keyword-selector ')'
2154Parser::OwningExprResult
2155Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) {
2156  SourceLocation SelectorLoc = ConsumeToken();
2157
2158  if (Tok.isNot(tok::l_paren))
2159    return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@selector");
2160
2161  llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
2162  SourceLocation LParenLoc = ConsumeParen();
2163  SourceLocation sLoc;
2164  IdentifierInfo *SelIdent = ParseObjCSelectorPiece(sLoc);
2165  if (!SelIdent && Tok.isNot(tok::colon)) // missing selector name.
2166    return ExprError(Diag(Tok, diag::err_expected_ident));
2167
2168  KeyIdents.push_back(SelIdent);
2169  unsigned nColons = 0;
2170  if (Tok.isNot(tok::r_paren)) {
2171    while (1) {
2172      if (Tok.isNot(tok::colon))
2173        return ExprError(Diag(Tok, diag::err_expected_colon));
2174
2175      nColons++;
2176      ConsumeToken(); // Eat the ':'.
2177      if (Tok.is(tok::r_paren))
2178        break;
2179      // Check for another keyword selector.
2180      SourceLocation Loc;
2181      SelIdent = ParseObjCSelectorPiece(Loc);
2182      KeyIdents.push_back(SelIdent);
2183      if (!SelIdent && Tok.isNot(tok::colon))
2184        break;
2185    }
2186  }
2187  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
2188  Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]);
2189  return Owned(Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc,
2190                                                   LParenLoc, RParenLoc));
2191 }
2192