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