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