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