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