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