ParseExprCXX.cpp revision effa8d1c97b00a3f53e972b0e61d9aade5ea1c57
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 4100c028b4a127c98cc617811b9d1e72bd7d641895Zhongxing Xu // ::new and ::delete aren't nested-name-specifiers, so parsing the :: as 42bcf293bb63d1ce9f77ef8232432d979750d30b70Sebastian Redl // a scope specifier only makes things more complicated. 43fb4ccd7152723ac6190eb379250cfe7516cfd1b8Sebastian Redl if (Tok.is(tok::coloncolon) && (NextToken().is(tok::kw_new) || 44fb4ccd7152723ac6190eb379250cfe7516cfd1b8Sebastian Redl NextToken().is(tok::kw_delete))) 45fb4ccd7152723ac6190eb379250cfe7516cfd1b8Sebastian Redl return false; 46fb4ccd7152723ac6190eb379250cfe7516cfd1b8Sebastian Redl 47eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis if (Tok.is(tok::annot_cxxscope)) { 48eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setScopeRep(Tok.getAnnotationValue()); 49eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setRange(Tok.getAnnotationRange()); 50eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis ConsumeToken(); 514bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis return true; 52eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 53eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 54eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setBeginLoc(Tok.getLocation()); 55eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 56eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // '::' 57eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 58eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis if (Tok.is(tok::coloncolon)) { 59eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // Global scope. 60eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation CCLoc = ConsumeToken(); 61eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc)); 62eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setEndLoc(CCLoc); 63eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 64eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 65eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // nested-name-specifier: 66eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // type-name '::' 67eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // namespace-name '::' 68eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // nested-name-specifier identifier '::' 69eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // nested-name-specifier 'template'[opt] simple-template-id '::' [TODO] 70eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 71eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis while (Tok.is(tok::identifier) && NextToken().is(tok::coloncolon)) { 72eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis IdentifierInfo *II = Tok.getIdentifierInfo(); 73eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation IdLoc = ConsumeToken(); 74eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis assert(Tok.is(tok::coloncolon) && 75eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis "NextToken() not working properly!"); 76eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation CCLoc = ConsumeToken(); 77eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis if (SS.isInvalid()) 78eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis continue; 79eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 80eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setScopeRep( 81eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, IdLoc, CCLoc, *II) ); 82eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SS.setEndLoc(CCLoc); 83eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 844bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis 854bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis return true; 86eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis} 87eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 88eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// ParseCXXIdExpression - Handle id-expression. 89eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 90eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// id-expression: 91eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// unqualified-id 92eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// qualified-id 93eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 94eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// unqualified-id: 95eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// identifier 96eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// operator-function-id 97eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// conversion-function-id [TODO] 98eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '~' class-name [TODO] 99eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// template-id [TODO] 100eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 101eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// qualified-id: 102eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 103eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' identifier 104eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' operator-function-id 105eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' template-id [TODO] 106eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 107eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier: 108eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// type-name '::' 109eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// namespace-name '::' 110eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier identifier '::' 111eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier 'template'[opt] simple-template-id '::' [TODO] 112eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 113eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// NOTE: The standard specifies that, for qualified-id, the parser does not 114eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// expect: 115eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 116eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' conversion-function-id 117eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' '~' class-name 118eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 119eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// This may cause a slight inconsistency on diagnostics: 120eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 121eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// class C {}; 122eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// namespace A {} 123eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// void f() { 124eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// :: A :: ~ C(); // Some Sema error about using destructor with a 125eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// // namespace. 126eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// :: ~ C(); // Some Parser error like 'unexpected ~'. 127eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// } 128eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 129eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// We simplify the parser a bit and make it work like: 130eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 131eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// qualified-id: 132eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 133eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' unqualified-id 134eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 135eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// That way Sema can handle and report similar errors for namespaces and the 136eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// global scope. 137eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 138eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios KyrtzidisParser::ExprResult Parser::ParseCXXIdExpression() { 139eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // qualified-id: 140eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 141eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // '::' unqualified-id 142eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // 143eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis CXXScopeSpec SS; 1444bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis MaybeParseCXXScopeSpecifier(SS); 145eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 146eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // unqualified-id: 147eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // identifier 148eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // operator-function-id 1492def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor // conversion-function-id 150eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // '~' class-name [TODO] 151eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // template-id [TODO] 152eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // 153eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis switch (Tok.getKind()) { 154eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis default: 155eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis return Diag(Tok, diag::err_expected_unqualified_id); 156eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 157eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis case tok::identifier: { 158eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // Consume the identifier so that we can see if it is followed by a '('. 159eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis IdentifierInfo &II = *Tok.getIdentifierInfo(); 160eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation L = ConsumeToken(); 161eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis return Actions.ActOnIdentifierExpr(CurScope, L, II, 162eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis Tok.is(tok::l_paren), &SS); 163eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 164eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 165eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis case tok::kw_operator: { 166eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis SourceLocation OperatorLoc = Tok.getLocation(); 167e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor if (OverloadedOperatorKind Op = TryParseOperatorFunctionId()) { 168487a75ab300552e42afa45b8199133f838a40e5fDouglas Gregor return Actions.ActOnCXXOperatorFunctionIdExpr(CurScope, OperatorLoc, Op, 169487a75ab300552e42afa45b8199133f838a40e5fDouglas Gregor Tok.is(tok::l_paren), SS); 1702def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor } else if (TypeTy *Type = ParseConversionFunctionId()) { 171487a75ab300552e42afa45b8199133f838a40e5fDouglas Gregor return Actions.ActOnCXXConversionFunctionExpr(CurScope, OperatorLoc, 172487a75ab300552e42afa45b8199133f838a40e5fDouglas Gregor Type, Tok.is(tok::l_paren), 173487a75ab300552e42afa45b8199133f838a40e5fDouglas Gregor SS); 174eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 1752def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor 1762def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor // We already complained about a bad conversion-function-id, 1772def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor // above. 1782def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor return true; 179eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 180eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 181eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } // switch. 182eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 183eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis assert(0 && "The switch was supposed to take care everything."); 184eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis} 185eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 1865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCXXCasts - This handles the various ways to cast expressions to another 1875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// type. 1885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 1895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// postfix-expression: [C++ 5.2p1] 1905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'dynamic_cast' '<' type-name '>' '(' expression ')' 1915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'static_cast' '<' type-name '>' '(' expression ')' 1925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'reinterpret_cast' '<' type-name '>' '(' expression ')' 1935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'const_cast' '<' type-name '>' '(' expression ')' 1945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 1955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerParser::ExprResult Parser::ParseCXXCasts() { 1965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer tok::TokenKind Kind = Tok.getKind(); 1975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const char *CastName = 0; // For error messages 1985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer switch (Kind) { 2005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer default: assert(0 && "Unknown C++ cast!"); abort(); 2015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_const_cast: CastName = "const_cast"; break; 2025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_dynamic_cast: CastName = "dynamic_cast"; break; 2035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break; 2045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_static_cast: CastName = "static_cast"; break; 2055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation OpLoc = ConsumeToken(); 2085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation LAngleBracketLoc = Tok.getLocation(); 2095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName)) 2115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return ExprResult(true); 2125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer TypeTy *CastTy = ParseTypeName(); 2145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation RAngleBracketLoc = Tok.getLocation(); 2155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2161ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner if (ExpectAndConsume(tok::greater, diag::err_expected_greater)) 21728eb7e992b9a266abb300da25b6d3c1557cec361Chris Lattner return Diag(LAngleBracketLoc, diag::note_matching) << "<"; 2185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation LParenLoc = Tok.getLocation(), RParenLoc; 2205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2211ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner if (Tok.isNot(tok::l_paren)) 2221ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner return Diag(Tok, diag::err_expected_lparen_after) << CastName; 2235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 22415faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult Result(Actions, ParseSimpleParenExpression(RParenLoc)); 2255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2260e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (!Result.isInvalid()) 22749badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor Result = Actions.ActOnCXXNamedCast(OpLoc, Kind, 22849badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor LAngleBracketLoc, CastTy, RAngleBracketLoc, 229effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl LParenLoc, Result.release(), RParenLoc); 2305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 231effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl return Result.result(); 2325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 2335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 234c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// ParseCXXTypeid - This handles the C++ typeid expression. 235c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 236c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// postfix-expression: [C++ 5.2p1] 237c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 'typeid' '(' expression ')' 238c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 'typeid' '(' type-id ')' 239c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 240c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian RedlParser::ExprResult Parser::ParseCXXTypeid() { 241c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!"); 242c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 243c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SourceLocation OpLoc = ConsumeToken(); 244c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SourceLocation LParenLoc = Tok.getLocation(); 245c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SourceLocation RParenLoc; 246c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 247c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl // typeid expressions are always parenthesized. 248c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, 249c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl "typeid")) 250c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl return ExprResult(true); 251c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 25215faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult Result(Actions); 253c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 254c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl if (isTypeIdInParens()) { 255c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl TypeTy *Ty = ParseTypeName(); 256c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 257c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl // Match the ')'. 258c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl MatchRHSPunctuation(tok::r_paren, LParenLoc); 259c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 260c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl if (!Ty) 261c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl return ExprResult(true); 262c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 263c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true, 264c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Ty, RParenLoc); 265c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl } else { 266c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Result = ParseExpression(); 267c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 268c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl // Match the ')'. 2690e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Result.isInvalid()) 270c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SkipUntil(tok::r_paren); 271c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl else { 272c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl MatchRHSPunctuation(tok::r_paren, LParenLoc); 273c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 274c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false, 275effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl Result.release(), RParenLoc); 276c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl } 277c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl } 278c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 279effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl return Result.result(); 280c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl} 281c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 2825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCXXBoolLiteral - This handles the C++ Boolean literals. 2835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 2845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// boolean-literal: [C++ 2.13.5] 2855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'true' 2865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'false' 2875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerParser::ExprResult Parser::ParseCXXBoolLiteral() { 2885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer tok::TokenKind Kind = Tok.getKind(); 2891b273c403734d343d720acb28f04011807c8aa56Steve Naroff return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind); 2905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 29150dd289f45738ed22b7583d52ed2525b927042ffChris Lattner 29250dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// ParseThrowExpression - This handles the C++ throw expression. 29350dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// 29450dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// throw-expression: [C++ 15] 29550dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// 'throw' assignment-expression[opt] 29650dd289f45738ed22b7583d52ed2525b927042ffChris LattnerParser::ExprResult Parser::ParseThrowExpression() { 29750dd289f45738ed22b7583d52ed2525b927042ffChris Lattner assert(Tok.is(tok::kw_throw) && "Not throw!"); 29850dd289f45738ed22b7583d52ed2525b927042ffChris Lattner SourceLocation ThrowLoc = ConsumeToken(); // Eat the throw token. 2993e3d310a8c74f7e0ccaf2e0a64400d15b8cb5556Chris Lattner 3002a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // If the current token isn't the start of an assignment-expression, 3012a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // then the expression is not present. This handles things like: 3022a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // "C ? throw : (void)42", which is crazy but legal. 3032a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner switch (Tok.getKind()) { // FIXME: move this predicate somewhere common. 3042a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::semi: 3052a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_paren: 3062a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_square: 3072a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_brace: 3082a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::colon: 3092a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::comma: 31050dd289f45738ed22b7583d52ed2525b927042ffChris Lattner return Actions.ActOnCXXThrow(ThrowLoc); 31150dd289f45738ed22b7583d52ed2525b927042ffChris Lattner 3122a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner default: 31315faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult Expr(Actions, ParseAssignmentExpression()); 314effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl if (Expr.isInvalid()) return Expr.result(); 315effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl return Actions.ActOnCXXThrow(ThrowLoc, Expr.release()); 3162a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner } 31750dd289f45738ed22b7583d52ed2525b927042ffChris Lattner} 3184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 3194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXThis - This handles the C++ 'this' pointer. 3204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 3214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// C++ 9.3.2: In the body of a non-static member function, the keyword this is 3224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// a non-lvalue expression whose value is the address of the object for which 3234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// the function is called. 3244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios KyrtzidisParser::ExprResult Parser::ParseCXXThis() { 3254cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis assert(Tok.is(tok::kw_this) && "Not 'this'!"); 3264cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SourceLocation ThisLoc = ConsumeToken(); 327289d77302aa81dc24bf7aa75b36cb00a70a44bb5Argyrios Kyrtzidis return Actions.ActOnCXXThis(ThisLoc); 3284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 329987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 330987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// ParseCXXTypeConstructExpression - Parse construction of a specified type. 331987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// Can be interpreted either as function-style casting ("int(x)") 332987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// or class type construction ("ClassType(x,y,z)") 333987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// or creation of a value-initialized type ("int()"). 334987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 335987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// postfix-expression: [C++ 5.2p1] 336987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3] 337987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// typename-specifier '(' expression-list[opt] ')' [TODO] 338987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 339987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios KyrtzidisParser::ExprResult Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { 340987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 341987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis TypeTy *TypeRep = Actions.ActOnTypeName(CurScope, DeclaratorInfo).Val; 342987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 343987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis assert(Tok.is(tok::l_paren) && "Expected '('!"); 344987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SourceLocation LParenLoc = ConsumeParen(); 345987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 346a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector Exprs(Actions); 347987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis CommaLocsTy CommaLocs; 348987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 349987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis if (Tok.isNot(tok::r_paren)) { 350987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis if (ParseExpressionList(Exprs, CommaLocs)) { 351987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SkipUntil(tok::r_paren); 352987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis return ExprResult(true); 353987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 354987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 355987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 356987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // Match the ')'. 357987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 358987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 359987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&& 360987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis "Unexpected number of commas!"); 361987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis return Actions.ActOnCXXTypeConstructExpr(DS.getSourceRange(), TypeRep, 362987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis LParenLoc, 363a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl Exprs.take(), Exprs.size(), 364987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis &CommaLocs[0], RParenLoc); 365987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis} 366987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 36771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// ParseCXXCondition - if/switch/while/for condition expression. 36871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// 36971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// condition: 37071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// expression 37171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// type-specifier-seq declarator '=' assignment-expression 37271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 37371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// '=' assignment-expression 37471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// 37571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios KyrtzidisParser::ExprResult Parser::ParseCXXCondition() { 376a8a4598b6f2a07339ab8a1248295a07d771a2b2aArgyrios Kyrtzidis if (!isCXXConditionDeclaration()) 37771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis return ParseExpression(); // expression 37871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 37971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SourceLocation StartLoc = Tok.getLocation(); 38071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 38171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // type-specifier-seq 38271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis DeclSpec DS; 38371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis ParseSpecifierQualifierList(DS); 38471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 38571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // declarator 38671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::ConditionContext); 38771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 38871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 38971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // simple-asm-expr[opt] 39071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (Tok.is(tok::kw_asm)) { 391effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl OwningExprResult AsmLabel(ParseSimpleAsm()); 3920e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (AsmLabel.isInvalid()) { 39371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SkipUntil(tok::semi); 39471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis return true; 39571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis } 396effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl DeclaratorInfo.setAsmLabel(AsmLabel.release()); 39771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis } 39871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 39971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // If attributes are present, parse them. 40071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (Tok.is(tok::kw___attribute)) 40171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis DeclaratorInfo.AddAttributes(ParseAttributes()); 40271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 40371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // '=' assignment-expression 40471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (Tok.isNot(tok::equal)) 40571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis return Diag(Tok, diag::err_expected_equal_after_declarator); 40671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SourceLocation EqualLoc = ConsumeToken(); 40715faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult AssignExpr(Actions, ParseAssignmentExpression()); 4080e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (AssignExpr.isInvalid()) 40971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis return true; 41071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 41171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis return Actions.ActOnCXXConditionDeclarationExpr(CurScope, StartLoc, 412effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl DeclaratorInfo, EqualLoc, 413effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl AssignExpr.release()); 41471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis} 41571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 416987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers. 417987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// This should only be called when the current token is known to be part of 418987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// simple-type-specifier. 419987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 420987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// simple-type-specifier: 421eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier[opt] type-name 422987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template' simple-template-id [TODO] 423987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// char 424987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// wchar_t 425987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// bool 426987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// short 427987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// int 428987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// long 429987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// signed 430987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// unsigned 431987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// float 432987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// double 433987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// void 434987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// [GNU] typeof-specifier 435987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// [C++0x] auto [TODO] 436987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 437987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// type-name: 438987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// class-name 439987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// enum-name 440987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// typedef-name 441987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 442987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidisvoid Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { 443eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // Annotate typenames and C++ scope specifiers. 444eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis TryAnnotateTypeOrScopeToken(); 445eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 446987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetRangeStart(Tok.getLocation()); 447987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis const char *PrevSpec; 448987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SourceLocation Loc = Tok.getLocation(); 449987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 450987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis switch (Tok.getKind()) { 451987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis default: 452987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis assert(0 && "Not a simple-type-specifier token!"); 453987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis abort(); 454987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 455987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // type-name 456eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis case tok::annot_qualtypename: { 457eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec, 458eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis Tok.getAnnotationValue()); 459987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 460987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 461987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 462987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // builtin types 463987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_short: 464987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec); 465987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 466987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_long: 467987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec); 468987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 469987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_signed: 470987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec); 471987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 472987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_unsigned: 473987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec); 474987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 475987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_void: 476987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec); 477987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 478987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_char: 479987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec); 480987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 481987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_int: 482987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec); 483987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 484987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_float: 485987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec); 486987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 487987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_double: 488987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec); 489987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 490987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_wchar_t: 491987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec); 492987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 493987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_bool: 494987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec); 495987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 496987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 497987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // GNU typeof support. 498987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_typeof: 499987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis ParseTypeofSpecifier(DS); 500987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.Finish(Diags, PP.getSourceManager(), getLang()); 501987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis return; 502987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 503eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis if (Tok.is(tok::annot_qualtypename)) 504eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 505eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis else 506eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis DS.SetRangeEnd(Tok.getLocation()); 507987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis ConsumeToken(); 508987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.Finish(Diags, PP.getSourceManager(), getLang()); 509987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis} 5101cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5112f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++ 5122f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// [dcl.name]), which is a non-empty sequence of type-specifiers, 5132f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// e.g., "const short int". Note that the DeclSpec is *not* finished 5142f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// by parsing the type-specifier-seq, because these sequences are 5152f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// typically followed by some form of declarator. Returns true and 5162f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// emits diagnostics if this is not a type-specifier-seq, false 5172f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// otherwise. 5182f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 5192f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// type-specifier-seq: [C++ 8.1] 5202f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// type-specifier type-specifier-seq[opt] 5212f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 5222f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregorbool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) { 5232f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor DS.SetRangeStart(Tok.getLocation()); 5242f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor const char *PrevSpec = 0; 5252f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor int isInvalid = 0; 5262f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 5272f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Parse one or more of the type specifiers. 5282f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor if (!MaybeParseTypeSpecifier(DS, isInvalid, PrevSpec)) { 5291ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_operator_missing_type_specifier); 5302f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return true; 5312f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor } 532b90585c3c65db9ab587674586602729edbd096aaDaniel Dunbar while (MaybeParseTypeSpecifier(DS, isInvalid, PrevSpec)) ; 5332f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 5342f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return false; 5352f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor} 5362f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 53743c7bad105f742988e7ca40564285c83bea854a5Douglas Gregor/// TryParseOperatorFunctionId - Attempts to parse a C++ overloaded 5381cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator name (C++ [over.oper]). If successful, returns the 5391cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// predefined identifier that corresponds to that overloaded 5401cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator. Otherwise, returns NULL and does not consume any tokens. 5411cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// 5421cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator-function-id: [C++ 13.5] 5431cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// 'operator' operator 5441cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// 5451cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// operator: one of 5461cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// new delete new[] delete[] 5471cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// + - * / % ^ & | ~ 5481cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// ! = < > += -= *= /= %= 5491cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// ^= &= |= << >> >>= <<= == != 5501cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// <= >= && || ++ -- , ->* -> 5511cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor/// () [] 552e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas GregorOverloadedOperatorKind Parser::TryParseOperatorFunctionId() { 5539057a81efaf15c543aab1c5c8488e8a9ed2c0ff4Argyrios Kyrtzidis assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); 5541cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5551cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor OverloadedOperatorKind Op = OO_None; 5561cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor switch (NextToken().getKind()) { 5571cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::kw_new: 5581cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 5591cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'new' 5601cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor if (Tok.is(tok::l_square)) { 5611cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeBracket(); // '[' 5621cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 5631cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_Array_New; 5641cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } else { 5651cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_New; 5661cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } 567e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return Op; 5681cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5691cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::kw_delete: 5701cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 5711cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'delete' 5721cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor if (Tok.is(tok::l_square)) { 5731cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeBracket(); // '[' 5741cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 5751cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_Array_Delete; 5761cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } else { 5771cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor Op = OO_Delete; 5781cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } 579e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return Op; 5801cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 58102bcd4cd1a19121da12884aa4943226f72a81e6cDouglas Gregor#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 5821cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::Token: Op = OO_##Name; break; 58302bcd4cd1a19121da12884aa4943226f72a81e6cDouglas Gregor#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) 5841cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor#include "clang/Basic/OperatorKinds.def" 5851cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5861cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::l_paren: 5871cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 5881cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeParen(); // '(' 5891cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_paren, diag::err_expected_rparen); // ')' 590e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return OO_Call; 5911cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5921cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor case tok::l_square: 5931cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeToken(); // 'operator' 5941cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ConsumeBracket(); // '[' 5951cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' 596e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return OO_Subscript; 5971cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 5981cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor default: 599e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return OO_None; 6001cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor } 60143c7bad105f742988e7ca40564285c83bea854a5Douglas Gregor 60243c7bad105f742988e7ca40564285c83bea854a5Douglas Gregor ConsumeToken(); // 'operator' 60343c7bad105f742988e7ca40564285c83bea854a5Douglas Gregor ConsumeAnyToken(); // the operator itself 604e94ca9e4371c022329270436b3dd77adc4ddfa8fDouglas Gregor return Op; 6051cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor} 6062f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 6072f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// ParseConversionFunctionId - Parse a C++ conversion-function-id, 6082f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// which expresses the name of a user-defined conversion operator 6092f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// (C++ [class.conv.fct]p1). Returns the type that this operator is 6102f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// specifying a conversion for, or NULL if there was an error. 6112f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 6122f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// conversion-function-id: [C++ 12.3.2] 6132f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// operator conversion-type-id 6142f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 6152f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// conversion-type-id: 6162f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// type-specifier-seq conversion-declarator[opt] 6172f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 6182f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// conversion-declarator: 6192f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// ptr-operator conversion-declarator[opt] 6202f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas GregorParser::TypeTy *Parser::ParseConversionFunctionId() { 6212f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); 6222f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor ConsumeToken(); // 'operator' 6232f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 6242f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Parse the type-specifier-seq. 6252f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor DeclSpec DS; 6262f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor if (ParseCXXTypeSpecifierSeq(DS)) 6272f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return 0; 6282f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 6292f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Parse the conversion-declarator, which is merely a sequence of 6302f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // ptr-operators. 6312f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor Declarator D(DS, Declarator::TypeNameContext); 6324c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParseDeclaratorInternal(D, /*DirectDeclParser=*/0); 6332f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 6342f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Finish up the type. 6352f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor Action::TypeResult Result = Actions.ActOnTypeName(CurScope, D); 6362f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor if (Result.isInvalid) 6372f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return 0; 6382f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor else 6392f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return Result.Val; 6402f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor} 6414c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6424c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate 6434c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// memory in a typesafe manner and call constructors. 6444c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 6454c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-expression: 6464c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'new' new-placement[opt] new-type-id 6474c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer[opt] 6484c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 6494c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer[opt] 6504c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 6514c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-placement: 6524c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '(' expression-list ')' 6534c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 654cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// new-type-id: 655cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// type-specifier-seq new-declarator[opt] 656cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// 657cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// new-declarator: 658cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// ptr-operator new-declarator[opt] 659cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// direct-new-declarator 660cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// 6614c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer: 6624c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '(' expression-list[opt] ')' 6634c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// [C++0x] braced-init-list [TODO] 6644c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 6654c5d320a7581f4b80b151630c91cea5727fa9923Sebastian RedlParser::ExprResult Parser::ParseCXXNewExpression() 6664c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl{ 6674c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl assert((Tok.is(tok::coloncolon) || Tok.is(tok::kw_new)) && 6684c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl "Expected :: or 'new' keyword"); 6694c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6704c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation Start = Tok.getLocation(); 6714c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool UseGlobal = false; 6724c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::coloncolon)) { 6734c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl UseGlobal = true; 6744c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ConsumeToken(); 6754c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 6764c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6774c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl assert(Tok.is(tok::kw_new) && "Lookahead should have ensured 'new'"); 6784c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Consume 'new' 6794c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ConsumeToken(); 6804c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6814c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // A '(' now can be a new-placement or the '(' wrapping the type-id in the 6824c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // second form of new-expression. It can't be a new-type-id. 6834c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 684a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector PlacementArgs(Actions); 6854c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation PlacementLParen, PlacementRParen; 6864c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6874c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool ParenTypeId; 688cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl DeclSpec DS; 689cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 6904c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_paren)) { 6914c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // If it turns out to be a placement, we change the type location. 6924c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl PlacementLParen = ConsumeParen(); 693cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) { 694cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 6954c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return true; 696cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 6974c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 6984c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl PlacementRParen = MatchRHSPunctuation(tok::r_paren, PlacementLParen); 699cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (PlacementRParen.isInvalid()) { 700cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 7014c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return true; 702cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 7034c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 704cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (PlacementArgs.empty()) { 7054c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Reset the placement locations. There was no placement. 7064c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl PlacementLParen = PlacementRParen = SourceLocation(); 7074c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParenTypeId = true; 7084c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } else { 7094c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // We still need the type. 7104c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_paren)) { 711cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SourceLocation LParen = ConsumeParen(); 712cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseSpecifierQualifierList(DS); 713cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclarator(DeclaratorInfo); 714cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl MatchRHSPunctuation(tok::r_paren, LParen); 7154c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParenTypeId = true; 7164c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } else { 717cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseCXXTypeSpecifierSeq(DS)) 718cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl DeclaratorInfo.setInvalidType(true); 719cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl else 720cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclaratorInternal(DeclaratorInfo, 721cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl &Parser::ParseDirectNewDeclarator); 7224c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParenTypeId = false; 7234c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7244c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7254c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } else { 726cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl // A new-type-id is a simplified type-id, where essentially the 727cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl // direct-declarator is replaced by a direct-new-declarator. 728cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseCXXTypeSpecifierSeq(DS)) 729cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl DeclaratorInfo.setInvalidType(true); 730cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl else 731cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclaratorInternal(DeclaratorInfo, 732cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl &Parser::ParseDirectNewDeclarator); 7334c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ParenTypeId = false; 7344c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 735cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (DeclaratorInfo.getInvalidType()) { 736cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 737cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl return true; 738cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 7394c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 740a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector ConstructorArgs(Actions); 7414c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation ConstructorLParen, ConstructorRParen; 7424c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7434c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_paren)) { 7444c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ConstructorLParen = ConsumeParen(); 7454c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.isNot(tok::r_paren)) { 7464c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl CommaLocsTy CommaLocs; 747cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseExpressionList(ConstructorArgs, CommaLocs)) { 748cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 7494c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return true; 750cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 7514c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7524c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ConstructorRParen = MatchRHSPunctuation(tok::r_paren, ConstructorLParen); 753cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ConstructorRParen.isInvalid()) { 754cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 7554c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return true; 756cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 7574c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7584c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7594c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen, 760a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl PlacementArgs.take(), PlacementArgs.size(), 761cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl PlacementRParen, ParenTypeId, DeclaratorInfo, 762a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ConstructorLParen, ConstructorArgs.take(), 7634c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ConstructorArgs.size(), ConstructorRParen); 7644c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 7654c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7664c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be 7674c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// passed to ParseDeclaratorInternal. 7684c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 7694c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// direct-new-declarator: 7704c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '[' expression ']' 7714c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// direct-new-declarator '[' constant-expression ']' 7724c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 7734c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redlvoid Parser::ParseDirectNewDeclarator(Declarator &D) 7744c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl{ 7754c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Parse the array dimensions. 7764c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool first = true; 7774c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl while (Tok.is(tok::l_square)) { 7784c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation LLoc = ConsumeBracket(); 77915faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult Size(Actions, first ? ParseExpression() 78015faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl : ParseConstantExpression()); 7810e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Size.isInvalid()) { 7824c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Recover 7834c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SkipUntil(tok::r_square); 7844c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return; 7854c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7864c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl first = false; 7874c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7884c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false, 789effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl Size.release(), LLoc)); 7904c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7914c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (MatchRHSPunctuation(tok::r_square, LLoc).isInvalid()) 7924c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return; 7934c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 7944c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 7954c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 7964c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id. 7974c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// This ambiguity appears in the syntax of the C++ new operator. 7984c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 7994c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-expression: 8004c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 8014c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer[opt] 8024c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 8034c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-placement: 8044c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '(' expression-list ')' 8054c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 806cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redlbool Parser::ParseExpressionListOrTypeId(ExprListTy &PlacementArgs, 807cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl Declarator &D) 8084c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl{ 8094c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // The '(' was already consumed. 8104c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (isTypeIdInParens()) { 811cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseSpecifierQualifierList(D.getMutableDeclSpec()); 812cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclarator(D); 813cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl return D.getInvalidType(); 8144c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 8154c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8164c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // It's not a type, it has to be an expression list. 8174c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Discard the comma locations - ActOnCXXNew has enough parameters. 8184c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl CommaLocsTy CommaLocs; 8194c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return ParseExpressionList(PlacementArgs, CommaLocs); 8204c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 8214c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8224c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used 8234c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// to free memory allocated by new. 8244c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 8254c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// delete-expression: 8264c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'delete' cast-expression 8274c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'delete' '[' ']' cast-expression 8284c5d320a7581f4b80b151630c91cea5727fa9923Sebastian RedlParser::ExprResult Parser::ParseCXXDeleteExpression() 8294c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl{ 8304c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl assert((Tok.is(tok::coloncolon) || Tok.is(tok::kw_delete)) && 8314c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl "Expected :: or 'delete' keyword"); 8324c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8334c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation Start = Tok.getLocation(); 8344c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool UseGlobal = false; 8354c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::coloncolon)) { 8364c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl UseGlobal = true; 8374c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ConsumeToken(); 8384c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 8394c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8404c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl assert(Tok.is(tok::kw_delete) && "Lookahead should have ensured 'delete'"); 8414c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Consume 'delete' 8424c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ConsumeToken(); 8434c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 8444c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Array delete? 8454c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool ArrayDelete = false; 8464c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_square)) { 8474c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ArrayDelete = true; 8484c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation LHS = ConsumeBracket(); 8494c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation RHS = MatchRHSPunctuation(tok::r_square, LHS); 8504c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (RHS.isInvalid()) 8514c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return true; 8524c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 8534c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 85415faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult Operand(Actions, ParseCastExpression(false)); 8550e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Operand.isInvalid()) 856effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl return Operand.result(); 8574c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 858effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, 859effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl Operand.release()); 8604c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 861