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