Coverage Report

Created: 2020-02-15 09:57

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Parse/ParseInit.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- ParseInit.cpp - Initializer 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 initializer parsing as specified by C99 6.7.8.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "clang/Basic/TokenKinds.h"
14
#include "clang/Parse/ParseDiagnostic.h"
15
#include "clang/Parse/Parser.h"
16
#include "clang/Parse/RAIIObjectsForParser.h"
17
#include "clang/Sema/Designator.h"
18
#include "clang/Sema/Ownership.h"
19
#include "clang/Sema/Scope.h"
20
#include "llvm/ADT/STLExtras.h"
21
#include "llvm/ADT/SmallString.h"
22
using namespace clang;
23
24
25
/// MayBeDesignationStart - Return true if the current token might be the start
26
/// of a designator.  If we can tell it is impossible that it is a designator,
27
/// return false.
28
333k
bool Parser::MayBeDesignationStart() {
29
333k
  switch (Tok.getKind()) {
30
132k
  default:
31
132k
    return false;
32
0
33
1.34k
  case tok::period:      // designator: '.' identifier
34
1.34k
    return true;
35
0
36
349
  case tok::l_square: {  // designator: array-designator
37
349
    if (!PP.getLangOpts().CPlusPlus11)
38
227
      return true;
39
122
40
122
    // C++11 lambda expressions and C99 designators can be ambiguous all the
41
122
    // way through the closing ']' and to the next character. Handle the easy
42
122
    // cases here, and fall back to tentative parsing if those fail.
43
122
    switch (PP.LookAhead(0).getKind()) {
44
18
    case tok::equal:
45
18
    case tok::ellipsis:
46
18
    case tok::r_square:
47
18
      // Definitely starts a lambda expression.
48
18
      return false;
49
18
50
54
    case tok::amp:
51
54
    case tok::kw_this:
52
54
    case tok::star:
53
54
    case tok::identifier:
54
54
      // We have to do additional analysis, because these could be the
55
54
      // start of a constant expression or a lambda capture list.
56
54
      break;
57
54
58
54
    default:
59
50
      // Anything not mentioned above cannot occur following a '[' in a
60
50
      // lambda expression.
61
50
      return true;
62
54
    }
63
54
64
54
    // Handle the complicated case below.
65
54
    break;
66
54
  }
67
199k
  case tok::identifier:  // designation: identifier ':'
68
199k
    return PP.LookAhead(0).is(tok::colon);
69
54
  }
70
54
71
54
  // Parse up to (at most) the token after the closing ']' to determine
72
54
  // whether this is a C99 designator or a lambda.
73
54
  RevertingTentativeParsingAction Tentative(*this);
74
54
75
54
  LambdaIntroducer Intro;
76
54
  LambdaIntroducerTentativeParse ParseResult;
77
54
  if (ParseLambdaIntroducer(Intro, &ParseResult)) {
78
0
    // Hit and diagnosed an error in a lambda.
79
0
    // FIXME: Tell the caller this happened so they can recover.
80
0
    return true;
81
0
  }
82
54
83
54
  switch (ParseResult) {
84
37
  case LambdaIntroducerTentativeParse::Success:
85
37
  case LambdaIntroducerTentativeParse::Incomplete:
86
37
    // Might be a lambda-expression. Keep looking.
87
37
    // FIXME: If our tentative parse was not incomplete, parse the lambda from
88
37
    // here rather than throwing away then reparsing the LambdaIntroducer.
89
37
    break;
90
37
91
37
  case LambdaIntroducerTentativeParse::MessageSend:
92
17
  case LambdaIntroducerTentativeParse::Invalid:
93
17
    // Can't be a lambda-expression. Treat it as a designator.
94
17
    // FIXME: Should we disambiguate against a message-send?
95
17
    return true;
96
37
  }
97
37
98
37
  // Once we hit the closing square bracket, we look at the next
99
37
  // token. If it's an '=', this is a designator. Otherwise, it's a
100
37
  // lambda expression. This decision favors lambdas over the older
101
37
  // GNU designator syntax, which allows one to omit the '=', but is
102
37
  // consistent with GCC.
103
37
  return Tok.is(tok::equal);
104
37
}
105
106
static void CheckArrayDesignatorSyntax(Parser &P, SourceLocation Loc,
107
68
                                       Designation &Desig) {
108
68
  // If we have exactly one array designator, this used the GNU
109
68
  // 'designation: array-designator' extension, otherwise there should be no
110
68
  // designators at all!
111
68
  if (Desig.getNumDesignators() == 1 &&
112
68
      
(12
Desig.getDesignator(0).isArrayDesignator()12
||
113
12
       
Desig.getDesignator(0).isArrayRangeDesignator()4
))
114
8
    P.Diag(Loc, diag::ext_gnu_missing_equal_designator);
115
60
  else if (Desig.getNumDesignators() > 0)
116
4
    P.Diag(Loc, diag::err_expected_equal_designator);
117
68
}
118
119
/// ParseInitializerWithPotentialDesignator - Parse the 'initializer' production
120
/// checking to see if the token stream starts with a designator.
121
///
122
/// C99:
123
///
124
///       designation:
125
///         designator-list '='
126
/// [GNU]   array-designator
127
/// [GNU]   identifier ':'
128
///
129
///       designator-list:
130
///         designator
131
///         designator-list designator
132
///
133
///       designator:
134
///         array-designator
135
///         '.' identifier
136
///
137
///       array-designator:
138
///         '[' constant-expression ']'
139
/// [GNU]   '[' constant-expression '...' constant-expression ']'
140
///
141
/// C++20:
142
///
143
///       designated-initializer-list:
144
///         designated-initializer-clause
145
///         designated-initializer-list ',' designated-initializer-clause
146
///
147
///       designated-initializer-clause:
148
///         designator brace-or-equal-initializer
149
///
150
///       designator:
151
///         '.' identifier
152
///
153
/// We allow the C99 syntax extensions in C++20, but do not allow the C++20
154
/// extension (a braced-init-list after the designator with no '=') in C99.
155
///
156
/// NOTE: [OBC] allows '[ objc-receiver objc-message-args ]' as an
157
/// initializer (because it is an expression).  We need to consider this case
158
/// when parsing array designators.
159
///
160
/// \p CodeCompleteCB is called with Designation parsed so far.
161
ExprResult Parser::ParseInitializerWithPotentialDesignator(
162
1.66k
    llvm::function_ref<void(const Designation &)> CodeCompleteCB) {
163
1.66k
164
1.66k
  // If this is the old-style GNU extension:
165
1.66k
  //   designation ::= identifier ':'
166
1.66k
  // Handle it as a field designator.  Otherwise, this must be the start of a
167
1.66k
  // normal expression.
168
1.66k
  if (Tok.is(tok::identifier)) {
169
9
    const IdentifierInfo *FieldName = Tok.getIdentifierInfo();
170
9
171
9
    SmallString<256> NewSyntax;
172
9
    llvm::raw_svector_ostream(NewSyntax) << '.' << FieldName->getName()
173
9
                                         << " = ";
174
9
175
9
    SourceLocation NameLoc = ConsumeToken(); // Eat the identifier.
176
9
177
9
    assert(Tok.is(tok::colon) && "MayBeDesignationStart not working properly!");
178
9
    SourceLocation ColonLoc = ConsumeToken();
179
9
180
9
    Diag(NameLoc, diag::ext_gnu_old_style_field_designator)
181
9
      << FixItHint::CreateReplacement(SourceRange(NameLoc, ColonLoc),
182
9
                                      NewSyntax);
183
9
184
9
    Designation D;
185
9
    D.AddDesignator(Designator::getField(FieldName, SourceLocation(), NameLoc));
186
9
    return Actions.ActOnDesignatedInitializer(D, ColonLoc, true,
187
9
                                              ParseInitializer());
188
9
  }
189
1.66k
190
1.66k
  // Desig - This is initialized when we see our first designator.  We may have
191
1.66k
  // an objc message send with no designator, so we don't want to create this
192
1.66k
  // eagerly.
193
1.66k
  Designation Desig;
194
1.66k
195
1.66k
  // Parse each designator in the designator list until we find an initializer.
196
3.54k
  while (Tok.is(tok::period) || 
Tok.is(tok::l_square)1.97k
) {
197
1.96k
    if (Tok.is(tok::period)) {
198
1.57k
      // designator: '.' identifier
199
1.57k
      SourceLocation DotLoc = ConsumeToken();
200
1.57k
201
1.57k
      if (Tok.is(tok::code_completion)) {
202
9
        CodeCompleteCB(Desig);
203
9
        cutOffParsing();
204
9
        return ExprError();
205
9
      }
206
1.56k
      if (Tok.isNot(tok::identifier)) {
207
0
        Diag(Tok.getLocation(), diag::err_expected_field_designator);
208
0
        return ExprError();
209
0
      }
210
1.56k
211
1.56k
      Desig.AddDesignator(Designator::getField(Tok.getIdentifierInfo(), DotLoc,
212
1.56k
                                               Tok.getLocation()));
213
1.56k
      ConsumeToken(); // Eat the identifier.
214
1.56k
      continue;
215
1.56k
    }
216
393
217
393
    // We must have either an array designator now or an objc message send.
218
393
    assert(Tok.is(tok::l_square) && "Unexpected token!");
219
393
220
393
    // Handle the two forms of array designator:
221
393
    //   array-designator: '[' constant-expression ']'
222
393
    //   array-designator: '[' constant-expression '...' constant-expression ']'
223
393
    //
224
393
    // Also, we have to handle the case where the expression after the
225
393
    // designator an an objc message send: '[' objc-message-expr ']'.
226
393
    // Interesting cases are:
227
393
    //   [foo bar]         -> objc message send
228
393
    //   [foo]             -> array designator
229
393
    //   [foo ... bar]     -> array designator
230
393
    //   [4][foo bar]      -> obsolete GNU designation with objc message send.
231
393
    //
232
393
    // We do not need to check for an expression starting with [[ here. If it
233
393
    // contains an Objective-C message send, then it is not an ill-formed
234
393
    // attribute. If it is a lambda-expression within an array-designator, then
235
393
    // it will be rejected because a constant-expression cannot begin with a
236
393
    // lambda-expression.
237
393
    InMessageExpressionRAIIObject InMessage(*this, true);
238
393
239
393
    BalancedDelimiterTracker T(*this, tok::l_square);
240
393
    T.consumeOpen();
241
393
    SourceLocation StartLoc = T.getOpenLocation();
242
393
243
393
    ExprResult Idx;
244
393
245
393
    // If Objective-C is enabled and this is a typename (class message
246
393
    // send) or send to 'super', parse this as a message send
247
393
    // expression.  We handle C++ and C separately, since C++ requires
248
393
    // much more complicated parsing.
249
393
    if  (getLangOpts().ObjC && 
getLangOpts().CPlusPlus96
) {
250
58
      // Send to 'super'.
251
58
      if (Tok.is(tok::identifier) && 
Tok.getIdentifierInfo() == Ident_super30
&&
252
58
          
NextToken().isNot(tok::period)3
&&
253
58
          
getCurScope()->isInObjcMethodScope()3
) {
254
3
        CheckArrayDesignatorSyntax(*this, StartLoc, Desig);
255
3
        return ParseAssignmentExprWithObjCMessageExprStart(
256
3
            StartLoc, ConsumeToken(), nullptr, nullptr);
257
3
      }
258
55
259
55
      // Parse the receiver, which is either a type or an expression.
260
55
      bool IsExpr;
261
55
      void *TypeOrExpr;
262
55
      if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) {
263
0
        SkipUntil(tok::r_square, StopAtSemi);
264
0
        return ExprError();
265
0
      }
266
55
267
55
      // If the receiver was a type, we have a class message; parse
268
55
      // the rest of it.
269
55
      if (!IsExpr) {
270
20
        CheckArrayDesignatorSyntax(*this, StartLoc, Desig);
271
20
        return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
272
20
                                                           SourceLocation(),
273
20
                                   ParsedType::getFromOpaquePtr(TypeOrExpr),
274
20
                                                           nullptr);
275
20
      }
276
35
277
35
      // If the receiver was an expression, we still don't know
278
35
      // whether we have a message send or an array designator; just
279
35
      // adopt the expression for further analysis below.
280
35
      // FIXME: potentially-potentially evaluated expression above?
281
35
      Idx = ExprResult(static_cast<Expr*>(TypeOrExpr));
282
335
    } else if (getLangOpts().ObjC && 
Tok.is(tok::identifier)38
) {
283
10
      IdentifierInfo *II = Tok.getIdentifierInfo();
284
10
      SourceLocation IILoc = Tok.getLocation();
285
10
      ParsedType ReceiverType;
286
10
      // Three cases. This is a message send to a type: [type foo]
287
10
      // This is a message send to super:  [super foo]
288
10
      // This is a message sent to an expr:  [super.bar foo]
289
10
      switch (Actions.getObjCMessageKind(
290
10
          getCurScope(), II, IILoc, II == Ident_super,
291
10
          NextToken().is(tok::period), ReceiverType)) {
292
1
      case Sema::ObjCSuperMessage:
293
1
        CheckArrayDesignatorSyntax(*this, StartLoc, Desig);
294
1
        return ParseAssignmentExprWithObjCMessageExprStart(
295
1
            StartLoc, ConsumeToken(), nullptr, nullptr);
296
0
297
3
      case Sema::ObjCClassMessage:
298
3
        CheckArrayDesignatorSyntax(*this, StartLoc, Desig);
299
3
        ConsumeToken(); // the identifier
300
3
        if (!ReceiverType) {
301
0
          SkipUntil(tok::r_square, StopAtSemi);
302
0
          return ExprError();
303
0
        }
304
3
305
3
        // Parse type arguments and protocol qualifiers.
306
3
        if (Tok.is(tok::less)) {
307
0
          SourceLocation NewEndLoc;
308
0
          TypeResult NewReceiverType
309
0
            = parseObjCTypeArgsAndProtocolQualifiers(IILoc, ReceiverType,
310
0
                                                     /*consumeLastToken=*/true,
311
0
                                                     NewEndLoc);
312
0
          if (!NewReceiverType.isUsable()) {
313
0
            SkipUntil(tok::r_square, StopAtSemi);
314
0
            return ExprError();
315
0
          }
316
0
317
0
          ReceiverType = NewReceiverType.get();
318
0
        }
319
3
320
3
        return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
321
3
                                                           SourceLocation(),
322
3
                                                           ReceiverType,
323
3
                                                           nullptr);
324
3
325
6
      case Sema::ObjCInstanceMessage:
326
6
        // Fall through; we'll just parse the expression and
327
6
        // (possibly) treat this like an Objective-C message send
328
6
        // later.
329
6
        break;
330
366
      }
