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