Coverage Report

Created: 2019-07-24 05:18

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