331
366
    }
332
366
333
366
    // Parse the index expression, if we haven't already gotten one
334
366
    // above (which can only happen in Objective-C++).
335
366
    // Note that we parse this as an assignment expression, not a constant
336
366
    // expression (allowing *=, =, etc) to handle the objc case.  Sema needs
337
366
    // to validate that the expression is a constant.
338
366
    // FIXME: We also need to tell Sema that we're in a
339
366
    // potentially-potentially evaluated context.
340
366
    if (!Idx.get()) {
341
331
      Idx = ParseAssignmentExpression();
342
331
      if (Idx.isInvalid()) {
343
0
        SkipUntil(tok::r_square, StopAtSemi);
344
0
        return Idx;
345
0
      }
346
366
    }
347
366
348
366
    // Given an expression, we could either have a designator (if the next
349
366
    // tokens are '...' or ']' or an objc message send.  If this is an objc
350
366
    // message send, handle it now.  An objc-message send is the start of
351
366
    // an assignment-expression production.
352
366
    if (getLangOpts().ObjC && 
Tok.isNot(tok::ellipsis)69
&&
353
366
        
Tok.isNot(tok::r_square)69
) {
354
41
      CheckArrayDesignatorSyntax(*this, Tok.getLocation(), Desig);
355
41
      return ParseAssignmentExprWithObjCMessageExprStart(
356
41
          StartLoc, SourceLocation(), nullptr, Idx.get());
357
41
    }
