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