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