ParseExprCXX.cpp revision 1cd1b1e987f5e2f060d7972b13d83239b36d77d6
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- ParseExprCXX.cpp - C++ Expression Parsing ------------------------===// 25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// The LLVM Compiler Infrastructure 45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This file implements the Expression parsing implementation for C++. 115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/Diagnostic.h" 155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Parse/Parser.h" 16987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis#include "clang/Parse/DeclSpec.h" 175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang; 185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCXXCasts - This handles the various ways to cast expressions to another 205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// type. 215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// postfix-expression: [C++ 5.2p1] 235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'dynamic_cast' '<' type-name '>' '(' expression ')' 245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'static_cast' '<' type-name '>' '(' expression ')' 255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'reinterpret_cast' '<' type-name '>' '(' expression ')' 265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'const_cast' '<' type-name '>' '(' expression ')' 275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerParser::ExprResult Parser::ParseCXXCasts() { 295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer tok::TokenKind Kind = Tok.getKind(); 305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const char *CastName = 0; // For error messages 315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer switch (Kind) { 335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer default: assert(0 && "Unknown C++ cast!"); abort(); 345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_const_cast: CastName = "const_cast"; break; 355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_dynamic_cast: CastName = "dynamic_cast"; break; 365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break; 375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_static_cast: CastName = "static_cast"; break; 385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation OpLoc = ConsumeToken(); 415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation LAngleBracketLoc = Tok.getLocation(); 425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName)) 445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return ExprResult(true); 455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer TypeTy *CastTy = ParseTypeName(); 475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation RAngleBracketLoc = Tok.getLocation(); 485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (ExpectAndConsume(tok::greater, diag::err_expected_greater)) { 505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Diag(LAngleBracketLoc, diag::err_matching, "<"); 515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return ExprResult(true); 525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation LParenLoc = Tok.getLocation(), RParenLoc; 555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 564e1d99a8a4d2958f0858f4baac68066af2c5cf17Chris Lattner if (Tok.isNot(tok::l_paren)) { 575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Diag(Tok, diag::err_expected_lparen_after, CastName); 585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return ExprResult(true); 595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ExprResult Result = ParseSimpleParenExpression(RParenLoc); 625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (!Result.isInvalid) 6449badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor Result = Actions.ActOnCXXNamedCast(OpLoc, Kind, 6549badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor LAngleBracketLoc, CastTy, RAngleBracketLoc, 6649badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor LParenLoc, Result.Val, RParenLoc); 675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return Result; 695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCXXBoolLiteral - This handles the C++ Boolean literals. 725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// boolean-literal: [C++ 2.13.5] 745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'true' 755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'false' 765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerParser::ExprResult Parser::ParseCXXBoolLiteral() { 775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer tok::TokenKind Kind = Tok.getKind(); 781b273c403734d343d720acb28f04011807c8aa56Steve Naroff return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind); 795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 8050dd289f45738ed22b7583d52ed2525b927042ffChris Lattner 8150dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// ParseThrowExpression - This handles the C++ throw expression. 8250dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// 8350dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// throw-expression: [C++ 15] 8450dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// 'throw' assignment-expression[opt] 8550dd289f45738ed22b7583d52ed2525b927042ffChris LattnerParser::ExprResult Parser::ParseThrowExpression() { 8650dd289f45738ed22b7583d52ed2525b927042ffChris Lattner assert(Tok.is(tok::kw_throw) && "Not throw!"); 8750dd289f45738ed22b7583d52ed2525b927042ffChris Lattner SourceLocation ThrowLoc = ConsumeToken(); // Eat the throw token. 883e3d310a8c74f7e0ccaf2e0a64400d15b8cb5556Chris Lattner 892a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // If the current token isn't the start of an assignment-expression, 902a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // then the expression is not present. This handles things like: 912a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // "C ? throw : (void)42", which is crazy but legal. 922a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner switch (Tok.getKind()) { // FIXME: move this predicate somewhere common. 932a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::semi: 942a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_paren: 952a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_square: 962a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_brace: 972a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::colon: 982a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::comma: 9950dd289f45738ed22b7583d52ed2525b927042ffChris Lattner return Actions.ActOnCXXThrow(ThrowLoc); 10050dd289f45738ed22b7583d52ed2525b927042ffChris Lattner 1012a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner default: 1023e3d310a8c74f7e0ccaf2e0a64400d15b8cb5556Chris Lattner ExprResult Expr = ParseAssignmentExpression(); 1032a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner if (Expr.isInvalid) return Expr; 1042a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner return Actions.ActOnCXXThrow(ThrowLoc, Expr.Val); 1052a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner } 10650dd289f45738ed22b7583d52ed2525b927042ffChris Lattner} 1074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 1084cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXThis - This handles the C++ 'this' pointer. 1094cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 1104cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// C++ 9.3.2: In the body of a non-static member function, the keyword this is 1114cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// a non-lvalue expression whose value is the address of the object for which 1124cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// the function is called. 1134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios KyrtzidisParser::ExprResult Parser::ParseCXXThis() { 1144cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis assert(Tok.is(tok::kw_this) && "Not 'this'!"); 1154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SourceLocation ThisLoc = ConsumeToken(); 116289d77302aa81dc24bf7aa75b36cb00a70a44bb5Argyrios Kyrtzidis return Actions.ActOnCXXThis(ThisLoc); 1174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 118987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 119987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// ParseCXXTypeConstructExpression - Parse construction of a specified type. 120987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// Can be interpreted either as function-style casting ("int(x)") 121987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// or class type construction ("ClassType(x,y,z)") 122987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// or creation of a value-initialized type ("int()"). 123987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 124987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// postfix-expression: [C++ 5.2p1] 125987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3] 126987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// typename-specifier '(' expression-list[opt] ')' [TODO] 127987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 128987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios KyrtzidisParser::ExprResult Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { 129987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 130987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis TypeTy *TypeRep = Actions.ActOnTypeName(CurScope, DeclaratorInfo).Val; 131987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 132987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis assert(Tok.is(tok::l_paren) && "Expected '('!"); 133987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SourceLocation LParenLoc = ConsumeParen(); 134987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 135987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis ExprListTy Exprs; 136987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis CommaLocsTy CommaLocs; 137987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 138987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis if (Tok.isNot(tok::r_paren)) { 139987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis if (ParseExpressionList(Exprs, CommaLocs)) { 140987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SkipUntil(tok::r_paren); 141987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis return ExprResult(true); 142987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 143987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 144987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 145987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // Match the ')'. 146987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 147987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 148987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&& 149987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis "Unexpected number of commas!"); 150987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis return Actions.ActOnCXXTypeConstructExpr(DS.getSourceRange(), TypeRep, 151987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis LParenLoc, 152987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis &Exprs[0], Exprs.size(), 153987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis &CommaLocs[0], RParenLoc); 154987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis} 155987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 15671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// ParseCXXCondition - if/switch/while/for condition expression. 15771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// 15871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// condition: 15971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// expression 16071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// type-specifier-seq declarator '=' assignment-expression 16171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 16271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// '=' assignment-expression 16371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// 16471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios KyrtzidisParser::ExprResult Parser::ParseCXXCondition() { 165a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis if (!isCXXConditionDeclaration()) 16671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis return ParseExpression(); // expression 16771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 16871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SourceLocation StartLoc = Tok.getLocation(); 16971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 17071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // type-specifier-seq 17171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis DeclSpec DS; 17271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis ParseSpecifierQualifierList(DS); 17371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 17471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // declarator 17571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::ConditionContext); 17671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 17771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 17871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // simple-asm-expr[opt] 17971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (Tok.is(tok::kw_asm)) { 18071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis ExprResult AsmLabel = ParseSimpleAsm(); 18171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (AsmLabel.isInvalid) { 18271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SkipUntil(tok::semi); 18371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis return true; 18471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis } 18571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis DeclaratorInfo.setAsmLabel(AsmLabel.Val); 18671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis } 18771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 18871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // If attributes are present, parse them. 18971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (Tok.is(tok::kw___attribute)) 19071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis DeclaratorInfo.AddAttributes(ParseAttributes()); 19171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 19271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // '=' assignment-expression 19371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (Tok.isNot(tok::equal)) 19471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis return Diag(Tok, diag::err_expected_equal_after_declarator); 19571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SourceLocation EqualLoc = ConsumeToken(); 19671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis ExprResult AssignExpr = ParseAssignmentExpression(); 19771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (AssignExpr.isInvalid) 19871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis return true; 19971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 20071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis return Actions.ActOnCXXConditionDeclarationExpr(CurScope, StartLoc, 20171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis DeclaratorInfo, 20271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis EqualLoc, AssignExpr.Val); 20371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis} 20471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 205987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers. 206987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// This should only be called when the current token is known to be part of 207987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// simple-type-specifier. 208987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 209987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// simple-type-specifier: 210987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// '::'[opt] nested-name-specifier[opt] type-name [TODO] 211987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template' simple-template-id [TODO] 212987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// char 213987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// wchar_t 214987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// bool 215987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// short 216987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// int 217987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// long 218987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// signed 219987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// unsigned 220987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// float 221987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// double 222987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// void 223987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// [GNU] typeof-specifier 224987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// [C++0x] auto [TODO] 225987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 226987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// type-name: 227987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// class-name 228987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// enum-name 229987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// typedef-name 230987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 231987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidisvoid Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { 232987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetRangeStart(Tok.getLocation()); 233987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis const char *PrevSpec; 234987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SourceLocation Loc = Tok.getLocation(); 235987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 236987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis switch (Tok.getKind()) { 237987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis default: 238987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis assert(0 && "Not a simple-type-specifier token!"); 239987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis abort(); 240987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 241987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // type-name 242987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::identifier: { 243987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis TypeTy *TypeRep = Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope); 244987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis assert(TypeRep && "Identifier wasn't a type-name!"); 245987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec, TypeRep); 246987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 247987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 248987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 249987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // builtin types 250987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_short: 251987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec); 252987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 253987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_long: 254987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec); 255987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 256987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_signed: 257987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec); 258987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 259987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_unsigned: 260987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec); 261987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 262987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_void: 263987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec); 264987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 265987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_char: 266987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec); 267987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 268987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_int: 269987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec); 270987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 271987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_float: 272987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec); 273987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 274987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_double: 275987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec); 276987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 277987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_wchar_t: 278987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec); 279987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 280987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_bool: 281987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec); 282987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 283987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 284987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // GNU typeof support. 285987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_typeof: 286987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis ParseTypeofSpecifier(DS); 287987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.Finish(Diags, PP.getSourceManager(), getLang()); 288987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis return; 289987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 290987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetRangeEnd(Tok.getLocation()); 291987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis ConsumeToken(); 292987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.Finish(Diags, PP.getSourceManager(), getLang()); 293987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis} 2941cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 2951cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// MaybeParseOperatorFunctionId - Attempts to parse a C++ overloaded 2961cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator name (C++ [over.oper]). If successful, returns the 2971cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// predefined identifier that corresponds to that overloaded 2981cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator. Otherwise, returns NULL and does not consume any tokens. 2991cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// 3001cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator-function-id: [C++ 13.5] 3011cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// 'operator' operator 3021cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// 3031cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator: one of 3041cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// new delete new[] delete[] 3051cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// + - * / % ^ & | ~ 3061cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// ! = < > += -= *= /= %= 3071cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// ^= &= |= << >> >>= <<= == != 3081cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// <= >= && || ++ -- , ->* -> 3091cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// () [] 3101cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas GregorIdentifierInfo *Parser::MaybeParseOperatorFunctionId() { 3111cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor if (Tok.isNot(tok::kw_operator)) 3121cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor return 0; 3131cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 3141cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor OverloadedOperatorKind Op = OO_None; 3151cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor switch (NextToken().getKind()) { 3161cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::kw_new: 3171cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 3181cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'new' 3191cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor if (Tok.is(tok::l_square)) { 3201cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeBracket(); // '[' 3211cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 3221cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_Array_New; 3231cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } else { 3241cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_New; 3251cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } 3261cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor return &PP.getIdentifierTable().getOverloadedOperator(Op); 3271cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 3281cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::kw_delete: 3291cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 3301cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'delete' 3311cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor if (Tok.is(tok::l_square)) { 3321cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeBracket(); // '[' 3331cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 3341cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_Array_Delete; 3351cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } else { 3361cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_Delete; 3371cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } 3381cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor return &PP.getIdentifierTable().getOverloadedOperator(Op); 3391cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 3401cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor#define OVERLOADED_OPERATOR(Name,Spelling,Token) \ 3411cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::Token: Op = OO_##Name; break; 3421cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor#define OVERLOADED_OPERATOR_MULTI(Name,Spelling) 3431cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor#include "clang/Basic/OperatorKinds.def" 3441cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 3451cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::l_paren: 3461cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 3471cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeParen(); // '(' 3481cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_paren, diag::err_expected_rparen); // ')' 3491cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor return &PP.getIdentifierTable().getOverloadedOperator(OO_Call); 3501cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 3511cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::l_square: 3521cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 3531cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeBracket(); // '[' 3541cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 3551cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor return &PP.getIdentifierTable().getOverloadedOperator(OO_Subscript); 3561cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 3571cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor default: 3581cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor break; 3591cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } 3601cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 3611cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor if (Op == OO_None) 3621cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor return 0; 3631cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor else { 3641cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::kw_operator, diag::err_expected_operator); 3651cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeAnyToken(); // the operator itself 3661cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor return &PP.getIdentifierTable().getOverloadedOperator(Op); 3671cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } 3681cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor} 369