ParseExprCXX.cpp revision 4bdd91c09fd59e0c154d759288beff300e31e1d0
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/// 324bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidisbool Parser::MaybeParseCXXScopeSpecifier(CXXScopeSpec &SS) { 334bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis assert(getLang().CPlusPlus && 344bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis "Call sites of this function should be guarded by checking for C++."); 354bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis 364bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis if (Tok.isNot(tok::coloncolon) && 374bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis Tok.isNot(tok::annot_cxxscope) && 384bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis (Tok.isNot(tok::identifier) || NextToken().isNot(tok::coloncolon))) 394bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis return false; 40eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 41eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis if (Tok.is(tok::annot_cxxscope)) { 42eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setScopeRep(Tok.getAnnotationValue()); 43eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setRange(Tok.getAnnotationRange()); 44eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis ConsumeToken(); 454bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis return true; 46eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 47eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 48eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setBeginLoc(Tok.getLocation()); 49eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 50eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // '::' 51eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 52eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis if (Tok.is(tok::coloncolon)) { 53eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // Global scope. 54eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation CCLoc = ConsumeToken(); 55eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc)); 56eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setEndLoc(CCLoc); 57eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 58eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 59eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // nested-name-specifier: 60eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // type-name '::' 61eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // namespace-name '::' 62eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // nested-name-specifier identifier '::' 63eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // nested-name-specifier 'template'[opt] simple-template-id '::' [TODO] 64eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 65eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis while (Tok.is(tok::identifier) && NextToken().is(tok::coloncolon)) { 66eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis IdentifierInfo *II = Tok.getIdentifierInfo(); 67eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation IdLoc = ConsumeToken(); 68eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis assert(Tok.is(tok::coloncolon) && 69eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis "NextToken() not working properly!"); 70eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation CCLoc = ConsumeToken(); 71eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis if (SS.isInvalid()) 72eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis continue; 73eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 74eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setScopeRep( 75eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, IdLoc, CCLoc, *II) ); 76eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setEndLoc(CCLoc); 77eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 784bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis 794bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis return true; 80eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis} 81eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 82eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// ParseCXXIdExpression - Handle id-expression. 83eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 84eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// id-expression: 85eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// unqualified-id 86eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// qualified-id 87eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 88eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// unqualified-id: 89eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// identifier 90eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// operator-function-id 91eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// conversion-function-id [TODO] 92eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '~' class-name [TODO] 93eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// template-id [TODO] 94eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 95eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// qualified-id: 96eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 97eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' identifier 98eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' operator-function-id 99eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' template-id [TODO] 100eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 101eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier: 102eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// type-name '::' 103eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// namespace-name '::' 104eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier identifier '::' 105eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier 'template'[opt] simple-template-id '::' [TODO] 106eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 107eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// NOTE: The standard specifies that, for qualified-id, the parser does not 108eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// expect: 109eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 110eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' conversion-function-id 111eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' '~' class-name 112eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 113eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// This may cause a slight inconsistency on diagnostics: 114eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 115eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// class C {}; 116eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// namespace A {} 117eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// void f() { 118eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// :: A :: ~ C(); // Some Sema error about using destructor with a 119eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// // namespace. 120eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// :: ~ C(); // Some Parser error like 'unexpected ~'. 121eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// } 122eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 123eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// We simplify the parser a bit and make it work like: 124eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 125eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// qualified-id: 126eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 127eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' unqualified-id 128eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 129eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// That way Sema can handle and report similar errors for namespaces and the 130eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// global scope. 131eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 132eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios KyrtzidisParser::ExprResult Parser::ParseCXXIdExpression() { 133eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // qualified-id: 134eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 135eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // '::' unqualified-id 136eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // 137eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis CXXScopeSpec SS; 1384bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis MaybeParseCXXScopeSpecifier(SS); 139eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 140eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // unqualified-id: 141eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // identifier 142eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // operator-function-id 1432def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor // conversion-function-id 144eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // '~' class-name [TODO] 145eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // template-id [TODO] 146eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // 147eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis switch (Tok.getKind()) { 148eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis default: 149eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis return Diag(Tok, diag::err_expected_unqualified_id); 150eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 151eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis case tok::identifier: { 152eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // Consume the identifier so that we can see if it is followed by a '('. 153eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis IdentifierInfo &II = *Tok.getIdentifierInfo(); 154eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation L = ConsumeToken(); 155eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis return Actions.ActOnIdentifierExpr(CurScope, L, II, 156eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis Tok.is(tok::l_paren), &SS); 157eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 158eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 159eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis case tok::kw_operator: { 160eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation OperatorLoc = Tok.getLocation(); 161e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor if (OverloadedOperatorKind Op = TryParseOperatorFunctionId()) { 162487a75ab300552e42afa45b8199133f838a40e5fDouglas Gregor return Actions.ActOnCXXOperatorFunctionIdExpr(CurScope, OperatorLoc, Op, 163487a75ab300552e42afa45b8199133f838a40e5fDouglas Gregor Tok.is(tok::l_paren), SS); 1642def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor } else if (TypeTy *Type = ParseConversionFunctionId()) { 165487a75ab300552e42afa45b8199133f838a40e5fDouglas Gregor return Actions.ActOnCXXConversionFunctionExpr(CurScope, OperatorLoc, 166487a75ab300552e42afa45b8199133f838a40e5fDouglas Gregor Type, Tok.is(tok::l_paren), 167487a75ab300552e42afa45b8199133f838a40e5fDouglas Gregor SS); 168eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 1692def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor 1702def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor // We already complained about a bad conversion-function-id, 1712def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor // above. 1722def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor return true; 173eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 174eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 175eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } // switch. 176eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 177eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis assert(0 && "The switch was supposed to take care everything."); 178eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis} 179eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 1805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCXXCasts - This handles the various ways to cast expressions to another 1815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// type. 1825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 1835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// postfix-expression: [C++ 5.2p1] 1845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'dynamic_cast' '<' type-name '>' '(' expression ')' 1855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'static_cast' '<' type-name '>' '(' expression ')' 1865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'reinterpret_cast' '<' type-name '>' '(' expression ')' 1875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'const_cast' '<' type-name '>' '(' expression ')' 1885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 1895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerParser::ExprResult Parser::ParseCXXCasts() { 1905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer tok::TokenKind Kind = Tok.getKind(); 1915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const char *CastName = 0; // For error messages 1925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer switch (Kind) { 1945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer default: assert(0 && "Unknown C++ cast!"); abort(); 1955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_const_cast: CastName = "const_cast"; break; 1965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_dynamic_cast: CastName = "dynamic_cast"; break; 1975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break; 1985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_static_cast: CastName = "static_cast"; break; 1995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation OpLoc = ConsumeToken(); 2025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation LAngleBracketLoc = Tok.getLocation(); 2035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName)) 2055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return ExprResult(true); 2065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer TypeTy *CastTy = ParseTypeName(); 2085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation RAngleBracketLoc = Tok.getLocation(); 2095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2101ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner if (ExpectAndConsume(tok::greater, diag::err_expected_greater)) 21128eb7e992b9a266abb300da25b6d3c1557cec361Chris Lattner return Diag(LAngleBracketLoc, diag::note_matching) << "<"; 2125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation LParenLoc = Tok.getLocation(), RParenLoc; 2145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2151ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner if (Tok.isNot(tok::l_paren)) 2161ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner return Diag(Tok, diag::err_expected_lparen_after) << CastName; 2175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ExprResult Result = ParseSimpleParenExpression(RParenLoc); 2195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (!Result.isInvalid) 22149badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor Result = Actions.ActOnCXXNamedCast(OpLoc, Kind, 22249badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor LAngleBracketLoc, CastTy, RAngleBracketLoc, 22349badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor LParenLoc, Result.Val, RParenLoc); 2245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return Result; 2265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 2275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 228c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// ParseCXXTypeid - This handles the C++ typeid expression. 229c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 230c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// postfix-expression: [C++ 5.2p1] 231c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 'typeid' '(' expression ')' 232c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 'typeid' '(' type-id ')' 233c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 234c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian RedlParser::ExprResult Parser::ParseCXXTypeid() { 235c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!"); 236c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 237c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SourceLocation OpLoc = ConsumeToken(); 238c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SourceLocation LParenLoc = Tok.getLocation(); 239c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SourceLocation RParenLoc; 240c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 241c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl // typeid expressions are always parenthesized. 242c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, 243c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl "typeid")) 244c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl return ExprResult(true); 245c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 246c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Parser::ExprResult Result; 247c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 248c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl if (isTypeIdInParens()) { 249c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl TypeTy *Ty = ParseTypeName(); 250c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 251c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl // Match the ')'. 252c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl MatchRHSPunctuation(tok::r_paren, LParenLoc); 253c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 254c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl if (!Ty) 255c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl return ExprResult(true); 256c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 257c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true, 258c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Ty, RParenLoc); 259c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl } else { 260c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Result = ParseExpression(); 261c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 262c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl // Match the ')'. 263c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl if (Result.isInvalid) 264c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SkipUntil(tok::r_paren); 265c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl else { 266c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl MatchRHSPunctuation(tok::r_paren, LParenLoc); 267c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 268c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false, 269c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Result.Val, RParenLoc); 270c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl } 271c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl } 272c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 273c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl return Result; 274c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl} 275c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 2765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCXXBoolLiteral - This handles the C++ Boolean literals. 2775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 2785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// boolean-literal: [C++ 2.13.5] 2795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'true' 2805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'false' 2815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerParser::ExprResult Parser::ParseCXXBoolLiteral() { 2825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer tok::TokenKind Kind = Tok.getKind(); 2831b273c403734d343d720acb28f04011807c8aa56Steve Naroff return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind); 2845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 28550dd289f45738ed22b7583d52ed2525b927042ffChris Lattner 28650dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// ParseThrowExpression - This handles the C++ throw expression. 28750dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// 28850dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// throw-expression: [C++ 15] 28950dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// 'throw' assignment-expression[opt] 29050dd289f45738ed22b7583d52ed2525b927042ffChris LattnerParser::ExprResult Parser::ParseThrowExpression() { 29150dd289f45738ed22b7583d52ed2525b927042ffChris Lattner assert(Tok.is(tok::kw_throw) && "Not throw!"); 29250dd289f45738ed22b7583d52ed2525b927042ffChris Lattner SourceLocation ThrowLoc = ConsumeToken(); // Eat the throw token. 2933e3d310a8c74f7e0ccaf2e0a64400d15b8cb5556Chris Lattner 2942a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // If the current token isn't the start of an assignment-expression, 2952a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // then the expression is not present. This handles things like: 2962a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // "C ? throw : (void)42", which is crazy but legal. 2972a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner switch (Tok.getKind()) { // FIXME: move this predicate somewhere common. 2982a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::semi: 2992a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_paren: 3002a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_square: 3012a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_brace: 3022a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::colon: 3032a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::comma: 30450dd289f45738ed22b7583d52ed2525b927042ffChris Lattner return Actions.ActOnCXXThrow(ThrowLoc); 30550dd289f45738ed22b7583d52ed2525b927042ffChris Lattner 3062a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner default: 3073e3d310a8c74f7e0ccaf2e0a64400d15b8cb5556Chris Lattner ExprResult Expr = ParseAssignmentExpression(); 3082a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner if (Expr.isInvalid) return Expr; 3092a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner return Actions.ActOnCXXThrow(ThrowLoc, Expr.Val); 3102a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner } 31150dd289f45738ed22b7583d52ed2525b927042ffChris Lattner} 3124cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 3134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXThis - This handles the C++ 'this' pointer. 3144cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 3154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// C++ 9.3.2: In the body of a non-static member function, the keyword this is 3164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// a non-lvalue expression whose value is the address of the object for which 3174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// the function is called. 3184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios KyrtzidisParser::ExprResult Parser::ParseCXXThis() { 3194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis assert(Tok.is(tok::kw_this) && "Not 'this'!"); 3204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SourceLocation ThisLoc = ConsumeToken(); 321289d77302aa81dc24bf7aa75b36cb00a70a44bb5Argyrios Kyrtzidis return Actions.ActOnCXXThis(ThisLoc); 3224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 323987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 324987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// ParseCXXTypeConstructExpression - Parse construction of a specified type. 325987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// Can be interpreted either as function-style casting ("int(x)") 326987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// or class type construction ("ClassType(x,y,z)") 327987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// or creation of a value-initialized type ("int()"). 328987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 329987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// postfix-expression: [C++ 5.2p1] 330987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3] 331987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// typename-specifier '(' expression-list[opt] ')' [TODO] 332987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 333987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios KyrtzidisParser::ExprResult Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { 334987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 335987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis TypeTy *TypeRep = Actions.ActOnTypeName(CurScope, DeclaratorInfo).Val; 336987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 337987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis assert(Tok.is(tok::l_paren) && "Expected '('!"); 338987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SourceLocation LParenLoc = ConsumeParen(); 339987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 340a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector Exprs(Actions); 341987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis CommaLocsTy CommaLocs; 342987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 343987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis if (Tok.isNot(tok::r_paren)) { 344987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis if (ParseExpressionList(Exprs, CommaLocs)) { 345987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SkipUntil(tok::r_paren); 346987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis return ExprResult(true); 347987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 348987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 349987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 350987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // Match the ')'. 351987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 352987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 353987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&& 354987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis "Unexpected number of commas!"); 355987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis return Actions.ActOnCXXTypeConstructExpr(DS.getSourceRange(), TypeRep, 356987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis LParenLoc, 357a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl Exprs.take(), Exprs.size(), 358987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis &CommaLocs[0], RParenLoc); 359987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis} 360987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 36171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// ParseCXXCondition - if/switch/while/for condition expression. 36271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// 36371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// condition: 36471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// expression 36571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// type-specifier-seq declarator '=' assignment-expression 36671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 36771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// '=' assignment-expression 36871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// 36971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios KyrtzidisParser::ExprResult Parser::ParseCXXCondition() { 370a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis if (!isCXXConditionDeclaration()) 37171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis return ParseExpression(); // expression 37271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 37371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SourceLocation StartLoc = Tok.getLocation(); 37471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 37571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // type-specifier-seq 37671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis DeclSpec DS; 37771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis ParseSpecifierQualifierList(DS); 37871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 37971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // declarator 38071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::ConditionContext); 38171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 38271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 38371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // simple-asm-expr[opt] 38471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (Tok.is(tok::kw_asm)) { 38571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis ExprResult AsmLabel = ParseSimpleAsm(); 38671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (AsmLabel.isInvalid) { 38771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SkipUntil(tok::semi); 38871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis return true; 38971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis } 39071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis DeclaratorInfo.setAsmLabel(AsmLabel.Val); 39171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis } 39271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 39371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // If attributes are present, parse them. 39471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (Tok.is(tok::kw___attribute)) 39571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis DeclaratorInfo.AddAttributes(ParseAttributes()); 39671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 39771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // '=' assignment-expression 39871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (Tok.isNot(tok::equal)) 39971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis return Diag(Tok, diag::err_expected_equal_after_declarator); 40071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SourceLocation EqualLoc = ConsumeToken(); 40171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis ExprResult AssignExpr = ParseAssignmentExpression(); 40271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (AssignExpr.isInvalid) 40371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis return true; 40471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 40571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis return Actions.ActOnCXXConditionDeclarationExpr(CurScope, StartLoc, 40671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis DeclaratorInfo, 40771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis EqualLoc, AssignExpr.Val); 40871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis} 40971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 410987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers. 411987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// This should only be called when the current token is known to be part of 412987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// simple-type-specifier. 413987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 414987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// simple-type-specifier: 415eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier[opt] type-name 416987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template' simple-template-id [TODO] 417987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// char 418987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// wchar_t 419987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// bool 420987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// short 421987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// int 422987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// long 423987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// signed 424987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// unsigned 425987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// float 426987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// double 427987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// void 428987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// [GNU] typeof-specifier 429987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// [C++0x] auto [TODO] 430987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 431987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// type-name: 432987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// class-name 433987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// enum-name 434987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// typedef-name 435987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 436987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidisvoid Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { 437eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // Annotate typenames and C++ scope specifiers. 438eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis TryAnnotateTypeOrScopeToken(); 439eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 440987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetRangeStart(Tok.getLocation()); 441987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis const char *PrevSpec; 442987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SourceLocation Loc = Tok.getLocation(); 443987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 444987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis switch (Tok.getKind()) { 445987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis default: 446987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis assert(0 && "Not a simple-type-specifier token!"); 447987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis abort(); 448987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 449987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // type-name 450eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis case tok::annot_qualtypename: { 451eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec, 452eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis Tok.getAnnotationValue()); 453987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 454987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 455987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 456987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // builtin types 457987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_short: 458987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec); 459987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 460987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_long: 461987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec); 462987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 463987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_signed: 464987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec); 465987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 466987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_unsigned: 467987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec); 468987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 469987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_void: 470987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec); 471987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 472987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_char: 473987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec); 474987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 475987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_int: 476987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec); 477987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 478987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_float: 479987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec); 480987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 481987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_double: 482987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec); 483987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 484987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_wchar_t: 485987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec); 486987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 487987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_bool: 488987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec); 489987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 490987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 491987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // GNU typeof support. 492987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_typeof: 493987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis ParseTypeofSpecifier(DS); 494987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.Finish(Diags, PP.getSourceManager(), getLang()); 495987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis return; 496987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 497eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis if (Tok.is(tok::annot_qualtypename)) 498eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 499eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis else 500eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis DS.SetRangeEnd(Tok.getLocation()); 501987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis ConsumeToken(); 502987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.Finish(Diags, PP.getSourceManager(), getLang()); 503987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis} 5041cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5052f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++ 5062f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// [dcl.name]), which is a non-empty sequence of type-specifiers, 5072f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// e.g., "const short int". Note that the DeclSpec is *not* finished 5082f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// by parsing the type-specifier-seq, because these sequences are 5092f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// typically followed by some form of declarator. Returns true and 5102f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// emits diagnostics if this is not a type-specifier-seq, false 5112f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// otherwise. 5122f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 5132f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// type-specifier-seq: [C++ 8.1] 5142f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// type-specifier type-specifier-seq[opt] 5152f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 5162f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregorbool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) { 5172f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor DS.SetRangeStart(Tok.getLocation()); 5182f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor const char *PrevSpec = 0; 5192f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor int isInvalid = 0; 5202f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 5212f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Parse one or more of the type specifiers. 5222f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor if (!MaybeParseTypeSpecifier(DS, isInvalid, PrevSpec)) { 5231ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_operator_missing_type_specifier); 5242f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return true; 5252f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor } 526b90585c3c65db9ab587674586602729edbd096aaDaniel Dunbar while (MaybeParseTypeSpecifier(DS, isInvalid, PrevSpec)) ; 5272f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 5282f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return false; 5292f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor} 5302f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 53143c7bad105f742988e7ca40564285c83bea854a5Douglas Gregor/// TryParseOperatorFunctionId - Attempts to parse a C++ overloaded 5321cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator name (C++ [over.oper]). If successful, returns the 5331cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// predefined identifier that corresponds to that overloaded 5341cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator. Otherwise, returns NULL and does not consume any tokens. 5351cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// 5361cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator-function-id: [C++ 13.5] 5371cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// 'operator' operator 5381cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// 5391cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator: one of 5401cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// new delete new[] delete[] 5411cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// + - * / % ^ & | ~ 5421cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// ! = < > += -= *= /= %= 5431cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// ^= &= |= << >> >>= <<= == != 5441cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// <= >= && || ++ -- , ->* -> 5451cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// () [] 546e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas GregorOverloadedOperatorKind Parser::TryParseOperatorFunctionId() { 5479057a81efaf15c543aab1c5c8488e8a9ed2c0ff4Argyrios Kyrtzidis assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); 5481cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5491cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor OverloadedOperatorKind Op = OO_None; 5501cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor switch (NextToken().getKind()) { 5511cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::kw_new: 5521cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 5531cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'new' 5541cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor if (Tok.is(tok::l_square)) { 5551cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeBracket(); // '[' 5561cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 5571cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_Array_New; 5581cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } else { 5591cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_New; 5601cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } 561e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return Op; 5621cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5631cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::kw_delete: 5641cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 5651cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'delete' 5661cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor if (Tok.is(tok::l_square)) { 5671cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeBracket(); // '[' 5681cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 5691cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_Array_Delete; 5701cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } else { 5711cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_Delete; 5721cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } 573e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return Op; 5741cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 57502bcd4cd1a19121da12884aa4943226f72a81e6cDouglas Gregor#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 5761cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::Token: Op = OO_##Name; break; 57702bcd4cd1a19121da12884aa4943226f72a81e6cDouglas Gregor#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) 5781cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor#include "clang/Basic/OperatorKinds.def" 5791cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5801cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::l_paren: 5811cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 5821cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeParen(); // '(' 5831cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_paren, diag::err_expected_rparen); // ')' 584e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return OO_Call; 5851cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5861cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::l_square: 5871cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 5881cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeBracket(); // '[' 5891cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 590e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return OO_Subscript; 5911cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5921cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor default: 593e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return OO_None; 5941cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } 59543c7bad105f742988e7ca40564285c83bea854a5Douglas Gregor 59643c7bad105f742988e7ca40564285c83bea854a5Douglas Gregor ConsumeToken(); // 'operator' 59743c7bad105f742988e7ca40564285c83bea854a5Douglas Gregor ConsumeAnyToken(); // the operator itself 598e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return Op; 5991cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor} 6002f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 6012f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// ParseConversionFunctionId - Parse a C++ conversion-function-id, 6022f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// which expresses the name of a user-defined conversion operator 6032f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// (C++ [class.conv.fct]p1). Returns the type that this operator is 6042f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// specifying a conversion for, or NULL if there was an error. 6052f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 6062f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// conversion-function-id: [C++ 12.3.2] 6072f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// operator conversion-type-id 6082f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 6092f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// conversion-type-id: 6102f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// type-specifier-seq conversion-declarator[opt] 6112f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 6122f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// conversion-declarator: 6132f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// ptr-operator conversion-declarator[opt] 6142f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas GregorParser::TypeTy *Parser::ParseConversionFunctionId() { 6152f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); 6162f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor ConsumeToken(); // 'operator' 6172f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 6182f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Parse the type-specifier-seq. 6192f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor DeclSpec DS; 6202f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor if (ParseCXXTypeSpecifierSeq(DS)) 6212f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return 0; 6222f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 6232f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Parse the conversion-declarator, which is merely a sequence of 6242f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // ptr-operators. 6252f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor Declarator D(DS, Declarator::TypeNameContext); 6264c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParseDeclaratorInternal(D, /*DirectDeclParser=*/0); 6272f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 6282f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Finish up the type. 6292f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor Action::TypeResult Result = Actions.ActOnTypeName(CurScope, D); 6302f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor if (Result.isInvalid) 6312f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return 0; 6322f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor else 6332f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return Result.Val; 6342f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor} 6354c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6364c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate 6374c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// memory in a typesafe manner and call constructors. 6384c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 6394c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-expression: 6404c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'new' new-placement[opt] new-type-id 6414c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer[opt] 6424c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 6434c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer[opt] 6444c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 6454c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-placement: 6464c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '(' expression-list ')' 6474c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 6484c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer: 6494c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '(' expression-list[opt] ')' 6504c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// [C++0x] braced-init-list [TODO] 6514c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 6524c5d320a7581f4b80b151630c91cea5727fa9923Sebastian RedlParser::ExprResult Parser::ParseCXXNewExpression() 6534c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl{ 6544c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl assert((Tok.is(tok::coloncolon) || Tok.is(tok::kw_new)) && 6554c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl "Expected :: or 'new' keyword"); 6564c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6574c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation Start = Tok.getLocation(); 6584c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool UseGlobal = false; 6594c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::coloncolon)) { 6604c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl UseGlobal = true; 6614c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ConsumeToken(); 6624c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 6634c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6644c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl assert(Tok.is(tok::kw_new) && "Lookahead should have ensured 'new'"); 6654c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Consume 'new' 6664c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ConsumeToken(); 6674c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6684c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // A '(' now can be a new-placement or the '(' wrapping the type-id in the 6694c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // second form of new-expression. It can't be a new-type-id. 6704c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 671a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector PlacementArgs(Actions); 6724c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation PlacementLParen, PlacementRParen; 6734c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6744c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl TypeTy *Ty = 0; 6754c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation TyStart, TyEnd; 6764c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool ParenTypeId; 6774c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_paren)) { 6784c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // If it turns out to be a placement, we change the type location. 6794c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl PlacementLParen = ConsumeParen(); 6804c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl TyStart = Tok.getLocation(); 6814c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (ParseExpressionListOrTypeId(PlacementArgs, Ty)) 6824c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return true; 6834c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl TyEnd = Tok.getLocation(); 6844c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6854c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl PlacementRParen = MatchRHSPunctuation(tok::r_paren, PlacementLParen); 6864c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (PlacementRParen.isInvalid()) 6874c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return true; 6884c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6894c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Ty) { 6904c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Reset the placement locations. There was no placement. 6914c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl PlacementLParen = PlacementRParen = SourceLocation(); 6924c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParenTypeId = true; 6934c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } else { 6944c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // We still need the type. 6954c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_paren)) { 6964c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ConsumeParen(); 6974c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl TyStart = Tok.getLocation(); 6984c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl Ty = ParseTypeName(/*CXXNewMode=*/true); 6994c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParenTypeId = true; 7004c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } else { 7014c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl TyStart = Tok.getLocation(); 7024c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl Ty = ParseNewTypeId(); 7034c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParenTypeId = false; 7044c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7054c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (!Ty) 7064c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return true; 7074c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl TyEnd = Tok.getLocation(); 7084c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7094c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } else { 7104c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl TyStart = Tok.getLocation(); 7114c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl Ty = ParseNewTypeId(); 7124c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (!Ty) 7134c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return true; 7144c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl TyEnd = Tok.getLocation(); 7154c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParenTypeId = false; 7164c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7174c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 718a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector ConstructorArgs(Actions); 7194c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation ConstructorLParen, ConstructorRParen; 7204c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7214c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_paren)) { 7224c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ConstructorLParen = ConsumeParen(); 7234c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.isNot(tok::r_paren)) { 7244c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl CommaLocsTy CommaLocs; 7254c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (ParseExpressionList(ConstructorArgs, CommaLocs)) 7264c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return true; 7274c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7284c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ConstructorRParen = MatchRHSPunctuation(tok::r_paren, ConstructorLParen); 7294c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (ConstructorRParen.isInvalid()) 7304c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return true; 7314c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7324c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7334c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen, 734a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl PlacementArgs.take(), PlacementArgs.size(), 7354c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl PlacementRParen, ParenTypeId, TyStart, Ty, TyEnd, 736a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ConstructorLParen, ConstructorArgs.take(), 7374c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ConstructorArgs.size(), ConstructorRParen); 7384c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 7394c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7404c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseNewTypeId - Parses a type ID as it appears in a new expression. 7414c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// The most interesting part of this is the new-declarator, which can be a 7424c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// multi-dimensional array, of which the first has a non-constant expression as 7434c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// the size, e.g. 7444c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// @code new int[runtimeSize()][2][2] @endcode 7454c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 7464c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-type-id: 7474c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// type-specifier-seq new-declarator[opt] 7484c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 7494c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-declarator: 7504c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ptr-operator new-declarator[opt] 7514c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// direct-new-declarator 7524c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 7534c5d320a7581f4b80b151630c91cea5727fa9923Sebastian RedlParser::TypeTy * Parser::ParseNewTypeId() 7544c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl{ 7554c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl DeclSpec DS; 7564c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (ParseCXXTypeSpecifierSeq(DS)) 7574c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return 0; 7584c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7594c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // A new-declarator is a simplified version of a declarator. We use 7604c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // ParseDeclaratorInternal, but pass our own direct declarator parser, 7614c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // one that parses a direct-new-declarator. 7624c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 7634c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParseDeclaratorInternal(DeclaratorInfo, &Parser::ParseDirectNewDeclarator); 7644c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7654c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl TypeTy *Ty = Actions.ActOnTypeName(CurScope, DeclaratorInfo, 7664c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl /*CXXNewMode=*/true).Val; 7674c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return DeclaratorInfo.getInvalidType() ? 0 : Ty; 7684c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 7694c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7704c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be 7714c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// passed to ParseDeclaratorInternal. 7724c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 7734c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// direct-new-declarator: 7744c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '[' expression ']' 7754c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// direct-new-declarator '[' constant-expression ']' 7764c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 7774c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redlvoid Parser::ParseDirectNewDeclarator(Declarator &D) 7784c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl{ 7794c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Parse the array dimensions. 7804c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool first = true; 7814c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl while (Tok.is(tok::l_square)) { 7824c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation LLoc = ConsumeBracket(); 7834c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ExprResult Size = first ? ParseExpression() : ParseConstantExpression(); 7844c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Size.isInvalid) { 7854c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Recover 7864c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SkipUntil(tok::r_square); 7874c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return; 7884c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7894c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl first = false; 7904c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7914c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false, 7924c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl Size.Val, LLoc)); 7934c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7944c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (MatchRHSPunctuation(tok::r_square, LLoc).isInvalid()) 7954c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return; 7964c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7974c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 7984c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7994c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id. 8004c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// This ambiguity appears in the syntax of the C++ new operator. 8014c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 8024c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-expression: 8034c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 8044c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer[opt] 8054c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 8064c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-placement: 8074c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '(' expression-list ')' 8084c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 8094c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redlbool Parser::ParseExpressionListOrTypeId(ExprListTy &PlacementArgs, TypeTy *&Ty) 8104c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl{ 8114c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // The '(' was already consumed. 8124c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (isTypeIdInParens()) { 8134c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl Ty = ParseTypeName(/*CXXNewMode=*/true); 8144c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return Ty == 0; 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/// 8264c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// delete-expression: 8274c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'delete' cast-expression 8284c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'delete' '[' ']' cast-expression 8294c5d320a7581f4b80b151630c91cea5727fa9923Sebastian RedlParser::ExprResult Parser::ParseCXXDeleteExpression() 8304c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl{ 8314c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl assert((Tok.is(tok::coloncolon) || Tok.is(tok::kw_delete)) && 8324c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl "Expected :: or 'delete' keyword"); 8334c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8344c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation Start = Tok.getLocation(); 8354c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool UseGlobal = false; 8364c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::coloncolon)) { 8374c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl UseGlobal = true; 8384c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ConsumeToken(); 8394c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 8404c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8414c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl assert(Tok.is(tok::kw_delete) && "Lookahead should have ensured 'delete'"); 8424c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Consume 'delete' 8434c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ConsumeToken(); 8444c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8454c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Array delete? 8464c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool ArrayDelete = false; 8474c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_square)) { 8484c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ArrayDelete = true; 8494c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation LHS = ConsumeBracket(); 8504c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation RHS = MatchRHSPunctuation(tok::r_square, LHS); 8514c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (RHS.isInvalid()) 8524c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return true; 8534c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 8544c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8554c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ExprResult Operand = ParseCastExpression(false); 8564c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Operand.isInvalid) 8574c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return Operand; 8584c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8594c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, Operand.Val); 8604c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 861