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