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