ParseObjc.cpp revision ebf6443a4f493233f7e8d92b3a991848c8b1c00d
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 "AstGuard.h"
18#include "clang/Parse/ParseDiagnostic.h"
19#include "llvm/ADT/SmallVector.h"
20using namespace clang;
21
22
23/// ParseObjCAtDirectives - Handle parts of the external-declaration production:
24///       external-declaration: [C99 6.9]
25/// [OBJC]  objc-class-definition
26/// [OBJC]  objc-class-declaration
27/// [OBJC]  objc-alias-declaration
28/// [OBJC]  objc-protocol-definition
29/// [OBJC]  objc-method-definition
30/// [OBJC]  '@' 'end'
31Parser::DeclTy *Parser::ParseObjCAtDirectives() {
32  SourceLocation AtLoc = ConsumeToken(); // the "@"
33
34  switch (Tok.getObjCKeywordID()) {
35  case tok::objc_class:
36    return ParseObjCAtClassDeclaration(AtLoc);
37  case tok::objc_interface:
38    return ParseObjCAtInterfaceDeclaration(AtLoc);
39  case tok::objc_protocol:
40    return ParseObjCAtProtocolDeclaration(AtLoc);
41  case tok::objc_implementation:
42    return ParseObjCAtImplementationDeclaration(AtLoc);
43  case tok::objc_end:
44    return ParseObjCAtEndDeclaration(AtLoc);
45  case tok::objc_compatibility_alias:
46    return ParseObjCAtAliasDeclaration(AtLoc);
47  case tok::objc_synthesize:
48    return ParseObjCPropertySynthesize(AtLoc);
49  case tok::objc_dynamic:
50    return ParseObjCPropertyDynamic(AtLoc);
51  default:
52    Diag(AtLoc, diag::err_unexpected_at);
53    SkipUntil(tok::semi);
54    return 0;
55  }
56}
57
58///
59/// objc-class-declaration:
60///    '@' 'class' identifier-list ';'
61///
62Parser::DeclTy *Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) {
63  ConsumeToken(); // the identifier "class"
64  llvm::SmallVector<IdentifierInfo *, 8> ClassNames;
65
66  while (1) {
67    if (Tok.isNot(tok::identifier)) {
68      Diag(Tok, diag::err_expected_ident);
69      SkipUntil(tok::semi);
70      return 0;
71    }
72    ClassNames.push_back(Tok.getIdentifierInfo());
73    ConsumeToken();
74
75    if (Tok.isNot(tok::comma))
76      break;
77
78    ConsumeToken();
79  }
80
81  // Consume the ';'.
82  if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@class"))
83    return 0;
84
85  return Actions.ActOnForwardClassDeclaration(atLoc,
86                                      &ClassNames[0], ClassNames.size());
87}
88
89///
90///   objc-interface:
91///     objc-class-interface-attributes[opt] objc-class-interface
92///     objc-category-interface
93///
94///   objc-class-interface:
95///     '@' 'interface' identifier objc-superclass[opt]
96///       objc-protocol-refs[opt]
97///       objc-class-instance-variables[opt]
98///       objc-interface-decl-list
99///     @end
100///
101///   objc-category-interface:
102///     '@' 'interface' identifier '(' identifier[opt] ')'
103///       objc-protocol-refs[opt]
104///       objc-interface-decl-list
105///     @end
106///
107///   objc-superclass:
108///     ':' identifier
109///
110///   objc-class-interface-attributes:
111///     __attribute__((visibility("default")))
112///     __attribute__((visibility("hidden")))
113///     __attribute__((deprecated))
114///     __attribute__((unavailable))
115///     __attribute__((objc_exception)) - used by NSException on 64-bit
116///
117Parser::DeclTy *Parser::ParseObjCAtInterfaceDeclaration(
118  SourceLocation atLoc, AttributeList *attrList) {
119  assert(Tok.isObjCAtKeyword(tok::objc_interface) &&
120         "ParseObjCAtInterfaceDeclaration(): Expected @interface");
121  ConsumeToken(); // the "interface" identifier
122
123  if (Tok.isNot(tok::identifier)) {
124    Diag(Tok, diag::err_expected_ident); // missing class or category name.
125    return 0;
126  }
127  // We have a class or category name - consume it.
128  IdentifierInfo *nameId = Tok.getIdentifierInfo();
129  SourceLocation nameLoc = ConsumeToken();
130
131  if (Tok.is(tok::l_paren)) { // we have a category.
132    SourceLocation lparenLoc = ConsumeParen();
133    SourceLocation categoryLoc, rparenLoc;
134    IdentifierInfo *categoryId = 0;
135
136    // For ObjC2, the category name is optional (not an error).
137    if (Tok.is(tok::identifier)) {
138      categoryId = Tok.getIdentifierInfo();
139      categoryLoc = ConsumeToken();
140    } else if (!getLang().ObjC2) {
141      Diag(Tok, diag::err_expected_ident); // missing category name.
142      return 0;
143    }
144    if (Tok.isNot(tok::r_paren)) {
145      Diag(Tok, diag::err_expected_rparen);
146      SkipUntil(tok::r_paren, false); // don't stop at ';'
147      return 0;
148    }
149    rparenLoc = ConsumeParen();
150
151    // Next, we need to check for any protocol references.
152    SourceLocation EndProtoLoc;
153    llvm::SmallVector<DeclTy *, 8> ProtocolRefs;
154    if (Tok.is(tok::less) &&
155        ParseObjCProtocolReferences(ProtocolRefs, true, EndProtoLoc))
156      return 0;
157
158    if (attrList) // categories don't support attributes.
159      Diag(Tok, diag::err_objc_no_attributes_on_category);
160
161    DeclTy *CategoryType = Actions.ActOnStartCategoryInterface(atLoc,
162                                     nameId, nameLoc, categoryId, categoryLoc,
163                                     &ProtocolRefs[0], ProtocolRefs.size(),
164                                     EndProtoLoc);
165
166    ParseObjCInterfaceDeclList(CategoryType, tok::objc_not_keyword);
167    return CategoryType;
168  }
169  // Parse a class interface.
170  IdentifierInfo *superClassId = 0;
171  SourceLocation superClassLoc;
172
173  if (Tok.is(tok::colon)) { // a super class is specified.
174    ConsumeToken();
175    if (Tok.isNot(tok::identifier)) {
176      Diag(Tok, diag::err_expected_ident); // missing super class name.
177      return 0;
178    }
179    superClassId = Tok.getIdentifierInfo();
180    superClassLoc = ConsumeToken();
181  }
182  // Next, we need to check for any protocol references.
183  llvm::SmallVector<Action::DeclTy*, 8> ProtocolRefs;
184  SourceLocation EndProtoLoc;
185  if (Tok.is(tok::less) &&
186      ParseObjCProtocolReferences(ProtocolRefs, true, EndProtoLoc))
187    return 0;
188
189  DeclTy *ClsType =
190    Actions.ActOnStartClassInterface(atLoc, nameId, nameLoc,
191                                     superClassId, superClassLoc,
192                                     &ProtocolRefs[0], ProtocolRefs.size(),
193                                     EndProtoLoc, attrList);
194
195  if (Tok.is(tok::l_brace))
196    ParseObjCClassInstanceVariables(ClsType, atLoc);
197
198  ParseObjCInterfaceDeclList(ClsType, tok::objc_interface);
199  return ClsType;
200}
201
202/// constructSetterName - Return the setter name for the given
203/// identifier, i.e. "set" + Name where the initial character of Name
204/// has been capitalized.
205static IdentifierInfo *constructSetterName(IdentifierTable &Idents,
206                                           const IdentifierInfo *Name) {
207  llvm::SmallString<100> SelectorName;
208  SelectorName = "set";
209  SelectorName.append(Name->getName(), Name->getName()+Name->getLength());
210  SelectorName[3] = toupper(SelectorName[3]);
211  return &Idents.get(&SelectorName[0], &SelectorName[SelectorName.size()]);
212}
213
214///   objc-interface-decl-list:
215///     empty
216///     objc-interface-decl-list objc-property-decl [OBJC2]
217///     objc-interface-decl-list objc-method-requirement [OBJC2]
218///     objc-interface-decl-list objc-method-proto ';'
219///     objc-interface-decl-list declaration
220///     objc-interface-decl-list ';'
221///
222///   objc-method-requirement: [OBJC2]
223///     @required
224///     @optional
225///
226void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl,
227                                        tok::ObjCKeywordKind contextKey) {
228  llvm::SmallVector<DeclTy*, 32> allMethods;
229  llvm::SmallVector<DeclTy*, 16> allProperties;
230  tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword;
231
232  SourceLocation AtEndLoc;
233
234  while (1) {
235    // If this is a method prototype, parse it.
236    if (Tok.is(tok::minus) || Tok.is(tok::plus)) {
237      DeclTy *methodPrototype =
238        ParseObjCMethodPrototype(interfaceDecl, MethodImplKind);
239      allMethods.push_back(methodPrototype);
240      // Consume the ';' here, since ParseObjCMethodPrototype() is re-used for
241      // method definitions.
242      ExpectAndConsume(tok::semi, diag::err_expected_semi_after_method_proto,
243                       "", tok::semi);
244      continue;
245    }
246
247    // Ignore excess semicolons.
248    if (Tok.is(tok::semi)) {
249      ConsumeToken();
250      continue;
251    }
252
253    // If we got to the end of the file, exit the loop.
254    if (Tok.is(tok::eof))
255      break;
256
257    // If we don't have an @ directive, parse it as a function definition.
258    if (Tok.isNot(tok::at)) {
259      // The code below does not consume '}'s because it is afraid of eating the
260      // end of a namespace.  Because of the way this code is structured, an
261      // erroneous r_brace would cause an infinite loop if not handled here.
262      if (Tok.is(tok::r_brace))
263        break;
264
265      // FIXME: as the name implies, this rule allows function definitions.
266      // We could pass a flag or check for functions during semantic analysis.
267      ParseDeclarationOrFunctionDefinition();
268      continue;
269    }
270
271    // Otherwise, we have an @ directive, eat the @.
272    SourceLocation AtLoc = ConsumeToken(); // the "@"
273    tok::ObjCKeywordKind DirectiveKind = Tok.getObjCKeywordID();
274
275    if (DirectiveKind == tok::objc_end) { // @end -> terminate list
276      AtEndLoc = AtLoc;
277      break;
278    }
279
280    // Eat the identifier.
281    ConsumeToken();
282
283    switch (DirectiveKind) {
284    default:
285      // FIXME: If someone forgets an @end on a protocol, this loop will
286      // continue to eat up tons of stuff and spew lots of nonsense errors.  It
287      // would probably be better to bail out if we saw an @class or @interface
288      // or something like that.
289      Diag(AtLoc, diag::err_objc_illegal_interface_qual);
290      // Skip until we see an '@' or '}' or ';'.
291      SkipUntil(tok::r_brace, tok::at);
292      break;
293
294    case tok::objc_required:
295    case tok::objc_optional:
296      // This is only valid on protocols.
297      // FIXME: Should this check for ObjC2 being enabled?
298      if (contextKey != tok::objc_protocol)
299        Diag(AtLoc, diag::err_objc_directive_only_in_protocol);
300      else
301        MethodImplKind = DirectiveKind;
302      break;
303
304    case tok::objc_property:
305      if (!getLang().ObjC2)
306        Diag(AtLoc, diag::err_objc_propertoes_require_objc2);
307
308      ObjCDeclSpec OCDS;
309      // Parse property attribute list, if any.
310      if (Tok.is(tok::l_paren))
311        ParseObjCPropertyAttribute(OCDS);
312
313      // Parse all the comma separated declarators.
314      DeclSpec DS;
315      llvm::SmallVector<FieldDeclarator, 8> FieldDeclarators;
316      ParseStructDeclaration(DS, FieldDeclarators);
317
318      ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list, "",
319                       tok::at);
320
321      // Convert them all to property declarations.
322      for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) {
323        FieldDeclarator &FD = FieldDeclarators[i];
324        if (FD.D.getIdentifier() == 0) {
325          Diag(AtLoc, diag::err_objc_property_requires_field_name)
326            << FD.D.getSourceRange();
327          continue;
328        }
329        if (FD.BitfieldSize) {
330          Diag(AtLoc, diag::err_objc_property_bitfield)
331            << FD.D.getSourceRange();
332          continue;
333        }
334
335        // Install the property declarator into interfaceDecl.
336        IdentifierInfo *SelName =
337          OCDS.getGetterName() ? OCDS.getGetterName() : FD.D.getIdentifier();
338
339        Selector GetterSel =
340          PP.getSelectorTable().getNullarySelector(SelName);
341        IdentifierInfo *SetterName = OCDS.getSetterName();
342        if (!SetterName)
343          SetterName = constructSetterName(PP.getIdentifierTable(),
344                                           FD.D.getIdentifier());
345        Selector SetterSel =
346          PP.getSelectorTable().getUnarySelector(SetterName);
347        bool isOverridingProperty = false;
348        DeclTy *Property = Actions.ActOnProperty(CurScope, AtLoc, FD, OCDS,
349                                                 GetterSel, SetterSel,
350                                                 interfaceDecl,
351                                                 &isOverridingProperty,
352                                                 MethodImplKind);
353        if (!isOverridingProperty)
354          allProperties.push_back(Property);
355      }
356      break;
357    }
358  }
359
360  // We break out of the big loop in two cases: when we see @end or when we see
361  // EOF.  In the former case, eat the @end.  In the later case, emit an error.
362  if (Tok.isObjCAtKeyword(tok::objc_end))
363    ConsumeToken(); // the "end" identifier
364  else
365    Diag(Tok, diag::err_objc_missing_end);
366
367  // Insert collected methods declarations into the @interface object.
368  // This passes in an invalid SourceLocation for AtEndLoc when EOF is hit.
369  Actions.ActOnAtEnd(AtEndLoc, interfaceDecl,
370                     allMethods.empty() ? 0 : &allMethods[0],
371                     allMethods.size(),
372                     allProperties.empty() ? 0 : &allProperties[0],
373                     allProperties.size());
374}
375
376///   Parse property attribute declarations.
377///
378///   property-attr-decl: '(' property-attrlist ')'
379///   property-attrlist:
380///     property-attribute
381///     property-attrlist ',' property-attribute
382///   property-attribute:
383///     getter '=' identifier
384///     setter '=' identifier ':'
385///     readonly
386///     readwrite
387///     assign
388///     retain
389///     copy
390///     nonatomic
391///
392void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
393  assert(Tok.getKind() == tok::l_paren);
394  SourceLocation LHSLoc = ConsumeParen(); // consume '('
395
396  while (1) {
397    const IdentifierInfo *II = Tok.getIdentifierInfo();
398
399    // If this is not an identifier at all, bail out early.
400    if (II == 0) {
401      MatchRHSPunctuation(tok::r_paren, LHSLoc);
402      return;
403    }
404
405    SourceLocation AttrName = ConsumeToken(); // consume last attribute name
406
407    if (II->isStr("readonly"))
408      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_readonly);
409    else if (II->isStr("assign"))
410      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_assign);
411    else if (II->isStr("readwrite"))
412      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_readwrite);
413    else if (II->isStr("retain"))
414      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_retain);
415    else if (II->isStr("copy"))
416      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_copy);
417    else if (II->isStr("nonatomic"))
418      DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nonatomic);
419    else if (II->isStr("getter") || II->isStr("setter")) {
420      // getter/setter require extra treatment.
421      if (ExpectAndConsume(tok::equal, diag::err_objc_expected_equal, "",
422                           tok::r_paren))
423        return;
424
425      if (Tok.isNot(tok::identifier)) {
426        Diag(Tok, diag::err_expected_ident);
427        SkipUntil(tok::r_paren);
428        return;
429      }
430
431      if (II->getName()[0] == 's') {
432        DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_setter);
433        DS.setSetterName(Tok.getIdentifierInfo());
434        ConsumeToken();  // consume method name
435
436        if (ExpectAndConsume(tok::colon, diag::err_expected_colon, "",
437                             tok::r_paren))
438          return;
439      } else {
440        DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_getter);
441        DS.setGetterName(Tok.getIdentifierInfo());
442        ConsumeToken();  // consume method name
443      }
444    } else {
445      Diag(AttrName, diag::err_objc_expected_property_attr) << II;
446      SkipUntil(tok::r_paren);
447      return;
448    }
449
450    if (Tok.isNot(tok::comma))
451      break;
452
453    ConsumeToken();
454  }
455
456  MatchRHSPunctuation(tok::r_paren, LHSLoc);
457}
458
459///   objc-method-proto:
460///     objc-instance-method objc-method-decl objc-method-attributes[opt]
461///     objc-class-method objc-method-decl objc-method-attributes[opt]
462///
463///   objc-instance-method: '-'
464///   objc-class-method: '+'
465///
466///   objc-method-attributes:         [OBJC2]
467///     __attribute__((deprecated))
468///
469Parser::DeclTy *Parser::ParseObjCMethodPrototype(DeclTy *IDecl,
470                          tok::ObjCKeywordKind MethodImplKind) {
471  assert((Tok.is(tok::minus) || Tok.is(tok::plus)) && "expected +/-");
472
473  tok::TokenKind methodType = Tok.getKind();
474  SourceLocation mLoc = ConsumeToken();
475
476  DeclTy *MDecl = ParseObjCMethodDecl(mLoc, methodType, IDecl, MethodImplKind);
477  // Since this rule is used for both method declarations and definitions,
478  // the caller is (optionally) responsible for consuming the ';'.
479  return MDecl;
480}
481
482///   objc-selector:
483///     identifier
484///     one of
485///       enum struct union if else while do for switch case default
486///       break continue return goto asm sizeof typeof __alignof
487///       unsigned long const short volatile signed restrict _Complex
488///       in out inout bycopy byref oneway int char float double void _Bool
489///
490IdentifierInfo *Parser::ParseObjCSelector(SourceLocation &SelectorLoc) {
491  switch (Tok.getKind()) {
492  default:
493    return 0;
494  case tok::identifier:
495  case tok::kw_asm:
496  case tok::kw_auto:
497  case tok::kw_bool:
498  case tok::kw_break:
499  case tok::kw_case:
500  case tok::kw_catch:
501  case tok::kw_char:
502  case tok::kw_class:
503  case tok::kw_const:
504  case tok::kw_const_cast:
505  case tok::kw_continue:
506  case tok::kw_default:
507  case tok::kw_delete:
508  case tok::kw_do:
509  case tok::kw_double:
510  case tok::kw_dynamic_cast:
511  case tok::kw_else:
512  case tok::kw_enum:
513  case tok::kw_explicit:
514  case tok::kw_export:
515  case tok::kw_extern:
516  case tok::kw_false:
517  case tok::kw_float:
518  case tok::kw_for:
519  case tok::kw_friend:
520  case tok::kw_goto:
521  case tok::kw_if:
522  case tok::kw_inline:
523  case tok::kw_int:
524  case tok::kw_long:
525  case tok::kw_mutable:
526  case tok::kw_namespace:
527  case tok::kw_new:
528  case tok::kw_operator:
529  case tok::kw_private:
530  case tok::kw_protected:
531  case tok::kw_public:
532  case tok::kw_register:
533  case tok::kw_reinterpret_cast:
534  case tok::kw_restrict:
535  case tok::kw_return:
536  case tok::kw_short:
537  case tok::kw_signed:
538  case tok::kw_sizeof:
539  case tok::kw_static:
540  case tok::kw_static_cast:
541  case tok::kw_struct:
542  case tok::kw_switch:
543  case tok::kw_template:
544  case tok::kw_this:
545  case tok::kw_throw:
546  case tok::kw_true:
547  case tok::kw_try:
548  case tok::kw_typedef:
549  case tok::kw_typeid:
550  case tok::kw_typename:
551  case tok::kw_typeof:
552  case tok::kw_union:
553  case tok::kw_unsigned:
554  case tok::kw_using:
555  case tok::kw_virtual:
556  case tok::kw_void:
557  case tok::kw_volatile:
558  case tok::kw_wchar_t:
559  case tok::kw_while:
560  case tok::kw__Bool:
561  case tok::kw__Complex:
562  case tok::kw___alignof:
563    IdentifierInfo *II = Tok.getIdentifierInfo();
564    SelectorLoc = ConsumeToken();
565    return II;
566  }
567}
568
569///  objc-for-collection-in: 'in'
570///
571bool Parser::isTokIdentifier_in() const {
572  // FIXME: May have to do additional look-ahead to only allow for
573  // valid tokens following an 'in'; such as an identifier, unary operators,
574  // '[' etc.
575  return (getLang().ObjC2 && Tok.is(tok::identifier) &&
576          Tok.getIdentifierInfo() == ObjCTypeQuals[objc_in]);
577}
578
579/// ParseObjCTypeQualifierList - This routine parses the objective-c's type
580/// qualifier list and builds their bitmask representation in the input
581/// argument.
582///
583///   objc-type-qualifiers:
584///     objc-type-qualifier
585///     objc-type-qualifiers objc-type-qualifier
586///
587void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS) {
588  while (1) {
589    if (Tok.isNot(tok::identifier))
590      return;
591
592    const IdentifierInfo *II = Tok.getIdentifierInfo();
593    for (unsigned i = 0; i != objc_NumQuals; ++i) {
594      if (II != ObjCTypeQuals[i])
595        continue;
596
597      ObjCDeclSpec::ObjCDeclQualifier Qual;
598      switch (i) {
599      default: assert(0 && "Unknown decl qualifier");
600      case objc_in:     Qual = ObjCDeclSpec::DQ_In; break;
601      case objc_out:    Qual = ObjCDeclSpec::DQ_Out; break;
602      case objc_inout:  Qual = ObjCDeclSpec::DQ_Inout; break;
603      case objc_oneway: Qual = ObjCDeclSpec::DQ_Oneway; break;
604      case objc_bycopy: Qual = ObjCDeclSpec::DQ_Bycopy; break;
605      case objc_byref:  Qual = ObjCDeclSpec::DQ_Byref; break;
606      }
607      DS.setObjCDeclQualifier(Qual);
608      ConsumeToken();
609      II = 0;
610      break;
611    }
612
613    // If this wasn't a recognized qualifier, bail out.
614    if (II) return;
615  }
616}
617
618///   objc-type-name:
619///     '(' objc-type-qualifiers[opt] type-name ')'
620///     '(' objc-type-qualifiers[opt] ')'
621///
622Parser::TypeTy *Parser::ParseObjCTypeName(ObjCDeclSpec &DS) {
623  assert(Tok.is(tok::l_paren) && "expected (");
624
625  SourceLocation LParenLoc = ConsumeParen();
626  SourceLocation TypeStartLoc = Tok.getLocation();
627
628  // Parse type qualifiers, in, inout, etc.
629  ParseObjCTypeQualifierList(DS);
630
631  TypeTy *Ty = 0;
632  if (isTypeSpecifierQualifier()) {
633    TypeResult TypeSpec = ParseTypeName();
634    if (!TypeSpec.isInvalid())
635      Ty = TypeSpec.get();
636  }
637
638  if (Tok.is(tok::r_paren))
639    ConsumeParen();
640  else if (Tok.getLocation() == TypeStartLoc) {
641    // If we didn't eat any tokens, then this isn't a type.
642    Diag(Tok, diag::err_expected_type);
643    SkipUntil(tok::r_paren);
644  } else {
645    // Otherwise, we found *something*, but didn't get a ')' in the right
646    // place.  Emit an error then return what we have as the type.
647    MatchRHSPunctuation(tok::r_paren, LParenLoc);
648  }
649  return Ty;
650}
651
652///   objc-method-decl:
653///     objc-selector
654///     objc-keyword-selector objc-parmlist[opt]
655///     objc-type-name objc-selector
656///     objc-type-name objc-keyword-selector objc-parmlist[opt]
657///
658///   objc-keyword-selector:
659///     objc-keyword-decl
660///     objc-keyword-selector objc-keyword-decl
661///
662///   objc-keyword-decl:
663///     objc-selector ':' objc-type-name objc-keyword-attributes[opt] identifier
664///     objc-selector ':' objc-keyword-attributes[opt] identifier
665///     ':' objc-type-name objc-keyword-attributes[opt] identifier
666///     ':' objc-keyword-attributes[opt] identifier
667///
668///   objc-parmlist:
669///     objc-parms objc-ellipsis[opt]
670///
671///   objc-parms:
672///     objc-parms , parameter-declaration
673///
674///   objc-ellipsis:
675///     , ...
676///
677///   objc-keyword-attributes:         [OBJC2]
678///     __attribute__((unused))
679///
680Parser::DeclTy *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
681                                            tok::TokenKind mType,
682                                            DeclTy *IDecl,
683                                            tok::ObjCKeywordKind MethodImplKind)
684{
685  // Parse the return type if present.
686  TypeTy *ReturnType = 0;
687  ObjCDeclSpec DSRet;
688  if (Tok.is(tok::l_paren))
689    ReturnType = ParseObjCTypeName(DSRet);
690
691  SourceLocation selLoc;
692  IdentifierInfo *SelIdent = ParseObjCSelector(selLoc);
693
694  // An unnamed colon is valid.
695  if (!SelIdent && Tok.isNot(tok::colon)) { // missing selector name.
696    Diag(Tok, diag::err_expected_selector_for_method)
697      << SourceRange(mLoc, Tok.getLocation());
698    // Skip until we get a ; or {}.
699    SkipUntil(tok::r_brace);
700    return 0;
701  }
702
703  llvm::SmallVector<Declarator, 8> CargNames;
704  if (Tok.isNot(tok::colon)) {
705    // If attributes exist after the method, parse them.
706    AttributeList *MethodAttrs = 0;
707    if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
708      MethodAttrs = ParseAttributes();
709
710    Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
711    return Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(),
712                                          mType, IDecl, DSRet, ReturnType, Sel,
713                                          0, 0, 0, CargNames,
714                                          MethodAttrs, MethodImplKind);
715  }
716
717  llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
718  llvm::SmallVector<Action::TypeTy *, 12> KeyTypes;
719  llvm::SmallVector<ObjCDeclSpec, 12> ArgTypeQuals;
720  llvm::SmallVector<IdentifierInfo *, 12> ArgNames;
721
722  Action::TypeTy *TypeInfo;
723  while (1) {
724    KeyIdents.push_back(SelIdent);
725
726    // Each iteration parses a single keyword argument.
727    if (Tok.isNot(tok::colon)) {
728      Diag(Tok, diag::err_expected_colon);
729      break;
730    }
731    ConsumeToken(); // Eat the ':'.
732    ObjCDeclSpec DSType;
733    if (Tok.is(tok::l_paren)) // Parse the argument type.
734      TypeInfo = ParseObjCTypeName(DSType);
735    else
736      TypeInfo = 0;
737    KeyTypes.push_back(TypeInfo);
738    ArgTypeQuals.push_back(DSType);
739
740    // If attributes exist before the argument name, parse them.
741    if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
742      ParseAttributes(); // FIXME: pass attributes through.
743
744    if (Tok.isNot(tok::identifier)) {
745      Diag(Tok, diag::err_expected_ident); // missing argument name.
746      break;
747    }
748    ArgNames.push_back(Tok.getIdentifierInfo());
749    ConsumeToken(); // Eat the identifier.
750
751    // Check for another keyword selector.
752    SourceLocation Loc;
753    SelIdent = ParseObjCSelector(Loc);
754    if (!SelIdent && Tok.isNot(tok::colon))
755      break;
756    // We have a selector or a colon, continue parsing.
757  }
758
759  bool isVariadic = false;
760
761  // Parse the (optional) parameter list.
762  while (Tok.is(tok::comma)) {
763    ConsumeToken();
764    if (Tok.is(tok::ellipsis)) {
765      isVariadic = true;
766      ConsumeToken();
767      break;
768    }
769    DeclSpec DS;
770    ParseDeclarationSpecifiers(DS);
771    // Parse the declarator.
772    Declarator ParmDecl(DS, Declarator::PrototypeContext);
773    ParseDeclarator(ParmDecl);
774    CargNames.push_back(ParmDecl);
775  }
776
777  // FIXME: Add support for optional parmameter list...
778  // If attributes exist after the method, parse them.
779  AttributeList *MethodAttrs = 0;
780  if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
781    MethodAttrs = ParseAttributes();
782
783  Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(),
784                                                   &KeyIdents[0]);
785  return Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(),
786                                        mType, IDecl, DSRet, ReturnType, Sel,
787                                        &ArgTypeQuals[0], &KeyTypes[0],
788                                        &ArgNames[0], CargNames,
789                                        MethodAttrs,
790                                        MethodImplKind, isVariadic);
791}
792
793///   objc-protocol-refs:
794///     '<' identifier-list '>'
795///
796bool Parser::
797ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclTy*> &Protocols,
798                            bool WarnOnDeclarations, SourceLocation &EndLoc) {
799  assert(Tok.is(tok::less) && "expected <");
800
801  ConsumeToken(); // the "<"
802
803  llvm::SmallVector<IdentifierLocPair, 8> ProtocolIdents;
804
805  while (1) {
806    if (Tok.isNot(tok::identifier)) {
807      Diag(Tok, diag::err_expected_ident);
808      SkipUntil(tok::greater);
809      return true;
810    }
811    ProtocolIdents.push_back(std::make_pair(Tok.getIdentifierInfo(),
812                                       Tok.getLocation()));
813    ConsumeToken();
814
815    if (Tok.isNot(tok::comma))
816      break;
817    ConsumeToken();
818  }
819
820  // Consume the '>'.
821  if (Tok.isNot(tok::greater)) {
822    Diag(Tok, diag::err_expected_greater);
823    return true;
824  }
825
826  EndLoc = ConsumeAnyToken();
827
828  // Convert the list of protocols identifiers into a list of protocol decls.
829  Actions.FindProtocolDeclaration(WarnOnDeclarations,
830                                  &ProtocolIdents[0], ProtocolIdents.size(),
831                                  Protocols);
832  return false;
833}
834
835///   objc-class-instance-variables:
836///     '{' objc-instance-variable-decl-list[opt] '}'
837///
838///   objc-instance-variable-decl-list:
839///     objc-visibility-spec
840///     objc-instance-variable-decl ';'
841///     ';'
842///     objc-instance-variable-decl-list objc-visibility-spec
843///     objc-instance-variable-decl-list objc-instance-variable-decl ';'
844///     objc-instance-variable-decl-list ';'
845///
846///   objc-visibility-spec:
847///     @private
848///     @protected
849///     @public
850///     @package [OBJC2]
851///
852///   objc-instance-variable-decl:
853///     struct-declaration
854///
855void Parser::ParseObjCClassInstanceVariables(DeclTy *interfaceDecl,
856                                             SourceLocation atLoc) {
857  assert(Tok.is(tok::l_brace) && "expected {");
858  llvm::SmallVector<DeclTy*, 32> AllIvarDecls;
859  llvm::SmallVector<FieldDeclarator, 8> FieldDeclarators;
860
861  ParseScope ClassScope(this, Scope::DeclScope|Scope::ClassScope);
862
863  SourceLocation LBraceLoc = ConsumeBrace(); // the "{"
864
865  tok::ObjCKeywordKind visibility = tok::objc_protected;
866  // While we still have something to read, read the instance variables.
867  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
868    // Each iteration of this loop reads one objc-instance-variable-decl.
869
870    // Check for extraneous top-level semicolon.
871    if (Tok.is(tok::semi)) {
872      Diag(Tok, diag::ext_extra_struct_semi);
873      ConsumeToken();
874      continue;
875    }
876
877    // Set the default visibility to private.
878    if (Tok.is(tok::at)) { // parse objc-visibility-spec
879      ConsumeToken(); // eat the @ sign
880      switch (Tok.getObjCKeywordID()) {
881      case tok::objc_private:
882      case tok::objc_public:
883      case tok::objc_protected:
884      case tok::objc_package:
885        visibility = Tok.getObjCKeywordID();
886        ConsumeToken();
887        continue;
888      default:
889        Diag(Tok, diag::err_objc_illegal_visibility_spec);
890        continue;
891      }
892    }
893
894    // Parse all the comma separated declarators.
895    DeclSpec DS;
896    FieldDeclarators.clear();
897    ParseStructDeclaration(DS, FieldDeclarators);
898
899    // Convert them all to fields.
900    for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) {
901      FieldDeclarator &FD = FieldDeclarators[i];
902      // Install the declarator into interfaceDecl.
903      DeclTy *Field = Actions.ActOnIvar(CurScope,
904                                         DS.getSourceRange().getBegin(),
905                                         FD.D, FD.BitfieldSize, visibility);
906      AllIvarDecls.push_back(Field);
907    }
908
909    if (Tok.is(tok::semi)) {
910      ConsumeToken();
911    } else {
912      Diag(Tok, diag::err_expected_semi_decl_list);
913      // Skip to end of block or statement
914      SkipUntil(tok::r_brace, true, true);
915    }
916  }
917  SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
918  // Call ActOnFields() even if we don't have any decls. This is useful
919  // for code rewriting tools that need to be aware of the empty list.
920  Actions.ActOnFields(CurScope, atLoc, interfaceDecl,
921                      &AllIvarDecls[0], AllIvarDecls.size(),
922                      LBraceLoc, RBraceLoc, 0);
923  return;
924}
925
926///   objc-protocol-declaration:
927///     objc-protocol-definition
928///     objc-protocol-forward-reference
929///
930///   objc-protocol-definition:
931///     @protocol identifier
932///       objc-protocol-refs[opt]
933///       objc-interface-decl-list
934///     @end
935///
936///   objc-protocol-forward-reference:
937///     @protocol identifier-list ';'
938///
939///   "@protocol identifier ;" should be resolved as "@protocol
940///   identifier-list ;": objc-interface-decl-list may not start with a
941///   semicolon in the first alternative if objc-protocol-refs are omitted.
942Parser::DeclTy *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
943                                               AttributeList *attrList) {
944  assert(Tok.isObjCAtKeyword(tok::objc_protocol) &&
945         "ParseObjCAtProtocolDeclaration(): Expected @protocol");
946  ConsumeToken(); // the "protocol" identifier
947
948  if (Tok.isNot(tok::identifier)) {
949    Diag(Tok, diag::err_expected_ident); // missing protocol name.
950    return 0;
951  }
952  // Save the protocol name, then consume it.
953  IdentifierInfo *protocolName = Tok.getIdentifierInfo();
954  SourceLocation nameLoc = ConsumeToken();
955
956  if (Tok.is(tok::semi)) { // forward declaration of one protocol.
957    IdentifierLocPair ProtoInfo(protocolName, nameLoc);
958    ConsumeToken();
959    return Actions.ActOnForwardProtocolDeclaration(AtLoc, &ProtoInfo, 1,
960                                                   attrList);
961  }
962
963  if (Tok.is(tok::comma)) { // list of forward declarations.
964    llvm::SmallVector<IdentifierLocPair, 8> ProtocolRefs;
965    ProtocolRefs.push_back(std::make_pair(protocolName, nameLoc));
966
967    // Parse the list of forward declarations.
968    while (1) {
969      ConsumeToken(); // the ','
970      if (Tok.isNot(tok::identifier)) {
971        Diag(Tok, diag::err_expected_ident);
972        SkipUntil(tok::semi);
973        return 0;
974      }
975      ProtocolRefs.push_back(IdentifierLocPair(Tok.getIdentifierInfo(),
976                                               Tok.getLocation()));
977      ConsumeToken(); // the identifier
978
979      if (Tok.isNot(tok::comma))
980        break;
981    }
982    // Consume the ';'.
983    if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@protocol"))
984      return 0;
985
986    return Actions.ActOnForwardProtocolDeclaration(AtLoc,
987                                                   &ProtocolRefs[0],
988                                                   ProtocolRefs.size(),
989                                                   attrList);
990  }
991
992  // Last, and definitely not least, parse a protocol declaration.
993  SourceLocation EndProtoLoc;
994
995  llvm::SmallVector<DeclTy *, 8> ProtocolRefs;
996  if (Tok.is(tok::less) &&
997      ParseObjCProtocolReferences(ProtocolRefs, true, EndProtoLoc))
998    return 0;
999
1000  DeclTy *ProtoType =
1001    Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc,
1002                                        &ProtocolRefs[0], ProtocolRefs.size(),
1003                                        EndProtoLoc, attrList);
1004  ParseObjCInterfaceDeclList(ProtoType, tok::objc_protocol);
1005  return ProtoType;
1006}
1007
1008///   objc-implementation:
1009///     objc-class-implementation-prologue
1010///     objc-category-implementation-prologue
1011///
1012///   objc-class-implementation-prologue:
1013///     @implementation identifier objc-superclass[opt]
1014///       objc-class-instance-variables[opt]
1015///
1016///   objc-category-implementation-prologue:
1017///     @implementation identifier ( identifier )
1018
1019Parser::DeclTy *Parser::ParseObjCAtImplementationDeclaration(
1020  SourceLocation atLoc) {
1021  assert(Tok.isObjCAtKeyword(tok::objc_implementation) &&
1022         "ParseObjCAtImplementationDeclaration(): Expected @implementation");
1023  ConsumeToken(); // the "implementation" identifier
1024
1025  if (Tok.isNot(tok::identifier)) {
1026    Diag(Tok, diag::err_expected_ident); // missing class or category name.
1027    return 0;
1028  }
1029  // We have a class or category name - consume it.
1030  IdentifierInfo *nameId = Tok.getIdentifierInfo();
1031  SourceLocation nameLoc = ConsumeToken(); // consume class or category name
1032
1033  if (Tok.is(tok::l_paren)) {
1034    // we have a category implementation.
1035    SourceLocation lparenLoc = ConsumeParen();
1036    SourceLocation categoryLoc, rparenLoc;
1037    IdentifierInfo *categoryId = 0;
1038
1039    if (Tok.is(tok::identifier)) {
1040      categoryId = Tok.getIdentifierInfo();
1041      categoryLoc = ConsumeToken();
1042    } else {
1043      Diag(Tok, diag::err_expected_ident); // missing category name.
1044      return 0;
1045    }
1046    if (Tok.isNot(tok::r_paren)) {
1047      Diag(Tok, diag::err_expected_rparen);
1048      SkipUntil(tok::r_paren, false); // don't stop at ';'
1049      return 0;
1050    }
1051    rparenLoc = ConsumeParen();
1052    DeclTy *ImplCatType = Actions.ActOnStartCategoryImplementation(
1053                                    atLoc, nameId, nameLoc, categoryId,
1054                                    categoryLoc);
1055    ObjCImpDecl = ImplCatType;
1056    return 0;
1057  }
1058  // We have a class implementation
1059  SourceLocation superClassLoc;
1060  IdentifierInfo *superClassId = 0;
1061  if (Tok.is(tok::colon)) {
1062    // We have a super class
1063    ConsumeToken();
1064    if (Tok.isNot(tok::identifier)) {
1065      Diag(Tok, diag::err_expected_ident); // missing super class name.
1066      return 0;
1067    }
1068    superClassId = Tok.getIdentifierInfo();
1069    superClassLoc = ConsumeToken(); // Consume super class name
1070  }
1071  DeclTy *ImplClsType = Actions.ActOnStartClassImplementation(
1072                                  atLoc, nameId, nameLoc,
1073                                  superClassId, superClassLoc);
1074
1075  if (Tok.is(tok::l_brace)) // we have ivars
1076    ParseObjCClassInstanceVariables(ImplClsType/*FIXME*/, atLoc);
1077  ObjCImpDecl = ImplClsType;
1078
1079  return 0;
1080}
1081
1082Parser::DeclTy *Parser::ParseObjCAtEndDeclaration(SourceLocation atLoc) {
1083  assert(Tok.isObjCAtKeyword(tok::objc_end) &&
1084         "ParseObjCAtEndDeclaration(): Expected @end");
1085  ConsumeToken(); // the "end" identifier
1086  if (ObjCImpDecl)
1087    Actions.ActOnAtEnd(atLoc, ObjCImpDecl);
1088  else
1089    Diag(atLoc, diag::warn_expected_implementation); // missing @implementation
1090  return ObjCImpDecl;
1091}
1092
1093///   compatibility-alias-decl:
1094///     @compatibility_alias alias-name  class-name ';'
1095///
1096Parser::DeclTy *Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) {
1097  assert(Tok.isObjCAtKeyword(tok::objc_compatibility_alias) &&
1098         "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias");
1099  ConsumeToken(); // consume compatibility_alias
1100  if (Tok.isNot(tok::identifier)) {
1101    Diag(Tok, diag::err_expected_ident);
1102    return 0;
1103  }
1104  IdentifierInfo *aliasId = Tok.getIdentifierInfo();
1105  SourceLocation aliasLoc = ConsumeToken(); // consume alias-name
1106  if (Tok.isNot(tok::identifier)) {
1107    Diag(Tok, diag::err_expected_ident);
1108    return 0;
1109  }
1110  IdentifierInfo *classId = Tok.getIdentifierInfo();
1111  SourceLocation classLoc = ConsumeToken(); // consume class-name;
1112  if (Tok.isNot(tok::semi)) {
1113    Diag(Tok, diag::err_expected_semi_after) << "@compatibility_alias";
1114    return 0;
1115  }
1116  DeclTy *ClsType = Actions.ActOnCompatiblityAlias(atLoc,
1117                                                   aliasId, aliasLoc,
1118                                                   classId, classLoc);
1119  return ClsType;
1120}
1121
1122///   property-synthesis:
1123///     @synthesize property-ivar-list ';'
1124///
1125///   property-ivar-list:
1126///     property-ivar
1127///     property-ivar-list ',' property-ivar
1128///
1129///   property-ivar:
1130///     identifier
1131///     identifier '=' identifier
1132///
1133Parser::DeclTy *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
1134  assert(Tok.isObjCAtKeyword(tok::objc_synthesize) &&
1135         "ParseObjCPropertyDynamic(): Expected '@synthesize'");
1136  SourceLocation loc = ConsumeToken(); // consume synthesize
1137  if (Tok.isNot(tok::identifier)) {
1138    Diag(Tok, diag::err_expected_ident);
1139    return 0;
1140  }
1141  while (Tok.is(tok::identifier)) {
1142    IdentifierInfo *propertyIvar = 0;
1143    IdentifierInfo *propertyId = Tok.getIdentifierInfo();
1144    SourceLocation propertyLoc = ConsumeToken(); // consume property name
1145    if (Tok.is(tok::equal)) {
1146      // property '=' ivar-name
1147      ConsumeToken(); // consume '='
1148      if (Tok.isNot(tok::identifier)) {
1149        Diag(Tok, diag::err_expected_ident);
1150        break;
1151      }
1152      propertyIvar = Tok.getIdentifierInfo();
1153      ConsumeToken(); // consume ivar-name
1154    }
1155    Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, true, ObjCImpDecl,
1156                                  propertyId, propertyIvar);
1157    if (Tok.isNot(tok::comma))
1158      break;
1159    ConsumeToken(); // consume ','
1160  }
1161  if (Tok.isNot(tok::semi))
1162    Diag(Tok, diag::err_expected_semi_after) << "@synthesize";
1163  return 0;
1164}
1165
1166///   property-dynamic:
1167///     @dynamic  property-list
1168///
1169///   property-list:
1170///     identifier
1171///     property-list ',' identifier
1172///
1173Parser::DeclTy *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
1174  assert(Tok.isObjCAtKeyword(tok::objc_dynamic) &&
1175         "ParseObjCPropertyDynamic(): Expected '@dynamic'");
1176  SourceLocation loc = ConsumeToken(); // consume dynamic
1177  if (Tok.isNot(tok::identifier)) {
1178    Diag(Tok, diag::err_expected_ident);
1179    return 0;
1180  }
1181  while (Tok.is(tok::identifier)) {
1182    IdentifierInfo *propertyId = Tok.getIdentifierInfo();
1183    SourceLocation propertyLoc = ConsumeToken(); // consume property name
1184    Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, false, ObjCImpDecl,
1185                                  propertyId, 0);
1186
1187    if (Tok.isNot(tok::comma))
1188      break;
1189    ConsumeToken(); // consume ','
1190  }
1191  if (Tok.isNot(tok::semi))
1192    Diag(Tok, diag::err_expected_semi_after) << "@dynamic";
1193  return 0;
1194}
1195
1196///  objc-throw-statement:
1197///    throw expression[opt];
1198///
1199Parser::OwningStmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) {
1200  OwningExprResult Res(Actions);
1201  ConsumeToken(); // consume throw
1202  if (Tok.isNot(tok::semi)) {
1203    Res = ParseExpression();
1204    if (Res.isInvalid()) {
1205      SkipUntil(tok::semi);
1206      return StmtError();
1207    }
1208  }
1209  ConsumeToken(); // consume ';'
1210  return Actions.ActOnObjCAtThrowStmt(atLoc, move(Res), CurScope);
1211}
1212
1213/// objc-synchronized-statement:
1214///   @synchronized '(' expression ')' compound-statement
1215///
1216Parser::OwningStmtResult
1217Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
1218  ConsumeToken(); // consume synchronized
1219  if (Tok.isNot(tok::l_paren)) {
1220    Diag(Tok, diag::err_expected_lparen_after) << "@synchronized";
1221    return StmtError();
1222  }
1223  ConsumeParen();  // '('
1224  OwningExprResult Res(ParseExpression());
1225  if (Res.isInvalid()) {
1226    SkipUntil(tok::semi);
1227    return StmtError();
1228  }
1229  if (Tok.isNot(tok::r_paren)) {
1230    Diag(Tok, diag::err_expected_lbrace);
1231    return StmtError();
1232  }
1233  ConsumeParen();  // ')'
1234  if (Tok.isNot(tok::l_brace)) {
1235    Diag(Tok, diag::err_expected_lbrace);
1236    return StmtError();
1237  }
1238  // Enter a scope to hold everything within the compound stmt.  Compound
1239  // statements can always hold declarations.
1240  ParseScope BodyScope(this, Scope::DeclScope);
1241
1242  OwningStmtResult SynchBody(ParseCompoundStatementBody());
1243
1244  BodyScope.Exit();
1245  if (SynchBody.isInvalid())
1246    SynchBody = Actions.ActOnNullStmt(Tok.getLocation());
1247  return Actions.ActOnObjCAtSynchronizedStmt(atLoc, move(Res), move(SynchBody));
1248}
1249
1250///  objc-try-catch-statement:
1251///    @try compound-statement objc-catch-list[opt]
1252///    @try compound-statement objc-catch-list[opt] @finally compound-statement
1253///
1254///  objc-catch-list:
1255///    @catch ( parameter-declaration ) compound-statement
1256///    objc-catch-list @catch ( catch-parameter-declaration ) compound-statement
1257///  catch-parameter-declaration:
1258///     parameter-declaration
1259///     '...' [OBJC2]
1260///
1261Parser::OwningStmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
1262  bool catch_or_finally_seen = false;
1263
1264  ConsumeToken(); // consume try
1265  if (Tok.isNot(tok::l_brace)) {
1266    Diag(Tok, diag::err_expected_lbrace);
1267    return StmtError();
1268  }
1269  OwningStmtResult CatchStmts(Actions);
1270  OwningStmtResult FinallyStmt(Actions);
1271  ParseScope TryScope(this, Scope::DeclScope);
1272  OwningStmtResult TryBody(ParseCompoundStatementBody());
1273  TryScope.Exit();
1274  if (TryBody.isInvalid())
1275    TryBody = Actions.ActOnNullStmt(Tok.getLocation());
1276
1277  while (Tok.is(tok::at)) {
1278    // At this point, we need to lookahead to determine if this @ is the start
1279    // of an @catch or @finally.  We don't want to consume the @ token if this
1280    // is an @try or @encode or something else.
1281    Token AfterAt = GetLookAheadToken(1);
1282    if (!AfterAt.isObjCAtKeyword(tok::objc_catch) &&
1283        !AfterAt.isObjCAtKeyword(tok::objc_finally))
1284      break;
1285
1286    SourceLocation AtCatchFinallyLoc = ConsumeToken();
1287    if (Tok.isObjCAtKeyword(tok::objc_catch)) {
1288      OwningStmtResult FirstPart(Actions);
1289      ConsumeToken(); // consume catch
1290      if (Tok.is(tok::l_paren)) {
1291        ConsumeParen();
1292        ParseScope CatchScope(this, Scope::DeclScope|Scope::AtCatchScope);
1293        if (Tok.isNot(tok::ellipsis)) {
1294          DeclSpec DS;
1295          ParseDeclarationSpecifiers(DS);
1296          // For some odd reason, the name of the exception variable is
1297          // optional. As a result, we need to use PrototypeContext.
1298          Declarator DeclaratorInfo(DS, Declarator::PrototypeContext);
1299          ParseDeclarator(DeclaratorInfo);
1300          if (DeclaratorInfo.getIdentifier()) {
1301            DeclTy *aBlockVarDecl = Actions.ActOnDeclarator(CurScope,
1302                                                          DeclaratorInfo, 0);
1303            FirstPart =
1304              Actions.ActOnDeclStmt(aBlockVarDecl,
1305                                    DS.getSourceRange().getBegin(),
1306                                    DeclaratorInfo.getSourceRange().getEnd());
1307          }
1308        } else
1309          ConsumeToken(); // consume '...'
1310        SourceLocation RParenLoc = ConsumeParen();
1311
1312        OwningStmtResult CatchBody(Actions, true);
1313        if (Tok.is(tok::l_brace))
1314          CatchBody = ParseCompoundStatementBody();
1315        else
1316          Diag(Tok, diag::err_expected_lbrace);
1317        if (CatchBody.isInvalid())
1318          CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
1319        CatchStmts = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc,
1320                        RParenLoc, move(FirstPart), move(CatchBody),
1321                        move(CatchStmts));
1322      } else {
1323        Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
1324          << "@catch clause";
1325        return StmtError();
1326      }
1327      catch_or_finally_seen = true;
1328    } else {
1329      assert(Tok.isObjCAtKeyword(tok::objc_finally) && "Lookahead confused?");
1330      ConsumeToken(); // consume finally
1331      ParseScope FinallyScope(this, Scope::DeclScope);
1332
1333      OwningStmtResult FinallyBody(Actions, true);
1334      if (Tok.is(tok::l_brace))
1335        FinallyBody = ParseCompoundStatementBody();
1336      else
1337        Diag(Tok, diag::err_expected_lbrace);
1338      if (FinallyBody.isInvalid())
1339        FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
1340      FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
1341                                                   move(FinallyBody));
1342      catch_or_finally_seen = true;
1343      break;
1344    }
1345  }
1346  if (!catch_or_finally_seen) {
1347    Diag(atLoc, diag::err_missing_catch_finally);
1348    return StmtError();
1349  }
1350  return Actions.ActOnObjCAtTryStmt(atLoc, move(TryBody), move(CatchStmts),
1351                                    move(FinallyStmt));
1352}
1353
1354///   objc-method-def: objc-method-proto ';'[opt] '{' body '}'
1355///
1356Parser::DeclTy *Parser::ParseObjCMethodDefinition() {
1357  DeclTy *MDecl = ParseObjCMethodPrototype(ObjCImpDecl);
1358  // parse optional ';'
1359  if (Tok.is(tok::semi))
1360    ConsumeToken();
1361
1362  // We should have an opening brace now.
1363  if (Tok.isNot(tok::l_brace)) {
1364    Diag(Tok, diag::err_expected_method_body);
1365
1366    // Skip over garbage, until we get to '{'.  Don't eat the '{'.
1367    SkipUntil(tok::l_brace, true, true);
1368
1369    // If we didn't find the '{', bail out.
1370    if (Tok.isNot(tok::l_brace))
1371      return 0;
1372  }
1373  SourceLocation BraceLoc = Tok.getLocation();
1374
1375  // Enter a scope for the method body.
1376  ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope);
1377
1378  // Tell the actions module that we have entered a method definition with the
1379  // specified Declarator for the method.
1380  Actions.ActOnStartOfObjCMethodDef(CurScope, MDecl);
1381
1382  OwningStmtResult FnBody(ParseCompoundStatementBody());
1383
1384  // If the function body could not be parsed, make a bogus compoundstmt.
1385  if (FnBody.isInvalid())
1386    FnBody = Actions.ActOnCompoundStmt(BraceLoc, BraceLoc,
1387                                       MultiStmtArg(Actions), false);
1388
1389  // Leave the function body scope.
1390  BodyScope.Exit();
1391
1392  // TODO: Pass argument information.
1393  Actions.ActOnFinishFunctionBody(MDecl, move(FnBody));
1394  return MDecl;
1395}
1396
1397Parser::OwningStmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) {
1398  if (Tok.isObjCAtKeyword(tok::objc_try)) {
1399    return ParseObjCTryStmt(AtLoc);
1400  } else if (Tok.isObjCAtKeyword(tok::objc_throw))
1401    return ParseObjCThrowStmt(AtLoc);
1402  else if (Tok.isObjCAtKeyword(tok::objc_synchronized))
1403    return ParseObjCSynchronizedStmt(AtLoc);
1404  OwningExprResult Res(ParseExpressionWithLeadingAt(AtLoc));
1405  if (Res.isInvalid()) {
1406    // If the expression is invalid, skip ahead to the next semicolon. Not
1407    // doing this opens us up to the possibility of infinite loops if
1408    // ParseExpression does not consume any tokens.
1409    SkipUntil(tok::semi);
1410    return StmtError();
1411  }
1412  // Otherwise, eat the semicolon.
1413  ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
1414  return Actions.ActOnExprStmt(move(Res));
1415}
1416
1417Parser::OwningExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
1418  switch (Tok.getKind()) {
1419  case tok::string_literal:    // primary-expression: string-literal
1420  case tok::wide_string_literal:
1421    return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
1422  default:
1423    if (Tok.getIdentifierInfo() == 0)
1424      return ExprError(Diag(AtLoc, diag::err_unexpected_at));
1425
1426    switch (Tok.getIdentifierInfo()->getObjCKeywordID()) {
1427    case tok::objc_encode:
1428      return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc));
1429    case tok::objc_protocol:
1430      return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc));
1431    case tok::objc_selector:
1432      return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc));
1433    default:
1434      return ExprError(Diag(AtLoc, diag::err_unexpected_at));
1435    }
1436  }
1437}
1438
1439///   objc-message-expr:
1440///     '[' objc-receiver objc-message-args ']'
1441///
1442///   objc-receiver:
1443///     expression
1444///     class-name
1445///     type-name
1446Parser::OwningExprResult Parser::ParseObjCMessageExpression() {
1447  assert(Tok.is(tok::l_square) && "'[' expected");
1448  SourceLocation LBracLoc = ConsumeBracket(); // consume '['
1449
1450  // Parse receiver
1451  if (isTokObjCMessageIdentifierReceiver()) {
1452    IdentifierInfo *ReceiverName = Tok.getIdentifierInfo();
1453    SourceLocation NameLoc = ConsumeToken();
1454    return ParseObjCMessageExpressionBody(LBracLoc, NameLoc, ReceiverName,
1455                                          ExprArg(Actions));
1456  }
1457
1458  OwningExprResult Res(ParseExpression());
1459  if (Res.isInvalid()) {
1460    SkipUntil(tok::r_square);
1461    return move(Res);
1462  }
1463
1464  return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
1465                                        0, move(Res));
1466}
1467
1468/// ParseObjCMessageExpressionBody - Having parsed "'[' objc-receiver", parse
1469/// the rest of a message expression.
1470///
1471///   objc-message-args:
1472///     objc-selector
1473///     objc-keywordarg-list
1474///
1475///   objc-keywordarg-list:
1476///     objc-keywordarg
1477///     objc-keywordarg-list objc-keywordarg
1478///
1479///   objc-keywordarg:
1480///     selector-name[opt] ':' objc-keywordexpr
1481///
1482///   objc-keywordexpr:
1483///     nonempty-expr-list
1484///
1485///   nonempty-expr-list:
1486///     assignment-expression
1487///     nonempty-expr-list , assignment-expression
1488///
1489Parser::OwningExprResult
1490Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
1491                                       SourceLocation NameLoc,
1492                                       IdentifierInfo *ReceiverName,
1493                                       ExprArg ReceiverExpr) {
1494  // Parse objc-selector
1495  SourceLocation Loc;
1496  IdentifierInfo *selIdent = ParseObjCSelector(Loc);
1497
1498  SourceLocation SelectorLoc = Loc;
1499
1500  llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
1501  ExprVector KeyExprs(Actions);
1502
1503  if (Tok.is(tok::colon)) {
1504    while (1) {
1505      // Each iteration parses a single keyword argument.
1506      KeyIdents.push_back(selIdent);
1507
1508      if (Tok.isNot(tok::colon)) {
1509        Diag(Tok, diag::err_expected_colon);
1510        // We must manually skip to a ']', otherwise the expression skipper will
1511        // stop at the ']' when it skips to the ';'.  We want it to skip beyond
1512        // the enclosing expression.
1513        SkipUntil(tok::r_square);
1514        return ExprError();
1515      }
1516
1517      ConsumeToken(); // Eat the ':'.
1518      ///  Parse the expression after ':'
1519      OwningExprResult Res(ParseAssignmentExpression());
1520      if (Res.isInvalid()) {
1521        // We must manually skip to a ']', otherwise the expression skipper will
1522        // stop at the ']' when it skips to the ';'.  We want it to skip beyond
1523        // the enclosing expression.
1524        SkipUntil(tok::r_square);
1525        return move(Res);
1526      }
1527
1528      // We have a valid expression.
1529      KeyExprs.push_back(Res.release());
1530
1531      // Check for another keyword selector.
1532      selIdent = ParseObjCSelector(Loc);
1533      if (!selIdent && Tok.isNot(tok::colon))
1534        break;
1535      // We have a selector or a colon, continue parsing.
1536    }
1537    // Parse the, optional, argument list, comma separated.
1538    while (Tok.is(tok::comma)) {
1539      ConsumeToken(); // Eat the ','.
1540      ///  Parse the expression after ','
1541      OwningExprResult Res(ParseAssignmentExpression());
1542      if (Res.isInvalid()) {
1543        // We must manually skip to a ']', otherwise the expression skipper will
1544        // stop at the ']' when it skips to the ';'.  We want it to skip beyond
1545        // the enclosing expression.
1546        SkipUntil(tok::r_square);
1547        return move(Res);
1548      }
1549
1550      // We have a valid expression.
1551      KeyExprs.push_back(Res.release());
1552    }
1553  } else if (!selIdent) {
1554    Diag(Tok, diag::err_expected_ident); // missing selector name.
1555
1556    // We must manually skip to a ']', otherwise the expression skipper will
1557    // stop at the ']' when it skips to the ';'.  We want it to skip beyond
1558    // the enclosing expression.
1559    SkipUntil(tok::r_square);
1560    return ExprError();
1561  }
1562
1563  if (Tok.isNot(tok::r_square)) {
1564    Diag(Tok, diag::err_expected_rsquare);
1565    // We must manually skip to a ']', otherwise the expression skipper will
1566    // stop at the ']' when it skips to the ';'.  We want it to skip beyond
1567    // the enclosing expression.
1568    SkipUntil(tok::r_square);
1569    return ExprError();
1570  }
1571
1572  SourceLocation RBracLoc = ConsumeBracket(); // consume ']'
1573
1574  unsigned nKeys = KeyIdents.size();
1575  if (nKeys == 0)
1576    KeyIdents.push_back(selIdent);
1577  Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]);
1578
1579  // We've just parsed a keyword message.
1580  if (ReceiverName)
1581    return Owned(Actions.ActOnClassMessage(CurScope, ReceiverName, Sel,
1582                                           LBracLoc, NameLoc, SelectorLoc,
1583                                           RBracLoc,
1584                                           KeyExprs.take(), KeyExprs.size()));
1585  return Owned(Actions.ActOnInstanceMessage(ReceiverExpr.release(), Sel,
1586                                            LBracLoc, SelectorLoc, RBracLoc,
1587                                            KeyExprs.take(), KeyExprs.size()));
1588}
1589
1590Parser::OwningExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
1591  OwningExprResult Res(ParseStringLiteralExpression());
1592  if (Res.isInvalid()) return move(Res);
1593
1594  // @"foo" @"bar" is a valid concatenated string.  Eat any subsequent string
1595  // expressions.  At this point, we know that the only valid thing that starts
1596  // with '@' is an @"".
1597  llvm::SmallVector<SourceLocation, 4> AtLocs;
1598  ExprVector AtStrings(Actions);
1599  AtLocs.push_back(AtLoc);
1600  AtStrings.push_back(Res.release());
1601
1602  while (Tok.is(tok::at)) {
1603    AtLocs.push_back(ConsumeToken()); // eat the @.
1604
1605    // Invalid unless there is a string literal.
1606    if (!isTokenStringLiteral())
1607      return ExprError(Diag(Tok, diag::err_objc_concat_string));
1608
1609    OwningExprResult Lit(ParseStringLiteralExpression());
1610    if (Lit.isInvalid())
1611      return move(Lit);
1612
1613    AtStrings.push_back(Lit.release());
1614  }
1615
1616  return Owned(Actions.ParseObjCStringLiteral(&AtLocs[0], AtStrings.take(),
1617                                              AtStrings.size()));
1618}
1619
1620///    objc-encode-expression:
1621///      @encode ( type-name )
1622Parser::OwningExprResult
1623Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) {
1624  assert(Tok.isObjCAtKeyword(tok::objc_encode) && "Not an @encode expression!");
1625
1626  SourceLocation EncLoc = ConsumeToken();
1627
1628  if (Tok.isNot(tok::l_paren))
1629    return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@encode");
1630
1631  SourceLocation LParenLoc = ConsumeParen();
1632
1633  TypeResult Ty = ParseTypeName();
1634
1635  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
1636
1637  if (Ty.isInvalid())
1638    return ExprError();
1639
1640  return Owned(Actions.ParseObjCEncodeExpression(AtLoc, EncLoc, LParenLoc,
1641                                                 Ty.get(), RParenLoc));
1642}
1643
1644///     objc-protocol-expression
1645///       @protocol ( protocol-name )
1646Parser::OwningExprResult
1647Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) {
1648  SourceLocation ProtoLoc = ConsumeToken();
1649
1650  if (Tok.isNot(tok::l_paren))
1651    return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@protocol");
1652
1653  SourceLocation LParenLoc = ConsumeParen();
1654
1655  if (Tok.isNot(tok::identifier))
1656    return ExprError(Diag(Tok, diag::err_expected_ident));
1657
1658  IdentifierInfo *protocolId = Tok.getIdentifierInfo();
1659  ConsumeToken();
1660
1661  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
1662
1663  return Owned(Actions.ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc,
1664                                                   LParenLoc, RParenLoc));
1665}
1666
1667///     objc-selector-expression
1668///       @selector '(' objc-keyword-selector ')'
1669Parser::OwningExprResult
1670Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) {
1671  SourceLocation SelectorLoc = ConsumeToken();
1672
1673  if (Tok.isNot(tok::l_paren))
1674    return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@selector");
1675
1676  llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
1677  SourceLocation LParenLoc = ConsumeParen();
1678  SourceLocation sLoc;
1679  IdentifierInfo *SelIdent = ParseObjCSelector(sLoc);
1680  if (!SelIdent && Tok.isNot(tok::colon)) // missing selector name.
1681    return ExprError(Diag(Tok, diag::err_expected_ident));
1682
1683  KeyIdents.push_back(SelIdent);
1684  unsigned nColons = 0;
1685  if (Tok.isNot(tok::r_paren)) {
1686    while (1) {
1687      if (Tok.isNot(tok::colon))
1688        return ExprError(Diag(Tok, diag::err_expected_colon));
1689
1690      nColons++;
1691      ConsumeToken(); // Eat the ':'.
1692      if (Tok.is(tok::r_paren))
1693        break;
1694      // Check for another keyword selector.
1695      SourceLocation Loc;
1696      SelIdent = ParseObjCSelector(Loc);
1697      KeyIdents.push_back(SelIdent);
1698      if (!SelIdent && Tok.isNot(tok::colon))
1699        break;
1700    }
1701  }
1702  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
1703  Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]);
1704  return Owned(Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc,
1705                                                   LParenLoc, RParenLoc));
1706 }
1707