ParseObjc.cpp revision 2ccccb3ff40c64927817a7e1ddf1da8c188ed224
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/ParseDiagnostic.h"
15#include "clang/Parse/Parser.h"
16#include "clang/Sema/DeclSpec.h"
17#include "clang/Sema/Scope.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'
30Decl *Parser::ParseObjCAtDirectives() {
31  SourceLocation AtLoc = ConsumeToken(); // the "@"
32
33  if (Tok.is(tok::code_completion)) {
34    Actions.CodeCompleteObjCAtDirective(getCurScope(), 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 0;
59  }
60}
61
62///
63/// objc-class-declaration:
64///    '@' 'class' identifier-list ';'
65///
66Decl *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 0;
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 0;
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///
125Decl *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(getCurScope());
134    ConsumeCodeCompletionToken();
135  }
136
137  if (Tok.isNot(tok::identifier)) {
138    Diag(Tok, diag::err_expected_ident); // missing class or category name.
139    return 0;
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(getCurScope(), 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 0;
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 0;
168    }
169    rparenLoc = ConsumeParen();
170    // Next, we need to check for any protocol references.
171    SourceLocation LAngleLoc, EndProtoLoc;
172    llvm::SmallVector<Decl *, 8> ProtocolRefs;
173    llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
174    if (Tok.is(tok::less) &&
175        ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true,
176                                    LAngleLoc, EndProtoLoc))
177      return 0;
178
179    if (attrList) // categories don't support attributes.
180      Diag(Tok, diag::err_objc_no_attributes_on_category);
181
182    Decl *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(getCurScope(), 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 0;
213    }
214    superClassId = Tok.getIdentifierInfo();
215    superClassLoc = ConsumeToken();
216  }
217  // Next, we need to check for any protocol references.
218  llvm::SmallVector<Decl *, 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 0;
225
226  Decl *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  Decl *IDecl;
245  llvm::SmallVectorImpl<Decl *> &Props;
246  ObjCDeclSpec &OCDS;
247  SourceLocation AtLoc;
248  tok::ObjCKeywordKind MethodImplKind;
249
250  ObjCPropertyCallback(Parser &P, Decl *IDecl,
251                       llvm::SmallVectorImpl<Decl *> &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  Decl *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 0;
263    }
264    if (FD.BitfieldSize) {
265      P.Diag(AtLoc, diag::err_objc_property_bitfield)
266        << FD.D.getSourceRange();
267      return 0;
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    Decl *Property =
286      P.Actions.ActOnProperty(P.getCurScope(), 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(Decl *interfaceDecl,
310                                        tok::ObjCKeywordKind contextKey) {
311  llvm::SmallVector<Decl *, 32> allMethods;
312  llvm::SmallVector<Decl *, 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      Decl *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      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(getCurScope(),
351                                  ObjCImpDecl? Action::PCC_ObjCImplementation
352                                             : Action::PCC_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(getCurScope(), 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(getCurScope(), 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(getCurScope(), 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, Decl *ClassDecl,
472                                        Decl **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(getCurScope(), 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(getCurScope(), ClassDecl,
513                                                 Methods, NumMethods);
514        else
515          Actions.CodeCompleteObjCPropertyGetter(getCurScope(), 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///
565Decl *Parser::ParseObjCMethodPrototype(Decl *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  Decl *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///
776Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
777                                  tok::TokenKind mType,
778                                  Decl *IDecl,
779                                  tok::ObjCKeywordKind MethodImplKind) {
780  ParsingDeclRAIIObject PD(*this);
781
782  if (Tok.is(tok::code_completion)) {
783    Actions.CodeCompleteObjCMethodDecl(getCurScope(), 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(getCurScope(), 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 0;
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    Decl *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    // Code completion for the next piece of the selector.
860    if (Tok.is(tok::code_completion)) {
861      ConsumeCodeCompletionToken();
862      KeyIdents.push_back(SelIdent);
863      Actions.CodeCompleteObjCMethodDeclSelector(getCurScope(),
864                                                 mType == tok::minus,
865                                                 /*AtParameterName=*/true,
866                                                 ReturnType,
867                                                 KeyIdents.data(),
868                                                 KeyIdents.size());
869      KeyIdents.pop_back();
870      break;
871    }
872
873    if (Tok.isNot(tok::identifier)) {
874      Diag(Tok, diag::err_expected_ident); // missing argument name.
875      break;
876    }
877
878    ArgInfo.Name = Tok.getIdentifierInfo();
879    ArgInfo.NameLoc = Tok.getLocation();
880    ConsumeToken(); // Eat the identifier.
881
882    ArgInfos.push_back(ArgInfo);
883    KeyIdents.push_back(SelIdent);
884
885    // Code completion for the next piece of the selector.
886    if (Tok.is(tok::code_completion)) {
887      ConsumeCodeCompletionToken();
888      Actions.CodeCompleteObjCMethodDeclSelector(getCurScope(),
889                                                 mType == tok::minus,
890                                                 /*AtParameterName=*/false,
891                                                 ReturnType,
892                                                 KeyIdents.data(),
893                                                 KeyIdents.size());
894      break;
895    }
896
897    // Check for another keyword selector.
898    SourceLocation Loc;
899    SelIdent = ParseObjCSelectorPiece(Loc);
900    if (!SelIdent && Tok.isNot(tok::colon))
901      break;
902    // We have a selector or a colon, continue parsing.
903  }
904
905  bool isVariadic = false;
906
907  // Parse the (optional) parameter list.
908  while (Tok.is(tok::comma)) {
909    ConsumeToken();
910    if (Tok.is(tok::ellipsis)) {
911      isVariadic = true;
912      ConsumeToken();
913      break;
914    }
915    DeclSpec DS;
916    ParseDeclarationSpecifiers(DS);
917    // Parse the declarator.
918    Declarator ParmDecl(DS, Declarator::PrototypeContext);
919    ParseDeclarator(ParmDecl);
920    IdentifierInfo *ParmII = ParmDecl.getIdentifier();
921    Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl);
922    CParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
923                                                    ParmDecl.getIdentifierLoc(),
924                                                    Param,
925                                                   0));
926
927  }
928
929  // FIXME: Add support for optional parmameter list...
930  // If attributes exist after the method, parse them.
931  if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
932    MethodAttrs.reset(addAttributeLists(MethodAttrs.take(),
933                                        ParseGNUAttributes()));
934
935  if (KeyIdents.size() == 0)
936    return 0;
937  Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(),
938                                                   &KeyIdents[0]);
939  Decl *Result
940       = Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(),
941                                        mType, IDecl, DSRet, ReturnType, Sel,
942                                        &ArgInfos[0],
943                                        CParamInfo.data(), CParamInfo.size(),
944                                        MethodAttrs.get(),
945                                        MethodImplKind, isVariadic);
946  PD.complete(Result);
947
948  // Delete referenced AttributeList objects.
949  for (llvm::SmallVectorImpl<Action::ObjCArgInfo>::iterator
950       I = ArgInfos.begin(), E = ArgInfos.end(); I != E; ++I)
951    delete I->ArgAttrs;
952
953  return Result;
954}
955
956///   objc-protocol-refs:
957///     '<' identifier-list '>'
958///
959bool Parser::
960ParseObjCProtocolReferences(llvm::SmallVectorImpl<Decl *> &Protocols,
961                            llvm::SmallVectorImpl<SourceLocation> &ProtocolLocs,
962                            bool WarnOnDeclarations,
963                            SourceLocation &LAngleLoc, SourceLocation &EndLoc) {
964  assert(Tok.is(tok::less) && "expected <");
965
966  LAngleLoc = ConsumeToken(); // the "<"
967
968  llvm::SmallVector<IdentifierLocPair, 8> ProtocolIdents;
969
970  while (1) {
971    if (Tok.is(tok::code_completion)) {
972      Actions.CodeCompleteObjCProtocolReferences(ProtocolIdents.data(),
973                                                 ProtocolIdents.size());
974      ConsumeCodeCompletionToken();
975    }
976
977    if (Tok.isNot(tok::identifier)) {
978      Diag(Tok, diag::err_expected_ident);
979      SkipUntil(tok::greater);
980      return true;
981    }
982    ProtocolIdents.push_back(std::make_pair(Tok.getIdentifierInfo(),
983                                       Tok.getLocation()));
984    ProtocolLocs.push_back(Tok.getLocation());
985    ConsumeToken();
986
987    if (Tok.isNot(tok::comma))
988      break;
989    ConsumeToken();
990  }
991
992  // Consume the '>'.
993  if (Tok.isNot(tok::greater)) {
994    Diag(Tok, diag::err_expected_greater);
995    return true;
996  }
997
998  EndLoc = ConsumeAnyToken();
999
1000  // Convert the list of protocols identifiers into a list of protocol decls.
1001  Actions.FindProtocolDeclaration(WarnOnDeclarations,
1002                                  &ProtocolIdents[0], ProtocolIdents.size(),
1003                                  Protocols);
1004  return false;
1005}
1006
1007///   objc-class-instance-variables:
1008///     '{' objc-instance-variable-decl-list[opt] '}'
1009///
1010///   objc-instance-variable-decl-list:
1011///     objc-visibility-spec
1012///     objc-instance-variable-decl ';'
1013///     ';'
1014///     objc-instance-variable-decl-list objc-visibility-spec
1015///     objc-instance-variable-decl-list objc-instance-variable-decl ';'
1016///     objc-instance-variable-decl-list ';'
1017///
1018///   objc-visibility-spec:
1019///     @private
1020///     @protected
1021///     @public
1022///     @package [OBJC2]
1023///
1024///   objc-instance-variable-decl:
1025///     struct-declaration
1026///
1027void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl,
1028                                             tok::ObjCKeywordKind visibility,
1029                                             SourceLocation atLoc) {
1030  assert(Tok.is(tok::l_brace) && "expected {");
1031  llvm::SmallVector<Decl *, 32> AllIvarDecls;
1032
1033  ParseScope ClassScope(this, Scope::DeclScope|Scope::ClassScope);
1034
1035  SourceLocation LBraceLoc = ConsumeBrace(); // the "{"
1036
1037  // While we still have something to read, read the instance variables.
1038  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
1039    // Each iteration of this loop reads one objc-instance-variable-decl.
1040
1041    // Check for extraneous top-level semicolon.
1042    if (Tok.is(tok::semi)) {
1043      Diag(Tok, diag::ext_extra_ivar_semi)
1044        << FixItHint::CreateRemoval(Tok.getLocation());
1045      ConsumeToken();
1046      continue;
1047    }
1048
1049    // Set the default visibility to private.
1050    if (Tok.is(tok::at)) { // parse objc-visibility-spec
1051      ConsumeToken(); // eat the @ sign
1052
1053      if (Tok.is(tok::code_completion)) {
1054        Actions.CodeCompleteObjCAtVisibility(getCurScope());
1055        ConsumeCodeCompletionToken();
1056      }
1057
1058      switch (Tok.getObjCKeywordID()) {
1059      case tok::objc_private:
1060      case tok::objc_public:
1061      case tok::objc_protected:
1062      case tok::objc_package:
1063        visibility = Tok.getObjCKeywordID();
1064        ConsumeToken();
1065        continue;
1066      default:
1067        Diag(Tok, diag::err_objc_illegal_visibility_spec);
1068        continue;
1069      }
1070    }
1071
1072    if (Tok.is(tok::code_completion)) {
1073      Actions.CodeCompleteOrdinaryName(getCurScope(),
1074                                       Action::PCC_ObjCInstanceVariableList);
1075      ConsumeCodeCompletionToken();
1076    }
1077
1078    struct ObjCIvarCallback : FieldCallback {
1079      Parser &P;
1080      Decl *IDecl;
1081      tok::ObjCKeywordKind visibility;
1082      llvm::SmallVectorImpl<Decl *> &AllIvarDecls;
1083
1084      ObjCIvarCallback(Parser &P, Decl *IDecl, tok::ObjCKeywordKind V,
1085                       llvm::SmallVectorImpl<Decl *> &AllIvarDecls) :
1086        P(P), IDecl(IDecl), visibility(V), AllIvarDecls(AllIvarDecls) {
1087      }
1088
1089      Decl *invoke(FieldDeclarator &FD) {
1090        // Install the declarator into the interface decl.
1091        Decl *Field
1092          = P.Actions.ActOnIvar(P.getCurScope(),
1093                                FD.D.getDeclSpec().getSourceRange().getBegin(),
1094                                IDecl, FD.D, FD.BitfieldSize, visibility);
1095        if (Field)
1096          AllIvarDecls.push_back(Field);
1097        return Field;
1098      }
1099    } Callback(*this, interfaceDecl, visibility, AllIvarDecls);
1100
1101    // Parse all the comma separated declarators.
1102    DeclSpec DS;
1103    ParseStructDeclaration(DS, Callback);
1104
1105    if (Tok.is(tok::semi)) {
1106      ConsumeToken();
1107    } else {
1108      Diag(Tok, diag::err_expected_semi_decl_list);
1109      // Skip to end of block or statement
1110      SkipUntil(tok::r_brace, true, true);
1111    }
1112  }
1113  SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
1114  // Call ActOnFields() even if we don't have any decls. This is useful
1115  // for code rewriting tools that need to be aware of the empty list.
1116  Actions.ActOnFields(getCurScope(), atLoc, interfaceDecl,
1117                      AllIvarDecls.data(), AllIvarDecls.size(),
1118                      LBraceLoc, RBraceLoc, 0);
1119  return;
1120}
1121
1122///   objc-protocol-declaration:
1123///     objc-protocol-definition
1124///     objc-protocol-forward-reference
1125///
1126///   objc-protocol-definition:
1127///     @protocol identifier
1128///       objc-protocol-refs[opt]
1129///       objc-interface-decl-list
1130///     @end
1131///
1132///   objc-protocol-forward-reference:
1133///     @protocol identifier-list ';'
1134///
1135///   "@protocol identifier ;" should be resolved as "@protocol
1136///   identifier-list ;": objc-interface-decl-list may not start with a
1137///   semicolon in the first alternative if objc-protocol-refs are omitted.
1138Decl *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
1139                                                      AttributeList *attrList) {
1140  assert(Tok.isObjCAtKeyword(tok::objc_protocol) &&
1141         "ParseObjCAtProtocolDeclaration(): Expected @protocol");
1142  ConsumeToken(); // the "protocol" identifier
1143
1144  if (Tok.is(tok::code_completion)) {
1145    Actions.CodeCompleteObjCProtocolDecl(getCurScope());
1146    ConsumeCodeCompletionToken();
1147  }
1148
1149  if (Tok.isNot(tok::identifier)) {
1150    Diag(Tok, diag::err_expected_ident); // missing protocol name.
1151    return 0;
1152  }
1153  // Save the protocol name, then consume it.
1154  IdentifierInfo *protocolName = Tok.getIdentifierInfo();
1155  SourceLocation nameLoc = ConsumeToken();
1156
1157  if (Tok.is(tok::semi)) { // forward declaration of one protocol.
1158    IdentifierLocPair ProtoInfo(protocolName, nameLoc);
1159    ConsumeToken();
1160    return Actions.ActOnForwardProtocolDeclaration(AtLoc, &ProtoInfo, 1,
1161                                                   attrList);
1162  }
1163
1164  if (Tok.is(tok::comma)) { // list of forward declarations.
1165    llvm::SmallVector<IdentifierLocPair, 8> ProtocolRefs;
1166    ProtocolRefs.push_back(std::make_pair(protocolName, nameLoc));
1167
1168    // Parse the list of forward declarations.
1169    while (1) {
1170      ConsumeToken(); // the ','
1171      if (Tok.isNot(tok::identifier)) {
1172        Diag(Tok, diag::err_expected_ident);
1173        SkipUntil(tok::semi);
1174        return 0;
1175      }
1176      ProtocolRefs.push_back(IdentifierLocPair(Tok.getIdentifierInfo(),
1177                                               Tok.getLocation()));
1178      ConsumeToken(); // the identifier
1179
1180      if (Tok.isNot(tok::comma))
1181        break;
1182    }
1183    // Consume the ';'.
1184    if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@protocol"))
1185      return 0;
1186
1187    return Actions.ActOnForwardProtocolDeclaration(AtLoc,
1188                                                   &ProtocolRefs[0],
1189                                                   ProtocolRefs.size(),
1190                                                   attrList);
1191  }
1192
1193  // Last, and definitely not least, parse a protocol declaration.
1194  SourceLocation LAngleLoc, EndProtoLoc;
1195
1196  llvm::SmallVector<Decl *, 8> ProtocolRefs;
1197  llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
1198  if (Tok.is(tok::less) &&
1199      ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, false,
1200                                  LAngleLoc, EndProtoLoc))
1201    return 0;
1202
1203  Decl *ProtoType =
1204    Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc,
1205                                        ProtocolRefs.data(),
1206                                        ProtocolRefs.size(),
1207                                        ProtocolLocs.data(),
1208                                        EndProtoLoc, attrList);
1209  ParseObjCInterfaceDeclList(ProtoType, tok::objc_protocol);
1210  return ProtoType;
1211}
1212
1213///   objc-implementation:
1214///     objc-class-implementation-prologue
1215///     objc-category-implementation-prologue
1216///
1217///   objc-class-implementation-prologue:
1218///     @implementation identifier objc-superclass[opt]
1219///       objc-class-instance-variables[opt]
1220///
1221///   objc-category-implementation-prologue:
1222///     @implementation identifier ( identifier )
1223Decl *Parser::ParseObjCAtImplementationDeclaration(
1224  SourceLocation atLoc) {
1225  assert(Tok.isObjCAtKeyword(tok::objc_implementation) &&
1226         "ParseObjCAtImplementationDeclaration(): Expected @implementation");
1227  ConsumeToken(); // the "implementation" identifier
1228
1229  // Code completion after '@implementation'.
1230  if (Tok.is(tok::code_completion)) {
1231    Actions.CodeCompleteObjCImplementationDecl(getCurScope());
1232    ConsumeCodeCompletionToken();
1233  }
1234
1235  if (Tok.isNot(tok::identifier)) {
1236    Diag(Tok, diag::err_expected_ident); // missing class or category name.
1237    return 0;
1238  }
1239  // We have a class or category name - consume it.
1240  IdentifierInfo *nameId = Tok.getIdentifierInfo();
1241  SourceLocation nameLoc = ConsumeToken(); // consume class or category name
1242
1243  if (Tok.is(tok::l_paren)) {
1244    // we have a category implementation.
1245    SourceLocation lparenLoc = ConsumeParen();
1246    SourceLocation categoryLoc, rparenLoc;
1247    IdentifierInfo *categoryId = 0;
1248
1249    if (Tok.is(tok::code_completion)) {
1250      Actions.CodeCompleteObjCImplementationCategory(getCurScope(), nameId, nameLoc);
1251      ConsumeCodeCompletionToken();
1252    }
1253
1254    if (Tok.is(tok::identifier)) {
1255      categoryId = Tok.getIdentifierInfo();
1256      categoryLoc = ConsumeToken();
1257    } else {
1258      Diag(Tok, diag::err_expected_ident); // missing category name.
1259      return 0;
1260    }
1261    if (Tok.isNot(tok::r_paren)) {
1262      Diag(Tok, diag::err_expected_rparen);
1263      SkipUntil(tok::r_paren, false); // don't stop at ';'
1264      return 0;
1265    }
1266    rparenLoc = ConsumeParen();
1267    Decl *ImplCatType = Actions.ActOnStartCategoryImplementation(
1268                                    atLoc, nameId, nameLoc, categoryId,
1269                                    categoryLoc);
1270    ObjCImpDecl = ImplCatType;
1271    PendingObjCImpDecl.push_back(ObjCImpDecl);
1272    return 0;
1273  }
1274  // We have a class implementation
1275  SourceLocation superClassLoc;
1276  IdentifierInfo *superClassId = 0;
1277  if (Tok.is(tok::colon)) {
1278    // We have a super class
1279    ConsumeToken();
1280    if (Tok.isNot(tok::identifier)) {
1281      Diag(Tok, diag::err_expected_ident); // missing super class name.
1282      return 0;
1283    }
1284    superClassId = Tok.getIdentifierInfo();
1285    superClassLoc = ConsumeToken(); // Consume super class name
1286  }
1287  Decl *ImplClsType = Actions.ActOnStartClassImplementation(
1288                                  atLoc, nameId, nameLoc,
1289                                  superClassId, superClassLoc);
1290
1291  if (Tok.is(tok::l_brace)) // we have ivars
1292    ParseObjCClassInstanceVariables(ImplClsType/*FIXME*/,
1293                                    tok::objc_private, atLoc);
1294  ObjCImpDecl = ImplClsType;
1295  PendingObjCImpDecl.push_back(ObjCImpDecl);
1296
1297  return 0;
1298}
1299
1300Decl *Parser::ParseObjCAtEndDeclaration(SourceRange atEnd) {
1301  assert(Tok.isObjCAtKeyword(tok::objc_end) &&
1302         "ParseObjCAtEndDeclaration(): Expected @end");
1303  Decl *Result = ObjCImpDecl;
1304  ConsumeToken(); // the "end" identifier
1305  if (ObjCImpDecl) {
1306    Actions.ActOnAtEnd(getCurScope(), atEnd, ObjCImpDecl);
1307    ObjCImpDecl = 0;
1308    PendingObjCImpDecl.pop_back();
1309  }
1310  else {
1311    // missing @implementation
1312    Diag(atEnd.getBegin(), diag::warn_expected_implementation);
1313  }
1314  return Result;
1315}
1316
1317Parser::DeclGroupPtrTy Parser::FinishPendingObjCActions() {
1318  Actions.DiagnoseUseOfUnimplementedSelectors();
1319  if (PendingObjCImpDecl.empty())
1320    return Actions.ConvertDeclToDeclGroup(0);
1321  Decl *ImpDecl = PendingObjCImpDecl.pop_back_val();
1322  Actions.ActOnAtEnd(getCurScope(), SourceRange(), ImpDecl);
1323  return Actions.ConvertDeclToDeclGroup(ImpDecl);
1324}
1325
1326///   compatibility-alias-decl:
1327///     @compatibility_alias alias-name  class-name ';'
1328///
1329Decl *Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) {
1330  assert(Tok.isObjCAtKeyword(tok::objc_compatibility_alias) &&
1331         "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias");
1332  ConsumeToken(); // consume compatibility_alias
1333  if (Tok.isNot(tok::identifier)) {
1334    Diag(Tok, diag::err_expected_ident);
1335    return 0;
1336  }
1337  IdentifierInfo *aliasId = Tok.getIdentifierInfo();
1338  SourceLocation aliasLoc = ConsumeToken(); // consume alias-name
1339  if (Tok.isNot(tok::identifier)) {
1340    Diag(Tok, diag::err_expected_ident);
1341    return 0;
1342  }
1343  IdentifierInfo *classId = Tok.getIdentifierInfo();
1344  SourceLocation classLoc = ConsumeToken(); // consume class-name;
1345  if (Tok.isNot(tok::semi)) {
1346    Diag(Tok, diag::err_expected_semi_after) << "@compatibility_alias";
1347    return 0;
1348  }
1349  return Actions.ActOnCompatiblityAlias(atLoc, aliasId, aliasLoc,
1350                                        classId, classLoc);
1351}
1352
1353///   property-synthesis:
1354///     @synthesize property-ivar-list ';'
1355///
1356///   property-ivar-list:
1357///     property-ivar
1358///     property-ivar-list ',' property-ivar
1359///
1360///   property-ivar:
1361///     identifier
1362///     identifier '=' identifier
1363///
1364Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
1365  assert(Tok.isObjCAtKeyword(tok::objc_synthesize) &&
1366         "ParseObjCPropertyDynamic(): Expected '@synthesize'");
1367  SourceLocation loc = ConsumeToken(); // consume synthesize
1368
1369  while (true) {
1370    if (Tok.is(tok::code_completion)) {
1371      Actions.CodeCompleteObjCPropertyDefinition(getCurScope(), ObjCImpDecl);
1372      ConsumeCodeCompletionToken();
1373    }
1374
1375    if (Tok.isNot(tok::identifier)) {
1376      Diag(Tok, diag::err_synthesized_property_name);
1377      SkipUntil(tok::semi);
1378      return 0;
1379    }
1380
1381    IdentifierInfo *propertyIvar = 0;
1382    IdentifierInfo *propertyId = Tok.getIdentifierInfo();
1383    SourceLocation propertyLoc = ConsumeToken(); // consume property name
1384    if (Tok.is(tok::equal)) {
1385      // property '=' ivar-name
1386      ConsumeToken(); // consume '='
1387
1388      if (Tok.is(tok::code_completion)) {
1389        Actions.CodeCompleteObjCPropertySynthesizeIvar(getCurScope(), propertyId,
1390                                                       ObjCImpDecl);
1391        ConsumeCodeCompletionToken();
1392      }
1393
1394      if (Tok.isNot(tok::identifier)) {
1395        Diag(Tok, diag::err_expected_ident);
1396        break;
1397      }
1398      propertyIvar = Tok.getIdentifierInfo();
1399      ConsumeToken(); // consume ivar-name
1400    }
1401    Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, true, ObjCImpDecl,
1402                                  propertyId, propertyIvar);
1403    if (Tok.isNot(tok::comma))
1404      break;
1405    ConsumeToken(); // consume ','
1406  }
1407  if (Tok.isNot(tok::semi)) {
1408    Diag(Tok, diag::err_expected_semi_after) << "@synthesize";
1409    SkipUntil(tok::semi);
1410  }
1411  else
1412    ConsumeToken(); // consume ';'
1413  return 0;
1414}
1415
1416///   property-dynamic:
1417///     @dynamic  property-list
1418///
1419///   property-list:
1420///     identifier
1421///     property-list ',' identifier
1422///
1423Decl *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
1424  assert(Tok.isObjCAtKeyword(tok::objc_dynamic) &&
1425         "ParseObjCPropertyDynamic(): Expected '@dynamic'");
1426  SourceLocation loc = ConsumeToken(); // consume dynamic
1427  while (true) {
1428    if (Tok.is(tok::code_completion)) {
1429      Actions.CodeCompleteObjCPropertyDefinition(getCurScope(), ObjCImpDecl);
1430      ConsumeCodeCompletionToken();
1431    }
1432
1433    if (Tok.isNot(tok::identifier)) {
1434      Diag(Tok, diag::err_expected_ident);
1435      SkipUntil(tok::semi);
1436      return 0;
1437    }
1438
1439    IdentifierInfo *propertyId = Tok.getIdentifierInfo();
1440    SourceLocation propertyLoc = ConsumeToken(); // consume property name
1441    Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, false, ObjCImpDecl,
1442                                  propertyId, 0);
1443
1444    if (Tok.isNot(tok::comma))
1445      break;
1446    ConsumeToken(); // consume ','
1447  }
1448  if (Tok.isNot(tok::semi)) {
1449    Diag(Tok, diag::err_expected_semi_after) << "@dynamic";
1450    SkipUntil(tok::semi);
1451  }
1452  else
1453    ConsumeToken(); // consume ';'
1454  return 0;
1455}
1456
1457///  objc-throw-statement:
1458///    throw expression[opt];
1459///
1460Parser::OwningStmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) {
1461  OwningExprResult Res;
1462  ConsumeToken(); // consume throw
1463  if (Tok.isNot(tok::semi)) {
1464    Res = ParseExpression();
1465    if (Res.isInvalid()) {
1466      SkipUntil(tok::semi);
1467      return StmtError();
1468    }
1469  }
1470  // consume ';'
1471  ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@throw");
1472  return Actions.ActOnObjCAtThrowStmt(atLoc, move(Res), getCurScope());
1473}
1474
1475/// objc-synchronized-statement:
1476///   @synchronized '(' expression ')' compound-statement
1477///
1478Parser::OwningStmtResult
1479Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
1480  ConsumeToken(); // consume synchronized
1481  if (Tok.isNot(tok::l_paren)) {
1482    Diag(Tok, diag::err_expected_lparen_after) << "@synchronized";
1483    return StmtError();
1484  }
1485  ConsumeParen();  // '('
1486  OwningExprResult Res(ParseExpression());
1487  if (Res.isInvalid()) {
1488    SkipUntil(tok::semi);
1489    return StmtError();
1490  }
1491  if (Tok.isNot(tok::r_paren)) {
1492    Diag(Tok, diag::err_expected_lbrace);
1493    return StmtError();
1494  }
1495  ConsumeParen();  // ')'
1496  if (Tok.isNot(tok::l_brace)) {
1497    Diag(Tok, diag::err_expected_lbrace);
1498    return StmtError();
1499  }
1500  // Enter a scope to hold everything within the compound stmt.  Compound
1501  // statements can always hold declarations.
1502  ParseScope BodyScope(this, Scope::DeclScope);
1503
1504  OwningStmtResult SynchBody(ParseCompoundStatementBody());
1505
1506  BodyScope.Exit();
1507  if (SynchBody.isInvalid())
1508    SynchBody = Actions.ActOnNullStmt(Tok.getLocation());
1509  return Actions.ActOnObjCAtSynchronizedStmt(atLoc, move(Res), move(SynchBody));
1510}
1511
1512///  objc-try-catch-statement:
1513///    @try compound-statement objc-catch-list[opt]
1514///    @try compound-statement objc-catch-list[opt] @finally compound-statement
1515///
1516///  objc-catch-list:
1517///    @catch ( parameter-declaration ) compound-statement
1518///    objc-catch-list @catch ( catch-parameter-declaration ) compound-statement
1519///  catch-parameter-declaration:
1520///     parameter-declaration
1521///     '...' [OBJC2]
1522///
1523Parser::OwningStmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
1524  bool catch_or_finally_seen = false;
1525
1526  ConsumeToken(); // consume try
1527  if (Tok.isNot(tok::l_brace)) {
1528    Diag(Tok, diag::err_expected_lbrace);
1529    return StmtError();
1530  }
1531  StmtVector CatchStmts(Actions);
1532  OwningStmtResult FinallyStmt;
1533  ParseScope TryScope(this, Scope::DeclScope);
1534  OwningStmtResult TryBody(ParseCompoundStatementBody());
1535  TryScope.Exit();
1536  if (TryBody.isInvalid())
1537    TryBody = Actions.ActOnNullStmt(Tok.getLocation());
1538
1539  while (Tok.is(tok::at)) {
1540    // At this point, we need to lookahead to determine if this @ is the start
1541    // of an @catch or @finally.  We don't want to consume the @ token if this
1542    // is an @try or @encode or something else.
1543    Token AfterAt = GetLookAheadToken(1);
1544    if (!AfterAt.isObjCAtKeyword(tok::objc_catch) &&
1545        !AfterAt.isObjCAtKeyword(tok::objc_finally))
1546      break;
1547
1548    SourceLocation AtCatchFinallyLoc = ConsumeToken();
1549    if (Tok.isObjCAtKeyword(tok::objc_catch)) {
1550      Decl *FirstPart = 0;
1551      ConsumeToken(); // consume catch
1552      if (Tok.is(tok::l_paren)) {
1553        ConsumeParen();
1554        ParseScope CatchScope(this, Scope::DeclScope|Scope::AtCatchScope);
1555        if (Tok.isNot(tok::ellipsis)) {
1556          DeclSpec DS;
1557          ParseDeclarationSpecifiers(DS);
1558          // For some odd reason, the name of the exception variable is
1559          // optional. As a result, we need to use "PrototypeContext", because
1560          // we must accept either 'declarator' or 'abstract-declarator' here.
1561          Declarator ParmDecl(DS, Declarator::PrototypeContext);
1562          ParseDeclarator(ParmDecl);
1563
1564          // Inform the actions module about the declarator, so it
1565          // gets added to the current scope.
1566          FirstPart = Actions.ActOnObjCExceptionDecl(getCurScope(), ParmDecl);
1567        } else
1568          ConsumeToken(); // consume '...'
1569
1570        SourceLocation RParenLoc;
1571
1572        if (Tok.is(tok::r_paren))
1573          RParenLoc = ConsumeParen();
1574        else // Skip over garbage, until we get to ')'.  Eat the ')'.
1575          SkipUntil(tok::r_paren, true, false);
1576
1577        OwningStmtResult CatchBody(true);
1578        if (Tok.is(tok::l_brace))
1579          CatchBody = ParseCompoundStatementBody();
1580        else
1581          Diag(Tok, diag::err_expected_lbrace);
1582        if (CatchBody.isInvalid())
1583          CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
1584
1585        OwningStmtResult Catch = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc,
1586                                                              RParenLoc,
1587                                                              FirstPart,
1588                                                              move(CatchBody));
1589        if (!Catch.isInvalid())
1590          CatchStmts.push_back(Catch.release());
1591
1592      } else {
1593        Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
1594          << "@catch clause";
1595        return StmtError();
1596      }
1597      catch_or_finally_seen = true;
1598    } else {
1599      assert(Tok.isObjCAtKeyword(tok::objc_finally) && "Lookahead confused?");
1600      ConsumeToken(); // consume finally
1601      ParseScope FinallyScope(this, Scope::DeclScope);
1602
1603      OwningStmtResult FinallyBody(true);
1604      if (Tok.is(tok::l_brace))
1605        FinallyBody = ParseCompoundStatementBody();
1606      else
1607        Diag(Tok, diag::err_expected_lbrace);
1608      if (FinallyBody.isInvalid())
1609        FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
1610      FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
1611                                                   move(FinallyBody));
1612      catch_or_finally_seen = true;
1613      break;
1614    }
1615  }
1616  if (!catch_or_finally_seen) {
1617    Diag(atLoc, diag::err_missing_catch_finally);
1618    return StmtError();
1619  }
1620
1621  return Actions.ActOnObjCAtTryStmt(atLoc, move(TryBody),
1622                                    move_arg(CatchStmts),
1623                                    move(FinallyStmt));
1624}
1625
1626///   objc-method-def: objc-method-proto ';'[opt] '{' body '}'
1627///
1628Decl *Parser::ParseObjCMethodDefinition() {
1629  Decl *MDecl = ParseObjCMethodPrototype(ObjCImpDecl);
1630
1631  PrettyStackTraceActionsDecl CrashInfo(MDecl, Tok.getLocation(), Actions,
1632                                        PP.getSourceManager(),
1633                                        "parsing Objective-C method");
1634
1635  // parse optional ';'
1636  if (Tok.is(tok::semi)) {
1637    if (ObjCImpDecl) {
1638      Diag(Tok, diag::warn_semicolon_before_method_body)
1639        << FixItHint::CreateRemoval(Tok.getLocation());
1640    }
1641    ConsumeToken();
1642  }
1643
1644  // We should have an opening brace now.
1645  if (Tok.isNot(tok::l_brace)) {
1646    Diag(Tok, diag::err_expected_method_body);
1647
1648    // Skip over garbage, until we get to '{'.  Don't eat the '{'.
1649    SkipUntil(tok::l_brace, true, true);
1650
1651    // If we didn't find the '{', bail out.
1652    if (Tok.isNot(tok::l_brace))
1653      return 0;
1654  }
1655  SourceLocation BraceLoc = Tok.getLocation();
1656
1657  // Enter a scope for the method body.
1658  ParseScope BodyScope(this,
1659                       Scope::ObjCMethodScope|Scope::FnScope|Scope::DeclScope);
1660
1661  // Tell the actions module that we have entered a method definition with the
1662  // specified Declarator for the method.
1663  Actions.ActOnStartOfObjCMethodDef(getCurScope(), MDecl);
1664
1665  OwningStmtResult FnBody(ParseCompoundStatementBody());
1666
1667  // If the function body could not be parsed, make a bogus compoundstmt.
1668  if (FnBody.isInvalid())
1669    FnBody = Actions.ActOnCompoundStmt(BraceLoc, BraceLoc,
1670                                       MultiStmtArg(Actions), false);
1671
1672  // TODO: Pass argument information.
1673  Actions.ActOnFinishFunctionBody(MDecl, move(FnBody));
1674
1675  // Leave the function body scope.
1676  BodyScope.Exit();
1677
1678  return MDecl;
1679}
1680
1681Parser::OwningStmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) {
1682  if (Tok.is(tok::code_completion)) {
1683    Actions.CodeCompleteObjCAtStatement(getCurScope());
1684    ConsumeCodeCompletionToken();
1685    return StmtError();
1686  }
1687
1688  if (Tok.isObjCAtKeyword(tok::objc_try))
1689    return ParseObjCTryStmt(AtLoc);
1690
1691  if (Tok.isObjCAtKeyword(tok::objc_throw))
1692    return ParseObjCThrowStmt(AtLoc);
1693
1694  if (Tok.isObjCAtKeyword(tok::objc_synchronized))
1695    return ParseObjCSynchronizedStmt(AtLoc);
1696
1697  OwningExprResult Res(ParseExpressionWithLeadingAt(AtLoc));
1698  if (Res.isInvalid()) {
1699    // If the expression is invalid, skip ahead to the next semicolon. Not
1700    // doing this opens us up to the possibility of infinite loops if
1701    // ParseExpression does not consume any tokens.
1702    SkipUntil(tok::semi);
1703    return StmtError();
1704  }
1705
1706  // Otherwise, eat the semicolon.
1707  ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
1708  return Actions.ActOnExprStmt(Actions.MakeFullExpr(Res));
1709}
1710
1711Parser::OwningExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
1712  switch (Tok.getKind()) {
1713  case tok::code_completion:
1714    Actions.CodeCompleteObjCAtExpression(getCurScope());
1715    ConsumeCodeCompletionToken();
1716    return ExprError();
1717
1718  case tok::string_literal:    // primary-expression: string-literal
1719  case tok::wide_string_literal:
1720    return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
1721  default:
1722    if (Tok.getIdentifierInfo() == 0)
1723      return ExprError(Diag(AtLoc, diag::err_unexpected_at));
1724
1725    switch (Tok.getIdentifierInfo()->getObjCKeywordID()) {
1726    case tok::objc_encode:
1727      return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc));
1728    case tok::objc_protocol:
1729      return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc));
1730    case tok::objc_selector:
1731      return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc));
1732    default:
1733      return ExprError(Diag(AtLoc, diag::err_unexpected_at));
1734    }
1735  }
1736}
1737
1738/// \brirg Parse the receiver of an Objective-C++ message send.
1739///
1740/// This routine parses the receiver of a message send in
1741/// Objective-C++ either as a type or as an expression. Note that this
1742/// routine must not be called to parse a send to 'super', since it
1743/// has no way to return such a result.
1744///
1745/// \param IsExpr Whether the receiver was parsed as an expression.
1746///
1747/// \param TypeOrExpr If the receiver was parsed as an expression (\c
1748/// IsExpr is true), the parsed expression. If the receiver was parsed
1749/// as a type (\c IsExpr is false), the parsed type.
1750///
1751/// \returns True if an error occurred during parsing or semantic
1752/// analysis, in which case the arguments do not have valid
1753/// values. Otherwise, returns false for a successful parse.
1754///
1755///   objc-receiver: [C++]
1756///     'super' [not parsed here]
1757///     expression
1758///     simple-type-specifier
1759///     typename-specifier
1760bool Parser::ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr) {
1761  if (Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
1762      Tok.is(tok::kw_typename) || Tok.is(tok::annot_cxxscope))
1763    TryAnnotateTypeOrScopeToken();
1764
1765  if (!isCXXSimpleTypeSpecifier()) {
1766    //   objc-receiver:
1767    //     expression
1768    OwningExprResult Receiver = ParseExpression();
1769    if (Receiver.isInvalid())
1770      return true;
1771
1772    IsExpr = true;
1773    TypeOrExpr = Receiver.take();
1774    return false;
1775  }
1776
1777  // objc-receiver:
1778  //   typename-specifier
1779  //   simple-type-specifier
1780  //   expression (that starts with one of the above)
1781  DeclSpec DS;
1782  ParseCXXSimpleTypeSpecifier(DS);
1783
1784  if (Tok.is(tok::l_paren)) {
1785    // If we see an opening parentheses at this point, we are
1786    // actually parsing an expression that starts with a
1787    // function-style cast, e.g.,
1788    //
1789    //   postfix-expression:
1790    //     simple-type-specifier ( expression-list [opt] )
1791    //     typename-specifier ( expression-list [opt] )
1792    //
1793    // Parse the remainder of this case, then the (optional)
1794    // postfix-expression suffix, followed by the (optional)
1795    // right-hand side of the binary expression. We have an
1796    // instance method.
1797    OwningExprResult Receiver = ParseCXXTypeConstructExpression(DS);
1798    if (!Receiver.isInvalid())
1799      Receiver = ParsePostfixExpressionSuffix(move(Receiver));
1800    if (!Receiver.isInvalid())
1801      Receiver = ParseRHSOfBinaryExpression(move(Receiver), prec::Comma);
1802    if (Receiver.isInvalid())
1803      return true;
1804
1805    IsExpr = true;
1806    TypeOrExpr = Receiver.take();
1807    return false;
1808  }
1809
1810  // We have a class message. Turn the simple-type-specifier or
1811  // typename-specifier we parsed into a type and parse the
1812  // remainder of the class message.
1813  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
1814  TypeResult Type = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
1815  if (Type.isInvalid())
1816    return true;
1817
1818  IsExpr = false;
1819  TypeOrExpr = Type.get();
1820  return false;
1821}
1822
1823/// \brief Determine whether the parser is currently referring to a an
1824/// Objective-C message send, using a simplified heuristic to avoid overhead.
1825///
1826/// This routine will only return true for a subset of valid message-send
1827/// expressions.
1828bool Parser::isSimpleObjCMessageExpression() {
1829  assert(Tok.is(tok::l_square) && getLang().ObjC1 &&
1830         "Incorrect start for isSimpleObjCMessageExpression");
1831  return GetLookAheadToken(1).is(tok::identifier) &&
1832         GetLookAheadToken(2).is(tok::identifier);
1833}
1834
1835///   objc-message-expr:
1836///     '[' objc-receiver objc-message-args ']'
1837///
1838///   objc-receiver: [C]
1839///     'super'
1840///     expression
1841///     class-name
1842///     type-name
1843///
1844Parser::OwningExprResult Parser::ParseObjCMessageExpression() {
1845  assert(Tok.is(tok::l_square) && "'[' expected");
1846  SourceLocation LBracLoc = ConsumeBracket(); // consume '['
1847
1848  if (Tok.is(tok::code_completion)) {
1849    Actions.CodeCompleteObjCMessageReceiver(getCurScope());
1850    ConsumeCodeCompletionToken();
1851    SkipUntil(tok::r_square);
1852    return ExprError();
1853  }
1854
1855  if (getLang().CPlusPlus) {
1856    // We completely separate the C and C++ cases because C++ requires
1857    // more complicated (read: slower) parsing.
1858
1859    // Handle send to super.
1860    // FIXME: This doesn't benefit from the same typo-correction we
1861    // get in Objective-C.
1862    if (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_super &&
1863        NextToken().isNot(tok::period) && getCurScope()->isInObjcMethodScope())
1864      return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(), 0,
1865                                            ExprArg(Actions));
1866
1867    // Parse the receiver, which is either a type or an expression.
1868    bool IsExpr;
1869    void *TypeOrExpr;
1870    if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) {
1871      SkipUntil(tok::r_square);
1872      return ExprError();
1873    }
1874
1875    if (IsExpr)
1876      return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 0,
1877                           OwningExprResult(static_cast<Expr*>(TypeOrExpr)));
1878
1879    return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
1880                                          TypeOrExpr, ExprArg(Actions));
1881  }
1882
1883  if (Tok.is(tok::identifier)) {
1884    IdentifierInfo *Name = Tok.getIdentifierInfo();
1885    SourceLocation NameLoc = Tok.getLocation();
1886    TypeTy *ReceiverType;
1887    switch (Actions.getObjCMessageKind(getCurScope(), Name, NameLoc,
1888                                       Name == Ident_super,
1889                                       NextToken().is(tok::period),
1890                                       ReceiverType)) {
1891    case Action::ObjCSuperMessage:
1892      return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(), 0,
1893                                            ExprArg(Actions));
1894
1895    case Action::ObjCClassMessage:
1896      if (!ReceiverType) {
1897        SkipUntil(tok::r_square);
1898        return ExprError();
1899      }
1900
1901      ConsumeToken(); // the type name
1902
1903      return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
1904                                            ReceiverType,
1905                                            ExprArg(Actions));
1906
1907    case Action::ObjCInstanceMessage:
1908      // Fall through to parse an expression.
1909      break;
1910    }
1911  }
1912
1913  // Otherwise, an arbitrary expression can be the receiver of a send.
1914  OwningExprResult Res(ParseExpression());
1915  if (Res.isInvalid()) {
1916    SkipUntil(tok::r_square);
1917    return move(Res);
1918  }
1919
1920  return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 0,
1921                                        move(Res));
1922}
1923
1924/// \brief Parse the remainder of an Objective-C message following the
1925/// '[' objc-receiver.
1926///
1927/// This routine handles sends to super, class messages (sent to a
1928/// class name), and instance messages (sent to an object), and the
1929/// target is represented by \p SuperLoc, \p ReceiverType, or \p
1930/// ReceiverExpr, respectively. Only one of these parameters may have
1931/// a valid value.
1932///
1933/// \param LBracLoc The location of the opening '['.
1934///
1935/// \param SuperLoc If this is a send to 'super', the location of the
1936/// 'super' keyword that indicates a send to the superclass.
1937///
1938/// \param ReceiverType If this is a class message, the type of the
1939/// class we are sending a message to.
1940///
1941/// \param ReceiverExpr If this is an instance message, the expression
1942/// used to compute the receiver object.
1943///
1944///   objc-message-args:
1945///     objc-selector
1946///     objc-keywordarg-list
1947///
1948///   objc-keywordarg-list:
1949///     objc-keywordarg
1950///     objc-keywordarg-list objc-keywordarg
1951///
1952///   objc-keywordarg:
1953///     selector-name[opt] ':' objc-keywordexpr
1954///
1955///   objc-keywordexpr:
1956///     nonempty-expr-list
1957///
1958///   nonempty-expr-list:
1959///     assignment-expression
1960///     nonempty-expr-list , assignment-expression
1961///
1962Parser::OwningExprResult
1963Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
1964                                       SourceLocation SuperLoc,
1965                                       TypeTy *ReceiverType,
1966                                       ExprArg ReceiverExpr) {
1967  if (Tok.is(tok::code_completion)) {
1968    if (SuperLoc.isValid())
1969      Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc, 0, 0);
1970    else if (ReceiverType)
1971      Actions.CodeCompleteObjCClassMessage(getCurScope(), ReceiverType, 0, 0);
1972    else
1973      Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr.get(),
1974                                              0, 0);
1975    ConsumeCodeCompletionToken();
1976  }
1977
1978  // Parse objc-selector
1979  SourceLocation Loc;
1980  IdentifierInfo *selIdent = ParseObjCSelectorPiece(Loc);
1981
1982  SourceLocation SelectorLoc = Loc;
1983
1984  llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
1985  ExprVector KeyExprs(Actions);
1986
1987  if (Tok.is(tok::colon)) {
1988    while (1) {
1989      // Each iteration parses a single keyword argument.
1990      KeyIdents.push_back(selIdent);
1991
1992      if (Tok.isNot(tok::colon)) {
1993        Diag(Tok, diag::err_expected_colon);
1994        // We must manually skip to a ']', otherwise the expression skipper will
1995        // stop at the ']' when it skips to the ';'.  We want it to skip beyond
1996        // the enclosing expression.
1997        SkipUntil(tok::r_square);
1998        return ExprError();
1999      }
2000
2001      ConsumeToken(); // Eat the ':'.
2002      ///  Parse the expression after ':'
2003      OwningExprResult Res(ParseAssignmentExpression());
2004      if (Res.isInvalid()) {
2005        // We must manually skip to a ']', otherwise the expression skipper will
2006        // stop at the ']' when it skips to the ';'.  We want it to skip beyond
2007        // the enclosing expression.
2008        SkipUntil(tok::r_square);
2009        return move(Res);
2010      }
2011
2012      // We have a valid expression.
2013      KeyExprs.push_back(Res.release());
2014
2015      // Code completion after each argument.
2016      if (Tok.is(tok::code_completion)) {
2017        if (SuperLoc.isValid())
2018          Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc,
2019                                               KeyIdents.data(),
2020                                               KeyIdents.size());
2021        else if (ReceiverType)
2022          Actions.CodeCompleteObjCClassMessage(getCurScope(), ReceiverType,
2023                                               KeyIdents.data(),
2024                                               KeyIdents.size());
2025        else
2026          Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr.get(),
2027                                                  KeyIdents.data(),
2028                                                  KeyIdents.size());
2029        ConsumeCodeCompletionToken();
2030      }
2031
2032      // Check for another keyword selector.
2033      selIdent = ParseObjCSelectorPiece(Loc);
2034      if (!selIdent && Tok.isNot(tok::colon))
2035        break;
2036      // We have a selector or a colon, continue parsing.
2037    }
2038    // Parse the, optional, argument list, comma separated.
2039    while (Tok.is(tok::comma)) {
2040      ConsumeToken(); // Eat the ','.
2041      ///  Parse the expression after ','
2042      OwningExprResult Res(ParseAssignmentExpression());
2043      if (Res.isInvalid()) {
2044        // We must manually skip to a ']', otherwise the expression skipper will
2045        // stop at the ']' when it skips to the ';'.  We want it to skip beyond
2046        // the enclosing expression.
2047        SkipUntil(tok::r_square);
2048        return move(Res);
2049      }
2050
2051      // We have a valid expression.
2052      KeyExprs.push_back(Res.release());
2053    }
2054  } else if (!selIdent) {
2055    Diag(Tok, diag::err_expected_ident); // missing selector name.
2056
2057    // We must manually skip to a ']', otherwise the expression skipper will
2058    // stop at the ']' when it skips to the ';'.  We want it to skip beyond
2059    // the enclosing expression.
2060    SkipUntil(tok::r_square);
2061    return ExprError();
2062  }
2063
2064  if (Tok.isNot(tok::r_square)) {
2065    if (Tok.is(tok::identifier))
2066      Diag(Tok, diag::err_expected_colon);
2067    else
2068      Diag(Tok, diag::err_expected_rsquare);
2069    // We must manually skip to a ']', otherwise the expression skipper will
2070    // stop at the ']' when it skips to the ';'.  We want it to skip beyond
2071    // the enclosing expression.
2072    SkipUntil(tok::r_square);
2073    return ExprError();
2074  }
2075
2076  SourceLocation RBracLoc = ConsumeBracket(); // consume ']'
2077
2078  unsigned nKeys = KeyIdents.size();
2079  if (nKeys == 0)
2080    KeyIdents.push_back(selIdent);
2081  Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]);
2082
2083  if (SuperLoc.isValid())
2084    return Actions.ActOnSuperMessage(getCurScope(), SuperLoc, Sel,
2085                                     LBracLoc, SelectorLoc, RBracLoc,
2086                                     Action::MultiExprArg(Actions,
2087                                                          KeyExprs.take(),
2088                                                          KeyExprs.size()));
2089  else if (ReceiverType)
2090    return Actions.ActOnClassMessage(getCurScope(), ReceiverType, Sel,
2091                                     LBracLoc, SelectorLoc, RBracLoc,
2092                                     Action::MultiExprArg(Actions,
2093                                                          KeyExprs.take(),
2094                                                          KeyExprs.size()));
2095  return Actions.ActOnInstanceMessage(getCurScope(), move(ReceiverExpr), Sel,
2096                                      LBracLoc, SelectorLoc, RBracLoc,
2097                                      Action::MultiExprArg(Actions,
2098                                                           KeyExprs.take(),
2099                                                           KeyExprs.size()));
2100}
2101
2102Parser::OwningExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
2103  OwningExprResult Res(ParseStringLiteralExpression());
2104  if (Res.isInvalid()) return move(Res);
2105
2106  // @"foo" @"bar" is a valid concatenated string.  Eat any subsequent string
2107  // expressions.  At this point, we know that the only valid thing that starts
2108  // with '@' is an @"".
2109  llvm::SmallVector<SourceLocation, 4> AtLocs;
2110  ExprVector AtStrings(Actions);
2111  AtLocs.push_back(AtLoc);
2112  AtStrings.push_back(Res.release());
2113
2114  while (Tok.is(tok::at)) {
2115    AtLocs.push_back(ConsumeToken()); // eat the @.
2116
2117    // Invalid unless there is a string literal.
2118    if (!isTokenStringLiteral())
2119      return ExprError(Diag(Tok, diag::err_objc_concat_string));
2120
2121    OwningExprResult Lit(ParseStringLiteralExpression());
2122    if (Lit.isInvalid())
2123      return move(Lit);
2124
2125    AtStrings.push_back(Lit.release());
2126  }
2127
2128  return Owned(Actions.ParseObjCStringLiteral(&AtLocs[0], AtStrings.take(),
2129                                              AtStrings.size()));
2130}
2131
2132///    objc-encode-expression:
2133///      @encode ( type-name )
2134Parser::OwningExprResult
2135Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) {
2136  assert(Tok.isObjCAtKeyword(tok::objc_encode) && "Not an @encode expression!");
2137
2138  SourceLocation EncLoc = ConsumeToken();
2139
2140  if (Tok.isNot(tok::l_paren))
2141    return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@encode");
2142
2143  SourceLocation LParenLoc = ConsumeParen();
2144
2145  TypeResult Ty = ParseTypeName();
2146
2147  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
2148
2149  if (Ty.isInvalid())
2150    return ExprError();
2151
2152  return Owned(Actions.ParseObjCEncodeExpression(AtLoc, EncLoc, LParenLoc,
2153                                                 Ty.get(), RParenLoc));
2154}
2155
2156///     objc-protocol-expression
2157///       @protocol ( protocol-name )
2158Parser::OwningExprResult
2159Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) {
2160  SourceLocation ProtoLoc = ConsumeToken();
2161
2162  if (Tok.isNot(tok::l_paren))
2163    return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@protocol");
2164
2165  SourceLocation LParenLoc = ConsumeParen();
2166
2167  if (Tok.isNot(tok::identifier))
2168    return ExprError(Diag(Tok, diag::err_expected_ident));
2169
2170  IdentifierInfo *protocolId = Tok.getIdentifierInfo();
2171  ConsumeToken();
2172
2173  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
2174
2175  return Owned(Actions.ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc,
2176                                                   LParenLoc, RParenLoc));
2177}
2178
2179///     objc-selector-expression
2180///       @selector '(' objc-keyword-selector ')'
2181Parser::OwningExprResult
2182Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) {
2183  SourceLocation SelectorLoc = ConsumeToken();
2184
2185  if (Tok.isNot(tok::l_paren))
2186    return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@selector");
2187
2188  llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
2189  SourceLocation LParenLoc = ConsumeParen();
2190  SourceLocation sLoc;
2191  IdentifierInfo *SelIdent = ParseObjCSelectorPiece(sLoc);
2192  if (!SelIdent && Tok.isNot(tok::colon)) // missing selector name.
2193    return ExprError(Diag(Tok, diag::err_expected_ident));
2194
2195  KeyIdents.push_back(SelIdent);
2196  unsigned nColons = 0;
2197  if (Tok.isNot(tok::r_paren)) {
2198    while (1) {
2199      if (Tok.isNot(tok::colon))
2200        return ExprError(Diag(Tok, diag::err_expected_colon));
2201
2202      nColons++;
2203      ConsumeToken(); // Eat the ':'.
2204      if (Tok.is(tok::r_paren))
2205        break;
2206      // Check for another keyword selector.
2207      SourceLocation Loc;
2208      SelIdent = ParseObjCSelectorPiece(Loc);
2209      KeyIdents.push_back(SelIdent);
2210      if (!SelIdent && Tok.isNot(tok::colon))
2211        break;
2212    }
2213  }
2214  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
2215  Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]);
2216  return Owned(Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc,
2217                                                   LParenLoc, RParenLoc));
2218 }
2219