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