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 "RAIIObjectsForParser.h"
16 #include "clang/AST/ASTContext.h"
17 #include "clang/Basic/CharInfo.h"
18 #include "clang/Parse/ParseDiagnostic.h"
19 #include "clang/Sema/DeclSpec.h"
20 #include "clang/Sema/PrettyDeclStackTrace.h"
21 #include "clang/Sema/Scope.h"
22 #include "llvm/ADT/SmallVector.h"
23 #include "llvm/ADT/StringExtras.h"
24
25 using namespace clang;
26
27 /// Skips attributes after an Objective-C @ directive. Emits a diagnostic.
MaybeSkipAttributes(tok::ObjCKeywordKind Kind)28 void Parser::MaybeSkipAttributes(tok::ObjCKeywordKind Kind) {
29 ParsedAttributes attrs(AttrFactory);
30 if (Tok.is(tok::kw___attribute)) {
31 if (Kind == tok::objc_interface || Kind == tok::objc_protocol)
32 Diag(Tok, diag::err_objc_postfix_attribute_hint)
33 << (Kind == tok::objc_protocol);
34 else
35 Diag(Tok, diag::err_objc_postfix_attribute);
36 ParseGNUAttributes(attrs);
37 }
38 }
39
40 /// ParseObjCAtDirectives - Handle parts of the external-declaration production:
41 /// external-declaration: [C99 6.9]
42 /// [OBJC] objc-class-definition
43 /// [OBJC] objc-class-declaration
44 /// [OBJC] objc-alias-declaration
45 /// [OBJC] objc-protocol-definition
46 /// [OBJC] objc-method-definition
47 /// [OBJC] '@' 'end'
ParseObjCAtDirectives()48 Parser::DeclGroupPtrTy Parser::ParseObjCAtDirectives() {
49 SourceLocation AtLoc = ConsumeToken(); // the "@"
50
51 if (Tok.is(tok::code_completion)) {
52 Actions.CodeCompleteObjCAtDirective(getCurScope());
53 cutOffParsing();
54 return nullptr;
55 }
56
57 Decl *SingleDecl = nullptr;
58 switch (Tok.getObjCKeywordID()) {
59 case tok::objc_class:
60 return ParseObjCAtClassDeclaration(AtLoc);
61 case tok::objc_interface: {
62 ParsedAttributes attrs(AttrFactory);
63 SingleDecl = ParseObjCAtInterfaceDeclaration(AtLoc, attrs);
64 break;
65 }
66 case tok::objc_protocol: {
67 ParsedAttributes attrs(AttrFactory);
68 return ParseObjCAtProtocolDeclaration(AtLoc, attrs);
69 }
70 case tok::objc_implementation:
71 return ParseObjCAtImplementationDeclaration(AtLoc);
72 case tok::objc_end:
73 return ParseObjCAtEndDeclaration(AtLoc);
74 case tok::objc_compatibility_alias:
75 SingleDecl = ParseObjCAtAliasDeclaration(AtLoc);
76 break;
77 case tok::objc_synthesize:
78 SingleDecl = ParseObjCPropertySynthesize(AtLoc);
79 break;
80 case tok::objc_dynamic:
81 SingleDecl = ParseObjCPropertyDynamic(AtLoc);
82 break;
83 case tok::objc_import:
84 if (getLangOpts().Modules || getLangOpts().DebuggerSupport)
85 return ParseModuleImport(AtLoc);
86 Diag(AtLoc, diag::err_atimport);
87 SkipUntil(tok::semi);
88 return Actions.ConvertDeclToDeclGroup(nullptr);
89 default:
90 Diag(AtLoc, diag::err_unexpected_at);
91 SkipUntil(tok::semi);
92 SingleDecl = nullptr;
93 break;
94 }
95 return Actions.ConvertDeclToDeclGroup(SingleDecl);
96 }
97
98 /// Class to handle popping type parameters when leaving the scope.
99 class Parser::ObjCTypeParamListScope {
100 Sema &Actions;
101 Scope *S;
102 ObjCTypeParamList *Params;
103
104 public:
ObjCTypeParamListScope(Sema & Actions,Scope * S)105 ObjCTypeParamListScope(Sema &Actions, Scope *S)
106 : Actions(Actions), S(S), Params(nullptr) {}
107
~ObjCTypeParamListScope()108 ~ObjCTypeParamListScope() {
109 leave();
110 }
111
enter(ObjCTypeParamList * P)112 void enter(ObjCTypeParamList *P) {
113 assert(!Params);
114 Params = P;
115 }
116
leave()117 void leave() {
118 if (Params)
119 Actions.popObjCTypeParamList(S, Params);
120 Params = nullptr;
121 }
122 };
123
124 ///
125 /// objc-class-declaration:
126 /// '@' 'class' objc-class-forward-decl (',' objc-class-forward-decl)* ';'
127 ///
128 /// objc-class-forward-decl:
129 /// identifier objc-type-parameter-list[opt]
130 ///
131 Parser::DeclGroupPtrTy
ParseObjCAtClassDeclaration(SourceLocation atLoc)132 Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) {
133 ConsumeToken(); // the identifier "class"
134 SmallVector<IdentifierInfo *, 8> ClassNames;
135 SmallVector<SourceLocation, 8> ClassLocs;
136 SmallVector<ObjCTypeParamList *, 8> ClassTypeParams;
137
138 while (1) {
139 MaybeSkipAttributes(tok::objc_class);
140 if (Tok.isNot(tok::identifier)) {
141 Diag(Tok, diag::err_expected) << tok::identifier;
142 SkipUntil(tok::semi);
143 return Actions.ConvertDeclToDeclGroup(nullptr);
144 }
145 ClassNames.push_back(Tok.getIdentifierInfo());
146 ClassLocs.push_back(Tok.getLocation());
147 ConsumeToken();
148
149 // Parse the optional objc-type-parameter-list.
150 ObjCTypeParamList *TypeParams = nullptr;
151 if (Tok.is(tok::less))
152 TypeParams = parseObjCTypeParamList();
153 ClassTypeParams.push_back(TypeParams);
154 if (!TryConsumeToken(tok::comma))
155 break;
156 }
157
158 // Consume the ';'.
159 if (ExpectAndConsume(tok::semi, diag::err_expected_after, "@class"))
160 return Actions.ConvertDeclToDeclGroup(nullptr);
161
162 return Actions.ActOnForwardClassDeclaration(atLoc, ClassNames.data(),
163 ClassLocs.data(),
164 ClassTypeParams,
165 ClassNames.size());
166 }
167
CheckNestedObjCContexts(SourceLocation AtLoc)168 void Parser::CheckNestedObjCContexts(SourceLocation AtLoc)
169 {
170 Sema::ObjCContainerKind ock = Actions.getObjCContainerKind();
171 if (ock == Sema::OCK_None)
172 return;
173
174 Decl *Decl = Actions.getObjCDeclContext();
175 if (CurParsedObjCImpl) {
176 CurParsedObjCImpl->finish(AtLoc);
177 } else {
178 Actions.ActOnAtEnd(getCurScope(), AtLoc);
179 }
180 Diag(AtLoc, diag::err_objc_missing_end)
181 << FixItHint::CreateInsertion(AtLoc, "@end\n");
182 if (Decl)
183 Diag(Decl->getLocStart(), diag::note_objc_container_start)
184 << (int) ock;
185 }
186
187 ///
188 /// objc-interface:
189 /// objc-class-interface-attributes[opt] objc-class-interface
190 /// objc-category-interface
191 ///
192 /// objc-class-interface:
193 /// '@' 'interface' identifier objc-type-parameter-list[opt]
194 /// objc-superclass[opt] objc-protocol-refs[opt]
195 /// objc-class-instance-variables[opt]
196 /// objc-interface-decl-list
197 /// @end
198 ///
199 /// objc-category-interface:
200 /// '@' 'interface' identifier objc-type-parameter-list[opt]
201 /// '(' identifier[opt] ')' objc-protocol-refs[opt]
202 /// objc-interface-decl-list
203 /// @end
204 ///
205 /// objc-superclass:
206 /// ':' identifier objc-type-arguments[opt]
207 ///
208 /// objc-class-interface-attributes:
209 /// __attribute__((visibility("default")))
210 /// __attribute__((visibility("hidden")))
211 /// __attribute__((deprecated))
212 /// __attribute__((unavailable))
213 /// __attribute__((objc_exception)) - used by NSException on 64-bit
214 /// __attribute__((objc_root_class))
215 ///
ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,ParsedAttributes & attrs)216 Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
217 ParsedAttributes &attrs) {
218 assert(Tok.isObjCAtKeyword(tok::objc_interface) &&
219 "ParseObjCAtInterfaceDeclaration(): Expected @interface");
220 CheckNestedObjCContexts(AtLoc);
221 ConsumeToken(); // the "interface" identifier
222
223 // Code completion after '@interface'.
224 if (Tok.is(tok::code_completion)) {
225 Actions.CodeCompleteObjCInterfaceDecl(getCurScope());
226 cutOffParsing();
227 return nullptr;
228 }
229
230 MaybeSkipAttributes(tok::objc_interface);
231
232 if (Tok.isNot(tok::identifier)) {
233 Diag(Tok, diag::err_expected)
234 << tok::identifier; // missing class or category name.
235 return nullptr;
236 }
237
238 // We have a class or category name - consume it.
239 IdentifierInfo *nameId = Tok.getIdentifierInfo();
240 SourceLocation nameLoc = ConsumeToken();
241
242 // Parse the objc-type-parameter-list or objc-protocol-refs. For the latter
243 // case, LAngleLoc will be valid and ProtocolIdents will capture the
244 // protocol references (that have not yet been resolved).
245 SourceLocation LAngleLoc, EndProtoLoc;
246 SmallVector<IdentifierLocPair, 8> ProtocolIdents;
247 ObjCTypeParamList *typeParameterList = nullptr;
248 ObjCTypeParamListScope typeParamScope(Actions, getCurScope());
249 if (Tok.is(tok::less))
250 typeParameterList = parseObjCTypeParamListOrProtocolRefs(
251 typeParamScope, LAngleLoc, ProtocolIdents, EndProtoLoc);
252
253 if (Tok.is(tok::l_paren) &&
254 !isKnownToBeTypeSpecifier(GetLookAheadToken(1))) { // we have a category.
255
256 BalancedDelimiterTracker T(*this, tok::l_paren);
257 T.consumeOpen();
258
259 SourceLocation categoryLoc;
260 IdentifierInfo *categoryId = nullptr;
261 if (Tok.is(tok::code_completion)) {
262 Actions.CodeCompleteObjCInterfaceCategory(getCurScope(), nameId, nameLoc);
263 cutOffParsing();
264 return nullptr;
265 }
266
267 // For ObjC2, the category name is optional (not an error).
268 if (Tok.is(tok::identifier)) {
269 categoryId = Tok.getIdentifierInfo();
270 categoryLoc = ConsumeToken();
271 }
272 else if (!getLangOpts().ObjC2) {
273 Diag(Tok, diag::err_expected)
274 << tok::identifier; // missing category name.
275 return nullptr;
276 }
277
278 T.consumeClose();
279 if (T.getCloseLocation().isInvalid())
280 return nullptr;
281
282 if (!attrs.empty()) { // categories don't support attributes.
283 Diag(nameLoc, diag::err_objc_no_attributes_on_category);
284 attrs.clear();
285 }
286
287 // Next, we need to check for any protocol references.
288 assert(LAngleLoc.isInvalid() && "Cannot have already parsed protocols");
289 SmallVector<Decl *, 8> ProtocolRefs;
290 SmallVector<SourceLocation, 8> ProtocolLocs;
291 if (Tok.is(tok::less) &&
292 ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true, true,
293 LAngleLoc, EndProtoLoc,
294 /*consumeLastToken=*/true))
295 return nullptr;
296
297 Decl *CategoryType =
298 Actions.ActOnStartCategoryInterface(AtLoc,
299 nameId, nameLoc,
300 typeParameterList,
301 categoryId, categoryLoc,
302 ProtocolRefs.data(),
303 ProtocolRefs.size(),
304 ProtocolLocs.data(),
305 EndProtoLoc);
306
307 if (Tok.is(tok::l_brace))
308 ParseObjCClassInstanceVariables(CategoryType, tok::objc_private, AtLoc);
309
310 ParseObjCInterfaceDeclList(tok::objc_not_keyword, CategoryType);
311
312 return CategoryType;
313 }
314 // Parse a class interface.
315 IdentifierInfo *superClassId = nullptr;
316 SourceLocation superClassLoc;
317 SourceLocation typeArgsLAngleLoc;
318 SmallVector<ParsedType, 4> typeArgs;
319 SourceLocation typeArgsRAngleLoc;
320 SmallVector<Decl *, 4> protocols;
321 SmallVector<SourceLocation, 4> protocolLocs;
322 if (Tok.is(tok::colon)) { // a super class is specified.
323 ConsumeToken();
324
325 // Code completion of superclass names.
326 if (Tok.is(tok::code_completion)) {
327 Actions.CodeCompleteObjCSuperclass(getCurScope(), nameId, nameLoc);
328 cutOffParsing();
329 return nullptr;
330 }
331
332 if (Tok.isNot(tok::identifier)) {
333 Diag(Tok, diag::err_expected)
334 << tok::identifier; // missing super class name.
335 return nullptr;
336 }
337 superClassId = Tok.getIdentifierInfo();
338 superClassLoc = ConsumeToken();
339
340 // Type arguments for the superclass or protocol conformances.
341 if (Tok.is(tok::less)) {
342 parseObjCTypeArgsOrProtocolQualifiers(
343 nullptr, typeArgsLAngleLoc, typeArgs, typeArgsRAngleLoc, LAngleLoc,
344 protocols, protocolLocs, EndProtoLoc,
345 /*consumeLastToken=*/true,
346 /*warnOnIncompleteProtocols=*/true);
347 }
348 }
349
350 // Next, we need to check for any protocol references.
351 if (LAngleLoc.isValid()) {
352 if (!ProtocolIdents.empty()) {
353 // We already parsed the protocols named when we thought we had a
354 // type parameter list. Translate them into actual protocol references.
355 for (const auto &pair : ProtocolIdents) {
356 protocolLocs.push_back(pair.second);
357 }
358 Actions.FindProtocolDeclaration(/*WarnOnDeclarations=*/true,
359 /*ForObjCContainer=*/true,
360 ProtocolIdents, protocols);
361 }
362 } else if (protocols.empty() && Tok.is(tok::less) &&
363 ParseObjCProtocolReferences(protocols, protocolLocs, true, true,
364 LAngleLoc, EndProtoLoc,
365 /*consumeLastToken=*/true)) {
366 return nullptr;
367 }
368
369 if (Tok.isNot(tok::less))
370 Actions.ActOnTypedefedProtocols(protocols, superClassId, superClassLoc);
371
372 Decl *ClsType =
373 Actions.ActOnStartClassInterface(getCurScope(), AtLoc, nameId, nameLoc,
374 typeParameterList, superClassId,
375 superClassLoc,
376 typeArgs,
377 SourceRange(typeArgsLAngleLoc,
378 typeArgsRAngleLoc),
379 protocols.data(), protocols.size(),
380 protocolLocs.data(),
381 EndProtoLoc, attrs.getList());
382
383 if (Tok.is(tok::l_brace))
384 ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, AtLoc);
385
386 ParseObjCInterfaceDeclList(tok::objc_interface, ClsType);
387
388 return ClsType;
389 }
390
391 /// Add an attribute for a context-sensitive type nullability to the given
392 /// declarator.
addContextSensitiveTypeNullability(Parser & P,Declarator & D,NullabilityKind nullability,SourceLocation nullabilityLoc,bool & addedToDeclSpec)393 static void addContextSensitiveTypeNullability(Parser &P,
394 Declarator &D,
395 NullabilityKind nullability,
396 SourceLocation nullabilityLoc,
397 bool &addedToDeclSpec) {
398 // Create the attribute.
399 auto getNullabilityAttr = [&]() -> AttributeList * {
400 return D.getAttributePool().create(
401 P.getNullabilityKeyword(nullability),
402 SourceRange(nullabilityLoc),
403 nullptr, SourceLocation(),
404 nullptr, 0,
405 AttributeList::AS_ContextSensitiveKeyword);
406 };
407
408 if (D.getNumTypeObjects() > 0) {
409 // Add the attribute to the declarator chunk nearest the declarator.
410 auto nullabilityAttr = getNullabilityAttr();
411 DeclaratorChunk &chunk = D.getTypeObject(0);
412 nullabilityAttr->setNext(chunk.getAttrListRef());
413 chunk.getAttrListRef() = nullabilityAttr;
414 } else if (!addedToDeclSpec) {
415 // Otherwise, just put it on the declaration specifiers (if one
416 // isn't there already).
417 D.getMutableDeclSpec().addAttributes(getNullabilityAttr());
418 addedToDeclSpec = true;
419 }
420 }
421
422 /// Parse an Objective-C type parameter list, if present, or capture
423 /// the locations of the protocol identifiers for a list of protocol
424 /// references.
425 ///
426 /// objc-type-parameter-list:
427 /// '<' objc-type-parameter (',' objc-type-parameter)* '>'
428 ///
429 /// objc-type-parameter:
430 /// objc-type-parameter-variance? identifier objc-type-parameter-bound[opt]
431 ///
432 /// objc-type-parameter-bound:
433 /// ':' type-name
434 ///
435 /// objc-type-parameter-variance:
436 /// '__covariant'
437 /// '__contravariant'
438 ///
439 /// \param lAngleLoc The location of the starting '<'.
440 ///
441 /// \param protocolIdents Will capture the list of identifiers, if the
442 /// angle brackets contain a list of protocol references rather than a
443 /// type parameter list.
444 ///
445 /// \param rAngleLoc The location of the ending '>'.
parseObjCTypeParamListOrProtocolRefs(ObjCTypeParamListScope & Scope,SourceLocation & lAngleLoc,SmallVectorImpl<IdentifierLocPair> & protocolIdents,SourceLocation & rAngleLoc,bool mayBeProtocolList)446 ObjCTypeParamList *Parser::parseObjCTypeParamListOrProtocolRefs(
447 ObjCTypeParamListScope &Scope, SourceLocation &lAngleLoc,
448 SmallVectorImpl<IdentifierLocPair> &protocolIdents,
449 SourceLocation &rAngleLoc, bool mayBeProtocolList) {
450 assert(Tok.is(tok::less) && "Not at the beginning of a type parameter list");
451
452 // Within the type parameter list, don't treat '>' as an operator.
453 GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);
454
455 // Local function to "flush" the protocol identifiers, turning them into
456 // type parameters.
457 SmallVector<Decl *, 4> typeParams;
458 auto makeProtocolIdentsIntoTypeParameters = [&]() {
459 unsigned index = 0;
460 for (const auto &pair : protocolIdents) {
461 DeclResult typeParam = Actions.actOnObjCTypeParam(
462 getCurScope(), ObjCTypeParamVariance::Invariant, SourceLocation(),
463 index++, pair.first, pair.second, SourceLocation(), nullptr);
464 if (typeParam.isUsable())
465 typeParams.push_back(typeParam.get());
466 }
467
468 protocolIdents.clear();
469 mayBeProtocolList = false;
470 };
471
472 bool invalid = false;
473 lAngleLoc = ConsumeToken();
474
475 do {
476 // Parse the variance, if any.
477 SourceLocation varianceLoc;
478 ObjCTypeParamVariance variance = ObjCTypeParamVariance::Invariant;
479 if (Tok.is(tok::kw___covariant) || Tok.is(tok::kw___contravariant)) {
480 variance = Tok.is(tok::kw___covariant)
481 ? ObjCTypeParamVariance::Covariant
482 : ObjCTypeParamVariance::Contravariant;
483 varianceLoc = ConsumeToken();
484
485 // Once we've seen a variance specific , we know this is not a
486 // list of protocol references.
487 if (mayBeProtocolList) {
488 // Up until now, we have been queuing up parameters because they
489 // might be protocol references. Turn them into parameters now.
490 makeProtocolIdentsIntoTypeParameters();
491 }
492 }
493
494 // Parse the identifier.
495 if (!Tok.is(tok::identifier)) {
496 // Code completion.
497 if (Tok.is(tok::code_completion)) {
498 // FIXME: If these aren't protocol references, we'll need different
499 // completions.
500 Actions.CodeCompleteObjCProtocolReferences(protocolIdents);
501 cutOffParsing();
502
503 // FIXME: Better recovery here?.
504 return nullptr;
505 }
506
507 Diag(Tok, diag::err_objc_expected_type_parameter);
508 invalid = true;
509 break;
510 }
511
512 IdentifierInfo *paramName = Tok.getIdentifierInfo();
513 SourceLocation paramLoc = ConsumeToken();
514
515 // If there is a bound, parse it.
516 SourceLocation colonLoc;
517 TypeResult boundType;
518 if (TryConsumeToken(tok::colon, colonLoc)) {
519 // Once we've seen a bound, we know this is not a list of protocol
520 // references.
521 if (mayBeProtocolList) {
522 // Up until now, we have been queuing up parameters because they
523 // might be protocol references. Turn them into parameters now.
524 makeProtocolIdentsIntoTypeParameters();
525 }
526
527 // type-name
528 boundType = ParseTypeName();
529 if (boundType.isInvalid())
530 invalid = true;
531 } else if (mayBeProtocolList) {
532 // If this could still be a protocol list, just capture the identifier.
533 // We don't want to turn it into a parameter.
534 protocolIdents.push_back(std::make_pair(paramName, paramLoc));
535 continue;
536 }
537
538 // Create the type parameter.
539 DeclResult typeParam = Actions.actOnObjCTypeParam(
540 getCurScope(), variance, varianceLoc, typeParams.size(), paramName,
541 paramLoc, colonLoc, boundType.isUsable() ? boundType.get() : nullptr);
542 if (typeParam.isUsable())
543 typeParams.push_back(typeParam.get());
544 } while (TryConsumeToken(tok::comma));
545
546 // Parse the '>'.
547 if (invalid) {
548 SkipUntil(tok::greater, tok::at, StopBeforeMatch);
549 if (Tok.is(tok::greater))
550 ConsumeToken();
551 } else if (ParseGreaterThanInTemplateList(rAngleLoc,
552 /*ConsumeLastToken=*/true,
553 /*ObjCGenericList=*/true)) {
554 Diag(lAngleLoc, diag::note_matching) << "'<'";
555 SkipUntil({tok::greater, tok::greaterequal, tok::at, tok::minus,
556 tok::minus, tok::plus, tok::colon, tok::l_paren, tok::l_brace,
557 tok::comma, tok::semi },
558 StopBeforeMatch);
559 if (Tok.is(tok::greater))
560 ConsumeToken();
561 }
562
563 if (mayBeProtocolList) {
564 // A type parameter list must be followed by either a ':' (indicating the
565 // presence of a superclass) or a '(' (indicating that this is a category
566 // or extension). This disambiguates between an objc-type-parameter-list
567 // and a objc-protocol-refs.
568 if (Tok.isNot(tok::colon) && Tok.isNot(tok::l_paren)) {
569 // Returning null indicates that we don't have a type parameter list.
570 // The results the caller needs to handle the protocol references are
571 // captured in the reference parameters already.
572 return nullptr;
573 }
574
575 // We have a type parameter list that looks like a list of protocol
576 // references. Turn that parameter list into type parameters.
577 makeProtocolIdentsIntoTypeParameters();
578 }
579
580 // Form the type parameter list and enter its scope.
581 ObjCTypeParamList *list = Actions.actOnObjCTypeParamList(
582 getCurScope(),
583 lAngleLoc,
584 typeParams,
585 rAngleLoc);
586 Scope.enter(list);
587
588 // Clear out the angle locations; they're used by the caller to indicate
589 // whether there are any protocol references.
590 lAngleLoc = SourceLocation();
591 rAngleLoc = SourceLocation();
592 return invalid ? nullptr : list;
593 }
594
595 /// Parse an objc-type-parameter-list.
parseObjCTypeParamList()596 ObjCTypeParamList *Parser::parseObjCTypeParamList() {
597 SourceLocation lAngleLoc;
598 SmallVector<IdentifierLocPair, 1> protocolIdents;
599 SourceLocation rAngleLoc;
600
601 ObjCTypeParamListScope Scope(Actions, getCurScope());
602 return parseObjCTypeParamListOrProtocolRefs(Scope, lAngleLoc, protocolIdents,
603 rAngleLoc,
604 /*mayBeProtocolList=*/false);
605 }
606
607 /// objc-interface-decl-list:
608 /// empty
609 /// objc-interface-decl-list objc-property-decl [OBJC2]
610 /// objc-interface-decl-list objc-method-requirement [OBJC2]
611 /// objc-interface-decl-list objc-method-proto ';'
612 /// objc-interface-decl-list declaration
613 /// objc-interface-decl-list ';'
614 ///
615 /// objc-method-requirement: [OBJC2]
616 /// @required
617 /// @optional
618 ///
ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,Decl * CDecl)619 void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,
620 Decl *CDecl) {
621 SmallVector<Decl *, 32> allMethods;
622 SmallVector<DeclGroupPtrTy, 8> allTUVariables;
623 tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword;
624
625 SourceRange AtEnd;
626
627 while (1) {
628 // If this is a method prototype, parse it.
629 if (Tok.isOneOf(tok::minus, tok::plus)) {
630 if (Decl *methodPrototype =
631 ParseObjCMethodPrototype(MethodImplKind, false))
632 allMethods.push_back(methodPrototype);
633 // Consume the ';' here, since ParseObjCMethodPrototype() is re-used for
634 // method definitions.
635 if (ExpectAndConsumeSemi(diag::err_expected_semi_after_method_proto)) {
636 // We didn't find a semi and we error'ed out. Skip until a ';' or '@'.
637 SkipUntil(tok::at, StopAtSemi | StopBeforeMatch);
638 if (Tok.is(tok::semi))
639 ConsumeToken();
640 }
641 continue;
642 }
643 if (Tok.is(tok::l_paren)) {
644 Diag(Tok, diag::err_expected_minus_or_plus);
645 ParseObjCMethodDecl(Tok.getLocation(),
646 tok::minus,
647 MethodImplKind, false);
648 continue;
649 }
650 // Ignore excess semicolons.
651 if (Tok.is(tok::semi)) {
652 ConsumeToken();
653 continue;
654 }
655
656 // If we got to the end of the file, exit the loop.
657 if (isEofOrEom())
658 break;
659
660 // Code completion within an Objective-C interface.
661 if (Tok.is(tok::code_completion)) {
662 Actions.CodeCompleteOrdinaryName(getCurScope(),
663 CurParsedObjCImpl? Sema::PCC_ObjCImplementation
664 : Sema::PCC_ObjCInterface);
665 return cutOffParsing();
666 }
667
668 // If we don't have an @ directive, parse it as a function definition.
669 if (Tok.isNot(tok::at)) {
670 // The code below does not consume '}'s because it is afraid of eating the
671 // end of a namespace. Because of the way this code is structured, an
672 // erroneous r_brace would cause an infinite loop if not handled here.
673 if (Tok.is(tok::r_brace))
674 break;
675 ParsedAttributesWithRange attrs(AttrFactory);
676 allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(attrs));
677 continue;
678 }
679
680 // Otherwise, we have an @ directive, eat the @.
681 SourceLocation AtLoc = ConsumeToken(); // the "@"
682 if (Tok.is(tok::code_completion)) {
683 Actions.CodeCompleteObjCAtDirective(getCurScope());
684 return cutOffParsing();
685 }
686
687 tok::ObjCKeywordKind DirectiveKind = Tok.getObjCKeywordID();
688
689 if (DirectiveKind == tok::objc_end) { // @end -> terminate list
690 AtEnd.setBegin(AtLoc);
691 AtEnd.setEnd(Tok.getLocation());
692 break;
693 } else if (DirectiveKind == tok::objc_not_keyword) {
694 Diag(Tok, diag::err_objc_unknown_at);
695 SkipUntil(tok::semi);
696 continue;
697 }
698
699 // Eat the identifier.
700 ConsumeToken();
701
702 switch (DirectiveKind) {
703 default:
704 // FIXME: If someone forgets an @end on a protocol, this loop will
705 // continue to eat up tons of stuff and spew lots of nonsense errors. It
706 // would probably be better to bail out if we saw an @class or @interface
707 // or something like that.
708 Diag(AtLoc, diag::err_objc_illegal_interface_qual);
709 // Skip until we see an '@' or '}' or ';'.
710 SkipUntil(tok::r_brace, tok::at, StopAtSemi);
711 break;
712
713 case tok::objc_implementation:
714 case tok::objc_interface:
715 Diag(AtLoc, diag::err_objc_missing_end)
716 << FixItHint::CreateInsertion(AtLoc, "@end\n");
717 Diag(CDecl->getLocStart(), diag::note_objc_container_start)
718 << (int) Actions.getObjCContainerKind();
719 ConsumeToken();
720 break;
721
722 case tok::objc_required:
723 case tok::objc_optional:
724 // This is only valid on protocols.
725 // FIXME: Should this check for ObjC2 being enabled?
726 if (contextKey != tok::objc_protocol)
727 Diag(AtLoc, diag::err_objc_directive_only_in_protocol);
728 else
729 MethodImplKind = DirectiveKind;
730 break;
731
732 case tok::objc_property:
733 if (!getLangOpts().ObjC2)
734 Diag(AtLoc, diag::err_objc_properties_require_objc2);
735
736 ObjCDeclSpec OCDS;
737 SourceLocation LParenLoc;
738 // Parse property attribute list, if any.
739 if (Tok.is(tok::l_paren)) {
740 LParenLoc = Tok.getLocation();
741 ParseObjCPropertyAttribute(OCDS);
742 }
743
744 bool addedToDeclSpec = false;
745 auto ObjCPropertyCallback = [&](ParsingFieldDeclarator &FD) {
746 if (FD.D.getIdentifier() == nullptr) {
747 Diag(AtLoc, diag::err_objc_property_requires_field_name)
748 << FD.D.getSourceRange();
749 return;
750 }
751 if (FD.BitfieldSize) {
752 Diag(AtLoc, diag::err_objc_property_bitfield)
753 << FD.D.getSourceRange();
754 return;
755 }
756
757 // Map a nullability property attribute to a context-sensitive keyword
758 // attribute.
759 if (OCDS.getPropertyAttributes() & ObjCDeclSpec::DQ_PR_nullability)
760 addContextSensitiveTypeNullability(*this, FD.D, OCDS.getNullability(),
761 OCDS.getNullabilityLoc(),
762 addedToDeclSpec);
763
764 // Install the property declarator into interfaceDecl.
765 IdentifierInfo *SelName =
766 OCDS.getGetterName() ? OCDS.getGetterName() : FD.D.getIdentifier();
767
768 Selector GetterSel = PP.getSelectorTable().getNullarySelector(SelName);
769 IdentifierInfo *SetterName = OCDS.getSetterName();
770 Selector SetterSel;
771 if (SetterName)
772 SetterSel = PP.getSelectorTable().getSelector(1, &SetterName);
773 else
774 SetterSel = SelectorTable::constructSetterSelector(
775 PP.getIdentifierTable(), PP.getSelectorTable(),
776 FD.D.getIdentifier());
777 Decl *Property = Actions.ActOnProperty(
778 getCurScope(), AtLoc, LParenLoc, FD, OCDS, GetterSel, SetterSel,
779 MethodImplKind);
780
781 FD.complete(Property);
782 };
783
784 // Parse all the comma separated declarators.
785 ParsingDeclSpec DS(*this);
786 ParseStructDeclaration(DS, ObjCPropertyCallback);
787
788 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
789 break;
790 }
791 }
792
793 // We break out of the big loop in two cases: when we see @end or when we see
794 // EOF. In the former case, eat the @end. In the later case, emit an error.
795 if (Tok.is(tok::code_completion)) {
796 Actions.CodeCompleteObjCAtDirective(getCurScope());
797 return cutOffParsing();
798 } else if (Tok.isObjCAtKeyword(tok::objc_end)) {
799 ConsumeToken(); // the "end" identifier
800 } else {
801 Diag(Tok, diag::err_objc_missing_end)
802 << FixItHint::CreateInsertion(Tok.getLocation(), "\n@end\n");
803 Diag(CDecl->getLocStart(), diag::note_objc_container_start)
804 << (int) Actions.getObjCContainerKind();
805 AtEnd.setBegin(Tok.getLocation());
806 AtEnd.setEnd(Tok.getLocation());
807 }
808
809 // Insert collected methods declarations into the @interface object.
810 // This passes in an invalid SourceLocation for AtEndLoc when EOF is hit.
811 Actions.ActOnAtEnd(getCurScope(), AtEnd, allMethods, allTUVariables);
812 }
813
814 /// Diagnose redundant or conflicting nullability information.
diagnoseRedundantPropertyNullability(Parser & P,ObjCDeclSpec & DS,NullabilityKind nullability,SourceLocation nullabilityLoc)815 static void diagnoseRedundantPropertyNullability(Parser &P,
816 ObjCDeclSpec &DS,
817 NullabilityKind nullability,
818 SourceLocation nullabilityLoc){
819 if (DS.getNullability() == nullability) {
820 P.Diag(nullabilityLoc, diag::warn_nullability_duplicate)
821 << DiagNullabilityKind(nullability, true)
822 << SourceRange(DS.getNullabilityLoc());
823 return;
824 }
825
826 P.Diag(nullabilityLoc, diag::err_nullability_conflicting)
827 << DiagNullabilityKind(nullability, true)
828 << DiagNullabilityKind(DS.getNullability(), true)
829 << SourceRange(DS.getNullabilityLoc());
830 }
831
832 /// Parse property attribute declarations.
833 ///
834 /// property-attr-decl: '(' property-attrlist ')'
835 /// property-attrlist:
836 /// property-attribute
837 /// property-attrlist ',' property-attribute
838 /// property-attribute:
839 /// getter '=' identifier
840 /// setter '=' identifier ':'
841 /// readonly
842 /// readwrite
843 /// assign
844 /// retain
845 /// copy
846 /// nonatomic
847 /// atomic
848 /// strong
849 /// weak
850 /// unsafe_unretained
851 /// nonnull
852 /// nullable
853 /// null_unspecified
854 /// null_resettable
855 /// class
856 ///
ParseObjCPropertyAttribute(ObjCDeclSpec & DS)857 void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
858 assert(Tok.getKind() == tok::l_paren);
859 BalancedDelimiterTracker T(*this, tok::l_paren);
860 T.consumeOpen();
861
862 while (1) {
863 if (Tok.is(tok::code_completion)) {
864 Actions.CodeCompleteObjCPropertyFlags(getCurScope(), DS);
865 return cutOffParsing();
866 }
867 const IdentifierInfo *II = Tok.getIdentifierInfo();
868
869 // If this is not an identifier at all, bail out early.
870 if (!II) {
871 T.consumeClose();
872 return;
873 }
874
875 SourceLocation AttrName = ConsumeToken(); // consume last attribute name
876
877 if (II->isStr("readonly"))
878 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_readonly);
879 else if (II->isStr("assign"))
880 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_assign);
881 else if (II->isStr("unsafe_unretained"))
882 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_unsafe_unretained);
883 else if (II->isStr("readwrite"))
884 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_readwrite);
885 else if (II->isStr("retain"))
886 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_retain);
887 else if (II->isStr("strong"))
888 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_strong);
889 else if (II->isStr("copy"))
890 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_copy);
891 else if (II->isStr("nonatomic"))
892 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nonatomic);
893 else if (II->isStr("atomic"))
894 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_atomic);
895 else if (II->isStr("weak"))
896 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_weak);
897 else if (II->isStr("getter") || II->isStr("setter")) {
898 bool IsSetter = II->getNameStart()[0] == 's';
899
900 // getter/setter require extra treatment.
901 unsigned DiagID = IsSetter ? diag::err_objc_expected_equal_for_setter :
902 diag::err_objc_expected_equal_for_getter;
903
904 if (ExpectAndConsume(tok::equal, DiagID)) {
905 SkipUntil(tok::r_paren, StopAtSemi);
906 return;
907 }
908
909 if (Tok.is(tok::code_completion)) {
910 if (IsSetter)
911 Actions.CodeCompleteObjCPropertySetter(getCurScope());
912 else
913 Actions.CodeCompleteObjCPropertyGetter(getCurScope());
914 return cutOffParsing();
915 }
916
917 SourceLocation SelLoc;
918 IdentifierInfo *SelIdent = ParseObjCSelectorPiece(SelLoc);
919
920 if (!SelIdent) {
921 Diag(Tok, diag::err_objc_expected_selector_for_getter_setter)
922 << IsSetter;
923 SkipUntil(tok::r_paren, StopAtSemi);
924 return;
925 }
926
927 if (IsSetter) {
928 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_setter);
929 DS.setSetterName(SelIdent);
930
931 if (ExpectAndConsume(tok::colon,
932 diag::err_expected_colon_after_setter_name)) {
933 SkipUntil(tok::r_paren, StopAtSemi);
934 return;
935 }
936 } else {
937 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_getter);
938 DS.setGetterName(SelIdent);
939 }
940 } else if (II->isStr("nonnull")) {
941 if (DS.getPropertyAttributes() & ObjCDeclSpec::DQ_PR_nullability)
942 diagnoseRedundantPropertyNullability(*this, DS,
943 NullabilityKind::NonNull,
944 Tok.getLocation());
945 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nullability);
946 DS.setNullability(Tok.getLocation(), NullabilityKind::NonNull);
947 } else if (II->isStr("nullable")) {
948 if (DS.getPropertyAttributes() & ObjCDeclSpec::DQ_PR_nullability)
949 diagnoseRedundantPropertyNullability(*this, DS,
950 NullabilityKind::Nullable,
951 Tok.getLocation());
952 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nullability);
953 DS.setNullability(Tok.getLocation(), NullabilityKind::Nullable);
954 } else if (II->isStr("null_unspecified")) {
955 if (DS.getPropertyAttributes() & ObjCDeclSpec::DQ_PR_nullability)
956 diagnoseRedundantPropertyNullability(*this, DS,
957 NullabilityKind::Unspecified,
958 Tok.getLocation());
959 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nullability);
960 DS.setNullability(Tok.getLocation(), NullabilityKind::Unspecified);
961 } else if (II->isStr("null_resettable")) {
962 if (DS.getPropertyAttributes() & ObjCDeclSpec::DQ_PR_nullability)
963 diagnoseRedundantPropertyNullability(*this, DS,
964 NullabilityKind::Unspecified,
965 Tok.getLocation());
966 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nullability);
967 DS.setNullability(Tok.getLocation(), NullabilityKind::Unspecified);
968
969 // Also set the null_resettable bit.
970 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_null_resettable);
971 } else if (II->isStr("class")) {
972 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_class);
973 } else {
974 Diag(AttrName, diag::err_objc_expected_property_attr) << II;
975 SkipUntil(tok::r_paren, StopAtSemi);
976 return;
977 }
978
979 if (Tok.isNot(tok::comma))
980 break;
981
982 ConsumeToken();
983 }
984
985 T.consumeClose();
986 }
987
988 /// objc-method-proto:
989 /// objc-instance-method objc-method-decl objc-method-attributes[opt]
990 /// objc-class-method objc-method-decl objc-method-attributes[opt]
991 ///
992 /// objc-instance-method: '-'
993 /// objc-class-method: '+'
994 ///
995 /// objc-method-attributes: [OBJC2]
996 /// __attribute__((deprecated))
997 ///
ParseObjCMethodPrototype(tok::ObjCKeywordKind MethodImplKind,bool MethodDefinition)998 Decl *Parser::ParseObjCMethodPrototype(tok::ObjCKeywordKind MethodImplKind,
999 bool MethodDefinition) {
1000 assert(Tok.isOneOf(tok::minus, tok::plus) && "expected +/-");
1001
1002 tok::TokenKind methodType = Tok.getKind();
1003 SourceLocation mLoc = ConsumeToken();
1004 Decl *MDecl = ParseObjCMethodDecl(mLoc, methodType, MethodImplKind,
1005 MethodDefinition);
1006 // Since this rule is used for both method declarations and definitions,
1007 // the caller is (optionally) responsible for consuming the ';'.
1008 return MDecl;
1009 }
1010
1011 /// objc-selector:
1012 /// identifier
1013 /// one of
1014 /// enum struct union if else while do for switch case default
1015 /// break continue return goto asm sizeof typeof __alignof
1016 /// unsigned long const short volatile signed restrict _Complex
1017 /// in out inout bycopy byref oneway int char float double void _Bool
1018 ///
ParseObjCSelectorPiece(SourceLocation & SelectorLoc)1019 IdentifierInfo *Parser::ParseObjCSelectorPiece(SourceLocation &SelectorLoc) {
1020
1021 switch (Tok.getKind()) {
1022 default:
1023 return nullptr;
1024 case tok::ampamp:
1025 case tok::ampequal:
1026 case tok::amp:
1027 case tok::pipe:
1028 case tok::tilde:
1029 case tok::exclaim:
1030 case tok::exclaimequal:
1031 case tok::pipepipe:
1032 case tok::pipeequal:
1033 case tok::caret:
1034 case tok::caretequal: {
1035 std::string ThisTok(PP.getSpelling(Tok));
1036 if (isLetter(ThisTok[0])) {
1037 IdentifierInfo *II = &PP.getIdentifierTable().get(ThisTok.data());
1038 Tok.setKind(tok::identifier);
1039 SelectorLoc = ConsumeToken();
1040 return II;
1041 }
1042 return nullptr;
1043 }
1044
1045 case tok::identifier:
1046 case tok::kw_asm:
1047 case tok::kw_auto:
1048 case tok::kw_bool:
1049 case tok::kw_break:
1050 case tok::kw_case:
1051 case tok::kw_catch:
1052 case tok::kw_char:
1053 case tok::kw_class:
1054 case tok::kw_const:
1055 case tok::kw_const_cast:
1056 case tok::kw_continue:
1057 case tok::kw_default:
1058 case tok::kw_delete:
1059 case tok::kw_do:
1060 case tok::kw_double:
1061 case tok::kw_dynamic_cast:
1062 case tok::kw_else:
1063 case tok::kw_enum:
1064 case tok::kw_explicit:
1065 case tok::kw_export:
1066 case tok::kw_extern:
1067 case tok::kw_false:
1068 case tok::kw_float:
1069 case tok::kw_for:
1070 case tok::kw_friend:
1071 case tok::kw_goto:
1072 case tok::kw_if:
1073 case tok::kw_inline:
1074 case tok::kw_int:
1075 case tok::kw_long:
1076 case tok::kw_mutable:
1077 case tok::kw_namespace:
1078 case tok::kw_new:
1079 case tok::kw_operator:
1080 case tok::kw_private:
1081 case tok::kw_protected:
1082 case tok::kw_public:
1083 case tok::kw_register:
1084 case tok::kw_reinterpret_cast:
1085 case tok::kw_restrict:
1086 case tok::kw_return:
1087 case tok::kw_short:
1088 case tok::kw_signed:
1089 case tok::kw_sizeof:
1090 case tok::kw_static:
1091 case tok::kw_static_cast:
1092 case tok::kw_struct:
1093 case tok::kw_switch:
1094 case tok::kw_template:
1095 case tok::kw_this:
1096 case tok::kw_throw:
1097 case tok::kw_true:
1098 case tok::kw_try:
1099 case tok::kw_typedef:
1100 case tok::kw_typeid:
1101 case tok::kw_typename:
1102 case tok::kw_typeof:
1103 case tok::kw_union:
1104 case tok::kw_unsigned:
1105 case tok::kw_using:
1106 case tok::kw_virtual:
1107 case tok::kw_void:
1108 case tok::kw_volatile:
1109 case tok::kw_wchar_t:
1110 case tok::kw_while:
1111 case tok::kw__Bool:
1112 case tok::kw__Complex:
1113 case tok::kw___alignof:
1114 case tok::kw___auto_type:
1115 IdentifierInfo *II = Tok.getIdentifierInfo();
1116 SelectorLoc = ConsumeToken();
1117 return II;
1118 }
1119 }
1120
1121 /// objc-for-collection-in: 'in'
1122 ///
isTokIdentifier_in() const1123 bool Parser::isTokIdentifier_in() const {
1124 // FIXME: May have to do additional look-ahead to only allow for
1125 // valid tokens following an 'in'; such as an identifier, unary operators,
1126 // '[' etc.
1127 return (getLangOpts().ObjC2 && Tok.is(tok::identifier) &&
1128 Tok.getIdentifierInfo() == ObjCTypeQuals[objc_in]);
1129 }
1130
1131 /// ParseObjCTypeQualifierList - This routine parses the objective-c's type
1132 /// qualifier list and builds their bitmask representation in the input
1133 /// argument.
1134 ///
1135 /// objc-type-qualifiers:
1136 /// objc-type-qualifier
1137 /// objc-type-qualifiers objc-type-qualifier
1138 ///
1139 /// objc-type-qualifier:
1140 /// 'in'
1141 /// 'out'
1142 /// 'inout'
1143 /// 'oneway'
1144 /// 'bycopy'
1145 /// 'byref'
1146 /// 'nonnull'
1147 /// 'nullable'
1148 /// 'null_unspecified'
1149 ///
ParseObjCTypeQualifierList(ObjCDeclSpec & DS,Declarator::TheContext Context)1150 void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS,
1151 Declarator::TheContext Context) {
1152 assert(Context == Declarator::ObjCParameterContext ||
1153 Context == Declarator::ObjCResultContext);
1154
1155 while (1) {
1156 if (Tok.is(tok::code_completion)) {
1157 Actions.CodeCompleteObjCPassingType(getCurScope(), DS,
1158 Context == Declarator::ObjCParameterContext);
1159 return cutOffParsing();
1160 }
1161
1162 if (Tok.isNot(tok::identifier))
1163 return;
1164
1165 const IdentifierInfo *II = Tok.getIdentifierInfo();
1166 for (unsigned i = 0; i != objc_NumQuals; ++i) {
1167 if (II != ObjCTypeQuals[i] ||
1168 NextToken().is(tok::less) ||
1169 NextToken().is(tok::coloncolon))
1170 continue;
1171
1172 ObjCDeclSpec::ObjCDeclQualifier Qual;
1173 NullabilityKind Nullability;
1174 switch (i) {
1175 default: llvm_unreachable("Unknown decl qualifier");
1176 case objc_in: Qual = ObjCDeclSpec::DQ_In; break;
1177 case objc_out: Qual = ObjCDeclSpec::DQ_Out; break;
1178 case objc_inout: Qual = ObjCDeclSpec::DQ_Inout; break;
1179 case objc_oneway: Qual = ObjCDeclSpec::DQ_Oneway; break;
1180 case objc_bycopy: Qual = ObjCDeclSpec::DQ_Bycopy; break;
1181 case objc_byref: Qual = ObjCDeclSpec::DQ_Byref; break;
1182
1183 case objc_nonnull:
1184 Qual = ObjCDeclSpec::DQ_CSNullability;
1185 Nullability = NullabilityKind::NonNull;
1186 break;
1187
1188 case objc_nullable:
1189 Qual = ObjCDeclSpec::DQ_CSNullability;
1190 Nullability = NullabilityKind::Nullable;
1191 break;
1192
1193 case objc_null_unspecified:
1194 Qual = ObjCDeclSpec::DQ_CSNullability;
1195 Nullability = NullabilityKind::Unspecified;
1196 break;
1197 }
1198
1199 // FIXME: Diagnose redundant specifiers.
1200 DS.setObjCDeclQualifier(Qual);
1201 if (Qual == ObjCDeclSpec::DQ_CSNullability)
1202 DS.setNullability(Tok.getLocation(), Nullability);
1203
1204 ConsumeToken();
1205 II = nullptr;
1206 break;
1207 }
1208
1209 // If this wasn't a recognized qualifier, bail out.
1210 if (II) return;
1211 }
1212 }
1213
1214 /// Take all the decl attributes out of the given list and add
1215 /// them to the given attribute set.
takeDeclAttributes(ParsedAttributes & attrs,AttributeList * list)1216 static void takeDeclAttributes(ParsedAttributes &attrs,
1217 AttributeList *list) {
1218 while (list) {
1219 AttributeList *cur = list;
1220 list = cur->getNext();
1221
1222 if (!cur->isUsedAsTypeAttr()) {
1223 // Clear out the next pointer. We're really completely
1224 // destroying the internal invariants of the declarator here,
1225 // but it doesn't matter because we're done with it.
1226 cur->setNext(nullptr);
1227 attrs.add(cur);
1228 }
1229 }
1230 }
1231
1232 /// takeDeclAttributes - Take all the decl attributes from the given
1233 /// declarator and add them to the given list.
takeDeclAttributes(ParsedAttributes & attrs,Declarator & D)1234 static void takeDeclAttributes(ParsedAttributes &attrs,
1235 Declarator &D) {
1236 // First, take ownership of all attributes.
1237 attrs.getPool().takeAllFrom(D.getAttributePool());
1238 attrs.getPool().takeAllFrom(D.getDeclSpec().getAttributePool());
1239
1240 // Now actually move the attributes over.
1241 takeDeclAttributes(attrs, D.getDeclSpec().getAttributes().getList());
1242 takeDeclAttributes(attrs, D.getAttributes());
1243 for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
1244 takeDeclAttributes(attrs,
1245 const_cast<AttributeList*>(D.getTypeObject(i).getAttrs()));
1246 }
1247
1248 /// objc-type-name:
1249 /// '(' objc-type-qualifiers[opt] type-name ')'
1250 /// '(' objc-type-qualifiers[opt] ')'
1251 ///
ParseObjCTypeName(ObjCDeclSpec & DS,Declarator::TheContext context,ParsedAttributes * paramAttrs)1252 ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS,
1253 Declarator::TheContext context,
1254 ParsedAttributes *paramAttrs) {
1255 assert(context == Declarator::ObjCParameterContext ||
1256 context == Declarator::ObjCResultContext);
1257 assert((paramAttrs != nullptr) ==
1258 (context == Declarator::ObjCParameterContext));
1259
1260 assert(Tok.is(tok::l_paren) && "expected (");
1261
1262 BalancedDelimiterTracker T(*this, tok::l_paren);
1263 T.consumeOpen();
1264
1265 SourceLocation TypeStartLoc = Tok.getLocation();
1266 ObjCDeclContextSwitch ObjCDC(*this);
1267
1268 // Parse type qualifiers, in, inout, etc.
1269 ParseObjCTypeQualifierList(DS, context);
1270
1271 ParsedType Ty;
1272 if (isTypeSpecifierQualifier() || isObjCInstancetype()) {
1273 // Parse an abstract declarator.
1274 DeclSpec declSpec(AttrFactory);
1275 declSpec.setObjCQualifiers(&DS);
1276 DeclSpecContext dsContext = DSC_normal;
1277 if (context == Declarator::ObjCResultContext)
1278 dsContext = DSC_objc_method_result;
1279 ParseSpecifierQualifierList(declSpec, AS_none, dsContext);
1280 Declarator declarator(declSpec, context);
1281 ParseDeclarator(declarator);
1282
1283 // If that's not invalid, extract a type.
1284 if (!declarator.isInvalidType()) {
1285 // Map a nullability specifier to a context-sensitive keyword attribute.
1286 bool addedToDeclSpec = false;
1287 if (DS.getObjCDeclQualifier() & ObjCDeclSpec::DQ_CSNullability)
1288 addContextSensitiveTypeNullability(*this, declarator,
1289 DS.getNullability(),
1290 DS.getNullabilityLoc(),
1291 addedToDeclSpec);
1292
1293 TypeResult type = Actions.ActOnTypeName(getCurScope(), declarator);
1294 if (!type.isInvalid())
1295 Ty = type.get();
1296
1297 // If we're parsing a parameter, steal all the decl attributes
1298 // and add them to the decl spec.
1299 if (context == Declarator::ObjCParameterContext)
1300 takeDeclAttributes(*paramAttrs, declarator);
1301 }
1302 }
1303
1304 if (Tok.is(tok::r_paren))
1305 T.consumeClose();
1306 else if (Tok.getLocation() == TypeStartLoc) {
1307 // If we didn't eat any tokens, then this isn't a type.
1308 Diag(Tok, diag::err_expected_type);
1309 SkipUntil(tok::r_paren, StopAtSemi);
1310 } else {
1311 // Otherwise, we found *something*, but didn't get a ')' in the right
1312 // place. Emit an error then return what we have as the type.
1313 T.consumeClose();
1314 }
1315 return Ty;
1316 }
1317
1318 /// objc-method-decl:
1319 /// objc-selector
1320 /// objc-keyword-selector objc-parmlist[opt]
1321 /// objc-type-name objc-selector
1322 /// objc-type-name objc-keyword-selector objc-parmlist[opt]
1323 ///
1324 /// objc-keyword-selector:
1325 /// objc-keyword-decl
1326 /// objc-keyword-selector objc-keyword-decl
1327 ///
1328 /// objc-keyword-decl:
1329 /// objc-selector ':' objc-type-name objc-keyword-attributes[opt] identifier
1330 /// objc-selector ':' objc-keyword-attributes[opt] identifier
1331 /// ':' objc-type-name objc-keyword-attributes[opt] identifier
1332 /// ':' objc-keyword-attributes[opt] identifier
1333 ///
1334 /// objc-parmlist:
1335 /// objc-parms objc-ellipsis[opt]
1336 ///
1337 /// objc-parms:
1338 /// objc-parms , parameter-declaration
1339 ///
1340 /// objc-ellipsis:
1341 /// , ...
1342 ///
1343 /// objc-keyword-attributes: [OBJC2]
1344 /// __attribute__((unused))
1345 ///
ParseObjCMethodDecl(SourceLocation mLoc,tok::TokenKind mType,tok::ObjCKeywordKind MethodImplKind,bool MethodDefinition)1346 Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
1347 tok::TokenKind mType,
1348 tok::ObjCKeywordKind MethodImplKind,
1349 bool MethodDefinition) {
1350 ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
1351
1352 if (Tok.is(tok::code_completion)) {
1353 Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus,
1354 /*ReturnType=*/nullptr);
1355 cutOffParsing();
1356 return nullptr;
1357 }
1358
1359 // Parse the return type if present.
1360 ParsedType ReturnType;
1361 ObjCDeclSpec DSRet;
1362 if (Tok.is(tok::l_paren))
1363 ReturnType = ParseObjCTypeName(DSRet, Declarator::ObjCResultContext,
1364 nullptr);
1365
1366 // If attributes exist before the method, parse them.
1367 ParsedAttributes methodAttrs(AttrFactory);
1368 if (getLangOpts().ObjC2)
1369 MaybeParseGNUAttributes(methodAttrs);
1370
1371 if (Tok.is(tok::code_completion)) {
1372 Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus,
1373 ReturnType);
1374 cutOffParsing();
1375 return nullptr;
1376 }
1377
1378 // Now parse the selector.
1379 SourceLocation selLoc;
1380 IdentifierInfo *SelIdent = ParseObjCSelectorPiece(selLoc);
1381
1382 // An unnamed colon is valid.
1383 if (!SelIdent && Tok.isNot(tok::colon)) { // missing selector name.
1384 Diag(Tok, diag::err_expected_selector_for_method)
1385 << SourceRange(mLoc, Tok.getLocation());
1386 // Skip until we get a ; or @.
1387 SkipUntil(tok::at, StopAtSemi | StopBeforeMatch);
1388 return nullptr;
1389 }
1390
1391 SmallVector<DeclaratorChunk::ParamInfo, 8> CParamInfo;
1392 if (Tok.isNot(tok::colon)) {
1393 // If attributes exist after the method, parse them.
1394 if (getLangOpts().ObjC2)
1395 MaybeParseGNUAttributes(methodAttrs);
1396
1397 Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
1398 Decl *Result
1399 = Actions.ActOnMethodDeclaration(getCurScope(), mLoc, Tok.getLocation(),
1400 mType, DSRet, ReturnType,
1401 selLoc, Sel, nullptr,
1402 CParamInfo.data(), CParamInfo.size(),
1403 methodAttrs.getList(), MethodImplKind,
1404 false, MethodDefinition);
1405 PD.complete(Result);
1406 return Result;
1407 }
1408
1409 SmallVector<IdentifierInfo *, 12> KeyIdents;
1410 SmallVector<SourceLocation, 12> KeyLocs;
1411 SmallVector<Sema::ObjCArgInfo, 12> ArgInfos;
1412 ParseScope PrototypeScope(this, Scope::FunctionPrototypeScope |
1413 Scope::FunctionDeclarationScope | Scope::DeclScope);
1414
1415 AttributePool allParamAttrs(AttrFactory);
1416 while (1) {
1417 ParsedAttributes paramAttrs(AttrFactory);
1418 Sema::ObjCArgInfo ArgInfo;
1419
1420 // Each iteration parses a single keyword argument.
1421 if (ExpectAndConsume(tok::colon))
1422 break;
1423
1424 ArgInfo.Type = nullptr;
1425 if (Tok.is(tok::l_paren)) // Parse the argument type if present.
1426 ArgInfo.Type = ParseObjCTypeName(ArgInfo.DeclSpec,
1427 Declarator::ObjCParameterContext,
1428 ¶mAttrs);
1429
1430 // If attributes exist before the argument name, parse them.
1431 // Regardless, collect all the attributes we've parsed so far.
1432 ArgInfo.ArgAttrs = nullptr;
1433 if (getLangOpts().ObjC2) {
1434 MaybeParseGNUAttributes(paramAttrs);
1435 ArgInfo.ArgAttrs = paramAttrs.getList();
1436 }
1437
1438 // Code completion for the next piece of the selector.
1439 if (Tok.is(tok::code_completion)) {
1440 KeyIdents.push_back(SelIdent);
1441 Actions.CodeCompleteObjCMethodDeclSelector(getCurScope(),
1442 mType == tok::minus,
1443 /*AtParameterName=*/true,
1444 ReturnType, KeyIdents);
1445 cutOffParsing();
1446 return nullptr;
1447 }
1448
1449 if (Tok.isNot(tok::identifier)) {
1450 Diag(Tok, diag::err_expected)
1451 << tok::identifier; // missing argument name.
1452 break;
1453 }
1454
1455 ArgInfo.Name = Tok.getIdentifierInfo();
1456 ArgInfo.NameLoc = Tok.getLocation();
1457 ConsumeToken(); // Eat the identifier.
1458
1459 ArgInfos.push_back(ArgInfo);
1460 KeyIdents.push_back(SelIdent);
1461 KeyLocs.push_back(selLoc);
1462
1463 // Make sure the attributes persist.
1464 allParamAttrs.takeAllFrom(paramAttrs.getPool());
1465
1466 // Code completion for the next piece of the selector.
1467 if (Tok.is(tok::code_completion)) {
1468 Actions.CodeCompleteObjCMethodDeclSelector(getCurScope(),
1469 mType == tok::minus,
1470 /*AtParameterName=*/false,
1471 ReturnType, KeyIdents);
1472 cutOffParsing();
1473 return nullptr;
1474 }
1475
1476 // Check for another keyword selector.
1477 SelIdent = ParseObjCSelectorPiece(selLoc);
1478 if (!SelIdent && Tok.isNot(tok::colon))
1479 break;
1480 if (!SelIdent) {
1481 SourceLocation ColonLoc = Tok.getLocation();
1482 if (PP.getLocForEndOfToken(ArgInfo.NameLoc) == ColonLoc) {
1483 Diag(ArgInfo.NameLoc, diag::warn_missing_selector_name) << ArgInfo.Name;
1484 Diag(ArgInfo.NameLoc, diag::note_missing_selector_name) << ArgInfo.Name;
1485 Diag(ColonLoc, diag::note_force_empty_selector_name) << ArgInfo.Name;
1486 }
1487 }
1488 // We have a selector or a colon, continue parsing.
1489 }
1490
1491 bool isVariadic = false;
1492 bool cStyleParamWarned = false;
1493 // Parse the (optional) parameter list.
1494 while (Tok.is(tok::comma)) {
1495 ConsumeToken();
1496 if (Tok.is(tok::ellipsis)) {
1497 isVariadic = true;
1498 ConsumeToken();
1499 break;
1500 }
1501 if (!cStyleParamWarned) {
1502 Diag(Tok, diag::warn_cstyle_param);
1503 cStyleParamWarned = true;
1504 }
1505 DeclSpec DS(AttrFactory);
1506 ParseDeclarationSpecifiers(DS);
1507 // Parse the declarator.
1508 Declarator ParmDecl(DS, Declarator::PrototypeContext);
1509 ParseDeclarator(ParmDecl);
1510 IdentifierInfo *ParmII = ParmDecl.getIdentifier();
1511 Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl);
1512 CParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
1513 ParmDecl.getIdentifierLoc(),
1514 Param,
1515 nullptr));
1516 }
1517
1518 // FIXME: Add support for optional parameter list...
1519 // If attributes exist after the method, parse them.
1520 if (getLangOpts().ObjC2)
1521 MaybeParseGNUAttributes(methodAttrs);
1522
1523 if (KeyIdents.size() == 0)
1524 return nullptr;
1525
1526 Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(),
1527 &KeyIdents[0]);
1528 Decl *Result
1529 = Actions.ActOnMethodDeclaration(getCurScope(), mLoc, Tok.getLocation(),
1530 mType, DSRet, ReturnType,
1531 KeyLocs, Sel, &ArgInfos[0],
1532 CParamInfo.data(), CParamInfo.size(),
1533 methodAttrs.getList(),
1534 MethodImplKind, isVariadic, MethodDefinition);
1535
1536 PD.complete(Result);
1537 return Result;
1538 }
1539
1540 /// objc-protocol-refs:
1541 /// '<' identifier-list '>'
1542 ///
1543 bool Parser::
ParseObjCProtocolReferences(SmallVectorImpl<Decl * > & Protocols,SmallVectorImpl<SourceLocation> & ProtocolLocs,bool WarnOnDeclarations,bool ForObjCContainer,SourceLocation & LAngleLoc,SourceLocation & EndLoc,bool consumeLastToken)1544 ParseObjCProtocolReferences(SmallVectorImpl<Decl *> &Protocols,
1545 SmallVectorImpl<SourceLocation> &ProtocolLocs,
1546 bool WarnOnDeclarations, bool ForObjCContainer,
1547 SourceLocation &LAngleLoc, SourceLocation &EndLoc,
1548 bool consumeLastToken) {
1549 assert(Tok.is(tok::less) && "expected <");
1550
1551 LAngleLoc = ConsumeToken(); // the "<"
1552
1553 SmallVector<IdentifierLocPair, 8> ProtocolIdents;
1554
1555 while (1) {
1556 if (Tok.is(tok::code_completion)) {
1557 Actions.CodeCompleteObjCProtocolReferences(ProtocolIdents);
1558 cutOffParsing();
1559 return true;
1560 }
1561
1562 if (Tok.isNot(tok::identifier)) {
1563 Diag(Tok, diag::err_expected) << tok::identifier;
1564 SkipUntil(tok::greater, StopAtSemi);
1565 return true;
1566 }
1567 ProtocolIdents.push_back(std::make_pair(Tok.getIdentifierInfo(),
1568 Tok.getLocation()));
1569 ProtocolLocs.push_back(Tok.getLocation());
1570 ConsumeToken();
1571
1572 if (!TryConsumeToken(tok::comma))
1573 break;
1574 }
1575
1576 // Consume the '>'.
1577 if (ParseGreaterThanInTemplateList(EndLoc, consumeLastToken,
1578 /*ObjCGenericList=*/false))
1579 return true;
1580
1581 // Convert the list of protocols identifiers into a list of protocol decls.
1582 Actions.FindProtocolDeclaration(WarnOnDeclarations, ForObjCContainer,
1583 ProtocolIdents, Protocols);
1584 return false;
1585 }
1586
parseObjCProtocolQualifierType(SourceLocation & rAngleLoc)1587 TypeResult Parser::parseObjCProtocolQualifierType(SourceLocation &rAngleLoc) {
1588 assert(Tok.is(tok::less) && "Protocol qualifiers start with '<'");
1589 assert(getLangOpts().ObjC1 && "Protocol qualifiers only exist in Objective-C");
1590
1591 SourceLocation lAngleLoc;
1592 SmallVector<Decl *, 8> protocols;
1593 SmallVector<SourceLocation, 8> protocolLocs;
1594 (void)ParseObjCProtocolReferences(protocols, protocolLocs, false, false,
1595 lAngleLoc, rAngleLoc,
1596 /*consumeLastToken=*/true);
1597 TypeResult result = Actions.actOnObjCProtocolQualifierType(lAngleLoc,
1598 protocols,
1599 protocolLocs,
1600 rAngleLoc);
1601 if (result.isUsable()) {
1602 Diag(lAngleLoc, diag::warn_objc_protocol_qualifier_missing_id)
1603 << FixItHint::CreateInsertion(lAngleLoc, "id")
1604 << SourceRange(lAngleLoc, rAngleLoc);
1605 }
1606
1607 return result;
1608 }
1609
1610 /// Parse Objective-C type arguments or protocol qualifiers.
1611 ///
1612 /// objc-type-arguments:
1613 /// '<' type-name '...'[opt] (',' type-name '...'[opt])* '>'
1614 ///
parseObjCTypeArgsOrProtocolQualifiers(ParsedType baseType,SourceLocation & typeArgsLAngleLoc,SmallVectorImpl<ParsedType> & typeArgs,SourceLocation & typeArgsRAngleLoc,SourceLocation & protocolLAngleLoc,SmallVectorImpl<Decl * > & protocols,SmallVectorImpl<SourceLocation> & protocolLocs,SourceLocation & protocolRAngleLoc,bool consumeLastToken,bool warnOnIncompleteProtocols)1615 void Parser::parseObjCTypeArgsOrProtocolQualifiers(
1616 ParsedType baseType,
1617 SourceLocation &typeArgsLAngleLoc,
1618 SmallVectorImpl<ParsedType> &typeArgs,
1619 SourceLocation &typeArgsRAngleLoc,
1620 SourceLocation &protocolLAngleLoc,
1621 SmallVectorImpl<Decl *> &protocols,
1622 SmallVectorImpl<SourceLocation> &protocolLocs,
1623 SourceLocation &protocolRAngleLoc,
1624 bool consumeLastToken,
1625 bool warnOnIncompleteProtocols) {
1626 assert(Tok.is(tok::less) && "Not at the start of type args or protocols");
1627 SourceLocation lAngleLoc = ConsumeToken();
1628
1629 // Whether all of the elements we've parsed thus far are single
1630 // identifiers, which might be types or might be protocols.
1631 bool allSingleIdentifiers = true;
1632 SmallVector<IdentifierInfo *, 4> identifiers;
1633 SmallVectorImpl<SourceLocation> &identifierLocs = protocolLocs;
1634
1635 // Parse a list of comma-separated identifiers, bailing out if we
1636 // see something different.
1637 do {
1638 // Parse a single identifier.
1639 if (Tok.is(tok::identifier) &&
1640 (NextToken().is(tok::comma) ||
1641 NextToken().is(tok::greater) ||
1642 NextToken().is(tok::greatergreater))) {
1643 identifiers.push_back(Tok.getIdentifierInfo());
1644 identifierLocs.push_back(ConsumeToken());
1645 continue;
1646 }
1647
1648 if (Tok.is(tok::code_completion)) {
1649 // FIXME: Also include types here.
1650 SmallVector<IdentifierLocPair, 4> identifierLocPairs;
1651 for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1652 identifierLocPairs.push_back(IdentifierLocPair(identifiers[i],
1653 identifierLocs[i]));
1654 }
1655
1656 QualType BaseT = Actions.GetTypeFromParser(baseType);
1657 if (!BaseT.isNull() && BaseT->acceptsObjCTypeParams()) {
1658 Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Type);
1659 } else {
1660 Actions.CodeCompleteObjCProtocolReferences(identifierLocPairs);
1661 }
1662 cutOffParsing();
1663 return;
1664 }
1665
1666 allSingleIdentifiers = false;
1667 break;
1668 } while (TryConsumeToken(tok::comma));
1669
1670 // If we parsed an identifier list, semantic analysis sorts out
1671 // whether it refers to protocols or to type arguments.
1672 if (allSingleIdentifiers) {
1673 // Parse the closing '>'.
1674 SourceLocation rAngleLoc;
1675 (void)ParseGreaterThanInTemplateList(rAngleLoc, consumeLastToken,
1676 /*ObjCGenericList=*/true);
1677
1678 // Let Sema figure out what we parsed.
1679 Actions.actOnObjCTypeArgsOrProtocolQualifiers(getCurScope(),
1680 baseType,
1681 lAngleLoc,
1682 identifiers,
1683 identifierLocs,
1684 rAngleLoc,
1685 typeArgsLAngleLoc,
1686 typeArgs,
1687 typeArgsRAngleLoc,
1688 protocolLAngleLoc,
1689 protocols,
1690 protocolRAngleLoc,
1691 warnOnIncompleteProtocols);
1692 return;
1693 }
1694
1695 // We parsed an identifier list but stumbled into non single identifiers, this
1696 // means we might (a) check that what we already parsed is a legitimate type
1697 // (not a protocol or unknown type) and (b) parse the remaining ones, which
1698 // must all be type args.
1699
1700 // Convert the identifiers into type arguments.
1701 bool invalid = false;
1702 IdentifierInfo *foundProtocolId = nullptr, *foundValidTypeId = nullptr;
1703 SourceLocation foundProtocolSrcLoc, foundValidTypeSrcLoc;
1704 SmallVector<IdentifierInfo *, 2> unknownTypeArgs;
1705 SmallVector<SourceLocation, 2> unknownTypeArgsLoc;
1706
1707 for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1708 ParsedType typeArg
1709 = Actions.getTypeName(*identifiers[i], identifierLocs[i], getCurScope());
1710 if (typeArg) {
1711 DeclSpec DS(AttrFactory);
1712 const char *prevSpec = nullptr;
1713 unsigned diagID;
1714 DS.SetTypeSpecType(TST_typename, identifierLocs[i], prevSpec, diagID,
1715 typeArg, Actions.getASTContext().getPrintingPolicy());
1716
1717 // Form a declarator to turn this into a type.
1718 Declarator D(DS, Declarator::TypeNameContext);
1719 TypeResult fullTypeArg = Actions.ActOnTypeName(getCurScope(), D);
1720 if (fullTypeArg.isUsable()) {
1721 typeArgs.push_back(fullTypeArg.get());
1722 if (!foundValidTypeId) {
1723 foundValidTypeId = identifiers[i];
1724 foundValidTypeSrcLoc = identifierLocs[i];
1725 }
1726 } else {
1727 invalid = true;
1728 unknownTypeArgs.push_back(identifiers[i]);
1729 unknownTypeArgsLoc.push_back(identifierLocs[i]);
1730 }
1731 } else {
1732 invalid = true;
1733 if (!Actions.LookupProtocol(identifiers[i], identifierLocs[i])) {
1734 unknownTypeArgs.push_back(identifiers[i]);
1735 unknownTypeArgsLoc.push_back(identifierLocs[i]);
1736 } else if (!foundProtocolId) {
1737 foundProtocolId = identifiers[i];
1738 foundProtocolSrcLoc = identifierLocs[i];
1739 }
1740 }
1741 }
1742
1743 // Continue parsing type-names.
1744 do {
1745 Token CurTypeTok = Tok;
1746 TypeResult typeArg = ParseTypeName();
1747
1748 // Consume the '...' for a pack expansion.
1749 SourceLocation ellipsisLoc;
1750 TryConsumeToken(tok::ellipsis, ellipsisLoc);
1751 if (typeArg.isUsable() && ellipsisLoc.isValid()) {
1752 typeArg = Actions.ActOnPackExpansion(typeArg.get(), ellipsisLoc);
1753 }
1754
1755 if (typeArg.isUsable()) {
1756 typeArgs.push_back(typeArg.get());
1757 if (!foundValidTypeId) {
1758 foundValidTypeId = CurTypeTok.getIdentifierInfo();
1759 foundValidTypeSrcLoc = CurTypeTok.getLocation();
1760 }
1761 } else {
1762 invalid = true;
1763 }
1764 } while (TryConsumeToken(tok::comma));
1765
1766 // Diagnose the mix between type args and protocols.
1767 if (foundProtocolId && foundValidTypeId)
1768 Actions.DiagnoseTypeArgsAndProtocols(foundProtocolId, foundProtocolSrcLoc,
1769 foundValidTypeId,
1770 foundValidTypeSrcLoc);
1771
1772 // Diagnose unknown arg types.
1773 ParsedType T;
1774 if (unknownTypeArgs.size())
1775 for (unsigned i = 0, e = unknownTypeArgsLoc.size(); i < e; ++i)
1776 Actions.DiagnoseUnknownTypeName(unknownTypeArgs[i], unknownTypeArgsLoc[i],
1777 getCurScope(), nullptr, T);
1778
1779 // Parse the closing '>'.
1780 SourceLocation rAngleLoc;
1781 (void)ParseGreaterThanInTemplateList(rAngleLoc, consumeLastToken,
1782 /*ObjCGenericList=*/true);
1783
1784 if (invalid) {
1785 typeArgs.clear();
1786 return;
1787 }
1788
1789 // Record left/right angle locations.
1790 typeArgsLAngleLoc = lAngleLoc;
1791 typeArgsRAngleLoc = rAngleLoc;
1792 }
1793
parseObjCTypeArgsAndProtocolQualifiers(ParsedType baseType,SourceLocation & typeArgsLAngleLoc,SmallVectorImpl<ParsedType> & typeArgs,SourceLocation & typeArgsRAngleLoc,SourceLocation & protocolLAngleLoc,SmallVectorImpl<Decl * > & protocols,SmallVectorImpl<SourceLocation> & protocolLocs,SourceLocation & protocolRAngleLoc,bool consumeLastToken)1794 void Parser::parseObjCTypeArgsAndProtocolQualifiers(
1795 ParsedType baseType,
1796 SourceLocation &typeArgsLAngleLoc,
1797 SmallVectorImpl<ParsedType> &typeArgs,
1798 SourceLocation &typeArgsRAngleLoc,
1799 SourceLocation &protocolLAngleLoc,
1800 SmallVectorImpl<Decl *> &protocols,
1801 SmallVectorImpl<SourceLocation> &protocolLocs,
1802 SourceLocation &protocolRAngleLoc,
1803 bool consumeLastToken) {
1804 assert(Tok.is(tok::less));
1805
1806 // Parse the first angle-bracket-delimited clause.
1807 parseObjCTypeArgsOrProtocolQualifiers(baseType,
1808 typeArgsLAngleLoc,
1809 typeArgs,
1810 typeArgsRAngleLoc,
1811 protocolLAngleLoc,
1812 protocols,
1813 protocolLocs,
1814 protocolRAngleLoc,
1815 consumeLastToken,
1816 /*warnOnIncompleteProtocols=*/false);
1817
1818 // An Objective-C object pointer followed by type arguments
1819 // can then be followed again by a set of protocol references, e.g.,
1820 // \c NSArray<NSView><NSTextDelegate>
1821 if ((consumeLastToken && Tok.is(tok::less)) ||
1822 (!consumeLastToken && NextToken().is(tok::less))) {
1823 // If we aren't consuming the last token, the prior '>' is still hanging
1824 // there. Consume it before we parse the protocol qualifiers.
1825 if (!consumeLastToken)
1826 ConsumeToken();
1827
1828 if (!protocols.empty()) {
1829 SkipUntilFlags skipFlags = SkipUntilFlags();
1830 if (!consumeLastToken)
1831 skipFlags = skipFlags | StopBeforeMatch;
1832 Diag(Tok, diag::err_objc_type_args_after_protocols)
1833 << SourceRange(protocolLAngleLoc, protocolRAngleLoc);
1834 SkipUntil(tok::greater, tok::greatergreater, skipFlags);
1835 } else {
1836 ParseObjCProtocolReferences(protocols, protocolLocs,
1837 /*WarnOnDeclarations=*/false,
1838 /*ForObjCContainer=*/false,
1839 protocolLAngleLoc, protocolRAngleLoc,
1840 consumeLastToken);
1841 }
1842 }
1843 }
1844
parseObjCTypeArgsAndProtocolQualifiers(SourceLocation loc,ParsedType type,bool consumeLastToken,SourceLocation & endLoc)1845 TypeResult Parser::parseObjCTypeArgsAndProtocolQualifiers(
1846 SourceLocation loc,
1847 ParsedType type,
1848 bool consumeLastToken,
1849 SourceLocation &endLoc) {
1850 assert(Tok.is(tok::less));
1851 SourceLocation typeArgsLAngleLoc;
1852 SmallVector<ParsedType, 4> typeArgs;
1853 SourceLocation typeArgsRAngleLoc;
1854 SourceLocation protocolLAngleLoc;
1855 SmallVector<Decl *, 4> protocols;
1856 SmallVector<SourceLocation, 4> protocolLocs;
1857 SourceLocation protocolRAngleLoc;
1858
1859 // Parse type arguments and protocol qualifiers.
1860 parseObjCTypeArgsAndProtocolQualifiers(type, typeArgsLAngleLoc, typeArgs,
1861 typeArgsRAngleLoc, protocolLAngleLoc,
1862 protocols, protocolLocs,
1863 protocolRAngleLoc, consumeLastToken);
1864
1865 // Compute the location of the last token.
1866 if (consumeLastToken)
1867 endLoc = PrevTokLocation;
1868 else
1869 endLoc = Tok.getLocation();
1870
1871 return Actions.actOnObjCTypeArgsAndProtocolQualifiers(
1872 getCurScope(),
1873 loc,
1874 type,
1875 typeArgsLAngleLoc,
1876 typeArgs,
1877 typeArgsRAngleLoc,
1878 protocolLAngleLoc,
1879 protocols,
1880 protocolLocs,
1881 protocolRAngleLoc);
1882 }
1883
HelperActionsForIvarDeclarations(Decl * interfaceDecl,SourceLocation atLoc,BalancedDelimiterTracker & T,SmallVectorImpl<Decl * > & AllIvarDecls,bool RBraceMissing)1884 void Parser::HelperActionsForIvarDeclarations(Decl *interfaceDecl, SourceLocation atLoc,
1885 BalancedDelimiterTracker &T,
1886 SmallVectorImpl<Decl *> &AllIvarDecls,
1887 bool RBraceMissing) {
1888 if (!RBraceMissing)
1889 T.consumeClose();
1890
1891 Actions.ActOnObjCContainerStartDefinition(interfaceDecl);
1892 Actions.ActOnLastBitfield(T.getCloseLocation(), AllIvarDecls);
1893 Actions.ActOnObjCContainerFinishDefinition();
1894 // Call ActOnFields() even if we don't have any decls. This is useful
1895 // for code rewriting tools that need to be aware of the empty list.
1896 Actions.ActOnFields(getCurScope(), atLoc, interfaceDecl,
1897 AllIvarDecls,
1898 T.getOpenLocation(), T.getCloseLocation(), nullptr);
1899 }
1900
1901 /// objc-class-instance-variables:
1902 /// '{' objc-instance-variable-decl-list[opt] '}'
1903 ///
1904 /// objc-instance-variable-decl-list:
1905 /// objc-visibility-spec
1906 /// objc-instance-variable-decl ';'
1907 /// ';'
1908 /// objc-instance-variable-decl-list objc-visibility-spec
1909 /// objc-instance-variable-decl-list objc-instance-variable-decl ';'
1910 /// objc-instance-variable-decl-list ';'
1911 ///
1912 /// objc-visibility-spec:
1913 /// @private
1914 /// @protected
1915 /// @public
1916 /// @package [OBJC2]
1917 ///
1918 /// objc-instance-variable-decl:
1919 /// struct-declaration
1920 ///
ParseObjCClassInstanceVariables(Decl * interfaceDecl,tok::ObjCKeywordKind visibility,SourceLocation atLoc)1921 void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl,
1922 tok::ObjCKeywordKind visibility,
1923 SourceLocation atLoc) {
1924 assert(Tok.is(tok::l_brace) && "expected {");
1925 SmallVector<Decl *, 32> AllIvarDecls;
1926
1927 ParseScope ClassScope(this, Scope::DeclScope|Scope::ClassScope);
1928 ObjCDeclContextSwitch ObjCDC(*this);
1929
1930 BalancedDelimiterTracker T(*this, tok::l_brace);
1931 T.consumeOpen();
1932 // While we still have something to read, read the instance variables.
1933 while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
1934 // Each iteration of this loop reads one objc-instance-variable-decl.
1935
1936 // Check for extraneous top-level semicolon.
1937 if (Tok.is(tok::semi)) {
1938 ConsumeExtraSemi(InstanceVariableList);
1939 continue;
1940 }
1941
1942 // Set the default visibility to private.
1943 if (TryConsumeToken(tok::at)) { // parse objc-visibility-spec
1944 if (Tok.is(tok::code_completion)) {
1945 Actions.CodeCompleteObjCAtVisibility(getCurScope());
1946 return cutOffParsing();
1947 }
1948
1949 switch (Tok.getObjCKeywordID()) {
1950 case tok::objc_private:
1951 case tok::objc_public:
1952 case tok::objc_protected:
1953 case tok::objc_package:
1954 visibility = Tok.getObjCKeywordID();
1955 ConsumeToken();
1956 continue;
1957
1958 case tok::objc_end:
1959 Diag(Tok, diag::err_objc_unexpected_atend);
1960 Tok.setLocation(Tok.getLocation().getLocWithOffset(-1));
1961 Tok.setKind(tok::at);
1962 Tok.setLength(1);
1963 PP.EnterToken(Tok);
1964 HelperActionsForIvarDeclarations(interfaceDecl, atLoc,
1965 T, AllIvarDecls, true);
1966 return;
1967
1968 default:
1969 Diag(Tok, diag::err_objc_illegal_visibility_spec);
1970 continue;
1971 }
1972 }
1973
1974 if (Tok.is(tok::code_completion)) {
1975 Actions.CodeCompleteOrdinaryName(getCurScope(),
1976 Sema::PCC_ObjCInstanceVariableList);
1977 return cutOffParsing();
1978 }
1979
1980 auto ObjCIvarCallback = [&](ParsingFieldDeclarator &FD) {
1981 Actions.ActOnObjCContainerStartDefinition(interfaceDecl);
1982 // Install the declarator into the interface decl.
1983 FD.D.setObjCIvar(true);
1984 Decl *Field = Actions.ActOnIvar(
1985 getCurScope(), FD.D.getDeclSpec().getSourceRange().getBegin(), FD.D,
1986 FD.BitfieldSize, visibility);
1987 Actions.ActOnObjCContainerFinishDefinition();
1988 if (Field)
1989 AllIvarDecls.push_back(Field);
1990 FD.complete(Field);
1991 };
1992
1993 // Parse all the comma separated declarators.
1994 ParsingDeclSpec DS(*this);
1995 ParseStructDeclaration(DS, ObjCIvarCallback);
1996
1997 if (Tok.is(tok::semi)) {
1998 ConsumeToken();
1999 } else {
2000 Diag(Tok, diag::err_expected_semi_decl_list);
2001 // Skip to end of block or statement
2002 SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
2003 }
2004 }
2005 HelperActionsForIvarDeclarations(interfaceDecl, atLoc,
2006 T, AllIvarDecls, false);
2007 }
2008
2009 /// objc-protocol-declaration:
2010 /// objc-protocol-definition
2011 /// objc-protocol-forward-reference
2012 ///
2013 /// objc-protocol-definition:
2014 /// \@protocol identifier
2015 /// objc-protocol-refs[opt]
2016 /// objc-interface-decl-list
2017 /// \@end
2018 ///
2019 /// objc-protocol-forward-reference:
2020 /// \@protocol identifier-list ';'
2021 ///
2022 /// "\@protocol identifier ;" should be resolved as "\@protocol
2023 /// identifier-list ;": objc-interface-decl-list may not start with a
2024 /// semicolon in the first alternative if objc-protocol-refs are omitted.
2025 Parser::DeclGroupPtrTy
ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,ParsedAttributes & attrs)2026 Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
2027 ParsedAttributes &attrs) {
2028 assert(Tok.isObjCAtKeyword(tok::objc_protocol) &&
2029 "ParseObjCAtProtocolDeclaration(): Expected @protocol");
2030 ConsumeToken(); // the "protocol" identifier
2031
2032 if (Tok.is(tok::code_completion)) {
2033 Actions.CodeCompleteObjCProtocolDecl(getCurScope());
2034 cutOffParsing();
2035 return nullptr;
2036 }
2037
2038 MaybeSkipAttributes(tok::objc_protocol);
2039
2040 if (Tok.isNot(tok::identifier)) {
2041 Diag(Tok, diag::err_expected) << tok::identifier; // missing protocol name.
2042 return nullptr;
2043 }
2044 // Save the protocol name, then consume it.
2045 IdentifierInfo *protocolName = Tok.getIdentifierInfo();
2046 SourceLocation nameLoc = ConsumeToken();
2047
2048 if (TryConsumeToken(tok::semi)) { // forward declaration of one protocol.
2049 IdentifierLocPair ProtoInfo(protocolName, nameLoc);
2050 return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtoInfo,
2051 attrs.getList());
2052 }
2053
2054 CheckNestedObjCContexts(AtLoc);
2055
2056 if (Tok.is(tok::comma)) { // list of forward declarations.
2057 SmallVector<IdentifierLocPair, 8> ProtocolRefs;
2058 ProtocolRefs.push_back(std::make_pair(protocolName, nameLoc));
2059
2060 // Parse the list of forward declarations.
2061 while (1) {
2062 ConsumeToken(); // the ','
2063 if (Tok.isNot(tok::identifier)) {
2064 Diag(Tok, diag::err_expected) << tok::identifier;
2065 SkipUntil(tok::semi);
2066 return nullptr;
2067 }
2068 ProtocolRefs.push_back(IdentifierLocPair(Tok.getIdentifierInfo(),
2069 Tok.getLocation()));
2070 ConsumeToken(); // the identifier
2071
2072 if (Tok.isNot(tok::comma))
2073 break;
2074 }
2075 // Consume the ';'.
2076 if (ExpectAndConsume(tok::semi, diag::err_expected_after, "@protocol"))
2077 return nullptr;
2078
2079 return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtocolRefs,
2080 attrs.getList());
2081 }
2082
2083 // Last, and definitely not least, parse a protocol declaration.
2084 SourceLocation LAngleLoc, EndProtoLoc;
2085
2086 SmallVector<Decl *, 8> ProtocolRefs;
2087 SmallVector<SourceLocation, 8> ProtocolLocs;
2088 if (Tok.is(tok::less) &&
2089 ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, false, true,
2090 LAngleLoc, EndProtoLoc,
2091 /*consumeLastToken=*/true))
2092 return nullptr;
2093
2094 Decl *ProtoType =
2095 Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc,
2096 ProtocolRefs.data(),
2097 ProtocolRefs.size(),
2098 ProtocolLocs.data(),
2099 EndProtoLoc, attrs.getList());
2100
2101 ParseObjCInterfaceDeclList(tok::objc_protocol, ProtoType);
2102 return Actions.ConvertDeclToDeclGroup(ProtoType);
2103 }
2104
2105 /// objc-implementation:
2106 /// objc-class-implementation-prologue
2107 /// objc-category-implementation-prologue
2108 ///
2109 /// objc-class-implementation-prologue:
2110 /// @implementation identifier objc-superclass[opt]
2111 /// objc-class-instance-variables[opt]
2112 ///
2113 /// objc-category-implementation-prologue:
2114 /// @implementation identifier ( identifier )
2115 Parser::DeclGroupPtrTy
ParseObjCAtImplementationDeclaration(SourceLocation AtLoc)2116 Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc) {
2117 assert(Tok.isObjCAtKeyword(tok::objc_implementation) &&
2118 "ParseObjCAtImplementationDeclaration(): Expected @implementation");
2119 CheckNestedObjCContexts(AtLoc);
2120 ConsumeToken(); // the "implementation" identifier
2121
2122 // Code completion after '@implementation'.
2123 if (Tok.is(tok::code_completion)) {
2124 Actions.CodeCompleteObjCImplementationDecl(getCurScope());
2125 cutOffParsing();
2126 return nullptr;
2127 }
2128
2129 MaybeSkipAttributes(tok::objc_implementation);
2130
2131 if (Tok.isNot(tok::identifier)) {
2132 Diag(Tok, diag::err_expected)
2133 << tok::identifier; // missing class or category name.
2134 return nullptr;
2135 }
2136 // We have a class or category name - consume it.
2137 IdentifierInfo *nameId = Tok.getIdentifierInfo();
2138 SourceLocation nameLoc = ConsumeToken(); // consume class or category name
2139 Decl *ObjCImpDecl = nullptr;
2140
2141 // Neither a type parameter list nor a list of protocol references is
2142 // permitted here. Parse and diagnose them.
2143 if (Tok.is(tok::less)) {
2144 SourceLocation lAngleLoc, rAngleLoc;
2145 SmallVector<IdentifierLocPair, 8> protocolIdents;
2146 SourceLocation diagLoc = Tok.getLocation();
2147 ObjCTypeParamListScope typeParamScope(Actions, getCurScope());
2148 if (parseObjCTypeParamListOrProtocolRefs(typeParamScope, lAngleLoc,
2149 protocolIdents, rAngleLoc)) {
2150 Diag(diagLoc, diag::err_objc_parameterized_implementation)
2151 << SourceRange(diagLoc, PrevTokLocation);
2152 } else if (lAngleLoc.isValid()) {
2153 Diag(lAngleLoc, diag::err_unexpected_protocol_qualifier)
2154 << FixItHint::CreateRemoval(SourceRange(lAngleLoc, rAngleLoc));
2155 }
2156 }
2157
2158 if (Tok.is(tok::l_paren)) {
2159 // we have a category implementation.
2160 ConsumeParen();
2161 SourceLocation categoryLoc, rparenLoc;
2162 IdentifierInfo *categoryId = nullptr;
2163
2164 if (Tok.is(tok::code_completion)) {
2165 Actions.CodeCompleteObjCImplementationCategory(getCurScope(), nameId, nameLoc);
2166 cutOffParsing();
2167 return nullptr;
2168 }
2169
2170 if (Tok.is(tok::identifier)) {
2171 categoryId = Tok.getIdentifierInfo();
2172 categoryLoc = ConsumeToken();
2173 } else {
2174 Diag(Tok, diag::err_expected)
2175 << tok::identifier; // missing category name.
2176 return nullptr;
2177 }
2178 if (Tok.isNot(tok::r_paren)) {
2179 Diag(Tok, diag::err_expected) << tok::r_paren;
2180 SkipUntil(tok::r_paren); // don't stop at ';'
2181 return nullptr;
2182 }
2183 rparenLoc = ConsumeParen();
2184 if (Tok.is(tok::less)) { // we have illegal '<' try to recover
2185 Diag(Tok, diag::err_unexpected_protocol_qualifier);
2186 SourceLocation protocolLAngleLoc, protocolRAngleLoc;
2187 SmallVector<Decl *, 4> protocols;
2188 SmallVector<SourceLocation, 4> protocolLocs;
2189 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
2190 /*warnOnIncompleteProtocols=*/false,
2191 /*ForObjCContainer=*/false,
2192 protocolLAngleLoc, protocolRAngleLoc,
2193 /*consumeLastToken=*/true);
2194 }
2195 ObjCImpDecl = Actions.ActOnStartCategoryImplementation(
2196 AtLoc, nameId, nameLoc, categoryId,
2197 categoryLoc);
2198
2199 } else {
2200 // We have a class implementation
2201 SourceLocation superClassLoc;
2202 IdentifierInfo *superClassId = nullptr;
2203 if (TryConsumeToken(tok::colon)) {
2204 // We have a super class
2205 if (Tok.isNot(tok::identifier)) {
2206 Diag(Tok, diag::err_expected)
2207 << tok::identifier; // missing super class name.
2208 return nullptr;
2209 }
2210 superClassId = Tok.getIdentifierInfo();
2211 superClassLoc = ConsumeToken(); // Consume super class name
2212 }
2213 ObjCImpDecl = Actions.ActOnStartClassImplementation(
2214 AtLoc, nameId, nameLoc,
2215 superClassId, superClassLoc);
2216
2217 if (Tok.is(tok::l_brace)) // we have ivars
2218 ParseObjCClassInstanceVariables(ObjCImpDecl, tok::objc_private, AtLoc);
2219 else if (Tok.is(tok::less)) { // we have illegal '<' try to recover
2220 Diag(Tok, diag::err_unexpected_protocol_qualifier);
2221
2222 SourceLocation protocolLAngleLoc, protocolRAngleLoc;
2223 SmallVector<Decl *, 4> protocols;
2224 SmallVector<SourceLocation, 4> protocolLocs;
2225 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
2226 /*warnOnIncompleteProtocols=*/false,
2227 /*ForObjCContainer=*/false,
2228 protocolLAngleLoc, protocolRAngleLoc,
2229 /*consumeLastToken=*/true);
2230 }
2231 }
2232 assert(ObjCImpDecl);
2233
2234 SmallVector<Decl *, 8> DeclsInGroup;
2235
2236 {
2237 ObjCImplParsingDataRAII ObjCImplParsing(*this, ObjCImpDecl);
2238 while (!ObjCImplParsing.isFinished() && !isEofOrEom()) {
2239 ParsedAttributesWithRange attrs(AttrFactory);
2240 MaybeParseCXX11Attributes(attrs);
2241 MaybeParseMicrosoftAttributes(attrs);
2242 if (DeclGroupPtrTy DGP = ParseExternalDeclaration(attrs)) {
2243 DeclGroupRef DG = DGP.get();
2244 DeclsInGroup.append(DG.begin(), DG.end());
2245 }
2246 }
2247 }
2248
2249 return Actions.ActOnFinishObjCImplementation(ObjCImpDecl, DeclsInGroup);
2250 }
2251
2252 Parser::DeclGroupPtrTy
ParseObjCAtEndDeclaration(SourceRange atEnd)2253 Parser::ParseObjCAtEndDeclaration(SourceRange atEnd) {
2254 assert(Tok.isObjCAtKeyword(tok::objc_end) &&
2255 "ParseObjCAtEndDeclaration(): Expected @end");
2256 ConsumeToken(); // the "end" identifier
2257 if (CurParsedObjCImpl)
2258 CurParsedObjCImpl->finish(atEnd);
2259 else
2260 // missing @implementation
2261 Diag(atEnd.getBegin(), diag::err_expected_objc_container);
2262 return nullptr;
2263 }
2264
~ObjCImplParsingDataRAII()2265 Parser::ObjCImplParsingDataRAII::~ObjCImplParsingDataRAII() {
2266 if (!Finished) {
2267 finish(P.Tok.getLocation());
2268 if (P.isEofOrEom()) {
2269 P.Diag(P.Tok, diag::err_objc_missing_end)
2270 << FixItHint::CreateInsertion(P.Tok.getLocation(), "\n@end\n");
2271 P.Diag(Dcl->getLocStart(), diag::note_objc_container_start)
2272 << Sema::OCK_Implementation;
2273 }
2274 }
2275 P.CurParsedObjCImpl = nullptr;
2276 assert(LateParsedObjCMethods.empty());
2277 }
2278
finish(SourceRange AtEnd)2279 void Parser::ObjCImplParsingDataRAII::finish(SourceRange AtEnd) {
2280 assert(!Finished);
2281 P.Actions.DefaultSynthesizeProperties(P.getCurScope(), Dcl);
2282 for (size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
2283 P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
2284 true/*Methods*/);
2285
2286 P.Actions.ActOnAtEnd(P.getCurScope(), AtEnd);
2287
2288 if (HasCFunction)
2289 for (size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
2290 P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
2291 false/*c-functions*/);
2292
2293 /// \brief Clear and free the cached objc methods.
2294 for (LateParsedObjCMethodContainer::iterator
2295 I = LateParsedObjCMethods.begin(),
2296 E = LateParsedObjCMethods.end(); I != E; ++I)
2297 delete *I;
2298 LateParsedObjCMethods.clear();
2299
2300 Finished = true;
2301 }
2302
2303 /// compatibility-alias-decl:
2304 /// @compatibility_alias alias-name class-name ';'
2305 ///
ParseObjCAtAliasDeclaration(SourceLocation atLoc)2306 Decl *Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) {
2307 assert(Tok.isObjCAtKeyword(tok::objc_compatibility_alias) &&
2308 "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias");
2309 ConsumeToken(); // consume compatibility_alias
2310 if (Tok.isNot(tok::identifier)) {
2311 Diag(Tok, diag::err_expected) << tok::identifier;
2312 return nullptr;
2313 }
2314 IdentifierInfo *aliasId = Tok.getIdentifierInfo();
2315 SourceLocation aliasLoc = ConsumeToken(); // consume alias-name
2316 if (Tok.isNot(tok::identifier)) {
2317 Diag(Tok, diag::err_expected) << tok::identifier;
2318 return nullptr;
2319 }
2320 IdentifierInfo *classId = Tok.getIdentifierInfo();
2321 SourceLocation classLoc = ConsumeToken(); // consume class-name;
2322 ExpectAndConsume(tok::semi, diag::err_expected_after, "@compatibility_alias");
2323 return Actions.ActOnCompatibilityAlias(atLoc, aliasId, aliasLoc,
2324 classId, classLoc);
2325 }
2326
2327 /// property-synthesis:
2328 /// @synthesize property-ivar-list ';'
2329 ///
2330 /// property-ivar-list:
2331 /// property-ivar
2332 /// property-ivar-list ',' property-ivar
2333 ///
2334 /// property-ivar:
2335 /// identifier
2336 /// identifier '=' identifier
2337 ///
ParseObjCPropertySynthesize(SourceLocation atLoc)2338 Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
2339 assert(Tok.isObjCAtKeyword(tok::objc_synthesize) &&
2340 "ParseObjCPropertySynthesize(): Expected '@synthesize'");
2341 ConsumeToken(); // consume synthesize
2342
2343 while (true) {
2344 if (Tok.is(tok::code_completion)) {
2345 Actions.CodeCompleteObjCPropertyDefinition(getCurScope());
2346 cutOffParsing();
2347 return nullptr;
2348 }
2349
2350 if (Tok.isNot(tok::identifier)) {
2351 Diag(Tok, diag::err_synthesized_property_name);
2352 SkipUntil(tok::semi);
2353 return nullptr;
2354 }
2355
2356 IdentifierInfo *propertyIvar = nullptr;
2357 IdentifierInfo *propertyId = Tok.getIdentifierInfo();
2358 SourceLocation propertyLoc = ConsumeToken(); // consume property name
2359 SourceLocation propertyIvarLoc;
2360 if (TryConsumeToken(tok::equal)) {
2361 // property '=' ivar-name
2362 if (Tok.is(tok::code_completion)) {
2363 Actions.CodeCompleteObjCPropertySynthesizeIvar(getCurScope(), propertyId);
2364 cutOffParsing();
2365 return nullptr;
2366 }
2367
2368 if (Tok.isNot(tok::identifier)) {
2369 Diag(Tok, diag::err_expected) << tok::identifier;
2370 break;
2371 }
2372 propertyIvar = Tok.getIdentifierInfo();
2373 propertyIvarLoc = ConsumeToken(); // consume ivar-name
2374 }
2375 Actions.ActOnPropertyImplDecl(
2376 getCurScope(), atLoc, propertyLoc, true,
2377 propertyId, propertyIvar, propertyIvarLoc,
2378 ObjCPropertyQueryKind::OBJC_PR_query_unknown);
2379 if (Tok.isNot(tok::comma))
2380 break;
2381 ConsumeToken(); // consume ','
2382 }
2383 ExpectAndConsume(tok::semi, diag::err_expected_after, "@synthesize");
2384 return nullptr;
2385 }
2386
2387 /// property-dynamic:
2388 /// @dynamic property-list
2389 ///
2390 /// property-list:
2391 /// identifier
2392 /// property-list ',' identifier
2393 ///
ParseObjCPropertyDynamic(SourceLocation atLoc)2394 Decl *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
2395 assert(Tok.isObjCAtKeyword(tok::objc_dynamic) &&
2396 "ParseObjCPropertyDynamic(): Expected '@dynamic'");
2397 ConsumeToken(); // consume dynamic
2398
2399 bool isClassProperty = false;
2400 if (Tok.is(tok::l_paren)) {
2401 ConsumeParen();
2402 const IdentifierInfo *II = Tok.getIdentifierInfo();
2403
2404 if (!II) {
2405 Diag(Tok, diag::err_objc_expected_property_attr) << II;
2406 SkipUntil(tok::r_paren, StopAtSemi);
2407 } else {
2408 SourceLocation AttrName = ConsumeToken(); // consume attribute name
2409 if (II->isStr("class")) {
2410 isClassProperty = true;
2411 if (Tok.isNot(tok::r_paren)) {
2412 Diag(Tok, diag::err_expected) << tok::r_paren;
2413 SkipUntil(tok::r_paren, StopAtSemi);
2414 } else
2415 ConsumeParen();
2416 } else {
2417 Diag(AttrName, diag::err_objc_expected_property_attr) << II;
2418 SkipUntil(tok::r_paren, StopAtSemi);
2419 }
2420 }
2421 }
2422
2423 while (true) {
2424 if (Tok.is(tok::code_completion)) {
2425 Actions.CodeCompleteObjCPropertyDefinition(getCurScope());
2426 cutOffParsing();
2427 return nullptr;
2428 }
2429
2430 if (Tok.isNot(tok::identifier)) {
2431 Diag(Tok, diag::err_expected) << tok::identifier;
2432 SkipUntil(tok::semi);
2433 return nullptr;
2434 }
2435
2436 IdentifierInfo *propertyId = Tok.getIdentifierInfo();
2437 SourceLocation propertyLoc = ConsumeToken(); // consume property name
2438 Actions.ActOnPropertyImplDecl(
2439 getCurScope(), atLoc, propertyLoc, false,
2440 propertyId, nullptr, SourceLocation(),
2441 isClassProperty ? ObjCPropertyQueryKind::OBJC_PR_query_class :
2442 ObjCPropertyQueryKind::OBJC_PR_query_unknown);
2443
2444 if (Tok.isNot(tok::comma))
2445 break;
2446 ConsumeToken(); // consume ','
2447 }
2448 ExpectAndConsume(tok::semi, diag::err_expected_after, "@dynamic");
2449 return nullptr;
2450 }
2451
2452 /// objc-throw-statement:
2453 /// throw expression[opt];
2454 ///
ParseObjCThrowStmt(SourceLocation atLoc)2455 StmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) {
2456 ExprResult Res;
2457 ConsumeToken(); // consume throw
2458 if (Tok.isNot(tok::semi)) {
2459 Res = ParseExpression();
2460 if (Res.isInvalid()) {
2461 SkipUntil(tok::semi);
2462 return StmtError();
2463 }
2464 }
2465 // consume ';'
2466 ExpectAndConsume(tok::semi, diag::err_expected_after, "@throw");
2467 return Actions.ActOnObjCAtThrowStmt(atLoc, Res.get(), getCurScope());
2468 }
2469
2470 /// objc-synchronized-statement:
2471 /// @synchronized '(' expression ')' compound-statement
2472 ///
2473 StmtResult
ParseObjCSynchronizedStmt(SourceLocation atLoc)2474 Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
2475 ConsumeToken(); // consume synchronized
2476 if (Tok.isNot(tok::l_paren)) {
2477 Diag(Tok, diag::err_expected_lparen_after) << "@synchronized";
2478 return StmtError();
2479 }
2480
2481 // The operand is surrounded with parentheses.
2482 ConsumeParen(); // '('
2483 ExprResult operand(ParseExpression());
2484
2485 if (Tok.is(tok::r_paren)) {
2486 ConsumeParen(); // ')'
2487 } else {
2488 if (!operand.isInvalid())
2489 Diag(Tok, diag::err_expected) << tok::r_paren;
2490
2491 // Skip forward until we see a left brace, but don't consume it.
2492 SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch);
2493 }
2494
2495 // Require a compound statement.
2496 if (Tok.isNot(tok::l_brace)) {
2497 if (!operand.isInvalid())
2498 Diag(Tok, diag::err_expected) << tok::l_brace;
2499 return StmtError();
2500 }
2501
2502 // Check the @synchronized operand now.
2503 if (!operand.isInvalid())
2504 operand = Actions.ActOnObjCAtSynchronizedOperand(atLoc, operand.get());
2505
2506 // Parse the compound statement within a new scope.
2507 ParseScope bodyScope(this, Scope::DeclScope);
2508 StmtResult body(ParseCompoundStatementBody());
2509 bodyScope.Exit();
2510
2511 // If there was a semantic or parse error earlier with the
2512 // operand, fail now.
2513 if (operand.isInvalid())
2514 return StmtError();
2515
2516 if (body.isInvalid())
2517 body = Actions.ActOnNullStmt(Tok.getLocation());
2518
2519 return Actions.ActOnObjCAtSynchronizedStmt(atLoc, operand.get(), body.get());
2520 }
2521
2522 /// objc-try-catch-statement:
2523 /// @try compound-statement objc-catch-list[opt]
2524 /// @try compound-statement objc-catch-list[opt] @finally compound-statement
2525 ///
2526 /// objc-catch-list:
2527 /// @catch ( parameter-declaration ) compound-statement
2528 /// objc-catch-list @catch ( catch-parameter-declaration ) compound-statement
2529 /// catch-parameter-declaration:
2530 /// parameter-declaration
2531 /// '...' [OBJC2]
2532 ///
ParseObjCTryStmt(SourceLocation atLoc)2533 StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
2534 bool catch_or_finally_seen = false;
2535
2536 ConsumeToken(); // consume try
2537 if (Tok.isNot(tok::l_brace)) {
2538 Diag(Tok, diag::err_expected) << tok::l_brace;
2539 return StmtError();
2540 }
2541 StmtVector CatchStmts;
2542 StmtResult FinallyStmt;
2543 ParseScope TryScope(this, Scope::DeclScope);
2544 StmtResult TryBody(ParseCompoundStatementBody());
2545 TryScope.Exit();
2546 if (TryBody.isInvalid())
2547 TryBody = Actions.ActOnNullStmt(Tok.getLocation());
2548
2549 while (Tok.is(tok::at)) {
2550 // At this point, we need to lookahead to determine if this @ is the start
2551 // of an @catch or @finally. We don't want to consume the @ token if this
2552 // is an @try or @encode or something else.
2553 Token AfterAt = GetLookAheadToken(1);
2554 if (!AfterAt.isObjCAtKeyword(tok::objc_catch) &&
2555 !AfterAt.isObjCAtKeyword(tok::objc_finally))
2556 break;
2557
2558 SourceLocation AtCatchFinallyLoc = ConsumeToken();
2559 if (Tok.isObjCAtKeyword(tok::objc_catch)) {
2560 Decl *FirstPart = nullptr;
2561 ConsumeToken(); // consume catch
2562 if (Tok.is(tok::l_paren)) {
2563 ConsumeParen();
2564 ParseScope CatchScope(this, Scope::DeclScope|Scope::AtCatchScope);
2565 if (Tok.isNot(tok::ellipsis)) {
2566 DeclSpec DS(AttrFactory);
2567 ParseDeclarationSpecifiers(DS);
2568 Declarator ParmDecl(DS, Declarator::ObjCCatchContext);
2569 ParseDeclarator(ParmDecl);
2570
2571 // Inform the actions module about the declarator, so it
2572 // gets added to the current scope.
2573 FirstPart = Actions.ActOnObjCExceptionDecl(getCurScope(), ParmDecl);
2574 } else
2575 ConsumeToken(); // consume '...'
2576
2577 SourceLocation RParenLoc;
2578
2579 if (Tok.is(tok::r_paren))
2580 RParenLoc = ConsumeParen();
2581 else // Skip over garbage, until we get to ')'. Eat the ')'.
2582 SkipUntil(tok::r_paren, StopAtSemi);
2583
2584 StmtResult CatchBody(true);
2585 if (Tok.is(tok::l_brace))
2586 CatchBody = ParseCompoundStatementBody();
2587 else
2588 Diag(Tok, diag::err_expected) << tok::l_brace;
2589 if (CatchBody.isInvalid())
2590 CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
2591
2592 StmtResult Catch = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc,
2593 RParenLoc,
2594 FirstPart,
2595 CatchBody.get());
2596 if (!Catch.isInvalid())
2597 CatchStmts.push_back(Catch.get());
2598
2599 } else {
2600 Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
2601 << "@catch clause";
2602 return StmtError();
2603 }
2604 catch_or_finally_seen = true;
2605 } else {
2606 assert(Tok.isObjCAtKeyword(tok::objc_finally) && "Lookahead confused?");
2607 ConsumeToken(); // consume finally
2608 ParseScope FinallyScope(this, Scope::DeclScope);
2609
2610 StmtResult FinallyBody(true);
2611 if (Tok.is(tok::l_brace))
2612 FinallyBody = ParseCompoundStatementBody();
2613 else
2614 Diag(Tok, diag::err_expected) << tok::l_brace;
2615 if (FinallyBody.isInvalid())
2616 FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
2617 FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
2618 FinallyBody.get());
2619 catch_or_finally_seen = true;
2620 break;
2621 }
2622 }
2623 if (!catch_or_finally_seen) {
2624 Diag(atLoc, diag::err_missing_catch_finally);
2625 return StmtError();
2626 }
2627
2628 return Actions.ActOnObjCAtTryStmt(atLoc, TryBody.get(),
2629 CatchStmts,
2630 FinallyStmt.get());
2631 }
2632
2633 /// objc-autoreleasepool-statement:
2634 /// @autoreleasepool compound-statement
2635 ///
2636 StmtResult
ParseObjCAutoreleasePoolStmt(SourceLocation atLoc)2637 Parser::ParseObjCAutoreleasePoolStmt(SourceLocation atLoc) {
2638 ConsumeToken(); // consume autoreleasepool
2639 if (Tok.isNot(tok::l_brace)) {
2640 Diag(Tok, diag::err_expected) << tok::l_brace;
2641 return StmtError();
2642 }
2643 // Enter a scope to hold everything within the compound stmt. Compound
2644 // statements can always hold declarations.
2645 ParseScope BodyScope(this, Scope::DeclScope);
2646
2647 StmtResult AutoreleasePoolBody(ParseCompoundStatementBody());
2648
2649 BodyScope.Exit();
2650 if (AutoreleasePoolBody.isInvalid())
2651 AutoreleasePoolBody = Actions.ActOnNullStmt(Tok.getLocation());
2652 return Actions.ActOnObjCAutoreleasePoolStmt(atLoc,
2653 AutoreleasePoolBody.get());
2654 }
2655
2656 /// StashAwayMethodOrFunctionBodyTokens - Consume the tokens and store them
2657 /// for later parsing.
StashAwayMethodOrFunctionBodyTokens(Decl * MDecl)2658 void Parser::StashAwayMethodOrFunctionBodyTokens(Decl *MDecl) {
2659 if (SkipFunctionBodies && (!MDecl || Actions.canSkipFunctionBody(MDecl)) &&
2660 trySkippingFunctionBody()) {
2661 Actions.ActOnSkippedFunctionBody(MDecl);
2662 return;
2663 }
2664
2665 LexedMethod* LM = new LexedMethod(this, MDecl);
2666 CurParsedObjCImpl->LateParsedObjCMethods.push_back(LM);
2667 CachedTokens &Toks = LM->Toks;
2668 // Begin by storing the '{' or 'try' or ':' token.
2669 Toks.push_back(Tok);
2670 if (Tok.is(tok::kw_try)) {
2671 ConsumeToken();
2672 if (Tok.is(tok::colon)) {
2673 Toks.push_back(Tok);
2674 ConsumeToken();
2675 while (Tok.isNot(tok::l_brace)) {
2676 ConsumeAndStoreUntil(tok::l_paren, Toks, /*StopAtSemi=*/false);
2677 ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false);
2678 }
2679 }
2680 Toks.push_back(Tok); // also store '{'
2681 }
2682 else if (Tok.is(tok::colon)) {
2683 ConsumeToken();
2684 // FIXME: This is wrong, due to C++11 braced initialization.
2685 while (Tok.isNot(tok::l_brace)) {
2686 ConsumeAndStoreUntil(tok::l_paren, Toks, /*StopAtSemi=*/false);
2687 ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false);
2688 }
2689 Toks.push_back(Tok); // also store '{'
2690 }
2691 ConsumeBrace();
2692 // Consume everything up to (and including) the matching right brace.
2693 ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
2694 while (Tok.is(tok::kw_catch)) {
2695 ConsumeAndStoreUntil(tok::l_brace, Toks, /*StopAtSemi=*/false);
2696 ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
2697 }
2698 }
2699
2700 /// objc-method-def: objc-method-proto ';'[opt] '{' body '}'
2701 ///
ParseObjCMethodDefinition()2702 Decl *Parser::ParseObjCMethodDefinition() {
2703 Decl *MDecl = ParseObjCMethodPrototype();
2704
2705 PrettyDeclStackTraceEntry CrashInfo(Actions, MDecl, Tok.getLocation(),
2706 "parsing Objective-C method");
2707
2708 // parse optional ';'
2709 if (Tok.is(tok::semi)) {
2710 if (CurParsedObjCImpl) {
2711 Diag(Tok, diag::warn_semicolon_before_method_body)
2712 << FixItHint::CreateRemoval(Tok.getLocation());
2713 }
2714 ConsumeToken();
2715 }
2716
2717 // We should have an opening brace now.
2718 if (Tok.isNot(tok::l_brace)) {
2719 Diag(Tok, diag::err_expected_method_body);
2720
2721 // Skip over garbage, until we get to '{'. Don't eat the '{'.
2722 SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch);
2723
2724 // If we didn't find the '{', bail out.
2725 if (Tok.isNot(tok::l_brace))
2726 return nullptr;
2727 }
2728
2729 if (!MDecl) {
2730 ConsumeBrace();
2731 SkipUntil(tok::r_brace);
2732 return nullptr;
2733 }
2734
2735 // Allow the rest of sema to find private method decl implementations.
2736 Actions.AddAnyMethodToGlobalPool(MDecl);
2737 assert (CurParsedObjCImpl
2738 && "ParseObjCMethodDefinition - Method out of @implementation");
2739 // Consume the tokens and store them for later parsing.
2740 StashAwayMethodOrFunctionBodyTokens(MDecl);
2741 return MDecl;
2742 }
2743
ParseObjCAtStatement(SourceLocation AtLoc)2744 StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) {
2745 if (Tok.is(tok::code_completion)) {
2746 Actions.CodeCompleteObjCAtStatement(getCurScope());
2747 cutOffParsing();
2748 return StmtError();
2749 }
2750
2751 if (Tok.isObjCAtKeyword(tok::objc_try))
2752 return ParseObjCTryStmt(AtLoc);
2753
2754 if (Tok.isObjCAtKeyword(tok::objc_throw))
2755 return ParseObjCThrowStmt(AtLoc);
2756
2757 if (Tok.isObjCAtKeyword(tok::objc_synchronized))
2758 return ParseObjCSynchronizedStmt(AtLoc);
2759
2760 if (Tok.isObjCAtKeyword(tok::objc_autoreleasepool))
2761 return ParseObjCAutoreleasePoolStmt(AtLoc);
2762
2763 if (Tok.isObjCAtKeyword(tok::objc_import) &&
2764 getLangOpts().DebuggerSupport) {
2765 SkipUntil(tok::semi);
2766 return Actions.ActOnNullStmt(Tok.getLocation());
2767 }
2768
2769 ExprResult Res(ParseExpressionWithLeadingAt(AtLoc));
2770 if (Res.isInvalid()) {
2771 // If the expression is invalid, skip ahead to the next semicolon. Not
2772 // doing this opens us up to the possibility of infinite loops if
2773 // ParseExpression does not consume any tokens.
2774 SkipUntil(tok::semi);
2775 return StmtError();
2776 }
2777
2778 // Otherwise, eat the semicolon.
2779 ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
2780 return Actions.ActOnExprStmt(Res);
2781 }
2782
ParseObjCAtExpression(SourceLocation AtLoc)2783 ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
2784 switch (Tok.getKind()) {
2785 case tok::code_completion:
2786 Actions.CodeCompleteObjCAtExpression(getCurScope());
2787 cutOffParsing();
2788 return ExprError();
2789
2790 case tok::minus:
2791 case tok::plus: {
2792 tok::TokenKind Kind = Tok.getKind();
2793 SourceLocation OpLoc = ConsumeToken();
2794
2795 if (!Tok.is(tok::numeric_constant)) {
2796 const char *Symbol = nullptr;
2797 switch (Kind) {
2798 case tok::minus: Symbol = "-"; break;
2799 case tok::plus: Symbol = "+"; break;
2800 default: llvm_unreachable("missing unary operator case");
2801 }
2802 Diag(Tok, diag::err_nsnumber_nonliteral_unary)
2803 << Symbol;
2804 return ExprError();
2805 }
2806
2807 ExprResult Lit(Actions.ActOnNumericConstant(Tok));
2808 if (Lit.isInvalid()) {
2809 return Lit;
2810 }
2811 ConsumeToken(); // Consume the literal token.
2812
2813 Lit = Actions.ActOnUnaryOp(getCurScope(), OpLoc, Kind, Lit.get());
2814 if (Lit.isInvalid())
2815 return Lit;
2816
2817 return ParsePostfixExpressionSuffix(
2818 Actions.BuildObjCNumericLiteral(AtLoc, Lit.get()));
2819 }
2820
2821 case tok::string_literal: // primary-expression: string-literal
2822 case tok::wide_string_literal:
2823 return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
2824
2825 case tok::char_constant:
2826 return ParsePostfixExpressionSuffix(ParseObjCCharacterLiteral(AtLoc));
2827
2828 case tok::numeric_constant:
2829 return ParsePostfixExpressionSuffix(ParseObjCNumericLiteral(AtLoc));
2830
2831 case tok::kw_true: // Objective-C++, etc.
2832 case tok::kw___objc_yes: // c/c++/objc/objc++ __objc_yes
2833 return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc, true));
2834 case tok::kw_false: // Objective-C++, etc.
2835 case tok::kw___objc_no: // c/c++/objc/objc++ __objc_no
2836 return ParsePostfixExpressionSuffix(ParseObjCBooleanLiteral(AtLoc, false));
2837
2838 case tok::l_square:
2839 // Objective-C array literal
2840 return ParsePostfixExpressionSuffix(ParseObjCArrayLiteral(AtLoc));
2841
2842 case tok::l_brace:
2843 // Objective-C dictionary literal
2844 return ParsePostfixExpressionSuffix(ParseObjCDictionaryLiteral(AtLoc));
2845
2846 case tok::l_paren:
2847 // Objective-C boxed expression
2848 return ParsePostfixExpressionSuffix(ParseObjCBoxedExpr(AtLoc));
2849
2850 default:
2851 if (Tok.getIdentifierInfo() == nullptr)
2852 return ExprError(Diag(AtLoc, diag::err_unexpected_at));
2853
2854 switch (Tok.getIdentifierInfo()->getObjCKeywordID()) {
2855 case tok::objc_encode:
2856 return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc));
2857 case tok::objc_protocol:
2858 return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc));
2859 case tok::objc_selector:
2860 return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc));
2861 default: {
2862 const char *str = nullptr;
2863 if (GetLookAheadToken(1).is(tok::l_brace)) {
2864 char ch = Tok.getIdentifierInfo()->getNameStart()[0];
2865 str =
2866 ch == 't' ? "try"
2867 : (ch == 'f' ? "finally"
2868 : (ch == 'a' ? "autoreleasepool" : nullptr));
2869 }
2870 if (str) {
2871 SourceLocation kwLoc = Tok.getLocation();
2872 return ExprError(Diag(AtLoc, diag::err_unexpected_at) <<
2873 FixItHint::CreateReplacement(kwLoc, str));
2874 }
2875 else
2876 return ExprError(Diag(AtLoc, diag::err_unexpected_at));
2877 }
2878 }
2879 }
2880 }
2881
2882 /// \brief Parse the receiver of an Objective-C++ message send.
2883 ///
2884 /// This routine parses the receiver of a message send in
2885 /// Objective-C++ either as a type or as an expression. Note that this
2886 /// routine must not be called to parse a send to 'super', since it
2887 /// has no way to return such a result.
2888 ///
2889 /// \param IsExpr Whether the receiver was parsed as an expression.
2890 ///
2891 /// \param TypeOrExpr If the receiver was parsed as an expression (\c
2892 /// IsExpr is true), the parsed expression. If the receiver was parsed
2893 /// as a type (\c IsExpr is false), the parsed type.
2894 ///
2895 /// \returns True if an error occurred during parsing or semantic
2896 /// analysis, in which case the arguments do not have valid
2897 /// values. Otherwise, returns false for a successful parse.
2898 ///
2899 /// objc-receiver: [C++]
2900 /// 'super' [not parsed here]
2901 /// expression
2902 /// simple-type-specifier
2903 /// typename-specifier
ParseObjCXXMessageReceiver(bool & IsExpr,void * & TypeOrExpr)2904 bool Parser::ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr) {
2905 InMessageExpressionRAIIObject InMessage(*this, true);
2906
2907 if (Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_typename,
2908 tok::annot_cxxscope))
2909 TryAnnotateTypeOrScopeToken();
2910
2911 if (!Actions.isSimpleTypeSpecifier(Tok.getKind())) {
2912 // objc-receiver:
2913 // expression
2914 // Make sure any typos in the receiver are corrected or diagnosed, so that
2915 // proper recovery can happen. FIXME: Perhaps filter the corrected expr to
2916 // only the things that are valid ObjC receivers?
2917 ExprResult Receiver = Actions.CorrectDelayedTyposInExpr(ParseExpression());
2918 if (Receiver.isInvalid())
2919 return true;
2920
2921 IsExpr = true;
2922 TypeOrExpr = Receiver.get();
2923 return false;
2924 }
2925
2926 // objc-receiver:
2927 // typename-specifier
2928 // simple-type-specifier
2929 // expression (that starts with one of the above)
2930 DeclSpec DS(AttrFactory);
2931 ParseCXXSimpleTypeSpecifier(DS);
2932
2933 if (Tok.is(tok::l_paren)) {
2934 // If we see an opening parentheses at this point, we are
2935 // actually parsing an expression that starts with a
2936 // function-style cast, e.g.,
2937 //
2938 // postfix-expression:
2939 // simple-type-specifier ( expression-list [opt] )
2940 // typename-specifier ( expression-list [opt] )
2941 //
2942 // Parse the remainder of this case, then the (optional)
2943 // postfix-expression suffix, followed by the (optional)
2944 // right-hand side of the binary expression. We have an
2945 // instance method.
2946 ExprResult Receiver = ParseCXXTypeConstructExpression(DS);
2947 if (!Receiver.isInvalid())
2948 Receiver = ParsePostfixExpressionSuffix(Receiver.get());
2949 if (!Receiver.isInvalid())
2950 Receiver = ParseRHSOfBinaryExpression(Receiver.get(), prec::Comma);
2951 if (Receiver.isInvalid())
2952 return true;
2953
2954 IsExpr = true;
2955 TypeOrExpr = Receiver.get();
2956 return false;
2957 }
2958
2959 // We have a class message. Turn the simple-type-specifier or
2960 // typename-specifier we parsed into a type and parse the
2961 // remainder of the class message.
2962 Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
2963 TypeResult Type = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
2964 if (Type.isInvalid())
2965 return true;
2966
2967 IsExpr = false;
2968 TypeOrExpr = Type.get().getAsOpaquePtr();
2969 return false;
2970 }
2971
2972 /// \brief Determine whether the parser is currently referring to a an
2973 /// Objective-C message send, using a simplified heuristic to avoid overhead.
2974 ///
2975 /// This routine will only return true for a subset of valid message-send
2976 /// expressions.
isSimpleObjCMessageExpression()2977 bool Parser::isSimpleObjCMessageExpression() {
2978 assert(Tok.is(tok::l_square) && getLangOpts().ObjC1 &&
2979 "Incorrect start for isSimpleObjCMessageExpression");
2980 return GetLookAheadToken(1).is(tok::identifier) &&
2981 GetLookAheadToken(2).is(tok::identifier);
2982 }
2983
isStartOfObjCClassMessageMissingOpenBracket()2984 bool Parser::isStartOfObjCClassMessageMissingOpenBracket() {
2985 if (!getLangOpts().ObjC1 || !NextToken().is(tok::identifier) ||
2986 InMessageExpression)
2987 return false;
2988
2989 ParsedType Type;
2990
2991 if (Tok.is(tok::annot_typename))
2992 Type = getTypeAnnotation(Tok);
2993 else if (Tok.is(tok::identifier))
2994 Type = Actions.getTypeName(*Tok.getIdentifierInfo(), Tok.getLocation(),
2995 getCurScope());
2996 else
2997 return false;
2998
2999 if (!Type.get().isNull() && Type.get()->isObjCObjectOrInterfaceType()) {
3000 const Token &AfterNext = GetLookAheadToken(2);
3001 if (AfterNext.isOneOf(tok::colon, tok::r_square)) {
3002 if (Tok.is(tok::identifier))
3003 TryAnnotateTypeOrScopeToken();
3004
3005 return Tok.is(tok::annot_typename);
3006 }
3007 }
3008
3009 return false;
3010 }
3011
3012 /// objc-message-expr:
3013 /// '[' objc-receiver objc-message-args ']'
3014 ///
3015 /// objc-receiver: [C]
3016 /// 'super'
3017 /// expression
3018 /// class-name
3019 /// type-name
3020 ///
ParseObjCMessageExpression()3021 ExprResult Parser::ParseObjCMessageExpression() {
3022 assert(Tok.is(tok::l_square) && "'[' expected");
3023 SourceLocation LBracLoc = ConsumeBracket(); // consume '['
3024
3025 if (Tok.is(tok::code_completion)) {
3026 Actions.CodeCompleteObjCMessageReceiver(getCurScope());
3027 cutOffParsing();
3028 return ExprError();
3029 }
3030
3031 InMessageExpressionRAIIObject InMessage(*this, true);
3032
3033 if (getLangOpts().CPlusPlus) {
3034 // We completely separate the C and C++ cases because C++ requires
3035 // more complicated (read: slower) parsing.
3036
3037 // Handle send to super.
3038 // FIXME: This doesn't benefit from the same typo-correction we
3039 // get in Objective-C.
3040 if (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_super &&
3041 NextToken().isNot(tok::period) && getCurScope()->isInObjcMethodScope())
3042 return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(), nullptr,
3043 nullptr);
3044
3045 // Parse the receiver, which is either a type or an expression.
3046 bool IsExpr;
3047 void *TypeOrExpr = nullptr;
3048 if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) {
3049 SkipUntil(tok::r_square, StopAtSemi);
3050 return ExprError();
3051 }
3052
3053 if (IsExpr)
3054 return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), nullptr,
3055 static_cast<Expr *>(TypeOrExpr));
3056
3057 return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
3058 ParsedType::getFromOpaquePtr(TypeOrExpr),
3059 nullptr);
3060 }
3061
3062 if (Tok.is(tok::identifier)) {
3063 IdentifierInfo *Name = Tok.getIdentifierInfo();
3064 SourceLocation NameLoc = Tok.getLocation();
3065 ParsedType ReceiverType;
3066 switch (Actions.getObjCMessageKind(getCurScope(), Name, NameLoc,
3067 Name == Ident_super,
3068 NextToken().is(tok::period),
3069 ReceiverType)) {
3070 case Sema::ObjCSuperMessage:
3071 return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(), nullptr,
3072 nullptr);
3073
3074 case Sema::ObjCClassMessage:
3075 if (!ReceiverType) {
3076 SkipUntil(tok::r_square, StopAtSemi);
3077 return ExprError();
3078 }
3079
3080 ConsumeToken(); // the type name
3081
3082 // Parse type arguments and protocol qualifiers.
3083 if (Tok.is(tok::less)) {
3084 SourceLocation NewEndLoc;
3085 TypeResult NewReceiverType
3086 = parseObjCTypeArgsAndProtocolQualifiers(NameLoc, ReceiverType,
3087 /*consumeLastToken=*/true,
3088 NewEndLoc);
3089 if (!NewReceiverType.isUsable()) {
3090 SkipUntil(tok::r_square, StopAtSemi);
3091 return ExprError();
3092 }
3093
3094 ReceiverType = NewReceiverType.get();
3095 }
3096
3097 return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
3098 ReceiverType, nullptr);
3099
3100 case Sema::ObjCInstanceMessage:
3101 // Fall through to parse an expression.
3102 break;
3103 }
3104 }
3105
3106 // Otherwise, an arbitrary expression can be the receiver of a send.
3107 ExprResult Res = Actions.CorrectDelayedTyposInExpr(ParseExpression());
3108 if (Res.isInvalid()) {
3109 SkipUntil(tok::r_square, StopAtSemi);
3110 return Res;
3111 }
3112
3113 return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), nullptr,
3114 Res.get());
3115 }
3116
3117 /// \brief Parse the remainder of an Objective-C message following the
3118 /// '[' objc-receiver.
3119 ///
3120 /// This routine handles sends to super, class messages (sent to a
3121 /// class name), and instance messages (sent to an object), and the
3122 /// target is represented by \p SuperLoc, \p ReceiverType, or \p
3123 /// ReceiverExpr, respectively. Only one of these parameters may have
3124 /// a valid value.
3125 ///
3126 /// \param LBracLoc The location of the opening '['.
3127 ///
3128 /// \param SuperLoc If this is a send to 'super', the location of the
3129 /// 'super' keyword that indicates a send to the superclass.
3130 ///
3131 /// \param ReceiverType If this is a class message, the type of the
3132 /// class we are sending a message to.
3133 ///
3134 /// \param ReceiverExpr If this is an instance message, the expression
3135 /// used to compute the receiver object.
3136 ///
3137 /// objc-message-args:
3138 /// objc-selector
3139 /// objc-keywordarg-list
3140 ///
3141 /// objc-keywordarg-list:
3142 /// objc-keywordarg
3143 /// objc-keywordarg-list objc-keywordarg
3144 ///
3145 /// objc-keywordarg:
3146 /// selector-name[opt] ':' objc-keywordexpr
3147 ///
3148 /// objc-keywordexpr:
3149 /// nonempty-expr-list
3150 ///
3151 /// nonempty-expr-list:
3152 /// assignment-expression
3153 /// nonempty-expr-list , assignment-expression
3154 ///
3155 ExprResult
ParseObjCMessageExpressionBody(SourceLocation LBracLoc,SourceLocation SuperLoc,ParsedType ReceiverType,Expr * ReceiverExpr)3156 Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
3157 SourceLocation SuperLoc,
3158 ParsedType ReceiverType,
3159 Expr *ReceiverExpr) {
3160 InMessageExpressionRAIIObject InMessage(*this, true);
3161
3162 if (Tok.is(tok::code_completion)) {
3163 if (SuperLoc.isValid())
3164 Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc, None,
3165 false);
3166 else if (ReceiverType)
3167 Actions.CodeCompleteObjCClassMessage(getCurScope(), ReceiverType, None,
3168 false);
3169 else
3170 Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr,
3171 None, false);
3172 cutOffParsing();
3173 return ExprError();
3174 }
3175
3176 // Parse objc-selector
3177 SourceLocation Loc;
3178 IdentifierInfo *selIdent = ParseObjCSelectorPiece(Loc);
3179
3180 SmallVector<IdentifierInfo *, 12> KeyIdents;
3181 SmallVector<SourceLocation, 12> KeyLocs;
3182 ExprVector KeyExprs;
3183
3184 if (Tok.is(tok::colon)) {
3185 while (1) {
3186 // Each iteration parses a single keyword argument.
3187 KeyIdents.push_back(selIdent);
3188 KeyLocs.push_back(Loc);
3189
3190 if (ExpectAndConsume(tok::colon)) {
3191 // We must manually skip to a ']', otherwise the expression skipper will
3192 // stop at the ']' when it skips to the ';'. We want it to skip beyond
3193 // the enclosing expression.
3194 SkipUntil(tok::r_square, StopAtSemi);
3195 return ExprError();
3196 }
3197
3198 /// Parse the expression after ':'
3199
3200 if (Tok.is(tok::code_completion)) {
3201 if (SuperLoc.isValid())
3202 Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc,
3203 KeyIdents,
3204 /*AtArgumentEpression=*/true);
3205 else if (ReceiverType)
3206 Actions.CodeCompleteObjCClassMessage(getCurScope(), ReceiverType,
3207 KeyIdents,
3208 /*AtArgumentEpression=*/true);
3209 else
3210 Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr,
3211 KeyIdents,
3212 /*AtArgumentEpression=*/true);
3213
3214 cutOffParsing();
3215 return ExprError();
3216 }
3217
3218 ExprResult Expr;
3219 if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
3220 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
3221 Expr = ParseBraceInitializer();
3222 } else
3223 Expr = ParseAssignmentExpression();
3224
3225 ExprResult Res(Expr);
3226 if (Res.isInvalid()) {
3227 // We must manually skip to a ']', otherwise the expression skipper will
3228 // stop at the ']' when it skips to the ';'. We want it to skip beyond
3229 // the enclosing expression.
3230 SkipUntil(tok::r_square, StopAtSemi);
3231 return Res;
3232 }
3233
3234 // We have a valid expression.
3235 KeyExprs.push_back(Res.get());
3236
3237 // Code completion after each argument.
3238 if (Tok.is(tok::code_completion)) {
3239 if (SuperLoc.isValid())
3240 Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc,
3241 KeyIdents,
3242 /*AtArgumentEpression=*/false);
3243 else if (ReceiverType)
3244 Actions.CodeCompleteObjCClassMessage(getCurScope(), ReceiverType,
3245 KeyIdents,
3246 /*AtArgumentEpression=*/false);
3247 else
3248 Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr,
3249 KeyIdents,
3250 /*AtArgumentEpression=*/false);
3251 cutOffParsing();
3252 return ExprError();
3253 }
3254
3255 // Check for another keyword selector.
3256 selIdent = ParseObjCSelectorPiece(Loc);
3257 if (!selIdent && Tok.isNot(tok::colon))
3258 break;
3259 // We have a selector or a colon, continue parsing.
3260 }
3261 // Parse the, optional, argument list, comma separated.
3262 while (Tok.is(tok::comma)) {
3263 SourceLocation commaLoc = ConsumeToken(); // Eat the ','.
3264 /// Parse the expression after ','
3265 ExprResult Res(ParseAssignmentExpression());
3266 if (Tok.is(tok::colon))
3267 Res = Actions.CorrectDelayedTyposInExpr(Res);
3268 if (Res.isInvalid()) {
3269 if (Tok.is(tok::colon)) {
3270 Diag(commaLoc, diag::note_extra_comma_message_arg) <<
3271 FixItHint::CreateRemoval(commaLoc);
3272 }
3273 // We must manually skip to a ']', otherwise the expression skipper will
3274 // stop at the ']' when it skips to the ';'. We want it to skip beyond
3275 // the enclosing expression.
3276 SkipUntil(tok::r_square, StopAtSemi);
3277 return Res;
3278 }
3279
3280 // We have a valid expression.
3281 KeyExprs.push_back(Res.get());
3282 }
3283 } else if (!selIdent) {
3284 Diag(Tok, diag::err_expected) << tok::identifier; // missing selector name.
3285
3286 // We must manually skip to a ']', otherwise the expression skipper will
3287 // stop at the ']' when it skips to the ';'. We want it to skip beyond
3288 // the enclosing expression.
3289 SkipUntil(tok::r_square, StopAtSemi);
3290 return ExprError();
3291 }
3292
3293 if (Tok.isNot(tok::r_square)) {
3294 Diag(Tok, diag::err_expected)
3295 << (Tok.is(tok::identifier) ? tok::colon : tok::r_square);
3296 // We must manually skip to a ']', otherwise the expression skipper will
3297 // stop at the ']' when it skips to the ';'. We want it to skip beyond
3298 // the enclosing expression.
3299 SkipUntil(tok::r_square, StopAtSemi);
3300 return ExprError();
3301 }
3302
3303 SourceLocation RBracLoc = ConsumeBracket(); // consume ']'
3304
3305 unsigned nKeys = KeyIdents.size();
3306 if (nKeys == 0) {
3307 KeyIdents.push_back(selIdent);
3308 KeyLocs.push_back(Loc);
3309 }
3310 Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]);
3311
3312 if (SuperLoc.isValid())
3313 return Actions.ActOnSuperMessage(getCurScope(), SuperLoc, Sel,
3314 LBracLoc, KeyLocs, RBracLoc, KeyExprs);
3315 else if (ReceiverType)
3316 return Actions.ActOnClassMessage(getCurScope(), ReceiverType, Sel,
3317 LBracLoc, KeyLocs, RBracLoc, KeyExprs);
3318 return Actions.ActOnInstanceMessage(getCurScope(), ReceiverExpr, Sel,
3319 LBracLoc, KeyLocs, RBracLoc, KeyExprs);
3320 }
3321
ParseObjCStringLiteral(SourceLocation AtLoc)3322 ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
3323 ExprResult Res(ParseStringLiteralExpression());
3324 if (Res.isInvalid()) return Res;
3325
3326 // @"foo" @"bar" is a valid concatenated string. Eat any subsequent string
3327 // expressions. At this point, we know that the only valid thing that starts
3328 // with '@' is an @"".
3329 SmallVector<SourceLocation, 4> AtLocs;
3330 ExprVector AtStrings;
3331 AtLocs.push_back(AtLoc);
3332 AtStrings.push_back(Res.get());
3333
3334 while (Tok.is(tok::at)) {
3335 AtLocs.push_back(ConsumeToken()); // eat the @.
3336
3337 // Invalid unless there is a string literal.
3338 if (!isTokenStringLiteral())
3339 return ExprError(Diag(Tok, diag::err_objc_concat_string));
3340
3341 ExprResult Lit(ParseStringLiteralExpression());
3342 if (Lit.isInvalid())
3343 return Lit;
3344
3345 AtStrings.push_back(Lit.get());
3346 }
3347
3348 return Actions.ParseObjCStringLiteral(AtLocs.data(), AtStrings);
3349 }
3350
3351 /// ParseObjCBooleanLiteral -
3352 /// objc-scalar-literal : '@' boolean-keyword
3353 /// ;
3354 /// boolean-keyword: 'true' | 'false' | '__objc_yes' | '__objc_no'
3355 /// ;
ParseObjCBooleanLiteral(SourceLocation AtLoc,bool ArgValue)3356 ExprResult Parser::ParseObjCBooleanLiteral(SourceLocation AtLoc,
3357 bool ArgValue) {
3358 SourceLocation EndLoc = ConsumeToken(); // consume the keyword.
3359 return Actions.ActOnObjCBoolLiteral(AtLoc, EndLoc, ArgValue);
3360 }
3361
3362 /// ParseObjCCharacterLiteral -
3363 /// objc-scalar-literal : '@' character-literal
3364 /// ;
ParseObjCCharacterLiteral(SourceLocation AtLoc)3365 ExprResult Parser::ParseObjCCharacterLiteral(SourceLocation AtLoc) {
3366 ExprResult Lit(Actions.ActOnCharacterConstant(Tok));
3367 if (Lit.isInvalid()) {
3368 return Lit;
3369 }
3370 ConsumeToken(); // Consume the literal token.
3371 return Actions.BuildObjCNumericLiteral(AtLoc, Lit.get());
3372 }
3373
3374 /// ParseObjCNumericLiteral -
3375 /// objc-scalar-literal : '@' scalar-literal
3376 /// ;
3377 /// scalar-literal : | numeric-constant /* any numeric constant. */
3378 /// ;
ParseObjCNumericLiteral(SourceLocation AtLoc)3379 ExprResult Parser::ParseObjCNumericLiteral(SourceLocation AtLoc) {
3380 ExprResult Lit(Actions.ActOnNumericConstant(Tok));
3381 if (Lit.isInvalid()) {
3382 return Lit;
3383 }
3384 ConsumeToken(); // Consume the literal token.
3385 return Actions.BuildObjCNumericLiteral(AtLoc, Lit.get());
3386 }
3387
3388 /// ParseObjCBoxedExpr -
3389 /// objc-box-expression:
3390 /// @( assignment-expression )
3391 ExprResult
ParseObjCBoxedExpr(SourceLocation AtLoc)3392 Parser::ParseObjCBoxedExpr(SourceLocation AtLoc) {
3393 if (Tok.isNot(tok::l_paren))
3394 return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@");
3395
3396 BalancedDelimiterTracker T(*this, tok::l_paren);
3397 T.consumeOpen();
3398 ExprResult ValueExpr(ParseAssignmentExpression());
3399 if (T.consumeClose())
3400 return ExprError();
3401
3402 if (ValueExpr.isInvalid())
3403 return ExprError();
3404
3405 // Wrap the sub-expression in a parenthesized expression, to distinguish
3406 // a boxed expression from a literal.
3407 SourceLocation LPLoc = T.getOpenLocation(), RPLoc = T.getCloseLocation();
3408 ValueExpr = Actions.ActOnParenExpr(LPLoc, RPLoc, ValueExpr.get());
3409 return Actions.BuildObjCBoxedExpr(SourceRange(AtLoc, RPLoc),
3410 ValueExpr.get());
3411 }
3412
ParseObjCArrayLiteral(SourceLocation AtLoc)3413 ExprResult Parser::ParseObjCArrayLiteral(SourceLocation AtLoc) {
3414 ExprVector ElementExprs; // array elements.
3415 ConsumeBracket(); // consume the l_square.
3416
3417 while (Tok.isNot(tok::r_square)) {
3418 // Parse list of array element expressions (all must be id types).
3419 ExprResult Res(ParseAssignmentExpression());
3420 if (Res.isInvalid()) {
3421 // We must manually skip to a ']', otherwise the expression skipper will
3422 // stop at the ']' when it skips to the ';'. We want it to skip beyond
3423 // the enclosing expression.
3424 SkipUntil(tok::r_square, StopAtSemi);
3425 return Res;
3426 }
3427
3428 // Parse the ellipsis that indicates a pack expansion.
3429 if (Tok.is(tok::ellipsis))
3430 Res = Actions.ActOnPackExpansion(Res.get(), ConsumeToken());
3431 if (Res.isInvalid())
3432 return true;
3433
3434 ElementExprs.push_back(Res.get());
3435
3436 if (Tok.is(tok::comma))
3437 ConsumeToken(); // Eat the ','.
3438 else if (Tok.isNot(tok::r_square))
3439 return ExprError(Diag(Tok, diag::err_expected_either) << tok::r_square
3440 << tok::comma);
3441 }
3442 SourceLocation EndLoc = ConsumeBracket(); // location of ']'
3443 MultiExprArg Args(ElementExprs);
3444 return Actions.BuildObjCArrayLiteral(SourceRange(AtLoc, EndLoc), Args);
3445 }
3446
ParseObjCDictionaryLiteral(SourceLocation AtLoc)3447 ExprResult Parser::ParseObjCDictionaryLiteral(SourceLocation AtLoc) {
3448 SmallVector<ObjCDictionaryElement, 4> Elements; // dictionary elements.
3449 ConsumeBrace(); // consume the l_square.
3450 while (Tok.isNot(tok::r_brace)) {
3451 // Parse the comma separated key : value expressions.
3452 ExprResult KeyExpr;
3453 {
3454 ColonProtectionRAIIObject X(*this);
3455 KeyExpr = ParseAssignmentExpression();
3456 if (KeyExpr.isInvalid()) {
3457 // We must manually skip to a '}', otherwise the expression skipper will
3458 // stop at the '}' when it skips to the ';'. We want it to skip beyond
3459 // the enclosing expression.
3460 SkipUntil(tok::r_brace, StopAtSemi);
3461 return KeyExpr;
3462 }
3463 }
3464
3465 if (ExpectAndConsume(tok::colon)) {
3466 SkipUntil(tok::r_brace, StopAtSemi);
3467 return ExprError();
3468 }
3469
3470 ExprResult ValueExpr(ParseAssignmentExpression());
3471 if (ValueExpr.isInvalid()) {
3472 // We must manually skip to a '}', otherwise the expression skipper will
3473 // stop at the '}' when it skips to the ';'. We want it to skip beyond
3474 // the enclosing expression.
3475 SkipUntil(tok::r_brace, StopAtSemi);
3476 return ValueExpr;
3477 }
3478
3479 // Parse the ellipsis that designates this as a pack expansion.
3480 SourceLocation EllipsisLoc;
3481 if (getLangOpts().CPlusPlus)
3482 TryConsumeToken(tok::ellipsis, EllipsisLoc);
3483
3484 // We have a valid expression. Collect it in a vector so we can
3485 // build the argument list.
3486 ObjCDictionaryElement Element = {
3487 KeyExpr.get(), ValueExpr.get(), EllipsisLoc, None
3488 };
3489 Elements.push_back(Element);
3490
3491 if (!TryConsumeToken(tok::comma) && Tok.isNot(tok::r_brace))
3492 return ExprError(Diag(Tok, diag::err_expected_either) << tok::r_brace
3493 << tok::comma);
3494 }
3495 SourceLocation EndLoc = ConsumeBrace();
3496
3497 // Create the ObjCDictionaryLiteral.
3498 return Actions.BuildObjCDictionaryLiteral(SourceRange(AtLoc, EndLoc),
3499 Elements);
3500 }
3501
3502 /// objc-encode-expression:
3503 /// \@encode ( type-name )
3504 ExprResult
ParseObjCEncodeExpression(SourceLocation AtLoc)3505 Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) {
3506 assert(Tok.isObjCAtKeyword(tok::objc_encode) && "Not an @encode expression!");
3507
3508 SourceLocation EncLoc = ConsumeToken();
3509
3510 if (Tok.isNot(tok::l_paren))
3511 return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@encode");
3512
3513 BalancedDelimiterTracker T(*this, tok::l_paren);
3514 T.consumeOpen();
3515
3516 TypeResult Ty = ParseTypeName();
3517
3518 T.consumeClose();
3519
3520 if (Ty.isInvalid())
3521 return ExprError();
3522
3523 return Actions.ParseObjCEncodeExpression(AtLoc, EncLoc, T.getOpenLocation(),
3524 Ty.get(), T.getCloseLocation());
3525 }
3526
3527 /// objc-protocol-expression
3528 /// \@protocol ( protocol-name )
3529 ExprResult
ParseObjCProtocolExpression(SourceLocation AtLoc)3530 Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) {
3531 SourceLocation ProtoLoc = ConsumeToken();
3532
3533 if (Tok.isNot(tok::l_paren))
3534 return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@protocol");
3535
3536 BalancedDelimiterTracker T(*this, tok::l_paren);
3537 T.consumeOpen();
3538
3539 if (Tok.isNot(tok::identifier))
3540 return ExprError(Diag(Tok, diag::err_expected) << tok::identifier);
3541
3542 IdentifierInfo *protocolId = Tok.getIdentifierInfo();
3543 SourceLocation ProtoIdLoc = ConsumeToken();
3544
3545 T.consumeClose();
3546
3547 return Actions.ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc,
3548 T.getOpenLocation(), ProtoIdLoc,
3549 T.getCloseLocation());
3550 }
3551
3552 /// objc-selector-expression
3553 /// @selector '(' '('[opt] objc-keyword-selector ')'[opt] ')'
ParseObjCSelectorExpression(SourceLocation AtLoc)3554 ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) {
3555 SourceLocation SelectorLoc = ConsumeToken();
3556
3557 if (Tok.isNot(tok::l_paren))
3558 return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@selector");
3559
3560 SmallVector<IdentifierInfo *, 12> KeyIdents;
3561 SourceLocation sLoc;
3562
3563 BalancedDelimiterTracker T(*this, tok::l_paren);
3564 T.consumeOpen();
3565 bool HasOptionalParen = Tok.is(tok::l_paren);
3566 if (HasOptionalParen)
3567 ConsumeParen();
3568
3569 if (Tok.is(tok::code_completion)) {
3570 Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents);
3571 cutOffParsing();
3572 return ExprError();
3573 }
3574
3575 IdentifierInfo *SelIdent = ParseObjCSelectorPiece(sLoc);
3576 if (!SelIdent && // missing selector name.
3577 Tok.isNot(tok::colon) && Tok.isNot(tok::coloncolon))
3578 return ExprError(Diag(Tok, diag::err_expected) << tok::identifier);
3579
3580 KeyIdents.push_back(SelIdent);
3581
3582 unsigned nColons = 0;
3583 if (Tok.isNot(tok::r_paren)) {
3584 while (1) {
3585 if (TryConsumeToken(tok::coloncolon)) { // Handle :: in C++.
3586 ++nColons;
3587 KeyIdents.push_back(nullptr);
3588 } else if (ExpectAndConsume(tok::colon)) // Otherwise expect ':'.
3589 return ExprError();
3590 ++nColons;
3591
3592 if (Tok.is(tok::r_paren))
3593 break;
3594
3595 if (Tok.is(tok::code_completion)) {
3596 Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents);
3597 cutOffParsing();
3598 return ExprError();
3599 }
3600
3601 // Check for another keyword selector.
3602 SourceLocation Loc;
3603 SelIdent = ParseObjCSelectorPiece(Loc);
3604 KeyIdents.push_back(SelIdent);
3605 if (!SelIdent && Tok.isNot(tok::colon) && Tok.isNot(tok::coloncolon))
3606 break;
3607 }
3608 }
3609 if (HasOptionalParen && Tok.is(tok::r_paren))
3610 ConsumeParen(); // ')'
3611 T.consumeClose();
3612 Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]);
3613 return Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc,
3614 T.getOpenLocation(),
3615 T.getCloseLocation(),
3616 !HasOptionalParen);
3617 }
3618
ParseLexedObjCMethodDefs(LexedMethod & LM,bool parseMethod)3619 void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) {
3620 // MCDecl might be null due to error in method or c-function prototype, etc.
3621 Decl *MCDecl = LM.D;
3622 bool skip = MCDecl &&
3623 ((parseMethod && !Actions.isObjCMethodDecl(MCDecl)) ||
3624 (!parseMethod && Actions.isObjCMethodDecl(MCDecl)));
3625 if (skip)
3626 return;
3627
3628 // Save the current token position.
3629 SourceLocation OrigLoc = Tok.getLocation();
3630
3631 assert(!LM.Toks.empty() && "ParseLexedObjCMethodDef - Empty body!");
3632 // Append the current token at the end of the new token stream so that it
3633 // doesn't get lost.
3634 LM.Toks.push_back(Tok);
3635 PP.EnterTokenStream(LM.Toks, true);
3636
3637 // Consume the previously pushed token.
3638 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
3639
3640 assert(Tok.isOneOf(tok::l_brace, tok::kw_try, tok::colon) &&
3641 "Inline objective-c method not starting with '{' or 'try' or ':'");
3642 // Enter a scope for the method or c-function body.
3643 ParseScope BodyScope(this,
3644 parseMethod
3645 ? Scope::ObjCMethodScope|Scope::FnScope|Scope::DeclScope
3646 : Scope::FnScope|Scope::DeclScope);
3647
3648 // Tell the actions module that we have entered a method or c-function definition
3649 // with the specified Declarator for the method/function.
3650 if (parseMethod)
3651 Actions.ActOnStartOfObjCMethodDef(getCurScope(), MCDecl);
3652 else
3653 Actions.ActOnStartOfFunctionDef(getCurScope(), MCDecl);
3654 if (Tok.is(tok::kw_try))
3655 ParseFunctionTryBlock(MCDecl, BodyScope);
3656 else {
3657 if (Tok.is(tok::colon))
3658 ParseConstructorInitializer(MCDecl);
3659 else
3660 Actions.ActOnDefaultCtorInitializers(MCDecl);
3661 ParseFunctionStatementBody(MCDecl, BodyScope);
3662 }
3663
3664 if (Tok.getLocation() != OrigLoc) {
3665 // Due to parsing error, we either went over the cached tokens or
3666 // there are still cached tokens left. If it's the latter case skip the
3667 // leftover tokens.
3668 // Since this is an uncommon situation that should be avoided, use the
3669 // expensive isBeforeInTranslationUnit call.
3670 if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(),
3671 OrigLoc))
3672 while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof))
3673 ConsumeAnyToken();
3674 }
3675 }
3676