ParseExprCXX.cpp revision 1ab3b96de160e4fbffec2a776e284a48a3bb543d
1//===--- ParseExprCXX.cpp - C++ Expression 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 the Expression parsing implementation for C++. 11// 12//===----------------------------------------------------------------------===// 13 14#include "clang/Basic/Diagnostic.h" 15#include "clang/Parse/Parser.h" 16#include "clang/Parse/DeclSpec.h" 17using namespace clang; 18 19/// ParseCXXScopeSpecifier - Parse global scope or nested-name-specifier. 20/// 21/// '::'[opt] nested-name-specifier 22/// '::' 23/// 24/// nested-name-specifier: 25/// type-name '::' 26/// namespace-name '::' 27/// nested-name-specifier identifier '::' 28/// nested-name-specifier 'template'[opt] simple-template-id '::' [TODO] 29/// 30void Parser::ParseCXXScopeSpecifier(CXXScopeSpec &SS) { 31 assert(isTokenCXXScopeSpecifier() && "Not scope specifier!"); 32 33 if (Tok.is(tok::annot_cxxscope)) { 34 SS.setScopeRep(Tok.getAnnotationValue()); 35 SS.setRange(Tok.getAnnotationRange()); 36 ConsumeToken(); 37 return; 38 } 39 40 SS.setBeginLoc(Tok.getLocation()); 41 42 // '::' 43 44 if (Tok.is(tok::coloncolon)) { 45 // Global scope. 46 SourceLocation CCLoc = ConsumeToken(); 47 SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc)); 48 SS.setEndLoc(CCLoc); 49 } 50 51 // nested-name-specifier: 52 // type-name '::' 53 // namespace-name '::' 54 // nested-name-specifier identifier '::' 55 // nested-name-specifier 'template'[opt] simple-template-id '::' [TODO] 56 57 while (Tok.is(tok::identifier) && NextToken().is(tok::coloncolon)) { 58 IdentifierInfo *II = Tok.getIdentifierInfo(); 59 SourceLocation IdLoc = ConsumeToken(); 60 assert(Tok.is(tok::coloncolon) && 61 "NextToken() not working properly!"); 62 SourceLocation CCLoc = ConsumeToken(); 63 if (SS.isInvalid()) 64 continue; 65 66 SS.setScopeRep( 67 Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, IdLoc, CCLoc, *II) ); 68 SS.setEndLoc(CCLoc); 69 } 70} 71 72/// ParseCXXIdExpression - Handle id-expression. 73/// 74/// id-expression: 75/// unqualified-id 76/// qualified-id 77/// 78/// unqualified-id: 79/// identifier 80/// operator-function-id 81/// conversion-function-id [TODO] 82/// '~' class-name [TODO] 83/// template-id [TODO] 84/// 85/// qualified-id: 86/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 87/// '::' identifier 88/// '::' operator-function-id 89/// '::' template-id [TODO] 90/// 91/// nested-name-specifier: 92/// type-name '::' 93/// namespace-name '::' 94/// nested-name-specifier identifier '::' 95/// nested-name-specifier 'template'[opt] simple-template-id '::' [TODO] 96/// 97/// NOTE: The standard specifies that, for qualified-id, the parser does not 98/// expect: 99/// 100/// '::' conversion-function-id 101/// '::' '~' class-name 102/// 103/// This may cause a slight inconsistency on diagnostics: 104/// 105/// class C {}; 106/// namespace A {} 107/// void f() { 108/// :: A :: ~ C(); // Some Sema error about using destructor with a 109/// // namespace. 110/// :: ~ C(); // Some Parser error like 'unexpected ~'. 111/// } 112/// 113/// We simplify the parser a bit and make it work like: 114/// 115/// qualified-id: 116/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 117/// '::' unqualified-id 118/// 119/// That way Sema can handle and report similar errors for namespaces and the 120/// global scope. 121/// 122Parser::ExprResult Parser::ParseCXXIdExpression() { 123 // qualified-id: 124 // '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 125 // '::' unqualified-id 126 // 127 CXXScopeSpec SS; 128 if (isTokenCXXScopeSpecifier()) 129 ParseCXXScopeSpecifier(SS); 130 131 // unqualified-id: 132 // identifier 133 // operator-function-id 134 // conversion-function-id 135 // '~' class-name [TODO] 136 // template-id [TODO] 137 // 138 switch (Tok.getKind()) { 139 default: 140 return Diag(Tok, diag::err_expected_unqualified_id); 141 142 case tok::identifier: { 143 // Consume the identifier so that we can see if it is followed by a '('. 144 IdentifierInfo &II = *Tok.getIdentifierInfo(); 145 SourceLocation L = ConsumeToken(); 146 return Actions.ActOnIdentifierExpr(CurScope, L, II, 147 Tok.is(tok::l_paren), &SS); 148 } 149 150 case tok::kw_operator: { 151 SourceLocation OperatorLoc = Tok.getLocation(); 152 if (IdentifierInfo *II = TryParseOperatorFunctionId()) { 153 return Actions.ActOnIdentifierExpr(CurScope, OperatorLoc, *II, 154 Tok.is(tok::l_paren), &SS); 155 } else if (TypeTy *Type = ParseConversionFunctionId()) { 156 return Actions.ActOnConversionFunctionExpr(CurScope, OperatorLoc, 157 Type, Tok.is(tok::l_paren), 158 &SS); 159 } 160 161 // We already complained about a bad conversion-function-id, 162 // above. 163 return true; 164 } 165 166 } // switch. 167 168 assert(0 && "The switch was supposed to take care everything."); 169} 170 171/// ParseCXXCasts - This handles the various ways to cast expressions to another 172/// type. 173/// 174/// postfix-expression: [C++ 5.2p1] 175/// 'dynamic_cast' '<' type-name '>' '(' expression ')' 176/// 'static_cast' '<' type-name '>' '(' expression ')' 177/// 'reinterpret_cast' '<' type-name '>' '(' expression ')' 178/// 'const_cast' '<' type-name '>' '(' expression ')' 179/// 180Parser::ExprResult Parser::ParseCXXCasts() { 181 tok::TokenKind Kind = Tok.getKind(); 182 const char *CastName = 0; // For error messages 183 184 switch (Kind) { 185 default: assert(0 && "Unknown C++ cast!"); abort(); 186 case tok::kw_const_cast: CastName = "const_cast"; break; 187 case tok::kw_dynamic_cast: CastName = "dynamic_cast"; break; 188 case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break; 189 case tok::kw_static_cast: CastName = "static_cast"; break; 190 } 191 192 SourceLocation OpLoc = ConsumeToken(); 193 SourceLocation LAngleBracketLoc = Tok.getLocation(); 194 195 if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName)) 196 return ExprResult(true); 197 198 TypeTy *CastTy = ParseTypeName(); 199 SourceLocation RAngleBracketLoc = Tok.getLocation(); 200 201 if (ExpectAndConsume(tok::greater, diag::err_expected_greater)) 202 return Diag(LAngleBracketLoc, diag::err_matching) << "<"; 203 204 SourceLocation LParenLoc = Tok.getLocation(), RParenLoc; 205 206 if (Tok.isNot(tok::l_paren)) 207 return Diag(Tok, diag::err_expected_lparen_after) << CastName; 208 209 ExprResult Result = ParseSimpleParenExpression(RParenLoc); 210 211 if (!Result.isInvalid) 212 Result = Actions.ActOnCXXNamedCast(OpLoc, Kind, 213 LAngleBracketLoc, CastTy, RAngleBracketLoc, 214 LParenLoc, Result.Val, RParenLoc); 215 216 return Result; 217} 218 219/// ParseCXXTypeid - This handles the C++ typeid expression. 220/// 221/// postfix-expression: [C++ 5.2p1] 222/// 'typeid' '(' expression ')' 223/// 'typeid' '(' type-id ')' 224/// 225Parser::ExprResult Parser::ParseCXXTypeid() { 226 assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!"); 227 228 SourceLocation OpLoc = ConsumeToken(); 229 SourceLocation LParenLoc = Tok.getLocation(); 230 SourceLocation RParenLoc; 231 232 // typeid expressions are always parenthesized. 233 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, 234 "typeid")) 235 return ExprResult(true); 236 237 Parser::ExprResult Result; 238 239 if (isTypeIdInParens()) { 240 TypeTy *Ty = ParseTypeName(); 241 242 // Match the ')'. 243 MatchRHSPunctuation(tok::r_paren, LParenLoc); 244 245 if (!Ty) 246 return ExprResult(true); 247 248 Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true, 249 Ty, RParenLoc); 250 } else { 251 Result = ParseExpression(); 252 253 // Match the ')'. 254 if (Result.isInvalid) 255 SkipUntil(tok::r_paren); 256 else { 257 MatchRHSPunctuation(tok::r_paren, LParenLoc); 258 259 Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false, 260 Result.Val, RParenLoc); 261 } 262 } 263 264 return Result; 265} 266 267/// ParseCXXBoolLiteral - This handles the C++ Boolean literals. 268/// 269/// boolean-literal: [C++ 2.13.5] 270/// 'true' 271/// 'false' 272Parser::ExprResult Parser::ParseCXXBoolLiteral() { 273 tok::TokenKind Kind = Tok.getKind(); 274 return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind); 275} 276 277/// ParseThrowExpression - This handles the C++ throw expression. 278/// 279/// throw-expression: [C++ 15] 280/// 'throw' assignment-expression[opt] 281Parser::ExprResult Parser::ParseThrowExpression() { 282 assert(Tok.is(tok::kw_throw) && "Not throw!"); 283 SourceLocation ThrowLoc = ConsumeToken(); // Eat the throw token. 284 285 // If the current token isn't the start of an assignment-expression, 286 // then the expression is not present. This handles things like: 287 // "C ? throw : (void)42", which is crazy but legal. 288 switch (Tok.getKind()) { // FIXME: move this predicate somewhere common. 289 case tok::semi: 290 case tok::r_paren: 291 case tok::r_square: 292 case tok::r_brace: 293 case tok::colon: 294 case tok::comma: 295 return Actions.ActOnCXXThrow(ThrowLoc); 296 297 default: 298 ExprResult Expr = ParseAssignmentExpression(); 299 if (Expr.isInvalid) return Expr; 300 return Actions.ActOnCXXThrow(ThrowLoc, Expr.Val); 301 } 302} 303 304/// ParseCXXThis - This handles the C++ 'this' pointer. 305/// 306/// C++ 9.3.2: In the body of a non-static member function, the keyword this is 307/// a non-lvalue expression whose value is the address of the object for which 308/// the function is called. 309Parser::ExprResult Parser::ParseCXXThis() { 310 assert(Tok.is(tok::kw_this) && "Not 'this'!"); 311 SourceLocation ThisLoc = ConsumeToken(); 312 return Actions.ActOnCXXThis(ThisLoc); 313} 314 315/// ParseCXXTypeConstructExpression - Parse construction of a specified type. 316/// Can be interpreted either as function-style casting ("int(x)") 317/// or class type construction ("ClassType(x,y,z)") 318/// or creation of a value-initialized type ("int()"). 319/// 320/// postfix-expression: [C++ 5.2p1] 321/// simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3] 322/// typename-specifier '(' expression-list[opt] ')' [TODO] 323/// 324Parser::ExprResult Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { 325 Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 326 TypeTy *TypeRep = Actions.ActOnTypeName(CurScope, DeclaratorInfo).Val; 327 328 assert(Tok.is(tok::l_paren) && "Expected '('!"); 329 SourceLocation LParenLoc = ConsumeParen(); 330 331 ExprListTy Exprs; 332 CommaLocsTy CommaLocs; 333 334 if (Tok.isNot(tok::r_paren)) { 335 if (ParseExpressionList(Exprs, CommaLocs)) { 336 SkipUntil(tok::r_paren); 337 return ExprResult(true); 338 } 339 } 340 341 // Match the ')'. 342 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 343 344 assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&& 345 "Unexpected number of commas!"); 346 return Actions.ActOnCXXTypeConstructExpr(DS.getSourceRange(), TypeRep, 347 LParenLoc, 348 &Exprs[0], Exprs.size(), 349 &CommaLocs[0], RParenLoc); 350} 351 352/// ParseCXXCondition - if/switch/while/for condition expression. 353/// 354/// condition: 355/// expression 356/// type-specifier-seq declarator '=' assignment-expression 357/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 358/// '=' assignment-expression 359/// 360Parser::ExprResult Parser::ParseCXXCondition() { 361 if (!isCXXConditionDeclaration()) 362 return ParseExpression(); // expression 363 364 SourceLocation StartLoc = Tok.getLocation(); 365 366 // type-specifier-seq 367 DeclSpec DS; 368 ParseSpecifierQualifierList(DS); 369 370 // declarator 371 Declarator DeclaratorInfo(DS, Declarator::ConditionContext); 372 ParseDeclarator(DeclaratorInfo); 373 374 // simple-asm-expr[opt] 375 if (Tok.is(tok::kw_asm)) { 376 ExprResult AsmLabel = ParseSimpleAsm(); 377 if (AsmLabel.isInvalid) { 378 SkipUntil(tok::semi); 379 return true; 380 } 381 DeclaratorInfo.setAsmLabel(AsmLabel.Val); 382 } 383 384 // If attributes are present, parse them. 385 if (Tok.is(tok::kw___attribute)) 386 DeclaratorInfo.AddAttributes(ParseAttributes()); 387 388 // '=' assignment-expression 389 if (Tok.isNot(tok::equal)) 390 return Diag(Tok, diag::err_expected_equal_after_declarator); 391 SourceLocation EqualLoc = ConsumeToken(); 392 ExprResult AssignExpr = ParseAssignmentExpression(); 393 if (AssignExpr.isInvalid) 394 return true; 395 396 return Actions.ActOnCXXConditionDeclarationExpr(CurScope, StartLoc, 397 DeclaratorInfo, 398 EqualLoc, AssignExpr.Val); 399} 400 401/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers. 402/// This should only be called when the current token is known to be part of 403/// simple-type-specifier. 404/// 405/// simple-type-specifier: 406/// '::'[opt] nested-name-specifier[opt] type-name 407/// '::'[opt] nested-name-specifier 'template' simple-template-id [TODO] 408/// char 409/// wchar_t 410/// bool 411/// short 412/// int 413/// long 414/// signed 415/// unsigned 416/// float 417/// double 418/// void 419/// [GNU] typeof-specifier 420/// [C++0x] auto [TODO] 421/// 422/// type-name: 423/// class-name 424/// enum-name 425/// typedef-name 426/// 427void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { 428 // Annotate typenames and C++ scope specifiers. 429 TryAnnotateTypeOrScopeToken(); 430 431 DS.SetRangeStart(Tok.getLocation()); 432 const char *PrevSpec; 433 SourceLocation Loc = Tok.getLocation(); 434 435 switch (Tok.getKind()) { 436 default: 437 assert(0 && "Not a simple-type-specifier token!"); 438 abort(); 439 440 // type-name 441 case tok::annot_qualtypename: { 442 DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec, 443 Tok.getAnnotationValue()); 444 break; 445 } 446 447 // builtin types 448 case tok::kw_short: 449 DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec); 450 break; 451 case tok::kw_long: 452 DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec); 453 break; 454 case tok::kw_signed: 455 DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec); 456 break; 457 case tok::kw_unsigned: 458 DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec); 459 break; 460 case tok::kw_void: 461 DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec); 462 break; 463 case tok::kw_char: 464 DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec); 465 break; 466 case tok::kw_int: 467 DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec); 468 break; 469 case tok::kw_float: 470 DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec); 471 break; 472 case tok::kw_double: 473 DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec); 474 break; 475 case tok::kw_wchar_t: 476 DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec); 477 break; 478 case tok::kw_bool: 479 DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec); 480 break; 481 482 // GNU typeof support. 483 case tok::kw_typeof: 484 ParseTypeofSpecifier(DS); 485 DS.Finish(Diags, PP.getSourceManager(), getLang()); 486 return; 487 } 488 if (Tok.is(tok::annot_qualtypename)) 489 DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 490 else 491 DS.SetRangeEnd(Tok.getLocation()); 492 ConsumeToken(); 493 DS.Finish(Diags, PP.getSourceManager(), getLang()); 494} 495 496/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++ 497/// [dcl.name]), which is a non-empty sequence of type-specifiers, 498/// e.g., "const short int". Note that the DeclSpec is *not* finished 499/// by parsing the type-specifier-seq, because these sequences are 500/// typically followed by some form of declarator. Returns true and 501/// emits diagnostics if this is not a type-specifier-seq, false 502/// otherwise. 503/// 504/// type-specifier-seq: [C++ 8.1] 505/// type-specifier type-specifier-seq[opt] 506/// 507bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) { 508 DS.SetRangeStart(Tok.getLocation()); 509 const char *PrevSpec = 0; 510 int isInvalid = 0; 511 512 // Parse one or more of the type specifiers. 513 if (!MaybeParseTypeSpecifier(DS, isInvalid, PrevSpec)) { 514 Diag(Tok, diag::err_operator_missing_type_specifier); 515 return true; 516 } 517 while (MaybeParseTypeSpecifier(DS, isInvalid, PrevSpec)) ; 518 519 return false; 520} 521 522/// TryParseOperatorFunctionId - Attempts to parse a C++ overloaded 523/// operator name (C++ [over.oper]). If successful, returns the 524/// predefined identifier that corresponds to that overloaded 525/// operator. Otherwise, returns NULL and does not consume any tokens. 526/// 527/// operator-function-id: [C++ 13.5] 528/// 'operator' operator 529/// 530/// operator: one of 531/// new delete new[] delete[] 532/// + - * / % ^ & | ~ 533/// ! = < > += -= *= /= %= 534/// ^= &= |= << >> >>= <<= == != 535/// <= >= && || ++ -- , ->* -> 536/// () [] 537IdentifierInfo *Parser::TryParseOperatorFunctionId() { 538 assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); 539 540 OverloadedOperatorKind Op = OO_None; 541 switch (NextToken().getKind()) { 542 case tok::kw_new: 543 ConsumeToken(); // 'operator' 544 ConsumeToken(); // 'new' 545 if (Tok.is(tok::l_square)) { 546 ConsumeBracket(); // '[' 547 ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 548 Op = OO_Array_New; 549 } else { 550 Op = OO_New; 551 } 552 return &PP.getIdentifierTable().getOverloadedOperator(Op); 553 554 case tok::kw_delete: 555 ConsumeToken(); // 'operator' 556 ConsumeToken(); // 'delete' 557 if (Tok.is(tok::l_square)) { 558 ConsumeBracket(); // '[' 559 ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 560 Op = OO_Array_Delete; 561 } else { 562 Op = OO_Delete; 563 } 564 return &PP.getIdentifierTable().getOverloadedOperator(Op); 565 566#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 567 case tok::Token: Op = OO_##Name; break; 568#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) 569#include "clang/Basic/OperatorKinds.def" 570 571 case tok::l_paren: 572 ConsumeToken(); // 'operator' 573 ConsumeParen(); // '(' 574 ExpectAndConsume(tok::r_paren, diag::err_expected_rparen); // ')' 575 return &PP.getIdentifierTable().getOverloadedOperator(OO_Call); 576 577 case tok::l_square: 578 ConsumeToken(); // 'operator' 579 ConsumeBracket(); // '[' 580 ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 581 return &PP.getIdentifierTable().getOverloadedOperator(OO_Subscript); 582 583 default: 584 return 0; 585 } 586 587 ConsumeToken(); // 'operator' 588 ConsumeAnyToken(); // the operator itself 589 return &PP.getIdentifierTable().getOverloadedOperator(Op); 590} 591 592/// ParseConversionFunctionId - Parse a C++ conversion-function-id, 593/// which expresses the name of a user-defined conversion operator 594/// (C++ [class.conv.fct]p1). Returns the type that this operator is 595/// specifying a conversion for, or NULL if there was an error. 596/// 597/// conversion-function-id: [C++ 12.3.2] 598/// operator conversion-type-id 599/// 600/// conversion-type-id: 601/// type-specifier-seq conversion-declarator[opt] 602/// 603/// conversion-declarator: 604/// ptr-operator conversion-declarator[opt] 605Parser::TypeTy *Parser::ParseConversionFunctionId() { 606 assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); 607 ConsumeToken(); // 'operator' 608 609 // Parse the type-specifier-seq. 610 DeclSpec DS; 611 if (ParseCXXTypeSpecifierSeq(DS)) 612 return 0; 613 614 // Parse the conversion-declarator, which is merely a sequence of 615 // ptr-operators. 616 Declarator D(DS, Declarator::TypeNameContext); 617 ParseDeclaratorInternal(D, /*PtrOperator=*/true); 618 619 // Finish up the type. 620 Action::TypeResult Result = Actions.ActOnTypeName(CurScope, D); 621 if (Result.isInvalid) 622 return 0; 623 else 624 return Result.Val; 625} 626