ParseExprCXX.cpp revision a7bc7c880f86bc180684ef032d06df51bcae7a23
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. 22eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 23eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier 24eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' 25eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 26eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier: 27eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// type-name '::' 28eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// namespace-name '::' 29eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier identifier '::' 30eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier 'template'[opt] simple-template-id '::' [TODO] 31eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 32a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattnerbool Parser::MaybeParseCXXScopeSpecifier(CXXScopeSpec &SS, 33a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner const Token *GlobalQualifier) { 344bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis assert(getLang().CPlusPlus && 354bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis "Call sites of this function should be guarded by checking for C++."); 364bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis 37eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis if (Tok.is(tok::annot_cxxscope)) { 38a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner assert(GlobalQualifier == 0 && 39a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner "Cannot have :: followed by a resolve annotation scope"); 40eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setScopeRep(Tok.getAnnotationValue()); 41eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setRange(Tok.getAnnotationRange()); 42eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis ConsumeToken(); 434bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis return true; 44eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 45e607e808c2b90724a2a6fd841e850f07de1f5b30Chris Lattner 46a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner if (GlobalQualifier == 0 && 47a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner Tok.isNot(tok::coloncolon) && 48e607e808c2b90724a2a6fd841e850f07de1f5b30Chris Lattner (Tok.isNot(tok::identifier) || NextToken().isNot(tok::coloncolon))) 49e607e808c2b90724a2a6fd841e850f07de1f5b30Chris Lattner return false; 50e607e808c2b90724a2a6fd841e850f07de1f5b30Chris Lattner 51e607e808c2b90724a2a6fd841e850f07de1f5b30Chris Lattner // ::new and ::delete aren't nested-name-specifiers, so parsing the :: as 52e607e808c2b90724a2a6fd841e850f07de1f5b30Chris Lattner // a scope specifier only makes things more complicated. 53a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner if (GlobalQualifier == 0 && Tok.is(tok::coloncolon)) { 54e607e808c2b90724a2a6fd841e850f07de1f5b30Chris Lattner Token Next = NextToken(); 55e607e808c2b90724a2a6fd841e850f07de1f5b30Chris Lattner if (Next.is(tok::kw_new) || Next.is(tok::kw_delete)) 56e607e808c2b90724a2a6fd841e850f07de1f5b30Chris Lattner return false; 57e607e808c2b90724a2a6fd841e850f07de1f5b30Chris Lattner } 58eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 59a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner if (GlobalQualifier) { 60a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner // Pre-parsed '::'. 61a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner SS.setBeginLoc(GlobalQualifier->getLocation()); 62a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, 63a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner GlobalQualifier->getLocation())); 64a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner SS.setEndLoc(GlobalQualifier->getLocation()); 65a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner } else { 66a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner SS.setBeginLoc(Tok.getLocation()); 67eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 68a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner // '::' 69a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner if (Tok.is(tok::coloncolon)) { 70a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner // Global scope. 71a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner SourceLocation CCLoc = ConsumeToken(); 72a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc)); 73a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner SS.setEndLoc(CCLoc); 74a7bc7c880f86bc180684ef032d06df51bcae7a23Chris Lattner } 75eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 76eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 77eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // nested-name-specifier: 78eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // type-name '::' 79eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // namespace-name '::' 80eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // nested-name-specifier identifier '::' 81eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // nested-name-specifier 'template'[opt] simple-template-id '::' [TODO] 82eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis while (Tok.is(tok::identifier) && NextToken().is(tok::coloncolon)) { 83eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis IdentifierInfo *II = Tok.getIdentifierInfo(); 84eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation IdLoc = ConsumeToken(); 85e607e808c2b90724a2a6fd841e850f07de1f5b30Chris Lattner assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!"); 86eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation CCLoc = ConsumeToken(); 87eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis if (SS.isInvalid()) 88eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis continue; 89eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 90eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setScopeRep( 91e607e808c2b90724a2a6fd841e850f07de1f5b30Chris Lattner Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, IdLoc, CCLoc, *II)); 92eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setEndLoc(CCLoc); 93eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 944bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis 954bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis return true; 96eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis} 97eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 98eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// ParseCXXIdExpression - Handle id-expression. 99eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 100eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// id-expression: 101eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// unqualified-id 102eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// qualified-id 103eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 104eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// unqualified-id: 105eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// identifier 106eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// operator-function-id 107eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// conversion-function-id [TODO] 108eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '~' class-name [TODO] 109eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// template-id [TODO] 110eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 111eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// qualified-id: 112eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 113eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' identifier 114eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' operator-function-id 115eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' template-id [TODO] 116eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 117eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier: 118eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// type-name '::' 119eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// namespace-name '::' 120eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier identifier '::' 121eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier 'template'[opt] simple-template-id '::' [TODO] 122eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 123eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// NOTE: The standard specifies that, for qualified-id, the parser does not 124eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// expect: 125eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 126eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' conversion-function-id 127eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' '~' class-name 128eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 129eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// This may cause a slight inconsistency on diagnostics: 130eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 131eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// class C {}; 132eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// namespace A {} 133eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// void f() { 134eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// :: A :: ~ C(); // Some Sema error about using destructor with a 135eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// // namespace. 136eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// :: ~ C(); // Some Parser error like 'unexpected ~'. 137eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// } 138eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 139eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// We simplify the parser a bit and make it work like: 140eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 141eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// qualified-id: 142eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 143eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' unqualified-id 144eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 145eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// That way Sema can handle and report similar errors for namespaces and the 146eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// global scope. 147eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 14820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult Parser::ParseCXXIdExpression() { 149eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // qualified-id: 150eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 151eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // '::' unqualified-id 152eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // 153eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis CXXScopeSpec SS; 1544bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis MaybeParseCXXScopeSpecifier(SS); 155eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 156eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // unqualified-id: 157eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // identifier 158eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // operator-function-id 1592def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor // conversion-function-id 160eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // '~' class-name [TODO] 161eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // template-id [TODO] 162eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // 163eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis switch (Tok.getKind()) { 164eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis default: 16520df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(Diag(Tok, diag::err_expected_unqualified_id)); 166eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 167eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis case tok::identifier: { 168eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // Consume the identifier so that we can see if it is followed by a '('. 169eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis IdentifierInfo &II = *Tok.getIdentifierInfo(); 170eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation L = ConsumeToken(); 17120df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnIdentifierExpr(CurScope, L, II, 17220df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl Tok.is(tok::l_paren), &SS)); 173eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 174eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 175eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis case tok::kw_operator: { 176eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation OperatorLoc = Tok.getLocation(); 177e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor if (OverloadedOperatorKind Op = TryParseOperatorFunctionId()) { 17820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXOperatorFunctionIdExpr( 17920df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl CurScope, OperatorLoc, Op, Tok.is(tok::l_paren), SS)); 1802def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor } else if (TypeTy *Type = ParseConversionFunctionId()) { 18120df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXConversionFunctionExpr( 18220df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl CurScope, OperatorLoc, Type, Tok.is(tok::l_paren),SS)); 183eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 18420df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl 1852def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor // We already complained about a bad conversion-function-id, 1862def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor // above. 18720df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 188eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 189eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 190eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } // switch. 191eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 192eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis assert(0 && "The switch was supposed to take care everything."); 193eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis} 194eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 1955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCXXCasts - This handles the various ways to cast expressions to another 1965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// type. 1975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 1985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// postfix-expression: [C++ 5.2p1] 1995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'dynamic_cast' '<' type-name '>' '(' expression ')' 2005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'static_cast' '<' type-name '>' '(' expression ')' 2015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'reinterpret_cast' '<' type-name '>' '(' expression ')' 2025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'const_cast' '<' type-name '>' '(' expression ')' 2035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 20420df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult Parser::ParseCXXCasts() { 2055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer tok::TokenKind Kind = Tok.getKind(); 2065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const char *CastName = 0; // For error messages 2075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer switch (Kind) { 2095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer default: assert(0 && "Unknown C++ cast!"); abort(); 2105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_const_cast: CastName = "const_cast"; break; 2115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_dynamic_cast: CastName = "dynamic_cast"; break; 2125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break; 2135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_static_cast: CastName = "static_cast"; break; 2145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation OpLoc = ConsumeToken(); 2175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation LAngleBracketLoc = Tok.getLocation(); 2185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName)) 22020df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 2215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer TypeTy *CastTy = ParseTypeName(); 2235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation RAngleBracketLoc = Tok.getLocation(); 2245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2251ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner if (ExpectAndConsume(tok::greater, diag::err_expected_greater)) 22620df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << "<"); 2275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation LParenLoc = Tok.getLocation(), RParenLoc; 2295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2301ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner if (Tok.isNot(tok::l_paren)) 23120df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(Diag(Tok, diag::err_expected_lparen_after) << CastName); 2325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 233d8c4e15138e69a51754cc259c8a592cc47950c8eSebastian Redl OwningExprResult Result(ParseSimpleParenExpression(RParenLoc)); 2345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2350e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (!Result.isInvalid()) 23649badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor Result = Actions.ActOnCXXNamedCast(OpLoc, Kind, 23749badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor LAngleBracketLoc, CastTy, RAngleBracketLoc, 238effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl LParenLoc, Result.release(), RParenLoc); 2395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 24020df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return move(Result); 2415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 2425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 243c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// ParseCXXTypeid - This handles the C++ typeid expression. 244c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 245c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// postfix-expression: [C++ 5.2p1] 246c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 'typeid' '(' expression ')' 247c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 'typeid' '(' type-id ')' 248c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 24920df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult Parser::ParseCXXTypeid() { 250c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!"); 251c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 252c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SourceLocation OpLoc = ConsumeToken(); 253c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SourceLocation LParenLoc = Tok.getLocation(); 254c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SourceLocation RParenLoc; 255c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 256c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl // typeid expressions are always parenthesized. 257c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, 258c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl "typeid")) 25920df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 260c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 26115faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult Result(Actions); 262c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 263c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl if (isTypeIdInParens()) { 264c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl TypeTy *Ty = ParseTypeName(); 265c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 266c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl // Match the ')'. 267c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl MatchRHSPunctuation(tok::r_paren, LParenLoc); 268c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 269c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl if (!Ty) 27020df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 271c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 272c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true, 273c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Ty, RParenLoc); 274c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl } else { 275c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Result = ParseExpression(); 276c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 277c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl // Match the ')'. 2780e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Result.isInvalid()) 279c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SkipUntil(tok::r_paren); 280c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl else { 281c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl MatchRHSPunctuation(tok::r_paren, LParenLoc); 282c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 283c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false, 284effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl Result.release(), RParenLoc); 285c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl } 286c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl } 287c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 28820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return move(Result); 289c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl} 290c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 2915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCXXBoolLiteral - This handles the C++ Boolean literals. 2925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 2935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// boolean-literal: [C++ 2.13.5] 2945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'true' 2955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'false' 29620df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult Parser::ParseCXXBoolLiteral() { 2975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer tok::TokenKind Kind = Tok.getKind(); 29820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind)); 2995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 30050dd289f45738ed22b7583d52ed2525b927042ffChris Lattner 30150dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// ParseThrowExpression - This handles the C++ throw expression. 30250dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// 30350dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// throw-expression: [C++ 15] 30450dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// 'throw' assignment-expression[opt] 30520df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult Parser::ParseThrowExpression() { 30650dd289f45738ed22b7583d52ed2525b927042ffChris Lattner assert(Tok.is(tok::kw_throw) && "Not throw!"); 30750dd289f45738ed22b7583d52ed2525b927042ffChris Lattner SourceLocation ThrowLoc = ConsumeToken(); // Eat the throw token. 30820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl 3092a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // If the current token isn't the start of an assignment-expression, 3102a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // then the expression is not present. This handles things like: 3112a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // "C ? throw : (void)42", which is crazy but legal. 3122a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner switch (Tok.getKind()) { // FIXME: move this predicate somewhere common. 3132a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::semi: 3142a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_paren: 3152a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_square: 3162a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_brace: 3172a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::colon: 3182a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::comma: 31920df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXThrow(ThrowLoc)); 32050dd289f45738ed22b7583d52ed2525b927042ffChris Lattner 3212a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner default: 3222f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl OwningExprResult Expr(ParseAssignmentExpression()); 32320df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl if (Expr.isInvalid()) return move(Expr); 32420df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXThrow(ThrowLoc, Expr.release())); 3252a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner } 32650dd289f45738ed22b7583d52ed2525b927042ffChris Lattner} 3274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 3284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXThis - This handles the C++ 'this' pointer. 3294cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 3304cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// C++ 9.3.2: In the body of a non-static member function, the keyword this is 3314cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// a non-lvalue expression whose value is the address of the object for which 3324cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// the function is called. 33320df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult Parser::ParseCXXThis() { 3344cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis assert(Tok.is(tok::kw_this) && "Not 'this'!"); 3354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SourceLocation ThisLoc = ConsumeToken(); 33620df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXThis(ThisLoc)); 3374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 338987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 339987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// ParseCXXTypeConstructExpression - Parse construction of a specified type. 340987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// Can be interpreted either as function-style casting ("int(x)") 341987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// or class type construction ("ClassType(x,y,z)") 342987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// or creation of a value-initialized type ("int()"). 343987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 344987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// postfix-expression: [C++ 5.2p1] 345987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3] 346987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// typename-specifier '(' expression-list[opt] ')' [TODO] 347987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 34820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult 34920df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { 350987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 351987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis TypeTy *TypeRep = Actions.ActOnTypeName(CurScope, DeclaratorInfo).Val; 352987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 353987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis assert(Tok.is(tok::l_paren) && "Expected '('!"); 354987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SourceLocation LParenLoc = ConsumeParen(); 355987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 356a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector Exprs(Actions); 357987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis CommaLocsTy CommaLocs; 358987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 359987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis if (Tok.isNot(tok::r_paren)) { 360987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis if (ParseExpressionList(Exprs, CommaLocs)) { 361987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SkipUntil(tok::r_paren); 36220df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 363987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 364987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 365987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 366987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // Match the ')'. 367987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 368987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 369987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&& 370987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis "Unexpected number of commas!"); 37120df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXTypeConstructExpr(DS.getSourceRange(), TypeRep, 37220df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl LParenLoc, 37320df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl Exprs.take(), Exprs.size(), 37420df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl &CommaLocs[0], RParenLoc)); 375987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis} 376987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 37771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// ParseCXXCondition - if/switch/while/for condition expression. 37871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// 37971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// condition: 38071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// expression 38171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// type-specifier-seq declarator '=' assignment-expression 38271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 38371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// '=' assignment-expression 38471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// 3852f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian RedlParser::OwningExprResult Parser::ParseCXXCondition() { 386a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis if (!isCXXConditionDeclaration()) 38771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis return ParseExpression(); // expression 38871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 38971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SourceLocation StartLoc = Tok.getLocation(); 39071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 39171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // type-specifier-seq 39271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis DeclSpec DS; 39371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis ParseSpecifierQualifierList(DS); 39471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 39571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // declarator 39671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::ConditionContext); 39771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 39871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 39971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // simple-asm-expr[opt] 40071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (Tok.is(tok::kw_asm)) { 401effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl OwningExprResult AsmLabel(ParseSimpleAsm()); 4020e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (AsmLabel.isInvalid()) { 40371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SkipUntil(tok::semi); 4042f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl return ExprError(); 40571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis } 406effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl DeclaratorInfo.setAsmLabel(AsmLabel.release()); 40771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis } 40871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 40971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // If attributes are present, parse them. 41071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (Tok.is(tok::kw___attribute)) 41171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis DeclaratorInfo.AddAttributes(ParseAttributes()); 41271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 41371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // '=' assignment-expression 41471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (Tok.isNot(tok::equal)) 4152f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl return ExprError(Diag(Tok, diag::err_expected_equal_after_declarator)); 41671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SourceLocation EqualLoc = ConsumeToken(); 4172f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl OwningExprResult AssignExpr(ParseAssignmentExpression()); 4180e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (AssignExpr.isInvalid()) 4192f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl return ExprError(); 4202f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl 4212f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl return Owned(Actions.ActOnCXXConditionDeclarationExpr(CurScope, StartLoc, 4222f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl DeclaratorInfo,EqualLoc, 4232f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl AssignExpr.release())); 42471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis} 42571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 426987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers. 427987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// This should only be called when the current token is known to be part of 428987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// simple-type-specifier. 429987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 430987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// simple-type-specifier: 431eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier[opt] type-name 432987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template' simple-template-id [TODO] 433987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// char 434987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// wchar_t 435987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// bool 436987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// short 437987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// int 438987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// long 439987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// signed 440987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// unsigned 441987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// float 442987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// double 443987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// void 444987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// [GNU] typeof-specifier 445987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// [C++0x] auto [TODO] 446987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 447987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// type-name: 448987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// class-name 449987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// enum-name 450987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// typedef-name 451987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 452987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidisvoid Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { 453eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // Annotate typenames and C++ scope specifiers. 454eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis TryAnnotateTypeOrScopeToken(); 455eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 456987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetRangeStart(Tok.getLocation()); 457987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis const char *PrevSpec; 458987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SourceLocation Loc = Tok.getLocation(); 459987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 460987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis switch (Tok.getKind()) { 461987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis default: 462987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis assert(0 && "Not a simple-type-specifier token!"); 463987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis abort(); 464987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 465987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // type-name 466eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis case tok::annot_qualtypename: { 467eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec, 468eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis Tok.getAnnotationValue()); 469987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 470987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 471987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 472987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // builtin types 473987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_short: 474987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec); 475987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 476987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_long: 477987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec); 478987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 479987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_signed: 480987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec); 481987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 482987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_unsigned: 483987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec); 484987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 485987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_void: 486987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec); 487987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 488987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_char: 489987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec); 490987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 491987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_int: 492987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec); 493987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 494987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_float: 495987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec); 496987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 497987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_double: 498987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec); 499987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 500987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_wchar_t: 501987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec); 502987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 503987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_bool: 504987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec); 505987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 506987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 507987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // GNU typeof support. 508987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_typeof: 509987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis ParseTypeofSpecifier(DS); 510987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.Finish(Diags, PP.getSourceManager(), getLang()); 511987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis return; 512987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 513eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis if (Tok.is(tok::annot_qualtypename)) 514eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 515eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis else 516eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis DS.SetRangeEnd(Tok.getLocation()); 517987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis ConsumeToken(); 518987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.Finish(Diags, PP.getSourceManager(), getLang()); 519987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis} 5201cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5212f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++ 5222f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// [dcl.name]), which is a non-empty sequence of type-specifiers, 5232f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// e.g., "const short int". Note that the DeclSpec is *not* finished 5242f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// by parsing the type-specifier-seq, because these sequences are 5252f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// typically followed by some form of declarator. Returns true and 5262f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// emits diagnostics if this is not a type-specifier-seq, false 5272f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// otherwise. 5282f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 5292f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// type-specifier-seq: [C++ 8.1] 5302f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// type-specifier type-specifier-seq[opt] 5312f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 5322f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregorbool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) { 5332f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor DS.SetRangeStart(Tok.getLocation()); 5342f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor const char *PrevSpec = 0; 5352f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor int isInvalid = 0; 5362f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 5372f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Parse one or more of the type specifiers. 5382f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor if (!MaybeParseTypeSpecifier(DS, isInvalid, PrevSpec)) { 5391ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_operator_missing_type_specifier); 5402f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return true; 5412f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor } 542b90585c3c65db9ab587674586602729edbd096aaDaniel Dunbar while (MaybeParseTypeSpecifier(DS, isInvalid, PrevSpec)) ; 5432f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 5442f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return false; 5452f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor} 5462f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 54743c7bad105f742988e7ca40564285c83bea854a5Douglas Gregor/// TryParseOperatorFunctionId - Attempts to parse a C++ overloaded 5481cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator name (C++ [over.oper]). If successful, returns the 5491cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// predefined identifier that corresponds to that overloaded 5501cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator. Otherwise, returns NULL and does not consume any tokens. 5511cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// 5521cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator-function-id: [C++ 13.5] 5531cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// 'operator' operator 5541cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// 5551cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator: one of 5561cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// new delete new[] delete[] 5571cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// + - * / % ^ & | ~ 5581cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// ! = < > += -= *= /= %= 5591cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// ^= &= |= << >> >>= <<= == != 5601cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// <= >= && || ++ -- , ->* -> 5611cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// () [] 562e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas GregorOverloadedOperatorKind Parser::TryParseOperatorFunctionId() { 5639057a81efaf15c543aab1c5c8488e8a9ed2c0ff4Argyrios Kyrtzidis assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); 5641cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5651cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor OverloadedOperatorKind Op = OO_None; 5661cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor switch (NextToken().getKind()) { 5671cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::kw_new: 5681cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 5691cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'new' 5701cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor if (Tok.is(tok::l_square)) { 5711cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeBracket(); // '[' 5721cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 5731cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_Array_New; 5741cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } else { 5751cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_New; 5761cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } 577e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return Op; 5781cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5791cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::kw_delete: 5801cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 5811cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'delete' 5821cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor if (Tok.is(tok::l_square)) { 5831cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeBracket(); // '[' 5841cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 5851cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_Array_Delete; 5861cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } else { 5871cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_Delete; 5881cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } 589e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return Op; 5901cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 59102bcd4cd1a19121da12884aa4943226f72a81e6cDouglas Gregor#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 5921cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::Token: Op = OO_##Name; break; 59302bcd4cd1a19121da12884aa4943226f72a81e6cDouglas Gregor#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) 5941cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor#include "clang/Basic/OperatorKinds.def" 5951cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5961cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::l_paren: 5971cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 5981cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeParen(); // '(' 5991cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_paren, diag::err_expected_rparen); // ')' 600e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return OO_Call; 6011cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 6021cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::l_square: 6031cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 6041cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeBracket(); // '[' 6051cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 606e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return OO_Subscript; 6071cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 6081cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor default: 609e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return OO_None; 6101cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } 61143c7bad105f742988e7ca40564285c83bea854a5Douglas Gregor 61243c7bad105f742988e7ca40564285c83bea854a5Douglas Gregor ConsumeToken(); // 'operator' 61343c7bad105f742988e7ca40564285c83bea854a5Douglas Gregor ConsumeAnyToken(); // the operator itself 614e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return Op; 6151cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor} 6162f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 6172f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// ParseConversionFunctionId - Parse a C++ conversion-function-id, 6182f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// which expresses the name of a user-defined conversion operator 6192f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// (C++ [class.conv.fct]p1). Returns the type that this operator is 6202f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// specifying a conversion for, or NULL if there was an error. 6212f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 6222f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// conversion-function-id: [C++ 12.3.2] 6232f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// operator conversion-type-id 6242f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 6252f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// conversion-type-id: 6262f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// type-specifier-seq conversion-declarator[opt] 6272f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 6282f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// conversion-declarator: 6292f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// ptr-operator conversion-declarator[opt] 6302f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas GregorParser::TypeTy *Parser::ParseConversionFunctionId() { 6312f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); 6322f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor ConsumeToken(); // 'operator' 6332f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 6342f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Parse the type-specifier-seq. 6352f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor DeclSpec DS; 6362f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor if (ParseCXXTypeSpecifierSeq(DS)) 6372f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return 0; 6382f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 6392f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Parse the conversion-declarator, which is merely a sequence of 6402f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // ptr-operators. 6412f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor Declarator D(DS, Declarator::TypeNameContext); 6424c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParseDeclaratorInternal(D, /*DirectDeclParser=*/0); 6432f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 6442f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Finish up the type. 6452f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor Action::TypeResult Result = Actions.ActOnTypeName(CurScope, D); 6462f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor if (Result.isInvalid) 6472f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return 0; 6482f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor else 6492f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return Result.Val; 6502f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor} 6514c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6524c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate 6534c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// memory in a typesafe manner and call constructors. 65459232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// 65559232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// This method is called to parse the new expression after the optional :: has 65659232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// been already parsed. If the :: was present, "UseGlobal" is true and "Start" 65759232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// is its location. Otherwise, "Start" is the location of the 'new' token. 6584c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 6594c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-expression: 6604c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'new' new-placement[opt] new-type-id 6614c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer[opt] 6624c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 6634c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer[opt] 6644c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 6654c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-placement: 6664c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '(' expression-list ')' 6674c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 668cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// new-type-id: 669cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// type-specifier-seq new-declarator[opt] 670cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// 671cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// new-declarator: 672cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// ptr-operator new-declarator[opt] 673cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// direct-new-declarator 674cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// 6754c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer: 6764c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '(' expression-list[opt] ')' 6774c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// [C++0x] braced-init-list [TODO] 6784c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 67959232d35f5820e334b6c8b007ae8006f4390055dChris LattnerParser::OwningExprResult 68059232d35f5820e334b6c8b007ae8006f4390055dChris LattnerParser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { 68159232d35f5820e334b6c8b007ae8006f4390055dChris Lattner assert(Tok.is(tok::kw_new) && "expected 'new' token"); 68259232d35f5820e334b6c8b007ae8006f4390055dChris Lattner ConsumeToken(); // Consume 'new' 6834c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6844c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // A '(' now can be a new-placement or the '(' wrapping the type-id in the 6854c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // second form of new-expression. It can't be a new-type-id. 6864c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 687a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector PlacementArgs(Actions); 6884c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation PlacementLParen, PlacementRParen; 6894c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6904c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool ParenTypeId; 691cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl DeclSpec DS; 692cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 6934c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_paren)) { 6944c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // If it turns out to be a placement, we change the type location. 6954c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl PlacementLParen = ConsumeParen(); 696cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) { 697cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 69820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 699cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 7004c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7014c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl PlacementRParen = MatchRHSPunctuation(tok::r_paren, PlacementLParen); 702cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (PlacementRParen.isInvalid()) { 703cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 70420df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 705cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 7064c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 707cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (PlacementArgs.empty()) { 7084c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Reset the placement locations. There was no placement. 7094c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl PlacementLParen = PlacementRParen = SourceLocation(); 7104c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParenTypeId = true; 7114c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } else { 7124c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // We still need the type. 7134c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_paren)) { 714cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SourceLocation LParen = ConsumeParen(); 715cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseSpecifierQualifierList(DS); 716cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclarator(DeclaratorInfo); 717cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl MatchRHSPunctuation(tok::r_paren, LParen); 7184c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParenTypeId = true; 7194c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } else { 720cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseCXXTypeSpecifierSeq(DS)) 721cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl DeclaratorInfo.setInvalidType(true); 722cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl else 723cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclaratorInternal(DeclaratorInfo, 724cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl &Parser::ParseDirectNewDeclarator); 7254c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParenTypeId = false; 7264c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7274c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7284c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } else { 729cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl // A new-type-id is a simplified type-id, where essentially the 730cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl // direct-declarator is replaced by a direct-new-declarator. 731cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseCXXTypeSpecifierSeq(DS)) 732cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl DeclaratorInfo.setInvalidType(true); 733cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl else 734cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclaratorInternal(DeclaratorInfo, 735cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl &Parser::ParseDirectNewDeclarator); 7364c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParenTypeId = false; 7374c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 738cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (DeclaratorInfo.getInvalidType()) { 739cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 74020df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 741cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 7424c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 743a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector ConstructorArgs(Actions); 7444c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation ConstructorLParen, ConstructorRParen; 7454c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7464c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_paren)) { 7474c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ConstructorLParen = ConsumeParen(); 7484c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.isNot(tok::r_paren)) { 7494c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl CommaLocsTy CommaLocs; 750cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseExpressionList(ConstructorArgs, CommaLocs)) { 751cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 75220df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 753cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 7544c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7554c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ConstructorRParen = MatchRHSPunctuation(tok::r_paren, ConstructorLParen); 756cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ConstructorRParen.isInvalid()) { 757cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 75820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 759cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 7604c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7614c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 76220df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen, 76320df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl PlacementArgs.take(), PlacementArgs.size(), 76420df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl PlacementRParen, ParenTypeId, DeclaratorInfo, 76520df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl ConstructorLParen, ConstructorArgs.take(), 76620df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl ConstructorArgs.size(), ConstructorRParen)); 7674c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 7684c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7694c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be 7704c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// passed to ParseDeclaratorInternal. 7714c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 7724c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// direct-new-declarator: 7734c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '[' expression ']' 7744c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// direct-new-declarator '[' constant-expression ']' 7754c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 77659232d35f5820e334b6c8b007ae8006f4390055dChris Lattnervoid Parser::ParseDirectNewDeclarator(Declarator &D) { 7774c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Parse the array dimensions. 7784c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool first = true; 7794c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl while (Tok.is(tok::l_square)) { 7804c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation LLoc = ConsumeBracket(); 7812f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl OwningExprResult Size(first ? ParseExpression() 7822f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl : ParseConstantExpression()); 7830e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Size.isInvalid()) { 7844c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Recover 7854c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SkipUntil(tok::r_square); 7864c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return; 7874c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7884c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl first = false; 7894c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7904c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false, 791effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl Size.release(), LLoc)); 7924c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7934c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (MatchRHSPunctuation(tok::r_square, LLoc).isInvalid()) 7944c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return; 7954c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7964c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 7974c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7984c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id. 7994c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// This ambiguity appears in the syntax of the C++ new operator. 8004c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 8014c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-expression: 8024c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 8034c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer[opt] 8044c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 8054c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-placement: 8064c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '(' expression-list ')' 8074c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 808cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redlbool Parser::ParseExpressionListOrTypeId(ExprListTy &PlacementArgs, 80959232d35f5820e334b6c8b007ae8006f4390055dChris Lattner Declarator &D) { 8104c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // The '(' was already consumed. 8114c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (isTypeIdInParens()) { 812cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseSpecifierQualifierList(D.getMutableDeclSpec()); 813cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclarator(D); 814cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl return D.getInvalidType(); 8154c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 8164c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8174c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // It's not a type, it has to be an expression list. 8184c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Discard the comma locations - ActOnCXXNew has enough parameters. 8194c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl CommaLocsTy CommaLocs; 8204c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return ParseExpressionList(PlacementArgs, CommaLocs); 8214c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 8224c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8234c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used 8244c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// to free memory allocated by new. 8254c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 82659232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// This method is called to parse the 'delete' expression after the optional 82759232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// '::' has been already parsed. If the '::' was present, "UseGlobal" is true 82859232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// and "Start" is its location. Otherwise, "Start" is the location of the 82959232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// 'delete' token. 83059232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// 8314c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// delete-expression: 8324c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'delete' cast-expression 8334c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'delete' '[' ']' cast-expression 83459232d35f5820e334b6c8b007ae8006f4390055dChris LattnerParser::OwningExprResult 83559232d35f5820e334b6c8b007ae8006f4390055dChris LattnerParser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) { 83659232d35f5820e334b6c8b007ae8006f4390055dChris Lattner assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword"); 83759232d35f5820e334b6c8b007ae8006f4390055dChris Lattner ConsumeToken(); // Consume 'delete' 8384c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8394c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Array delete? 8404c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool ArrayDelete = false; 8414c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_square)) { 8424c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ArrayDelete = true; 8434c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation LHS = ConsumeBracket(); 8444c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation RHS = MatchRHSPunctuation(tok::r_square, LHS); 8454c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (RHS.isInvalid()) 84620df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 8474c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 8484c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8492f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl OwningExprResult Operand(ParseCastExpression(false)); 8500e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Operand.isInvalid()) 85120df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return move(Operand); 8524c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 85320df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, 85420df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl Operand.release())); 8554c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 856