clang 19.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
19#include "clang/Parse/Parser.h"
21#include "clang/Sema/DeclSpec.h"
22#include "clang/Sema/Scope.h"
23#include "llvm/ADT/SmallVector.h"
24#include "llvm/ADT/StringExtras.h"
25
26using namespace clang;
27
28/// Skips attributes after an Objective-C @ directive. Emits a diagnostic.
29void Parser::MaybeSkipAttributes(tok::ObjCKeywordKind Kind) {
30 ParsedAttributes attrs(AttrFactory);
31 if (Tok.is(tok::kw___attribute)) {
32 if (Kind == tok::objc_interface || Kind == tok::objc_protocol)
33 Diag(Tok, diag::err_objc_postfix_attribute_hint)
34 << (Kind == tok::objc_protocol);
35 else
36 Diag(Tok, diag::err_objc_postfix_attribute);
37 ParseGNUAttributes(attrs);
38 }
39}
40
41/// ParseObjCAtDirectives - Handle parts of the external-declaration production:
42/// external-declaration: [C99 6.9]
43/// [OBJC] objc-class-definition
44/// [OBJC] objc-class-declaration
45/// [OBJC] objc-alias-declaration
46/// [OBJC] objc-protocol-definition
47/// [OBJC] objc-method-definition
48/// [OBJC] '@' 'end'
50Parser::ParseObjCAtDirectives(ParsedAttributes &DeclAttrs,
51 ParsedAttributes &DeclSpecAttrs) {
52 DeclAttrs.takeAllFrom(DeclSpecAttrs);
53
54 SourceLocation AtLoc = ConsumeToken(); // the "@"
55
56 if (Tok.is(tok::code_completion)) {
57 cutOffParsing();
59 return nullptr;
60 }
61
62 switch (Tok.getObjCKeywordID()) {
63 case tok::objc_interface:
64 case tok::objc_protocol:
65 case tok::objc_implementation:
66 break;
67 default:
68 for (const auto &Attr : DeclAttrs) {
69 if (Attr.isGNUAttribute())
70 Diag(Tok.getLocation(), diag::err_objc_unexpected_attr);
71 }
72 }
73
74 Decl *SingleDecl = nullptr;
75 switch (Tok.getObjCKeywordID()) {
76 case tok::objc_class:
77 return ParseObjCAtClassDeclaration(AtLoc);
78 case tok::objc_interface:
79 SingleDecl = ParseObjCAtInterfaceDeclaration(AtLoc, DeclAttrs);
80 break;
81 case tok::objc_protocol:
82 return ParseObjCAtProtocolDeclaration(AtLoc, DeclAttrs);
83 case tok::objc_implementation:
84 return ParseObjCAtImplementationDeclaration(AtLoc, DeclAttrs);
85 case tok::objc_end:
86 return ParseObjCAtEndDeclaration(AtLoc);
87 case tok::objc_compatibility_alias:
88 SingleDecl = ParseObjCAtAliasDeclaration(AtLoc);
89 break;
90 case tok::objc_synthesize:
91 SingleDecl = ParseObjCPropertySynthesize(AtLoc);
92 break;
93 case tok::objc_dynamic:
94 SingleDecl = ParseObjCPropertyDynamic(AtLoc);
95 break;
96 case tok::objc_import:
97 if (getLangOpts().Modules || getLangOpts().DebuggerSupport) {
99 SingleDecl = ParseModuleImport(AtLoc, IS);
100 break;
101 }
102 Diag(AtLoc, diag::err_atimport);
103 SkipUntil(tok::semi);
104 return Actions.ConvertDeclToDeclGroup(nullptr);
105 default:
106 Diag(AtLoc, diag::err_unexpected_at);
107 SkipUntil(tok::semi);
108 SingleDecl = nullptr;
109 break;
110 }
111 return Actions.ConvertDeclToDeclGroup(SingleDecl);
112}
113
114/// Class to handle popping type parameters when leaving the scope.
116 Sema &Actions;
117 Scope *S;
118 ObjCTypeParamList *Params;
119
120public:
122 : Actions(Actions), S(S), Params(nullptr) {}
123
125 leave();
126 }
127
129 assert(!Params);
130 Params = P;
131 }
132
133 void leave() {
134 if (Params)
135 Actions.popObjCTypeParamList(S, Params);
136 Params = nullptr;
137 }
138};
139
140///
141/// objc-class-declaration:
142/// '@' 'class' objc-class-forward-decl (',' objc-class-forward-decl)* ';'
143///
144/// objc-class-forward-decl:
145/// identifier objc-type-parameter-list[opt]
146///
148Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) {
149 ConsumeToken(); // the identifier "class"
153
154 while (true) {
155 MaybeSkipAttributes(tok::objc_class);
156 if (Tok.is(tok::code_completion)) {
157 cutOffParsing();
159 return Actions.ConvertDeclToDeclGroup(nullptr);
160 }
161 if (expectIdentifier()) {
162 SkipUntil(tok::semi);
163 return Actions.ConvertDeclToDeclGroup(nullptr);
164 }
165 ClassNames.push_back(Tok.getIdentifierInfo());
166 ClassLocs.push_back(Tok.getLocation());
167 ConsumeToken();
168
169 // Parse the optional objc-type-parameter-list.
170 ObjCTypeParamList *TypeParams = nullptr;
171 if (Tok.is(tok::less))
172 TypeParams = parseObjCTypeParamList();
173 ClassTypeParams.push_back(TypeParams);
174 if (!TryConsumeToken(tok::comma))
175 break;
176 }
177
178 // Consume the ';'.
179 if (ExpectAndConsume(tok::semi, diag::err_expected_after, "@class"))
180 return Actions.ConvertDeclToDeclGroup(nullptr);
181
182 return Actions.ActOnForwardClassDeclaration(atLoc, ClassNames.data(),
183 ClassLocs.data(),
184 ClassTypeParams,
185 ClassNames.size());
186}
187
188void Parser::CheckNestedObjCContexts(SourceLocation AtLoc)
189{
191 if (ock == Sema::OCK_None)
192 return;
193
194 Decl *Decl = Actions.getObjCDeclContext();
195 if (CurParsedObjCImpl) {
196 CurParsedObjCImpl->finish(AtLoc);
197 } else {
198 Actions.ActOnAtEnd(getCurScope(), AtLoc);
199 }
200 Diag(AtLoc, diag::err_objc_missing_end)
201 << FixItHint::CreateInsertion(AtLoc, "@end\n");
202 if (Decl)
203 Diag(Decl->getBeginLoc(), diag::note_objc_container_start) << (int)ock;
204}
205
206///
207/// objc-interface:
208/// objc-class-interface-attributes[opt] objc-class-interface
209/// objc-category-interface
210///
211/// objc-class-interface:
212/// '@' 'interface' identifier objc-type-parameter-list[opt]
213/// objc-superclass[opt] objc-protocol-refs[opt]
214/// objc-class-instance-variables[opt]
215/// objc-interface-decl-list
216/// @end
217///
218/// objc-category-interface:
219/// '@' 'interface' identifier objc-type-parameter-list[opt]
220/// '(' identifier[opt] ')' objc-protocol-refs[opt]
221/// objc-interface-decl-list
222/// @end
223///
224/// objc-superclass:
225/// ':' identifier objc-type-arguments[opt]
226///
227/// objc-class-interface-attributes:
228/// __attribute__((visibility("default")))
229/// __attribute__((visibility("hidden")))
230/// __attribute__((deprecated))
231/// __attribute__((unavailable))
232/// __attribute__((objc_exception)) - used by NSException on 64-bit
233/// __attribute__((objc_root_class))
234///
235Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
236 ParsedAttributes &attrs) {
237 assert(Tok.isObjCAtKeyword(tok::objc_interface) &&
238 "ParseObjCAtInterfaceDeclaration(): Expected @interface");
239 CheckNestedObjCContexts(AtLoc);
240 ConsumeToken(); // the "interface" identifier
241
242 // Code completion after '@interface'.
243 if (Tok.is(tok::code_completion)) {
244 cutOffParsing();
246 return nullptr;
247 }
248
249 MaybeSkipAttributes(tok::objc_interface);
250
251 if (expectIdentifier())
252 return nullptr; // missing class or category name.
253
254 // We have a class or category name - consume it.
255 IdentifierInfo *nameId = Tok.getIdentifierInfo();
256 SourceLocation nameLoc = ConsumeToken();
257
258 // Parse the objc-type-parameter-list or objc-protocol-refs. For the latter
259 // case, LAngleLoc will be valid and ProtocolIdents will capture the
260 // protocol references (that have not yet been resolved).
261 SourceLocation LAngleLoc, EndProtoLoc;
263 ObjCTypeParamList *typeParameterList = nullptr;
264 ObjCTypeParamListScope typeParamScope(Actions, getCurScope());
265 if (Tok.is(tok::less))
266 typeParameterList = parseObjCTypeParamListOrProtocolRefs(
267 typeParamScope, LAngleLoc, ProtocolIdents, EndProtoLoc);
268
269 if (Tok.is(tok::l_paren) &&
270 !isKnownToBeTypeSpecifier(GetLookAheadToken(1))) { // we have a category.
271
272 BalancedDelimiterTracker T(*this, tok::l_paren);
273 T.consumeOpen();
274
275 SourceLocation categoryLoc;
276 IdentifierInfo *categoryId = nullptr;
277 if (Tok.is(tok::code_completion)) {
278 cutOffParsing();
279 Actions.CodeCompleteObjCInterfaceCategory(getCurScope(), nameId, nameLoc);
280 return nullptr;
281 }
282
283 // For ObjC2, the category name is optional (not an error).
284 if (Tok.is(tok::identifier)) {
285 categoryId = Tok.getIdentifierInfo();
286 categoryLoc = ConsumeToken();
287 }
288 else if (!getLangOpts().ObjC) {
289 Diag(Tok, diag::err_expected)
290 << tok::identifier; // missing category name.
291 return nullptr;
292 }
293
294 T.consumeClose();
295 if (T.getCloseLocation().isInvalid())
296 return nullptr;
297
298 // Next, we need to check for any protocol references.
299 assert(LAngleLoc.isInvalid() && "Cannot have already parsed protocols");
300 SmallVector<Decl *, 8> ProtocolRefs;
302 if (Tok.is(tok::less) &&
303 ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true, true,
304 LAngleLoc, EndProtoLoc,
305 /*consumeLastToken=*/true))
306 return nullptr;
307
308 ObjCCategoryDecl *CategoryType = Actions.ActOnStartCategoryInterface(
309 AtLoc, nameId, nameLoc, typeParameterList, categoryId, categoryLoc,
310 ProtocolRefs.data(), ProtocolRefs.size(), ProtocolLocs.data(),
311 EndProtoLoc, attrs);
312
313 if (Tok.is(tok::l_brace))
314 ParseObjCClassInstanceVariables(CategoryType, tok::objc_private, AtLoc);
315
316 ParseObjCInterfaceDeclList(tok::objc_not_keyword, CategoryType);
317
318 return CategoryType;
319 }
320 // Parse a class interface.
321 IdentifierInfo *superClassId = nullptr;
322 SourceLocation superClassLoc;
323 SourceLocation typeArgsLAngleLoc;
325 SourceLocation typeArgsRAngleLoc;
326 SmallVector<Decl *, 4> protocols;
328 if (Tok.is(tok::colon)) { // a super class is specified.
329 ConsumeToken();
330
331 // Code completion of superclass names.
332 if (Tok.is(tok::code_completion)) {
333 cutOffParsing();
334 Actions.CodeCompleteObjCSuperclass(getCurScope(), nameId, nameLoc);
335 return nullptr;
336 }
337
338 if (expectIdentifier())
339 return nullptr; // missing super class name.
340 superClassId = Tok.getIdentifierInfo();
341 superClassLoc = ConsumeToken();
342
343 // Type arguments for the superclass or protocol conformances.
344 if (Tok.is(tok::less)) {
345 parseObjCTypeArgsOrProtocolQualifiers(
346 nullptr, typeArgsLAngleLoc, typeArgs, typeArgsRAngleLoc, LAngleLoc,
347 protocols, protocolLocs, EndProtoLoc,
348 /*consumeLastToken=*/true,
349 /*warnOnIncompleteProtocols=*/true);
350 if (Tok.is(tok::eof))
351 return nullptr;
352 }
353 }
354
355 // Next, we need to check for any protocol references.
356 if (LAngleLoc.isValid()) {
357 if (!ProtocolIdents.empty()) {
358 // We already parsed the protocols named when we thought we had a
359 // type parameter list. Translate them into actual protocol references.
360 for (const auto &pair : ProtocolIdents) {
361 protocolLocs.push_back(pair.second);
362 }
363 Actions.FindProtocolDeclaration(/*WarnOnDeclarations=*/true,
364 /*ForObjCContainer=*/true,
365 ProtocolIdents, protocols);
366 }
367 } else if (protocols.empty() && Tok.is(tok::less) &&
368 ParseObjCProtocolReferences(protocols, protocolLocs, true, true,
369 LAngleLoc, EndProtoLoc,
370 /*consumeLastToken=*/true)) {
371 return nullptr;
372 }
373
374 if (Tok.isNot(tok::less))
375 Actions.ActOnTypedefedProtocols(protocols, protocolLocs,
376 superClassId, superClassLoc);
377
378 SkipBodyInfo SkipBody;
380 getCurScope(), AtLoc, nameId, nameLoc, typeParameterList, superClassId,
381 superClassLoc, typeArgs,
382 SourceRange(typeArgsLAngleLoc, typeArgsRAngleLoc), protocols.data(),
383 protocols.size(), protocolLocs.data(), EndProtoLoc, attrs, &SkipBody);
384
385 if (Tok.is(tok::l_brace))
386 ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, AtLoc);
387
388 ParseObjCInterfaceDeclList(tok::objc_interface, ClsType);
389
390 if (SkipBody.CheckSameAsPrevious) {
391 auto *PreviousDef = cast<ObjCInterfaceDecl>(SkipBody.Previous);
392 if (Actions.ActOnDuplicateODRHashDefinition(ClsType, PreviousDef)) {
393 ClsType->mergeDuplicateDefinitionWithCommon(PreviousDef->getDefinition());
394 } else {
395 ODRDiagsEmitter DiagsEmitter(Diags, Actions.getASTContext(),
397 DiagsEmitter.diagnoseMismatch(PreviousDef, ClsType);
398 ClsType->setInvalidDecl();
399 }
400 }
401
402 return ClsType;
403}
404
405/// Add an attribute for a context-sensitive type nullability to the given
406/// declarator.
408 Declarator &D,
409 NullabilityKind nullability,
410 SourceLocation nullabilityLoc,
411 bool &addedToDeclSpec) {
412 // Create the attribute.
413 auto getNullabilityAttr = [&](AttributePool &Pool) -> ParsedAttr * {
414 return Pool.create(P.getNullabilityKeyword(nullability),
415 SourceRange(nullabilityLoc), nullptr, SourceLocation(),
416 nullptr, 0, ParsedAttr::Form::ContextSensitiveKeyword());
417 };
418
419 if (D.getNumTypeObjects() > 0) {
420 // Add the attribute to the declarator chunk nearest the declarator.
422 getNullabilityAttr(D.getAttributePool()));
423 } else if (!addedToDeclSpec) {
424 // Otherwise, just put it on the declaration specifiers (if one
425 // isn't there already).
427 getNullabilityAttr(D.getMutableDeclSpec().getAttributes().getPool()));
428 addedToDeclSpec = true;
429 }
430}
431
432/// Parse an Objective-C type parameter list, if present, or capture
433/// the locations of the protocol identifiers for a list of protocol
434/// references.
435///
436/// objc-type-parameter-list:
437/// '<' objc-type-parameter (',' objc-type-parameter)* '>'
438///
439/// objc-type-parameter:
440/// objc-type-parameter-variance? identifier objc-type-parameter-bound[opt]
441///
442/// objc-type-parameter-bound:
443/// ':' type-name
444///
445/// objc-type-parameter-variance:
446/// '__covariant'
447/// '__contravariant'
448///
449/// \param lAngleLoc The location of the starting '<'.
450///
451/// \param protocolIdents Will capture the list of identifiers, if the
452/// angle brackets contain a list of protocol references rather than a
453/// type parameter list.
454///
455/// \param rAngleLoc The location of the ending '>'.
456ObjCTypeParamList *Parser::parseObjCTypeParamListOrProtocolRefs(
457 ObjCTypeParamListScope &Scope, SourceLocation &lAngleLoc,
459 SourceLocation &rAngleLoc, bool mayBeProtocolList) {
460 assert(Tok.is(tok::less) && "Not at the beginning of a type parameter list");
461
462 // Within the type parameter list, don't treat '>' as an operator.
463 GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);
464
465 // Local function to "flush" the protocol identifiers, turning them into
466 // type parameters.
467 SmallVector<Decl *, 4> typeParams;
468 auto makeProtocolIdentsIntoTypeParameters = [&]() {
469 unsigned index = 0;
470 for (const auto &pair : protocolIdents) {
471 DeclResult typeParam = Actions.actOnObjCTypeParam(
473 index++, pair.first, pair.second, SourceLocation(), nullptr);
474 if (typeParam.isUsable())
475 typeParams.push_back(typeParam.get());
476 }
477
478 protocolIdents.clear();
479 mayBeProtocolList = false;
480 };
481
482 bool invalid = false;
483 lAngleLoc = ConsumeToken();
484
485 do {
486 // Parse the variance, if any.
487 SourceLocation varianceLoc;
489 if (Tok.is(tok::kw___covariant) || Tok.is(tok::kw___contravariant)) {
490 variance = Tok.is(tok::kw___covariant)
493 varianceLoc = ConsumeToken();
494
495 // Once we've seen a variance specific , we know this is not a
496 // list of protocol references.
497 if (mayBeProtocolList) {
498 // Up until now, we have been queuing up parameters because they
499 // might be protocol references. Turn them into parameters now.
500 makeProtocolIdentsIntoTypeParameters();
501 }
502 }
503
504 // Parse the identifier.
505 if (!Tok.is(tok::identifier)) {
506 // Code completion.
507 if (Tok.is(tok::code_completion)) {
508 // FIXME: If these aren't protocol references, we'll need different
509 // completions.
510 cutOffParsing();
511 Actions.CodeCompleteObjCProtocolReferences(protocolIdents);
512
513 // FIXME: Better recovery here?.
514 return nullptr;
515 }
516
517 Diag(Tok, diag::err_objc_expected_type_parameter);
518 invalid = true;
519 break;
520 }
521
522 IdentifierInfo *paramName = Tok.getIdentifierInfo();
523 SourceLocation paramLoc = ConsumeToken();
524
525 // If there is a bound, parse it.
526 SourceLocation colonLoc;
527 TypeResult boundType;
528 if (TryConsumeToken(tok::colon, colonLoc)) {
529 // Once we've seen a bound, we know this is not a list of protocol
530 // references.
531 if (mayBeProtocolList) {
532 // Up until now, we have been queuing up parameters because they
533 // might be protocol references. Turn them into parameters now.
534 makeProtocolIdentsIntoTypeParameters();
535 }
536
537 // type-name
538 boundType = ParseTypeName();
539 if (boundType.isInvalid())
540 invalid = true;
541 } else if (mayBeProtocolList) {
542 // If this could still be a protocol list, just capture the identifier.
543 // We don't want to turn it into a parameter.
544 protocolIdents.push_back(std::make_pair(paramName, paramLoc));
545 continue;
546 }
547
548 // Create the type parameter.
549 DeclResult typeParam = Actions.actOnObjCTypeParam(
550 getCurScope(), variance, varianceLoc, typeParams.size(), paramName,
551 paramLoc, colonLoc, boundType.isUsable() ? boundType.get() : nullptr);
552 if (typeParam.isUsable())
553 typeParams.push_back(typeParam.get());
554 } while (TryConsumeToken(tok::comma));
555
556 // Parse the '>'.
557 if (invalid) {
558 SkipUntil(tok::greater, tok::at, StopBeforeMatch);
559 if (Tok.is(tok::greater))
560 ConsumeToken();
561 } else if (ParseGreaterThanInTemplateList(lAngleLoc, rAngleLoc,
562 /*ConsumeLastToken=*/true,
563 /*ObjCGenericList=*/true)) {
564 SkipUntil({tok::greater, tok::greaterequal, tok::at, tok::minus,
565 tok::minus, tok::plus, tok::colon, tok::l_paren, tok::l_brace,
566 tok::comma, tok::semi },
568 if (Tok.is(tok::greater))
569 ConsumeToken();
570 }
571
572 if (mayBeProtocolList) {
573 // A type parameter list must be followed by either a ':' (indicating the
574 // presence of a superclass) or a '(' (indicating that this is a category
575 // or extension). This disambiguates between an objc-type-parameter-list
576 // and a objc-protocol-refs.
577 if (Tok.isNot(tok::colon) && Tok.isNot(tok::l_paren)) {
578 // Returning null indicates that we don't have a type parameter list.
579 // The results the caller needs to handle the protocol references are
580 // captured in the reference parameters already.
581 return nullptr;
582 }
583
584 // We have a type parameter list that looks like a list of protocol
585 // references. Turn that parameter list into type parameters.
586 makeProtocolIdentsIntoTypeParameters();
587 }
588
589 // Form the type parameter list and enter its scope.
591 getCurScope(),
592 lAngleLoc,
593 typeParams,
594 rAngleLoc);
595 Scope.enter(list);
596
597 // Clear out the angle locations; they're used by the caller to indicate
598 // whether there are any protocol references.
599 lAngleLoc = SourceLocation();
600 rAngleLoc = SourceLocation();
601 return invalid ? nullptr : list;
602}
603
604/// Parse an objc-type-parameter-list.
605ObjCTypeParamList *Parser::parseObjCTypeParamList() {
606 SourceLocation lAngleLoc;
608 SourceLocation rAngleLoc;
609
610 ObjCTypeParamListScope Scope(Actions, getCurScope());
611 return parseObjCTypeParamListOrProtocolRefs(Scope, lAngleLoc, protocolIdents,
612 rAngleLoc,
613 /*mayBeProtocolList=*/false);
614}
615
616static bool isTopLevelObjCKeyword(tok::ObjCKeywordKind DirectiveKind) {
617 switch (DirectiveKind) {
618 case tok::objc_class:
619 case tok::objc_compatibility_alias:
620 case tok::objc_interface:
621 case tok::objc_implementation:
622 case tok::objc_protocol:
623 return true;
624 default:
625 return false;
626 }
627}
628
629/// objc-interface-decl-list:
630/// empty
631/// objc-interface-decl-list objc-property-decl [OBJC2]
632/// objc-interface-decl-list objc-method-requirement [OBJC2]
633/// objc-interface-decl-list objc-method-proto ';'
634/// objc-interface-decl-list declaration
635/// objc-interface-decl-list ';'
636///
637/// objc-method-requirement: [OBJC2]
638/// @required
639/// @optional
640///
641void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,
642 Decl *CDecl) {
643 SmallVector<Decl *, 32> allMethods;
644 SmallVector<DeclGroupPtrTy, 8> allTUVariables;
645 tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword;
646
647 SourceRange AtEnd;
648
649 while (true) {
650 // If this is a method prototype, parse it.
651 if (Tok.isOneOf(tok::minus, tok::plus)) {
652 if (Decl *methodPrototype =
653 ParseObjCMethodPrototype(MethodImplKind, false))
654 allMethods.push_back(methodPrototype);
655 // Consume the ';' here, since ParseObjCMethodPrototype() is re-used for
656 // method definitions.
657 if (ExpectAndConsumeSemi(diag::err_expected_semi_after_method_proto)) {
658 // We didn't find a semi and we error'ed out. Skip until a ';' or '@'.
660 if (Tok.is(tok::semi))
661 ConsumeToken();
662 }
663 continue;
664 }
665 if (Tok.is(tok::l_paren)) {
666 Diag(Tok, diag::err_expected_minus_or_plus);
667 ParseObjCMethodDecl(Tok.getLocation(),
668 tok::minus,
669 MethodImplKind, false);
670 continue;
671 }
672 // Ignore excess semicolons.
673 if (Tok.is(tok::semi)) {
674 // FIXME: This should use ConsumeExtraSemi() for extraneous semicolons,
675 // to make -Wextra-semi diagnose them.
676 ConsumeToken();
677 continue;
678 }
679
680 // If we got to the end of the file, exit the loop.
681 if (isEofOrEom())
682 break;
683
684 // Code completion within an Objective-C interface.
685 if (Tok.is(tok::code_completion)) {
686 cutOffParsing();
688 CurParsedObjCImpl? Sema::PCC_ObjCImplementation
690 return;
691 }
692
693 // If we don't have an @ directive, parse it as a function definition.
694 if (Tok.isNot(tok::at)) {
695 // The code below does not consume '}'s because it is afraid of eating the
696 // end of a namespace. Because of the way this code is structured, an
697 // erroneous r_brace would cause an infinite loop if not handled here.
698 if (Tok.is(tok::r_brace))
699 break;
700
701 ParsedAttributes EmptyDeclAttrs(AttrFactory);
702 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
703
704 // Since we call ParseDeclarationOrFunctionDefinition() instead of
705 // ParseExternalDeclaration() below (so that this doesn't parse nested
706 // @interfaces), this needs to duplicate some code from the latter.
707 if (Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
708 SourceLocation DeclEnd;
709 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
710 allTUVariables.push_back(ParseDeclaration(DeclaratorContext::File,
711 DeclEnd, EmptyDeclAttrs,
712 EmptyDeclSpecAttrs));
713 continue;
714 }
715
716 allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(
717 EmptyDeclAttrs, EmptyDeclSpecAttrs));
718 continue;
719 }
720
721 // Otherwise, we have an @ directive, peak at the next token
722 SourceLocation AtLoc = Tok.getLocation();
723 const auto &NextTok = NextToken();
724 if (NextTok.is(tok::code_completion)) {
725 cutOffParsing();
727 return;
728 }
729
730 tok::ObjCKeywordKind DirectiveKind = NextTok.getObjCKeywordID();
731 if (DirectiveKind == tok::objc_end) { // @end -> terminate list
732 ConsumeToken(); // the "@"
733 AtEnd.setBegin(AtLoc);
734 AtEnd.setEnd(Tok.getLocation());
735 break;
736 } else if (DirectiveKind == tok::objc_not_keyword) {
737 Diag(NextTok, diag::err_objc_unknown_at);
738 SkipUntil(tok::semi);
739 continue;
740 }
741
742 // If we see something like '@interface' that's only allowed at the top
743 // level, bail out as if we saw an '@end'. We'll diagnose this below.
744 if (isTopLevelObjCKeyword(DirectiveKind))
745 break;
746
747 // Otherwise parse it as part of the current declaration. Eat "@identifier".
748 ConsumeToken();
749 ConsumeToken();
750
751 switch (DirectiveKind) {
752 default:
753 // FIXME: If someone forgets an @end on a protocol, this loop will
754 // continue to eat up tons of stuff and spew lots of nonsense errors. It
755 // would probably be better to bail out if we saw an @class or @interface
756 // or something like that.
757 Diag(AtLoc, diag::err_objc_illegal_interface_qual);
758 // Skip until we see an '@' or '}' or ';'.
759 SkipUntil(tok::r_brace, tok::at, StopAtSemi);
760 break;
761
762 case tok::objc_required:
763 case tok::objc_optional:
764 // This is only valid on protocols.
765 if (contextKey != tok::objc_protocol)
766 Diag(AtLoc, diag::err_objc_directive_only_in_protocol);
767 else
768 MethodImplKind = DirectiveKind;
769 break;
770
771 case tok::objc_property:
772 ObjCDeclSpec OCDS;
773 SourceLocation LParenLoc;
774 // Parse property attribute list, if any.
775 if (Tok.is(tok::l_paren)) {
776 LParenLoc = Tok.getLocation();
777 ParseObjCPropertyAttribute(OCDS);
778 }
779
780 bool addedToDeclSpec = false;
781 auto ObjCPropertyCallback = [&](ParsingFieldDeclarator &FD) {
782 if (FD.D.getIdentifier() == nullptr) {
783 Diag(AtLoc, diag::err_objc_property_requires_field_name)
784 << FD.D.getSourceRange();
785 return;
786 }
787 if (FD.BitfieldSize) {
788 Diag(AtLoc, diag::err_objc_property_bitfield)
789 << FD.D.getSourceRange();
790 return;
791 }
792
793 // Map a nullability property attribute to a context-sensitive keyword
794 // attribute.
795 if (OCDS.getPropertyAttributes() &
798 OCDS.getNullabilityLoc(),
799 addedToDeclSpec);
800
801 // Install the property declarator into interfaceDecl.
802 const IdentifierInfo *SelName =
803 OCDS.getGetterName() ? OCDS.getGetterName() : FD.D.getIdentifier();
804
805 Selector GetterSel = PP.getSelectorTable().getNullarySelector(SelName);
806 const IdentifierInfo *SetterName = OCDS.getSetterName();
807 Selector SetterSel;
808 if (SetterName)
809 SetterSel = PP.getSelectorTable().getSelector(1, &SetterName);
810 else
813 FD.D.getIdentifier());
814 Decl *Property = Actions.ActOnProperty(
815 getCurScope(), AtLoc, LParenLoc, FD, OCDS, GetterSel, SetterSel,
816 MethodImplKind);
817
818 FD.complete(Property);
819 };
820
821 // Parse all the comma separated declarators.
822 ParsingDeclSpec DS(*this);
823 ParseStructDeclaration(DS, ObjCPropertyCallback);
824
825 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
826 break;
827 }
828 }
829
830 // We break out of the big loop in 3 cases: when we see @end or when we see
831 // top-level ObjC keyword or EOF. In the former case, eat the @end. In the
832 // later cases, emit an error.
833 if (Tok.isObjCAtKeyword(tok::objc_end)) {
834 ConsumeToken(); // the "end" identifier
835 } else {
836 Diag(Tok, diag::err_objc_missing_end)
837 << FixItHint::CreateInsertion(Tok.getLocation(), "\n@end\n");
838 Diag(CDecl->getBeginLoc(), diag::note_objc_container_start)
839 << (int)Actions.getObjCContainerKind();
840 AtEnd.setBegin(Tok.getLocation());
841 AtEnd.setEnd(Tok.getLocation());
842 }
843
844 // Insert collected methods declarations into the @interface object.
845 // This passes in an invalid SourceLocation for AtEndLoc when EOF is hit.
846 Actions.ActOnAtEnd(getCurScope(), AtEnd, allMethods, allTUVariables);
847}
848
849/// Diagnose redundant or conflicting nullability information.
851 ObjCDeclSpec &DS,
852 NullabilityKind nullability,
853 SourceLocation nullabilityLoc){
854 if (DS.getNullability() == nullability) {
855 P.Diag(nullabilityLoc, diag::warn_nullability_duplicate)
856 << DiagNullabilityKind(nullability, true)
858 return;
859 }
860
861 P.Diag(nullabilityLoc, diag::err_nullability_conflicting)
862 << DiagNullabilityKind(nullability, true)
865}
866
867/// Parse property attribute declarations.
868///
869/// property-attr-decl: '(' property-attrlist ')'
870/// property-attrlist:
871/// property-attribute
872/// property-attrlist ',' property-attribute
873/// property-attribute:
874/// getter '=' identifier
875/// setter '=' identifier ':'
876/// direct
877/// readonly
878/// readwrite
879/// assign
880/// retain
881/// copy
882/// nonatomic
883/// atomic
884/// strong
885/// weak
886/// unsafe_unretained
887/// nonnull
888/// nullable
889/// null_unspecified
890/// null_resettable
891/// class
892///
893void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
894 assert(Tok.getKind() == tok::l_paren);
895 BalancedDelimiterTracker T(*this, tok::l_paren);
896 T.consumeOpen();
897
898 while (true) {
899 if (Tok.is(tok::code_completion)) {
900 cutOffParsing();
902 return;
903 }
904 const IdentifierInfo *II = Tok.getIdentifierInfo();
905
906 // If this is not an identifier at all, bail out early.
907 if (!II) {
908 T.consumeClose();
909 return;
910 }
911
912 SourceLocation AttrName = ConsumeToken(); // consume last attribute name
913
914 if (II->isStr("readonly"))
916 else if (II->isStr("assign"))
918 else if (II->isStr("unsafe_unretained"))
920 else if (II->isStr("readwrite"))
922 else if (II->isStr("retain"))
924 else if (II->isStr("strong"))
926 else if (II->isStr("copy"))
928 else if (II->isStr("nonatomic"))
930 else if (II->isStr("atomic"))
932 else if (II->isStr("weak"))
934 else if (II->isStr("getter") || II->isStr("setter")) {
935 bool IsSetter = II->getNameStart()[0] == 's';
936
937 // getter/setter require extra treatment.
938 unsigned DiagID = IsSetter ? diag::err_objc_expected_equal_for_setter :
939 diag::err_objc_expected_equal_for_getter;
940
941 if (ExpectAndConsume(tok::equal, DiagID)) {
942 SkipUntil(tok::r_paren, StopAtSemi);
943 return;
944 }
945
946 if (Tok.is(tok::code_completion)) {
947 cutOffParsing();
948 if (IsSetter)
950 else
952 return;
953 }
954
955 SourceLocation SelLoc;
956 IdentifierInfo *SelIdent = ParseObjCSelectorPiece(SelLoc);
957
958 if (!SelIdent) {
959 Diag(Tok, diag::err_objc_expected_selector_for_getter_setter)
960 << IsSetter;
961 SkipUntil(tok::r_paren, StopAtSemi);
962 return;
963 }
964
965 if (IsSetter) {
967 DS.setSetterName(SelIdent, SelLoc);
968
969 if (ExpectAndConsume(tok::colon,
970 diag::err_expected_colon_after_setter_name)) {
971 SkipUntil(tok::r_paren, StopAtSemi);
972 return;
973 }
974 } else {
976 DS.setGetterName(SelIdent, SelLoc);
977 }
978 } else if (II->isStr("nonnull")) {
982 Tok.getLocation());
985 } else if (II->isStr("nullable")) {
989 Tok.getLocation());
992 } else if (II->isStr("null_unspecified")) {
996 Tok.getLocation());
999 } else if (II->isStr("null_resettable")) {
1003 Tok.getLocation());
1006
1007 // Also set the null_resettable bit.
1009 } else if (II->isStr("class")) {
1011 } else if (II->isStr("direct")) {
1013 } else {
1014 Diag(AttrName, diag::err_objc_expected_property_attr) << II;
1015 SkipUntil(tok::r_paren, StopAtSemi);
1016 return;
1017 }
1018
1019 if (Tok.isNot(tok::comma))
1020 break;
1021
1022 ConsumeToken();
1023 }
1024
1025 T.consumeClose();
1026}
1027
1028/// objc-method-proto:
1029/// objc-instance-method objc-method-decl objc-method-attributes[opt]
1030/// objc-class-method objc-method-decl objc-method-attributes[opt]
1031///
1032/// objc-instance-method: '-'
1033/// objc-class-method: '+'
1034///
1035/// objc-method-attributes: [OBJC2]
1036/// __attribute__((deprecated))
1037///
1038Decl *Parser::ParseObjCMethodPrototype(tok::ObjCKeywordKind MethodImplKind,
1039 bool MethodDefinition) {
1040 assert(Tok.isOneOf(tok::minus, tok::plus) && "expected +/-");
1041
1042 tok::TokenKind methodType = Tok.getKind();
1044 Decl *MDecl = ParseObjCMethodDecl(mLoc, methodType, MethodImplKind,
1045 MethodDefinition);
1046 // Since this rule is used for both method declarations and definitions,
1047 // the caller is (optionally) responsible for consuming the ';'.
1048 return MDecl;
1049}
1050
1051/// objc-selector:
1052/// identifier
1053/// one of
1054/// enum struct union if else while do for switch case default
1055/// break continue return goto asm sizeof typeof __alignof
1056/// unsigned long const short volatile signed restrict _Complex
1057/// in out inout bycopy byref oneway int char float double void _Bool
1058///
1059IdentifierInfo *Parser::ParseObjCSelectorPiece(SourceLocation &SelectorLoc) {
1060
1061 switch (Tok.getKind()) {
1062 default:
1063 return nullptr;
1064 case tok::colon:
1065 // Empty selector piece uses the location of the ':'.
1066 SelectorLoc = Tok.getLocation();
1067 return nullptr;
1068 case tok::ampamp:
1069 case tok::ampequal:
1070 case tok::amp:
1071 case tok::pipe:
1072 case tok::tilde:
1073 case tok::exclaim:
1074 case tok::exclaimequal:
1075 case tok::pipepipe:
1076 case tok::pipeequal:
1077 case tok::caret:
1078 case tok::caretequal: {
1079 std::string ThisTok(PP.getSpelling(Tok));
1080 if (isLetter(ThisTok[0])) {
1081 IdentifierInfo *II = &PP.getIdentifierTable().get(ThisTok);
1082 Tok.setKind(tok::identifier);
1083 SelectorLoc = ConsumeToken();
1084 return II;
1085 }
1086 return nullptr;
1087 }
1088
1089 case tok::identifier:
1090 case tok::kw_asm:
1091 case tok::kw_auto:
1092 case tok::kw_bool:
1093 case tok::kw_break:
1094 case tok::kw_case:
1095 case tok::kw_catch:
1096 case tok::kw_char:
1097 case tok::kw_class:
1098 case tok::kw_const:
1099 case tok::kw_const_cast:
1100 case tok::kw_continue:
1101 case tok::kw_default:
1102 case tok::kw_delete:
1103 case tok::kw_do:
1104 case tok::kw_double:
1105 case tok::kw_dynamic_cast:
1106 case tok::kw_else:
1107 case tok::kw_enum:
1108 case tok::kw_explicit:
1109 case tok::kw_export:
1110 case tok::kw_extern:
1111 case tok::kw_false:
1112 case tok::kw_float:
1113 case tok::kw_for:
1114 case tok::kw_friend:
1115 case tok::kw_goto:
1116 case tok::kw_if:
1117 case tok::kw_inline:
1118 case tok::kw_int:
1119 case tok::kw_long:
1120 case tok::kw_mutable:
1121 case tok::kw_namespace:
1122 case tok::kw_new:
1123 case tok::kw_operator:
1124 case tok::kw_private:
1125 case tok::kw_protected:
1126 case tok::kw_public:
1127 case tok::kw_register:
1128 case tok::kw_reinterpret_cast:
1129 case tok::kw_restrict:
1130 case tok::kw_return:
1131 case tok::kw_short:
1132 case tok::kw_signed:
1133 case tok::kw_sizeof:
1134 case tok::kw_static:
1135 case tok::kw_static_cast:
1136 case tok::kw_struct:
1137 case tok::kw_switch:
1138 case tok::kw_template:
1139 case tok::kw_this:
1140 case tok::kw_throw:
1141 case tok::kw_true:
1142 case tok::kw_try:
1143 case tok::kw_typedef:
1144 case tok::kw_typeid:
1145 case tok::kw_typename:
1146 case tok::kw_typeof:
1147 case tok::kw_union:
1148 case tok::kw_unsigned:
1149 case tok::kw_using:
1150 case tok::kw_virtual:
1151 case tok::kw_void:
1152 case tok::kw_volatile:
1153 case tok::kw_wchar_t:
1154 case tok::kw_while:
1155 case tok::kw__Bool:
1156 case tok::kw__Complex:
1157 case tok::kw___alignof:
1158 case tok::kw___auto_type:
1160 SelectorLoc = ConsumeToken();
1161 return II;
1162 }
1163}
1164
1165/// objc-for-collection-in: 'in'
1166///
1167bool Parser::isTokIdentifier_in() const {
1168 // FIXME: May have to do additional look-ahead to only allow for
1169 // valid tokens following an 'in'; such as an identifier, unary operators,
1170 // '[' etc.
1171 return (getLangOpts().ObjC && Tok.is(tok::identifier) &&
1172 Tok.getIdentifierInfo() == ObjCTypeQuals[objc_in]);
1173}
1174
1175/// ParseObjCTypeQualifierList - This routine parses the objective-c's type
1176/// qualifier list and builds their bitmask representation in the input
1177/// argument.
1178///
1179/// objc-type-qualifiers:
1180/// objc-type-qualifier
1181/// objc-type-qualifiers objc-type-qualifier
1182///
1183/// objc-type-qualifier:
1184/// 'in'
1185/// 'out'
1186/// 'inout'
1187/// 'oneway'
1188/// 'bycopy'
1189/// 'byref'
1190/// 'nonnull'
1191/// 'nullable'
1192/// 'null_unspecified'
1193///
1194void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS,
1195 DeclaratorContext Context) {
1196 assert(Context == DeclaratorContext::ObjCParameter ||
1198
1199 while (true) {
1200 if (Tok.is(tok::code_completion)) {
1201 cutOffParsing();
1204 return;
1205 }
1206
1207 if (Tok.isNot(tok::identifier))
1208 return;
1209
1210 const IdentifierInfo *II = Tok.getIdentifierInfo();
1211 for (unsigned i = 0; i != objc_NumQuals; ++i) {
1212 if (II != ObjCTypeQuals[i] ||
1213 NextToken().is(tok::less) ||
1214 NextToken().is(tok::coloncolon))
1215 continue;
1216
1219 switch (i) {
1220 default: llvm_unreachable("Unknown decl qualifier");
1221 case objc_in: Qual = ObjCDeclSpec::DQ_In; break;
1222 case objc_out: Qual = ObjCDeclSpec::DQ_Out; break;
1223 case objc_inout: Qual = ObjCDeclSpec::DQ_Inout; break;
1224 case objc_oneway: Qual = ObjCDeclSpec::DQ_Oneway; break;
1225 case objc_bycopy: Qual = ObjCDeclSpec::DQ_Bycopy; break;
1226 case objc_byref: Qual = ObjCDeclSpec::DQ_Byref; break;
1227
1228 case objc_nonnull:
1231 break;
1232
1233 case objc_nullable:
1236 break;
1237
1238 case objc_null_unspecified:
1241 break;
1242 }
1243
1244 // FIXME: Diagnose redundant specifiers.
1245 DS.setObjCDeclQualifier(Qual);
1247 DS.setNullability(Tok.getLocation(), Nullability);
1248
1249 ConsumeToken();
1250 II = nullptr;
1251 break;
1252 }
1253
1254 // If this wasn't a recognized qualifier, bail out.
1255 if (II) return;
1256 }
1257}
1258
1259/// Take all the decl attributes out of the given list and add
1260/// them to the given attribute set.
1262 ParsedAttributesView &from) {
1263 for (auto &AL : llvm::reverse(from)) {
1264 if (!AL.isUsedAsTypeAttr()) {
1265 from.remove(&AL);
1266 attrs.addAtEnd(&AL);
1267 }
1268 }
1269}
1270
1271/// takeDeclAttributes - Take all the decl attributes from the given
1272/// declarator and add them to the given list.
1274 Declarator &D) {
1275 // This gets called only from Parser::ParseObjCTypeName(), and that should
1276 // never add declaration attributes to the Declarator.
1277 assert(D.getDeclarationAttributes().empty());
1278
1279 // First, take ownership of all attributes.
1282
1283 // Now actually move the attributes over.
1286 for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
1288}
1289
1290/// objc-type-name:
1291/// '(' objc-type-qualifiers[opt] type-name ')'
1292/// '(' objc-type-qualifiers[opt] ')'
1293///
1294ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS,
1295 DeclaratorContext context,
1296 ParsedAttributes *paramAttrs) {
1297 assert(context == DeclaratorContext::ObjCParameter ||
1299 assert((paramAttrs != nullptr) ==
1301
1302 assert(Tok.is(tok::l_paren) && "expected (");
1303
1304 BalancedDelimiterTracker T(*this, tok::l_paren);
1305 T.consumeOpen();
1306
1307 ObjCDeclContextSwitch ObjCDC(*this);
1308
1309 // Parse type qualifiers, in, inout, etc.
1310 ParseObjCTypeQualifierList(DS, context);
1311 SourceLocation TypeStartLoc = Tok.getLocation();
1312
1313 ParsedType Ty;
1314 if (isTypeSpecifierQualifier() || isObjCInstancetype()) {
1315 // Parse an abstract declarator.
1316 DeclSpec declSpec(AttrFactory);
1317 declSpec.setObjCQualifiers(&DS);
1318 DeclSpecContext dsContext = DeclSpecContext::DSC_normal;
1319 if (context == DeclaratorContext::ObjCResult)
1320 dsContext = DeclSpecContext::DSC_objc_method_result;
1321 ParseSpecifierQualifierList(declSpec, AS_none, dsContext);
1322 Declarator declarator(declSpec, ParsedAttributesView::none(), context);
1323 ParseDeclarator(declarator);
1324
1325 // If that's not invalid, extract a type.
1326 if (!declarator.isInvalidType()) {
1327 // Map a nullability specifier to a context-sensitive keyword attribute.
1328 bool addedToDeclSpec = false;
1330 addContextSensitiveTypeNullability(*this, declarator,
1331 DS.getNullability(),
1332 DS.getNullabilityLoc(),
1333 addedToDeclSpec);
1334
1335 TypeResult type = Actions.ActOnTypeName(declarator);
1336 if (!type.isInvalid())
1337 Ty = type.get();
1338
1339 // If we're parsing a parameter, steal all the decl attributes
1340 // and add them to the decl spec.
1341 if (context == DeclaratorContext::ObjCParameter)
1342 takeDeclAttributes(*paramAttrs, declarator);
1343 }
1344 }
1345
1346 if (Tok.is(tok::r_paren))
1347 T.consumeClose();
1348 else if (Tok.getLocation() == TypeStartLoc) {
1349 // If we didn't eat any tokens, then this isn't a type.
1350 Diag(Tok, diag::err_expected_type);
1351 SkipUntil(tok::r_paren, StopAtSemi);
1352 } else {
1353 // Otherwise, we found *something*, but didn't get a ')' in the right
1354 // place. Emit an error then return what we have as the type.
1355 T.consumeClose();
1356 }
1357 return Ty;
1358}
1359
1360/// objc-method-decl:
1361/// objc-selector
1362/// objc-keyword-selector objc-parmlist[opt]
1363/// objc-type-name objc-selector
1364/// objc-type-name objc-keyword-selector objc-parmlist[opt]
1365///
1366/// objc-keyword-selector:
1367/// objc-keyword-decl
1368/// objc-keyword-selector objc-keyword-decl
1369///
1370/// objc-keyword-decl:
1371/// objc-selector ':' objc-type-name objc-keyword-attributes[opt] identifier
1372/// objc-selector ':' objc-keyword-attributes[opt] identifier
1373/// ':' objc-type-name objc-keyword-attributes[opt] identifier
1374/// ':' objc-keyword-attributes[opt] identifier
1375///
1376/// objc-parmlist:
1377/// objc-parms objc-ellipsis[opt]
1378///
1379/// objc-parms:
1380/// objc-parms , parameter-declaration
1381///
1382/// objc-ellipsis:
1383/// , ...
1384///
1385/// objc-keyword-attributes: [OBJC2]
1386/// __attribute__((unused))
1387///
1388Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
1389 tok::TokenKind mType,
1390 tok::ObjCKeywordKind MethodImplKind,
1391 bool MethodDefinition) {
1393
1394 if (Tok.is(tok::code_completion)) {
1395 cutOffParsing();
1396 Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus,
1397 /*ReturnType=*/nullptr);
1398 return nullptr;
1399 }
1400
1401 // Parse the return type if present.
1402 ParsedType ReturnType;
1403 ObjCDeclSpec DSRet;
1404 if (Tok.is(tok::l_paren))
1405 ReturnType =
1406 ParseObjCTypeName(DSRet, DeclaratorContext::ObjCResult, nullptr);
1407
1408 // If attributes exist before the method, parse them.
1409 ParsedAttributes methodAttrs(AttrFactory);
1410 MaybeParseAttributes(PAKM_CXX11 | (getLangOpts().ObjC ? PAKM_GNU : 0),
1411 methodAttrs);
1412
1413 if (Tok.is(tok::code_completion)) {
1414 cutOffParsing();
1415 Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus,
1416 ReturnType);
1417 return nullptr;
1418 }
1419
1420 // Now parse the selector.
1421 SourceLocation selLoc;
1422 IdentifierInfo *SelIdent = ParseObjCSelectorPiece(selLoc);
1423
1424 // An unnamed colon is valid.
1425 if (!SelIdent && Tok.isNot(tok::colon)) { // missing selector name.
1426 Diag(Tok, diag::err_expected_selector_for_method)
1427 << SourceRange(mLoc, Tok.getLocation());
1428 // Skip until we get a ; or @.
1430 return nullptr;
1431 }
1432
1434 if (Tok.isNot(tok::colon)) {
1435 // If attributes exist after the method, parse them.
1436 MaybeParseAttributes(PAKM_CXX11 | (getLangOpts().ObjC ? PAKM_GNU : 0),
1437 methodAttrs);
1438
1439 Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
1441 getCurScope(), mLoc, Tok.getLocation(), mType, DSRet, ReturnType,
1442 selLoc, Sel, nullptr, CParamInfo.data(), CParamInfo.size(), methodAttrs,
1443 MethodImplKind, false, MethodDefinition);
1444 PD.complete(Result);
1445 return Result;
1446 }
1447
1451 ParseScope PrototypeScope(this, Scope::FunctionPrototypeScope |
1453
1454 AttributePool allParamAttrs(AttrFactory);
1455 while (true) {
1456 ParsedAttributes paramAttrs(AttrFactory);
1457 Sema::ObjCArgInfo ArgInfo;
1458
1459 // Each iteration parses a single keyword argument.
1460 if (ExpectAndConsume(tok::colon))
1461 break;
1462
1463 ArgInfo.Type = nullptr;
1464 if (Tok.is(tok::l_paren)) // Parse the argument type if present.
1465 ArgInfo.Type = ParseObjCTypeName(
1466 ArgInfo.DeclSpec, DeclaratorContext::ObjCParameter, &paramAttrs);
1467
1468 // If attributes exist before the argument name, parse them.
1469 // Regardless, collect all the attributes we've parsed so far.
1470 MaybeParseAttributes(PAKM_CXX11 | (getLangOpts().ObjC ? PAKM_GNU : 0),
1471 paramAttrs);
1472 ArgInfo.ArgAttrs = paramAttrs;
1473
1474 // Code completion for the next piece of the selector.
1475 if (Tok.is(tok::code_completion)) {
1476 cutOffParsing();
1477 KeyIdents.push_back(SelIdent);
1479 mType == tok::minus,
1480 /*AtParameterName=*/true,
1481 ReturnType, KeyIdents);
1482 return nullptr;
1483 }
1484
1485 if (expectIdentifier())
1486 break; // missing argument name.
1487
1488 ArgInfo.Name = Tok.getIdentifierInfo();
1489 ArgInfo.NameLoc = Tok.getLocation();
1490 ConsumeToken(); // Eat the identifier.
1491
1492 ArgInfos.push_back(ArgInfo);
1493 KeyIdents.push_back(SelIdent);
1494 KeyLocs.push_back(selLoc);
1495
1496 // Make sure the attributes persist.
1497 allParamAttrs.takeAllFrom(paramAttrs.getPool());
1498
1499 // Code completion for the next piece of the selector.
1500 if (Tok.is(tok::code_completion)) {
1501 cutOffParsing();
1503 mType == tok::minus,
1504 /*AtParameterName=*/false,
1505 ReturnType, KeyIdents);
1506 return nullptr;
1507 }
1508
1509 // Check for another keyword selector.
1510 SelIdent = ParseObjCSelectorPiece(selLoc);
1511 if (!SelIdent && Tok.isNot(tok::colon))
1512 break;
1513 if (!SelIdent) {
1514 SourceLocation ColonLoc = Tok.getLocation();
1515 if (PP.getLocForEndOfToken(ArgInfo.NameLoc) == ColonLoc) {
1516 Diag(ArgInfo.NameLoc, diag::warn_missing_selector_name) << ArgInfo.Name;
1517 Diag(ArgInfo.NameLoc, diag::note_missing_selector_name) << ArgInfo.Name;
1518 Diag(ColonLoc, diag::note_force_empty_selector_name) << ArgInfo.Name;
1519 }
1520 }
1521 // We have a selector or a colon, continue parsing.
1522 }
1523
1524 bool isVariadic = false;
1525 bool cStyleParamWarned = false;
1526 // Parse the (optional) parameter list.
1527 while (Tok.is(tok::comma)) {
1528 ConsumeToken();
1529 if (Tok.is(tok::ellipsis)) {
1530 isVariadic = true;
1531 ConsumeToken();
1532 break;
1533 }
1534 if (!cStyleParamWarned) {
1535 Diag(Tok, diag::warn_cstyle_param);
1536 cStyleParamWarned = true;
1537 }
1538 DeclSpec DS(AttrFactory);
1539 ParseDeclarationSpecifiers(DS);
1540 // Parse the declarator.
1543 ParseDeclarator(ParmDecl);
1544 const IdentifierInfo *ParmII = ParmDecl.getIdentifier();
1545 Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl);
1546 CParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
1547 ParmDecl.getIdentifierLoc(),
1548 Param,
1549 nullptr));
1550 }
1551
1552 // FIXME: Add support for optional parameter list...
1553 // If attributes exist after the method, parse them.
1554 MaybeParseAttributes(PAKM_CXX11 | (getLangOpts().ObjC ? PAKM_GNU : 0),
1555 methodAttrs);
1556
1557 if (KeyIdents.size() == 0)
1558 return nullptr;
1559
1560 Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(),
1561 &KeyIdents[0]);
1563 getCurScope(), mLoc, Tok.getLocation(), mType, DSRet, ReturnType, KeyLocs,
1564 Sel, &ArgInfos[0], CParamInfo.data(), CParamInfo.size(), methodAttrs,
1565 MethodImplKind, isVariadic, MethodDefinition);
1566
1567 PD.complete(Result);
1568 return Result;
1569}
1570
1571/// objc-protocol-refs:
1572/// '<' identifier-list '>'
1573///
1574bool Parser::
1575ParseObjCProtocolReferences(SmallVectorImpl<Decl *> &Protocols,
1576 SmallVectorImpl<SourceLocation> &ProtocolLocs,
1577 bool WarnOnDeclarations, bool ForObjCContainer,
1578 SourceLocation &LAngleLoc, SourceLocation &EndLoc,
1579 bool consumeLastToken) {
1580 assert(Tok.is(tok::less) && "expected <");
1581
1582 LAngleLoc = ConsumeToken(); // the "<"
1583
1584 SmallVector<IdentifierLocPair, 8> ProtocolIdents;
1585
1586 while (true) {
1587 if (Tok.is(tok::code_completion)) {
1588 cutOffParsing();
1589 Actions.CodeCompleteObjCProtocolReferences(ProtocolIdents);
1590 return true;
1591 }
1592
1593 if (expectIdentifier()) {
1594 SkipUntil(tok::greater, StopAtSemi);
1595 return true;
1596 }
1597 ProtocolIdents.push_back(std::make_pair(Tok.getIdentifierInfo(),
1598 Tok.getLocation()));
1599 ProtocolLocs.push_back(Tok.getLocation());
1600 ConsumeToken();
1601
1602 if (!TryConsumeToken(tok::comma))
1603 break;
1604 }
1605
1606 // Consume the '>'.
1607 if (ParseGreaterThanInTemplateList(LAngleLoc, EndLoc, consumeLastToken,
1608 /*ObjCGenericList=*/false))
1609 return true;
1610
1611 // Convert the list of protocols identifiers into a list of protocol decls.
1612 Actions.FindProtocolDeclaration(WarnOnDeclarations, ForObjCContainer,
1613 ProtocolIdents, Protocols);
1614 return false;
1615}
1616
1617TypeResult Parser::parseObjCProtocolQualifierType(SourceLocation &rAngleLoc) {
1618 assert(Tok.is(tok::less) && "Protocol qualifiers start with '<'");
1619 assert(getLangOpts().ObjC && "Protocol qualifiers only exist in Objective-C");
1620
1621 SourceLocation lAngleLoc;
1622 SmallVector<Decl *, 8> protocols;
1623 SmallVector<SourceLocation, 8> protocolLocs;
1624 (void)ParseObjCProtocolReferences(protocols, protocolLocs, false, false,
1625 lAngleLoc, rAngleLoc,
1626 /*consumeLastToken=*/true);
1627 TypeResult result = Actions.actOnObjCProtocolQualifierType(lAngleLoc,
1628 protocols,
1629 protocolLocs,
1630 rAngleLoc);
1631 if (result.isUsable()) {
1632 Diag(lAngleLoc, diag::warn_objc_protocol_qualifier_missing_id)
1633 << FixItHint::CreateInsertion(lAngleLoc, "id")
1634 << SourceRange(lAngleLoc, rAngleLoc);
1635 }
1636
1637 return result;
1638}
1639
1640/// Parse Objective-C type arguments or protocol qualifiers.
1641///
1642/// objc-type-arguments:
1643/// '<' type-name '...'[opt] (',' type-name '...'[opt])* '>'
1644///
1645void Parser::parseObjCTypeArgsOrProtocolQualifiers(
1646 ParsedType baseType,
1647 SourceLocation &typeArgsLAngleLoc,
1649 SourceLocation &typeArgsRAngleLoc,
1650 SourceLocation &protocolLAngleLoc,
1651 SmallVectorImpl<Decl *> &protocols,
1652 SmallVectorImpl<SourceLocation> &protocolLocs,
1653 SourceLocation &protocolRAngleLoc,
1654 bool consumeLastToken,
1655 bool warnOnIncompleteProtocols) {
1656 assert(Tok.is(tok::less) && "Not at the start of type args or protocols");
1657 SourceLocation lAngleLoc = ConsumeToken();
1658
1659 // Whether all of the elements we've parsed thus far are single
1660 // identifiers, which might be types or might be protocols.
1661 bool allSingleIdentifiers = true;
1663 SmallVectorImpl<SourceLocation> &identifierLocs = protocolLocs;
1664
1665 // Parse a list of comma-separated identifiers, bailing out if we
1666 // see something different.
1667 do {
1668 // Parse a single identifier.
1669 if (Tok.is(tok::identifier) &&
1670 (NextToken().is(tok::comma) ||
1671 NextToken().is(tok::greater) ||
1672 NextToken().is(tok::greatergreater))) {
1673 identifiers.push_back(Tok.getIdentifierInfo());
1674 identifierLocs.push_back(ConsumeToken());
1675 continue;
1676 }
1677
1678 if (Tok.is(tok::code_completion)) {
1679 // FIXME: Also include types here.
1680 SmallVector<IdentifierLocPair, 4> identifierLocPairs;
1681 for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1682 identifierLocPairs.push_back(IdentifierLocPair(identifiers[i],
1683 identifierLocs[i]));
1684 }
1685
1686 QualType BaseT = Actions.GetTypeFromParser(baseType);
1687 cutOffParsing();
1688 if (!BaseT.isNull() && BaseT->acceptsObjCTypeParams()) {
1690 } else {
1691 Actions.CodeCompleteObjCProtocolReferences(identifierLocPairs);
1692 }
1693 return;
1694 }
1695
1696 allSingleIdentifiers = false;
1697 break;
1698 } while (TryConsumeToken(tok::comma));
1699
1700 // If we parsed an identifier list, semantic analysis sorts out
1701 // whether it refers to protocols or to type arguments.
1702 if (allSingleIdentifiers) {
1703 // Parse the closing '>'.
1704 SourceLocation rAngleLoc;
1705 (void)ParseGreaterThanInTemplateList(lAngleLoc, rAngleLoc, consumeLastToken,
1706 /*ObjCGenericList=*/true);
1707
1708 // Let Sema figure out what we parsed.
1710 baseType,
1711 lAngleLoc,
1712 identifiers,
1713 identifierLocs,
1714 rAngleLoc,
1715 typeArgsLAngleLoc,
1716 typeArgs,
1717 typeArgsRAngleLoc,
1718 protocolLAngleLoc,
1719 protocols,
1720 protocolRAngleLoc,
1721 warnOnIncompleteProtocols);
1722 return;
1723 }
1724
1725 // We parsed an identifier list but stumbled into non single identifiers, this
1726 // means we might (a) check that what we already parsed is a legitimate type
1727 // (not a protocol or unknown type) and (b) parse the remaining ones, which
1728 // must all be type args.
1729
1730 // Convert the identifiers into type arguments.
1731 bool invalid = false;
1732 IdentifierInfo *foundProtocolId = nullptr, *foundValidTypeId = nullptr;
1733 SourceLocation foundProtocolSrcLoc, foundValidTypeSrcLoc;
1734 SmallVector<IdentifierInfo *, 2> unknownTypeArgs;
1735 SmallVector<SourceLocation, 2> unknownTypeArgsLoc;
1736
1737 for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1738 ParsedType typeArg
1739 = Actions.getTypeName(*identifiers[i], identifierLocs[i], getCurScope());
1740 if (typeArg) {
1741 DeclSpec DS(AttrFactory);
1742 const char *prevSpec = nullptr;
1743 unsigned diagID;
1744 DS.SetTypeSpecType(TST_typename, identifierLocs[i], prevSpec, diagID,
1745 typeArg, Actions.getASTContext().getPrintingPolicy());
1746
1747 // Form a declarator to turn this into a type.
1750 TypeResult fullTypeArg = Actions.ActOnTypeName(D);
1751 if (fullTypeArg.isUsable()) {
1752 typeArgs.push_back(fullTypeArg.get());
1753 if (!foundValidTypeId) {
1754 foundValidTypeId = identifiers[i];
1755 foundValidTypeSrcLoc = identifierLocs[i];
1756 }
1757 } else {
1758 invalid = true;
1759 unknownTypeArgs.push_back(identifiers[i]);
1760 unknownTypeArgsLoc.push_back(identifierLocs[i]);
1761 }
1762 } else {
1763 invalid = true;
1764 if (!Actions.LookupProtocol(identifiers[i], identifierLocs[i])) {
1765 unknownTypeArgs.push_back(identifiers[i]);
1766 unknownTypeArgsLoc.push_back(identifierLocs[i]);
1767 } else if (!foundProtocolId) {
1768 foundProtocolId = identifiers[i];
1769 foundProtocolSrcLoc = identifierLocs[i];
1770 }
1771 }
1772 }
1773
1774 // Continue parsing type-names.
1775 do {
1776 Token CurTypeTok = Tok;
1777 TypeResult typeArg = ParseTypeName();
1778
1779 // Consume the '...' for a pack expansion.
1780 SourceLocation ellipsisLoc;
1781 TryConsumeToken(tok::ellipsis, ellipsisLoc);
1782 if (typeArg.isUsable() && ellipsisLoc.isValid()) {
1783 typeArg = Actions.ActOnPackExpansion(typeArg.get(), ellipsisLoc);
1784 }
1785
1786 if (typeArg.isUsable()) {
1787 typeArgs.push_back(typeArg.get());
1788 if (!foundValidTypeId) {
1789 foundValidTypeId = CurTypeTok.getIdentifierInfo();
1790 foundValidTypeSrcLoc = CurTypeTok.getLocation();
1791 }
1792 } else {
1793 invalid = true;
1794 }
1795 } while (TryConsumeToken(tok::comma));
1796
1797 // Diagnose the mix between type args and protocols.
1798 if (foundProtocolId && foundValidTypeId)
1799 Actions.DiagnoseTypeArgsAndProtocols(foundProtocolId, foundProtocolSrcLoc,
1800 foundValidTypeId,
1801 foundValidTypeSrcLoc);
1802
1803 // Diagnose unknown arg types.
1804 ParsedType T;
1805 if (unknownTypeArgs.size())
1806 for (unsigned i = 0, e = unknownTypeArgsLoc.size(); i < e; ++i)
1807 Actions.DiagnoseUnknownTypeName(unknownTypeArgs[i], unknownTypeArgsLoc[i],
1808 getCurScope(), nullptr, T);
1809
1810 // Parse the closing '>'.
1811 SourceLocation rAngleLoc;
1812 (void)ParseGreaterThanInTemplateList(lAngleLoc, rAngleLoc, consumeLastToken,
1813 /*ObjCGenericList=*/true);
1814
1815 if (invalid) {
1816 typeArgs.clear();
1817 return;
1818 }
1819
1820 // Record left/right angle locations.
1821 typeArgsLAngleLoc = lAngleLoc;
1822 typeArgsRAngleLoc = rAngleLoc;
1823}
1824
1825void Parser::parseObjCTypeArgsAndProtocolQualifiers(
1826 ParsedType baseType,
1827 SourceLocation &typeArgsLAngleLoc,
1829 SourceLocation &typeArgsRAngleLoc,
1830 SourceLocation &protocolLAngleLoc,
1831 SmallVectorImpl<Decl *> &protocols,
1832 SmallVectorImpl<SourceLocation> &protocolLocs,
1833 SourceLocation &protocolRAngleLoc,
1834 bool consumeLastToken) {
1835 assert(Tok.is(tok::less));
1836
1837 // Parse the first angle-bracket-delimited clause.
1838 parseObjCTypeArgsOrProtocolQualifiers(baseType,
1839 typeArgsLAngleLoc,
1840 typeArgs,
1841 typeArgsRAngleLoc,
1842 protocolLAngleLoc,
1843 protocols,
1844 protocolLocs,
1845 protocolRAngleLoc,
1846 consumeLastToken,
1847 /*warnOnIncompleteProtocols=*/false);
1848 if (Tok.is(tok::eof)) // Nothing else to do here...
1849 return;
1850
1851 // An Objective-C object pointer followed by type arguments
1852 // can then be followed again by a set of protocol references, e.g.,
1853 // \c NSArray<NSView><NSTextDelegate>
1854 if ((consumeLastToken && Tok.is(tok::less)) ||
1855 (!consumeLastToken && NextToken().is(tok::less))) {
1856 // If we aren't consuming the last token, the prior '>' is still hanging
1857 // there. Consume it before we parse the protocol qualifiers.
1858 if (!consumeLastToken)
1859 ConsumeToken();
1860
1861 if (!protocols.empty()) {
1862 SkipUntilFlags skipFlags = SkipUntilFlags();
1863 if (!consumeLastToken)
1864 skipFlags = skipFlags | StopBeforeMatch;
1865 Diag(Tok, diag::err_objc_type_args_after_protocols)
1866 << SourceRange(protocolLAngleLoc, protocolRAngleLoc);
1867 SkipUntil(tok::greater, tok::greatergreater, skipFlags);
1868 } else {
1869 ParseObjCProtocolReferences(protocols, protocolLocs,
1870 /*WarnOnDeclarations=*/false,
1871 /*ForObjCContainer=*/false,
1872 protocolLAngleLoc, protocolRAngleLoc,
1873 consumeLastToken);
1874 }
1875 }
1876}
1877
1878TypeResult Parser::parseObjCTypeArgsAndProtocolQualifiers(
1879 SourceLocation loc,
1881 bool consumeLastToken,
1882 SourceLocation &endLoc) {
1883 assert(Tok.is(tok::less));
1884 SourceLocation typeArgsLAngleLoc;
1886 SourceLocation typeArgsRAngleLoc;
1887 SourceLocation protocolLAngleLoc;
1888 SmallVector<Decl *, 4> protocols;
1889 SmallVector<SourceLocation, 4> protocolLocs;
1890 SourceLocation protocolRAngleLoc;
1891
1892 // Parse type arguments and protocol qualifiers.
1893 parseObjCTypeArgsAndProtocolQualifiers(type, typeArgsLAngleLoc, typeArgs,
1894 typeArgsRAngleLoc, protocolLAngleLoc,
1895 protocols, protocolLocs,
1896 protocolRAngleLoc, consumeLastToken);
1897
1898 if (Tok.is(tok::eof))
1899 return true; // Invalid type result.
1900
1901 // Compute the location of the last token.
1902 if (consumeLastToken)
1903 endLoc = PrevTokLocation;
1904 else
1905 endLoc = Tok.getLocation();
1906
1908 getCurScope(),
1909 loc,
1910 type,
1911 typeArgsLAngleLoc,
1912 typeArgs,
1913 typeArgsRAngleLoc,
1914 protocolLAngleLoc,
1915 protocols,
1916 protocolLocs,
1917 protocolRAngleLoc);
1918}
1919
1920void Parser::HelperActionsForIvarDeclarations(
1921 ObjCContainerDecl *interfaceDecl, SourceLocation atLoc,
1923 bool RBraceMissing) {
1924 if (!RBraceMissing)
1925 T.consumeClose();
1926
1927 assert(getObjCDeclContext() == interfaceDecl &&
1928 "Ivars should have interfaceDecl as their decl context");
1929 Actions.ActOnLastBitfield(T.getCloseLocation(), AllIvarDecls);
1930 // Call ActOnFields() even if we don't have any decls. This is useful
1931 // for code rewriting tools that need to be aware of the empty list.
1932 Actions.ActOnFields(getCurScope(), atLoc, interfaceDecl, AllIvarDecls,
1933 T.getOpenLocation(), T.getCloseLocation(),
1935}
1936
1937/// objc-class-instance-variables:
1938/// '{' objc-instance-variable-decl-list[opt] '}'
1939///
1940/// objc-instance-variable-decl-list:
1941/// objc-visibility-spec
1942/// objc-instance-variable-decl ';'
1943/// ';'
1944/// objc-instance-variable-decl-list objc-visibility-spec
1945/// objc-instance-variable-decl-list objc-instance-variable-decl ';'
1946/// objc-instance-variable-decl-list static_assert-declaration
1947/// objc-instance-variable-decl-list ';'
1948///
1949/// objc-visibility-spec:
1950/// @private
1951/// @protected
1952/// @public
1953/// @package [OBJC2]
1954///
1955/// objc-instance-variable-decl:
1956/// struct-declaration
1957///
1958void Parser::ParseObjCClassInstanceVariables(ObjCContainerDecl *interfaceDecl,
1959 tok::ObjCKeywordKind visibility,
1960 SourceLocation atLoc) {
1961 assert(Tok.is(tok::l_brace) && "expected {");
1962 SmallVector<Decl *, 32> AllIvarDecls;
1963
1964 ParseScope ClassScope(this, Scope::DeclScope | Scope::ClassScope);
1965
1966 BalancedDelimiterTracker T(*this, tok::l_brace);
1967 T.consumeOpen();
1968 // While we still have something to read, read the instance variables.
1969 while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
1970 // Each iteration of this loop reads one objc-instance-variable-decl.
1971
1972 // Check for extraneous top-level semicolon.
1973 if (Tok.is(tok::semi)) {
1974 ConsumeExtraSemi(InstanceVariableList);
1975 continue;
1976 }
1977
1978 // Set the default visibility to private.
1979 if (TryConsumeToken(tok::at)) { // parse objc-visibility-spec
1980 if (Tok.is(tok::code_completion)) {
1981 cutOffParsing();
1983 return;
1984 }
1985
1986 switch (Tok.getObjCKeywordID()) {
1987 case tok::objc_private:
1988 case tok::objc_public:
1989 case tok::objc_protected:
1990 case tok::objc_package:
1991 visibility = Tok.getObjCKeywordID();
1992 ConsumeToken();
1993 continue;
1994
1995 case tok::objc_end:
1996 Diag(Tok, diag::err_objc_unexpected_atend);
1998 Tok.setKind(tok::at);
1999 Tok.setLength(1);
2000 PP.EnterToken(Tok, /*IsReinject*/true);
2001 HelperActionsForIvarDeclarations(interfaceDecl, atLoc,
2002 T, AllIvarDecls, true);
2003 return;
2004
2005 default:
2006 Diag(Tok, diag::err_objc_illegal_visibility_spec);
2007 continue;
2008 }
2009 }
2010
2011 if (Tok.is(tok::code_completion)) {
2012 cutOffParsing();
2015 return;
2016 }
2017
2018 // This needs to duplicate a small amount of code from
2019 // ParseStructUnionBody() for things that should work in both
2020 // C struct and in Objective-C class instance variables.
2021 if (Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
2022 SourceLocation DeclEnd;
2023 ParseStaticAssertDeclaration(DeclEnd);
2024 continue;
2025 }
2026
2027 auto ObjCIvarCallback = [&](ParsingFieldDeclarator &FD) {
2028 assert(getObjCDeclContext() == interfaceDecl &&
2029 "Ivar should have interfaceDecl as its decl context");
2030 // Install the declarator into the interface decl.
2031 FD.D.setObjCIvar(true);
2032 Decl *Field = Actions.ActOnIvar(
2033 getCurScope(), FD.D.getDeclSpec().getSourceRange().getBegin(), FD.D,
2034 FD.BitfieldSize, visibility);
2035 if (Field)
2036 AllIvarDecls.push_back(Field);
2037 FD.complete(Field);
2038 };
2039
2040 // Parse all the comma separated declarators.
2041 ParsingDeclSpec DS(*this);
2042 ParseStructDeclaration(DS, ObjCIvarCallback);
2043
2044 if (Tok.is(tok::semi)) {
2045 ConsumeToken();
2046 } else {
2047 Diag(Tok, diag::err_expected_semi_decl_list);
2048 // Skip to end of block or statement
2049 SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
2050 }
2051 }
2052 HelperActionsForIvarDeclarations(interfaceDecl, atLoc,
2053 T, AllIvarDecls, false);
2054}
2055
2056/// objc-protocol-declaration:
2057/// objc-protocol-definition
2058/// objc-protocol-forward-reference
2059///
2060/// objc-protocol-definition:
2061/// \@protocol identifier
2062/// objc-protocol-refs[opt]
2063/// objc-interface-decl-list
2064/// \@end
2065///
2066/// objc-protocol-forward-reference:
2067/// \@protocol identifier-list ';'
2068///
2069/// "\@protocol identifier ;" should be resolved as "\@protocol
2070/// identifier-list ;": objc-interface-decl-list may not start with a
2071/// semicolon in the first alternative if objc-protocol-refs are omitted.
2073Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
2074 ParsedAttributes &attrs) {
2075 assert(Tok.isObjCAtKeyword(tok::objc_protocol) &&
2076 "ParseObjCAtProtocolDeclaration(): Expected @protocol");
2077 ConsumeToken(); // the "protocol" identifier
2078
2079 if (Tok.is(tok::code_completion)) {
2080 cutOffParsing();
2082 return nullptr;
2083 }
2084
2085 MaybeSkipAttributes(tok::objc_protocol);
2086
2087 if (expectIdentifier())
2088 return nullptr; // missing protocol name.
2089 // Save the protocol name, then consume it.
2090 IdentifierInfo *protocolName = Tok.getIdentifierInfo();
2091 SourceLocation nameLoc = ConsumeToken();
2092
2093 if (TryConsumeToken(tok::semi)) { // forward declaration of one protocol.
2094 IdentifierLocPair ProtoInfo(protocolName, nameLoc);
2095 return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtoInfo, attrs);
2096 }
2097
2098 CheckNestedObjCContexts(AtLoc);
2099
2100 if (Tok.is(tok::comma)) { // list of forward declarations.
2102 ProtocolRefs.push_back(std::make_pair(protocolName, nameLoc));
2103
2104 // Parse the list of forward declarations.
2105 while (true) {
2106 ConsumeToken(); // the ','
2107 if (expectIdentifier()) {
2108 SkipUntil(tok::semi);
2109 return nullptr;
2110 }
2111 ProtocolRefs.push_back(IdentifierLocPair(Tok.getIdentifierInfo(),
2112 Tok.getLocation()));
2113 ConsumeToken(); // the identifier
2114
2115 if (Tok.isNot(tok::comma))
2116 break;
2117 }
2118 // Consume the ';'.
2119 if (ExpectAndConsume(tok::semi, diag::err_expected_after, "@protocol"))
2120 return nullptr;
2121
2122 return Actions.ActOnForwardProtocolDeclaration(AtLoc, ProtocolRefs, attrs);
2123 }
2124
2125 // Last, and definitely not least, parse a protocol declaration.
2126 SourceLocation LAngleLoc, EndProtoLoc;
2127
2128 SmallVector<Decl *, 8> ProtocolRefs;
2129 SmallVector<SourceLocation, 8> ProtocolLocs;
2130 if (Tok.is(tok::less) &&
2131 ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, false, true,
2132 LAngleLoc, EndProtoLoc,
2133 /*consumeLastToken=*/true))
2134 return nullptr;
2135
2136 SkipBodyInfo SkipBody;
2137 ObjCProtocolDecl *ProtoType = Actions.ActOnStartProtocolInterface(
2138 AtLoc, protocolName, nameLoc, ProtocolRefs.data(), ProtocolRefs.size(),
2139 ProtocolLocs.data(), EndProtoLoc, attrs, &SkipBody);
2140
2141 ParseObjCInterfaceDeclList(tok::objc_protocol, ProtoType);
2142 if (SkipBody.CheckSameAsPrevious) {
2143 auto *PreviousDef = cast<ObjCProtocolDecl>(SkipBody.Previous);
2144 if (Actions.ActOnDuplicateODRHashDefinition(ProtoType, PreviousDef)) {
2146 PreviousDef->getDefinition());
2147 } else {
2148 ODRDiagsEmitter DiagsEmitter(Diags, Actions.getASTContext(),
2150 DiagsEmitter.diagnoseMismatch(PreviousDef, ProtoType);
2151 }
2152 }
2153 return Actions.ConvertDeclToDeclGroup(ProtoType);
2154}
2155
2156/// objc-implementation:
2157/// objc-class-implementation-prologue
2158/// objc-category-implementation-prologue
2159///
2160/// objc-class-implementation-prologue:
2161/// @implementation identifier objc-superclass[opt]
2162/// objc-class-instance-variables[opt]
2163///
2164/// objc-category-implementation-prologue:
2165/// @implementation identifier ( identifier )
2167Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc,
2168 ParsedAttributes &Attrs) {
2169 assert(Tok.isObjCAtKeyword(tok::objc_implementation) &&
2170 "ParseObjCAtImplementationDeclaration(): Expected @implementation");
2171 CheckNestedObjCContexts(AtLoc);
2172 ConsumeToken(); // the "implementation" identifier
2173
2174 // Code completion after '@implementation'.
2175 if (Tok.is(tok::code_completion)) {
2176 cutOffParsing();
2178 return nullptr;
2179 }
2180
2181 MaybeSkipAttributes(tok::objc_implementation);
2182
2183 if (expectIdentifier())
2184 return nullptr; // missing class or category name.
2185 // We have a class or category name - consume it.
2186 IdentifierInfo *nameId = Tok.getIdentifierInfo();
2187 SourceLocation nameLoc = ConsumeToken(); // consume class or category name
2188 ObjCImplDecl *ObjCImpDecl = nullptr;
2189
2190 // Neither a type parameter list nor a list of protocol references is
2191 // permitted here. Parse and diagnose them.
2192 if (Tok.is(tok::less)) {
2193 SourceLocation lAngleLoc, rAngleLoc;
2194 SmallVector<IdentifierLocPair, 8> protocolIdents;
2195 SourceLocation diagLoc = Tok.getLocation();
2196 ObjCTypeParamListScope typeParamScope(Actions, getCurScope());
2197 if (parseObjCTypeParamListOrProtocolRefs(typeParamScope, lAngleLoc,
2198 protocolIdents, rAngleLoc)) {
2199 Diag(diagLoc, diag::err_objc_parameterized_implementation)
2200 << SourceRange(diagLoc, PrevTokLocation);
2201 } else if (lAngleLoc.isValid()) {
2202 Diag(lAngleLoc, diag::err_unexpected_protocol_qualifier)
2203 << FixItHint::CreateRemoval(SourceRange(lAngleLoc, rAngleLoc));
2204 }
2205 }
2206
2207 if (Tok.is(tok::l_paren)) {
2208 // we have a category implementation.
2209 ConsumeParen();
2210 SourceLocation categoryLoc, rparenLoc;
2211 IdentifierInfo *categoryId = nullptr;
2212
2213 if (Tok.is(tok::code_completion)) {
2214 cutOffParsing();
2215 Actions.CodeCompleteObjCImplementationCategory(getCurScope(), nameId, nameLoc);
2216 return nullptr;
2217 }
2218
2219 if (Tok.is(tok::identifier)) {
2220 categoryId = Tok.getIdentifierInfo();
2221 categoryLoc = ConsumeToken();
2222 } else {
2223 Diag(Tok, diag::err_expected)
2224 << tok::identifier; // missing category name.
2225 return nullptr;
2226 }
2227 if (Tok.isNot(tok::r_paren)) {
2228 Diag(Tok, diag::err_expected) << tok::r_paren;
2229 SkipUntil(tok::r_paren); // don't stop at ';'
2230 return nullptr;
2231 }
2232 rparenLoc = ConsumeParen();
2233 if (Tok.is(tok::less)) { // we have illegal '<' try to recover
2234 Diag(Tok, diag::err_unexpected_protocol_qualifier);
2235 SourceLocation protocolLAngleLoc, protocolRAngleLoc;
2236 SmallVector<Decl *, 4> protocols;
2237 SmallVector<SourceLocation, 4> protocolLocs;
2238 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
2239 /*warnOnIncompleteProtocols=*/false,
2240 /*ForObjCContainer=*/false,
2241 protocolLAngleLoc, protocolRAngleLoc,
2242 /*consumeLastToken=*/true);
2243 }
2244 ObjCImpDecl = Actions.ActOnStartCategoryImplementation(
2245 AtLoc, nameId, nameLoc, categoryId, categoryLoc, Attrs);
2246
2247 } else {
2248 // We have a class implementation
2249 SourceLocation superClassLoc;
2250 IdentifierInfo *superClassId = nullptr;
2251 if (TryConsumeToken(tok::colon)) {
2252 // We have a super class
2253 if (expectIdentifier())
2254 return nullptr; // missing super class name.
2255 superClassId = Tok.getIdentifierInfo();
2256 superClassLoc = ConsumeToken(); // Consume super class name
2257 }
2258 ObjCImpDecl = Actions.ActOnStartClassImplementation(
2259 AtLoc, nameId, nameLoc, superClassId, superClassLoc, Attrs);
2260
2261 if (Tok.is(tok::l_brace)) // we have ivars
2262 ParseObjCClassInstanceVariables(ObjCImpDecl, tok::objc_private, AtLoc);
2263 else if (Tok.is(tok::less)) { // we have illegal '<' try to recover
2264 Diag(Tok, diag::err_unexpected_protocol_qualifier);
2265
2266 SourceLocation protocolLAngleLoc, protocolRAngleLoc;
2267 SmallVector<Decl *, 4> protocols;
2268 SmallVector<SourceLocation, 4> protocolLocs;
2269 (void)ParseObjCProtocolReferences(protocols, protocolLocs,
2270 /*warnOnIncompleteProtocols=*/false,
2271 /*ForObjCContainer=*/false,
2272 protocolLAngleLoc, protocolRAngleLoc,
2273 /*consumeLastToken=*/true);
2274 }
2275 }
2276 assert(ObjCImpDecl);
2277
2278 SmallVector<Decl *, 8> DeclsInGroup;
2279
2280 {
2281 ObjCImplParsingDataRAII ObjCImplParsing(*this, ObjCImpDecl);
2282 while (!ObjCImplParsing.isFinished() && !isEofOrEom()) {
2283 ParsedAttributes DeclAttrs(AttrFactory);
2284 MaybeParseCXX11Attributes(DeclAttrs);
2285 ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
2286 if (DeclGroupPtrTy DGP =
2287 ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs)) {
2288 DeclGroupRef DG = DGP.get();
2289 DeclsInGroup.append(DG.begin(), DG.end());
2290 }
2291 }
2292 }
2293
2294 return Actions.ActOnFinishObjCImplementation(ObjCImpDecl, DeclsInGroup);
2295}
2296
2298Parser::ParseObjCAtEndDeclaration(SourceRange atEnd) {
2299 assert(Tok.isObjCAtKeyword(tok::objc_end) &&
2300 "ParseObjCAtEndDeclaration(): Expected @end");
2301 ConsumeToken(); // the "end" identifier
2302 if (CurParsedObjCImpl)
2303 CurParsedObjCImpl->finish(atEnd);
2304 else
2305 // missing @implementation
2306 Diag(atEnd.getBegin(), diag::err_expected_objc_container);
2307 return nullptr;
2308}
2309
2310Parser::ObjCImplParsingDataRAII::~ObjCImplParsingDataRAII() {
2311 if (!Finished) {
2312 finish(P.Tok.getLocation());
2313 if (P.isEofOrEom()) {
2314 P.Diag(P.Tok, diag::err_objc_missing_end)
2315 << FixItHint::CreateInsertion(P.Tok.getLocation(), "\n@end\n");
2316 P.Diag(Dcl->getBeginLoc(), diag::note_objc_container_start)
2318 }
2319 }
2320 P.CurParsedObjCImpl = nullptr;
2321 assert(LateParsedObjCMethods.empty());
2322}
2323
2324void Parser::ObjCImplParsingDataRAII::finish(SourceRange AtEnd) {
2325 assert(!Finished);
2326 P.Actions.DefaultSynthesizeProperties(P.getCurScope(), Dcl, AtEnd.getBegin());
2327 for (size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
2328 P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
2329 true/*Methods*/);
2330
2331 P.Actions.ActOnAtEnd(P.getCurScope(), AtEnd);
2332
2333 if (HasCFunction)
2334 for (size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
2335 P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
2336 false/*c-functions*/);
2337
2338 /// Clear and free the cached objc methods.
2339 for (LateParsedObjCMethodContainer::iterator
2340 I = LateParsedObjCMethods.begin(),
2341 E = LateParsedObjCMethods.end(); I != E; ++I)
2342 delete *I;
2343 LateParsedObjCMethods.clear();
2344
2345 Finished = true;
2346}
2347
2348/// compatibility-alias-decl:
2349/// @compatibility_alias alias-name class-name ';'
2350///
2351Decl *Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) {
2352 assert(Tok.isObjCAtKeyword(tok::objc_compatibility_alias) &&
2353 "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias");
2354 ConsumeToken(); // consume compatibility_alias
2355 if (expectIdentifier())
2356 return nullptr;
2357 IdentifierInfo *aliasId = Tok.getIdentifierInfo();
2358 SourceLocation aliasLoc = ConsumeToken(); // consume alias-name
2359 if (expectIdentifier())
2360 return nullptr;
2361 IdentifierInfo *classId = Tok.getIdentifierInfo();
2362 SourceLocation classLoc = ConsumeToken(); // consume class-name;
2363 ExpectAndConsume(tok::semi, diag::err_expected_after, "@compatibility_alias");
2364 return Actions.ActOnCompatibilityAlias(atLoc, aliasId, aliasLoc,
2365 classId, classLoc);
2366}
2367
2368/// property-synthesis:
2369/// @synthesize property-ivar-list ';'
2370///
2371/// property-ivar-list:
2372/// property-ivar
2373/// property-ivar-list ',' property-ivar
2374///
2375/// property-ivar:
2376/// identifier
2377/// identifier '=' identifier
2378///
2379Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
2380 assert(Tok.isObjCAtKeyword(tok::objc_synthesize) &&
2381 "ParseObjCPropertySynthesize(): Expected '@synthesize'");
2382 ConsumeToken(); // consume synthesize
2383
2384 while (true) {
2385 if (Tok.is(tok::code_completion)) {
2386 cutOffParsing();
2388 return nullptr;
2389 }
2390
2391 if (Tok.isNot(tok::identifier)) {
2392 Diag(Tok, diag::err_synthesized_property_name);
2393 SkipUntil(tok::semi);
2394 return nullptr;
2395 }
2396
2397 IdentifierInfo *propertyIvar = nullptr;
2398 IdentifierInfo *propertyId = Tok.getIdentifierInfo();
2399 SourceLocation propertyLoc = ConsumeToken(); // consume property name
2400 SourceLocation propertyIvarLoc;
2401 if (TryConsumeToken(tok::equal)) {
2402 // property '=' ivar-name
2403 if (Tok.is(tok::code_completion)) {
2404 cutOffParsing();
2406 return nullptr;
2407 }
2408
2409 if (expectIdentifier())
2410 break;
2411 propertyIvar = Tok.getIdentifierInfo();
2412 propertyIvarLoc = ConsumeToken(); // consume ivar-name
2413 }
2414 Actions.ActOnPropertyImplDecl(
2415 getCurScope(), atLoc, propertyLoc, true,
2416 propertyId, propertyIvar, propertyIvarLoc,
2418 if (Tok.isNot(tok::comma))
2419 break;
2420 ConsumeToken(); // consume ','
2421 }
2422 ExpectAndConsume(tok::semi, diag::err_expected_after, "@synthesize");
2423 return nullptr;
2424}
2425
2426/// property-dynamic:
2427/// @dynamic property-list
2428///
2429/// property-list:
2430/// identifier
2431/// property-list ',' identifier
2432///
2433Decl *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
2434 assert(Tok.isObjCAtKeyword(tok::objc_dynamic) &&
2435 "ParseObjCPropertyDynamic(): Expected '@dynamic'");
2436 ConsumeToken(); // consume dynamic
2437
2438 bool isClassProperty = false;
2439 if (Tok.is(tok::l_paren)) {
2440 ConsumeParen();
2441 const IdentifierInfo *II = Tok.getIdentifierInfo();
2442
2443 if (!II) {
2444 Diag(Tok, diag::err_objc_expected_property_attr) << II;
2445 SkipUntil(tok::r_paren, StopAtSemi);
2446 } else {
2447 SourceLocation AttrName = ConsumeToken(); // consume attribute name
2448 if (II->isStr("class")) {
2449 isClassProperty = true;
2450 if (Tok.isNot(tok::r_paren)) {
2451 Diag(Tok, diag::err_expected) << tok::r_paren;
2452 SkipUntil(tok::r_paren, StopAtSemi);
2453 } else
2454 ConsumeParen();
2455 } else {
2456 Diag(AttrName, diag::err_objc_expected_property_attr) << II;
2457 SkipUntil(tok::r_paren, StopAtSemi);
2458 }
2459 }
2460 }
2461
2462 while (true) {
2463 if (Tok.is(tok::code_completion)) {
2464 cutOffParsing();
2466 return nullptr;
2467 }
2468
2469 if (expectIdentifier()) {
2470 SkipUntil(tok::semi);
2471 return nullptr;
2472 }
2473
2474 IdentifierInfo *propertyId = Tok.getIdentifierInfo();
2475 SourceLocation propertyLoc = ConsumeToken(); // consume property name
2476 Actions.ActOnPropertyImplDecl(
2477 getCurScope(), atLoc, propertyLoc, false,
2478 propertyId, nullptr, SourceLocation(),
2481
2482 if (Tok.isNot(tok::comma))
2483 break;
2484 ConsumeToken(); // consume ','
2485 }
2486 ExpectAndConsume(tok::semi, diag::err_expected_after, "@dynamic");
2487 return nullptr;
2488}
2489
2490/// objc-throw-statement:
2491/// throw expression[opt];
2492///
2493StmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) {
2494 ExprResult Res;
2495 ConsumeToken(); // consume throw
2496 if (Tok.isNot(tok::semi)) {
2497 Res = ParseExpression();
2498 if (Res.isInvalid()) {
2499 SkipUntil(tok::semi);
2500 return StmtError();
2501 }
2502 }
2503 // consume ';'
2504 ExpectAndConsume(tok::semi, diag::err_expected_after, "@throw");
2505 return Actions.ActOnObjCAtThrowStmt(atLoc, Res.get(), getCurScope());
2506}
2507
2508/// objc-synchronized-statement:
2509/// @synchronized '(' expression ')' compound-statement
2510///
2512Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
2513 ConsumeToken(); // consume synchronized
2514 if (Tok.isNot(tok::l_paren)) {
2515 Diag(Tok, diag::err_expected_lparen_after) << "@synchronized";
2516 return StmtError();
2517 }
2518
2519 // The operand is surrounded with parentheses.
2520 ConsumeParen(); // '('
2521 ExprResult operand(ParseExpression());
2522
2523 if (Tok.is(tok::r_paren)) {
2524 ConsumeParen(); // ')'
2525 } else {
2526 if (!operand.isInvalid())
2527 Diag(Tok, diag::err_expected) << tok::r_paren;
2528
2529 // Skip forward until we see a left brace, but don't consume it.
2530 SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch);
2531 }
2532
2533 // Require a compound statement.
2534 if (Tok.isNot(tok::l_brace)) {
2535 if (!operand.isInvalid())
2536 Diag(Tok, diag::err_expected) << tok::l_brace;
2537 return StmtError();
2538 }
2539
2540 // Check the @synchronized operand now.
2541 if (!operand.isInvalid())
2542 operand = Actions.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.ActOnObjCAtSynchronizedStmt(atLoc, operand.get(), body.get());
2558}
2559
2560/// objc-try-catch-statement:
2561/// @try compound-statement objc-catch-list[opt]
2562/// @try compound-statement objc-catch-list[opt] @finally compound-statement
2563///
2564/// objc-catch-list:
2565/// @catch ( parameter-declaration ) compound-statement
2566/// objc-catch-list @catch ( catch-parameter-declaration ) compound-statement
2567/// catch-parameter-declaration:
2568/// parameter-declaration
2569/// '...' [OBJC2]
2570///
2571StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
2572 bool catch_or_finally_seen = false;
2573
2574 ConsumeToken(); // consume try
2575 if (Tok.isNot(tok::l_brace)) {
2576 Diag(Tok, diag::err_expected) << tok::l_brace;
2577 return StmtError();
2578 }
2579 StmtVector CatchStmts;
2580 StmtResult FinallyStmt;
2581 ParseScope TryScope(this, Scope::DeclScope | Scope::CompoundStmtScope);
2582 StmtResult TryBody(ParseCompoundStatementBody());
2583 TryScope.Exit();
2584 if (TryBody.isInvalid())
2585 TryBody = Actions.ActOnNullStmt(Tok.getLocation());
2586
2587 while (Tok.is(tok::at)) {
2588 // At this point, we need to lookahead to determine if this @ is the start
2589 // of an @catch or @finally. We don't want to consume the @ token if this
2590 // is an @try or @encode or something else.
2591 Token AfterAt = GetLookAheadToken(1);
2592 if (!AfterAt.isObjCAtKeyword(tok::objc_catch) &&
2593 !AfterAt.isObjCAtKeyword(tok::objc_finally))
2594 break;
2595
2596 SourceLocation AtCatchFinallyLoc = ConsumeToken();
2597 if (Tok.isObjCAtKeyword(tok::objc_catch)) {
2598 Decl *FirstPart = nullptr;
2599 ConsumeToken(); // consume catch
2600 if (Tok.is(tok::l_paren)) {
2601 ConsumeParen();
2602 ParseScope CatchScope(this, Scope::DeclScope |
2605 if (Tok.isNot(tok::ellipsis)) {
2606 DeclSpec DS(AttrFactory);
2607 ParseDeclarationSpecifiers(DS);
2610 ParseDeclarator(ParmDecl);
2611
2612 // Inform the actions module about the declarator, so it
2613 // gets added to the current scope.
2614 FirstPart = Actions.ActOnObjCExceptionDecl(getCurScope(), ParmDecl);
2615 } else
2616 ConsumeToken(); // consume '...'
2617
2618 SourceLocation RParenLoc;
2619
2620 if (Tok.is(tok::r_paren))
2621 RParenLoc = ConsumeParen();
2622 else // Skip over garbage, until we get to ')'. Eat the ')'.
2623 SkipUntil(tok::r_paren, StopAtSemi);
2624
2625 StmtResult CatchBody(true);
2626 if (Tok.is(tok::l_brace))
2627 CatchBody = ParseCompoundStatementBody();
2628 else
2629 Diag(Tok, diag::err_expected) << tok::l_brace;
2630 if (CatchBody.isInvalid())
2631 CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
2632
2633 StmtResult Catch = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc,
2634 RParenLoc,
2635 FirstPart,
2636 CatchBody.get());
2637 if (!Catch.isInvalid())
2638 CatchStmts.push_back(Catch.get());
2639
2640 } else {
2641 Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
2642 << "@catch clause";
2643 return StmtError();
2644 }
2645 catch_or_finally_seen = true;
2646 } else {
2647 assert(Tok.isObjCAtKeyword(tok::objc_finally) && "Lookahead confused?");
2648 ConsumeToken(); // consume finally
2649 ParseScope FinallyScope(this,
2651
2652 bool ShouldCapture =
2653 getTargetInfo().getTriple().isWindowsMSVCEnvironment();
2654 if (ShouldCapture)
2656 CR_ObjCAtFinally, 1);
2657
2658 StmtResult FinallyBody(true);
2659 if (Tok.is(tok::l_brace))
2660 FinallyBody = ParseCompoundStatementBody();
2661 else
2662 Diag(Tok, diag::err_expected) << tok::l_brace;
2663
2664 if (FinallyBody.isInvalid()) {
2665 FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
2666 if (ShouldCapture)
2667 Actions.ActOnCapturedRegionError();
2668 } else if (ShouldCapture) {
2669 FinallyBody = Actions.ActOnCapturedRegionEnd(FinallyBody.get());
2670 }
2671
2672 FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
2673 FinallyBody.get());
2674 catch_or_finally_seen = true;
2675 break;
2676 }
2677 }
2678 if (!catch_or_finally_seen) {
2679 Diag(atLoc, diag::err_missing_catch_finally);
2680 return StmtError();
2681 }
2682
2683 return Actions.ActOnObjCAtTryStmt(atLoc, TryBody.get(),
2684 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.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.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.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.getObjCMessageKind(getCurScope(), Name, NameLoc,
3132 Name == Ident_super,
3133 NextToken().is(tok::period),
3134 ReceiverType)) {
3136 return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(), nullptr,
3137 nullptr);
3138
3140 if (!ReceiverType) {
3141 SkipUntil(tok::r_square, StopAtSemi);
3142 return ExprError();
3143 }
3144
3145 ConsumeToken(); // the type name
3146
3147 // Parse type arguments and protocol qualifiers.
3148 if (Tok.is(tok::less)) {
3149 SourceLocation NewEndLoc;
3150 TypeResult NewReceiverType
3151 = parseObjCTypeArgsAndProtocolQualifiers(NameLoc, ReceiverType,
3152 /*consumeLastToken=*/true,
3153 NewEndLoc);
3154 if (!NewReceiverType.isUsable()) {
3155 SkipUntil(tok::r_square, StopAtSemi);
3156 return ExprError();
3157 }
3158
3159 ReceiverType = NewReceiverType.get();
3160 }
3161
3162 return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
3163 ReceiverType, nullptr);
3164
3166 // Fall through to parse an expression.
3167 break;
3168 }
3169 }
3170
3171 // Otherwise, an arbitrary expression can be the receiver of a send.
3173 if (Res.isInvalid()) {
3174 SkipUntil(tok::r_square, StopAtSemi);
3175 return Res;
3176 }
3177
3178 return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), nullptr,
3179 Res.get());
3180}
3181
3182/// Parse the remainder of an Objective-C message following the
3183/// '[' objc-receiver.
3184///
3185/// This routine handles sends to super, class messages (sent to a
3186/// class name), and instance messages (sent to an object), and the
3187/// target is represented by \p SuperLoc, \p ReceiverType, or \p
3188/// ReceiverExpr, respectively. Only one of these parameters may have
3189/// a valid value.
3190///
3191/// \param LBracLoc The location of the opening '['.
3192///
3193/// \param SuperLoc If this is a send to 'super', the location of the
3194/// 'super' keyword that indicates a send to the superclass.
3195///
3196/// \param ReceiverType If this is a class message, the type of the
3197/// class we are sending a message to.
3198///
3199/// \param ReceiverExpr If this is an instance message, the expression
3200/// used to compute the receiver object.
3201///
3202/// objc-message-args:
3203/// objc-selector
3204/// objc-keywordarg-list
3205///
3206/// objc-keywordarg-list:
3207/// objc-keywordarg
3208/// objc-keywordarg-list objc-keywordarg
3209///
3210/// objc-keywordarg:
3211/// selector-name[opt] ':' objc-keywordexpr
3212///
3213/// objc-keywordexpr:
3214/// nonempty-expr-list
3215///
3216/// nonempty-expr-list:
3217/// assignment-expression
3218/// nonempty-expr-list , assignment-expression
3219///
3221Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
3222 SourceLocation SuperLoc,
3223 ParsedType ReceiverType,
3224 Expr *ReceiverExpr) {
3225 InMessageExpressionRAIIObject InMessage(*this, true);
3226
3227 if (Tok.is(tok::code_completion)) {
3228 cutOffParsing();
3229 if (SuperLoc.isValid())
3230 Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc,
3231 std::nullopt, false);
3232 else if (ReceiverType)
3233 Actions.CodeCompleteObjCClassMessage(getCurScope(), ReceiverType,
3234 std::nullopt, false);
3235 else
3236 Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr,
3237 std::nullopt, false);
3238 return ExprError();
3239 }
3240
3241 // Parse objc-selector
3242 SourceLocation Loc;
3243 IdentifierInfo *selIdent = ParseObjCSelectorPiece(Loc);
3244
3247 ExprVector KeyExprs;
3248
3249 if (Tok.is(tok::colon)) {
3250 while (true) {
3251 // Each iteration parses a single keyword argument.
3252 KeyIdents.push_back(selIdent);
3253 KeyLocs.push_back(Loc);
3254
3255 if (ExpectAndConsume(tok::colon)) {
3256 // We must manually skip to a ']', otherwise the expression skipper will
3257 // stop at the ']' when it skips to the ';'. We want it to skip beyond
3258 // the enclosing expression.
3259 SkipUntil(tok::r_square, StopAtSemi);
3260 return ExprError();
3261 }
3262
3263 /// Parse the expression after ':'
3264
3265 if (Tok.is(tok::code_completion)) {
3266 cutOffParsing();
3267 if (SuperLoc.isValid())
3268 Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc,
3269 KeyIdents,
3270 /*AtArgumentExpression=*/true);
3271 else if (ReceiverType)
3272 Actions.CodeCompleteObjCClassMessage(getCurScope(), ReceiverType,
3273 KeyIdents,
3274 /*AtArgumentExpression=*/true);
3275 else
3276 Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr,
3277 KeyIdents,
3278 /*AtArgumentExpression=*/true);
3279
3280 return ExprError();
3281 }
3282
3284 if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
3285 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
3286 Expr = ParseBraceInitializer();
3287 } else
3289
3290 ExprResult Res(Expr);
3291 if (Res.isInvalid()) {
3292 // We must manually skip to a ']', otherwise the expression skipper will
3293 // stop at the ']' when it skips to the ';'. We want it to skip beyond
3294 // the enclosing expression.
3295 SkipUntil(tok::r_square, StopAtSemi);
3296 return Res;
3297 }
3298
3299 // We have a valid expression.
3300 KeyExprs.push_back(Res.get());
3301
3302 // Code completion after each argument.
3303 if (Tok.is(tok::code_completion)) {
3304 cutOffParsing();
3305 if (SuperLoc.isValid())
3306 Actions.CodeCompleteObjCSuperMessage(getCurScope(), SuperLoc,
3307 KeyIdents,
3308 /*AtArgumentExpression=*/false);
3309 else if (ReceiverType)
3310 Actions.CodeCompleteObjCClassMessage(getCurScope(), ReceiverType,
3311 KeyIdents,
3312 /*AtArgumentExpression=*/false);
3313 else
3314 Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr,
3315 KeyIdents,
3316 /*AtArgumentExpression=*/false);
3317 return ExprError();
3318 }
3319
3320 // Check for another keyword selector.
3321 selIdent = ParseObjCSelectorPiece(Loc);
3322 if (!selIdent && Tok.isNot(tok::colon))
3323 break;
3324 // We have a selector or a colon, continue parsing.
3325 }
3326 // Parse the, optional, argument list, comma separated.
3327 while (Tok.is(tok::comma)) {
3328 SourceLocation commaLoc = ConsumeToken(); // Eat the ','.
3329 /// Parse the expression after ','
3331 if (Tok.is(tok::colon))
3332 Res = Actions.CorrectDelayedTyposInExpr(Res);
3333 if (Res.isInvalid()) {
3334 if (Tok.is(tok::colon)) {
3335 Diag(commaLoc, diag::note_extra_comma_message_arg) <<
3336 FixItHint::CreateRemoval(commaLoc);
3337 }
3338 // We must manually skip to a ']', otherwise the expression skipper will
3339 // stop at the ']' when it skips to the ';'. We want it to skip beyond
3340 // the enclosing expression.
3341 SkipUntil(tok::r_square, StopAtSemi);
3342 return Res;
3343 }
3344
3345 // We have a valid expression.
3346 KeyExprs.push_back(Res.get());
3347 }
3348 } else if (!selIdent) {
3349 Diag(Tok, diag::err_expected) << tok::identifier; // missing selector name.
3350
3351 // We must manually skip to a ']', otherwise the expression skipper will
3352 // stop at the ']' when it skips to the ';'. We want it to skip beyond
3353 // the enclosing expression.
3354 SkipUntil(tok::r_square, StopAtSemi);
3355 return ExprError();
3356 }
3357
3358 if (Tok.isNot(tok::r_square)) {
3359 Diag(Tok, diag::err_expected)
3360 << (Tok.is(tok::identifier) ? tok::colon : tok::r_square);
3361 // We must manually skip to a ']', otherwise the expression skipper will
3362 // stop at the ']' when it skips to the ';'. We want it to skip beyond
3363 // the enclosing expression.
3364 SkipUntil(tok::r_square, StopAtSemi);
3365 return ExprError();
3366 }
3367
3368 SourceLocation RBracLoc = ConsumeBracket(); // consume ']'
3369
3370 unsigned nKeys = KeyIdents.size();
3371 if (nKeys == 0) {
3372 KeyIdents.push_back(selIdent);
3373 KeyLocs.push_back(Loc);
3374 }
3375 Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]);
3376
3377 if (SuperLoc.isValid())
3378 return Actions.ActOnSuperMessage(getCurScope(), SuperLoc, Sel,
3379 LBracLoc, KeyLocs, RBracLoc, KeyExprs);
3380 else if (ReceiverType)
3381 return Actions.ActOnClassMessage(getCurScope(), ReceiverType, Sel,
3382 LBracLoc, KeyLocs, RBracLoc, KeyExprs);
3383 return Actions.ActOnInstanceMessage(getCurScope(), ReceiverExpr, Sel,
3384 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.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.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.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.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.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.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.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.ParseObjCEncodeExpression(AtLoc, EncLoc, T.getOpenLocation(),
3609 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.ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc,
3633 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.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();
3682 Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents);
3683 return ExprError();
3684 }
3685
3686 // Check for another keyword selector.
3687 SourceLocation Loc;
3688 SelIdent = ParseObjCSelectorPiece(Loc);
3689 KeyIdents.push_back(SelIdent);
3690 if (!SelIdent && Tok.isNot(tok::colon) && Tok.isNot(tok::coloncolon))
3691 break;
3692 }
3693 }
3694 if (HasOptionalParen && Tok.is(tok::r_paren))
3695 ConsumeParen(); // ')'
3696 T.consumeClose();
3697 Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]);
3698 return Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc,
3699 T.getOpenLocation(),
3700 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 = MCDecl &&
3708 ((parseMethod && !Actions.isObjCMethodDecl(MCDecl)) ||
3709 (!parseMethod && Actions.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.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
#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:407
static void diagnoseRedundantPropertyNullability(Parser &P, ObjCDeclSpec &DS, NullabilityKind nullability, SourceLocation nullabilityLoc)
Diagnose redundant or conflicting nullability information.
Definition: ParseObjc.cpp:850
static bool isTopLevelObjCKeyword(tok::ObjCKeywordKind DirectiveKind)
Definition: ParseObjc.cpp:616
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:1261
__device__ int
Class to handle popping type parameters when leaving the scope.
Definition: ParseObjc.cpp:115
ObjCTypeParamListScope(Sema &Actions, Scope *S)
Definition: ParseObjc.cpp:121
void enter(ObjCTypeParamList *P)
Definition: ParseObjc.cpp:128
const clang::PrintingPolicy & getPrintingPolicy() const
Definition: ASTContext.h:697
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:733
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:246
ParsedAttributes & getAttributes()
Definition: DeclSpec.h:869
AttributePool & getAttributePool() const
Definition: DeclSpec.h:842
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:132
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: DeclBase.h:437
Information about one declarator, including the parsed type information and the identifier.
Definition: DeclSpec.h:1898
const DeclaratorChunk & getTypeObject(unsigned i) const
Return the specified TypeInfo from this declarator.
Definition: DeclSpec.h:2396
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
Definition: DeclSpec.h:2045
const ParsedAttributes & getAttributes() const
Definition: DeclSpec.h:2681
unsigned getNumTypeObjects() const
Return the number of types applied to this declarator.
Definition: DeclSpec.h:2392
const ParsedAttributesView & getDeclarationAttributes() const
Definition: DeclSpec.h:2684
AttributePool & getAttributePool() const
Definition: DeclSpec.h:2054
DeclSpec & getMutableDeclSpec()
getMutableDeclSpec - Return a non-const version of the DeclSpec.
Definition: DeclSpec.h:2052
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:2326
ObjCContainerDecl - Represents a container for method declarations.
Definition: DeclObjC.h:947
Captures information about "declaration specifiers" specific to Objective-C.
Definition: DeclSpec.h:896
void setObjCDeclQualifier(ObjCDeclQualifier DQVal)
Definition: DeclSpec.h:923
ObjCPropertyAttribute::Kind getPropertyAttributes() const
Definition: DeclSpec.h:930
ObjCDeclQualifier
ObjCDeclQualifier - Qualifier used on types in method declarations.
Definition: DeclSpec.h:904
void setSetterName(IdentifierInfo *name, SourceLocation loc)
Definition: DeclSpec.h:974
const IdentifierInfo * getSetterName() const
Definition: DeclSpec.h:971
ObjCDeclQualifier getObjCDeclQualifier() const
Definition: DeclSpec.h:920
SourceLocation getNullabilityLoc() const
Definition: DeclSpec.h:946
NullabilityKind getNullability() const
Definition: DeclSpec.h:938
void setGetterName(IdentifierInfo *name, SourceLocation loc)
Definition: DeclSpec.h:966
void setNullability(SourceLocation loc, NullabilityKind kind)
Definition: DeclSpec.h:954
const IdentifierInfo * getGetterName() const
Definition: DeclSpec.h:963
void setPropertyAttributes(ObjCPropertyAttribute::Kind PRVal)
Definition: DeclSpec.h:933
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:2082
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:126
static const ParsedAttributesView & none()
Definition: ParsedAttr.h:826
void addAtEnd(ParsedAttr *newAttr)
Definition: ParsedAttr.h:836
void remove(ParsedAttr *ToBeRemoved)
Definition: ParsedAttr.h:841
ParsedAttributes - A collection of parsed attributes.
Definition: ParsedAttr.h:946
AttributePool & getPool() const
Definition: ParsedAttr.h:952
void takeAllFrom(ParsedAttributes &Other)
Definition: ParsedAttr.h:954
Parser - This implements a parser for the C family of languages.
Definition: Parser.h:56
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:48
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Definition: Parser.cpp:80
Preprocessor & getPreprocessor() const
Definition: Parser.h:489
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
Definition: Parser.h:540
static TypeResult getTypeAnnotation(const Token &Tok)
getTypeAnnotation - Read a parsed type out of an annotation token.
Definition: Parser.h:869
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
Definition: Parser.h:568
bool TryConsumeToken(tok::TokenKind Expected)
Definition: Parser.h:548
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Definition: Parser.h:505
Scope * getCurScope() const
Definition: Parser.h:494
const TargetInfo & getTargetInfo() const
Definition: Parser.h:488
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:1286
friend class ObjCDeclContextSwitch
Definition: Parser.h:63
ExprResult ParseAssignmentExpression(TypeCastState isTypeCast=NotTypeCast)
Parse an expr that doesn't include (top-level) commas.
Definition: ParseExpr.cpp:167
const LangOptions & getLangOpts() const
Definition: Parser.h:487
ExprResult ParseExpression(TypeCastState isTypeCast=NotTypeCast)
Simple precedence-based parser for binary/ternary operators.
Definition: ParseExpr.cpp:130
SmallVector< Stmt *, 32 > StmtVector
A SmallVector of statements.
Definition: Parser.h:513
SkipUntilFlags
Control flags for SkipUntil functions.
Definition: Parser.h:1264
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
Definition: Parser.h:1267
@ StopAtSemi
Stop skipping at semicolon.
Definition: Parser.h:1265
bool TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No)
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
Definition: Parser.cpp:1997
ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral=false)
ObjCContainerDecl * getObjCDeclContext() const
Definition: Parser.h:499
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
Definition: Parser.h:864
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:940
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:1007
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.
Records and restores the CurFPFeatures state on entry/exit of compound statements.
Definition: Sema.h:10556
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:457
void CodeCompleteObjCMethodDeclSelector(Scope *S, bool IsInstanceMethod, bool AtParameterName, ParsedType ReturnType, ArrayRef< const IdentifierInfo * > SelIdents)
void CodeCompleteObjCProtocolDecl(Scope *S)
ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Op, Expr *Input, bool IsAfterAmp=false)
Definition: SemaExpr.cpp:16077
void ActOnStartOfObjCMethodDef(Scope *S, Decl *D)
ActOnStartOfObjCMethodDef - This routine sets up parameters; invisible and user declared,...
DeclGroupPtrTy ActOnFinishObjCImplementation(Decl *ObjCImpDecl, ArrayRef< Decl * > Decls)
ExprResult ParseObjCProtocolExpression(IdentifierInfo *ProtocolName, SourceLocation AtLoc, SourceLocation ProtoLoc, SourceLocation LParenLoc, SourceLocation ProtoIdLoc, SourceLocation RParenLoc)
ParseObjCProtocolExpression - Build protocol expression for @protocol.
Decl * ActOnSkippedFunctionBody(Decl *Decl)
Definition: SemaDecl.cpp:16012
ExprResult ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *operand)
Definition: SemaStmt.cpp:4383
void CodeCompleteObjCMessageReceiver(Scope *S)
DeclGroupPtrTy ActOnForwardClassDeclaration(SourceLocation Loc, IdentifierInfo **IdentList, SourceLocation *IdentLocs, ArrayRef< ObjCTypeParamList * > TypeParamLists, unsigned NumElts)
ObjCContainerKind
Definition: Sema.h:11860
@ OCK_Implementation
Definition: Sema.h:11866
@ OCK_None
Definition: Sema.h:11861
Decl * ActOnParamDeclarator(Scope *S, Declarator &D, SourceLocation ExplicitThisLoc={})
ActOnParamDeclarator - Called from Parser::ParseFunctionDeclarator() to introduce parameters into fun...
Definition: SemaDecl.cpp:15168
void CodeCompleteObjCAtDirective(Scope *S)
ObjCTypeParamList * actOnObjCTypeParamList(Scope *S, SourceLocation lAngleLoc, ArrayRef< Decl * > typeParams, SourceLocation rAngleLoc)
bool ActOnDuplicateODRHashDefinition(T *Duplicate, T *Previous)
Check ODR hashes for C/ObjC when merging types from modules.
Definition: Sema.h:11847
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...
ExprResult ActOnCharacterConstant(const Token &Tok, Scope *UDLScope=nullptr)
Definition: SemaExpr.cpp:3788
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 BuildObjCDictionaryLiteral(SourceRange SR, MutableArrayRef< ObjCDictionaryElement > Elements)
Decl * ActOnProperty(Scope *S, SourceLocation AtLoc, SourceLocation LParenLoc, FieldDeclarator &FD, ObjCDeclSpec &ODS, Selector GetterSel, Selector SetterSel, tok::ObjCKeywordKind MethodImplKind, DeclContext *lexicalDC=nullptr)
void CodeCompleteObjCAtExpression(Scope *S)
void CodeCompleteObjCPropertySynthesizeIvar(Scope *S, IdentifierInfo *PropertyName)
ObjCImplementationDecl * ActOnStartClassImplementation(SourceLocation AtClassImplLoc, const IdentifierInfo *ClassName, SourceLocation ClassLoc, const IdentifierInfo *SuperClassname, SourceLocation SuperClassLoc, const ParsedAttributesView &AttrList)
ExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
Decl * ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef< Decl * > allMethods=std::nullopt, ArrayRef< DeclGroupPtrTy > allTUVars=std::nullopt)
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: SemaType.cpp:1159
void CodeCompleteObjCClassForwardDecl(Scope *S)
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...
ASTContext & Context
Definition: Sema.h:858
void ActOnCapturedRegionError()
Definition: SemaStmt.cpp:4929
StmtResult ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body)
Definition: SemaStmt.cpp:4439
ObjCProtocolDecl * LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)
Find the protocol with the given name, if any.
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
Definition: SemaDecl.cpp:66
ASTContext & getASTContext() const
Definition: Sema.h:527
void CodeCompleteObjCPropertyDefinition(Scope *S)
bool isObjCMethodDecl(Decl *D)
Definition: Sema.h:12027
StmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try, MultiStmtArg Catch, Stmt *Finally)
Definition: SemaStmt.cpp:4321
void AddAnyMethodToGlobalPool(Decl *D)
AddAnyMethodToGlobalPool - Add any method, instance or factory to global pool.
void DiagnoseTypeArgsAndProtocols(IdentifierInfo *ProtocolId, SourceLocation ProtocolLoc, IdentifierInfo *TypeArgId, SourceLocation TypeArgLoc, bool SelectProtocolFirst=false)
ObjCProtocolDecl * ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc, Decl *const *ProtoRefNames, unsigned NumProtoRefs, const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, const ParsedAttributesView &AttrList, SkipBodyInfo *SkipBody)
void CodeCompleteObjCImplementationDecl(Scope *S)
void CodeCompleteObjCPropertySetter(Scope *S)
void popObjCTypeParamList(Scope *S, ObjCTypeParamList *typeParamList)
Decl * ActOnStartOfFunctionDef(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists, SkipBodyInfo *SkipBody=nullptr, FnBodyKind BodyKind=FnBodyKind::Other)
Definition: SemaDecl.cpp:15497
void CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver, ArrayRef< const IdentifierInfo * > SelIdents, bool AtArgumentExpression, ObjCInterfaceDecl *Super=nullptr)
StmtResult ActOnNullStmt(SourceLocation SemiLoc, bool HasLeadingEmptyMacro=false)
Definition: SemaStmt.cpp:73
void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, CapturedRegionKind Kind, unsigned NumParams)
Definition: SemaStmt.cpp:4840
void CodeCompleteObjCProtocolReferences(ArrayRef< IdentifierLocPair > Protocols)
ObjCMessageKind getObjCMessageKind(Scope *S, IdentifierInfo *Name, SourceLocation NameLoc, bool IsSuper, bool HasTrailingDot, ParsedType &ReceiverType)
ExprResult ActOnClassMessage(Scope *S, ParsedType Receiver, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
void CodeCompleteObjCAtVisibility(Scope *S)
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)
ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs, ArrayRef< Expr * > Strings)
void CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName, SourceLocation ClassNameLoc)
DeclResult actOnObjCTypeParam(Scope *S, ObjCTypeParamVariance variance, SourceLocation varianceLoc, unsigned index, IdentifierInfo *paramName, SourceLocation paramLoc, SourceLocation colonLoc, ParsedType typeBound)
@ PCC_ObjCInterface
Code completion occurs within an Objective-C interface, protocol, or category.
Definition: Sema.h:12591
@ PCC_ObjCImplementation
Code completion occurs within an Objective-C implementation or category implementation.
Definition: Sema.h:12594
@ PCC_Type
Code completion occurs where only a type is permitted.
Definition: Sema.h:12620
@ PCC_ObjCInstanceVariableList
Code completion occurs within the list of instance variables in an Objective-C interface,...
Definition: Sema.h:12597
StmtResult ActOnCapturedRegionEnd(Stmt *S)
Definition: SemaStmt.cpp:4944
ObjCContainerDecl * getObjCDeclContext() const
Definition: SemaDecl.cpp:20655
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)
Definition: SemaExpr.cpp:4339
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:15994
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)
StmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw, Scope *CurScope)
Definition: SemaStmt.cpp:4365
ExprResult BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr)
BuildObjCBoxedExpr - builds an ObjCBoxedExpr AST node for the '@' prefixed parenthesized expression.
ExprResult ActOnObjCBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind)
ActOnObjCBoolLiteral - Parse {__objc_yes,__objc_no} literals.
Definition: SemaExpr.cpp:21401
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 ActOnDefaultCtorInitializers(Decl *CDtorDecl)
TypeResult ActOnTypeName(Declarator &D)
Definition: SemaType.cpp:6813
ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg, SourceLocation EllipsisLoc)
Invoked when parsing a template argument followed by an ellipsis, which creates a pack expansion.
StmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body)
Definition: SemaStmt.cpp:4316
void CodeCompleteObjCInterfaceCategory(Scope *S, IdentifierInfo *ClassName, SourceLocation ClassNameLoc)
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 ActOnLastBitfield(SourceLocation DeclStart, SmallVectorImpl< Decl * > &AllIvarDecls)
ActOnLastBitfield - This routine handles synthesized bitfields rules for class and class extensions.
Definition: SemaDecl.cpp:19074
ExprResult ActOnInstanceMessage(Scope *S, Expr *Receiver, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
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...
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:290
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: SemaType.cpp:1121
ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc, SourceLocation EncodeLoc, SourceLocation LParenLoc, ParsedType Ty, SourceLocation RParenLoc)
void CodeCompleteObjCMethodDecl(Scope *S, std::optional< bool > IsInstanceMethod, ParsedType ReturnType)
ModuleImportState
An enumeration to represent the transition of states in parsing module fragments and imports.
Definition: Sema.h:7766
@ NotACXX20Module
Not a C++20 TU, or an invalid state was found.
void CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS, bool IsParameter)
void CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver, ArrayRef< const IdentifierInfo * > SelIdents, bool AtArgumentExpression, bool IsSuper=false)
void CodeCompleteOrdinaryName(Scope *S, ParserCompletionContext CompletionContext)
void ActOnFields(Scope *S, SourceLocation RecLoc, Decl *TagDecl, ArrayRef< Decl * > Fields, SourceLocation LBrac, SourceLocation RBrac, const ParsedAttributesView &AttrList)
Definition: SemaDecl.cpp:19320
void CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS)
void CodeCompleteObjCPropertyGetter(Scope *S)
void CodeCompleteObjCSelector(Scope *S, ArrayRef< const IdentifierInfo * > SelIdents)
void CodeCompleteObjCAtStatement(Scope *S)
DeclGroupPtrTy ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc, ArrayRef< IdentifierLocPair > IdentList, const ParsedAttributesView &attrList)
ActOnForwardProtocolDeclaration - Handle @protocol foo;.
void CodeCompleteObjCInterfaceDecl(Scope *S)
ExprResult BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number)
BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the numeric literal expression.
void CodeCompleteObjCImplementationCategory(Scope *S, IdentifierInfo *ClassName, SourceLocation ClassNameLoc)
ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope=nullptr)
Definition: SemaExpr.cpp:3920
StmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc, SourceLocation RParen, Decl *Parm, Stmt *Body)
Definition: SemaStmt.cpp:4305
Decl * ActOnObjCExceptionDecl(Scope *S, Declarator &D)
@ ObjCSuperMessage
The message is sent to 'super'.
Definition: Sema.h:12306
@ ObjCClassMessage
The message is a class message, and the identifier is a type name.
Definition: Sema.h:12311
@ ObjCInstanceMessage
The message is an instance message.
Definition: Sema.h:12308
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...
Definition: SemaDecl.cpp:18959
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
Definition: SemaType.cpp:3222
StmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *SynchExpr, Stmt *SynchBody)
Definition: SemaStmt.cpp:4421
void DiagnoseUnknownTypeName(IdentifierInfo *&II, SourceLocation IILoc, Scope *S, CXXScopeSpec *SS, ParsedType &SuggestedType, bool IsTemplateName=false)
Definition: SemaDecl.cpp:700
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...
ObjCContainerKind getObjCContainerKind() const
ExprResult BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements)
void CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc, ArrayRef< const IdentifierInfo * > SelIdents, bool AtArgumentExpression)
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...
ExprResult ParseObjCSelectorExpression(Selector Sel, SourceLocation AtLoc, SourceLocation SelLoc, SourceLocation LParenLoc, SourceLocation RParenLoc, bool WarnMultipleSelectors)
ParseObjCSelectorExpression - Build selector expression for @selector.
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:1236
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:1813
bool isObjCObjectOrInterfaceType() const
Definition: Type.h:7748
bool acceptsObjCTypeParams() const
Determines if this is an ObjC interface type that may accept type parameters.
Definition: Type.cpp:1706
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:55
@ CPlusPlus11
Definition: LangStandard.h:56
NullabilityKind
Describes the nullability of a particular type.
Definition: Specifiers.h:333
@ 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:133
StmtResult StmtError()
Definition: Ownership.h:265
DeclaratorContext
Definition: DeclSpec.h:1848
@ 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:124
ParamInfo - An array of paraminfo objects is allocated whenever a function declarator is parsed.
Definition: DeclSpec.h:1329
const ParsedAttributesView & getAttrs() const
If there are attributes applied to this declaratorchunk, return them.
Definition: DeclSpec.h:1659
An element in an Objective-C dictionary literal.
Definition: ExprObjC.h:262
IdentifierInfo * Name
Definition: Sema.h:11975
ParsedAttributesView ArgAttrs
ArgAttrs - Attribute list for this argument.
Definition: Sema.h:11983
ObjCDeclSpec DeclSpec
Definition: Sema.h:11980
SourceLocation NameLoc
Definition: Sema.h:11976
bool CheckSameAsPrevious
Definition: Sema.h:359
NamedDecl * Previous
Definition: Sema.h:360