xref: /llvm-project/clang/lib/Parse/ParseObjc.cpp (revision eae650366d0bf8b14446cabb5fa0a515e22f753e)
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   // 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 ///
220 void 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 ///
405 void 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 ///
486 Parser::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 ///
507 IdentifierInfo *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 ///
588 bool 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 ///
604 void 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 ///
639 Parser::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 ///
697 Parser::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 ///
820 bool Parser::
821 ParseObjCProtocolReferences(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 ///
882 void 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.
980 Parser::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 )
1059 Parser::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 
1122 Parser::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 ///
1139 Parser::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 ///
1174 Parser::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 ///
1217 Parser::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 ///
1243 Parser::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 ///
1260 Parser::OwningStmtResult
1261 Parser::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 ///
1305 Parser::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 ///
1403 Parser::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 
1453 Parser::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 
1473 Parser::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
1502 Parser::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 ///
1547 Parser::OwningExprResult
1548 Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
1549                                        SourceLocation NameLoc,
1550                                        IdentifierInfo *ReceiverName,
1551                                        ExprArg ReceiverExpr) {
1552   if (Tok.is(tok::code_completion)) {
1553     if (ReceiverName)
1554       Actions.CodeCompleteObjCFactoryMethod(CurScope, ReceiverName);
1555     else
1556       Actions.CodeCompleteObjCInstanceMethod(CurScope, ReceiverExpr.release());
1557     ConsumeToken();
1558   }
1559   // Parse objc-selector
1560   SourceLocation Loc;
1561   IdentifierInfo *selIdent = ParseObjCSelectorPiece(Loc);
1562 
1563   SourceLocation SelectorLoc = Loc;
1564 
1565   llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
1566   ExprVector KeyExprs(Actions);
1567 
1568   if (Tok.is(tok::colon)) {
1569     while (1) {
1570       // Each iteration parses a single keyword argument.
1571       KeyIdents.push_back(selIdent);
1572 
1573       if (Tok.isNot(tok::colon)) {
1574         Diag(Tok, diag::err_expected_colon);
1575         // We must manually skip to a ']', otherwise the expression skipper will
1576         // stop at the ']' when it skips to the ';'.  We want it to skip beyond
1577         // the enclosing expression.
1578         SkipUntil(tok::r_square);
1579         return ExprError();
1580       }
1581 
1582       ConsumeToken(); // Eat the ':'.
1583       ///  Parse the expression after ':'
1584       OwningExprResult Res(ParseAssignmentExpression());
1585       if (Res.isInvalid()) {
1586         // We must manually skip to a ']', otherwise the expression skipper will
1587         // stop at the ']' when it skips to the ';'.  We want it to skip beyond
1588         // the enclosing expression.
1589         SkipUntil(tok::r_square);
1590         return move(Res);
1591       }
1592 
1593       // We have a valid expression.
1594       KeyExprs.push_back(Res.release());
1595 
1596       // Check for another keyword selector.
1597       selIdent = ParseObjCSelectorPiece(Loc);
1598       if (!selIdent && Tok.isNot(tok::colon))
1599         break;
1600       // We have a selector or a colon, continue parsing.
1601     }
1602     // Parse the, optional, argument list, comma separated.
1603     while (Tok.is(tok::comma)) {
1604       ConsumeToken(); // Eat the ','.
1605       ///  Parse the expression after ','
1606       OwningExprResult Res(ParseAssignmentExpression());
1607       if (Res.isInvalid()) {
1608         // We must manually skip to a ']', otherwise the expression skipper will
1609         // stop at the ']' when it skips to the ';'.  We want it to skip beyond
1610         // the enclosing expression.
1611         SkipUntil(tok::r_square);
1612         return move(Res);
1613       }
1614 
1615       // We have a valid expression.
1616       KeyExprs.push_back(Res.release());
1617     }
1618   } else if (!selIdent) {
1619     Diag(Tok, diag::err_expected_ident); // missing selector name.
1620 
1621     // We must manually skip to a ']', otherwise the expression skipper will
1622     // stop at the ']' when it skips to the ';'.  We want it to skip beyond
1623     // the enclosing expression.
1624     SkipUntil(tok::r_square);
1625     return ExprError();
1626   }
1627 
1628   if (Tok.isNot(tok::r_square)) {
1629     Diag(Tok, diag::err_expected_rsquare);
1630     // We must manually skip to a ']', otherwise the expression skipper will
1631     // stop at the ']' when it skips to the ';'.  We want it to skip beyond
1632     // the enclosing expression.
1633     SkipUntil(tok::r_square);
1634     return ExprError();
1635   }
1636 
1637   SourceLocation RBracLoc = ConsumeBracket(); // consume ']'
1638 
1639   unsigned nKeys = KeyIdents.size();
1640   if (nKeys == 0)
1641     KeyIdents.push_back(selIdent);
1642   Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]);
1643 
1644   // We've just parsed a keyword message.
1645   if (ReceiverName)
1646     return Owned(Actions.ActOnClassMessage(CurScope, ReceiverName, Sel,
1647                                            LBracLoc, NameLoc, SelectorLoc,
1648                                            RBracLoc,
1649                                            KeyExprs.take(), KeyExprs.size()));
1650   return Owned(Actions.ActOnInstanceMessage(ReceiverExpr.release(), Sel,
1651                                             LBracLoc, SelectorLoc, RBracLoc,
1652                                             KeyExprs.take(), KeyExprs.size()));
1653 }
1654 
1655 Parser::OwningExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
1656   OwningExprResult Res(ParseStringLiteralExpression());
1657   if (Res.isInvalid()) return move(Res);
1658 
1659   // @"foo" @"bar" is a valid concatenated string.  Eat any subsequent string
1660   // expressions.  At this point, we know that the only valid thing that starts
1661   // with '@' is an @"".
1662   llvm::SmallVector<SourceLocation, 4> AtLocs;
1663   ExprVector AtStrings(Actions);
1664   AtLocs.push_back(AtLoc);
1665   AtStrings.push_back(Res.release());
1666 
1667   while (Tok.is(tok::at)) {
1668     AtLocs.push_back(ConsumeToken()); // eat the @.
1669 
1670     // Invalid unless there is a string literal.
1671     if (!isTokenStringLiteral())
1672       return ExprError(Diag(Tok, diag::err_objc_concat_string));
1673 
1674     OwningExprResult Lit(ParseStringLiteralExpression());
1675     if (Lit.isInvalid())
1676       return move(Lit);
1677 
1678     AtStrings.push_back(Lit.release());
1679   }
1680 
1681   return Owned(Actions.ParseObjCStringLiteral(&AtLocs[0], AtStrings.take(),
1682                                               AtStrings.size()));
1683 }
1684 
1685 ///    objc-encode-expression:
1686 ///      @encode ( type-name )
1687 Parser::OwningExprResult
1688 Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) {
1689   assert(Tok.isObjCAtKeyword(tok::objc_encode) && "Not an @encode expression!");
1690 
1691   SourceLocation EncLoc = ConsumeToken();
1692 
1693   if (Tok.isNot(tok::l_paren))
1694     return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@encode");
1695 
1696   SourceLocation LParenLoc = ConsumeParen();
1697 
1698   TypeResult Ty = ParseTypeName();
1699 
1700   SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
1701 
1702   if (Ty.isInvalid())
1703     return ExprError();
1704 
1705   return Owned(Actions.ParseObjCEncodeExpression(AtLoc, EncLoc, LParenLoc,
1706                                                  Ty.get(), RParenLoc));
1707 }
1708 
1709 ///     objc-protocol-expression
1710 ///       @protocol ( protocol-name )
1711 Parser::OwningExprResult
1712 Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) {
1713   SourceLocation ProtoLoc = ConsumeToken();
1714 
1715   if (Tok.isNot(tok::l_paren))
1716     return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@protocol");
1717 
1718   SourceLocation LParenLoc = ConsumeParen();
1719 
1720   if (Tok.isNot(tok::identifier))
1721     return ExprError(Diag(Tok, diag::err_expected_ident));
1722 
1723   IdentifierInfo *protocolId = Tok.getIdentifierInfo();
1724   ConsumeToken();
1725 
1726   SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
1727 
1728   return Owned(Actions.ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc,
1729                                                    LParenLoc, RParenLoc));
1730 }
1731 
1732 ///     objc-selector-expression
1733 ///       @selector '(' objc-keyword-selector ')'
1734 Parser::OwningExprResult
1735 Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) {
1736   SourceLocation SelectorLoc = ConsumeToken();
1737 
1738   if (Tok.isNot(tok::l_paren))
1739     return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@selector");
1740 
1741   llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
1742   SourceLocation LParenLoc = ConsumeParen();
1743   SourceLocation sLoc;
1744   IdentifierInfo *SelIdent = ParseObjCSelectorPiece(sLoc);
1745   if (!SelIdent && Tok.isNot(tok::colon)) // missing selector name.
1746     return ExprError(Diag(Tok, diag::err_expected_ident));
1747 
1748   KeyIdents.push_back(SelIdent);
1749   unsigned nColons = 0;
1750   if (Tok.isNot(tok::r_paren)) {
1751     while (1) {
1752       if (Tok.isNot(tok::colon))
1753         return ExprError(Diag(Tok, diag::err_expected_colon));
1754 
1755       nColons++;
1756       ConsumeToken(); // Eat the ':'.
1757       if (Tok.is(tok::r_paren))
1758         break;
1759       // Check for another keyword selector.
1760       SourceLocation Loc;
1761       SelIdent = ParseObjCSelectorPiece(Loc);
1762       KeyIdents.push_back(SelIdent);
1763       if (!SelIdent && Tok.isNot(tok::colon))
1764         break;
1765     }
1766   }
1767   SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
1768   Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]);
1769   return Owned(Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc,
1770                                                    LParenLoc, RParenLoc));
1771  }
1772