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