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