ParseExprCXX.cpp revision 357089dea05855e27f80f6f244f9c60fc77cee83
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) { 50a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner // Pre-parsed '::'. 51a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner SS.setBeginLoc(GlobalQualifier->getLocation()); 52a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, 53a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner GlobalQualifier->getLocation())); 54a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner SS.setEndLoc(GlobalQualifier->getLocation()); 5555a7cefc846765ac7d142a63f773747a20518d71Chris Lattner 5655a7cefc846765ac7d142a63f773747a20518d71Chris Lattner assert(Tok.isNot(tok::kw_new) && Tok.isNot(tok::kw_delete) && 5755a7cefc846765ac7d142a63f773747a20518d71Chris Lattner "Never called with preparsed :: qualifier and with new/delete"); 58357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner } else if (Tok.is(tok::coloncolon)) { 5955a7cefc846765ac7d142a63f773747a20518d71Chris Lattner // '::' - Global scope qualifier. 60357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner SourceLocation CCLoc = ConsumeToken(); 6155a7cefc846765ac7d142a63f773747a20518d71Chris Lattner 62357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner // ::new and ::delete aren't nested-name-specifiers, and 63357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner // MaybeParseCXXScopeSpecifier is never called in a context where one 64357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner // could exist. This means that if we see it, we have a syntax error. 65357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner if (Tok.is(tok::kw_new) || Tok.is(tok::kw_delete)) { 66357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner Diag(Tok, diag::err_invalid_qualified_new_delete) 67357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner << Tok.is(tok::kw_delete); 68357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner return false; 69a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner } 70357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner 71357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner SS.setBeginLoc(CCLoc); 72357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc)); 73357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner SS.setEndLoc(CCLoc); 74357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner } else if (Tok.is(tok::identifier) && NextToken().is(tok::coloncolon)) { 75357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner SS.setBeginLoc(Tok.getLocation()); 76357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner } else { 77357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner // Not a CXXScopeSpecifier. 78357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner return false; 79eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 80eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 81eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // nested-name-specifier: 82eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // type-name '::' 83eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // namespace-name '::' 84eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // nested-name-specifier identifier '::' 85eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // nested-name-specifier 'template'[opt] simple-template-id '::' [TODO] 86eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis while (Tok.is(tok::identifier) && NextToken().is(tok::coloncolon)) { 87eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis IdentifierInfo *II = Tok.getIdentifierInfo(); 88eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation IdLoc = ConsumeToken(); 89e607e808c2b90724a2a6fd841e850f07de1f5b30Chris Lattner assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!"); 90eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation CCLoc = ConsumeToken(); 91eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis if (SS.isInvalid()) 92eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis continue; 93eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 94eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setScopeRep( 95e607e808c2b90724a2a6fd841e850f07de1f5b30Chris Lattner Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, IdLoc, CCLoc, *II)); 96eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setEndLoc(CCLoc); 97eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 984bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis 994bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis return true; 100eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis} 101eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 102eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// ParseCXXIdExpression - Handle id-expression. 103eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 104eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// id-expression: 105eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// unqualified-id 106eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// qualified-id 107eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 108eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// unqualified-id: 109eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// identifier 110eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// operator-function-id 111eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// conversion-function-id [TODO] 112eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '~' class-name [TODO] 113eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// template-id [TODO] 114eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 115eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// qualified-id: 116eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 117eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' identifier 118eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' operator-function-id 119eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' template-id [TODO] 120eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 121eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier: 122eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// type-name '::' 123eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// namespace-name '::' 124eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier identifier '::' 125eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier 'template'[opt] simple-template-id '::' [TODO] 126eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 127eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// NOTE: The standard specifies that, for qualified-id, the parser does not 128eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// expect: 129eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 130eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' conversion-function-id 131eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' '~' class-name 132eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 133eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// This may cause a slight inconsistency on diagnostics: 134eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 135eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// class C {}; 136eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// namespace A {} 137eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// void f() { 138eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// :: A :: ~ C(); // Some Sema error about using destructor with a 139eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// // namespace. 140eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// :: ~ C(); // Some Parser error like 'unexpected ~'. 141eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// } 142eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 143eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// We simplify the parser a bit and make it work like: 144eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 145eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// qualified-id: 146eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 147eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' unqualified-id 148eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 149eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// That way Sema can handle and report similar errors for namespaces and the 150eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// global scope. 151eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 15220df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult Parser::ParseCXXIdExpression() { 153eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // qualified-id: 154eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 155eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // '::' unqualified-id 156eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // 157eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis CXXScopeSpec SS; 1584bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis MaybeParseCXXScopeSpecifier(SS); 159eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 160eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // unqualified-id: 161eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // identifier 162eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // operator-function-id 1632def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor // conversion-function-id 164eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // '~' class-name [TODO] 165eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // template-id [TODO] 166eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // 167eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis switch (Tok.getKind()) { 168eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis default: 16920df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(Diag(Tok, diag::err_expected_unqualified_id)); 170eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 171eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis case tok::identifier: { 172eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // Consume the identifier so that we can see if it is followed by a '('. 173eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis IdentifierInfo &II = *Tok.getIdentifierInfo(); 174eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation L = ConsumeToken(); 17520df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnIdentifierExpr(CurScope, L, II, 17620df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl Tok.is(tok::l_paren), &SS)); 177eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 178eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 179eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis case tok::kw_operator: { 180eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation OperatorLoc = Tok.getLocation(); 1817452c6fc567ea1799f617395d0fa4c7ed075e5d9Chris Lattner if (OverloadedOperatorKind Op = TryParseOperatorFunctionId()) 18220df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXOperatorFunctionIdExpr( 18320df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl CurScope, OperatorLoc, Op, Tok.is(tok::l_paren), SS)); 1847452c6fc567ea1799f617395d0fa4c7ed075e5d9Chris Lattner if (TypeTy *Type = ParseConversionFunctionId()) 1857452c6fc567ea1799f617395d0fa4c7ed075e5d9Chris Lattner return Owned(Actions.ActOnCXXConversionFunctionExpr(CurScope, OperatorLoc, 1867452c6fc567ea1799f617395d0fa4c7ed075e5d9Chris Lattner Type, 1877452c6fc567ea1799f617395d0fa4c7ed075e5d9Chris Lattner Tok.is(tok::l_paren), SS)); 18820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl 1892def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor // We already complained about a bad conversion-function-id, 1902def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor // above. 19120df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 192eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 193eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 194eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } // switch. 195eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 196eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis assert(0 && "The switch was supposed to take care everything."); 197eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis} 198eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 1995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCXXCasts - This handles the various ways to cast expressions to another 2005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// type. 2015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 2025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// postfix-expression: [C++ 5.2p1] 2035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'dynamic_cast' '<' type-name '>' '(' expression ')' 2045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'static_cast' '<' type-name '>' '(' expression ')' 2055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'reinterpret_cast' '<' type-name '>' '(' expression ')' 2065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'const_cast' '<' type-name '>' '(' expression ')' 2075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 20820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult Parser::ParseCXXCasts() { 2095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer tok::TokenKind Kind = Tok.getKind(); 2105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const char *CastName = 0; // For error messages 2115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer switch (Kind) { 2135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer default: assert(0 && "Unknown C++ cast!"); abort(); 2145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_const_cast: CastName = "const_cast"; break; 2155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_dynamic_cast: CastName = "dynamic_cast"; break; 2165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break; 2175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_static_cast: CastName = "static_cast"; break; 2185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation OpLoc = ConsumeToken(); 2215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation LAngleBracketLoc = Tok.getLocation(); 2225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName)) 22420df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 2255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer TypeTy *CastTy = ParseTypeName(); 2275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation RAngleBracketLoc = Tok.getLocation(); 2285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2291ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner if (ExpectAndConsume(tok::greater, diag::err_expected_greater)) 23020df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << "<"); 2315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation LParenLoc = Tok.getLocation(), RParenLoc; 2335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2341ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner if (Tok.isNot(tok::l_paren)) 23520df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(Diag(Tok, diag::err_expected_lparen_after) << CastName); 2365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 237d8c4e15138e69a51754cc259c8a592cc47950c8eSebastian Redl OwningExprResult Result(ParseSimpleParenExpression(RParenLoc)); 2385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2390e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (!Result.isInvalid()) 24049badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor Result = Actions.ActOnCXXNamedCast(OpLoc, Kind, 24149badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor LAngleBracketLoc, CastTy, RAngleBracketLoc, 242effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl LParenLoc, Result.release(), RParenLoc); 2435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 24420df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return move(Result); 2455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 2465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 247c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// ParseCXXTypeid - This handles the C++ typeid expression. 248c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 249c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// postfix-expression: [C++ 5.2p1] 250c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 'typeid' '(' expression ')' 251c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 'typeid' '(' type-id ')' 252c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 25320df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult Parser::ParseCXXTypeid() { 254c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!"); 255c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 256c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SourceLocation OpLoc = ConsumeToken(); 257c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SourceLocation LParenLoc = Tok.getLocation(); 258c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SourceLocation RParenLoc; 259c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 260c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl // typeid expressions are always parenthesized. 261c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, 262c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl "typeid")) 26320df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 264c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 26515faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult Result(Actions); 266c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 267c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl if (isTypeIdInParens()) { 268c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl TypeTy *Ty = ParseTypeName(); 269c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 270c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl // Match the ')'. 271c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl MatchRHSPunctuation(tok::r_paren, LParenLoc); 272c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 273c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl if (!Ty) 27420df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 275c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 276c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true, 277c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Ty, RParenLoc); 278c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl } else { 279c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Result = ParseExpression(); 280c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 281c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl // Match the ')'. 2820e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Result.isInvalid()) 283c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SkipUntil(tok::r_paren); 284c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl else { 285c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl MatchRHSPunctuation(tok::r_paren, LParenLoc); 286c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 287c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false, 288effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl Result.release(), RParenLoc); 289c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl } 290c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl } 291c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 29220df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return move(Result); 293c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl} 294c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 2955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCXXBoolLiteral - This handles the C++ Boolean literals. 2965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 2975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// boolean-literal: [C++ 2.13.5] 2985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'true' 2995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'false' 30020df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult Parser::ParseCXXBoolLiteral() { 3015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer tok::TokenKind Kind = Tok.getKind(); 30220df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind)); 3035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 30450dd289f45738ed22b7583d52ed2525b927042ffChris Lattner 30550dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// ParseThrowExpression - This handles the C++ throw expression. 30650dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// 30750dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// throw-expression: [C++ 15] 30850dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// 'throw' assignment-expression[opt] 30920df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult Parser::ParseThrowExpression() { 31050dd289f45738ed22b7583d52ed2525b927042ffChris Lattner assert(Tok.is(tok::kw_throw) && "Not throw!"); 31150dd289f45738ed22b7583d52ed2525b927042ffChris Lattner SourceLocation ThrowLoc = ConsumeToken(); // Eat the throw token. 31220df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl 3132a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // If the current token isn't the start of an assignment-expression, 3142a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // then the expression is not present. This handles things like: 3152a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // "C ? throw : (void)42", which is crazy but legal. 3162a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner switch (Tok.getKind()) { // FIXME: move this predicate somewhere common. 3172a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::semi: 3182a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_paren: 3192a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_square: 3202a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_brace: 3212a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::colon: 3222a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::comma: 32320df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXThrow(ThrowLoc)); 32450dd289f45738ed22b7583d52ed2525b927042ffChris Lattner 3252a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner default: 3262f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl OwningExprResult Expr(ParseAssignmentExpression()); 32720df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl if (Expr.isInvalid()) return move(Expr); 32820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXThrow(ThrowLoc, Expr.release())); 3292a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner } 33050dd289f45738ed22b7583d52ed2525b927042ffChris Lattner} 3314cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 3324cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXThis - This handles the C++ 'this' pointer. 3334cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 3344cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// C++ 9.3.2: In the body of a non-static member function, the keyword this is 3354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// a non-lvalue expression whose value is the address of the object for which 3364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// the function is called. 33720df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult Parser::ParseCXXThis() { 3384cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis assert(Tok.is(tok::kw_this) && "Not 'this'!"); 3394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SourceLocation ThisLoc = ConsumeToken(); 34020df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXThis(ThisLoc)); 3414cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 342987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 343987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// ParseCXXTypeConstructExpression - Parse construction of a specified type. 344987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// Can be interpreted either as function-style casting ("int(x)") 345987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// or class type construction ("ClassType(x,y,z)") 346987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// or creation of a value-initialized type ("int()"). 347987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 348987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// postfix-expression: [C++ 5.2p1] 349987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3] 350987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// typename-specifier '(' expression-list[opt] ')' [TODO] 351987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 35220df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult 35320df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { 354987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 355987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis TypeTy *TypeRep = Actions.ActOnTypeName(CurScope, DeclaratorInfo).Val; 356987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 357987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis assert(Tok.is(tok::l_paren) && "Expected '('!"); 358987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SourceLocation LParenLoc = ConsumeParen(); 359987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 360a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector Exprs(Actions); 361987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis CommaLocsTy CommaLocs; 362987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 363987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis if (Tok.isNot(tok::r_paren)) { 364987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis if (ParseExpressionList(Exprs, CommaLocs)) { 365987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SkipUntil(tok::r_paren); 36620df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 367987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 368987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 369987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 370987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // Match the ')'. 371987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 372987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 373987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&& 374987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis "Unexpected number of commas!"); 37520df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXTypeConstructExpr(DS.getSourceRange(), TypeRep, 37620df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl LParenLoc, 37720df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl Exprs.take(), Exprs.size(), 37820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl &CommaLocs[0], RParenLoc)); 379987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis} 380987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 38171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// ParseCXXCondition - if/switch/while/for condition expression. 38271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// 38371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// condition: 38471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// expression 38571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// type-specifier-seq declarator '=' assignment-expression 38671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 38771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// '=' assignment-expression 38871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// 3892f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian RedlParser::OwningExprResult Parser::ParseCXXCondition() { 390a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis if (!isCXXConditionDeclaration()) 39171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis return ParseExpression(); // expression 39271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 39371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SourceLocation StartLoc = Tok.getLocation(); 39471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 39571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // type-specifier-seq 39671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis DeclSpec DS; 39771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis ParseSpecifierQualifierList(DS); 39871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 39971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // declarator 40071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::ConditionContext); 40171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 40271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 40371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // simple-asm-expr[opt] 40471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (Tok.is(tok::kw_asm)) { 405effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl OwningExprResult AsmLabel(ParseSimpleAsm()); 4060e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (AsmLabel.isInvalid()) { 40771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SkipUntil(tok::semi); 4082f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl return ExprError(); 40971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis } 410effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl DeclaratorInfo.setAsmLabel(AsmLabel.release()); 41171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis } 41271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 41371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // If attributes are present, parse them. 41471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (Tok.is(tok::kw___attribute)) 41571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis DeclaratorInfo.AddAttributes(ParseAttributes()); 41671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 41771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // '=' assignment-expression 41871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (Tok.isNot(tok::equal)) 4192f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl return ExprError(Diag(Tok, diag::err_expected_equal_after_declarator)); 42071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SourceLocation EqualLoc = ConsumeToken(); 4212f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl OwningExprResult AssignExpr(ParseAssignmentExpression()); 4220e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (AssignExpr.isInvalid()) 4232f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl return ExprError(); 4242f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl 4252f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl return Owned(Actions.ActOnCXXConditionDeclarationExpr(CurScope, StartLoc, 4262f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl DeclaratorInfo,EqualLoc, 4272f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl AssignExpr.release())); 42871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis} 42971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 430987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers. 431987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// This should only be called when the current token is known to be part of 432987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// simple-type-specifier. 433987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 434987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// simple-type-specifier: 435eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier[opt] type-name 436987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template' simple-template-id [TODO] 437987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// char 438987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// wchar_t 439987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// bool 440987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// short 441987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// int 442987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// long 443987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// signed 444987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// unsigned 445987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// float 446987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// double 447987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// void 448987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// [GNU] typeof-specifier 449987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// [C++0x] auto [TODO] 450987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 451987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// type-name: 452987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// class-name 453987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// enum-name 454987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// typedef-name 455987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 456987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidisvoid Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { 457987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetRangeStart(Tok.getLocation()); 458987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis const char *PrevSpec; 459987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SourceLocation Loc = Tok.getLocation(); 460987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 461987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis switch (Tok.getKind()) { 46255a7cefc846765ac7d142a63f773747a20518d71Chris Lattner case tok::identifier: // foo::bar 46355a7cefc846765ac7d142a63f773747a20518d71Chris Lattner case tok::coloncolon: // ::foo::bar 46455a7cefc846765ac7d142a63f773747a20518d71Chris Lattner assert(0 && "Annotation token should already be formed!"); 465987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis default: 466987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis assert(0 && "Not a simple-type-specifier token!"); 467987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis abort(); 46855a7cefc846765ac7d142a63f773747a20518d71Chris Lattner 469987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // type-name 470eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis case tok::annot_qualtypename: { 471eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec, 472eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis Tok.getAnnotationValue()); 473987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 474987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 475987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 476987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // builtin types 477987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_short: 478987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec); 479987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 480987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_long: 481987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec); 482987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 483987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_signed: 484987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec); 485987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 486987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_unsigned: 487987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec); 488987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 489987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_void: 490987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec); 491987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 492987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_char: 493987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec); 494987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 495987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_int: 496987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec); 497987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 498987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_float: 499987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec); 500987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 501987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_double: 502987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec); 503987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 504987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_wchar_t: 505987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec); 506987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 507987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_bool: 508987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec); 509987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 510987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 511987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // GNU typeof support. 512987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_typeof: 513987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis ParseTypeofSpecifier(DS); 514987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.Finish(Diags, PP.getSourceManager(), getLang()); 515987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis return; 516987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 517eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis if (Tok.is(tok::annot_qualtypename)) 518eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 519eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis else 520eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis DS.SetRangeEnd(Tok.getLocation()); 521987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis ConsumeToken(); 522987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.Finish(Diags, PP.getSourceManager(), getLang()); 523987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis} 5241cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5252f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++ 5262f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// [dcl.name]), which is a non-empty sequence of type-specifiers, 5272f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// e.g., "const short int". Note that the DeclSpec is *not* finished 5282f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// by parsing the type-specifier-seq, because these sequences are 5292f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// typically followed by some form of declarator. Returns true and 5302f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// emits diagnostics if this is not a type-specifier-seq, false 5312f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// otherwise. 5322f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 5332f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// type-specifier-seq: [C++ 8.1] 5342f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// type-specifier type-specifier-seq[opt] 5352f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 5362f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregorbool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) { 5372f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor DS.SetRangeStart(Tok.getLocation()); 5382f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor const char *PrevSpec = 0; 5392f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor int isInvalid = 0; 5402f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 5412f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Parse one or more of the type specifiers. 5422f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor if (!MaybeParseTypeSpecifier(DS, isInvalid, PrevSpec)) { 5431ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_operator_missing_type_specifier); 5442f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return true; 5452f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor } 546b90585c3c65db9ab587674586602729edbd096aaDaniel Dunbar while (MaybeParseTypeSpecifier(DS, isInvalid, PrevSpec)) ; 5472f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 5482f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return false; 5492f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor} 5502f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 55143c7bad105f742988e7ca40564285c83bea854a5Douglas Gregor/// TryParseOperatorFunctionId - Attempts to parse a C++ overloaded 5521cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator name (C++ [over.oper]). If successful, returns the 5531cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// predefined identifier that corresponds to that overloaded 5541cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator. Otherwise, returns NULL and does not consume any tokens. 5551cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// 5561cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator-function-id: [C++ 13.5] 5571cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// 'operator' operator 5581cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// 5591cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator: one of 5601cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// new delete new[] delete[] 5611cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// + - * / % ^ & | ~ 5621cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// ! = < > += -= *= /= %= 5631cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// ^= &= |= << >> >>= <<= == != 5641cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// <= >= && || ++ -- , ->* -> 5651cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// () [] 566e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas GregorOverloadedOperatorKind Parser::TryParseOperatorFunctionId() { 5679057a81efaf15c543aab1c5c8488e8a9ed2c0ff4Argyrios Kyrtzidis assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); 5681cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5691cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor OverloadedOperatorKind Op = OO_None; 5701cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor switch (NextToken().getKind()) { 5711cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::kw_new: 5721cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 5731cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'new' 5741cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor if (Tok.is(tok::l_square)) { 5751cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeBracket(); // '[' 5761cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 5771cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_Array_New; 5781cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } else { 5791cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_New; 5801cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } 581e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return Op; 5821cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5831cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::kw_delete: 5841cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 5851cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'delete' 5861cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor if (Tok.is(tok::l_square)) { 5871cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeBracket(); // '[' 5881cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 5891cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_Array_Delete; 5901cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } else { 5911cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_Delete; 5921cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } 593e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return Op; 5941cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 59502bcd4cd1a19121da12884aa4943226f72a81e6cDouglas Gregor#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 5961cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::Token: Op = OO_##Name; break; 59702bcd4cd1a19121da12884aa4943226f72a81e6cDouglas Gregor#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) 5981cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor#include "clang/Basic/OperatorKinds.def" 5991cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 6001cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::l_paren: 6011cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 6021cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeParen(); // '(' 6031cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_paren, diag::err_expected_rparen); // ')' 604e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return OO_Call; 6051cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 6061cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::l_square: 6071cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 6081cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeBracket(); // '[' 6091cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 610e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return OO_Subscript; 6111cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 6121cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor default: 613e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return OO_None; 6141cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } 61543c7bad105f742988e7ca40564285c83bea854a5Douglas Gregor 61643c7bad105f742988e7ca40564285c83bea854a5Douglas Gregor ConsumeToken(); // 'operator' 61743c7bad105f742988e7ca40564285c83bea854a5Douglas Gregor ConsumeAnyToken(); // the operator itself 618e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return Op; 6191cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor} 6202f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 6212f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// ParseConversionFunctionId - Parse a C++ conversion-function-id, 6222f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// which expresses the name of a user-defined conversion operator 6232f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// (C++ [class.conv.fct]p1). Returns the type that this operator is 6242f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// specifying a conversion for, or NULL if there was an error. 6252f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 6262f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// conversion-function-id: [C++ 12.3.2] 6272f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// operator conversion-type-id 6282f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 6292f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// conversion-type-id: 6302f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// type-specifier-seq conversion-declarator[opt] 6312f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 6322f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// conversion-declarator: 6332f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// ptr-operator conversion-declarator[opt] 6342f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas GregorParser::TypeTy *Parser::ParseConversionFunctionId() { 6352f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); 6362f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor ConsumeToken(); // 'operator' 6372f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 6382f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Parse the type-specifier-seq. 6392f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor DeclSpec DS; 6402f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor if (ParseCXXTypeSpecifierSeq(DS)) 6412f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return 0; 6422f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 6432f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Parse the conversion-declarator, which is merely a sequence of 6442f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // ptr-operators. 6452f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor Declarator D(DS, Declarator::TypeNameContext); 6464c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParseDeclaratorInternal(D, /*DirectDeclParser=*/0); 6472f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 6482f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Finish up the type. 6492f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor Action::TypeResult Result = Actions.ActOnTypeName(CurScope, D); 6502f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor if (Result.isInvalid) 6512f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return 0; 6522f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor else 6532f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return Result.Val; 6542f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor} 6554c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6564c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate 6574c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// memory in a typesafe manner and call constructors. 65859232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// 65959232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// This method is called to parse the new expression after the optional :: has 66059232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// been already parsed. If the :: was present, "UseGlobal" is true and "Start" 66159232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// is its location. Otherwise, "Start" is the location of the 'new' token. 6624c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 6634c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-expression: 6644c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'new' new-placement[opt] new-type-id 6654c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer[opt] 6664c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 6674c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer[opt] 6684c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 6694c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-placement: 6704c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '(' expression-list ')' 6714c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 672cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// new-type-id: 673cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// type-specifier-seq new-declarator[opt] 674cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// 675cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// new-declarator: 676cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// ptr-operator new-declarator[opt] 677cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// direct-new-declarator 678cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// 6794c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer: 6804c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '(' expression-list[opt] ')' 6814c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// [C++0x] braced-init-list [TODO] 6824c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 68359232d35f5820e334b6c8b007ae8006f4390055dChris LattnerParser::OwningExprResult 68459232d35f5820e334b6c8b007ae8006f4390055dChris LattnerParser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { 68559232d35f5820e334b6c8b007ae8006f4390055dChris Lattner assert(Tok.is(tok::kw_new) && "expected 'new' token"); 68659232d35f5820e334b6c8b007ae8006f4390055dChris Lattner ConsumeToken(); // Consume 'new' 6874c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6884c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // A '(' now can be a new-placement or the '(' wrapping the type-id in the 6894c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // second form of new-expression. It can't be a new-type-id. 6904c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 691a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector PlacementArgs(Actions); 6924c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation PlacementLParen, PlacementRParen; 6934c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6944c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool ParenTypeId; 695cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl DeclSpec DS; 696cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 6974c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_paren)) { 6984c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // If it turns out to be a placement, we change the type location. 6994c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl PlacementLParen = ConsumeParen(); 700cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) { 701cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 70220df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 703cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 7044c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7054c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl PlacementRParen = MatchRHSPunctuation(tok::r_paren, PlacementLParen); 706cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (PlacementRParen.isInvalid()) { 707cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 70820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 709cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 7104c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 711cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (PlacementArgs.empty()) { 7124c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Reset the placement locations. There was no placement. 7134c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl PlacementLParen = PlacementRParen = SourceLocation(); 7144c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParenTypeId = true; 7154c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } else { 7164c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // We still need the type. 7174c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_paren)) { 718cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SourceLocation LParen = ConsumeParen(); 719cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseSpecifierQualifierList(DS); 720cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclarator(DeclaratorInfo); 721cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl MatchRHSPunctuation(tok::r_paren, LParen); 7224c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParenTypeId = true; 7234c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } else { 724cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseCXXTypeSpecifierSeq(DS)) 725cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl DeclaratorInfo.setInvalidType(true); 726cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl else 727cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclaratorInternal(DeclaratorInfo, 728cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl &Parser::ParseDirectNewDeclarator); 7294c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParenTypeId = false; 7304c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7314c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7324c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } else { 733cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl // A new-type-id is a simplified type-id, where essentially the 734cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl // direct-declarator is replaced by a direct-new-declarator. 735cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseCXXTypeSpecifierSeq(DS)) 736cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl DeclaratorInfo.setInvalidType(true); 737cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl else 738cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclaratorInternal(DeclaratorInfo, 739cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl &Parser::ParseDirectNewDeclarator); 7404c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParenTypeId = false; 7414c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 742cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (DeclaratorInfo.getInvalidType()) { 743cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 74420df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 745cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 7464c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 747a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector ConstructorArgs(Actions); 7484c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation ConstructorLParen, ConstructorRParen; 7494c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7504c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_paren)) { 7514c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ConstructorLParen = ConsumeParen(); 7524c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.isNot(tok::r_paren)) { 7534c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl CommaLocsTy CommaLocs; 754cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseExpressionList(ConstructorArgs, CommaLocs)) { 755cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 75620df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 757cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 7584c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7594c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ConstructorRParen = MatchRHSPunctuation(tok::r_paren, ConstructorLParen); 760cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ConstructorRParen.isInvalid()) { 761cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 76220df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 763cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 7644c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7654c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 76620df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen, 76720df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl PlacementArgs.take(), PlacementArgs.size(), 76820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl PlacementRParen, ParenTypeId, DeclaratorInfo, 76920df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl ConstructorLParen, ConstructorArgs.take(), 77020df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl ConstructorArgs.size(), ConstructorRParen)); 7714c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 7724c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7734c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be 7744c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// passed to ParseDeclaratorInternal. 7754c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 7764c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// direct-new-declarator: 7774c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '[' expression ']' 7784c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// direct-new-declarator '[' constant-expression ']' 7794c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 78059232d35f5820e334b6c8b007ae8006f4390055dChris Lattnervoid Parser::ParseDirectNewDeclarator(Declarator &D) { 7814c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Parse the array dimensions. 7824c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool first = true; 7834c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl while (Tok.is(tok::l_square)) { 7844c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation LLoc = ConsumeBracket(); 7852f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl OwningExprResult Size(first ? ParseExpression() 7862f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl : ParseConstantExpression()); 7870e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Size.isInvalid()) { 7884c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Recover 7894c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SkipUntil(tok::r_square); 7904c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return; 7914c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7924c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl first = false; 7934c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7944c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false, 795effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl Size.release(), LLoc)); 7964c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7974c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (MatchRHSPunctuation(tok::r_square, LLoc).isInvalid()) 7984c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return; 7994c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 8004c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 8014c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8024c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id. 8034c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// This ambiguity appears in the syntax of the C++ new operator. 8044c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 8054c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-expression: 8064c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 8074c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer[opt] 8084c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 8094c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-placement: 8104c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '(' expression-list ')' 8114c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 812cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redlbool Parser::ParseExpressionListOrTypeId(ExprListTy &PlacementArgs, 81359232d35f5820e334b6c8b007ae8006f4390055dChris Lattner Declarator &D) { 8144c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // The '(' was already consumed. 8154c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (isTypeIdInParens()) { 816cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseSpecifierQualifierList(D.getMutableDeclSpec()); 817cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclarator(D); 818cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl return D.getInvalidType(); 8194c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 8204c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8214c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // It's not a type, it has to be an expression list. 8224c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Discard the comma locations - ActOnCXXNew has enough parameters. 8234c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl CommaLocsTy CommaLocs; 8244c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return ParseExpressionList(PlacementArgs, CommaLocs); 8254c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 8264c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8274c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used 8284c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// to free memory allocated by new. 8294c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 83059232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// This method is called to parse the 'delete' expression after the optional 83159232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// '::' has been already parsed. If the '::' was present, "UseGlobal" is true 83259232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// and "Start" is its location. Otherwise, "Start" is the location of the 83359232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// 'delete' token. 83459232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// 8354c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// delete-expression: 8364c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'delete' cast-expression 8374c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'delete' '[' ']' cast-expression 83859232d35f5820e334b6c8b007ae8006f4390055dChris LattnerParser::OwningExprResult 83959232d35f5820e334b6c8b007ae8006f4390055dChris LattnerParser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) { 84059232d35f5820e334b6c8b007ae8006f4390055dChris Lattner assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword"); 84159232d35f5820e334b6c8b007ae8006f4390055dChris Lattner ConsumeToken(); // Consume 'delete' 8424c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8434c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Array delete? 8444c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool ArrayDelete = false; 8454c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_square)) { 8464c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ArrayDelete = true; 8474c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation LHS = ConsumeBracket(); 8484c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation RHS = MatchRHSPunctuation(tok::r_square, LHS); 8494c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (RHS.isInvalid()) 85020df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 8514c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 8524c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8532f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl OwningExprResult Operand(ParseCastExpression(false)); 8540e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Operand.isInvalid()) 85520df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return move(Operand); 8564c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 85720df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, 85820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl Operand.release())); 8594c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 860