Coverage Report

Created: 2021-12-07 08:24

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