Coverage Report

Created: 2020-12-01 06:44

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