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