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