ParseExprCXX.cpp revision 7a0ab5f387722c83e19c7133b46b16988eb19e45
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 207a0ab5f387722c83e19c7133b46b16988eb19e45Chris Lattner/// ParseOptionalCXXScopeSpecifier - Parse global scope or 217a0ab5f387722c83e19c7133b46b16988eb19e45Chris Lattner/// nested-name-specifier if present. Returns true if a nested-name-specifier 227a0ab5f387722c83e19c7133b46b16988eb19e45Chris Lattner/// was parsed from the token stream. Note that this routine will not parse 237a0ab5f387722c83e19c7133b46b16988eb19e45Chris Lattner/// ::new or ::delete, it will just leave them in the token stream. 24eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 25eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier 26eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' 27eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 28eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier: 29eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// type-name '::' 30eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// namespace-name '::' 31eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier identifier '::' 32eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier 'template'[opt] simple-template-id '::' [TODO] 33eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 347a0ab5f387722c83e19c7133b46b16988eb19e45Chris Lattnerbool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS) { 354bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis assert(getLang().CPlusPlus && 367452c6fc567ea1799f617395d0fa4c7ed075e5d9Chris Lattner "Call sites of this function should be guarded by checking for C++"); 374bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis 38eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis if (Tok.is(tok::annot_cxxscope)) { 39eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setScopeRep(Tok.getAnnotationValue()); 40eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setRange(Tok.getAnnotationRange()); 41eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis ConsumeToken(); 424bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis return true; 43eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 44e607e808c2b90724a2a6fd841e850f07de1f5b30Chris Lattner 455b4547318bb179fc76f984f0eeaaf615927e795cChris Lattner if (Tok.is(tok::coloncolon)) { 465b4547318bb179fc76f984f0eeaaf615927e795cChris Lattner // ::new and ::delete aren't nested-name-specifiers. 475b4547318bb179fc76f984f0eeaaf615927e795cChris Lattner tok::TokenKind NextKind = NextToken().getKind(); 485b4547318bb179fc76f984f0eeaaf615927e795cChris Lattner if (NextKind == tok::kw_new || NextKind == tok::kw_delete) 495b4547318bb179fc76f984f0eeaaf615927e795cChris Lattner return false; 5055a7cefc846765ac7d142a63f773747a20518d71Chris Lattner 5155a7cefc846765ac7d142a63f773747a20518d71Chris Lattner // '::' - Global scope qualifier. 52357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner SourceLocation CCLoc = ConsumeToken(); 53357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner SS.setBeginLoc(CCLoc); 54357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc)); 55357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner SS.setEndLoc(CCLoc); 56357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner } else if (Tok.is(tok::identifier) && NextToken().is(tok::coloncolon)) { 57357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner SS.setBeginLoc(Tok.getLocation()); 58357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner } else { 59357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner // Not a CXXScopeSpecifier. 60357089dea05855e27f80f6f244f9c60fc77cee83Chris Lattner return false; 61eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 62eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 63eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // nested-name-specifier: 64eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // type-name '::' 65eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // namespace-name '::' 66eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // nested-name-specifier identifier '::' 67eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // nested-name-specifier 'template'[opt] simple-template-id '::' [TODO] 68eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis while (Tok.is(tok::identifier) && NextToken().is(tok::coloncolon)) { 69eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis IdentifierInfo *II = Tok.getIdentifierInfo(); 70eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation IdLoc = ConsumeToken(); 71e607e808c2b90724a2a6fd841e850f07de1f5b30Chris Lattner assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!"); 72eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation CCLoc = ConsumeToken(); 73eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis if (SS.isInvalid()) 74eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis continue; 75eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 76eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setScopeRep( 77e607e808c2b90724a2a6fd841e850f07de1f5b30Chris Lattner Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, IdLoc, CCLoc, *II)); 78eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setEndLoc(CCLoc); 79eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 804bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis 814bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis return true; 82eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis} 83eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 84eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// ParseCXXIdExpression - Handle id-expression. 85eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 86eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// id-expression: 87eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// unqualified-id 88eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// qualified-id 89eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 90eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// unqualified-id: 91eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// identifier 92eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// operator-function-id 93eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// conversion-function-id [TODO] 94eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '~' class-name [TODO] 95eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// template-id [TODO] 96eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 97eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// qualified-id: 98eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 99eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' identifier 100eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' operator-function-id 101eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' template-id [TODO] 102eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 103eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier: 104eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// type-name '::' 105eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// namespace-name '::' 106eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier identifier '::' 107eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier 'template'[opt] simple-template-id '::' [TODO] 108eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 109eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// NOTE: The standard specifies that, for qualified-id, the parser does not 110eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// expect: 111eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 112eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' conversion-function-id 113eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' '~' class-name 114eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 115eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// This may cause a slight inconsistency on diagnostics: 116eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 117eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// class C {}; 118eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// namespace A {} 119eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// void f() { 120eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// :: A :: ~ C(); // Some Sema error about using destructor with a 121eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// // namespace. 122eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// :: ~ C(); // Some Parser error like 'unexpected ~'. 123eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// } 124eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 125eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// We simplify the parser a bit and make it work like: 126eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 127eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// qualified-id: 128eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 129eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' unqualified-id 130eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 131eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// That way Sema can handle and report similar errors for namespaces and the 132eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// global scope. 133eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 13420df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult Parser::ParseCXXIdExpression() { 135eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // qualified-id: 136eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 137eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // '::' unqualified-id 138eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // 139eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis CXXScopeSpec SS; 1407a0ab5f387722c83e19c7133b46b16988eb19e45Chris Lattner ParseOptionalCXXScopeSpecifier(SS); 141eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 142eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // unqualified-id: 143eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // identifier 144eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // operator-function-id 1452def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor // conversion-function-id 146eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // '~' class-name [TODO] 147eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // template-id [TODO] 148eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // 149eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis switch (Tok.getKind()) { 150eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis default: 15120df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(Diag(Tok, diag::err_expected_unqualified_id)); 152eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 153eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis case tok::identifier: { 154eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // Consume the identifier so that we can see if it is followed by a '('. 155eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis IdentifierInfo &II = *Tok.getIdentifierInfo(); 156eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation L = ConsumeToken(); 15720df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnIdentifierExpr(CurScope, L, II, 15820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl Tok.is(tok::l_paren), &SS)); 159eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 160eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 161eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis case tok::kw_operator: { 162eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation OperatorLoc = Tok.getLocation(); 1637452c6fc567ea1799f617395d0fa4c7ed075e5d9Chris Lattner if (OverloadedOperatorKind Op = TryParseOperatorFunctionId()) 16420df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXOperatorFunctionIdExpr( 16520df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl CurScope, OperatorLoc, Op, Tok.is(tok::l_paren), SS)); 1667452c6fc567ea1799f617395d0fa4c7ed075e5d9Chris Lattner if (TypeTy *Type = ParseConversionFunctionId()) 1677452c6fc567ea1799f617395d0fa4c7ed075e5d9Chris Lattner return Owned(Actions.ActOnCXXConversionFunctionExpr(CurScope, OperatorLoc, 1687452c6fc567ea1799f617395d0fa4c7ed075e5d9Chris Lattner Type, 1697452c6fc567ea1799f617395d0fa4c7ed075e5d9Chris Lattner Tok.is(tok::l_paren), SS)); 17020df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl 1712def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor // We already complained about a bad conversion-function-id, 1722def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor // above. 17320df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 174eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 175eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 176eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } // switch. 177eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 178eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis assert(0 && "The switch was supposed to take care everything."); 179eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis} 180eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 1815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCXXCasts - This handles the various ways to cast expressions to another 1825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// type. 1835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 1845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// postfix-expression: [C++ 5.2p1] 1855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'dynamic_cast' '<' type-name '>' '(' expression ')' 1865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'static_cast' '<' type-name '>' '(' expression ')' 1875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'reinterpret_cast' '<' type-name '>' '(' expression ')' 1885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'const_cast' '<' type-name '>' '(' expression ')' 1895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 19020df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult Parser::ParseCXXCasts() { 1915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer tok::TokenKind Kind = Tok.getKind(); 1925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const char *CastName = 0; // For error messages 1935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer switch (Kind) { 1955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer default: assert(0 && "Unknown C++ cast!"); abort(); 1965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_const_cast: CastName = "const_cast"; break; 1975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_dynamic_cast: CastName = "dynamic_cast"; break; 1985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break; 1995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_static_cast: CastName = "static_cast"; break; 2005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation OpLoc = ConsumeToken(); 2035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation LAngleBracketLoc = Tok.getLocation(); 2045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName)) 20620df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 2075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer TypeTy *CastTy = ParseTypeName(); 2095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation RAngleBracketLoc = Tok.getLocation(); 2105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2111ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner if (ExpectAndConsume(tok::greater, diag::err_expected_greater)) 21220df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << "<"); 2135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation LParenLoc = Tok.getLocation(), RParenLoc; 2155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2161ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner if (Tok.isNot(tok::l_paren)) 21720df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(Diag(Tok, diag::err_expected_lparen_after) << CastName); 2185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 219d8c4e15138e69a51754cc259c8a592cc47950c8eSebastian Redl OwningExprResult Result(ParseSimpleParenExpression(RParenLoc)); 2205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2210e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (!Result.isInvalid()) 22249badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor Result = Actions.ActOnCXXNamedCast(OpLoc, Kind, 22349badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor LAngleBracketLoc, CastTy, RAngleBracketLoc, 224effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl LParenLoc, Result.release(), RParenLoc); 2255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 22620df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return move(Result); 2275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 2285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 229c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// ParseCXXTypeid - This handles the C++ typeid expression. 230c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 231c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// postfix-expression: [C++ 5.2p1] 232c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 'typeid' '(' expression ')' 233c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 'typeid' '(' type-id ')' 234c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 23520df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult Parser::ParseCXXTypeid() { 236c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!"); 237c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 238c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SourceLocation OpLoc = ConsumeToken(); 239c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SourceLocation LParenLoc = Tok.getLocation(); 240c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SourceLocation RParenLoc; 241c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 242c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl // typeid expressions are always parenthesized. 243c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, 244c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl "typeid")) 24520df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 246c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 24715faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult Result(Actions); 248c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 249c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl if (isTypeIdInParens()) { 250c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl TypeTy *Ty = ParseTypeName(); 251c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 252c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl // Match the ')'. 253c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl MatchRHSPunctuation(tok::r_paren, LParenLoc); 254c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 255c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl if (!Ty) 25620df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 257c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 258c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true, 259c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Ty, RParenLoc); 260c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl } else { 261c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Result = ParseExpression(); 262c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 263c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl // Match the ')'. 2640e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Result.isInvalid()) 265c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SkipUntil(tok::r_paren); 266c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl else { 267c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl MatchRHSPunctuation(tok::r_paren, LParenLoc); 268c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 269c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false, 270effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl Result.release(), RParenLoc); 271c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl } 272c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl } 273c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 27420df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return move(Result); 275c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl} 276c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 2775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCXXBoolLiteral - This handles the C++ Boolean literals. 2785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 2795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// boolean-literal: [C++ 2.13.5] 2805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'true' 2815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'false' 28220df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult Parser::ParseCXXBoolLiteral() { 2835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer tok::TokenKind Kind = Tok.getKind(); 28420df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind)); 2855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 28650dd289f45738ed22b7583d52ed2525b927042ffChris Lattner 28750dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// ParseThrowExpression - This handles the C++ throw expression. 28850dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// 28950dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// throw-expression: [C++ 15] 29050dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// 'throw' assignment-expression[opt] 29120df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult Parser::ParseThrowExpression() { 29250dd289f45738ed22b7583d52ed2525b927042ffChris Lattner assert(Tok.is(tok::kw_throw) && "Not throw!"); 29350dd289f45738ed22b7583d52ed2525b927042ffChris Lattner SourceLocation ThrowLoc = ConsumeToken(); // Eat the throw token. 29420df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl 2952a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // If the current token isn't the start of an assignment-expression, 2962a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // then the expression is not present. This handles things like: 2972a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // "C ? throw : (void)42", which is crazy but legal. 2982a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner switch (Tok.getKind()) { // FIXME: move this predicate somewhere common. 2992a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::semi: 3002a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_paren: 3012a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_square: 3022a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_brace: 3032a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::colon: 3042a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::comma: 30520df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXThrow(ThrowLoc)); 30650dd289f45738ed22b7583d52ed2525b927042ffChris Lattner 3072a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner default: 3082f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl OwningExprResult Expr(ParseAssignmentExpression()); 30920df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl if (Expr.isInvalid()) return move(Expr); 31020df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXThrow(ThrowLoc, Expr.release())); 3112a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner } 31250dd289f45738ed22b7583d52ed2525b927042ffChris Lattner} 3134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 3144cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXThis - This handles the C++ 'this' pointer. 3154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 3164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// C++ 9.3.2: In the body of a non-static member function, the keyword this is 3174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// a non-lvalue expression whose value is the address of the object for which 3184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// the function is called. 31920df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult Parser::ParseCXXThis() { 3204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis assert(Tok.is(tok::kw_this) && "Not 'this'!"); 3214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SourceLocation ThisLoc = ConsumeToken(); 32220df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXThis(ThisLoc)); 3234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 324987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 325987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// ParseCXXTypeConstructExpression - Parse construction of a specified type. 326987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// Can be interpreted either as function-style casting ("int(x)") 327987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// or class type construction ("ClassType(x,y,z)") 328987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// or creation of a value-initialized type ("int()"). 329987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 330987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// postfix-expression: [C++ 5.2p1] 331987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3] 332987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// typename-specifier '(' expression-list[opt] ')' [TODO] 333987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 33420df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::OwningExprResult 33520df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { 336987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 337987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis TypeTy *TypeRep = Actions.ActOnTypeName(CurScope, DeclaratorInfo).Val; 338987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 339987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis assert(Tok.is(tok::l_paren) && "Expected '('!"); 340987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SourceLocation LParenLoc = ConsumeParen(); 341987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 342a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector Exprs(Actions); 343987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis CommaLocsTy CommaLocs; 344987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 345987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis if (Tok.isNot(tok::r_paren)) { 346987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis if (ParseExpressionList(Exprs, CommaLocs)) { 347987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SkipUntil(tok::r_paren); 34820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 349987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 350987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 351987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 352987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // Match the ')'. 353987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 354987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 355987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&& 356987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis "Unexpected number of commas!"); 35720df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXTypeConstructExpr(DS.getSourceRange(), TypeRep, 35820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl LParenLoc, 35920df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl Exprs.take(), Exprs.size(), 36020df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl &CommaLocs[0], RParenLoc)); 361987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis} 362987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 36371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// ParseCXXCondition - if/switch/while/for condition expression. 36471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// 36571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// condition: 36671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// expression 36771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// type-specifier-seq declarator '=' assignment-expression 36871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 36971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// '=' assignment-expression 37071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// 3712f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian RedlParser::OwningExprResult Parser::ParseCXXCondition() { 372a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis if (!isCXXConditionDeclaration()) 37371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis return ParseExpression(); // expression 37471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 37571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SourceLocation StartLoc = Tok.getLocation(); 37671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 37771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // type-specifier-seq 37871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis DeclSpec DS; 37971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis ParseSpecifierQualifierList(DS); 38071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 38171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // declarator 38271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::ConditionContext); 38371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 38471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 38571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // simple-asm-expr[opt] 38671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (Tok.is(tok::kw_asm)) { 387effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl OwningExprResult AsmLabel(ParseSimpleAsm()); 3880e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (AsmLabel.isInvalid()) { 38971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SkipUntil(tok::semi); 3902f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl return ExprError(); 39171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis } 392effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl DeclaratorInfo.setAsmLabel(AsmLabel.release()); 39371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis } 39471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 39571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // If attributes are present, parse them. 39671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (Tok.is(tok::kw___attribute)) 39771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis DeclaratorInfo.AddAttributes(ParseAttributes()); 39871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 39971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // '=' assignment-expression 40071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (Tok.isNot(tok::equal)) 4012f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl return ExprError(Diag(Tok, diag::err_expected_equal_after_declarator)); 40271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SourceLocation EqualLoc = ConsumeToken(); 4032f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl OwningExprResult AssignExpr(ParseAssignmentExpression()); 4040e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (AssignExpr.isInvalid()) 4052f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl return ExprError(); 4062f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl 4072f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl return Owned(Actions.ActOnCXXConditionDeclarationExpr(CurScope, StartLoc, 4082f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl DeclaratorInfo,EqualLoc, 4092f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl AssignExpr.release())); 41071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis} 41171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 412987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers. 413987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// This should only be called when the current token is known to be part of 414987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// simple-type-specifier. 415987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 416987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// simple-type-specifier: 417eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier[opt] type-name 418987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template' simple-template-id [TODO] 419987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// char 420987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// wchar_t 421987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// bool 422987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// short 423987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// int 424987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// long 425987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// signed 426987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// unsigned 427987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// float 428987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// double 429987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// void 430987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// [GNU] typeof-specifier 431987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// [C++0x] auto [TODO] 432987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 433987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// type-name: 434987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// class-name 435987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// enum-name 436987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// typedef-name 437987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 438987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidisvoid Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { 439987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetRangeStart(Tok.getLocation()); 440987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis const char *PrevSpec; 441987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SourceLocation Loc = Tok.getLocation(); 442987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 443987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis switch (Tok.getKind()) { 44455a7cefc846765ac7d142a63f773747a20518d71Chris Lattner case tok::identifier: // foo::bar 44555a7cefc846765ac7d142a63f773747a20518d71Chris Lattner case tok::coloncolon: // ::foo::bar 44655a7cefc846765ac7d142a63f773747a20518d71Chris Lattner assert(0 && "Annotation token should already be formed!"); 447987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis default: 448987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis assert(0 && "Not a simple-type-specifier token!"); 449987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis abort(); 45055a7cefc846765ac7d142a63f773747a20518d71Chris Lattner 451987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // type-name 452b31757b68afe06ba442a05775d08fe7aa0f6f889Chris Lattner case tok::annot_typename: { 453eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec, 454eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis Tok.getAnnotationValue()); 455987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 456987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 457987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 458987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // builtin types 459987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_short: 460987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec); 461987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 462987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_long: 463987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec); 464987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 465987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_signed: 466987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec); 467987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 468987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_unsigned: 469987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec); 470987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 471987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_void: 472987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec); 473987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 474987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_char: 475987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec); 476987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 477987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_int: 478987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec); 479987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 480987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_float: 481987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec); 482987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 483987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_double: 484987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec); 485987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 486987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_wchar_t: 487987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec); 488987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 489987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_bool: 490987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec); 491987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 492987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 493987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // GNU typeof support. 494987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_typeof: 495987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis ParseTypeofSpecifier(DS); 496987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.Finish(Diags, PP.getSourceManager(), getLang()); 497987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis return; 498987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 499b31757b68afe06ba442a05775d08fe7aa0f6f889Chris Lattner if (Tok.is(tok::annot_typename)) 500eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 501eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis else 502eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis DS.SetRangeEnd(Tok.getLocation()); 503987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis ConsumeToken(); 504987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.Finish(Diags, PP.getSourceManager(), getLang()); 505987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis} 5061cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5072f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++ 5082f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// [dcl.name]), which is a non-empty sequence of type-specifiers, 5092f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// e.g., "const short int". Note that the DeclSpec is *not* finished 5102f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// by parsing the type-specifier-seq, because these sequences are 5112f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// typically followed by some form of declarator. Returns true and 5122f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// emits diagnostics if this is not a type-specifier-seq, false 5132f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// otherwise. 5142f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 5152f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// type-specifier-seq: [C++ 8.1] 5162f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// type-specifier type-specifier-seq[opt] 5172f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 5182f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregorbool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) { 5192f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor DS.SetRangeStart(Tok.getLocation()); 5202f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor const char *PrevSpec = 0; 5212f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor int isInvalid = 0; 5222f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 5232f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Parse one or more of the type specifiers. 5247a0ab5f387722c83e19c7133b46b16988eb19e45Chris Lattner if (!ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec)) { 5251ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_operator_missing_type_specifier); 5262f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return true; 5272f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor } 5287a0ab5f387722c83e19c7133b46b16988eb19e45Chris Lattner 5297a0ab5f387722c83e19c7133b46b16988eb19e45Chris Lattner while (ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec)); 5302f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 5312f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return false; 5322f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor} 5332f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 53443c7bad105f742988e7ca40564285c83bea854a5Douglas Gregor/// TryParseOperatorFunctionId - Attempts to parse a C++ overloaded 5351cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator name (C++ [over.oper]). If successful, returns the 5361cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// predefined identifier that corresponds to that overloaded 5371cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator. Otherwise, returns NULL and does not consume any tokens. 5381cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// 5391cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator-function-id: [C++ 13.5] 5401cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// 'operator' operator 5411cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// 5421cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator: one of 5431cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// new delete new[] delete[] 5441cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// + - * / % ^ & | ~ 5451cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// ! = < > += -= *= /= %= 5461cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// ^= &= |= << >> >>= <<= == != 5471cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// <= >= && || ++ -- , ->* -> 5481cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// () [] 549e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas GregorOverloadedOperatorKind Parser::TryParseOperatorFunctionId() { 5509057a81efaf15c543aab1c5c8488e8a9ed2c0ff4Argyrios Kyrtzidis assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); 5511cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5521cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor OverloadedOperatorKind Op = OO_None; 5531cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor switch (NextToken().getKind()) { 5541cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::kw_new: 5551cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 5561cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'new' 5571cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor if (Tok.is(tok::l_square)) { 5581cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeBracket(); // '[' 5591cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 5601cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_Array_New; 5611cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } else { 5621cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_New; 5631cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } 564e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return Op; 5651cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5661cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::kw_delete: 5671cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 5681cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'delete' 5691cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor if (Tok.is(tok::l_square)) { 5701cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeBracket(); // '[' 5711cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 5721cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_Array_Delete; 5731cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } else { 5741cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_Delete; 5751cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } 576e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return Op; 5771cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 57802bcd4cd1a19121da12884aa4943226f72a81e6cDouglas Gregor#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 5791cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::Token: Op = OO_##Name; break; 58002bcd4cd1a19121da12884aa4943226f72a81e6cDouglas Gregor#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) 5811cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor#include "clang/Basic/OperatorKinds.def" 5821cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5831cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::l_paren: 5841cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 5851cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeParen(); // '(' 5861cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_paren, diag::err_expected_rparen); // ')' 587e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return OO_Call; 5881cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5891cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::l_square: 5901cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 5911cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeBracket(); // '[' 5921cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 593e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return OO_Subscript; 5941cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5951cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor default: 596e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return OO_None; 5971cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } 59843c7bad105f742988e7ca40564285c83bea854a5Douglas Gregor 59943c7bad105f742988e7ca40564285c83bea854a5Douglas Gregor ConsumeToken(); // 'operator' 60043c7bad105f742988e7ca40564285c83bea854a5Douglas Gregor ConsumeAnyToken(); // the operator itself 601e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return Op; 6021cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor} 6032f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 6042f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// ParseConversionFunctionId - Parse a C++ conversion-function-id, 6052f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// which expresses the name of a user-defined conversion operator 6062f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// (C++ [class.conv.fct]p1). Returns the type that this operator is 6072f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// specifying a conversion for, or NULL if there was an error. 6082f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 6092f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// conversion-function-id: [C++ 12.3.2] 6102f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// operator conversion-type-id 6112f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 6122f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// conversion-type-id: 6132f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// type-specifier-seq conversion-declarator[opt] 6142f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 6152f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// conversion-declarator: 6162f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// ptr-operator conversion-declarator[opt] 6172f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas GregorParser::TypeTy *Parser::ParseConversionFunctionId() { 6182f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); 6192f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor ConsumeToken(); // 'operator' 6202f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 6212f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Parse the type-specifier-seq. 6222f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor DeclSpec DS; 6232f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor if (ParseCXXTypeSpecifierSeq(DS)) 6242f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return 0; 6252f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 6262f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Parse the conversion-declarator, which is merely a sequence of 6272f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // ptr-operators. 6282f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor Declarator D(DS, Declarator::TypeNameContext); 6294c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParseDeclaratorInternal(D, /*DirectDeclParser=*/0); 6302f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 6312f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Finish up the type. 6322f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor Action::TypeResult Result = Actions.ActOnTypeName(CurScope, D); 6332f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor if (Result.isInvalid) 6342f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return 0; 6352f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor else 6362f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return Result.Val; 6372f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor} 6384c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6394c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate 6404c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// memory in a typesafe manner and call constructors. 64159232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// 64259232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// This method is called to parse the new expression after the optional :: has 64359232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// been already parsed. If the :: was present, "UseGlobal" is true and "Start" 64459232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// is its location. Otherwise, "Start" is the location of the 'new' token. 6454c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 6464c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-expression: 6474c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'new' new-placement[opt] new-type-id 6484c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer[opt] 6494c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 6504c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer[opt] 6514c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 6524c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-placement: 6534c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '(' expression-list ')' 6544c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 655cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// new-type-id: 656cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// type-specifier-seq new-declarator[opt] 657cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// 658cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// new-declarator: 659cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// ptr-operator new-declarator[opt] 660cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// direct-new-declarator 661cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// 6624c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer: 6634c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '(' expression-list[opt] ')' 6644c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// [C++0x] braced-init-list [TODO] 6654c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 66659232d35f5820e334b6c8b007ae8006f4390055dChris LattnerParser::OwningExprResult 66759232d35f5820e334b6c8b007ae8006f4390055dChris LattnerParser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { 66859232d35f5820e334b6c8b007ae8006f4390055dChris Lattner assert(Tok.is(tok::kw_new) && "expected 'new' token"); 66959232d35f5820e334b6c8b007ae8006f4390055dChris Lattner ConsumeToken(); // Consume 'new' 6704c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6714c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // A '(' now can be a new-placement or the '(' wrapping the type-id in the 6724c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // second form of new-expression. It can't be a new-type-id. 6734c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 674a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector PlacementArgs(Actions); 6754c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation PlacementLParen, PlacementRParen; 6764c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6774c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool ParenTypeId; 678cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl DeclSpec DS; 679cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 6804c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_paren)) { 6814c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // If it turns out to be a placement, we change the type location. 6824c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl PlacementLParen = ConsumeParen(); 683cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) { 684cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 68520df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 686cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 6874c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6884c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl PlacementRParen = MatchRHSPunctuation(tok::r_paren, PlacementLParen); 689cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (PlacementRParen.isInvalid()) { 690cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 69120df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 692cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 6934c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 694cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (PlacementArgs.empty()) { 6954c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Reset the placement locations. There was no placement. 6964c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl PlacementLParen = PlacementRParen = SourceLocation(); 6974c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParenTypeId = true; 6984c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } else { 6994c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // We still need the type. 7004c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_paren)) { 701cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SourceLocation LParen = ConsumeParen(); 702cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseSpecifierQualifierList(DS); 703cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclarator(DeclaratorInfo); 704cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl MatchRHSPunctuation(tok::r_paren, LParen); 7054c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParenTypeId = true; 7064c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } else { 707cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseCXXTypeSpecifierSeq(DS)) 708cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl DeclaratorInfo.setInvalidType(true); 709cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl else 710cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclaratorInternal(DeclaratorInfo, 711cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl &Parser::ParseDirectNewDeclarator); 7124c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParenTypeId = false; 7134c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7144c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7154c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } else { 716cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl // A new-type-id is a simplified type-id, where essentially the 717cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl // direct-declarator is replaced by a direct-new-declarator. 718cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseCXXTypeSpecifierSeq(DS)) 719cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl DeclaratorInfo.setInvalidType(true); 720cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl else 721cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclaratorInternal(DeclaratorInfo, 722cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl &Parser::ParseDirectNewDeclarator); 7234c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParenTypeId = false; 7244c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 725cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (DeclaratorInfo.getInvalidType()) { 726cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 72720df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 728cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 7294c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 730a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector ConstructorArgs(Actions); 7314c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation ConstructorLParen, ConstructorRParen; 7324c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7334c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_paren)) { 7344c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ConstructorLParen = ConsumeParen(); 7354c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.isNot(tok::r_paren)) { 7364c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl CommaLocsTy CommaLocs; 737cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseExpressionList(ConstructorArgs, CommaLocs)) { 738cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 73920df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 740cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 7414c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7424c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ConstructorRParen = MatchRHSPunctuation(tok::r_paren, ConstructorLParen); 743cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ConstructorRParen.isInvalid()) { 744cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 74520df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 746cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 7474c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7484c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 74920df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen, 75020df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl PlacementArgs.take(), PlacementArgs.size(), 75120df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl PlacementRParen, ParenTypeId, DeclaratorInfo, 75220df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl ConstructorLParen, ConstructorArgs.take(), 75320df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl ConstructorArgs.size(), ConstructorRParen)); 7544c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 7554c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7564c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be 7574c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// passed to ParseDeclaratorInternal. 7584c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 7594c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// direct-new-declarator: 7604c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '[' expression ']' 7614c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// direct-new-declarator '[' constant-expression ']' 7624c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 76359232d35f5820e334b6c8b007ae8006f4390055dChris Lattnervoid Parser::ParseDirectNewDeclarator(Declarator &D) { 7644c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Parse the array dimensions. 7654c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool first = true; 7664c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl while (Tok.is(tok::l_square)) { 7674c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation LLoc = ConsumeBracket(); 7682f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl OwningExprResult Size(first ? ParseExpression() 7692f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl : ParseConstantExpression()); 7700e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Size.isInvalid()) { 7714c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Recover 7724c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SkipUntil(tok::r_square); 7734c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return; 7744c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7754c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl first = false; 7764c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7774c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false, 778effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl Size.release(), LLoc)); 7794c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7804c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (MatchRHSPunctuation(tok::r_square, LLoc).isInvalid()) 7814c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return; 7824c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7834c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 7844c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7854c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id. 7864c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// This ambiguity appears in the syntax of the C++ new operator. 7874c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 7884c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-expression: 7894c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 7904c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer[opt] 7914c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 7924c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-placement: 7934c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '(' expression-list ')' 7944c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 795cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redlbool Parser::ParseExpressionListOrTypeId(ExprListTy &PlacementArgs, 79659232d35f5820e334b6c8b007ae8006f4390055dChris Lattner Declarator &D) { 7974c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // The '(' was already consumed. 7984c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (isTypeIdInParens()) { 799cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseSpecifierQualifierList(D.getMutableDeclSpec()); 800cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclarator(D); 801cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl return D.getInvalidType(); 8024c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 8034c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8044c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // It's not a type, it has to be an expression list. 8054c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Discard the comma locations - ActOnCXXNew has enough parameters. 8064c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl CommaLocsTy CommaLocs; 8074c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return ParseExpressionList(PlacementArgs, CommaLocs); 8084c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 8094c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8104c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used 8114c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// to free memory allocated by new. 8124c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 81359232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// This method is called to parse the 'delete' expression after the optional 81459232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// '::' has been already parsed. If the '::' was present, "UseGlobal" is true 81559232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// and "Start" is its location. Otherwise, "Start" is the location of the 81659232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// 'delete' token. 81759232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// 8184c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// delete-expression: 8194c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'delete' cast-expression 8204c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'delete' '[' ']' cast-expression 82159232d35f5820e334b6c8b007ae8006f4390055dChris LattnerParser::OwningExprResult 82259232d35f5820e334b6c8b007ae8006f4390055dChris LattnerParser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) { 82359232d35f5820e334b6c8b007ae8006f4390055dChris Lattner assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword"); 82459232d35f5820e334b6c8b007ae8006f4390055dChris Lattner ConsumeToken(); // Consume 'delete' 8254c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8264c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Array delete? 8274c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool ArrayDelete = false; 8284c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_square)) { 8294c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ArrayDelete = true; 8304c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation LHS = ConsumeBracket(); 8314c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation RHS = MatchRHSPunctuation(tok::r_square, LHS); 8324c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (RHS.isInvalid()) 83320df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 8344c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 8354c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8362f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl OwningExprResult Operand(ParseCastExpression(false)); 8370e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Operand.isInvalid()) 83820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return move(Operand); 8394c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 84020df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return Owned(Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, 84120df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl Operand.release())); 8424c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 84364b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl 84464b45f7e0d3167f040841ac2920aead7f080730dSebastian Redlstatic UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind) 84564b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl{ 84664b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl switch(kind) { 84764b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl default: assert(false && "Not a known unary type trait."); 84864b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___has_nothrow_assign: return UTT_HasNothrowAssign; 84964b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___has_nothrow_copy: return UTT_HasNothrowCopy; 85064b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___has_nothrow_constructor: return UTT_HasNothrowConstructor; 85164b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___has_trivial_assign: return UTT_HasTrivialAssign; 85264b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___has_trivial_copy: return UTT_HasTrivialCopy; 85364b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___has_trivial_constructor: return UTT_HasTrivialConstructor; 85464b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___has_trivial_destructor: return UTT_HasTrivialDestructor; 85564b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___has_virtual_destructor: return UTT_HasVirtualDestructor; 85664b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___is_abstract: return UTT_IsAbstract; 85764b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___is_class: return UTT_IsClass; 85864b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___is_empty: return UTT_IsEmpty; 85964b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___is_enum: return UTT_IsEnum; 86064b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___is_pod: return UTT_IsPOD; 86164b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___is_polymorphic: return UTT_IsPolymorphic; 86264b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___is_union: return UTT_IsUnion; 86364b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl } 86464b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl} 86564b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl 86664b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl/// ParseUnaryTypeTrait - Parse the built-in unary type-trait 86764b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl/// pseudo-functions that allow implementation of the TR1/C++0x type traits 86864b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl/// templates. 86964b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl/// 87064b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl/// primary-expression: 87164b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl/// [GNU] unary-type-trait '(' type-id ')' 87264b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl/// 87364b45f7e0d3167f040841ac2920aead7f080730dSebastian RedlParser::OwningExprResult Parser::ParseUnaryTypeTrait() 87464b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl{ 87564b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl UnaryTypeTrait UTT = UnaryTypeTraitFromTokKind(Tok.getKind()); 87664b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl SourceLocation Loc = ConsumeToken(); 87764b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl 87864b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl SourceLocation LParen = Tok.getLocation(); 87964b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen)) 88064b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl return ExprError(); 88164b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl 88264b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl // FIXME: Error reporting absolutely sucks! If the this fails to parse a type 88364b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl // there will be cryptic errors about mismatched parentheses and missing 88464b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl // specifiers. 88564b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl TypeTy *Ty = ParseTypeName(); 88664b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl 88764b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl SourceLocation RParen = MatchRHSPunctuation(tok::r_paren, LParen); 88864b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl 88964b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl return Actions.ActOnUnaryTypeTrait(UTT, Loc, LParen, Ty, RParen); 89064b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl} 891