Coverage Report

Created: 2022-05-14 11:35

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