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 } 595