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 DesignatorCompletionInfo DesignatorCompletion) { 163 // If this is the old-style GNU extension: 164 // designation ::= identifier ':' 165 // Handle it as a field designator. Otherwise, this must be the start of a 166 // normal expression. 167 if (Tok.is(tok::identifier)) { 168 const IdentifierInfo *FieldName = Tok.getIdentifierInfo(); 169 170 SmallString<256> NewSyntax; 171 llvm::raw_svector_ostream(NewSyntax) << '.' << FieldName->getName() 172 << " = "; 173 174 SourceLocation NameLoc = ConsumeToken(); // Eat the identifier. 175 176 assert(Tok.is(tok::colon) && "MayBeDesignationStart not working properly!"); 177 SourceLocation ColonLoc = ConsumeToken(); 178 179 Diag(NameLoc, diag::ext_gnu_old_style_field_designator) 180 << FixItHint::CreateReplacement(SourceRange(NameLoc, ColonLoc), 181 NewSyntax); 182 183 Designation D; 184 D.AddDesignator(Designator::getField(FieldName, SourceLocation(), NameLoc)); 185 PreferredType.enterDesignatedInitializer( 186 Tok.getLocation(), DesignatorCompletion.PreferredBaseType, D); 187 return Actions.ActOnDesignatedInitializer(D, ColonLoc, true, 188 ParseInitializer()); 189 } 190 191 // Desig - This is initialized when we see our first designator. We may have 192 // an objc message send with no designator, so we don't want to create this 193 // eagerly. 194 Designation Desig; 195 196 // Parse each designator in the designator list until we find an initializer. 197 while (Tok.is(tok::period) || Tok.is(tok::l_square)) { 198 if (Tok.is(tok::period)) { 199 // designator: '.' identifier 200 SourceLocation DotLoc = ConsumeToken(); 201 202 if (Tok.is(tok::code_completion)) { 203 cutOffParsing(); 204 Actions.CodeCompleteDesignator(DesignatorCompletion.PreferredBaseType, 205 DesignatorCompletion.InitExprs, Desig); 206 return ExprError(); 207 } 208 if (Tok.isNot(tok::identifier)) { 209 Diag(Tok.getLocation(), diag::err_expected_field_designator); 210 return ExprError(); 211 } 212 213 Desig.AddDesignator(Designator::getField(Tok.getIdentifierInfo(), DotLoc, 214 Tok.getLocation())); 215 ConsumeToken(); // Eat the identifier. 216 continue; 217 } 218 219 // We must have either an array designator now or an objc message send. 220 assert(Tok.is(tok::l_square) && "Unexpected token!"); 221 222 // Handle the two forms of array designator: 223 // array-designator: '[' constant-expression ']' 224 // array-designator: '[' constant-expression '...' constant-expression ']' 225 // 226 // Also, we have to handle the case where the expression after the 227 // designator an an objc message send: '[' objc-message-expr ']'. 228 // Interesting cases are: 229 // [foo bar] -> objc message send 230 // [foo] -> array designator 231 // [foo ... bar] -> array designator 232 // [4][foo bar] -> obsolete GNU designation with objc message send. 233 // 234 // We do not need to check for an expression starting with [[ here. If it 235 // contains an Objective-C message send, then it is not an ill-formed 236 // attribute. If it is a lambda-expression within an array-designator, then 237 // it will be rejected because a constant-expression cannot begin with a 238 // lambda-expression. 239 InMessageExpressionRAIIObject InMessage(*this, true); 240 241 BalancedDelimiterTracker T(*this, tok::l_square); 242 T.consumeOpen(); 243 SourceLocation StartLoc = T.getOpenLocation(); 244 245 ExprResult Idx; 246 247 // If Objective-C is enabled and this is a typename (class message 248 // send) or send to 'super', parse this as a message send 249 // expression. We handle C++ and C separately, since C++ requires 250 // much more complicated parsing. 251 if (getLangOpts().ObjC && getLangOpts().CPlusPlus) { 252 // Send to 'super'. 253 if (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_super && 254 NextToken().isNot(tok::period) && 255 getCurScope()->isInObjcMethodScope()) { 256 CheckArrayDesignatorSyntax(*this, StartLoc, Desig); 257 return ParseAssignmentExprWithObjCMessageExprStart( 258 StartLoc, ConsumeToken(), nullptr, nullptr); 259 } 260 261 // Parse the receiver, which is either a type or an expression. 262 bool IsExpr; 263 void *TypeOrExpr; 264 if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) { 265 SkipUntil(tok::r_square, StopAtSemi); 266 return ExprError(); 267 } 268 269 // If the receiver was a type, we have a class message; parse 270 // the rest of it. 271 if (!IsExpr) { 272 CheckArrayDesignatorSyntax(*this, StartLoc, Desig); 273 return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, 274 SourceLocation(), 275 ParsedType::getFromOpaquePtr(TypeOrExpr), 276 nullptr); 277 } 278 279 // If the receiver was an expression, we still don't know 280 // whether we have a message send or an array designator; just 281 // adopt the expression for further analysis below. 282 // FIXME: potentially-potentially evaluated expression above? 283 Idx = ExprResult(static_cast<Expr*>(TypeOrExpr)); 284 } else if (getLangOpts().ObjC && Tok.is(tok::identifier)) { 285 IdentifierInfo *II = Tok.getIdentifierInfo(); 286 SourceLocation IILoc = Tok.getLocation(); 287 ParsedType ReceiverType; 288 // Three cases. This is a message send to a type: [type foo] 289 // This is a message send to super: [super foo] 290 // This is a message sent to an expr: [super.bar foo] 291 switch (Actions.getObjCMessageKind( 292 getCurScope(), II, IILoc, II == Ident_super, 293 NextToken().is(tok::period), ReceiverType)) { 294 case Sema::ObjCSuperMessage: 295 CheckArrayDesignatorSyntax(*this, StartLoc, Desig); 296 return ParseAssignmentExprWithObjCMessageExprStart( 297 StartLoc, ConsumeToken(), nullptr, nullptr); 298 299 case Sema::ObjCClassMessage: 300 CheckArrayDesignatorSyntax(*this, StartLoc, Desig); 301 ConsumeToken(); // the identifier 302 if (!ReceiverType) { 303 SkipUntil(tok::r_square, StopAtSemi); 304 return ExprError(); 305 } 306 307 // Parse type arguments and protocol qualifiers. 308 if (Tok.is(tok::less)) { 309 SourceLocation NewEndLoc; 310 TypeResult NewReceiverType 311 = parseObjCTypeArgsAndProtocolQualifiers(IILoc, ReceiverType, 312 /*consumeLastToken=*/true, 313 NewEndLoc); 314 if (!NewReceiverType.isUsable()) { 315 SkipUntil(tok::r_square, StopAtSemi); 316 return ExprError(); 317 } 318 319 ReceiverType = NewReceiverType.get(); 320 } 321 322 return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, 323 SourceLocation(), 324 ReceiverType, 325 nullptr); 326 327 case Sema::ObjCInstanceMessage: 328 // Fall through; we'll just parse the expression and 329 // (possibly) treat this like an Objective-C message send 330 // later. 331 break; 332 } 333 } 334 335 // Parse the index expression, if we haven't already gotten one 336 // above (which can only happen in Objective-C++). 337 // Note that we parse this as an assignment expression, not a constant 338 // expression (allowing *=, =, etc) to handle the objc case. Sema needs 339 // to validate that the expression is a constant. 340 // FIXME: We also need to tell Sema that we're in a 341 // potentially-potentially evaluated context. 342 if (!Idx.get()) { 343 Idx = ParseAssignmentExpression(); 344 if (Idx.isInvalid()) { 345 SkipUntil(tok::r_square, StopAtSemi); 346 return Idx; 347 } 348 } 349 350 // Given an expression, we could either have a designator (if the next 351 // tokens are '...' or ']' or an objc message send. If this is an objc 352 // message send, handle it now. An objc-message send is the start of 353 // an assignment-expression production. 354 if (getLangOpts().ObjC && Tok.isNot(tok::ellipsis) && 355 Tok.isNot(tok::r_square)) { 356 CheckArrayDesignatorSyntax(*this, Tok.getLocation(), Desig); 357 return ParseAssignmentExprWithObjCMessageExprStart( 358 StartLoc, SourceLocation(), nullptr, Idx.get()); 359 } 360 361 // If this is a normal array designator, remember it. 362 if (Tok.isNot(tok::ellipsis)) { 363 Desig.AddDesignator(Designator::getArray(Idx.get(), StartLoc)); 364 } else { 365 // Handle the gnu array range extension. 366 Diag(Tok, diag::ext_gnu_array_range); 367 SourceLocation EllipsisLoc = ConsumeToken(); 368 369 ExprResult RHS(ParseConstantExpression()); 370 if (RHS.isInvalid()) { 371 SkipUntil(tok::r_square, StopAtSemi); 372 return RHS; 373 } 374 Desig.AddDesignator(Designator::getArrayRange(Idx.get(), 375 RHS.get(), 376 StartLoc, EllipsisLoc)); 377 } 378 379 T.consumeClose(); 380 Desig.getDesignator(Desig.getNumDesignators() - 1).setRBracketLoc( 381 T.getCloseLocation()); 382 } 383 384 // Okay, we're done with the designator sequence. We know that there must be 385 // at least one designator, because the only case we can get into this method 386 // without a designator is when we have an objc message send. That case is 387 // handled and returned from above. 388 assert(!Desig.empty() && "Designator is empty?"); 389 390 // Handle a normal designator sequence end, which is an equal. 391 if (Tok.is(tok::equal)) { 392 SourceLocation EqualLoc = ConsumeToken(); 393 PreferredType.enterDesignatedInitializer( 394 Tok.getLocation(), DesignatorCompletion.PreferredBaseType, Desig); 395 return Actions.ActOnDesignatedInitializer(Desig, EqualLoc, false, 396 ParseInitializer()); 397 } 398 399 // Handle a C++20 braced designated initialization, which results in 400 // direct-list-initialization of the aggregate element. We allow this as an 401 // extension from C++11 onwards (when direct-list-initialization was added). 402 if (Tok.is(tok::l_brace) && getLangOpts().CPlusPlus11) { 403 PreferredType.enterDesignatedInitializer( 404 Tok.getLocation(), DesignatorCompletion.PreferredBaseType, Desig); 405 return Actions.ActOnDesignatedInitializer(Desig, SourceLocation(), false, 406 ParseBraceInitializer()); 407 } 408 409 // We read some number of designators and found something that isn't an = or 410 // an initializer. If we have exactly one array designator, this 411 // is the GNU 'designation: array-designator' extension. Otherwise, it is a 412 // parse error. 413 if (Desig.getNumDesignators() == 1 && 414 (Desig.getDesignator(0).isArrayDesignator() || 415 Desig.getDesignator(0).isArrayRangeDesignator())) { 416 Diag(Tok, diag::ext_gnu_missing_equal_designator) 417 << FixItHint::CreateInsertion(Tok.getLocation(), "= "); 418 return Actions.ActOnDesignatedInitializer(Desig, Tok.getLocation(), 419 true, ParseInitializer()); 420 } 421 422 Diag(Tok, diag::err_expected_equal_designator); 423 return ExprError(); 424 } 425 426 /// ParseBraceInitializer - Called when parsing an initializer that has a 427 /// leading open brace. 428 /// 429 /// initializer: [C99 6.7.8] 430 /// '{' initializer-list '}' 431 /// '{' initializer-list ',' '}' 432 /// [GNU] '{' '}' 433 /// 434 /// initializer-list: 435 /// designation[opt] initializer ...[opt] 436 /// initializer-list ',' designation[opt] initializer ...[opt] 437 /// 438 ExprResult Parser::ParseBraceInitializer() { 439 InMessageExpressionRAIIObject InMessage(*this, false); 440 441 BalancedDelimiterTracker T(*this, tok::l_brace); 442 T.consumeOpen(); 443 SourceLocation LBraceLoc = T.getOpenLocation(); 444 445 /// InitExprs - This is the actual list of expressions contained in the 446 /// initializer. 447 ExprVector InitExprs; 448 449 if (Tok.is(tok::r_brace)) { 450 // Empty initializers are a C++ feature and a GNU extension to C. 451 if (!getLangOpts().CPlusPlus) 452 Diag(LBraceLoc, diag::ext_gnu_empty_initializer); 453 // Match the '}'. 454 return Actions.ActOnInitList(LBraceLoc, None, ConsumeBrace()); 455 } 456 457 // Enter an appropriate expression evaluation context for an initializer list. 458 EnterExpressionEvaluationContext EnterContext( 459 Actions, EnterExpressionEvaluationContext::InitList); 460 461 bool InitExprsOk = true; 462 QualType LikelyType = PreferredType.get(T.getOpenLocation()); 463 DesignatorCompletionInfo DesignatorCompletion{InitExprs, LikelyType}; 464 bool CalledSignatureHelp = false; 465 auto RunSignatureHelp = [&] { 466 QualType PreferredType; 467 if (!LikelyType.isNull()) 468 PreferredType = Actions.ProduceConstructorSignatureHelp( 469 LikelyType->getCanonicalTypeInternal(), T.getOpenLocation(), 470 InitExprs, T.getOpenLocation(), /*Braced=*/true); 471 CalledSignatureHelp = true; 472 return PreferredType; 473 }; 474 475 while (true) { 476 PreferredType.enterFunctionArgument(Tok.getLocation(), RunSignatureHelp); 477 478 // Handle Microsoft __if_exists/if_not_exists if necessary. 479 if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) || 480 Tok.is(tok::kw___if_not_exists))) { 481 if (ParseMicrosoftIfExistsBraceInitializer(InitExprs, InitExprsOk)) { 482 if (Tok.isNot(tok::comma)) break; 483 ConsumeToken(); 484 } 485 if (Tok.is(tok::r_brace)) break; 486 continue; 487 } 488 489 // Parse: designation[opt] initializer 490 491 // If we know that this cannot be a designation, just parse the nested 492 // initializer directly. 493 ExprResult SubElt; 494 if (MayBeDesignationStart()) 495 SubElt = ParseInitializerWithPotentialDesignator(DesignatorCompletion); 496 else 497 SubElt = ParseInitializer(); 498 499 if (Tok.is(tok::ellipsis)) 500 SubElt = Actions.ActOnPackExpansion(SubElt.get(), ConsumeToken()); 501 502 SubElt = Actions.CorrectDelayedTyposInExpr(SubElt.get()); 503 504 // If we couldn't parse the subelement, bail out. 505 if (SubElt.isUsable()) { 506 InitExprs.push_back(SubElt.get()); 507 } else { 508 InitExprsOk = false; 509 510 // We have two ways to try to recover from this error: if the code looks 511 // grammatically ok (i.e. we have a comma coming up) try to continue 512 // parsing the rest of the initializer. This allows us to emit 513 // diagnostics for later elements that we find. If we don't see a comma, 514 // assume there is a parse error, and just skip to recover. 515 // FIXME: This comment doesn't sound right. If there is a r_brace 516 // immediately, it can't be an error, since there is no other way of 517 // leaving this loop except through this if. 518 if (Tok.isNot(tok::comma)) { 519 SkipUntil(tok::r_brace, StopBeforeMatch); 520 break; 521 } 522 } 523 524 // If we don't have a comma continued list, we're done. 525 if (Tok.isNot(tok::comma)) break; 526 527 // TODO: save comma locations if some client cares. 528 ConsumeToken(); 529 530 // Handle trailing comma. 531 if (Tok.is(tok::r_brace)) break; 532 } 533 534 bool closed = !T.consumeClose(); 535 536 if (InitExprsOk && closed) 537 return Actions.ActOnInitList(LBraceLoc, InitExprs, 538 T.getCloseLocation()); 539 540 return ExprError(); // an error occurred. 541 } 542 543 544 // Return true if a comma (or closing brace) is necessary after the 545 // __if_exists/if_not_exists statement. 546 bool Parser::ParseMicrosoftIfExistsBraceInitializer(ExprVector &InitExprs, 547 bool &InitExprsOk) { 548 bool trailingComma = false; 549 IfExistsCondition Result; 550 if (ParseMicrosoftIfExistsCondition(Result)) 551 return false; 552 553 BalancedDelimiterTracker Braces(*this, tok::l_brace); 554 if (Braces.consumeOpen()) { 555 Diag(Tok, diag::err_expected) << tok::l_brace; 556 return false; 557 } 558 559 switch (Result.Behavior) { 560 case IEB_Parse: 561 // Parse the declarations below. 562 break; 563 564 case IEB_Dependent: 565 Diag(Result.KeywordLoc, diag::warn_microsoft_dependent_exists) 566 << Result.IsIfExists; 567 // Fall through to skip. 568 LLVM_FALLTHROUGH; 569 570 case IEB_Skip: 571 Braces.skipToEnd(); 572 return false; 573 } 574 575 DesignatorCompletionInfo DesignatorCompletion{ 576 InitExprs, 577 PreferredType.get(Braces.getOpenLocation()), 578 }; 579 while (!isEofOrEom()) { 580 trailingComma = false; 581 // If we know that this cannot be a designation, just parse the nested 582 // initializer directly. 583 ExprResult SubElt; 584 if (MayBeDesignationStart()) 585 SubElt = ParseInitializerWithPotentialDesignator(DesignatorCompletion); 586 else 587 SubElt = ParseInitializer(); 588 589 if (Tok.is(tok::ellipsis)) 590 SubElt = Actions.ActOnPackExpansion(SubElt.get(), ConsumeToken()); 591 592 // If we couldn't parse the subelement, bail out. 593 if (!SubElt.isInvalid()) 594 InitExprs.push_back(SubElt.get()); 595 else 596 InitExprsOk = false; 597 598 if (Tok.is(tok::comma)) { 599 ConsumeToken(); 600 trailingComma = true; 601 } 602 603 if (Tok.is(tok::r_brace)) 604 break; 605 } 606 607 Braces.consumeClose(); 608 609 return !trailingComma; 610 } 611