358
325
359
325
    // If this is a normal array designator, remember it.
360
325
    if (Tok.isNot(tok::ellipsis)) {
361
305
      Desig.AddDesignator(Designator::getArray(Idx.get(), StartLoc));
362
305
    } else {
363
20
      // Handle the gnu array range extension.
364
20
      Diag(Tok, diag::ext_gnu_array_range);
365
20
      SourceLocation EllipsisLoc = ConsumeToken();
366
20
367
20
      ExprResult RHS(ParseConstantExpression());
368
20
      if (RHS.isInvalid()) {
369
0
        SkipUntil(tok::r_square, StopAtSemi);
370
0
        return RHS;
371
0
      }
372
20
      Desig.AddDesignator(Designator::getArrayRange(Idx.get(),
373
20
                                                    RHS.get(),
374
20
                                                    StartLoc, EllipsisLoc));
375
20
    }
376
325
377
325
    T.consumeClose();
378
325
    Desig.getDesignator(Desig.getNumDesignators() - 1).setRBracketLoc(
379
325
                                                        T.getCloseLocation());
380
325
  }
381
1.66k
382
1.66k
  // Okay, we're done with the designator sequence.  We know that there must be
383
1.66k
  // at least one designator, because the only case we can get into this method
384
1.66k
  // without a designator is when we have an objc message send.  That case is
