ParseExprCXX.cpp revision 7452c6fc567ea1799f617395d0fa4c7ed075e5d9
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" 17a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl#include "AstGuard.h" 185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang; 195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 204bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis/// MaybeParseCXXScopeSpecifier - Parse global scope or nested-name-specifier. 214bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis/// Returns true if a nested-name-specifier was parsed from the token stream. 2255a7cefc846765ac7d142a63f773747a20518d71Chris Lattner/// 2355a7cefc846765ac7d142a63f773747a20518d71Chris Lattner/// Note that this routine emits an error if you call it with ::new or ::delete 2455a7cefc846765ac7d142a63f773747a20518d71Chris Lattner/// as the current tokens, so only call it in contexts where these are invalid. 25eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 26eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier 27eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' 28eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 29eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier: 30eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// type-name '::' 31eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// namespace-name '::' 32eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier identifier '::' 33eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier 'template'[opt] simple-template-id '::' [TODO] 34eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 35a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattnerbool Parser::MaybeParseCXXScopeSpecifier(CXXScopeSpec &SS, 36a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner const Token *GlobalQualifier) { 374bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis assert(getLang().CPlusPlus && 387452c6fc567ea1799f617395d0fa4c7ed075e5d9Chris Lattner "Call sites of this function should be guarded by checking for C++"); 394bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis 40eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis if (Tok.is(tok::annot_cxxscope)) { 41a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner assert(GlobalQualifier == 0 && 4255a7cefc846765ac7d142a63f773747a20518d71Chris Lattner "Cannot have :: followed by a resolved annotation scope"); 43eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setScopeRep(Tok.getAnnotationValue()); 44eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setRange(Tok.getAnnotationRange()); 45eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis ConsumeToken(); 464bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis return true; 47eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 48e607e808c2b90724a2a6fd841e850f07de1f5b30Chris Lattner 49a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner if (GlobalQualifier == 0 && 50a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner Tok.isNot(tok::coloncolon) && 51e607e808c2b90724a2a6fd841e850f07de1f5b30Chris Lattner (Tok.isNot(tok::identifier) || NextToken().isNot(tok::coloncolon))) 52e607e808c2b90724a2a6fd841e850f07de1f5b30Chris Lattner return false; 53e607e808c2b90724a2a6fd841e850f07de1f5b30Chris Lattner 54a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner if (GlobalQualifier) { 55a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner // Pre-parsed '::'. 56a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner SS.setBeginLoc(GlobalQualifier->getLocation()); 57a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, 58a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner GlobalQualifier->getLocation())); 59a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner SS.setEndLoc(GlobalQualifier->getLocation()); 6055a7cefc846765ac7d142a63f773747a20518d71Chris Lattner 6155a7cefc846765ac7d142a63f773747a20518d71Chris Lattner assert(Tok.isNot(tok::kw_new) && Tok.isNot(tok::kw_delete) && 6255a7cefc846765ac7d142a63f773747a20518d71Chris Lattner "Never called with preparsed :: qualifier and with new/delete"); 63a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner } else { 64a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner SS.setBeginLoc(Tok.getLocation()); 65eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 6655a7cefc846765ac7d142a63f773747a20518d71Chris Lattner // '::' - Global scope qualifier. 67a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner if (Tok.is(tok::coloncolon)) { 68a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner SourceLocation CCLoc = ConsumeToken(); 6955a7cefc846765ac7d142a63f773747a20518d71Chris Lattner 7055a7cefc846765ac7d142a63f773747a20518d71Chris Lattner // ::new and ::delete aren't nested-name-specifiers, and 7155a7cefc846765ac7d142a63f773747a20518d71Chris Lattner // MaybeParseCXXScopeSpecifier is never called in a context where one could 7255a7cefc846765ac7d142a63f773747a20518d71Chris Lattner // exist. This means that if we see it, we have a syntax error. 7355a7cefc846765ac7d142a63f773747a20518d71Chris Lattner if (Tok.is(tok::kw_new) || Tok.is(tok::kw_delete)) { 7455a7cefc846765ac7d142a63f773747a20518d71Chris Lattner Diag(Tok, diag::err_invalid_qualified_new_delete) 7555a7cefc846765ac7d142a63f773747a20518d71Chris Lattner << Tok.is(tok::kw_delete); 7655a7cefc846765ac7d142a63f773747a20518d71Chris Lattner SS.setBeginLoc(SourceLocation()); 7755a7cefc846765ac7d142a63f773747a20518d71Chris Lattner return false; 7855a7cefc846765ac7d142a63f773747a20518d71Chris Lattner } 7955a7cefc846765ac7d142a63f773747a20518d71Chris Lattner 8055a7cefc846765ac7d142a63f773747a20518d71Chris Lattner // Global scope. 81a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc)); 82a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner SS.setEndLoc(CCLoc); 83a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner } 84eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 85eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 86eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // nested-name-specifier: 87eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // type-name '::' 88eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // namespace-name '::' 89eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // nested-name-specifier identifier '::' 90eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // nested-name-specifier 'template'[opt] simple-template-id '::' [TODO] 91eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis while (Tok.is(tok::identifier) && NextToken().is(tok::coloncolon)) { 92eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis IdentifierInfo *II = Tok.getIdentifierInfo(); 93eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation IdLoc = ConsumeToken(); 94e607e808c2b90724a2a6fd841e850f07de1f5b30Chris Lattner assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!"); 95eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation CCLoc = ConsumeToken(); 96eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis if (SS.isInvalid()) 97eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis continue; 98eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 99eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setScopeRep( 100e607e808c2b90724a2a6fd841e850f07de1f5b30Chris Lattner Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, IdLoc, CCLoc, *II)); 101eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setEndLoc(CCLoc); 102eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 1034bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis 1044bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis return true; 105eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis} 106eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 107eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// ParseCXXIdExpression - Handle id-expression. 108eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 109eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// id-expression: 110eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// unqualified-id 111eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// qualified-id 112eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 113eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// unqualified-id: 114eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// identifier 115eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// operator-function-id 116eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// conversion-function-id [TODO] 117eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '~' class-name [TODO] 118eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// template-id [TODO] 119eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 120eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// qualified-id: 121eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 122eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' identifier 123eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' operator-function-id 124eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' template-id [TODO] 125eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 126eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier: 127eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// type-name '::' 128eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// namespace-name '::' 129eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier identifier '::' 130eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier 'template'[opt] simple-template-id '::' [TODO] 131eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 132eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// NOTE: The standard specifies that, for qualified-id, the parser does not 133eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// expect: 134eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 135eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' conversion-function-id 136eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' '~' class-name 137eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 138eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// This may cause a slight inconsistency on diagnostics: 139eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 140eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// class C {}; 141eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// namespace A {} 142eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// void f() { 143eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// :: A :: ~ C(); // Some Sema error about using destructor with a 144eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// // namespace. 145eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// :: ~ C(); // Some Parser error like 'unexpected ~'. 146eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// } 147eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 148eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// We simplify the parser a bit and make it work like: 149eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 150eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// qualified-id: 151eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 152eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' unqualified-id 153eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 154eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// That way Sema can handle and report similar errors for namespaces and the 155eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// global scope. 156eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 15720df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult Parser::ParseCXXIdExpression() { 158eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // qualified-id: 159eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 160eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // '::' unqualified-id 161eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // 162eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis CXXScopeSpec SS; 1634bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis MaybeParseCXXScopeSpecifier(SS); 164eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 165eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // unqualified-id: 166eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // identifier 167eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // operator-function-id 1682def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor // conversion-function-id 169eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // '~' class-name [TODO] 170eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // template-id [TODO] 171eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // 172eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis switch (Tok.getKind()) { 173eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis default: 17420df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(Diag(Tok, diag::err_expected_unqualified_id)); 175eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 176eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis case tok::identifier: { 177eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // Consume the identifier so that we can see if it is followed by a '('. 178eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis IdentifierInfo &II = *Tok.getIdentifierInfo(); 179eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation L = ConsumeToken(); 18020df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnIdentifierExpr(CurScope, L, II, 18120df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl Tok.is(tok::l_paren), &SS)); 182eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 183eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 184eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis case tok::kw_operator: { 185eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation OperatorLoc = Tok.getLocation(); 1867452c6fc567ea1799f617395d0fa4c7ed075e5d9Chris Lattner if (OverloadedOperatorKind Op = TryParseOperatorFunctionId()) 18720df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXOperatorFunctionIdExpr( 18820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl CurScope, OperatorLoc, Op, Tok.is(tok::l_paren), SS)); 1897452c6fc567ea1799f617395d0fa4c7ed075e5d9Chris Lattner if (TypeTy *Type = ParseConversionFunctionId()) 1907452c6fc567ea1799f617395d0fa4c7ed075e5d9Chris Lattner return Owned(Actions.ActOnCXXConversionFunctionExpr(CurScope, OperatorLoc, 1917452c6fc567ea1799f617395d0fa4c7ed075e5d9Chris Lattner Type, 1927452c6fc567ea1799f617395d0fa4c7ed075e5d9Chris Lattner Tok.is(tok::l_paren), SS)); 19320df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl 1942def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor // We already complained about a bad conversion-function-id, 1952def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor // above. 19620df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 197eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 198eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 199eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } // switch. 200eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 201eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis assert(0 && "The switch was supposed to take care everything."); 202eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis} 203eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 2045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCXXCasts - This handles the various ways to cast expressions to another 2055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// type. 2065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 2075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// postfix-expression: [C++ 5.2p1] 2085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'dynamic_cast' '<' type-name '>' '(' expression ')' 2095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'static_cast' '<' type-name '>' '(' expression ')' 2105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'reinterpret_cast' '<' type-name '>' '(' expression ')' 2115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'const_cast' '<' type-name '>' '(' expression ')' 2125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 21320df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult Parser::ParseCXXCasts() { 2145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer tok::TokenKind Kind = Tok.getKind(); 2155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const char *CastName = 0; // For error messages 2165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer switch (Kind) { 2185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer default: assert(0 && "Unknown C++ cast!"); abort(); 2195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_const_cast: CastName = "const_cast"; break; 2205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_dynamic_cast: CastName = "dynamic_cast"; break; 2215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break; 2225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_static_cast: CastName = "static_cast"; break; 2235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation OpLoc = ConsumeToken(); 2265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation LAngleBracketLoc = Tok.getLocation(); 2275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName)) 22920df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 2305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer TypeTy *CastTy = ParseTypeName(); 2325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation RAngleBracketLoc = Tok.getLocation(); 2335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2341ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner if (ExpectAndConsume(tok::greater, diag::err_expected_greater)) 23520df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << "<"); 2365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation LParenLoc = Tok.getLocation(), RParenLoc; 2385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2391ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner if (Tok.isNot(tok::l_paren)) 24020df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(Diag(Tok, diag::err_expected_lparen_after) << CastName); 2415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 242d8c4e15138e69a51754cc259c8a592cc47950c8eSebastian Redl OwningExprResult Result(ParseSimpleParenExpression(RParenLoc)); 2435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2440e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (!Result.isInvalid()) 24549badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor Result = Actions.ActOnCXXNamedCast(OpLoc, Kind, 24649badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor LAngleBracketLoc, CastTy, RAngleBracketLoc, 247effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl LParenLoc, Result.release(), RParenLoc); 2485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 24920df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return move(Result); 2505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 2515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 252c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// ParseCXXTypeid - This handles the C++ typeid expression. 253c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 254c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// postfix-expression: [C++ 5.2p1] 255c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 'typeid' '(' expression ')' 256c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 'typeid' '(' type-id ')' 257c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 25820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult Parser::ParseCXXTypeid() { 259c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!"); 260c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 261c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SourceLocation OpLoc = ConsumeToken(); 262c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SourceLocation LParenLoc = Tok.getLocation(); 263c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SourceLocation RParenLoc; 264c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 265c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl // typeid expressions are always parenthesized. 266c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, 267c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl "typeid")) 26820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 269c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 27015faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult Result(Actions); 271c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 272c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl if (isTypeIdInParens()) { 273c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl TypeTy *Ty = ParseTypeName(); 274c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 275c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl // Match the ')'. 276c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl MatchRHSPunctuation(tok::r_paren, LParenLoc); 277c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 278c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl if (!Ty) 27920df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 280c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 281c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true, 282c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Ty, RParenLoc); 283c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl } else { 284c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Result = ParseExpression(); 285c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 286c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl // Match the ')'. 2870e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Result.isInvalid()) 288c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SkipUntil(tok::r_paren); 289c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl else { 290c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl MatchRHSPunctuation(tok::r_paren, LParenLoc); 291c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 292c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false, 293effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl Result.release(), RParenLoc); 294c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl } 295c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl } 296c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 29720df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return move(Result); 298c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl} 299c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 3005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCXXBoolLiteral - This handles the C++ Boolean literals. 3015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 3025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// boolean-literal: [C++ 2.13.5] 3035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'true' 3045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'false' 30520df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult Parser::ParseCXXBoolLiteral() { 3065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer tok::TokenKind Kind = Tok.getKind(); 30720df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind)); 3085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 30950dd289f45738ed22b7583d52ed2525b927042ffChris Lattner 31050dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// ParseThrowExpression - This handles the C++ throw expression. 31150dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// 31250dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// throw-expression: [C++ 15] 31350dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// 'throw' assignment-expression[opt] 31420df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult Parser::ParseThrowExpression() { 31550dd289f45738ed22b7583d52ed2525b927042ffChris Lattner assert(Tok.is(tok::kw_throw) && "Not throw!"); 31650dd289f45738ed22b7583d52ed2525b927042ffChris Lattner SourceLocation ThrowLoc = ConsumeToken(); // Eat the throw token. 31720df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl 3182a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // If the current token isn't the start of an assignment-expression, 3192a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // then the expression is not present. This handles things like: 3202a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // "C ? throw : (void)42", which is crazy but legal. 3212a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner switch (Tok.getKind()) { // FIXME: move this predicate somewhere common. 3222a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::semi: 3232a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_paren: 3242a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_square: 3252a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_brace: 3262a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::colon: 3272a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::comma: 32820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXThrow(ThrowLoc)); 32950dd289f45738ed22b7583d52ed2525b927042ffChris Lattner 3302a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner default: 3312f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl OwningExprResult Expr(ParseAssignmentExpression()); 33220df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl if (Expr.isInvalid()) return move(Expr); 33320df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXThrow(ThrowLoc, Expr.release())); 3342a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner } 33550dd289f45738ed22b7583d52ed2525b927042ffChris Lattner} 3364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 3374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXThis - This handles the C++ 'this' pointer. 3384cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 3394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// C++ 9.3.2: In the body of a non-static member function, the keyword this is 3404cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// a non-lvalue expression whose value is the address of the object for which 3414cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// the function is called. 34220df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult Parser::ParseCXXThis() { 3434cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis assert(Tok.is(tok::kw_this) && "Not 'this'!"); 3444cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SourceLocation ThisLoc = ConsumeToken(); 34520df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXThis(ThisLoc)); 3464cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 347987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 348987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// ParseCXXTypeConstructExpression - Parse construction of a specified type. 349987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// Can be interpreted either as function-style casting ("int(x)") 350987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// or class type construction ("ClassType(x,y,z)") 351987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// or creation of a value-initialized type ("int()"). 352987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 353987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// postfix-expression: [C++ 5.2p1] 354987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3] 355987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// typename-specifier '(' expression-list[opt] ')' [TODO] 356987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 35720df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult 35820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { 359987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 360987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis TypeTy *TypeRep = Actions.ActOnTypeName(CurScope, DeclaratorInfo).Val; 361987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 362987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis assert(Tok.is(tok::l_paren) && "Expected '('!"); 363987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SourceLocation LParenLoc = ConsumeParen(); 364987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 365a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector Exprs(Actions); 366987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis CommaLocsTy CommaLocs; 367987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 368987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis if (Tok.isNot(tok::r_paren)) { 369987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis if (ParseExpressionList(Exprs, CommaLocs)) { 370987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SkipUntil(tok::r_paren); 37120df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 372987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 373987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 374987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 375987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // Match the ')'. 376987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 377987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 378987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&& 379987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis "Unexpected number of commas!"); 38020df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXTypeConstructExpr(DS.getSourceRange(), TypeRep, 38120df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl LParenLoc, 38220df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl Exprs.take(), Exprs.size(), 38320df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl &CommaLocs[0], RParenLoc)); 384987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis} 385987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 38671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// ParseCXXCondition - if/switch/while/for condition expression. 38771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// 38871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// condition: 38971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// expression 39071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// type-specifier-seq declarator '=' assignment-expression 39171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 39271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// '=' assignment-expression 39371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// 3942f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian RedlParser::OwningExprResult Parser::ParseCXXCondition() { 395a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis if (!isCXXConditionDeclaration()) 39671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis return ParseExpression(); // expression 39771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 39871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SourceLocation StartLoc = Tok.getLocation(); 39971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 40071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // type-specifier-seq 40171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis DeclSpec DS; 40271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis ParseSpecifierQualifierList(DS); 40371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 40471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // declarator 40571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::ConditionContext); 40671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 40771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 40871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // simple-asm-expr[opt] 40971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (Tok.is(tok::kw_asm)) { 410effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl OwningExprResult AsmLabel(ParseSimpleAsm()); 4110e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (AsmLabel.isInvalid()) { 41271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SkipUntil(tok::semi); 4132f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl return ExprError(); 41471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis } 415effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl DeclaratorInfo.setAsmLabel(AsmLabel.release()); 41671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis } 41771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 41871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // If attributes are present, parse them. 41971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (Tok.is(tok::kw___attribute)) 42071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis DeclaratorInfo.AddAttributes(ParseAttributes()); 42171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 42271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // '=' assignment-expression 42371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (Tok.isNot(tok::equal)) 4242f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl return ExprError(Diag(Tok, diag::err_expected_equal_after_declarator)); 42571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SourceLocation EqualLoc = ConsumeToken(); 4262f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl OwningExprResult AssignExpr(ParseAssignmentExpression()); 4270e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (AssignExpr.isInvalid()) 4282f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl return ExprError(); 4292f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl 4302f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl return Owned(Actions.ActOnCXXConditionDeclarationExpr(CurScope, StartLoc, 4312f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl DeclaratorInfo,EqualLoc, 4322f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl AssignExpr.release())); 43371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis} 43471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 435987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers. 436987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// This should only be called when the current token is known to be part of 437987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// simple-type-specifier. 438987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 439987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// simple-type-specifier: 440eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier[opt] type-name 441987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template' simple-template-id [TODO] 442987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// char 443987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// wchar_t 444987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// bool 445987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// short 446987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// int 447987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// long 448987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// signed 449987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// unsigned 450987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// float 451987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// double 452987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// void 453987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// [GNU] typeof-specifier 454987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// [C++0x] auto [TODO] 455987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 456987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// type-name: 457987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// class-name 458987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// enum-name 459987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// typedef-name 460987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 461987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidisvoid Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { 462987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetRangeStart(Tok.getLocation()); 463987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis const char *PrevSpec; 464987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SourceLocation Loc = Tok.getLocation(); 465987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 466987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis switch (Tok.getKind()) { 46755a7cefc846765ac7d142a63f773747a20518d71Chris Lattner case tok::identifier: // foo::bar 46855a7cefc846765ac7d142a63f773747a20518d71Chris Lattner case tok::coloncolon: // ::foo::bar 46955a7cefc846765ac7d142a63f773747a20518d71Chris Lattner assert(0 && "Annotation token should already be formed!"); 470987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis default: 471987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis assert(0 && "Not a simple-type-specifier token!"); 472987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis abort(); 47355a7cefc846765ac7d142a63f773747a20518d71Chris Lattner 474987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // type-name 475eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis case tok::annot_qualtypename: { 476eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec, 477eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis Tok.getAnnotationValue()); 478987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 479987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 480987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 481987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // builtin types 482987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_short: 483987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec); 484987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 485987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_long: 486987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec); 487987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 488987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_signed: 489987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec); 490987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 491987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_unsigned: 492987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec); 493987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 494987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_void: 495987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec); 496987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 497987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_char: 498987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec); 499987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 500987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_int: 501987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec); 502987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 503987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_float: 504987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec); 505987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 506987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_double: 507987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec); 508987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 509987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_wchar_t: 510987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec); 511987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 512987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_bool: 513987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec); 514987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 515987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 516987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // GNU typeof support. 517987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_typeof: 518987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis ParseTypeofSpecifier(DS); 519987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.Finish(Diags, PP.getSourceManager(), getLang()); 520987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis return; 521987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 522eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis if (Tok.is(tok::annot_qualtypename)) 523eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 524eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis else 525eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis DS.SetRangeEnd(Tok.getLocation()); 526987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis ConsumeToken(); 527987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.Finish(Diags, PP.getSourceManager(), getLang()); 528987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis} 5291cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5302f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++ 5312f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// [dcl.name]), which is a non-empty sequence of type-specifiers, 5322f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// e.g., "const short int". Note that the DeclSpec is *not* finished 5332f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// by parsing the type-specifier-seq, because these sequences are 5342f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// typically followed by some form of declarator. Returns true and 5352f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// emits diagnostics if this is not a type-specifier-seq, false 5362f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// otherwise. 5372f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 5382f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// type-specifier-seq: [C++ 8.1] 5392f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// type-specifier type-specifier-seq[opt] 5402f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 5412f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregorbool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) { 5422f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor DS.SetRangeStart(Tok.getLocation()); 5432f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor const char *PrevSpec = 0; 5442f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor int isInvalid = 0; 5452f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 5462f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Parse one or more of the type specifiers. 5472f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor if (!MaybeParseTypeSpecifier(DS, isInvalid, PrevSpec)) { 5481ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_operator_missing_type_specifier); 5492f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return true; 5502f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor } 551b90585c3c65db9ab587674586602729edbd096aaDaniel Dunbar while (MaybeParseTypeSpecifier(DS, isInvalid, PrevSpec)) ; 5522f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 5532f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return false; 5542f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor} 5552f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 55643c7bad105f742988e7ca40564285c83bea854a5Douglas Gregor/// TryParseOperatorFunctionId - Attempts to parse a C++ overloaded 5571cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator name (C++ [over.oper]). If successful, returns the 5581cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// predefined identifier that corresponds to that overloaded 5591cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator. Otherwise, returns NULL and does not consume any tokens. 5601cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// 5611cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator-function-id: [C++ 13.5] 5621cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// 'operator' operator 5631cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// 5641cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator: one of 5651cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// new delete new[] delete[] 5661cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// + - * / % ^ & | ~ 5671cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// ! = < > += -= *= /= %= 5681cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// ^= &= |= << >> >>= <<= == != 5691cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// <= >= && || ++ -- , ->* -> 5701cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// () [] 571e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas GregorOverloadedOperatorKind Parser::TryParseOperatorFunctionId() { 5729057a81efaf15c543aab1c5c8488e8a9ed2c0ff4Argyrios Kyrtzidis assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); 5731cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5741cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor OverloadedOperatorKind Op = OO_None; 5751cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor switch (NextToken().getKind()) { 5761cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::kw_new: 5771cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 5781cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'new' 5791cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor if (Tok.is(tok::l_square)) { 5801cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeBracket(); // '[' 5811cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 5821cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_Array_New; 5831cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } else { 5841cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_New; 5851cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } 586e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return Op; 5871cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5881cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::kw_delete: 5891cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 5901cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'delete' 5911cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor if (Tok.is(tok::l_square)) { 5921cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeBracket(); // '[' 5931cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 5941cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_Array_Delete; 5951cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } else { 5961cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_Delete; 5971cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } 598e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return Op; 5991cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 60002bcd4cd1a19121da12884aa4943226f72a81e6cDouglas Gregor#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 6011cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::Token: Op = OO_##Name; break; 60202bcd4cd1a19121da12884aa4943226f72a81e6cDouglas Gregor#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) 6031cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor#include "clang/Basic/OperatorKinds.def" 6041cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 6051cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::l_paren: 6061cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 6071cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeParen(); // '(' 6081cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_paren, diag::err_expected_rparen); // ')' 609e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return OO_Call; 6101cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 6111cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::l_square: 6121cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 6131cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeBracket(); // '[' 6141cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 615e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return OO_Subscript; 6161cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 6171cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor default: 618e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return OO_None; 6191cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } 62043c7bad105f742988e7ca40564285c83bea854a5Douglas Gregor 62143c7bad105f742988e7ca40564285c83bea854a5Douglas Gregor ConsumeToken(); // 'operator' 62243c7bad105f742988e7ca40564285c83bea854a5Douglas Gregor ConsumeAnyToken(); // the operator itself 623e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return Op; 6241cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor} 6252f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 6262f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// ParseConversionFunctionId - Parse a C++ conversion-function-id, 6272f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// which expresses the name of a user-defined conversion operator 6282f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// (C++ [class.conv.fct]p1). Returns the type that this operator is 6292f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// specifying a conversion for, or NULL if there was an error. 6302f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 6312f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// conversion-function-id: [C++ 12.3.2] 6322f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// operator conversion-type-id 6332f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 6342f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// conversion-type-id: 6352f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// type-specifier-seq conversion-declarator[opt] 6362f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 6372f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// conversion-declarator: 6382f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// ptr-operator conversion-declarator[opt] 6392f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas GregorParser::TypeTy *Parser::ParseConversionFunctionId() { 6402f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); 6412f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor ConsumeToken(); // 'operator' 6422f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 6432f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Parse the type-specifier-seq. 6442f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor DeclSpec DS; 6452f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor if (ParseCXXTypeSpecifierSeq(DS)) 6462f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return 0; 6472f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 6482f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Parse the conversion-declarator, which is merely a sequence of 6492f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // ptr-operators. 6502f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor Declarator D(DS, Declarator::TypeNameContext); 6514c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParseDeclaratorInternal(D, /*DirectDeclParser=*/0); 6522f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 6532f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Finish up the type. 6542f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor Action::TypeResult Result = Actions.ActOnTypeName(CurScope, D); 6552f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor if (Result.isInvalid) 6562f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return 0; 6572f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor else 6582f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return Result.Val; 6592f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor} 6604c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6614c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate 6624c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// memory in a typesafe manner and call constructors. 66359232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// 66459232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// This method is called to parse the new expression after the optional :: has 66559232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// been already parsed. If the :: was present, "UseGlobal" is true and "Start" 66659232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// is its location. Otherwise, "Start" is the location of the 'new' token. 6674c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 6684c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-expression: 6694c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'new' new-placement[opt] new-type-id 6704c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer[opt] 6714c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 6724c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer[opt] 6734c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 6744c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-placement: 6754c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '(' expression-list ')' 6764c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 677cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// new-type-id: 678cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// type-specifier-seq new-declarator[opt] 679cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// 680cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// new-declarator: 681cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// ptr-operator new-declarator[opt] 682cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// direct-new-declarator 683cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// 6844c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer: 6854c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '(' expression-list[opt] ')' 6864c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// [C++0x] braced-init-list [TODO] 6874c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 68859232d35f5820e334b6c8b007ae8006f4390055dChris LattnerParser::OwningExprResult 68959232d35f5820e334b6c8b007ae8006f4390055dChris LattnerParser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { 69059232d35f5820e334b6c8b007ae8006f4390055dChris Lattner assert(Tok.is(tok::kw_new) && "expected 'new' token"); 69159232d35f5820e334b6c8b007ae8006f4390055dChris Lattner ConsumeToken(); // Consume 'new' 6924c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6934c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // A '(' now can be a new-placement or the '(' wrapping the type-id in the 6944c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // second form of new-expression. It can't be a new-type-id. 6954c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 696a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector PlacementArgs(Actions); 6974c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation PlacementLParen, PlacementRParen; 6984c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6994c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool ParenTypeId; 700cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl DeclSpec DS; 701cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 7024c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_paren)) { 7034c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // If it turns out to be a placement, we change the type location. 7044c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl PlacementLParen = ConsumeParen(); 705cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) { 706cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 70720df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 708cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 7094c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7104c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl PlacementRParen = MatchRHSPunctuation(tok::r_paren, PlacementLParen); 711cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (PlacementRParen.isInvalid()) { 712cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 71320df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 714cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 7154c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 716cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (PlacementArgs.empty()) { 7174c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Reset the placement locations. There was no placement. 7184c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl PlacementLParen = PlacementRParen = SourceLocation(); 7194c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParenTypeId = true; 7204c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } else { 7214c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // We still need the type. 7224c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_paren)) { 723cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SourceLocation LParen = ConsumeParen(); 724cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseSpecifierQualifierList(DS); 725cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclarator(DeclaratorInfo); 726cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl MatchRHSPunctuation(tok::r_paren, LParen); 7274c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParenTypeId = true; 7284c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } else { 729cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseCXXTypeSpecifierSeq(DS)) 730cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl DeclaratorInfo.setInvalidType(true); 731cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl else 732cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclaratorInternal(DeclaratorInfo, 733cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl &Parser::ParseDirectNewDeclarator); 7344c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParenTypeId = false; 7354c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7364c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7374c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } else { 738cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl // A new-type-id is a simplified type-id, where essentially the 739cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl // direct-declarator is replaced by a direct-new-declarator. 740cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseCXXTypeSpecifierSeq(DS)) 741cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl DeclaratorInfo.setInvalidType(true); 742cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl else 743cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclaratorInternal(DeclaratorInfo, 744cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl &Parser::ParseDirectNewDeclarator); 7454c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParenTypeId = false; 7464c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 747cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (DeclaratorInfo.getInvalidType()) { 748cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 74920df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 750cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 7514c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 752a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector ConstructorArgs(Actions); 7534c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation ConstructorLParen, ConstructorRParen; 7544c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7554c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_paren)) { 7564c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ConstructorLParen = ConsumeParen(); 7574c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.isNot(tok::r_paren)) { 7584c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl CommaLocsTy CommaLocs; 759cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseExpressionList(ConstructorArgs, CommaLocs)) { 760cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 76120df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 762cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 7634c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7644c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ConstructorRParen = MatchRHSPunctuation(tok::r_paren, ConstructorLParen); 765cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ConstructorRParen.isInvalid()) { 766cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 76720df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 768cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 7694c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7704c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 77120df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen, 77220df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl PlacementArgs.take(), PlacementArgs.size(), 77320df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl PlacementRParen, ParenTypeId, DeclaratorInfo, 77420df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl ConstructorLParen, ConstructorArgs.take(), 77520df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl ConstructorArgs.size(), ConstructorRParen)); 7764c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 7774c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7784c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be 7794c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// passed to ParseDeclaratorInternal. 7804c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 7814c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// direct-new-declarator: 7824c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '[' expression ']' 7834c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// direct-new-declarator '[' constant-expression ']' 7844c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 78559232d35f5820e334b6c8b007ae8006f4390055dChris Lattnervoid Parser::ParseDirectNewDeclarator(Declarator &D) { 7864c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Parse the array dimensions. 7874c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool first = true; 7884c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl while (Tok.is(tok::l_square)) { 7894c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation LLoc = ConsumeBracket(); 7902f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl OwningExprResult Size(first ? ParseExpression() 7912f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl : ParseConstantExpression()); 7920e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Size.isInvalid()) { 7934c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Recover 7944c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SkipUntil(tok::r_square); 7954c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return; 7964c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7974c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl first = false; 7984c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7994c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false, 800effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl Size.release(), LLoc)); 8014c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8024c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (MatchRHSPunctuation(tok::r_square, LLoc).isInvalid()) 8034c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return; 8044c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 8054c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 8064c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8074c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id. 8084c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// This ambiguity appears in the syntax of the C++ new operator. 8094c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 8104c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-expression: 8114c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 8124c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer[opt] 8134c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 8144c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-placement: 8154c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '(' expression-list ')' 8164c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 817cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redlbool Parser::ParseExpressionListOrTypeId(ExprListTy &PlacementArgs, 81859232d35f5820e334b6c8b007ae8006f4390055dChris Lattner Declarator &D) { 8194c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // The '(' was already consumed. 8204c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (isTypeIdInParens()) { 821cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseSpecifierQualifierList(D.getMutableDeclSpec()); 822cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclarator(D); 823cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl return D.getInvalidType(); 8244c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 8254c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8264c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // It's not a type, it has to be an expression list. 8274c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Discard the comma locations - ActOnCXXNew has enough parameters. 8284c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl CommaLocsTy CommaLocs; 8294c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return ParseExpressionList(PlacementArgs, CommaLocs); 8304c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 8314c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8324c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used 8334c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// to free memory allocated by new. 8344c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 83559232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// This method is called to parse the 'delete' expression after the optional 83659232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// '::' has been already parsed. If the '::' was present, "UseGlobal" is true 83759232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// and "Start" is its location. Otherwise, "Start" is the location of the 83859232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// 'delete' token. 83959232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// 8404c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// delete-expression: 8414c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'delete' cast-expression 8424c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'delete' '[' ']' cast-expression 84359232d35f5820e334b6c8b007ae8006f4390055dChris LattnerParser::OwningExprResult 84459232d35f5820e334b6c8b007ae8006f4390055dChris LattnerParser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) { 84559232d35f5820e334b6c8b007ae8006f4390055dChris Lattner assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword"); 84659232d35f5820e334b6c8b007ae8006f4390055dChris Lattner ConsumeToken(); // Consume 'delete' 8474c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8484c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Array delete? 8494c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool ArrayDelete = false; 8504c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_square)) { 8514c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ArrayDelete = true; 8524c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation LHS = ConsumeBracket(); 8534c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation RHS = MatchRHSPunctuation(tok::r_square, LHS); 8544c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (RHS.isInvalid()) 85520df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 8564c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 8574c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8582f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl OwningExprResult Operand(ParseCastExpression(false)); 8590e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Operand.isInvalid()) 86020df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return move(Operand); 8614c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 86220df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, 86320df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl Operand.release())); 8644c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 865