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