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