xref: /llvm-project/clang/lib/Parse/ParseObjc.cpp (revision 3e4fac74084eabb7545bc8064aa3ef9eb4ba1fcf)
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   return DeclPtrTy();
1206 }
1207 
1208 ///   property-dynamic:
1209 ///     @dynamic  property-list
1210 ///
1211 ///   property-list:
1212 ///     identifier
1213 ///     property-list ',' identifier
1214 ///
1215 Parser::DeclPtrTy Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
1216   assert(Tok.isObjCAtKeyword(tok::objc_dynamic) &&
1217          "ParseObjCPropertyDynamic(): Expected '@dynamic'");
1218   SourceLocation loc = ConsumeToken(); // consume dynamic
1219   if (Tok.isNot(tok::identifier)) {
1220     Diag(Tok, diag::err_expected_ident);
1221     return DeclPtrTy();
1222   }
1223   while (Tok.is(tok::identifier)) {
1224     IdentifierInfo *propertyId = Tok.getIdentifierInfo();
1225     SourceLocation propertyLoc = ConsumeToken(); // consume property name
1226     Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, false, ObjCImpDecl,
1227                                   propertyId, 0);
1228 
1229     if (Tok.isNot(tok::comma))
1230       break;
1231     ConsumeToken(); // consume ','
1232   }
1233   if (Tok.isNot(tok::semi))
1234     Diag(Tok, diag::err_expected_semi_after) << "@dynamic";
1235   return DeclPtrTy();
1236 }
1237 
1238 ///  objc-throw-statement:
1239 ///    throw expression[opt];
1240 ///
1241 Parser::OwningStmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) {
1242   OwningExprResult Res(Actions);
1243   ConsumeToken(); // consume throw
1244   if (Tok.isNot(tok::semi)) {
1245     Res = ParseExpression();
1246     if (Res.isInvalid()) {
1247       SkipUntil(tok::semi);
1248       return StmtError();
1249     }
1250   }
1251   ConsumeToken(); // consume ';'
1252   return Actions.ActOnObjCAtThrowStmt(atLoc, move(Res), CurScope);
1253 }
1254 
1255 /// objc-synchronized-statement:
1256 ///   @synchronized '(' expression ')' compound-statement
1257 ///
1258 Parser::OwningStmtResult
1259 Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
1260   ConsumeToken(); // consume synchronized
1261   if (Tok.isNot(tok::l_paren)) {
1262     Diag(Tok, diag::err_expected_lparen_after) << "@synchronized";
1263     return StmtError();
1264   }
1265   ConsumeParen();  // '('
1266   OwningExprResult Res(ParseExpression());
1267   if (Res.isInvalid()) {
1268     SkipUntil(tok::semi);
1269     return StmtError();
1270   }
1271   if (Tok.isNot(tok::r_paren)) {
1272     Diag(Tok, diag::err_expected_lbrace);
1273     return StmtError();
1274   }
1275   ConsumeParen();  // ')'
1276   if (Tok.isNot(tok::l_brace)) {
1277     Diag(Tok, diag::err_expected_lbrace);
1278     return StmtError();
1279   }
1280   // Enter a scope to hold everything within the compound stmt.  Compound
1281   // statements can always hold declarations.
1282   ParseScope BodyScope(this, Scope::DeclScope);
1283 
1284   OwningStmtResult SynchBody(ParseCompoundStatementBody());
1285 
1286   BodyScope.Exit();
1287   if (SynchBody.isInvalid())
1288     SynchBody = Actions.ActOnNullStmt(Tok.getLocation());
1289   return Actions.ActOnObjCAtSynchronizedStmt(atLoc, move(Res), move(SynchBody));
1290 }
1291 
1292 ///  objc-try-catch-statement:
1293 ///    @try compound-statement objc-catch-list[opt]
1294 ///    @try compound-statement objc-catch-list[opt] @finally compound-statement
1295 ///
1296 ///  objc-catch-list:
1297 ///    @catch ( parameter-declaration ) compound-statement
1298 ///    objc-catch-list @catch ( catch-parameter-declaration ) compound-statement
1299 ///  catch-parameter-declaration:
1300 ///     parameter-declaration
1301 ///     '...' [OBJC2]
1302 ///
1303 Parser::OwningStmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
1304   bool catch_or_finally_seen = false;
1305 
1306   ConsumeToken(); // consume try
1307   if (Tok.isNot(tok::l_brace)) {
1308     Diag(Tok, diag::err_expected_lbrace);
1309     return StmtError();
1310   }
1311   OwningStmtResult CatchStmts(Actions);
1312   OwningStmtResult FinallyStmt(Actions);
1313   ParseScope TryScope(this, Scope::DeclScope);
1314   OwningStmtResult TryBody(ParseCompoundStatementBody());
1315   TryScope.Exit();
1316   if (TryBody.isInvalid())
1317     TryBody = Actions.ActOnNullStmt(Tok.getLocation());
1318 
1319   while (Tok.is(tok::at)) {
1320     // At this point, we need to lookahead to determine if this @ is the start
1321     // of an @catch or @finally.  We don't want to consume the @ token if this
1322     // is an @try or @encode or something else.
1323     Token AfterAt = GetLookAheadToken(1);
1324     if (!AfterAt.isObjCAtKeyword(tok::objc_catch) &&
1325         !AfterAt.isObjCAtKeyword(tok::objc_finally))
1326       break;
1327 
1328     SourceLocation AtCatchFinallyLoc = ConsumeToken();
1329     if (Tok.isObjCAtKeyword(tok::objc_catch)) {
1330       DeclPtrTy FirstPart;
1331       ConsumeToken(); // consume catch
1332       if (Tok.is(tok::l_paren)) {
1333         ConsumeParen();
1334         ParseScope CatchScope(this, Scope::DeclScope|Scope::AtCatchScope);
1335         if (Tok.isNot(tok::ellipsis)) {
1336           DeclSpec DS;
1337           ParseDeclarationSpecifiers(DS);
1338           // For some odd reason, the name of the exception variable is
1339           // optional. As a result, we need to use "PrototypeContext", because
1340           // we must accept either 'declarator' or 'abstract-declarator' here.
1341           Declarator ParmDecl(DS, Declarator::PrototypeContext);
1342           ParseDeclarator(ParmDecl);
1343 
1344           // Inform the actions module about the parameter declarator, so it
1345           // gets added to the current scope.
1346           FirstPart = Actions.ActOnParamDeclarator(CurScope, ParmDecl);
1347         } else
1348           ConsumeToken(); // consume '...'
1349 
1350         SourceLocation RParenLoc;
1351 
1352         if (Tok.is(tok::r_paren))
1353           RParenLoc = ConsumeParen();
1354         else // Skip over garbage, until we get to ')'.  Eat the ')'.
1355           SkipUntil(tok::r_paren, true, false);
1356 
1357         OwningStmtResult CatchBody(Actions, true);
1358         if (Tok.is(tok::l_brace))
1359           CatchBody = ParseCompoundStatementBody();
1360         else
1361           Diag(Tok, diag::err_expected_lbrace);
1362         if (CatchBody.isInvalid())
1363           CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
1364         CatchStmts = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc,
1365                         RParenLoc, FirstPart, move(CatchBody),
1366                         move(CatchStmts));
1367       } else {
1368         Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
1369           << "@catch clause";
1370         return StmtError();
1371       }
1372       catch_or_finally_seen = true;
1373     } else {
1374       assert(Tok.isObjCAtKeyword(tok::objc_finally) && "Lookahead confused?");
1375       ConsumeToken(); // consume finally
1376       ParseScope FinallyScope(this, Scope::DeclScope);
1377 
1378       OwningStmtResult FinallyBody(Actions, true);
1379       if (Tok.is(tok::l_brace))
1380         FinallyBody = ParseCompoundStatementBody();
1381       else
1382         Diag(Tok, diag::err_expected_lbrace);
1383       if (FinallyBody.isInvalid())
1384         FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
1385       FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
1386                                                    move(FinallyBody));
1387       catch_or_finally_seen = true;
1388       break;
1389     }
1390   }
1391   if (!catch_or_finally_seen) {
1392     Diag(atLoc, diag::err_missing_catch_finally);
1393     return StmtError();
1394   }
1395   return Actions.ActOnObjCAtTryStmt(atLoc, move(TryBody), move(CatchStmts),
1396                                     move(FinallyStmt));
1397 }
1398 
1399 ///   objc-method-def: objc-method-proto ';'[opt] '{' body '}'
1400 ///
1401 Parser::DeclPtrTy Parser::ParseObjCMethodDefinition() {
1402   DeclPtrTy MDecl = ParseObjCMethodPrototype(ObjCImpDecl);
1403 
1404   PrettyStackTraceActionsDecl CrashInfo(MDecl, Tok.getLocation(), Actions,
1405                                         PP.getSourceManager(),
1406                                         "parsing Objective-C method");
1407 
1408   // parse optional ';'
1409   if (Tok.is(tok::semi)) {
1410     if (ObjCImpDecl)
1411       Diag(Tok, diag::warn_semicolon_before_method_nody);
1412     ConsumeToken();
1413   }
1414 
1415   // We should have an opening brace now.
1416   if (Tok.isNot(tok::l_brace)) {
1417     Diag(Tok, diag::err_expected_method_body);
1418 
1419     // Skip over garbage, until we get to '{'.  Don't eat the '{'.
1420     SkipUntil(tok::l_brace, true, true);
1421 
1422     // If we didn't find the '{', bail out.
1423     if (Tok.isNot(tok::l_brace))
1424       return DeclPtrTy();
1425   }
1426   SourceLocation BraceLoc = Tok.getLocation();
1427 
1428   // Enter a scope for the method body.
1429   ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope);
1430 
1431   // Tell the actions module that we have entered a method definition with the
1432   // specified Declarator for the method.
1433   Actions.ActOnStartOfObjCMethodDef(CurScope, MDecl);
1434 
1435   OwningStmtResult FnBody(ParseCompoundStatementBody());
1436 
1437   // If the function body could not be parsed, make a bogus compoundstmt.
1438   if (FnBody.isInvalid())
1439     FnBody = Actions.ActOnCompoundStmt(BraceLoc, BraceLoc,
1440                                        MultiStmtArg(Actions), false);
1441 
1442   // TODO: Pass argument information.
1443   Actions.ActOnFinishFunctionBody(MDecl, move(FnBody));
1444 
1445   // Leave the function body scope.
1446   BodyScope.Exit();
1447 
1448   return MDecl;
1449 }
1450 
1451 Parser::OwningStmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) {
1452   if (Tok.isObjCAtKeyword(tok::objc_try)) {
1453     return ParseObjCTryStmt(AtLoc);
1454   } else if (Tok.isObjCAtKeyword(tok::objc_throw))
1455     return ParseObjCThrowStmt(AtLoc);
1456   else if (Tok.isObjCAtKeyword(tok::objc_synchronized))
1457     return ParseObjCSynchronizedStmt(AtLoc);
1458   OwningExprResult Res(ParseExpressionWithLeadingAt(AtLoc));
1459   if (Res.isInvalid()) {
1460     // If the expression is invalid, skip ahead to the next semicolon. Not
1461     // doing this opens us up to the possibility of infinite loops if
1462     // ParseExpression does not consume any tokens.
1463     SkipUntil(tok::semi);
1464     return StmtError();
1465   }
1466   // Otherwise, eat the semicolon.
1467   ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
1468   return Actions.ActOnExprStmt(Actions.FullExpr(Res));
1469 }
1470 
1471 Parser::OwningExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
1472   switch (Tok.getKind()) {
1473   case tok::string_literal:    // primary-expression: string-literal
1474   case tok::wide_string_literal:
1475     return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
1476   default:
1477     if (Tok.getIdentifierInfo() == 0)
1478       return ExprError(Diag(AtLoc, diag::err_unexpected_at));
1479 
1480     switch (Tok.getIdentifierInfo()->getObjCKeywordID()) {
1481     case tok::objc_encode:
1482       return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc));
1483     case tok::objc_protocol:
1484       return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc));
1485     case tok::objc_selector:
1486       return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc));
1487     default:
1488       return ExprError(Diag(AtLoc, diag::err_unexpected_at));
1489     }
1490   }
1491 }
1492 
1493 ///   objc-message-expr:
1494 ///     '[' objc-receiver objc-message-args ']'
1495 ///
1496 ///   objc-receiver:
1497 ///     expression
1498 ///     class-name
1499 ///     type-name
1500 Parser::OwningExprResult Parser::ParseObjCMessageExpression() {
1501   assert(Tok.is(tok::l_square) && "'[' expected");
1502   SourceLocation LBracLoc = ConsumeBracket(); // consume '['
1503 
1504   // Parse receiver
1505   if (isTokObjCMessageIdentifierReceiver()) {
1506     IdentifierInfo *ReceiverName = Tok.getIdentifierInfo();
1507     if (ReceiverName != Ident_super || GetLookAheadToken(1).isNot(tok::period)) {
1508       SourceLocation NameLoc = ConsumeToken();
1509       return ParseObjCMessageExpressionBody(LBracLoc, NameLoc, ReceiverName,
1510                                             ExprArg(Actions));
1511     }
1512   }
1513 
1514   OwningExprResult Res(ParseExpression());
1515   if (Res.isInvalid()) {
1516     SkipUntil(tok::r_square);
1517     return move(Res);
1518   }
1519 
1520   return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
1521                                         0, move(Res));
1522 }
1523 
1524 /// ParseObjCMessageExpressionBody - Having parsed "'[' objc-receiver", parse
1525 /// the rest of a message expression.
1526 ///
1527 ///   objc-message-args:
1528 ///     objc-selector
1529 ///     objc-keywordarg-list
1530 ///
1531 ///   objc-keywordarg-list:
1532 ///     objc-keywordarg
1533 ///     objc-keywordarg-list objc-keywordarg
1534 ///
1535 ///   objc-keywordarg:
1536 ///     selector-name[opt] ':' objc-keywordexpr
1537 ///
1538 ///   objc-keywordexpr:
1539 ///     nonempty-expr-list
1540 ///
1541 ///   nonempty-expr-list:
1542 ///     assignment-expression
1543 ///     nonempty-expr-list , assignment-expression
1544 ///
1545 Parser::OwningExprResult
1546 Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
1547                                        SourceLocation NameLoc,
1548                                        IdentifierInfo *ReceiverName,
1549                                        ExprArg ReceiverExpr) {
1550   // Parse objc-selector
1551   SourceLocation Loc;
1552   IdentifierInfo *selIdent = ParseObjCSelectorPiece(Loc);
1553 
1554   SourceLocation SelectorLoc = Loc;
1555 
1556   llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
1557   ExprVector KeyExprs(Actions);
1558 
1559   if (Tok.is(tok::colon)) {
1560     while (1) {
1561       // Each iteration parses a single keyword argument.
1562       KeyIdents.push_back(selIdent);
1563 
1564       if (Tok.isNot(tok::colon)) {
1565         Diag(Tok, diag::err_expected_colon);
1566         // We must manually skip to a ']', otherwise the expression skipper will
1567         // stop at the ']' when it skips to the ';'.  We want it to skip beyond
1568         // the enclosing expression.
1569         SkipUntil(tok::r_square);
1570         return ExprError();
1571       }
1572 
1573       ConsumeToken(); // Eat the ':'.
1574       ///  Parse the expression after ':'
1575       OwningExprResult Res(ParseAssignmentExpression());
1576       if (Res.isInvalid()) {
1577         // We must manually skip to a ']', otherwise the expression skipper will
1578         // stop at the ']' when it skips to the ';'.  We want it to skip beyond
1579         // the enclosing expression.
1580         SkipUntil(tok::r_square);
1581         return move(Res);
1582       }
1583 
1584       // We have a valid expression.
1585       KeyExprs.push_back(Res.release());
1586 
1587       // Check for another keyword selector.
1588       selIdent = ParseObjCSelectorPiece(Loc);
1589       if (!selIdent && Tok.isNot(tok::colon))
1590         break;
1591       // We have a selector or a colon, continue parsing.
1592     }
1593     // Parse the, optional, argument list, comma separated.
1594     while (Tok.is(tok::comma)) {
1595       ConsumeToken(); // Eat the ','.
1596       ///  Parse the expression after ','
1597       OwningExprResult Res(ParseAssignmentExpression());
1598       if (Res.isInvalid()) {
1599         // We must manually skip to a ']', otherwise the expression skipper will
1600         // stop at the ']' when it skips to the ';'.  We want it to skip beyond
1601         // the enclosing expression.
1602         SkipUntil(tok::r_square);
1603         return move(Res);
1604       }
1605 
1606       // We have a valid expression.
1607       KeyExprs.push_back(Res.release());
1608     }
1609   } else if (!selIdent) {
1610     Diag(Tok, diag::err_expected_ident); // missing selector name.
1611 
1612     // We must manually skip to a ']', otherwise the expression skipper will
1613     // stop at the ']' when it skips to the ';'.  We want it to skip beyond
1614     // the enclosing expression.
1615     SkipUntil(tok::r_square);
1616     return ExprError();
1617   }
1618 
1619   if (Tok.isNot(tok::r_square)) {
1620     Diag(Tok, diag::err_expected_rsquare);
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   SourceLocation RBracLoc = ConsumeBracket(); // consume ']'
1629 
1630   unsigned nKeys = KeyIdents.size();
1631   if (nKeys == 0)
1632     KeyIdents.push_back(selIdent);
1633   Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]);
1634 
1635   // We've just parsed a keyword message.
1636   if (ReceiverName)
1637     return Owned(Actions.ActOnClassMessage(CurScope, ReceiverName, Sel,
1638                                            LBracLoc, NameLoc, SelectorLoc,
1639                                            RBracLoc,
1640                                            KeyExprs.take(), KeyExprs.size()));
1641   return Owned(Actions.ActOnInstanceMessage(ReceiverExpr.release(), Sel,
1642                                             LBracLoc, SelectorLoc, RBracLoc,
1643                                             KeyExprs.take(), KeyExprs.size()));
1644 }
1645 
1646 Parser::OwningExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
1647   OwningExprResult Res(ParseStringLiteralExpression());
1648   if (Res.isInvalid()) return move(Res);
1649 
1650   // @"foo" @"bar" is a valid concatenated string.  Eat any subsequent string
1651   // expressions.  At this point, we know that the only valid thing that starts
1652   // with '@' is an @"".
1653   llvm::SmallVector<SourceLocation, 4> AtLocs;
1654   ExprVector AtStrings(Actions);
1655   AtLocs.push_back(AtLoc);
1656   AtStrings.push_back(Res.release());
1657 
1658   while (Tok.is(tok::at)) {
1659     AtLocs.push_back(ConsumeToken()); // eat the @.
1660 
1661     // Invalid unless there is a string literal.
1662     if (!isTokenStringLiteral())
1663       return ExprError(Diag(Tok, diag::err_objc_concat_string));
1664 
1665     OwningExprResult Lit(ParseStringLiteralExpression());
1666     if (Lit.isInvalid())
1667       return move(Lit);
1668 
1669     AtStrings.push_back(Lit.release());
1670   }
1671 
1672   return Owned(Actions.ParseObjCStringLiteral(&AtLocs[0], AtStrings.take(),
1673                                               AtStrings.size()));
1674 }
1675 
1676 ///    objc-encode-expression:
1677 ///      @encode ( type-name )
1678 Parser::OwningExprResult
1679 Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) {
1680   assert(Tok.isObjCAtKeyword(tok::objc_encode) && "Not an @encode expression!");
1681 
1682   SourceLocation EncLoc = ConsumeToken();
1683 
1684   if (Tok.isNot(tok::l_paren))
1685     return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@encode");
1686 
1687   SourceLocation LParenLoc = ConsumeParen();
1688 
1689   TypeResult Ty = ParseTypeName();
1690 
1691   SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
1692 
1693   if (Ty.isInvalid())
1694     return ExprError();
1695 
1696   return Owned(Actions.ParseObjCEncodeExpression(AtLoc, EncLoc, LParenLoc,
1697                                                  Ty.get(), RParenLoc));
1698 }
1699 
1700 ///     objc-protocol-expression
1701 ///       @protocol ( protocol-name )
1702 Parser::OwningExprResult
1703 Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) {
1704   SourceLocation ProtoLoc = ConsumeToken();
1705 
1706   if (Tok.isNot(tok::l_paren))
1707     return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@protocol");
1708 
1709   SourceLocation LParenLoc = ConsumeParen();
1710 
1711   if (Tok.isNot(tok::identifier))
1712     return ExprError(Diag(Tok, diag::err_expected_ident));
1713 
1714   IdentifierInfo *protocolId = Tok.getIdentifierInfo();
1715   ConsumeToken();
1716 
1717   SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
1718 
1719   return Owned(Actions.ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc,
1720                                                    LParenLoc, RParenLoc));
1721 }
1722 
1723 ///     objc-selector-expression
1724 ///       @selector '(' objc-keyword-selector ')'
1725 Parser::OwningExprResult
1726 Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) {
1727   SourceLocation SelectorLoc = ConsumeToken();
1728 
1729   if (Tok.isNot(tok::l_paren))
1730     return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@selector");
1731 
1732   llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
1733   SourceLocation LParenLoc = ConsumeParen();
1734   SourceLocation sLoc;
1735   IdentifierInfo *SelIdent = ParseObjCSelectorPiece(sLoc);
1736   if (!SelIdent && Tok.isNot(tok::colon)) // missing selector name.
1737     return ExprError(Diag(Tok, diag::err_expected_ident));
1738 
1739   KeyIdents.push_back(SelIdent);
1740   unsigned nColons = 0;
1741   if (Tok.isNot(tok::r_paren)) {
1742     while (1) {
1743       if (Tok.isNot(tok::colon))
1744         return ExprError(Diag(Tok, diag::err_expected_colon));
1745 
1746       nColons++;
1747       ConsumeToken(); // Eat the ':'.
1748       if (Tok.is(tok::r_paren))
1749         break;
1750       // Check for another keyword selector.
1751       SourceLocation Loc;
1752       SelIdent = ParseObjCSelectorPiece(Loc);
1753       KeyIdents.push_back(SelIdent);
1754       if (!SelIdent && Tok.isNot(tok::colon))
1755         break;
1756     }
1757   }
1758   SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
1759   Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]);
1760   return Owned(Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc,
1761                                                    LParenLoc, RParenLoc));
1762  }
1763