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