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