xref: /llvm-project/clang/lib/Parse/ParseObjc.cpp (revision cfefb6d197c7ee7044dd9c5f8491f191a7872f0c)
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   // Parse the return type if present.
702   TypeTy *ReturnType = 0;
703   ObjCDeclSpec DSRet;
704   if (Tok.is(tok::l_paren))
705     ReturnType = ParseObjCTypeName(DSRet);
706 
707   SourceLocation selLoc;
708   IdentifierInfo *SelIdent = ParseObjCSelectorPiece(selLoc);
709 
710   // An unnamed colon is valid.
711   if (!SelIdent && Tok.isNot(tok::colon)) { // missing selector name.
712     Diag(Tok, diag::err_expected_selector_for_method)
713       << SourceRange(mLoc, Tok.getLocation());
714     // Skip until we get a ; or {}.
715     SkipUntil(tok::r_brace);
716     return DeclPtrTy();
717   }
718 
719   llvm::SmallVector<Declarator, 8> CargNames;
720   if (Tok.isNot(tok::colon)) {
721     // If attributes exist after the method, parse them.
722     AttributeList *MethodAttrs = 0;
723     if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
724       MethodAttrs = ParseAttributes();
725 
726     Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
727     return Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(),
728                                           mType, IDecl, DSRet, ReturnType, Sel,
729                                           0, CargNames, MethodAttrs,
730                                           MethodImplKind);
731   }
732 
733   llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
734   llvm::SmallVector<Action::ObjCArgInfo, 12> ArgInfos;
735 
736   while (1) {
737     Action::ObjCArgInfo ArgInfo;
738 
739     // Each iteration parses a single keyword argument.
740     if (Tok.isNot(tok::colon)) {
741       Diag(Tok, diag::err_expected_colon);
742       break;
743     }
744     ConsumeToken(); // Eat the ':'.
745 
746     ArgInfo.Type = 0;
747     if (Tok.is(tok::l_paren)) // Parse the argument type if present.
748       ArgInfo.Type = ParseObjCTypeName(ArgInfo.DeclSpec);
749 
750     // If attributes exist before the argument name, parse them.
751     ArgInfo.ArgAttrs = 0;
752     if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
753       ArgInfo.ArgAttrs = ParseAttributes();
754 
755     if (Tok.isNot(tok::identifier)) {
756       Diag(Tok, diag::err_expected_ident); // missing argument name.
757       break;
758     }
759 
760     ArgInfo.Name = Tok.getIdentifierInfo();
761     ArgInfo.NameLoc = Tok.getLocation();
762     ConsumeToken(); // Eat the identifier.
763 
764     ArgInfos.push_back(ArgInfo);
765     KeyIdents.push_back(SelIdent);
766 
767     // Check for another keyword selector.
768     SourceLocation Loc;
769     SelIdent = ParseObjCSelectorPiece(Loc);
770     if (!SelIdent && Tok.isNot(tok::colon))
771       break;
772     // We have a selector or a colon, continue parsing.
773   }
774 
775   bool isVariadic = false;
776 
777   // Parse the (optional) parameter list.
778   while (Tok.is(tok::comma)) {
779     ConsumeToken();
780     if (Tok.is(tok::ellipsis)) {
781       isVariadic = true;
782       ConsumeToken();
783       break;
784     }
785     DeclSpec DS;
786     ParseDeclarationSpecifiers(DS);
787     // Parse the declarator.
788     Declarator ParmDecl(DS, Declarator::PrototypeContext);
789     ParseDeclarator(ParmDecl);
790     CargNames.push_back(ParmDecl);
791   }
792 
793   // FIXME: Add support for optional parmameter list...
794   // If attributes exist after the method, parse them.
795   AttributeList *MethodAttrs = 0;
796   if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
797     MethodAttrs = ParseAttributes();
798 
799   if (KeyIdents.size() == 0)
800     return DeclPtrTy();
801   Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(),
802                                                    &KeyIdents[0]);
803   return Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(),
804                                         mType, IDecl, DSRet, ReturnType, Sel,
805                                         &ArgInfos[0], CargNames, MethodAttrs,
806                                         MethodImplKind, isVariadic);
807 }
808 
809 ///   objc-protocol-refs:
810 ///     '<' identifier-list '>'
811 ///
812 bool Parser::
813 ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclPtrTy> &Protocols,
814                             llvm::SmallVectorImpl<SourceLocation> &ProtocolLocs,
815                             bool WarnOnDeclarations,
816                             SourceLocation &LAngleLoc, SourceLocation &EndLoc) {
817   assert(Tok.is(tok::less) && "expected <");
818 
819   LAngleLoc = ConsumeToken(); // the "<"
820 
821   llvm::SmallVector<IdentifierLocPair, 8> ProtocolIdents;
822 
823   while (1) {
824     if (Tok.isNot(tok::identifier)) {
825       Diag(Tok, diag::err_expected_ident);
826       SkipUntil(tok::greater);
827       return true;
828     }
829     ProtocolIdents.push_back(std::make_pair(Tok.getIdentifierInfo(),
830                                        Tok.getLocation()));
831     ProtocolLocs.push_back(Tok.getLocation());
832     ConsumeToken();
833 
834     if (Tok.isNot(tok::comma))
835       break;
836     ConsumeToken();
837   }
838 
839   // Consume the '>'.
840   if (Tok.isNot(tok::greater)) {
841     Diag(Tok, diag::err_expected_greater);
842     return true;
843   }
844 
845   EndLoc = ConsumeAnyToken();
846 
847   // Convert the list of protocols identifiers into a list of protocol decls.
848   Actions.FindProtocolDeclaration(WarnOnDeclarations,
849                                   &ProtocolIdents[0], ProtocolIdents.size(),
850                                   Protocols);
851   return false;
852 }
853 
854 ///   objc-class-instance-variables:
855 ///     '{' objc-instance-variable-decl-list[opt] '}'
856 ///
857 ///   objc-instance-variable-decl-list:
858 ///     objc-visibility-spec
859 ///     objc-instance-variable-decl ';'
860 ///     ';'
861 ///     objc-instance-variable-decl-list objc-visibility-spec
862 ///     objc-instance-variable-decl-list objc-instance-variable-decl ';'
863 ///     objc-instance-variable-decl-list ';'
864 ///
865 ///   objc-visibility-spec:
866 ///     @private
867 ///     @protected
868 ///     @public
869 ///     @package [OBJC2]
870 ///
871 ///   objc-instance-variable-decl:
872 ///     struct-declaration
873 ///
874 void Parser::ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl,
875                                              SourceLocation atLoc) {
876   assert(Tok.is(tok::l_brace) && "expected {");
877   llvm::SmallVector<DeclPtrTy, 32> AllIvarDecls;
878 
879   ParseScope ClassScope(this, Scope::DeclScope|Scope::ClassScope);
880 
881   SourceLocation LBraceLoc = ConsumeBrace(); // the "{"
882 
883   tok::ObjCKeywordKind visibility = tok::objc_protected;
884   // While we still have something to read, read the instance variables.
885   while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
886     // Each iteration of this loop reads one objc-instance-variable-decl.
887 
888     // Check for extraneous top-level semicolon.
889     if (Tok.is(tok::semi)) {
890       Diag(Tok, diag::ext_extra_struct_semi);
891       ConsumeToken();
892       continue;
893     }
894 
895     // Set the default visibility to private.
896     if (Tok.is(tok::at)) { // parse objc-visibility-spec
897       ConsumeToken(); // eat the @ sign
898       switch (Tok.getObjCKeywordID()) {
899       case tok::objc_private:
900       case tok::objc_public:
901       case tok::objc_protected:
902       case tok::objc_package:
903         visibility = Tok.getObjCKeywordID();
904         ConsumeToken();
905         continue;
906       default:
907         Diag(Tok, diag::err_objc_illegal_visibility_spec);
908         continue;
909       }
910     }
911 
912     struct ObjCIvarCallback : FieldCallback {
913       Parser &P;
914       DeclPtrTy IDecl;
915       tok::ObjCKeywordKind visibility;
916       llvm::SmallVectorImpl<DeclPtrTy> &AllIvarDecls;
917 
918       ObjCIvarCallback(Parser &P, DeclPtrTy IDecl, tok::ObjCKeywordKind V,
919                        llvm::SmallVectorImpl<DeclPtrTy> &AllIvarDecls) :
920         P(P), IDecl(IDecl), visibility(V), AllIvarDecls(AllIvarDecls) {
921       }
922 
923       DeclPtrTy invoke(FieldDeclarator &FD) {
924         // Install the declarator into the interface decl.
925         DeclPtrTy Field
926           = P.Actions.ActOnIvar(P.CurScope,
927                                 FD.D.getDeclSpec().getSourceRange().getBegin(),
928                                 IDecl, FD.D, FD.BitfieldSize, visibility);
929         AllIvarDecls.push_back(Field);
930         return Field;
931       }
932     } Callback(*this, interfaceDecl, visibility, AllIvarDecls);
933 
934     // Parse all the comma separated declarators.
935     DeclSpec DS;
936     ParseStructDeclaration(DS, Callback);
937 
938     if (Tok.is(tok::semi)) {
939       ConsumeToken();
940     } else {
941       Diag(Tok, diag::err_expected_semi_decl_list);
942       // Skip to end of block or statement
943       SkipUntil(tok::r_brace, true, true);
944     }
945   }
946   SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
947   // Call ActOnFields() even if we don't have any decls. This is useful
948   // for code rewriting tools that need to be aware of the empty list.
949   Actions.ActOnFields(CurScope, atLoc, interfaceDecl,
950                       AllIvarDecls.data(), AllIvarDecls.size(),
951                       LBraceLoc, RBraceLoc, 0);
952   return;
953 }
954 
955 ///   objc-protocol-declaration:
956 ///     objc-protocol-definition
957 ///     objc-protocol-forward-reference
958 ///
959 ///   objc-protocol-definition:
960 ///     @protocol identifier
961 ///       objc-protocol-refs[opt]
962 ///       objc-interface-decl-list
963 ///     @end
964 ///
965 ///   objc-protocol-forward-reference:
966 ///     @protocol identifier-list ';'
967 ///
968 ///   "@protocol identifier ;" should be resolved as "@protocol
969 ///   identifier-list ;": objc-interface-decl-list may not start with a
970 ///   semicolon in the first alternative if objc-protocol-refs are omitted.
971 Parser::DeclPtrTy Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
972                                                       AttributeList *attrList) {
973   assert(Tok.isObjCAtKeyword(tok::objc_protocol) &&
974          "ParseObjCAtProtocolDeclaration(): Expected @protocol");
975   ConsumeToken(); // the "protocol" identifier
976 
977   if (Tok.isNot(tok::identifier)) {
978     Diag(Tok, diag::err_expected_ident); // missing protocol name.
979     return DeclPtrTy();
980   }
981   // Save the protocol name, then consume it.
982   IdentifierInfo *protocolName = Tok.getIdentifierInfo();
983   SourceLocation nameLoc = ConsumeToken();
984 
985   if (Tok.is(tok::semi)) { // forward declaration of one protocol.
986     IdentifierLocPair ProtoInfo(protocolName, nameLoc);
987     ConsumeToken();
988     return Actions.ActOnForwardProtocolDeclaration(AtLoc, &ProtoInfo, 1,
989                                                    attrList);
990   }
991 
992   if (Tok.is(tok::comma)) { // list of forward declarations.
993     llvm::SmallVector<IdentifierLocPair, 8> ProtocolRefs;
994     ProtocolRefs.push_back(std::make_pair(protocolName, nameLoc));
995 
996     // Parse the list of forward declarations.
997     while (1) {
998       ConsumeToken(); // the ','
999       if (Tok.isNot(tok::identifier)) {
1000         Diag(Tok, diag::err_expected_ident);
1001         SkipUntil(tok::semi);
1002         return DeclPtrTy();
1003       }
1004       ProtocolRefs.push_back(IdentifierLocPair(Tok.getIdentifierInfo(),
1005                                                Tok.getLocation()));
1006       ConsumeToken(); // the identifier
1007 
1008       if (Tok.isNot(tok::comma))
1009         break;
1010     }
1011     // Consume the ';'.
1012     if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@protocol"))
1013       return DeclPtrTy();
1014 
1015     return Actions.ActOnForwardProtocolDeclaration(AtLoc,
1016                                                    &ProtocolRefs[0],
1017                                                    ProtocolRefs.size(),
1018                                                    attrList);
1019   }
1020 
1021   // Last, and definitely not least, parse a protocol declaration.
1022   SourceLocation LAngleLoc, EndProtoLoc;
1023 
1024   llvm::SmallVector<DeclPtrTy, 8> ProtocolRefs;
1025   llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
1026   if (Tok.is(tok::less) &&
1027       ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, false,
1028                                   LAngleLoc, EndProtoLoc))
1029     return DeclPtrTy();
1030 
1031   DeclPtrTy ProtoType =
1032     Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc,
1033                                         ProtocolRefs.data(),
1034                                         ProtocolRefs.size(),
1035                                         EndProtoLoc, attrList);
1036   ParseObjCInterfaceDeclList(ProtoType, tok::objc_protocol);
1037   return ProtoType;
1038 }
1039 
1040 ///   objc-implementation:
1041 ///     objc-class-implementation-prologue
1042 ///     objc-category-implementation-prologue
1043 ///
1044 ///   objc-class-implementation-prologue:
1045 ///     @implementation identifier objc-superclass[opt]
1046 ///       objc-class-instance-variables[opt]
1047 ///
1048 ///   objc-category-implementation-prologue:
1049 ///     @implementation identifier ( identifier )
1050 Parser::DeclPtrTy Parser::ParseObjCAtImplementationDeclaration(
1051   SourceLocation atLoc) {
1052   assert(Tok.isObjCAtKeyword(tok::objc_implementation) &&
1053          "ParseObjCAtImplementationDeclaration(): Expected @implementation");
1054   ConsumeToken(); // the "implementation" identifier
1055 
1056   if (Tok.isNot(tok::identifier)) {
1057     Diag(Tok, diag::err_expected_ident); // missing class or category name.
1058     return DeclPtrTy();
1059   }
1060   // We have a class or category name - consume it.
1061   IdentifierInfo *nameId = Tok.getIdentifierInfo();
1062   SourceLocation nameLoc = ConsumeToken(); // consume class or category name
1063 
1064   if (Tok.is(tok::l_paren)) {
1065     // we have a category implementation.
1066     SourceLocation lparenLoc = ConsumeParen();
1067     SourceLocation categoryLoc, rparenLoc;
1068     IdentifierInfo *categoryId = 0;
1069 
1070     if (Tok.is(tok::identifier)) {
1071       categoryId = Tok.getIdentifierInfo();
1072       categoryLoc = ConsumeToken();
1073     } else {
1074       Diag(Tok, diag::err_expected_ident); // missing category name.
1075       return DeclPtrTy();
1076     }
1077     if (Tok.isNot(tok::r_paren)) {
1078       Diag(Tok, diag::err_expected_rparen);
1079       SkipUntil(tok::r_paren, false); // don't stop at ';'
1080       return DeclPtrTy();
1081     }
1082     rparenLoc = ConsumeParen();
1083     DeclPtrTy ImplCatType = Actions.ActOnStartCategoryImplementation(
1084                                     atLoc, nameId, nameLoc, categoryId,
1085                                     categoryLoc);
1086     ObjCImpDecl = ImplCatType;
1087     return DeclPtrTy();
1088   }
1089   // We have a class implementation
1090   SourceLocation superClassLoc;
1091   IdentifierInfo *superClassId = 0;
1092   if (Tok.is(tok::colon)) {
1093     // We have a super class
1094     ConsumeToken();
1095     if (Tok.isNot(tok::identifier)) {
1096       Diag(Tok, diag::err_expected_ident); // missing super class name.
1097       return DeclPtrTy();
1098     }
1099     superClassId = Tok.getIdentifierInfo();
1100     superClassLoc = ConsumeToken(); // Consume super class name
1101   }
1102   DeclPtrTy ImplClsType = Actions.ActOnStartClassImplementation(
1103                                   atLoc, nameId, nameLoc,
1104                                   superClassId, superClassLoc);
1105 
1106   if (Tok.is(tok::l_brace)) // we have ivars
1107     ParseObjCClassInstanceVariables(ImplClsType/*FIXME*/, atLoc);
1108   ObjCImpDecl = ImplClsType;
1109 
1110   return DeclPtrTy();
1111 }
1112 
1113 Parser::DeclPtrTy Parser::ParseObjCAtEndDeclaration(SourceLocation atLoc) {
1114   assert(Tok.isObjCAtKeyword(tok::objc_end) &&
1115          "ParseObjCAtEndDeclaration(): Expected @end");
1116   DeclPtrTy Result = ObjCImpDecl;
1117   ConsumeToken(); // the "end" identifier
1118   if (ObjCImpDecl) {
1119     Actions.ActOnAtEnd(atLoc, ObjCImpDecl);
1120     ObjCImpDecl = DeclPtrTy();
1121   }
1122   else
1123     Diag(atLoc, diag::warn_expected_implementation); // missing @implementation
1124   return Result;
1125 }
1126 
1127 ///   compatibility-alias-decl:
1128 ///     @compatibility_alias alias-name  class-name ';'
1129 ///
1130 Parser::DeclPtrTy Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) {
1131   assert(Tok.isObjCAtKeyword(tok::objc_compatibility_alias) &&
1132          "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias");
1133   ConsumeToken(); // consume compatibility_alias
1134   if (Tok.isNot(tok::identifier)) {
1135     Diag(Tok, diag::err_expected_ident);
1136     return DeclPtrTy();
1137   }
1138   IdentifierInfo *aliasId = Tok.getIdentifierInfo();
1139   SourceLocation aliasLoc = ConsumeToken(); // consume alias-name
1140   if (Tok.isNot(tok::identifier)) {
1141     Diag(Tok, diag::err_expected_ident);
1142     return DeclPtrTy();
1143   }
1144   IdentifierInfo *classId = Tok.getIdentifierInfo();
1145   SourceLocation classLoc = ConsumeToken(); // consume class-name;
1146   if (Tok.isNot(tok::semi)) {
1147     Diag(Tok, diag::err_expected_semi_after) << "@compatibility_alias";
1148     return DeclPtrTy();
1149   }
1150   return Actions.ActOnCompatiblityAlias(atLoc, aliasId, aliasLoc,
1151                                         classId, classLoc);
1152 }
1153 
1154 ///   property-synthesis:
1155 ///     @synthesize property-ivar-list ';'
1156 ///
1157 ///   property-ivar-list:
1158 ///     property-ivar
1159 ///     property-ivar-list ',' property-ivar
1160 ///
1161 ///   property-ivar:
1162 ///     identifier
1163 ///     identifier '=' identifier
1164 ///
1165 Parser::DeclPtrTy Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
1166   assert(Tok.isObjCAtKeyword(tok::objc_synthesize) &&
1167          "ParseObjCPropertyDynamic(): Expected '@synthesize'");
1168   SourceLocation loc = ConsumeToken(); // consume synthesize
1169   if (Tok.isNot(tok::identifier)) {
1170     Diag(Tok, diag::err_expected_ident);
1171     return DeclPtrTy();
1172   }
1173 
1174   while (Tok.is(tok::identifier)) {
1175     IdentifierInfo *propertyIvar = 0;
1176     IdentifierInfo *propertyId = Tok.getIdentifierInfo();
1177     SourceLocation propertyLoc = ConsumeToken(); // consume property name
1178     if (Tok.is(tok::equal)) {
1179       // property '=' ivar-name
1180       ConsumeToken(); // consume '='
1181       if (Tok.isNot(tok::identifier)) {
1182         Diag(Tok, diag::err_expected_ident);
1183         break;
1184       }
1185       propertyIvar = Tok.getIdentifierInfo();
1186       ConsumeToken(); // consume ivar-name
1187     }
1188     Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, true, ObjCImpDecl,
1189                                   propertyId, propertyIvar);
1190     if (Tok.isNot(tok::comma))
1191       break;
1192     ConsumeToken(); // consume ','
1193   }
1194   if (Tok.isNot(tok::semi))
1195     Diag(Tok, diag::err_expected_semi_after) << "@synthesize";
1196   return DeclPtrTy();
1197 }
1198 
1199 ///   property-dynamic:
1200 ///     @dynamic  property-list
1201 ///
1202 ///   property-list:
1203 ///     identifier
1204 ///     property-list ',' identifier
1205 ///
1206 Parser::DeclPtrTy Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
1207   assert(Tok.isObjCAtKeyword(tok::objc_dynamic) &&
1208          "ParseObjCPropertyDynamic(): Expected '@dynamic'");
1209   SourceLocation loc = ConsumeToken(); // consume dynamic
1210   if (Tok.isNot(tok::identifier)) {
1211     Diag(Tok, diag::err_expected_ident);
1212     return DeclPtrTy();
1213   }
1214   while (Tok.is(tok::identifier)) {
1215     IdentifierInfo *propertyId = Tok.getIdentifierInfo();
1216     SourceLocation propertyLoc = ConsumeToken(); // consume property name
1217     Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, false, ObjCImpDecl,
1218                                   propertyId, 0);
1219 
1220     if (Tok.isNot(tok::comma))
1221       break;
1222     ConsumeToken(); // consume ','
1223   }
1224   if (Tok.isNot(tok::semi))
1225     Diag(Tok, diag::err_expected_semi_after) << "@dynamic";
1226   return DeclPtrTy();
1227 }
1228 
1229 ///  objc-throw-statement:
1230 ///    throw expression[opt];
1231 ///
1232 Parser::OwningStmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) {
1233   OwningExprResult Res(Actions);
1234   ConsumeToken(); // consume throw
1235   if (Tok.isNot(tok::semi)) {
1236     Res = ParseExpression();
1237     if (Res.isInvalid()) {
1238       SkipUntil(tok::semi);
1239       return StmtError();
1240     }
1241   }
1242   ConsumeToken(); // consume ';'
1243   return Actions.ActOnObjCAtThrowStmt(atLoc, move(Res), CurScope);
1244 }
1245 
1246 /// objc-synchronized-statement:
1247 ///   @synchronized '(' expression ')' compound-statement
1248 ///
1249 Parser::OwningStmtResult
1250 Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
1251   ConsumeToken(); // consume synchronized
1252   if (Tok.isNot(tok::l_paren)) {
1253     Diag(Tok, diag::err_expected_lparen_after) << "@synchronized";
1254     return StmtError();
1255   }
1256   ConsumeParen();  // '('
1257   OwningExprResult Res(ParseExpression());
1258   if (Res.isInvalid()) {
1259     SkipUntil(tok::semi);
1260     return StmtError();
1261   }
1262   if (Tok.isNot(tok::r_paren)) {
1263     Diag(Tok, diag::err_expected_lbrace);
1264     return StmtError();
1265   }
1266   ConsumeParen();  // ')'
1267   if (Tok.isNot(tok::l_brace)) {
1268     Diag(Tok, diag::err_expected_lbrace);
1269     return StmtError();
1270   }
1271   // Enter a scope to hold everything within the compound stmt.  Compound
1272   // statements can always hold declarations.
1273   ParseScope BodyScope(this, Scope::DeclScope);
1274 
1275   OwningStmtResult SynchBody(ParseCompoundStatementBody());
1276 
1277   BodyScope.Exit();
1278   if (SynchBody.isInvalid())
1279     SynchBody = Actions.ActOnNullStmt(Tok.getLocation());
1280   return Actions.ActOnObjCAtSynchronizedStmt(atLoc, move(Res), move(SynchBody));
1281 }
1282 
1283 ///  objc-try-catch-statement:
1284 ///    @try compound-statement objc-catch-list[opt]
1285 ///    @try compound-statement objc-catch-list[opt] @finally compound-statement
1286 ///
1287 ///  objc-catch-list:
1288 ///    @catch ( parameter-declaration ) compound-statement
1289 ///    objc-catch-list @catch ( catch-parameter-declaration ) compound-statement
1290 ///  catch-parameter-declaration:
1291 ///     parameter-declaration
1292 ///     '...' [OBJC2]
1293 ///
1294 Parser::OwningStmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
1295   bool catch_or_finally_seen = false;
1296 
1297   ConsumeToken(); // consume try
1298   if (Tok.isNot(tok::l_brace)) {
1299     Diag(Tok, diag::err_expected_lbrace);
1300     return StmtError();
1301   }
1302   OwningStmtResult CatchStmts(Actions);
1303   OwningStmtResult FinallyStmt(Actions);
1304   ParseScope TryScope(this, Scope::DeclScope);
1305   OwningStmtResult TryBody(ParseCompoundStatementBody());
1306   TryScope.Exit();
1307   if (TryBody.isInvalid())
1308     TryBody = Actions.ActOnNullStmt(Tok.getLocation());
1309 
1310   while (Tok.is(tok::at)) {
1311     // At this point, we need to lookahead to determine if this @ is the start
1312     // of an @catch or @finally.  We don't want to consume the @ token if this
1313     // is an @try or @encode or something else.
1314     Token AfterAt = GetLookAheadToken(1);
1315     if (!AfterAt.isObjCAtKeyword(tok::objc_catch) &&
1316         !AfterAt.isObjCAtKeyword(tok::objc_finally))
1317       break;
1318 
1319     SourceLocation AtCatchFinallyLoc = ConsumeToken();
1320     if (Tok.isObjCAtKeyword(tok::objc_catch)) {
1321       DeclPtrTy FirstPart;
1322       ConsumeToken(); // consume catch
1323       if (Tok.is(tok::l_paren)) {
1324         ConsumeParen();
1325         ParseScope CatchScope(this, Scope::DeclScope|Scope::AtCatchScope);
1326         if (Tok.isNot(tok::ellipsis)) {
1327           DeclSpec DS;
1328           ParseDeclarationSpecifiers(DS);
1329           // For some odd reason, the name of the exception variable is
1330           // optional. As a result, we need to use "PrototypeContext", because
1331           // we must accept either 'declarator' or 'abstract-declarator' here.
1332           Declarator ParmDecl(DS, Declarator::PrototypeContext);
1333           ParseDeclarator(ParmDecl);
1334 
1335           // Inform the actions module about the parameter declarator, so it
1336           // gets added to the current scope.
1337           FirstPart = Actions.ActOnParamDeclarator(CurScope, ParmDecl);
1338         } else
1339           ConsumeToken(); // consume '...'
1340 
1341         SourceLocation RParenLoc;
1342 
1343         if (Tok.is(tok::r_paren))
1344           RParenLoc = ConsumeParen();
1345         else // Skip over garbage, until we get to ')'.  Eat the ')'.
1346           SkipUntil(tok::r_paren, true, false);
1347 
1348         OwningStmtResult CatchBody(Actions, true);
1349         if (Tok.is(tok::l_brace))
1350           CatchBody = ParseCompoundStatementBody();
1351         else
1352           Diag(Tok, diag::err_expected_lbrace);
1353         if (CatchBody.isInvalid())
1354           CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
1355         CatchStmts = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc,
1356                         RParenLoc, FirstPart, move(CatchBody),
1357                         move(CatchStmts));
1358       } else {
1359         Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
1360           << "@catch clause";
1361         return StmtError();
1362       }
1363       catch_or_finally_seen = true;
1364     } else {
1365       assert(Tok.isObjCAtKeyword(tok::objc_finally) && "Lookahead confused?");
1366       ConsumeToken(); // consume finally
1367       ParseScope FinallyScope(this, Scope::DeclScope);
1368 
1369       OwningStmtResult FinallyBody(Actions, true);
1370       if (Tok.is(tok::l_brace))
1371         FinallyBody = ParseCompoundStatementBody();
1372       else
1373         Diag(Tok, diag::err_expected_lbrace);
1374       if (FinallyBody.isInvalid())
1375         FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
1376       FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
1377                                                    move(FinallyBody));
1378       catch_or_finally_seen = true;
1379       break;
1380     }
1381   }
1382   if (!catch_or_finally_seen) {
1383     Diag(atLoc, diag::err_missing_catch_finally);
1384     return StmtError();
1385   }
1386   return Actions.ActOnObjCAtTryStmt(atLoc, move(TryBody), move(CatchStmts),
1387                                     move(FinallyStmt));
1388 }
1389 
1390 ///   objc-method-def: objc-method-proto ';'[opt] '{' body '}'
1391 ///
1392 Parser::DeclPtrTy Parser::ParseObjCMethodDefinition() {
1393   DeclPtrTy MDecl = ParseObjCMethodPrototype(ObjCImpDecl);
1394 
1395   PrettyStackTraceActionsDecl CrashInfo(MDecl, Tok.getLocation(), Actions,
1396                                         PP.getSourceManager(),
1397                                         "parsing Objective-C method");
1398 
1399   // parse optional ';'
1400   if (Tok.is(tok::semi)) {
1401     if (ObjCImpDecl)
1402       Diag(Tok, diag::warn_semicolon_before_method_nody);
1403     ConsumeToken();
1404   }
1405 
1406   // We should have an opening brace now.
1407   if (Tok.isNot(tok::l_brace)) {
1408     Diag(Tok, diag::err_expected_method_body);
1409 
1410     // Skip over garbage, until we get to '{'.  Don't eat the '{'.
1411     SkipUntil(tok::l_brace, true, true);
1412 
1413     // If we didn't find the '{', bail out.
1414     if (Tok.isNot(tok::l_brace))
1415       return DeclPtrTy();
1416   }
1417   SourceLocation BraceLoc = Tok.getLocation();
1418 
1419   // Enter a scope for the method body.
1420   ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope);
1421 
1422   // Tell the actions module that we have entered a method definition with the
1423   // specified Declarator for the method.
1424   Actions.ActOnStartOfObjCMethodDef(CurScope, MDecl);
1425 
1426   OwningStmtResult FnBody(ParseCompoundStatementBody());
1427 
1428   // If the function body could not be parsed, make a bogus compoundstmt.
1429   if (FnBody.isInvalid())
1430     FnBody = Actions.ActOnCompoundStmt(BraceLoc, BraceLoc,
1431                                        MultiStmtArg(Actions), false);
1432 
1433   // TODO: Pass argument information.
1434   Actions.ActOnFinishFunctionBody(MDecl, move(FnBody));
1435 
1436   // Leave the function body scope.
1437   BodyScope.Exit();
1438 
1439   return MDecl;
1440 }
1441 
1442 Parser::OwningStmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) {
1443   if (Tok.isObjCAtKeyword(tok::objc_try)) {
1444     return ParseObjCTryStmt(AtLoc);
1445   } else if (Tok.isObjCAtKeyword(tok::objc_throw))
1446     return ParseObjCThrowStmt(AtLoc);
1447   else if (Tok.isObjCAtKeyword(tok::objc_synchronized))
1448     return ParseObjCSynchronizedStmt(AtLoc);
1449   OwningExprResult Res(ParseExpressionWithLeadingAt(AtLoc));
1450   if (Res.isInvalid()) {
1451     // If the expression is invalid, skip ahead to the next semicolon. Not
1452     // doing this opens us up to the possibility of infinite loops if
1453     // ParseExpression does not consume any tokens.
1454     SkipUntil(tok::semi);
1455     return StmtError();
1456   }
1457   // Otherwise, eat the semicolon.
1458   ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
1459   return Actions.ActOnExprStmt(Actions.FullExpr(Res));
1460 }
1461 
1462 Parser::OwningExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
1463   switch (Tok.getKind()) {
1464   case tok::string_literal:    // primary-expression: string-literal
1465   case tok::wide_string_literal:
1466     return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
1467   default:
1468     if (Tok.getIdentifierInfo() == 0)
1469       return ExprError(Diag(AtLoc, diag::err_unexpected_at));
1470 
1471     switch (Tok.getIdentifierInfo()->getObjCKeywordID()) {
1472     case tok::objc_encode:
1473       return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc));
1474     case tok::objc_protocol:
1475       return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc));
1476     case tok::objc_selector:
1477       return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc));
1478     default:
1479       return ExprError(Diag(AtLoc, diag::err_unexpected_at));
1480     }
1481   }
1482 }
1483 
1484 ///   objc-message-expr:
1485 ///     '[' objc-receiver objc-message-args ']'
1486 ///
1487 ///   objc-receiver:
1488 ///     expression
1489 ///     class-name
1490 ///     type-name
1491 Parser::OwningExprResult Parser::ParseObjCMessageExpression() {
1492   assert(Tok.is(tok::l_square) && "'[' expected");
1493   SourceLocation LBracLoc = ConsumeBracket(); // consume '['
1494 
1495   // Parse receiver
1496   if (isTokObjCMessageIdentifierReceiver()) {
1497     IdentifierInfo *ReceiverName = Tok.getIdentifierInfo();
1498     if (ReceiverName != Ident_super || GetLookAheadToken(1).isNot(tok::period)) {
1499       SourceLocation NameLoc = ConsumeToken();
1500       return ParseObjCMessageExpressionBody(LBracLoc, NameLoc, ReceiverName,
1501                                             ExprArg(Actions));
1502     }
1503   }
1504 
1505   OwningExprResult Res(ParseExpression());
1506   if (Res.isInvalid()) {
1507     SkipUntil(tok::r_square);
1508     return move(Res);
1509   }
1510 
1511   return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
1512                                         0, move(Res));
1513 }
1514 
1515 /// ParseObjCMessageExpressionBody - Having parsed "'[' objc-receiver", parse
1516 /// the rest of a message expression.
1517 ///
1518 ///   objc-message-args:
1519 ///     objc-selector
1520 ///     objc-keywordarg-list
1521 ///
1522 ///   objc-keywordarg-list:
1523 ///     objc-keywordarg
1524 ///     objc-keywordarg-list objc-keywordarg
1525 ///
1526 ///   objc-keywordarg:
1527 ///     selector-name[opt] ':' objc-keywordexpr
1528 ///
1529 ///   objc-keywordexpr:
1530 ///     nonempty-expr-list
1531 ///
1532 ///   nonempty-expr-list:
1533 ///     assignment-expression
1534 ///     nonempty-expr-list , assignment-expression
1535 ///
1536 Parser::OwningExprResult
1537 Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
1538                                        SourceLocation NameLoc,
1539                                        IdentifierInfo *ReceiverName,
1540                                        ExprArg ReceiverExpr) {
1541   // Parse objc-selector
1542   SourceLocation Loc;
1543   IdentifierInfo *selIdent = ParseObjCSelectorPiece(Loc);
1544 
1545   SourceLocation SelectorLoc = Loc;
1546 
1547   llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
1548   ExprVector KeyExprs(Actions);
1549 
1550   if (Tok.is(tok::colon)) {
1551     while (1) {
1552       // Each iteration parses a single keyword argument.
1553       KeyIdents.push_back(selIdent);
1554 
1555       if (Tok.isNot(tok::colon)) {
1556         Diag(Tok, diag::err_expected_colon);
1557         // We must manually skip to a ']', otherwise the expression skipper will
1558         // stop at the ']' when it skips to the ';'.  We want it to skip beyond
1559         // the enclosing expression.
1560         SkipUntil(tok::r_square);
1561         return ExprError();
1562       }
1563 
1564       ConsumeToken(); // Eat the ':'.
1565       ///  Parse the expression after ':'
1566       OwningExprResult Res(ParseAssignmentExpression());
1567       if (Res.isInvalid()) {
1568         // We must manually skip to a ']', otherwise the expression skipper will
1569         // stop at the ']' when it skips to the ';'.  We want it to skip beyond
1570         // the enclosing expression.
1571         SkipUntil(tok::r_square);
1572         return move(Res);
1573       }
1574 
1575       // We have a valid expression.
1576       KeyExprs.push_back(Res.release());
1577 
1578       // Check for another keyword selector.
1579       selIdent = ParseObjCSelectorPiece(Loc);
1580       if (!selIdent && Tok.isNot(tok::colon))
1581         break;
1582       // We have a selector or a colon, continue parsing.
1583     }
1584     // Parse the, optional, argument list, comma separated.
1585     while (Tok.is(tok::comma)) {
1586       ConsumeToken(); // Eat the ','.
1587       ///  Parse the expression after ','
1588       OwningExprResult Res(ParseAssignmentExpression());
1589       if (Res.isInvalid()) {
1590         // We must manually skip to a ']', otherwise the expression skipper will
1591         // stop at the ']' when it skips to the ';'.  We want it to skip beyond
1592         // the enclosing expression.
1593         SkipUntil(tok::r_square);
1594         return move(Res);
1595       }
1596 
1597       // We have a valid expression.
1598       KeyExprs.push_back(Res.release());
1599     }
1600   } else if (!selIdent) {
1601     Diag(Tok, diag::err_expected_ident); // missing selector name.
1602 
1603     // We must manually skip to a ']', otherwise the expression skipper will
1604     // stop at the ']' when it skips to the ';'.  We want it to skip beyond
1605     // the enclosing expression.
1606     SkipUntil(tok::r_square);
1607     return ExprError();
1608   }
1609 
1610   if (Tok.isNot(tok::r_square)) {
1611     Diag(Tok, diag::err_expected_rsquare);
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   SourceLocation RBracLoc = ConsumeBracket(); // consume ']'
1620 
1621   unsigned nKeys = KeyIdents.size();
1622   if (nKeys == 0)
1623     KeyIdents.push_back(selIdent);
1624   Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]);
1625 
1626   // We've just parsed a keyword message.
1627   if (ReceiverName)
1628     return Owned(Actions.ActOnClassMessage(CurScope, ReceiverName, Sel,
1629                                            LBracLoc, NameLoc, SelectorLoc,
1630                                            RBracLoc,
1631                                            KeyExprs.take(), KeyExprs.size()));
1632   return Owned(Actions.ActOnInstanceMessage(ReceiverExpr.release(), Sel,
1633                                             LBracLoc, SelectorLoc, RBracLoc,
1634                                             KeyExprs.take(), KeyExprs.size()));
1635 }
1636 
1637 Parser::OwningExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
1638   OwningExprResult Res(ParseStringLiteralExpression());
1639   if (Res.isInvalid()) return move(Res);
1640 
1641   // @"foo" @"bar" is a valid concatenated string.  Eat any subsequent string
1642   // expressions.  At this point, we know that the only valid thing that starts
1643   // with '@' is an @"".
1644   llvm::SmallVector<SourceLocation, 4> AtLocs;
1645   ExprVector AtStrings(Actions);
1646   AtLocs.push_back(AtLoc);
1647   AtStrings.push_back(Res.release());
1648 
1649   while (Tok.is(tok::at)) {
1650     AtLocs.push_back(ConsumeToken()); // eat the @.
1651 
1652     // Invalid unless there is a string literal.
1653     if (!isTokenStringLiteral())
1654       return ExprError(Diag(Tok, diag::err_objc_concat_string));
1655 
1656     OwningExprResult Lit(ParseStringLiteralExpression());
1657     if (Lit.isInvalid())
1658       return move(Lit);
1659 
1660     AtStrings.push_back(Lit.release());
1661   }
1662 
1663   return Owned(Actions.ParseObjCStringLiteral(&AtLocs[0], AtStrings.take(),
1664                                               AtStrings.size()));
1665 }
1666 
1667 ///    objc-encode-expression:
1668 ///      @encode ( type-name )
1669 Parser::OwningExprResult
1670 Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) {
1671   assert(Tok.isObjCAtKeyword(tok::objc_encode) && "Not an @encode expression!");
1672 
1673   SourceLocation EncLoc = ConsumeToken();
1674 
1675   if (Tok.isNot(tok::l_paren))
1676     return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@encode");
1677 
1678   SourceLocation LParenLoc = ConsumeParen();
1679 
1680   TypeResult Ty = ParseTypeName();
1681 
1682   SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
1683 
1684   if (Ty.isInvalid())
1685     return ExprError();
1686 
1687   return Owned(Actions.ParseObjCEncodeExpression(AtLoc, EncLoc, LParenLoc,
1688                                                  Ty.get(), RParenLoc));
1689 }
1690 
1691 ///     objc-protocol-expression
1692 ///       @protocol ( protocol-name )
1693 Parser::OwningExprResult
1694 Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) {
1695   SourceLocation ProtoLoc = ConsumeToken();
1696 
1697   if (Tok.isNot(tok::l_paren))
1698     return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@protocol");
1699 
1700   SourceLocation LParenLoc = ConsumeParen();
1701 
1702   if (Tok.isNot(tok::identifier))
1703     return ExprError(Diag(Tok, diag::err_expected_ident));
1704 
1705   IdentifierInfo *protocolId = Tok.getIdentifierInfo();
1706   ConsumeToken();
1707 
1708   SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
1709 
1710   return Owned(Actions.ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc,
1711                                                    LParenLoc, RParenLoc));
1712 }
1713 
1714 ///     objc-selector-expression
1715 ///       @selector '(' objc-keyword-selector ')'
1716 Parser::OwningExprResult
1717 Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) {
1718   SourceLocation SelectorLoc = ConsumeToken();
1719 
1720   if (Tok.isNot(tok::l_paren))
1721     return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@selector");
1722 
1723   llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
1724   SourceLocation LParenLoc = ConsumeParen();
1725   SourceLocation sLoc;
1726   IdentifierInfo *SelIdent = ParseObjCSelectorPiece(sLoc);
1727   if (!SelIdent && Tok.isNot(tok::colon)) // missing selector name.
1728     return ExprError(Diag(Tok, diag::err_expected_ident));
1729 
1730   KeyIdents.push_back(SelIdent);
1731   unsigned nColons = 0;
1732   if (Tok.isNot(tok::r_paren)) {
1733     while (1) {
1734       if (Tok.isNot(tok::colon))
1735         return ExprError(Diag(Tok, diag::err_expected_colon));
1736 
1737       nColons++;
1738       ConsumeToken(); // Eat the ':'.
1739       if (Tok.is(tok::r_paren))
1740         break;
1741       // Check for another keyword selector.
1742       SourceLocation Loc;
1743       SelIdent = ParseObjCSelectorPiece(Loc);
1744       KeyIdents.push_back(SelIdent);
1745       if (!SelIdent && Tok.isNot(tok::colon))
1746         break;
1747     }
1748   }
1749   SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
1750   Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]);
1751   return Owned(Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc,
1752                                                    LParenLoc, RParenLoc));
1753  }
1754