385
1.66k
  // handled and returned from above.
386
1.66k
  assert(!Desig.empty() && "Designator is empty?");
387
1.58k
388
1.58k
  // Handle a normal designator sequence end, which is an equal.
389
1.58k
  if (Tok.is(tok::equal)) {
390
1.56k
    SourceLocation EqualLoc = ConsumeToken();
391
1.56k
    return Actions.ActOnDesignatedInitializer(Desig, EqualLoc, false,
392
1.56k
                                              ParseInitializer());
393
1.56k
  }
394
14
395
14
  // Handle a C++20 braced designated initialization, which results in
396
14
  // direct-list-initialization of the aggregate element. We allow this as an
397
14
  // extension from C++11 onwards (when direct-list-initialization was added).
398
14
  if (Tok.is(tok::l_brace) && 
getLangOpts().CPlusPlus116
) {
399
4
    return Actions.ActOnDesignatedInitializer(Desig, SourceLocation(), false,
400
4
                                              ParseBraceInitializer());
401
4
  }
402
10
403
10
  // We read some number of designators and found something that isn't an = or
404
10
  // an initializer.  If we have exactly one array designator, this
405
10
  // is the GNU 'designation: array-designator' extension.  Otherwise, it is a
406
10
  // parse error.
407
10
  if (Desig.getNumDesignators() == 1 &&
408
10
      
(9
Desig.getDesignator(0).isArrayDesignator()9
||
409
9
       
Desig.getDesignator(0).isArrayRangeDesignator()2
)) {
410
7
    Diag(Tok, diag::ext_gnu_missing_equal_designator)
411
7
      << FixItHint::CreateInsertion(Tok.getLocation(), "= ");
412
7
    return Actions.ActOnDesignatedInitializer(Desig, Tok.getLocation(),
413
7
                                              true, ParseInitializer());
414
7
  }
