Coverage Report

Created: 2022-07-16 07:03

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