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