415
3
416
3
  Diag(Tok, diag::err_expected_equal_designator);
417
3
  return ExprError();
418
3
}
419
420
/// ParseBraceInitializer - Called when parsing an initializer that has a
421
/// leading open brace.
422
///
423
///       initializer: [C99 6.7.8]
424
///         '{' initializer-list '}'
425
///         '{' initializer-list ',' '}'
426
/// [GNU]   '{' '}'
427
///
428
///       initializer-list:
429
///         designation[opt] initializer ...[opt]
430
///         initializer-list ',' designation[opt] initializer ...[opt]
431
///
432
81.6k
ExprResult Parser::ParseBraceInitializer() {
433
81.6k
  InMessageExpressionRAIIObject InMessage(*this, false);
434
81.6k
435
81.6k
  BalancedDelimiterTracker T(*this, tok::l_brace);
436
81.6k
  T.consumeOpen();
437
81.6k
  SourceLocation LBraceLoc = T.getOpenLocation();
438
81.6k
439
81.6k
  /// InitExprs - This is the actual list of expressions contained in the
440
81.6k
  /// initializer.
441
81.6k
  ExprVector InitExprs;
442
81.6k
443
81.6k
  if (Tok.is(tok::r_brace)) {
444
11.0k
    // Empty initializers are a C++ feature and a GNU extension to C.
445
11.0k
    if (!getLangOpts().CPlusPlus)
446
647
      Diag(LBraceLoc, diag::ext_gnu_empty_initializer);
447
11.0k
    // Match the '}'.
448
11.0k
    return Actions.ActOnInitList(LBraceLoc, None, ConsumeBrace());
449
11.0k
  }
450
70.5k
451
70.5k
  // Enter an appropriate expression evaluation context for an initializer list.
452
70.5k
  EnterExpressionEvaluationContext EnterContext(
453
70.5k
      Actions, EnterExpressionEvaluationContext::InitList);
454
70.5k
455
70.5k
  bool InitExprsOk = true;
456
70.5k
  auto CodeCompleteDesignation = [&](const Designation &D) {
457
9
    Actions.CodeCompleteDesignator(PreferredType.get(T.getOpenLocation()),
458
9
                                   InitExprs, D);
459
9
  };
460
70.5k
461
333k
  while (1) {
462
333k
    // Handle Microsoft __if_exists/if_not_exists if necessary.
463
333k
    if (getLangOpts().MicrosoftExt && 
(8.70k
Tok.is(tok::kw___if_exists)8.70k
||
464
8.70k
        
Tok.is(tok::kw___if_not_exists)8.69k
)) {
465
9
      if (ParseMicrosoftIfExistsBraceInitializer(InitExprs, InitExprsOk)) {
466
0
        if (Tok.isNot(tok::comma)) break;
467
0
        ConsumeToken();
468
0
      }
469
9
      if (Tok.is(tok::r_brace)) 
break0
;
470
9
      continue;
471
9
    }
472
333k
473
333k
    // Parse: designation[opt] initializer
474
333k
475
333k
    // If we know that this cannot be a designation, just parse the nested
476
333k
    // initializer directly.
477
333k
    ExprResult SubElt;
478
333k
    if (MayBeDesignationStart())
479
1.66k
      SubElt = ParseInitializerWithPotentialDesignator(CodeCompleteDesignation);
480
332k
    else
481
332k
      SubElt = ParseInitializer();
482
333k
483
333k
    if (Tok.is(tok::ellipsis))
484
93
      SubElt = Actions.ActOnPackExpansion(SubElt.get(), ConsumeToken());
485
333k
486
333k
    SubElt = Actions.CorrectDelayedTyposInExpr(SubElt.get());
487
333k
488
333k
    // If we couldn't parse the subelement, bail out.
489
333k
    if (SubElt.isUsable()) {
490
333k
      InitExprs.push_back(SubElt.get());
491
333k
    } else {
492
45
      InitExprsOk = false;
493
45
494
45
      // We have two ways to try to recover from this error: if the code looks
495
45
      // grammatically ok (i.e. we have a comma coming up) try to continue
496
45
      // parsing the rest of the initializer.  This allows us to emit
497
45
      // diagnostics for later elements that we find.  If we don't see a comma,
498
45
      // assume there is a parse error, and just skip to recover.
499
45
      // FIXME: This comment doesn't sound right. If there is a r_brace
500
45
      // immediately, it can't be an error, since there is no other way of
501
45
      // leaving this loop except through this if.
502
45
      if (Tok.isNot(tok::comma)) {
503
40
        SkipUntil(tok::r_brace, StopBeforeMatch);
504
40
        break;
505
40
      }
506
333k
    }
507
333k
508
333k
    // If we don't have a comma continued list, we're done.
509
333k
    if (Tok.isNot(tok::comma)) 
break69.9k
;
510
263k
511
263k
    // TODO: save comma locations if some client cares.
512
263k
    ConsumeToken();
513
263k
514
263k
    // Handle trailing comma.
515
263k
    if (Tok.is(tok::r_brace)) 
break645
;
516
263k
  }
517
70.5k
518
70.5k
  bool closed = !T.consumeClose();
519
70.5k
520
70.5k
  if (InitExprsOk && 
closed70.5k
)
521
70.5k
    return Actions.ActOnInitList(LBraceLoc, InitExprs,
522
70.5k
                                 T.getCloseLocation());
523
42
524
42
  return ExprError(); // an error occurred.
525
42
}
526
527
528
// Return true if a comma (or closing brace) is necessary after the
529
// __if_exists/if_not_exists statement.
530
bool Parser::ParseMicrosoftIfExistsBraceInitializer(ExprVector &InitExprs,
531
9
                                                    bool &InitExprsOk) {
532
9
  bool trailingComma = false;
533
9
  IfExistsCondition Result;
534
9
  if (ParseMicrosoftIfExistsCondition(Result))
535
0
    return false;
536
9
537
9
  BalancedDelimiterTracker Braces(*this, tok::l_brace);
538
9
  if (Braces.consumeOpen()) {
539
0
    Diag(Tok, diag::err_expected) << tok::l_brace;
540
0
    return false;
541
0
  }
542
9
543
9
  switch (Result.Behavior) {
544
4
  case IEB_Parse:
545
4
    // Parse the declarations below.
546
4
    break;
547
0
548
1
  case IEB_Dependent:
549
1
    Diag(Result.KeywordLoc, diag::warn_microsoft_dependent_exists)
550
1
      << Result.IsIfExists;
551
1
    // Fall through to skip.
552
1
    LLVM_FALLTHROUGH;
553
1
554
5
  case IEB_Skip:
555
5
    Braces.skipToEnd();
556
5
    return false;
557
4
  }
558
4
559
4
  auto CodeCompleteDesignation = [&](const Designation &D) {
560
0
    Actions.CodeCompleteDesignator(PreferredType.get(Braces.getOpenLocation()),
561
0
                                   InitExprs, D);
562
0
  };
563
4
  while (!isEofOrEom()) {
564
4
    trailingComma = false;
565
4
    // If we know that this cannot be a designation, just parse the nested
566
4
    // initializer directly.
567
4
    ExprResult SubElt;
568
4
    if (MayBeDesignationStart())
569
0
      SubElt = ParseInitializerWithPotentialDesignator(CodeCompleteDesignation);
570
4
    else
571
4
      SubElt = ParseInitializer();
572
4
573
4
    if (Tok.is(tok::ellipsis))
574
0
      SubElt = Actions.ActOnPackExpansion(SubElt.get(), ConsumeToken());
575
4
576
4
    // If we couldn't parse the subelement, bail out.
577
4
    if (!SubElt.isInvalid())
578
4
      InitExprs.push_back(SubElt.get());
579
0
    else
580
0
      InitExprsOk = false;
581
4
582
4
    if (Tok.is(tok::comma)) {
583
4
      ConsumeToken();
584
4
      trailingComma = true;
585
4
    }
586
4
587
4
    if (Tok.is(tok::r_brace))
588
4
      break;
589
4
  }
590
4
591
4
  Braces.consumeClose();
592
4
593
4
  return !trailingComma;
594
4
}