Coverage Report

Created: 2020-02-25 14:32

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