ParseExprCXX.cpp revision deeab90783eb28d955add1062b616c030eb2b781
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 14500d3297d2a21edeac4d46cbcbe21bc2352c2a28Chris Lattner#include "clang/Parse/ParseDiagnostic.h" 155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Parse/Parser.h" 16bc61bd8109d9accf8f966b59e3f16a1497e72adfDouglas Gregor#include "RAIIObjectsForParser.h" 17dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman#include "clang/Basic/PrettyStackTrace.h" 1819510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h" 19ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor#include "clang/Sema/Scope.h" 2019510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/ParsedTemplate.h" 213f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor#include "llvm/Support/ErrorHandling.h" 223f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang; 245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 25ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smithstatic int SelectDigraphErrorMessage(tok::TokenKind Kind) { 26ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith switch (Kind) { 27ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith case tok::kw_template: return 0; 28ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith case tok::kw_const_cast: return 1; 29ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith case tok::kw_dynamic_cast: return 2; 30ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith case tok::kw_reinterpret_cast: return 3; 31ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith case tok::kw_static_cast: return 4; 32ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith default: 33b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Unknown type for digraph error message."); 34ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith } 35ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith} 36ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith 37ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith// Are the two tokens adjacent in the same source file? 38ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smithstatic bool AreTokensAdjacent(Preprocessor &PP, Token &First, Token &Second) { 39ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith SourceManager &SM = PP.getSourceManager(); 40ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith SourceLocation FirstLoc = SM.getSpellingLoc(First.getLocation()); 41a64ccefdf0ea4e03ec88805d71b0af74950c7472Argyrios Kyrtzidis SourceLocation FirstEnd = FirstLoc.getLocWithOffset(First.getLength()); 42ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith return FirstEnd == SM.getSpellingLoc(Second.getLocation()); 43ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith} 44ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith 45ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith// Suggest fixit for "<::" after a cast. 46ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smithstatic void FixDigraph(Parser &P, Preprocessor &PP, Token &DigraphToken, 47ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith Token &ColonToken, tok::TokenKind Kind, bool AtDigraph) { 48ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith // Pull '<:' and ':' off token stream. 49ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith if (!AtDigraph) 50ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith PP.Lex(DigraphToken); 51ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith PP.Lex(ColonToken); 52ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith 53ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith SourceRange Range; 54ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith Range.setBegin(DigraphToken.getLocation()); 55ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith Range.setEnd(ColonToken.getLocation()); 56ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith P.Diag(DigraphToken.getLocation(), diag::err_missing_whitespace_digraph) 57ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith << SelectDigraphErrorMessage(Kind) 58ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith << FixItHint::CreateReplacement(Range, "< ::"); 59ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith 60ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith // Update token information to reflect their change in token type. 61ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith ColonToken.setKind(tok::coloncolon); 62a64ccefdf0ea4e03ec88805d71b0af74950c7472Argyrios Kyrtzidis ColonToken.setLocation(ColonToken.getLocation().getLocWithOffset(-1)); 63ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith ColonToken.setLength(2); 64ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith DigraphToken.setKind(tok::less); 65ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith DigraphToken.setLength(1); 66ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith 67ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith // Push new tokens back to token stream. 68ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith PP.EnterToken(ColonToken); 69ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith if (!AtDigraph) 70ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith PP.EnterToken(DigraphToken); 71ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith} 72ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith 73950be71c745409e373ae8a834490f9026c8ac222Richard Trieu// Check for '<::' which should be '< ::' instead of '[:' when following 74950be71c745409e373ae8a834490f9026c8ac222Richard Trieu// a template name. 75950be71c745409e373ae8a834490f9026c8ac222Richard Trieuvoid Parser::CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectType, 76950be71c745409e373ae8a834490f9026c8ac222Richard Trieu bool EnteringContext, 77950be71c745409e373ae8a834490f9026c8ac222Richard Trieu IdentifierInfo &II, CXXScopeSpec &SS) { 78c11030ea936f6952deb5a1423ce1648173cd417eRichard Trieu if (!Next.is(tok::l_square) || Next.getLength() != 2) 79950be71c745409e373ae8a834490f9026c8ac222Richard Trieu return; 80950be71c745409e373ae8a834490f9026c8ac222Richard Trieu 81950be71c745409e373ae8a834490f9026c8ac222Richard Trieu Token SecondToken = GetLookAheadToken(2); 82950be71c745409e373ae8a834490f9026c8ac222Richard Trieu if (!SecondToken.is(tok::colon) || !AreTokensAdjacent(PP, Next, SecondToken)) 83950be71c745409e373ae8a834490f9026c8ac222Richard Trieu return; 84950be71c745409e373ae8a834490f9026c8ac222Richard Trieu 85950be71c745409e373ae8a834490f9026c8ac222Richard Trieu TemplateTy Template; 86950be71c745409e373ae8a834490f9026c8ac222Richard Trieu UnqualifiedId TemplateName; 87950be71c745409e373ae8a834490f9026c8ac222Richard Trieu TemplateName.setIdentifier(&II, Tok.getLocation()); 88950be71c745409e373ae8a834490f9026c8ac222Richard Trieu bool MemberOfUnknownSpecialization; 89950be71c745409e373ae8a834490f9026c8ac222Richard Trieu if (!Actions.isTemplateName(getCurScope(), SS, /*hasTemplateKeyword=*/false, 90950be71c745409e373ae8a834490f9026c8ac222Richard Trieu TemplateName, ObjectType, EnteringContext, 91950be71c745409e373ae8a834490f9026c8ac222Richard Trieu Template, MemberOfUnknownSpecialization)) 92950be71c745409e373ae8a834490f9026c8ac222Richard Trieu return; 93950be71c745409e373ae8a834490f9026c8ac222Richard Trieu 94950be71c745409e373ae8a834490f9026c8ac222Richard Trieu FixDigraph(*this, PP, Next, SecondToken, tok::kw_template, 95950be71c745409e373ae8a834490f9026c8ac222Richard Trieu /*AtDigraph*/false); 96950be71c745409e373ae8a834490f9026c8ac222Richard Trieu} 97950be71c745409e373ae8a834490f9026c8ac222Richard Trieu 981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// \brief Parse global scope or nested-name-specifier if present. 992dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// 1002dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// Parses a C++ global scope specifier ('::') or nested-name-specifier (which 1011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// may be preceded by '::'). Note that this routine will not parse ::new or 1022dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// ::delete; it will just leave them in the token stream. 103eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 104eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier 105eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' 106eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 107eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier: 108eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// type-name '::' 109eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// namespace-name '::' 110eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier identifier '::' 1112dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// nested-name-specifier 'template'[opt] simple-template-id '::' 1122dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// 1132dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// 1141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// \param SS the scope specifier that will be set to the parsed 1152dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// nested-name-specifier (or empty) 1162dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// 1171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// \param ObjectType if this nested-name-specifier is being parsed following 1182dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// the "." or "->" of a member access expression, this parameter provides the 1192dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// type of the object whose members are being accessed. 120eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 1212dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// \param EnteringContext whether we will be entering into the context of 1222dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// the nested-name-specifier after parsing it. 1232dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// 124d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// \param MayBePseudoDestructor When non-NULL, points to a flag that 125d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// indicates whether this nested-name-specifier may be part of a 126d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// pseudo-destructor name. In this case, the flag will be set false 127d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// if we don't actually end up parsing a destructor name. Moreorover, 128d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// if we do end up determining that we are parsing a destructor name, 129d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// the last component of the nested-name-specifier is not parsed as 130d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// part of the scope specifier. 131d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor 132b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor/// member access expression, e.g., the \p T:: in \p p->T::m. 133b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor/// 1349ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall/// \returns true if there was an error parsing a scope specifier 135495c35d291da48c4f5655bbb54d15128ddde0d4dDouglas Gregorbool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, 136b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType ObjectType, 137b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor bool EnteringContext, 1384147d307086cf024a40a080e2bf379e9725f6f41Francois Pichet bool *MayBePseudoDestructor, 1394147d307086cf024a40a080e2bf379e9725f6f41Francois Pichet bool IsTypename) { 1404bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis assert(getLang().CPlusPlus && 1417452c6fc567ea1799f617395d0fa4c7ed075e5d9Chris Lattner "Call sites of this function should be guarded by checking for C++"); 1421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 143eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis if (Tok.is(tok::annot_cxxscope)) { 144c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(), 145c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor Tok.getAnnotationRange(), 146c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor SS); 147eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis ConsumeToken(); 1489ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return false; 149eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 150e607e808c2b90724a2a6fd841e850f07de1f5b30Chris Lattner 15139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor bool HasScopeSpecifier = false; 15239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor 1535b4547318bb179fc76f984f0eeaaf615927e795cChris Lattner if (Tok.is(tok::coloncolon)) { 1545b4547318bb179fc76f984f0eeaaf615927e795cChris Lattner // ::new and ::delete aren't nested-name-specifiers. 1555b4547318bb179fc76f984f0eeaaf615927e795cChris Lattner tok::TokenKind NextKind = NextToken().getKind(); 1565b4547318bb179fc76f984f0eeaaf615927e795cChris Lattner if (NextKind == tok::kw_new || NextKind == tok::kw_delete) 1575b4547318bb179fc76f984f0eeaaf615927e795cChris Lattner return false; 1581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15955a7cefc846765ac7d142a63f773747a20518d71Chris Lattner // '::' - Global scope qualifier. 1602e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor if (Actions.ActOnCXXGlobalScopeSpecifier(getCurScope(), ConsumeToken(), SS)) 1612e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor return true; 1622e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor 16339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor HasScopeSpecifier = true; 164eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 165eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 166d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor bool CheckForDestructor = false; 167d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor if (MayBePseudoDestructor && *MayBePseudoDestructor) { 168d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor CheckForDestructor = true; 169d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor *MayBePseudoDestructor = false; 170d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor } 171d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor 17242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (Tok.is(tok::kw_decltype) || Tok.is(tok::annot_decltype)) { 17342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DeclSpec DS(AttrFactory); 17442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie SourceLocation DeclLoc = Tok.getLocation(); 17542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie SourceLocation EndLoc = ParseDecltypeSpecifier(DS); 17642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (Tok.isNot(tok::coloncolon)) { 17742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie AnnotateExistingDecltypeSpecifier(DS, DeclLoc, EndLoc); 17842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie return false; 17942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 18042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 18142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie SourceLocation CCLoc = ConsumeToken(); 18242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (Actions.ActOnCXXNestedNameSpecifierDecltype(SS, DS, CCLoc)) 18342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie SS.SetInvalid(SourceRange(DeclLoc, CCLoc)); 18442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 18542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie HasScopeSpecifier = true; 18642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 18742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 18839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor while (true) { 1892dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor if (HasScopeSpecifier) { 1902dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor // C++ [basic.lookup.classref]p5: 1912dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor // If the qualified-id has the form 1923b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregor // 1932dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor // ::class-name-or-namespace-name::... 1943b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregor // 1952dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor // the class-name-or-namespace-name is looked up in global scope as a 1962dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor // class-name or namespace-name. 1972dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor // 1982dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor // To implement this, we clear out the object type as soon as we've 1992dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor // seen a leading '::' or part of a nested-name-specifier. 200b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ObjectType = ParsedType(); 20181b747b7fcc91c2fba9a3183d8fac80adbfc1d3eDouglas Gregor 20281b747b7fcc91c2fba9a3183d8fac80adbfc1d3eDouglas Gregor if (Tok.is(tok::code_completion)) { 20381b747b7fcc91c2fba9a3183d8fac80adbfc1d3eDouglas Gregor // Code completion for a nested-name-specifier, where the code 20481b747b7fcc91c2fba9a3183d8fac80adbfc1d3eDouglas Gregor // code completion token follows the '::'. 20523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.CodeCompleteQualifiedId(getCurScope(), SS, EnteringContext); 206b6b2b180c6857af75c6683f7107a7c8994f074edArgyrios Kyrtzidis // Include code completion token into the range of the scope otherwise 207b6b2b180c6857af75c6683f7107a7c8994f074edArgyrios Kyrtzidis // when we try to annotate the scope tokens the dangling code completion 208b6b2b180c6857af75c6683f7107a7c8994f074edArgyrios Kyrtzidis // token will cause assertion in 209b6b2b180c6857af75c6683f7107a7c8994f074edArgyrios Kyrtzidis // Preprocessor::AnnotatePreviousCachedTokens. 2107d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis SS.setEndLoc(Tok.getLocation()); 2117d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis cutOffParsing(); 2127d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis return true; 21381b747b7fcc91c2fba9a3183d8fac80adbfc1d3eDouglas Gregor } 2142dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor } 2151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 21639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // nested-name-specifier: 21777cf72a95baa18e82737bb45131e9658a00fee16Chris Lattner // nested-name-specifier 'template'[opt] simple-template-id '::' 21877cf72a95baa18e82737bb45131e9658a00fee16Chris Lattner 21977cf72a95baa18e82737bb45131e9658a00fee16Chris Lattner // Parse the optional 'template' keyword, then make sure we have 22077cf72a95baa18e82737bb45131e9658a00fee16Chris Lattner // 'identifier <' after it. 22177cf72a95baa18e82737bb45131e9658a00fee16Chris Lattner if (Tok.is(tok::kw_template)) { 2222dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor // If we don't have a scope specifier or an object type, this isn't a 223eab975dce83fcf6a7fa8fc9379944d4b1aaf1a00Eli Friedman // nested-name-specifier, since they aren't allowed to start with 224eab975dce83fcf6a7fa8fc9379944d4b1aaf1a00Eli Friedman // 'template'. 2252dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor if (!HasScopeSpecifier && !ObjectType) 226eab975dce83fcf6a7fa8fc9379944d4b1aaf1a00Eli Friedman break; 227eab975dce83fcf6a7fa8fc9379944d4b1aaf1a00Eli Friedman 2287bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor TentativeParsingAction TPA(*this); 22977cf72a95baa18e82737bb45131e9658a00fee16Chris Lattner SourceLocation TemplateKWLoc = ConsumeToken(); 230ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 231ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor UnqualifiedId TemplateName; 232ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor if (Tok.is(tok::identifier)) { 233ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // Consume the identifier. 2347bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor TemplateName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); 235ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor ConsumeToken(); 236ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor } else if (Tok.is(tok::kw_operator)) { 237ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, 2387bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor TemplateName)) { 2397bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor TPA.Commit(); 240ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor break; 2417bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor } 242ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 243e6252d1587f98dbac704178e7b2ce53116048310Sean Hunt if (TemplateName.getKind() != UnqualifiedId::IK_OperatorFunctionId && 244e6252d1587f98dbac704178e7b2ce53116048310Sean Hunt TemplateName.getKind() != UnqualifiedId::IK_LiteralOperatorId) { 245ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor Diag(TemplateName.getSourceRange().getBegin(), 246ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor diag::err_id_after_template_in_nested_name_spec) 247ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor << TemplateName.getSourceRange(); 2487bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor TPA.Commit(); 249ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor break; 250ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor } 251ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor } else { 2527bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor TPA.Revert(); 25377cf72a95baa18e82737bb45131e9658a00fee16Chris Lattner break; 25477cf72a95baa18e82737bb45131e9658a00fee16Chris Lattner } 2551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2567bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor // If the next token is not '<', we have a qualified-id that refers 2577bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor // to a template name, such as T::template apply, but is not a 2587bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor // template-id. 2597bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor if (Tok.isNot(tok::less)) { 2607bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor TPA.Revert(); 2617bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor break; 2627bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor } 2637bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor 2647bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor // Commit to parsing the template-id. 2657bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor TPA.Commit(); 266d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor TemplateTy Template; 26723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor if (TemplateNameKind TNK = Actions.ActOnDependentTemplateName(getCurScope(), 268d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor TemplateKWLoc, 269d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor SS, 270d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor TemplateName, 271d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor ObjectType, 272d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor EnteringContext, 273d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor Template)) { 274059101f922de6eb765601459925f4c8914420b23Douglas Gregor if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateName, 275d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor TemplateKWLoc, false)) 276d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor return true; 277d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor } else 2789ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return true; 2791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 28077cf72a95baa18e82737bb45131e9658a00fee16Chris Lattner continue; 28177cf72a95baa18e82737bb45131e9658a00fee16Chris Lattner } 2821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 28339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor if (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) { 2841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // We have 28539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // 28639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // simple-template-id '::' 28739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // 28839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // So we need to check whether the simple-template-id is of the 289c45c232440dfafedca1a3773b904fb42609b1b19Douglas Gregor // right kind (it should name a type or be dependent), and then 290c45c232440dfafedca1a3773b904fb42609b1b19Douglas Gregor // convert it into a type within the nested-name-specifier. 29125a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 292d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde)) { 293d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor *MayBePseudoDestructor = true; 2949ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return false; 295d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor } 296d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor 2976cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor // Consume the template-id token. 2986cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor ConsumeToken(); 2996cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor 3006cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!"); 3016cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor SourceLocation CCLoc = ConsumeToken(); 3021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3036796fc1adcaf57c38d072a238b016b2834afbe0dDavid Blaikie HasScopeSpecifier = true; 3046cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor 3056cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor ASTTemplateArgsPtr TemplateArgsPtr(Actions, 3066cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor TemplateId->getTemplateArgs(), 3076cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor TemplateId->NumArgs); 3086cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor 3096cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(), 3106cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor /*FIXME:*/SourceLocation(), 3116cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor SS, 3126cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor TemplateId->Template, 3136cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor TemplateId->TemplateNameLoc, 3146cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor TemplateId->LAngleLoc, 3156cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor TemplateArgsPtr, 3166cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor TemplateId->RAngleLoc, 3176cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor CCLoc, 3186cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor EnteringContext)) { 3196cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor SourceLocation StartLoc 3206cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor = SS.getBeginLoc().isValid()? SS.getBeginLoc() 3216cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor : TemplateId->TemplateNameLoc; 3226cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor SS.SetInvalid(SourceRange(StartLoc, CCLoc)); 32367b9e831943300ce54e564e601971828ce4def15Chris Lattner } 324eccce7e246a17e12a2afd6eabb9ac7c8d582db4eArgyrios Kyrtzidis 3256cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor continue; 32639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor } 32739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor 3285c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner 3295c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // The rest of the nested-name-specifier possibilities start with 3305c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // tok::identifier. 3315c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner if (Tok.isNot(tok::identifier)) 3325c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner break; 3335c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner 3345c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner IdentifierInfo &II = *Tok.getIdentifierInfo(); 3355c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner 3365c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // nested-name-specifier: 3375c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // type-name '::' 3385c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // namespace-name '::' 3395c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // nested-name-specifier identifier '::' 3405c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner Token Next = NextToken(); 34146646491834cd8faabb22482dfe93b24ce28a6c1Chris Lattner 34246646491834cd8faabb22482dfe93b24ce28a6c1Chris Lattner // If we get foo:bar, this is almost certainly a typo for foo::bar. Recover 34346646491834cd8faabb22482dfe93b24ce28a6c1Chris Lattner // and emit a fixit hint for it. 344b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor if (Next.is(tok::colon) && !ColonIsSacred) { 3452e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor if (Actions.IsInvalidUnlessNestedName(getCurScope(), SS, II, 3462e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor Tok.getLocation(), 3472e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor Next.getLocation(), ObjectType, 348b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor EnteringContext) && 349b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor // If the token after the colon isn't an identifier, it's still an 350b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor // error, but they probably meant something else strange so don't 351b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor // recover like this. 352b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor PP.LookAhead(1).is(tok::identifier)) { 353b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor Diag(Next, diag::err_unexected_colon_in_nested_name_spec) 354849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor << FixItHint::CreateReplacement(Next.getLocation(), "::"); 355b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor 356b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor // Recover as if the user wrote '::'. 357b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor Next.setKind(tok::coloncolon); 358b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor } 35946646491834cd8faabb22482dfe93b24ce28a6c1Chris Lattner } 36046646491834cd8faabb22482dfe93b24ce28a6c1Chris Lattner 3615c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner if (Next.is(tok::coloncolon)) { 36277549080fb7b9af31606b3c1b4830a94429fb1fdDouglas Gregor if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde) && 36323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor !Actions.isNonTypeNestedNameSpecifier(getCurScope(), SS, Tok.getLocation(), 36477549080fb7b9af31606b3c1b4830a94429fb1fdDouglas Gregor II, ObjectType)) { 365d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor *MayBePseudoDestructor = true; 3669ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return false; 367d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor } 368d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor 3695c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // We have an identifier followed by a '::'. Lookup this name 3705c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // as the name in a nested-name-specifier. 3715c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner SourceLocation IdLoc = ConsumeToken(); 37246646491834cd8faabb22482dfe93b24ce28a6c1Chris Lattner assert((Tok.is(tok::coloncolon) || Tok.is(tok::colon)) && 37346646491834cd8faabb22482dfe93b24ce28a6c1Chris Lattner "NextToken() not working properly!"); 3745c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner SourceLocation CCLoc = ConsumeToken(); 3751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3762e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor HasScopeSpecifier = true; 3772e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(), II, IdLoc, CCLoc, 3782e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor ObjectType, EnteringContext, SS)) 3792e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor SS.SetInvalid(SourceRange(IdLoc, CCLoc)); 3802e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor 3815c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner continue; 3825c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner } 3831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 384950be71c745409e373ae8a834490f9026c8ac222Richard Trieu CheckForTemplateAndDigraph(Next, ObjectType, EnteringContext, II, SS); 385ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith 3865c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // nested-name-specifier: 3875c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // type-name '<' 3885c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner if (Next.is(tok::less)) { 3895c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner TemplateTy Template; 390014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor UnqualifiedId TemplateName; 391014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor TemplateName.setIdentifier(&II, Tok.getLocation()); 3921fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor bool MemberOfUnknownSpecialization; 39323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor if (TemplateNameKind TNK = Actions.isTemplateName(getCurScope(), SS, 3947c15353ccaed24f2df932571166bf305c1b98b6dAbramo Bagnara /*hasTemplateKeyword=*/false, 395014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor TemplateName, 3962dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor ObjectType, 397495c35d291da48c4f5655bbb54d15128ddde0d4dDouglas Gregor EnteringContext, 3981fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor Template, 3991fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor MemberOfUnknownSpecialization)) { 4006796fc1adcaf57c38d072a238b016b2834afbe0dDavid Blaikie // We have found a template name, so annotate this token 4015c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // with a template-id annotation. We do not permit the 4025c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // template-id to be translated into a type annotation, 4035c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // because some clients (e.g., the parsing of class template 4045c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // specializations) still want to see the original template-id 4055c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // token. 406ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor ConsumeToken(); 407059101f922de6eb765601459925f4c8914420b23Douglas Gregor if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateName, 408ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor SourceLocation(), false)) 4099ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return true; 4105c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner continue; 411d5ab9b0a0ae24f7d0f49f6f10fd1b247e64b3306Douglas Gregor } 412d5ab9b0a0ae24f7d0f49f6f10fd1b247e64b3306Douglas Gregor 413d5ab9b0a0ae24f7d0f49f6f10fd1b247e64b3306Douglas Gregor if (MemberOfUnknownSpecialization && (ObjectType || SS.isSet()) && 4144147d307086cf024a40a080e2bf379e9725f6f41Francois Pichet (IsTypename || IsTemplateArgumentList(1))) { 415d5ab9b0a0ae24f7d0f49f6f10fd1b247e64b3306Douglas Gregor // We have something like t::getAs<T>, where getAs is a 416d5ab9b0a0ae24f7d0f49f6f10fd1b247e64b3306Douglas Gregor // member of an unknown specialization. However, this will only 417d5ab9b0a0ae24f7d0f49f6f10fd1b247e64b3306Douglas Gregor // parse correctly as a template, so suggest the keyword 'template' 418d5ab9b0a0ae24f7d0f49f6f10fd1b247e64b3306Douglas Gregor // before 'getAs' and treat this as a dependent template name. 4194147d307086cf024a40a080e2bf379e9725f6f41Francois Pichet unsigned DiagID = diag::err_missing_dependent_template_keyword; 42062ec1f2fd7368542bb926c04797fb07023547694Francois Pichet if (getLang().MicrosoftExt) 421cf320c6388c90f1938c264e87d77a0e43946e2c3Francois Pichet DiagID = diag::warn_missing_dependent_template_keyword; 4224147d307086cf024a40a080e2bf379e9725f6f41Francois Pichet 4234147d307086cf024a40a080e2bf379e9725f6f41Francois Pichet Diag(Tok.getLocation(), DiagID) 424d5ab9b0a0ae24f7d0f49f6f10fd1b247e64b3306Douglas Gregor << II.getName() 425d5ab9b0a0ae24f7d0f49f6f10fd1b247e64b3306Douglas Gregor << FixItHint::CreateInsertion(Tok.getLocation(), "template "); 426d5ab9b0a0ae24f7d0f49f6f10fd1b247e64b3306Douglas Gregor 427d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor if (TemplateNameKind TNK 42823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor = Actions.ActOnDependentTemplateName(getCurScope(), 429d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor Tok.getLocation(), SS, 430d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor TemplateName, ObjectType, 431d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor EnteringContext, Template)) { 432d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor // Consume the identifier. 433d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor ConsumeToken(); 434059101f922de6eb765601459925f4c8914420b23Douglas Gregor if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateName, 435d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor SourceLocation(), false)) 436d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor return true; 437d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor } 438d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor else 439d5ab9b0a0ae24f7d0f49f6f10fd1b247e64b3306Douglas Gregor return true; 440d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor 441d5ab9b0a0ae24f7d0f49f6f10fd1b247e64b3306Douglas Gregor continue; 4425c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner } 4435c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner } 4445c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner 44539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // We don't have any tokens that form the beginning of a 44639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // nested-name-specifier, so we're done. 44739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor break; 44839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor } 4491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 450d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // Even if we didn't see any pieces of a nested-name-specifier, we 451d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // still check whether there is a tilde in this position, which 452d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // indicates a potential pseudo-destructor. 453d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor if (CheckForDestructor && Tok.is(tok::tilde)) 454d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor *MayBePseudoDestructor = true; 455d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor 4569ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return false; 457eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis} 458eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 459eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// ParseCXXIdExpression - Handle id-expression. 460eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 461eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// id-expression: 462eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// unqualified-id 463eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// qualified-id 464eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 465eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// qualified-id: 466eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 467eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' identifier 468eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' operator-function-id 469edce4dd44732dfad69f28822dddcf2b8e92b4483Douglas Gregor/// '::' template-id 470eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 471eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// NOTE: The standard specifies that, for qualified-id, the parser does not 472eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// expect: 473eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 474eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' conversion-function-id 475eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' '~' class-name 476eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 477eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// This may cause a slight inconsistency on diagnostics: 478eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 479eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// class C {}; 480eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// namespace A {} 481eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// void f() { 482eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// :: A :: ~ C(); // Some Sema error about using destructor with a 483eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// // namespace. 484eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// :: ~ C(); // Some Parser error like 'unexpected ~'. 485eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// } 486eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 487eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// We simplify the parser a bit and make it work like: 488eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 489eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// qualified-id: 490eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 491eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' unqualified-id 492eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 493eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// That way Sema can handle and report similar errors for namespaces and the 494eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// global scope. 495eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 496ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl/// The isAddressOfOperand parameter indicates that this id-expression is a 497ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl/// direct operand of the address-of operator. This is, besides member contexts, 498ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl/// the only place where a qualified-id naming a non-static class member may 499ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl/// appear. 500ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl/// 50160d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) { 502eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // qualified-id: 503eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 504eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // '::' unqualified-id 505eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // 506eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis CXXScopeSpec SS; 507efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); 50802a24ee67c0a91bdb0db8a651d5748595652e670Douglas Gregor 50902a24ee67c0a91bdb0db8a651d5748595652e670Douglas Gregor UnqualifiedId Name; 51002a24ee67c0a91bdb0db8a651d5748595652e670Douglas Gregor if (ParseUnqualifiedId(SS, 51102a24ee67c0a91bdb0db8a651d5748595652e670Douglas Gregor /*EnteringContext=*/false, 51202a24ee67c0a91bdb0db8a651d5748595652e670Douglas Gregor /*AllowDestructorName=*/false, 51302a24ee67c0a91bdb0db8a651d5748595652e670Douglas Gregor /*AllowConstructorName=*/false, 514b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall /*ObjectType=*/ ParsedType(), 51502a24ee67c0a91bdb0db8a651d5748595652e670Douglas Gregor Name)) 51602a24ee67c0a91bdb0db8a651d5748595652e670Douglas Gregor return ExprError(); 517b681b61fea36618778b8030360e90e3f4641233bJohn McCall 518b681b61fea36618778b8030360e90e3f4641233bJohn McCall // This is only the direct operand of an & operator if it is not 519b681b61fea36618778b8030360e90e3f4641233bJohn McCall // followed by a postfix-expression suffix. 5209c72c6088d591ace8503b842d39448c2040f3033John McCall if (isAddressOfOperand && isPostfixExpressionSuffixStart()) 5219c72c6088d591ace8503b842d39448c2040f3033John McCall isAddressOfOperand = false; 52202a24ee67c0a91bdb0db8a651d5748595652e670Douglas Gregor 52323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor return Actions.ActOnIdExpression(getCurScope(), SS, Name, Tok.is(tok::l_paren), 52402a24ee67c0a91bdb0db8a651d5748595652e670Douglas Gregor isAddressOfOperand); 52502a24ee67c0a91bdb0db8a651d5748595652e670Douglas Gregor 526eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis} 527eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 528ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// ParseLambdaExpression - Parse a C++0x lambda expression. 529ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 530ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// lambda-expression: 531ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// lambda-introducer lambda-declarator[opt] compound-statement 532ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 533ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// lambda-introducer: 534ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// '[' lambda-capture[opt] ']' 535ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 536ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// lambda-capture: 537ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// capture-default 538ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// capture-list 539ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// capture-default ',' capture-list 540ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 541ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// capture-default: 542ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// '&' 543ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// '=' 544ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 545ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// capture-list: 546ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// capture 547ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// capture-list ',' capture 548ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 549ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// capture: 550ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// identifier 551ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// '&' identifier 552ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 'this' 553ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 554ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// lambda-declarator: 555ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// '(' parameter-declaration-clause ')' attribute-specifier[opt] 556ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 'mutable'[opt] exception-specification[opt] 557ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// trailing-return-type[opt] 558ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 559ae7902c4293d9de8b9591759513f0d075f45022aDouglas GregorExprResult Parser::ParseLambdaExpression() { 560ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // Parse lambda-introducer. 561ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor LambdaIntroducer Intro; 562ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 563ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor llvm::Optional<unsigned> DiagID(ParseLambdaIntroducer(Intro)); 564ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (DiagID) { 565ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Diag(Tok, DiagID.getValue()); 566ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor SkipUntil(tok::r_square); 567dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman SkipUntil(tok::l_brace); 568dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman SkipUntil(tok::r_brace); 569dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman return ExprError(); 570ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 571ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 572ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor return ParseLambdaExpressionAfterIntroducer(Intro); 573ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor} 574ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 575ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// TryParseLambdaExpression - Use lookahead and potentially tentative 576ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// parsing to determine if we are looking at a C++0x lambda expression, and parse 577ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// it if we are. 578ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 579ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// If we are not looking at a lambda expression, returns ExprError(). 580ae7902c4293d9de8b9591759513f0d075f45022aDouglas GregorExprResult Parser::TryParseLambdaExpression() { 581ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor assert(getLang().CPlusPlus0x 582ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor && Tok.is(tok::l_square) 583ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor && "Not at the start of a possible lambda expression."); 584ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 585ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor const Token Next = NextToken(), After = GetLookAheadToken(2); 586ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 587ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // If lookahead indicates this is a lambda... 588ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (Next.is(tok::r_square) || // [] 589ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Next.is(tok::equal) || // [= 590ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor (Next.is(tok::amp) && // [&] or [&, 591ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor (After.is(tok::r_square) || 592ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor After.is(tok::comma))) || 593ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor (Next.is(tok::identifier) && // [identifier] 594ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor After.is(tok::r_square))) { 595ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor return ParseLambdaExpression(); 596ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 597ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 598dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman // If lookahead indicates an ObjC message send... 599dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman // [identifier identifier 600ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (Next.is(tok::identifier) && After.is(tok::identifier)) { 601dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman return ExprEmpty(); 602ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 603ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 604dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman // Here, we're stuck: lambda introducers and Objective-C message sends are 605dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman // unambiguous, but it requires arbitrary lookhead. [a,b,c,d,e,f,g] is a 606dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman // lambda, and [a,b,c,d,e,f,g h] is a Objective-C message send. Instead of 607dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman // writing two routines to parse a lambda introducer, just try to parse 608dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman // a lambda introducer first, and fall back if that fails. 609dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman // (TryParseLambdaIntroducer never produces any diagnostic output.) 610ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor LambdaIntroducer Intro; 611ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (TryParseLambdaIntroducer(Intro)) 612dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman return ExprEmpty(); 613ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor return ParseLambdaExpressionAfterIntroducer(Intro); 614ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor} 615ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 616ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// ParseLambdaExpression - Parse a lambda introducer. 617ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 618ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// Returns a DiagnosticID if it hit something unexpected. 619ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregorllvm::Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro) { 620ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor typedef llvm::Optional<unsigned> DiagResult; 621ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 622ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor assert(Tok.is(tok::l_square) && "Lambda expressions begin with '['."); 6234a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_square); 6244a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 6254a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor 6264a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Intro.Range.setBegin(T.getOpenLocation()); 627ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 628ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor bool first = true; 629ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 630ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // Parse capture-default. 631ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (Tok.is(tok::amp) && 632ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor (NextToken().is(tok::comma) || NextToken().is(tok::r_square))) { 633ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Intro.Default = LCD_ByRef; 634ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ConsumeToken(); 635ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor first = false; 636ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } else if (Tok.is(tok::equal)) { 637ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Intro.Default = LCD_ByCopy; 638ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ConsumeToken(); 639ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor first = false; 640ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 641ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 642ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor while (Tok.isNot(tok::r_square)) { 643ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (!first) { 644ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (Tok.isNot(tok::comma)) 645ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor return DiagResult(diag::err_expected_comma_or_rsquare); 646ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ConsumeToken(); 647ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 648ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 649ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor first = false; 650ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 651ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // Parse capture. 652ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor LambdaCaptureKind Kind = LCK_ByCopy; 653ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor SourceLocation Loc; 654ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor IdentifierInfo* Id = 0; 655ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 656ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (Tok.is(tok::kw_this)) { 657ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Kind = LCK_This; 658ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Loc = ConsumeToken(); 659ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } else { 660ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (Tok.is(tok::amp)) { 661ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Kind = LCK_ByRef; 662ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ConsumeToken(); 663ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 664ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 665ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (Tok.is(tok::identifier)) { 666ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Id = Tok.getIdentifierInfo(); 667ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Loc = ConsumeToken(); 668ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } else if (Tok.is(tok::kw_this)) { 669ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // FIXME: If we want to suggest a fixit here, will need to return more 670ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // than just DiagnosticID. Perhaps full DiagnosticBuilder that can be 671ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // Clear()ed to prevent emission in case of tentative parsing? 672ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor return DiagResult(diag::err_this_captured_by_reference); 673ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } else { 674ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor return DiagResult(diag::err_expected_capture); 675ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 676ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 677ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 678ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Intro.addCapture(Kind, Loc, Id); 679ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 680ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 6814a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 6824a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Intro.Range.setEnd(T.getCloseLocation()); 683ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 684ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor return DiagResult(); 685ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor} 686ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 687ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// TryParseLambdaExpression - Tentatively parse a lambda introducer. 688ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 689ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// Returns true if it hit something unexpected. 690ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregorbool Parser::TryParseLambdaIntroducer(LambdaIntroducer &Intro) { 691ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor TentativeParsingAction PA(*this); 692ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 693ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor llvm::Optional<unsigned> DiagID(ParseLambdaIntroducer(Intro)); 694ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 695ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (DiagID) { 696ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor PA.Revert(); 697ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor return true; 698ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 699ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 700ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor PA.Commit(); 701ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor return false; 702ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor} 703ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 704ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// ParseLambdaExpressionAfterIntroducer - Parse the rest of a lambda 705ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// expression. 706ae7902c4293d9de8b9591759513f0d075f45022aDouglas GregorExprResult Parser::ParseLambdaExpressionAfterIntroducer( 707ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor LambdaIntroducer &Intro) { 708dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman SourceLocation LambdaBeginLoc = Intro.Range.getBegin(); 709dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman Diag(LambdaBeginLoc, diag::warn_cxx98_compat_lambda); 710dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman 711dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), LambdaBeginLoc, 712dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman "lambda expression parsing"); 713dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman 714dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman Actions.ActOnLambdaStart(LambdaBeginLoc, getCurScope()); 7157fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith 716ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // Parse lambda-declarator[opt]. 717ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor DeclSpec DS(AttrFactory); 718dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman Declarator D(DS, Declarator::BlockLiteralContext); 719ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 720ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (Tok.is(tok::l_paren)) { 721ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ParseScope PrototypeScope(this, 722ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Scope::FunctionPrototypeScope | 723ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Scope::DeclScope); 724ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 7254a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SourceLocation DeclLoc, DeclEndLoc; 7264a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 7274a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 7284a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor DeclLoc = T.getOpenLocation(); 729ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 730ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // Parse parameter-declaration-clause. 731ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ParsedAttributes Attr(AttrFactory); 732ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor llvm::SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo; 733ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor SourceLocation EllipsisLoc; 734ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 735ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (Tok.isNot(tok::r_paren)) 736ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ParseParameterDeclarationClause(D, Attr, ParamInfo, EllipsisLoc); 737ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 7384a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 7394a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor DeclEndLoc = T.getCloseLocation(); 740ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 741ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // Parse 'mutable'[opt]. 742ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor SourceLocation MutableLoc; 743ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (Tok.is(tok::kw_mutable)) { 744ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor MutableLoc = ConsumeToken(); 745ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor DeclEndLoc = MutableLoc; 746ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 747ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 748ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // Parse exception-specification[opt]. 749ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ExceptionSpecificationType ESpecType = EST_None; 750ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor SourceRange ESpecRange; 751ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor llvm::SmallVector<ParsedType, 2> DynamicExceptions; 752ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor llvm::SmallVector<SourceRange, 2> DynamicExceptionRanges; 753ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ExprResult NoexceptExpr; 754ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ESpecType = MaybeParseExceptionSpecification(ESpecRange, 755ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor DynamicExceptions, 756ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor DynamicExceptionRanges, 757ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor NoexceptExpr); 758ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 759ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (ESpecType != EST_None) 760ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor DeclEndLoc = ESpecRange.getEnd(); 761ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 762ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // Parse attribute-specifier[opt]. 763ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor MaybeParseCXX0XAttributes(Attr, &DeclEndLoc); 764ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 765ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // Parse trailing-return-type[opt]. 766ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ParsedType TrailingReturnType; 767ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (Tok.is(tok::arrow)) { 768ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor SourceRange Range; 769ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor TrailingReturnType = ParseTrailingReturnType(Range).get(); 770ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (Range.getEnd().isValid()) 771ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor DeclEndLoc = Range.getEnd(); 772ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 773ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 774ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor PrototypeScope.Exit(); 775ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 776ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor D.AddTypeInfo(DeclaratorChunk::getFunction(/*hasProto=*/true, 777ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor /*isVariadic=*/EllipsisLoc.isValid(), 778ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor EllipsisLoc, 779ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ParamInfo.data(), ParamInfo.size(), 780ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor DS.getTypeQualifiers(), 781ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor /*RefQualifierIsLValueRef=*/true, 782ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor /*RefQualifierLoc=*/SourceLocation(), 78343f5103f8051bbac19022e6edaf7d9138b0f3c0fDouglas Gregor /*ConstQualifierLoc=*/SourceLocation(), 78443f5103f8051bbac19022e6edaf7d9138b0f3c0fDouglas Gregor /*VolatileQualifierLoc=*/SourceLocation(), 785ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor MutableLoc, 786ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ESpecType, ESpecRange.getBegin(), 787ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor DynamicExceptions.data(), 788ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor DynamicExceptionRanges.data(), 789ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor DynamicExceptions.size(), 790ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor NoexceptExpr.isUsable() ? 791ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor NoexceptExpr.get() : 0, 792ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor DeclLoc, DeclEndLoc, D, 793ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor TrailingReturnType), 794ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Attr, DeclEndLoc); 795dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman 796deeab90783eb28d955add1062b616c030eb2b781Eli Friedman // Inform sema that we are starting a block. 797deeab90783eb28d955add1062b616c030eb2b781Eli Friedman Actions.ActOnLambdaArguments(D, getCurScope()); 798ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 799ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 800ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // Parse compound-statement. 801dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman if (!Tok.is(tok::l_brace)) { 802ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Diag(Tok, diag::err_expected_lambda_body); 803dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope()); 804dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman return ExprError(); 805ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 806ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 807dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman // FIXME: Rename BlockScope -> ClosureScope if we decide to continue using 808dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman // it. 809dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman ParseScope BodyScope(this, Scope::BlockScope | Scope::FnScope | 810dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman Scope::BreakScope | Scope::ContinueScope | 811dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman Scope::DeclScope); 812dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman StmtResult Stmt(ParseCompoundStatementBody()); 813dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman BodyScope.Exit(); 814dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman 815deeab90783eb28d955add1062b616c030eb2b781Eli Friedman if (!Stmt.isInvalid()) 816deeab90783eb28d955add1062b616c030eb2b781Eli Friedman return Actions.ActOnLambdaExpr(LambdaBeginLoc, Stmt.take(), 817deeab90783eb28d955add1062b616c030eb2b781Eli Friedman getCurScope()); 818dc3b723d35067e5d13474247b94a10c869cc7e58Eli Friedman 819deeab90783eb28d955add1062b616c030eb2b781Eli Friedman Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope()); 820deeab90783eb28d955add1062b616c030eb2b781Eli Friedman return ExprError(); 821ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor} 822ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 8235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCXXCasts - This handles the various ways to cast expressions to another 8245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// type. 8255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 8265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// postfix-expression: [C++ 5.2p1] 8275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'dynamic_cast' '<' type-name '>' '(' expression ')' 8285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'static_cast' '<' type-name '>' '(' expression ')' 8295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'reinterpret_cast' '<' type-name '>' '(' expression ')' 8305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'const_cast' '<' type-name '>' '(' expression ')' 8315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 83260d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Parser::ParseCXXCasts() { 8335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer tok::TokenKind Kind = Tok.getKind(); 8345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const char *CastName = 0; // For error messages 8355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 8365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer switch (Kind) { 837eb2d1f1c88836bd5382e5d7aa8f6b85148a88b27David Blaikie default: llvm_unreachable("Unknown C++ cast!"); 8385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_const_cast: CastName = "const_cast"; break; 8395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_dynamic_cast: CastName = "dynamic_cast"; break; 8405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break; 8415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_static_cast: CastName = "static_cast"; break; 8425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 8435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 8445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation OpLoc = ConsumeToken(); 8455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation LAngleBracketLoc = Tok.getLocation(); 8465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 847ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith // Check for "<::" which is parsed as "[:". If found, fix token stream, 848ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith // diagnose error, suggest fix, and recover parsing. 849ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith Token Next = NextToken(); 850ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith if (Tok.is(tok::l_square) && Tok.getLength() == 2 && Next.is(tok::colon) && 851ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith AreTokensAdjacent(PP, Tok, Next)) 852ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith FixDigraph(*this, PP, Tok, Next, Kind, /*AtDigraph*/true); 853ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith 8545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName)) 85520df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 8565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 85731862ba5ea70b1f2c81d03f8a0100b61cd6f06f6Argyrios Kyrtzidis // Parse the common declaration-specifiers piece. 85831862ba5ea70b1f2c81d03f8a0100b61cd6f06f6Argyrios Kyrtzidis DeclSpec DS(AttrFactory); 85931862ba5ea70b1f2c81d03f8a0100b61cd6f06f6Argyrios Kyrtzidis ParseSpecifierQualifierList(DS); 86031862ba5ea70b1f2c81d03f8a0100b61cd6f06f6Argyrios Kyrtzidis 86131862ba5ea70b1f2c81d03f8a0100b61cd6f06f6Argyrios Kyrtzidis // Parse the abstract-declarator, if present. 86231862ba5ea70b1f2c81d03f8a0100b61cd6f06f6Argyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 86331862ba5ea70b1f2c81d03f8a0100b61cd6f06f6Argyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 86431862ba5ea70b1f2c81d03f8a0100b61cd6f06f6Argyrios Kyrtzidis 8655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation RAngleBracketLoc = Tok.getLocation(); 8665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 8671ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner if (ExpectAndConsume(tok::greater, diag::err_expected_greater)) 86820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << "<"); 8695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 8704a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SourceLocation LParenLoc, RParenLoc; 8714a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 8725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 8734a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.expectAndConsume(diag::err_expected_lparen_after, CastName)) 87421e7ad24099965acfa801e4abdd91e3d94106428Argyrios Kyrtzidis return ExprError(); 8755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 87660d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult Result = ParseExpression(); 8771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 87821e7ad24099965acfa801e4abdd91e3d94106428Argyrios Kyrtzidis // Match the ')'. 8794a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 8805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 88131862ba5ea70b1f2c81d03f8a0100b61cd6f06f6Argyrios Kyrtzidis if (!Result.isInvalid() && !DeclaratorInfo.isInvalidType()) 88249badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor Result = Actions.ActOnCXXNamedCast(OpLoc, Kind, 88331862ba5ea70b1f2c81d03f8a0100b61cd6f06f6Argyrios Kyrtzidis LAngleBracketLoc, DeclaratorInfo, 884809070a886684cb5b92eb0e00a6581ab1fa6b17aDouglas Gregor RAngleBracketLoc, 8854a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getOpenLocation(), Result.take(), 8864a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()); 8875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 88820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return move(Result); 8895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 8905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 891c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// ParseCXXTypeid - This handles the C++ typeid expression. 892c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 893c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// postfix-expression: [C++ 5.2p1] 894c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 'typeid' '(' expression ')' 895c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 'typeid' '(' type-id ')' 896c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 89760d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Parser::ParseCXXTypeid() { 898c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!"); 899c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 900c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SourceLocation OpLoc = ConsumeToken(); 9014a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SourceLocation LParenLoc, RParenLoc; 9024a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 903c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 904c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl // typeid expressions are always parenthesized. 9054a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.expectAndConsume(diag::err_expected_lparen_after, "typeid")) 90620df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 9074a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor LParenLoc = T.getOpenLocation(); 908c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 90960d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult Result; 910c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 911c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl if (isTypeIdInParens()) { 912809070a886684cb5b92eb0e00a6581ab1fa6b17aDouglas Gregor TypeResult Ty = ParseTypeName(); 913c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 914c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl // Match the ')'. 9154a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 9164a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor RParenLoc = T.getCloseLocation(); 9174eb4f0f96289cbece50c1270e02af3caf8779705Douglas Gregor if (Ty.isInvalid() || RParenLoc.isInvalid()) 91820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 919c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 920c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true, 921b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall Ty.get().getAsOpaquePtr(), RParenLoc); 922c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl } else { 923e0762c92110dfdcdd207db461a4ea17afd168f1eDouglas Gregor // C++0x [expr.typeid]p3: 9241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // When typeid is applied to an expression other than an lvalue of a 9251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // polymorphic class type [...] The expression is an unevaluated 926e0762c92110dfdcdd207db461a4ea17afd168f1eDouglas Gregor // operand (Clause 5). 927e0762c92110dfdcdd207db461a4ea17afd168f1eDouglas Gregor // 9281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Note that we can't tell whether the expression is an lvalue of a 929e0762c92110dfdcdd207db461a4ea17afd168f1eDouglas Gregor // polymorphic class type until after we've parsed the expression, so 930ac7610dad6653bad02dd42de198ca358b6fb1f1dDouglas Gregor // we the expression is potentially potentially evaluated. 931ac7610dad6653bad02dd42de198ca358b6fb1f1dDouglas Gregor EnterExpressionEvaluationContext Unevaluated(Actions, 932f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall Sema::PotentiallyPotentiallyEvaluated); 933c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Result = ParseExpression(); 934c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 935c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl // Match the ')'. 9360e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Result.isInvalid()) 937c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SkipUntil(tok::r_paren); 938c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl else { 9394a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 9404a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor RParenLoc = T.getCloseLocation(); 9414eb4f0f96289cbece50c1270e02af3caf8779705Douglas Gregor if (RParenLoc.isInvalid()) 9424eb4f0f96289cbece50c1270e02af3caf8779705Douglas Gregor return ExprError(); 943fadb53b351977ca7f99a9a613596cba6531979a3Douglas Gregor 944c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false, 945effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl Result.release(), RParenLoc); 946c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl } 947c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl } 948c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 94920df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return move(Result); 950c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl} 951c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 95201b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet/// ParseCXXUuidof - This handles the Microsoft C++ __uuidof expression. 95301b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet/// 95401b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet/// '__uuidof' '(' expression ')' 95501b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet/// '__uuidof' '(' type-id ')' 95601b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet/// 95701b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois PichetExprResult Parser::ParseCXXUuidof() { 95801b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet assert(Tok.is(tok::kw___uuidof) && "Not '__uuidof'!"); 95901b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet 96001b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet SourceLocation OpLoc = ConsumeToken(); 9614a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 96201b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet 96301b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet // __uuidof expressions are always parenthesized. 9644a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.expectAndConsume(diag::err_expected_lparen_after, "__uuidof")) 96501b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet return ExprError(); 96601b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet 96701b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet ExprResult Result; 96801b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet 96901b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet if (isTypeIdInParens()) { 97001b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet TypeResult Ty = ParseTypeName(); 97101b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet 97201b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet // Match the ')'. 9734a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 97401b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet 97501b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet if (Ty.isInvalid()) 97601b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet return ExprError(); 97701b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet 9784a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Result = Actions.ActOnCXXUuidof(OpLoc, T.getOpenLocation(), /*isType=*/true, 9794a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Ty.get().getAsOpaquePtr(), 9804a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()); 98101b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet } else { 98201b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated); 98301b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet Result = ParseExpression(); 98401b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet 98501b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet // Match the ')'. 98601b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet if (Result.isInvalid()) 98701b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet SkipUntil(tok::r_paren); 98801b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet else { 9894a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 99001b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet 9914a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Result = Actions.ActOnCXXUuidof(OpLoc, T.getOpenLocation(), 9924a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor /*isType=*/false, 9934a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Result.release(), T.getCloseLocation()); 99401b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet } 99501b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet } 99601b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet 99701b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet return move(Result); 99801b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet} 99901b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet 1000d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// \brief Parse a C++ pseudo-destructor expression after the base, 1001d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// . or -> operator, and nested-name-specifier have already been 1002d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// parsed. 1003d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// 1004d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// postfix-expression: [C++ 5.2] 1005d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// postfix-expression . pseudo-destructor-name 1006d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// postfix-expression -> pseudo-destructor-name 1007d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// 1008d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// pseudo-destructor-name: 1009d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// ::[opt] nested-name-specifier[opt] type-name :: ~type-name 1010d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// ::[opt] nested-name-specifier template simple-template-id :: 1011d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// ~type-name 1012d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// ::[opt] nested-name-specifier[opt] ~type-name 1013d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// 101460d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult 1015d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas GregorParser::ParseCXXPseudoDestructor(ExprArg Base, SourceLocation OpLoc, 1016d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor tok::TokenKind OpKind, 1017d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor CXXScopeSpec &SS, 1018b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType ObjectType) { 1019d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // We're parsing either a pseudo-destructor-name or a dependent 1020d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // member access that has the same form as a 1021d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // pseudo-destructor-name. We parse both in the same way and let 1022d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // the action model sort them out. 1023d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // 1024d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // Note that the ::[opt] nested-name-specifier[opt] has already 1025d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // been parsed, and if there was a simple-template-id, it has 1026d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // been coalesced into a template-id annotation token. 1027d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor UnqualifiedId FirstTypeName; 1028d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor SourceLocation CCLoc; 1029d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor if (Tok.is(tok::identifier)) { 1030d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor FirstTypeName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); 1031d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor ConsumeToken(); 1032d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail"); 1033d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor CCLoc = ConsumeToken(); 1034d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor } else if (Tok.is(tok::annot_template_id)) { 1035d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor FirstTypeName.setTemplateId( 1036d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor (TemplateIdAnnotation *)Tok.getAnnotationValue()); 1037d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor ConsumeToken(); 1038d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail"); 1039d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor CCLoc = ConsumeToken(); 1040d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor } else { 1041d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor FirstTypeName.setIdentifier(0, SourceLocation()); 1042d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor } 1043d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor 1044d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // Parse the tilde. 1045d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor assert(Tok.is(tok::tilde) && "ParseOptionalCXXScopeSpecifier fail"); 1046d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor SourceLocation TildeLoc = ConsumeToken(); 104791ec7894ec186dd36f509682f00486c98d8228edDavid Blaikie 104891ec7894ec186dd36f509682f00486c98d8228edDavid Blaikie if (Tok.is(tok::kw_decltype) && !FirstTypeName.isValid() && SS.isEmpty()) { 104991ec7894ec186dd36f509682f00486c98d8228edDavid Blaikie DeclSpec DS(AttrFactory); 105085c60db2131c6d210d4777c3d50bdaf0e69bb8bfBenjamin Kramer ParseDecltypeSpecifier(DS); 105191ec7894ec186dd36f509682f00486c98d8228edDavid Blaikie if (DS.getTypeSpecType() == TST_error) 105291ec7894ec186dd36f509682f00486c98d8228edDavid Blaikie return ExprError(); 105391ec7894ec186dd36f509682f00486c98d8228edDavid Blaikie return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base, OpLoc, 105491ec7894ec186dd36f509682f00486c98d8228edDavid Blaikie OpKind, TildeLoc, DS, 105591ec7894ec186dd36f509682f00486c98d8228edDavid Blaikie Tok.is(tok::l_paren)); 105691ec7894ec186dd36f509682f00486c98d8228edDavid Blaikie } 105791ec7894ec186dd36f509682f00486c98d8228edDavid Blaikie 1058d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor if (!Tok.is(tok::identifier)) { 1059d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor Diag(Tok, diag::err_destructor_tilde_identifier); 1060d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor return ExprError(); 1061d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor } 1062d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor 1063d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // Parse the second type. 1064d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor UnqualifiedId SecondTypeName; 1065d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor IdentifierInfo *Name = Tok.getIdentifierInfo(); 1066d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor SourceLocation NameLoc = ConsumeToken(); 1067d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor SecondTypeName.setIdentifier(Name, NameLoc); 1068d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor 1069d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // If there is a '<', the second type name is a template-id. Parse 1070d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // it as such. 1071d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor if (Tok.is(tok::less) && 1072d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor ParseUnqualifiedIdTemplateId(SS, Name, NameLoc, false, ObjectType, 10730278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor SecondTypeName, /*AssumeTemplateName=*/true, 10740278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor /*TemplateKWLoc*/SourceLocation())) 1075d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor return ExprError(); 1076d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor 10779ae2f076ca5ab1feb3ba95629099ec2319833701John McCall return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base, 10789ae2f076ca5ab1feb3ba95629099ec2319833701John McCall OpLoc, OpKind, 1079d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor SS, FirstTypeName, CCLoc, 1080d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor TildeLoc, SecondTypeName, 1081d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor Tok.is(tok::l_paren)); 1082d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor} 1083d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor 10845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCXXBoolLiteral - This handles the C++ Boolean literals. 10855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 10865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// boolean-literal: [C++ 2.13.5] 10875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'true' 10885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'false' 108960d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Parser::ParseCXXBoolLiteral() { 10905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer tok::TokenKind Kind = Tok.getKind(); 1091f53597fb16142bdb4a66901f8c0b768db4f2a548Sebastian Redl return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind); 10925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 109350dd289f45738ed22b7583d52ed2525b927042ffChris Lattner 109450dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// ParseThrowExpression - This handles the C++ throw expression. 109550dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// 109650dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// throw-expression: [C++ 15] 109750dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// 'throw' assignment-expression[opt] 109860d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Parser::ParseThrowExpression() { 109950dd289f45738ed22b7583d52ed2525b927042ffChris Lattner assert(Tok.is(tok::kw_throw) && "Not throw!"); 110050dd289f45738ed22b7583d52ed2525b927042ffChris Lattner SourceLocation ThrowLoc = ConsumeToken(); // Eat the throw token. 110120df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl 11022a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // If the current token isn't the start of an assignment-expression, 11032a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // then the expression is not present. This handles things like: 11042a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // "C ? throw : (void)42", which is crazy but legal. 11052a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner switch (Tok.getKind()) { // FIXME: move this predicate somewhere common. 11062a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::semi: 11072a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_paren: 11082a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_square: 11092a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_brace: 11102a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::colon: 11112a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::comma: 1112bca01b46850f867b2f4137f25c882022b58f8471Douglas Gregor return Actions.ActOnCXXThrow(getCurScope(), ThrowLoc, 0); 111350dd289f45738ed22b7583d52ed2525b927042ffChris Lattner 11142a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner default: 111560d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult Expr(ParseAssignmentExpression()); 111620df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl if (Expr.isInvalid()) return move(Expr); 1117bca01b46850f867b2f4137f25c882022b58f8471Douglas Gregor return Actions.ActOnCXXThrow(getCurScope(), ThrowLoc, Expr.take()); 11182a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner } 111950dd289f45738ed22b7583d52ed2525b927042ffChris Lattner} 11204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 11214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXThis - This handles the C++ 'this' pointer. 11224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 11234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// C++ 9.3.2: In the body of a non-static member function, the keyword this is 11244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// a non-lvalue expression whose value is the address of the object for which 11254cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// the function is called. 112660d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Parser::ParseCXXThis() { 11274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis assert(Tok.is(tok::kw_this) && "Not 'this'!"); 11284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SourceLocation ThisLoc = ConsumeToken(); 1129f53597fb16142bdb4a66901f8c0b768db4f2a548Sebastian Redl return Actions.ActOnCXXThis(ThisLoc); 11304cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 1131987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 1132987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// ParseCXXTypeConstructExpression - Parse construction of a specified type. 1133987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// Can be interpreted either as function-style casting ("int(x)") 1134987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// or class type construction ("ClassType(x,y,z)") 1135987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// or creation of a value-initialized type ("int()"). 1136dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl/// See [C++ 5.2.3]. 1137987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 1138987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// postfix-expression: [C++ 5.2p1] 1139dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl/// simple-type-specifier '(' expression-list[opt] ')' 1140dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl/// [C++0x] simple-type-specifier braced-init-list 1141dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl/// typename-specifier '(' expression-list[opt] ')' 1142dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl/// [C++0x] typename-specifier braced-init-list 1143987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 114460d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult 114520df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { 1146987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 1147b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType TypeRep = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get(); 1148987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 1149dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl assert((Tok.is(tok::l_paren) || 1150dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl (getLang().CPlusPlus0x && Tok.is(tok::l_brace))) 1151dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl && "Expected '(' or '{'!"); 1152bc61bd8109d9accf8f966b59e3f16a1497e72adfDouglas Gregor 1153dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl if (Tok.is(tok::l_brace)) { 1154987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 1155dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl // FIXME: Convert to a proper type construct expression. 1156dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl return ParseBraceInitializer(); 1157987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 1158dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl } else { 1159dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl GreaterThanIsOperatorScope G(GreaterThanIsOperator, true); 1160dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl 11614a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 11624a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 1163dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl 1164dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl ExprVector Exprs(Actions); 1165dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl CommaLocsTy CommaLocs; 1166dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl 1167dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl if (Tok.isNot(tok::r_paren)) { 1168dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl if (ParseExpressionList(Exprs, CommaLocs)) { 1169dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl SkipUntil(tok::r_paren); 1170dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl return ExprError(); 1171dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl } 1172987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 1173987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 1174dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl // Match the ')'. 11754a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 1176987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 1177dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl // TypeRep could be null, if it references an invalid typedef. 1178dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl if (!TypeRep) 1179dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl return ExprError(); 1180ef0cb8e62d090ad88a01ca9fa89e48d7416f0ac7Sebastian Redl 1181dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&& 1182dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl "Unexpected number of commas!"); 11834a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor return Actions.ActOnCXXTypeConstructExpr(TypeRep, T.getOpenLocation(), 11844a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor move_arg(Exprs), 11854a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()); 1186dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl } 1187987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis} 1188987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 118999e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor/// ParseCXXCondition - if/switch/while condition expression. 119071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// 119171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// condition: 119271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// expression 119371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// type-specifier-seq declarator '=' assignment-expression 119471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 119571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// '=' assignment-expression 119671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// 119799e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor/// \param ExprResult if the condition was parsed as an expression, the 119899e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor/// parsed expression. 119999e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor/// 120099e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor/// \param DeclResult if the condition was parsed as a declaration, the 120199e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor/// parsed declaration. 120299e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor/// 1203586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor/// \param Loc The location of the start of the statement that requires this 1204586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor/// condition, e.g., the "for" in a for loop. 1205586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor/// 1206586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor/// \param ConvertToBoolean Whether the condition expression should be 1207586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor/// converted to a boolean value. 1208586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor/// 120999e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor/// \returns true if there was a parsing, false otherwise. 121060d7b3a319d84d688752be3870615ac0f111fb16John McCallbool Parser::ParseCXXCondition(ExprResult &ExprOut, 121160d7b3a319d84d688752be3870615ac0f111fb16John McCall Decl *&DeclOut, 1212586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor SourceLocation Loc, 1213586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor bool ConvertToBoolean) { 121401dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor if (Tok.is(tok::code_completion)) { 1215f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Condition); 12167d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis cutOffParsing(); 12177d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis return true; 121801dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor } 121901dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor 122099e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor if (!isCXXConditionDeclaration()) { 1221586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor // Parse the expression. 122260d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprOut = ParseExpression(); // expression 122360d7b3a319d84d688752be3870615ac0f111fb16John McCall DeclOut = 0; 122460d7b3a319d84d688752be3870615ac0f111fb16John McCall if (ExprOut.isInvalid()) 1225586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor return true; 1226586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor 1227586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor // If required, convert to a boolean value. 1228586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor if (ConvertToBoolean) 122960d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprOut 123060d7b3a319d84d688752be3870615ac0f111fb16John McCall = Actions.ActOnBooleanCondition(getCurScope(), Loc, ExprOut.get()); 123160d7b3a319d84d688752be3870615ac0f111fb16John McCall return ExprOut.isInvalid(); 123299e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor } 123371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 123471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // type-specifier-seq 12350b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall DeclSpec DS(AttrFactory); 123671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis ParseSpecifierQualifierList(DS); 123771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 123871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // declarator 123971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::ConditionContext); 124071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 124171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 124271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // simple-asm-expr[opt] 124371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (Tok.is(tok::kw_asm)) { 1244ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl SourceLocation Loc; 124560d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult AsmLabel(ParseSimpleAsm(&Loc)); 12460e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (AsmLabel.isInvalid()) { 124771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SkipUntil(tok::semi); 124899e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor return true; 124971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis } 1250effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl DeclaratorInfo.setAsmLabel(AsmLabel.release()); 1251ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl DeclaratorInfo.SetRangeEnd(Loc); 125271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis } 125371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 125471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // If attributes are present, parse them. 12557f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseGNUAttributes(DeclaratorInfo); 125671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 125799e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor // Type-check the declaration itself. 125860d7b3a319d84d688752be3870615ac0f111fb16John McCall DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(getCurScope(), 12597f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall DeclaratorInfo); 126060d7b3a319d84d688752be3870615ac0f111fb16John McCall DeclOut = Dcl.get(); 126160d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprOut = ExprError(); 1262a6eb5f81d13bacac01faff70a947047725b4413fArgyrios Kyrtzidis 126371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // '=' assignment-expression 1264a6eb5f81d13bacac01faff70a947047725b4413fArgyrios Kyrtzidis if (isTokenEqualOrMistypedEqualEqual( 1265a6eb5f81d13bacac01faff70a947047725b4413fArgyrios Kyrtzidis diag::err_invalid_equalequal_after_declarator)) { 1266dec0984fce504a39a7f085774fb67cfd9957be58Jeffrey Yasskin ConsumeToken(); 126760d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult AssignExpr(ParseAssignmentExpression()); 126899e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor if (!AssignExpr.isInvalid()) 126934b41d939a1328f484511c6002ba2456db879a29Richard Smith Actions.AddInitializerToDecl(DeclOut, AssignExpr.take(), false, 127034b41d939a1328f484511c6002ba2456db879a29Richard Smith DS.getTypeSpecType() == DeclSpec::TST_auto); 127199e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor } else { 127299e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor // FIXME: C++0x allows a braced-init-list 127399e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor Diag(Tok, diag::err_expected_equal_after_declarator); 127499e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor } 127599e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor 1276586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor // FIXME: Build a reference to this declaration? Convert it to bool? 1277586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor // (This is currently handled by Sema). 1278483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith 1279483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith Actions.FinalizeDeclaration(DeclOut); 1280586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor 128199e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor return false; 128271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis} 128371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 12846aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor/// \brief Determine whether the current token starts a C++ 12856aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor/// simple-type-specifier. 12866aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregorbool Parser::isCXXSimpleTypeSpecifier() const { 12876aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor switch (Tok.getKind()) { 12886aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::annot_typename: 12896aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_short: 12906aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_long: 1291338d7f7362d18fa9c39c6bb5282b4e20574a9309Francois Pichet case tok::kw___int64: 12926aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_signed: 12936aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_unsigned: 12946aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_void: 12956aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_char: 12966aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_int: 1297aa4a99b4a62615db243f7a5c433169f2fc704420Anton Korobeynikov case tok::kw_half: 12986aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_float: 12996aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_double: 13006aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_wchar_t: 13016aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_char16_t: 13026aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_char32_t: 13036aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_bool: 1304d9d75e57dfa22366c0379c92beac1db82db34e9aDouglas Gregor case tok::kw_decltype: 13056aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_typeof: 1306db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt case tok::kw___underlying_type: 13076aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor return true; 13086aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor 13096aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor default: 13106aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor break; 13116aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor } 13126aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor 13136aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor return false; 13146aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor} 13156aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor 1316987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers. 1317987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// This should only be called when the current token is known to be part of 1318987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// simple-type-specifier. 1319987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 1320987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// simple-type-specifier: 1321eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier[opt] type-name 1322987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template' simple-template-id [TODO] 1323987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// char 1324987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// wchar_t 1325987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// bool 1326987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// short 1327987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// int 1328987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// long 1329987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// signed 1330987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// unsigned 1331987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// float 1332987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// double 1333987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// void 1334987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// [GNU] typeof-specifier 1335987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// [C++0x] auto [TODO] 1336987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 1337987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// type-name: 1338987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// class-name 1339987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// enum-name 1340987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// typedef-name 1341987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 1342987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidisvoid Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { 1343987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetRangeStart(Tok.getLocation()); 1344987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis const char *PrevSpec; 1345fec54013fcd0eb72642741584ca04c1bc292bef8John McCall unsigned DiagID; 1346987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SourceLocation Loc = Tok.getLocation(); 13471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1348987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis switch (Tok.getKind()) { 134955a7cefc846765ac7d142a63f773747a20518d71Chris Lattner case tok::identifier: // foo::bar 135055a7cefc846765ac7d142a63f773747a20518d71Chris Lattner case tok::coloncolon: // ::foo::bar 1351b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Annotation token should already be formed!"); 13521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump default: 1353b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Not a simple-type-specifier token!"); 135455a7cefc846765ac7d142a63f773747a20518d71Chris Lattner 1355987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // type-name 1356b31757b68afe06ba442a05775d08fe7aa0f6f889Chris Lattner case tok::annot_typename: { 13576952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor if (getTypeAnnotation(Tok)) 13586952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, 13596952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor getTypeAnnotation(Tok)); 13606952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor else 13616952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor DS.SetTypeSpecError(); 13629bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor 13639bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 13649bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor ConsumeToken(); 13659bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor 13669bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id' 13679bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an 13689bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor // Objective-C interface. If we don't have Objective-C or a '<', this is 13699bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor // just a normal reference to a typedef name. 13709bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor if (Tok.is(tok::less) && getLang().ObjC1) 13719bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor ParseObjCProtocolQualifiers(DS); 13729bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor 13739bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor DS.Finish(Diags, PP); 13749bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor return; 1375987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 13761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1377987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // builtin types 1378987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_short: 1379fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, DiagID); 1380987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 1381987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_long: 1382fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec, DiagID); 1383338d7f7362d18fa9c39c6bb5282b4e20574a9309Francois Pichet break; 1384338d7f7362d18fa9c39c6bb5282b4e20574a9309Francois Pichet case tok::kw___int64: 1385338d7f7362d18fa9c39c6bb5282b4e20574a9309Francois Pichet DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec, DiagID); 1386987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 1387987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_signed: 1388fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec, DiagID); 1389987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 1390987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_unsigned: 1391fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec, DiagID); 1392987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 1393987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_void: 1394fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, DiagID); 1395987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 1396987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_char: 1397fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, DiagID); 1398987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 1399987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_int: 1400fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID); 1401987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 1402aa4a99b4a62615db243f7a5c433169f2fc704420Anton Korobeynikov case tok::kw_half: 1403aa4a99b4a62615db243f7a5c433169f2fc704420Anton Korobeynikov DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec, DiagID); 1404aa4a99b4a62615db243f7a5c433169f2fc704420Anton Korobeynikov break; 1405987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_float: 1406fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, DiagID); 1407987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 1408987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_double: 1409fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, DiagID); 1410987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 1411987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_wchar_t: 1412fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID); 1413987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 1414f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith case tok::kw_char16_t: 1415fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, DiagID); 1416f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith break; 1417f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith case tok::kw_char32_t: 1418fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, DiagID); 1419f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith break; 1420987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_bool: 1421fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID); 1422987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 14231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14246aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor // FIXME: C++0x decltype support. 1425987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // GNU typeof support. 1426987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_typeof: 1427987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis ParseTypeofSpecifier(DS); 14289b3064b55f3c858923734e8b1c9831777fc22554Douglas Gregor DS.Finish(Diags, PP); 1429987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis return; 1430987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 1431b31757b68afe06ba442a05775d08fe7aa0f6f889Chris Lattner if (Tok.is(tok::annot_typename)) 1432eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 1433eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis else 1434eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis DS.SetRangeEnd(Tok.getLocation()); 1435987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis ConsumeToken(); 14369b3064b55f3c858923734e8b1c9831777fc22554Douglas Gregor DS.Finish(Diags, PP); 1437987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis} 14381cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 14392f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++ 14402f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// [dcl.name]), which is a non-empty sequence of type-specifiers, 14412f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// e.g., "const short int". Note that the DeclSpec is *not* finished 14422f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// by parsing the type-specifier-seq, because these sequences are 14432f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// typically followed by some form of declarator. Returns true and 14442f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// emits diagnostics if this is not a type-specifier-seq, false 14452f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// otherwise. 14462f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 14472f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// type-specifier-seq: [C++ 8.1] 14482f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// type-specifier type-specifier-seq[opt] 14492f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 14502f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregorbool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) { 14512f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor DS.SetRangeStart(Tok.getLocation()); 14522f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor const char *PrevSpec = 0; 1453fec54013fcd0eb72642741584ca04c1bc292bef8John McCall unsigned DiagID; 1454fec54013fcd0eb72642741584ca04c1bc292bef8John McCall bool isInvalid = 0; 14552f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 14562f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Parse one or more of the type specifiers. 1457d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl if (!ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID, 1458d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl ParsedTemplateInfo(), /*SuppressDeclarations*/true)) { 14599fa8e569407e02148888136609431a3fe083096dNick Lewycky Diag(Tok, diag::err_expected_type); 14602f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return true; 14612f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor } 14621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1463d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl while (ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID, 1464d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl ParsedTemplateInfo(), /*SuppressDeclarations*/true)) 1465d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl {} 14662f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 1467396a9f235e160093b5f803f7a6a18fad7b68bdbeDouglas Gregor DS.Finish(Diags, PP); 14682f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return false; 14692f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor} 14702f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 14713f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \brief Finish parsing a C++ unqualified-id that is a template-id of 14723f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// some form. 14733f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 14743f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// This routine is invoked when a '<' is encountered after an identifier or 14753f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// operator-function-id is parsed by \c ParseUnqualifiedId() to determine 14763f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// whether the unqualified-id is actually a template-id. This routine will 14773f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// then parse the template arguments and form the appropriate template-id to 14783f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// return to the caller. 14793f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 14803f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \param SS the nested-name-specifier that precedes this template-id, if 14813f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// we're actually parsing a qualified-id. 14823f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 14833f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \param Name for constructor and destructor names, this is the actual 14843f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// identifier that may be a template-name. 14853f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 14863f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \param NameLoc the location of the class-name in a constructor or 14873f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// destructor. 14883f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 14893f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \param EnteringContext whether we're entering the scope of the 14903f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// nested-name-specifier. 14913f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 149246df8cc349096f141c841dbffaa72641ff1dd94bDouglas Gregor/// \param ObjectType if this unqualified-id occurs within a member access 149346df8cc349096f141c841dbffaa72641ff1dd94bDouglas Gregor/// expression, the type of the base object whose member is being accessed. 149446df8cc349096f141c841dbffaa72641ff1dd94bDouglas Gregor/// 14953f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \param Id as input, describes the template-name or operator-function-id 14963f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// that precedes the '<'. If template arguments were parsed successfully, 14973f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// will be updated with the template-id. 14983f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 1499d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// \param AssumeTemplateId When true, this routine will assume that the name 1500d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// refers to a template without performing name lookup to verify. 1501d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// 15023f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \returns true if a parse error occurred, false otherwise. 15033f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregorbool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, 15043f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor IdentifierInfo *Name, 15053f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor SourceLocation NameLoc, 15063f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor bool EnteringContext, 1507b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType ObjectType, 1508d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor UnqualifiedId &Id, 15090278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor bool AssumeTemplateId, 15100278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor SourceLocation TemplateKWLoc) { 15110278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor assert((AssumeTemplateId || Tok.is(tok::less)) && 15120278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor "Expected '<' to finish parsing a template-id"); 15133f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 15143f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor TemplateTy Template; 15153f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor TemplateNameKind TNK = TNK_Non_template; 15163f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor switch (Id.getKind()) { 15173f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor case UnqualifiedId::IK_Identifier: 1518014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor case UnqualifiedId::IK_OperatorFunctionId: 1519e6252d1587f98dbac704178e7b2ce53116048310Sean Hunt case UnqualifiedId::IK_LiteralOperatorId: 1520d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor if (AssumeTemplateId) { 152123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor TNK = Actions.ActOnDependentTemplateName(getCurScope(), TemplateKWLoc, SS, 1522d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor Id, ObjectType, EnteringContext, 1523d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor Template); 1524d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor if (TNK == TNK_Non_template) 1525d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor return true; 15261fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor } else { 15271fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor bool MemberOfUnknownSpecialization; 15287c15353ccaed24f2df932571166bf305c1b98b6dAbramo Bagnara TNK = Actions.isTemplateName(getCurScope(), SS, 15297c15353ccaed24f2df932571166bf305c1b98b6dAbramo Bagnara TemplateKWLoc.isValid(), Id, 15307c15353ccaed24f2df932571166bf305c1b98b6dAbramo Bagnara ObjectType, EnteringContext, Template, 15311fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor MemberOfUnknownSpecialization); 15321fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor 15331fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor if (TNK == TNK_Non_template && MemberOfUnknownSpecialization && 15341fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor ObjectType && IsTemplateArgumentList()) { 15351fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor // We have something like t->getAs<T>(), where getAs is a 15361fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor // member of an unknown specialization. However, this will only 15371fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor // parse correctly as a template, so suggest the keyword 'template' 15381fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor // before 'getAs' and treat this as a dependent template name. 15391fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor std::string Name; 15401fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor if (Id.getKind() == UnqualifiedId::IK_Identifier) 15411fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor Name = Id.Identifier->getName(); 15421fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor else { 15431fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor Name = "operator "; 15441fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor if (Id.getKind() == UnqualifiedId::IK_OperatorFunctionId) 15451fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor Name += getOperatorSpelling(Id.OperatorFunctionId.Operator); 15461fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor else 15471fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor Name += Id.Identifier->getName(); 15481fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor } 15491fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor Diag(Id.StartLocation, diag::err_missing_dependent_template_keyword) 15501fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor << Name 15511fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor << FixItHint::CreateInsertion(Id.StartLocation, "template "); 155223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor TNK = Actions.ActOnDependentTemplateName(getCurScope(), TemplateKWLoc, 1553d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor SS, Id, ObjectType, 1554d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor EnteringContext, Template); 1555d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor if (TNK == TNK_Non_template) 15561fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor return true; 15571fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor } 15581fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor } 15593f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor break; 15603f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 1561014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor case UnqualifiedId::IK_ConstructorName: { 1562014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor UnqualifiedId TemplateName; 15631fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor bool MemberOfUnknownSpecialization; 1564014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor TemplateName.setIdentifier(Name, NameLoc); 15657c15353ccaed24f2df932571166bf305c1b98b6dAbramo Bagnara TNK = Actions.isTemplateName(getCurScope(), SS, TemplateKWLoc.isValid(), 15667c15353ccaed24f2df932571166bf305c1b98b6dAbramo Bagnara TemplateName, ObjectType, 15671fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor EnteringContext, Template, 15681fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor MemberOfUnknownSpecialization); 15693f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor break; 1570014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor } 15713f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 1572014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor case UnqualifiedId::IK_DestructorName: { 1573014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor UnqualifiedId TemplateName; 15741fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor bool MemberOfUnknownSpecialization; 1575014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor TemplateName.setIdentifier(Name, NameLoc); 15762d1c21414199a7452f122598189363a3922605b1Douglas Gregor if (ObjectType) { 157723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor TNK = Actions.ActOnDependentTemplateName(getCurScope(), TemplateKWLoc, SS, 1578d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor TemplateName, ObjectType, 1579d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor EnteringContext, Template); 1580d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor if (TNK == TNK_Non_template) 15812d1c21414199a7452f122598189363a3922605b1Douglas Gregor return true; 15822d1c21414199a7452f122598189363a3922605b1Douglas Gregor } else { 15837c15353ccaed24f2df932571166bf305c1b98b6dAbramo Bagnara TNK = Actions.isTemplateName(getCurScope(), SS, TemplateKWLoc.isValid(), 15847c15353ccaed24f2df932571166bf305c1b98b6dAbramo Bagnara TemplateName, ObjectType, 15851fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor EnteringContext, Template, 15861fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor MemberOfUnknownSpecialization); 15872d1c21414199a7452f122598189363a3922605b1Douglas Gregor 1588b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall if (TNK == TNK_Non_template && !Id.DestructorName.get()) { 1589124b878dba5007df0a268ea128a6ad8dc5dd2c5eDouglas Gregor Diag(NameLoc, diag::err_destructor_template_id) 1590124b878dba5007df0a268ea128a6ad8dc5dd2c5eDouglas Gregor << Name << SS.getRange(); 15912d1c21414199a7452f122598189363a3922605b1Douglas Gregor return true; 15922d1c21414199a7452f122598189363a3922605b1Douglas Gregor } 15932d1c21414199a7452f122598189363a3922605b1Douglas Gregor } 15943f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor break; 1595014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor } 15963f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 15973f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor default: 15983f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return false; 15993f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor } 16003f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 16013f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor if (TNK == TNK_Non_template) 16023f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return false; 16033f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 16043f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // Parse the enclosed template argument list. 16053f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor SourceLocation LAngleLoc, RAngleLoc; 16063f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor TemplateArgList TemplateArgs; 16070278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor if (Tok.is(tok::less) && 16080278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor ParseTemplateIdAfterTemplateName(Template, Id.StartLocation, 1609059101f922de6eb765601459925f4c8914420b23Douglas Gregor SS, true, LAngleLoc, 16103f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor TemplateArgs, 16113f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor RAngleLoc)) 16123f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return true; 16133f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 16143f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor if (Id.getKind() == UnqualifiedId::IK_Identifier || 1615e6252d1587f98dbac704178e7b2ce53116048310Sean Hunt Id.getKind() == UnqualifiedId::IK_OperatorFunctionId || 1616e6252d1587f98dbac704178e7b2ce53116048310Sean Hunt Id.getKind() == UnqualifiedId::IK_LiteralOperatorId) { 16173f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // Form a parsed representation of the template-id to be stored in the 16183f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // UnqualifiedId. 16193f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor TemplateIdAnnotation *TemplateId 16203f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor = TemplateIdAnnotation::Allocate(TemplateArgs.size()); 16213f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 16223f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor if (Id.getKind() == UnqualifiedId::IK_Identifier) { 16233f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor TemplateId->Name = Id.Identifier; 1624014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor TemplateId->Operator = OO_None; 16253f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor TemplateId->TemplateNameLoc = Id.StartLocation; 16263f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor } else { 1627014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor TemplateId->Name = 0; 1628014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor TemplateId->Operator = Id.OperatorFunctionId.Operator; 1629014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor TemplateId->TemplateNameLoc = Id.StartLocation; 16303f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor } 16313f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 1632059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateId->SS = SS; 16332b5289b6fd7e3d9899868410a498c081c9595662John McCall TemplateId->Template = Template; 16343f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor TemplateId->Kind = TNK; 16353f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor TemplateId->LAngleLoc = LAngleLoc; 16363f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor TemplateId->RAngleLoc = RAngleLoc; 1637314b97f8c564b465af605efaee23f91ec18a982bDouglas Gregor ParsedTemplateArgument *Args = TemplateId->getTemplateArgs(); 16383f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); 1639314b97f8c564b465af605efaee23f91ec18a982bDouglas Gregor Arg != ArgEnd; ++Arg) 16403f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor Args[Arg] = TemplateArgs[Arg]; 16413f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 16423f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor Id.setTemplateId(TemplateId); 16433f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return false; 16443f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor } 16453f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 16463f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // Bundle the template arguments together. 16473f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor ASTTemplateArgsPtr TemplateArgsPtr(Actions, TemplateArgs.data(), 16483f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor TemplateArgs.size()); 16493f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 16503f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // Constructor and destructor names. 1651f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TypeResult Type 1652059101f922de6eb765601459925f4c8914420b23Douglas Gregor = Actions.ActOnTemplateIdType(SS, Template, NameLoc, 16533f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor LAngleLoc, TemplateArgsPtr, 16543f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor RAngleLoc); 16553f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor if (Type.isInvalid()) 16563f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return true; 16573f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 16583f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor if (Id.getKind() == UnqualifiedId::IK_ConstructorName) 16593f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor Id.setConstructorName(Type.get(), NameLoc, RAngleLoc); 16603f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor else 16613f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor Id.setDestructorName(Id.StartLocation, Type.get(), RAngleLoc); 16623f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 16633f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return false; 16643f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor} 16653f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 1666ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// \brief Parse an operator-function-id or conversion-function-id as part 1667ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// of a C++ unqualified-id. 16683f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 1669ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// This routine is responsible only for parsing the operator-function-id or 1670ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// conversion-function-id; it does not handle template arguments in any way. 16713f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 1672ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// \code 16733f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// operator-function-id: [C++ 13.5] 16743f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 'operator' operator 16753f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 1676ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// operator: one of 16773f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// new delete new[] delete[] 16783f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// + - * / % ^ & | ~ 16793f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// ! = < > += -= *= /= %= 16803f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// ^= &= |= << >> >>= <<= == != 16813f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// <= >= && || ++ -- , ->* -> 16823f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// () [] 16833f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 16843f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// conversion-function-id: [C++ 12.3.2] 16853f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// operator conversion-type-id 16863f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 16873f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// conversion-type-id: 16883f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// type-specifier-seq conversion-declarator[opt] 16893f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 16903f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// conversion-declarator: 16913f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// ptr-operator conversion-declarator[opt] 16923f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \endcode 16933f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 16943f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \param The nested-name-specifier that preceded this unqualified-id. If 16953f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// non-empty, then we are parsing the unqualified-id of a qualified-id. 16963f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 16973f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \param EnteringContext whether we are entering the scope of the 16983f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// nested-name-specifier. 16993f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 1700ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// \param ObjectType if this unqualified-id occurs within a member access 1701ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// expression, the type of the base object whose member is being accessed. 1702ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// 1703ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// \param Result on a successful parse, contains the parsed unqualified-id. 1704ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// 1705ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// \returns true if parsing fails, false otherwise. 1706ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregorbool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, 1707b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType ObjectType, 1708ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor UnqualifiedId &Result) { 1709ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); 1710ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1711ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // Consume the 'operator' keyword. 1712ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor SourceLocation KeywordLoc = ConsumeToken(); 1713ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1714ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // Determine what kind of operator name we have. 1715ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor unsigned SymbolIdx = 0; 1716ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor SourceLocation SymbolLocations[3]; 1717ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor OverloadedOperatorKind Op = OO_None; 1718ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor switch (Tok.getKind()) { 1719ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor case tok::kw_new: 1720ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor case tok::kw_delete: { 1721ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor bool isNew = Tok.getKind() == tok::kw_new; 1722ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // Consume the 'new' or 'delete'. 1723ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor SymbolLocations[SymbolIdx++] = ConsumeToken(); 1724ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor if (Tok.is(tok::l_square)) { 17254a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor // Consume the '[' and ']'. 17264a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_square); 17274a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 17284a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 17294a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.getCloseLocation().isInvalid()) 1730ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor return true; 1731ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 17324a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SymbolLocations[SymbolIdx++] = T.getOpenLocation(); 17334a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SymbolLocations[SymbolIdx++] = T.getCloseLocation(); 1734ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor Op = isNew? OO_Array_New : OO_Array_Delete; 1735ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor } else { 1736ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor Op = isNew? OO_New : OO_Delete; 1737ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor } 1738ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor break; 1739ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor } 1740ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1741ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 1742ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor case tok::Token: \ 1743ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor SymbolLocations[SymbolIdx++] = ConsumeToken(); \ 1744ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor Op = OO_##Name; \ 1745ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor break; 1746ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) 1747ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor#include "clang/Basic/OperatorKinds.def" 1748ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1749ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor case tok::l_paren: { 17504a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor // Consume the '(' and ')'. 17514a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 17524a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 17534a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 17544a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.getCloseLocation().isInvalid()) 1755ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor return true; 1756ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 17574a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SymbolLocations[SymbolIdx++] = T.getOpenLocation(); 17584a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SymbolLocations[SymbolIdx++] = T.getCloseLocation(); 1759ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor Op = OO_Call; 1760ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor break; 1761ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor } 1762ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1763ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor case tok::l_square: { 17644a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor // Consume the '[' and ']'. 17654a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_square); 17664a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 17674a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 17684a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.getCloseLocation().isInvalid()) 1769ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor return true; 1770ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 17714a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SymbolLocations[SymbolIdx++] = T.getOpenLocation(); 17724a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SymbolLocations[SymbolIdx++] = T.getCloseLocation(); 1773ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor Op = OO_Subscript; 1774ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor break; 1775ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor } 1776ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1777ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor case tok::code_completion: { 1778ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // Code completion for the operator name. 177923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.CodeCompleteOperatorName(getCurScope()); 17807d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis cutOffParsing(); 1781ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // Don't try to parse any further. 1782ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor return true; 1783ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor } 1784ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1785ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor default: 1786ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor break; 1787ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor } 1788ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1789ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor if (Op != OO_None) { 1790ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // We have parsed an operator-function-id. 1791ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor Result.setOperatorFunctionId(KeywordLoc, Op, SymbolLocations); 1792ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor return false; 1793ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor } 17940486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt 17950486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt // Parse a literal-operator-id. 17960486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt // 17970486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt // literal-operator-id: [C++0x 13.5.8] 17980486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt // operator "" identifier 17990486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt 18000486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt if (getLang().CPlusPlus0x && Tok.is(tok::string_literal)) { 18017fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith Diag(Tok.getLocation(), diag::warn_cxx98_compat_literal_operator); 18020486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt if (Tok.getLength() != 2) 18030486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt Diag(Tok.getLocation(), diag::err_operator_string_not_empty); 18040486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt ConsumeStringToken(); 18050486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt 18060486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt if (Tok.isNot(tok::identifier)) { 18070486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt Diag(Tok.getLocation(), diag::err_expected_ident); 18080486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt return true; 18090486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt } 18100486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt 18110486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt IdentifierInfo *II = Tok.getIdentifierInfo(); 18120486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt Result.setLiteralOperatorId(II, KeywordLoc, ConsumeToken()); 18133e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt return false; 18140486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt } 1815ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1816ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // Parse a conversion-function-id. 1817ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // 1818ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // conversion-function-id: [C++ 12.3.2] 1819ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // operator conversion-type-id 1820ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // 1821ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // conversion-type-id: 1822ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // type-specifier-seq conversion-declarator[opt] 1823ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // 1824ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // conversion-declarator: 1825ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // ptr-operator conversion-declarator[opt] 1826ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1827ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // Parse the type-specifier-seq. 18280b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall DeclSpec DS(AttrFactory); 1829f6e6fc801c700c7b8ac202ddbe550d9843a816fcDouglas Gregor if (ParseCXXTypeSpecifierSeq(DS)) // FIXME: ObjectType? 1830ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor return true; 1831ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1832ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // Parse the conversion-declarator, which is merely a sequence of 1833ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // ptr-operators. 1834ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor Declarator D(DS, Declarator::TypeNameContext); 1835ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor ParseDeclaratorInternal(D, /*DirectDeclParser=*/0); 1836ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1837ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // Finish up the type. 1838f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TypeResult Ty = Actions.ActOnTypeName(getCurScope(), D); 1839ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor if (Ty.isInvalid()) 1840ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor return true; 1841ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1842ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // Note that this is a conversion-function-id. 1843ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor Result.setConversionFunctionId(KeywordLoc, Ty.get(), 1844ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor D.getSourceRange().getEnd()); 1845ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor return false; 1846ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor} 1847ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1848ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// \brief Parse a C++ unqualified-id (or a C identifier), which describes the 1849ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// name of an entity. 1850ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// 1851ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// \code 1852ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// unqualified-id: [C++ expr.prim.general] 1853ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// identifier 1854ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// operator-function-id 1855ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// conversion-function-id 1856ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// [C++0x] literal-operator-id [TODO] 1857ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// ~ class-name 1858ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// template-id 1859ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// 1860ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// \endcode 1861ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// 1862ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// \param The nested-name-specifier that preceded this unqualified-id. If 1863ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// non-empty, then we are parsing the unqualified-id of a qualified-id. 1864ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// 1865ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// \param EnteringContext whether we are entering the scope of the 1866ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// nested-name-specifier. 1867ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// 18683f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \param AllowDestructorName whether we allow parsing of a destructor name. 18693f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 18703f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \param AllowConstructorName whether we allow parsing a constructor name. 18713f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 187246df8cc349096f141c841dbffaa72641ff1dd94bDouglas Gregor/// \param ObjectType if this unqualified-id occurs within a member access 187346df8cc349096f141c841dbffaa72641ff1dd94bDouglas Gregor/// expression, the type of the base object whose member is being accessed. 187446df8cc349096f141c841dbffaa72641ff1dd94bDouglas Gregor/// 18753f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \param Result on a successful parse, contains the parsed unqualified-id. 18763f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 18773f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \returns true if parsing fails, false otherwise. 18783f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregorbool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, 18793f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor bool AllowDestructorName, 18803f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor bool AllowConstructorName, 1881b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType ObjectType, 18823f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor UnqualifiedId &Result) { 18830278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor 18840278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor // Handle 'A::template B'. This is for template-ids which have not 18850278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor // already been annotated by ParseOptionalCXXScopeSpecifier(). 18860278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor bool TemplateSpecified = false; 18870278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor SourceLocation TemplateKWLoc; 18880278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor if (getLang().CPlusPlus && Tok.is(tok::kw_template) && 18890278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor (ObjectType || SS.isSet())) { 18900278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor TemplateSpecified = true; 18910278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor TemplateKWLoc = ConsumeToken(); 18920278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor } 18930278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor 18943f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // unqualified-id: 18953f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // identifier 18963f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // template-id (when it hasn't already been annotated) 18973f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor if (Tok.is(tok::identifier)) { 18983f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // Consume the identifier. 18993f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor IdentifierInfo *Id = Tok.getIdentifierInfo(); 19003f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor SourceLocation IdLoc = ConsumeToken(); 19013f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 1902b862b8f93424a583fc912ab37bbbac1c231e852eDouglas Gregor if (!getLang().CPlusPlus) { 1903b862b8f93424a583fc912ab37bbbac1c231e852eDouglas Gregor // If we're not in C++, only identifiers matter. Record the 1904b862b8f93424a583fc912ab37bbbac1c231e852eDouglas Gregor // identifier and return. 1905b862b8f93424a583fc912ab37bbbac1c231e852eDouglas Gregor Result.setIdentifier(Id, IdLoc); 1906b862b8f93424a583fc912ab37bbbac1c231e852eDouglas Gregor return false; 1907b862b8f93424a583fc912ab37bbbac1c231e852eDouglas Gregor } 1908b862b8f93424a583fc912ab37bbbac1c231e852eDouglas Gregor 19093f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor if (AllowConstructorName && 191023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.isCurrentClassName(*Id, getCurScope(), &SS)) { 19113f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // We have parsed a constructor name. 191223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Result.setConstructorName(Actions.getTypeName(*Id, IdLoc, getCurScope(), 19139e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor &SS, false, false, 19149e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor ParsedType(), 19159e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor /*NonTrivialTypeSourceInfo=*/true), 19163f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor IdLoc, IdLoc); 19173f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor } else { 19183f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // We have parsed an identifier. 19193f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor Result.setIdentifier(Id, IdLoc); 19203f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor } 19213f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 19223f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // If the next token is a '<', we may have a template. 19230278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor if (TemplateSpecified || Tok.is(tok::less)) 19243f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return ParseUnqualifiedIdTemplateId(SS, Id, IdLoc, EnteringContext, 19250278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor ObjectType, Result, 19260278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor TemplateSpecified, TemplateKWLoc); 19273f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 19283f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return false; 19293f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor } 19303f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 19313f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // unqualified-id: 19323f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // template-id (already parsed and annotated) 19333f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor if (Tok.is(tok::annot_template_id)) { 193425a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 19350efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor 19360efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor // If the template-name names the current class, then this is a constructor 19370efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor if (AllowConstructorName && TemplateId->Name && 193823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) { 19390efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor if (SS.isSet()) { 19400efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor // C++ [class.qual]p2 specifies that a qualified template-name 19410efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor // is taken as the constructor name where a constructor can be 19420efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor // declared. Thus, the template arguments are extraneous, so 19430efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor // complain about them and remove them entirely. 19440efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor Diag(TemplateId->TemplateNameLoc, 19450efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor diag::err_out_of_line_constructor_template_id) 19460efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor << TemplateId->Name 1947849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor << FixItHint::CreateRemoval( 19480efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc)); 19490efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor Result.setConstructorName(Actions.getTypeName(*TemplateId->Name, 19500efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor TemplateId->TemplateNameLoc, 195123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor getCurScope(), 19529e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor &SS, false, false, 19539e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor ParsedType(), 19549e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor /*NontrivialTypeSourceInfo=*/true), 19550efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor TemplateId->TemplateNameLoc, 19560efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor TemplateId->RAngleLoc); 19570efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor ConsumeToken(); 19580efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor return false; 19590efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor } 19600efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor 19610efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor Result.setConstructorTemplateId(TemplateId); 19620efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor ConsumeToken(); 19630efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor return false; 19640efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor } 19650efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor 19663f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // We have already parsed a template-id; consume the annotation token as 19673f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // our unqualified-id. 19680efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor Result.setTemplateId(TemplateId); 19693f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor ConsumeToken(); 19703f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return false; 19713f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor } 19723f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 19733f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // unqualified-id: 19743f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // operator-function-id 19753f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // conversion-function-id 19763f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor if (Tok.is(tok::kw_operator)) { 1977ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, Result)) 19783f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return true; 19793f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 1980e6252d1587f98dbac704178e7b2ce53116048310Sean Hunt // If we have an operator-function-id or a literal-operator-id and the next 1981e6252d1587f98dbac704178e7b2ce53116048310Sean Hunt // token is a '<', we may have a 1982ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // 1983ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // template-id: 1984ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // operator-function-id < template-argument-list[opt] > 1985e6252d1587f98dbac704178e7b2ce53116048310Sean Hunt if ((Result.getKind() == UnqualifiedId::IK_OperatorFunctionId || 1986e6252d1587f98dbac704178e7b2ce53116048310Sean Hunt Result.getKind() == UnqualifiedId::IK_LiteralOperatorId) && 19870278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor (TemplateSpecified || Tok.is(tok::less))) 1988ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor return ParseUnqualifiedIdTemplateId(SS, 0, SourceLocation(), 1989ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor EnteringContext, ObjectType, 19900278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor Result, 19910278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor TemplateSpecified, TemplateKWLoc); 19923f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 19933f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return false; 19943f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor } 19953f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 1996b862b8f93424a583fc912ab37bbbac1c231e852eDouglas Gregor if (getLang().CPlusPlus && 1997b862b8f93424a583fc912ab37bbbac1c231e852eDouglas Gregor (AllowDestructorName || SS.isSet()) && Tok.is(tok::tilde)) { 19983f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // C++ [expr.unary.op]p10: 19993f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // There is an ambiguity in the unary-expression ~X(), where X is a 20003f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // class-name. The ambiguity is resolved in favor of treating ~ as a 20013f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // unary complement rather than treating ~X as referring to a destructor. 20023f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 20033f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // Parse the '~'. 20043f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor SourceLocation TildeLoc = ConsumeToken(); 200553a75c07dbe79b3dd5dd88a0378aefa18f793083David Blaikie 200653a75c07dbe79b3dd5dd88a0378aefa18f793083David Blaikie if (SS.isEmpty() && Tok.is(tok::kw_decltype)) { 200753a75c07dbe79b3dd5dd88a0378aefa18f793083David Blaikie DeclSpec DS(AttrFactory); 200853a75c07dbe79b3dd5dd88a0378aefa18f793083David Blaikie SourceLocation EndLoc = ParseDecltypeSpecifier(DS); 200953a75c07dbe79b3dd5dd88a0378aefa18f793083David Blaikie if (ParsedType Type = Actions.getDestructorType(DS, ObjectType)) { 201053a75c07dbe79b3dd5dd88a0378aefa18f793083David Blaikie Result.setDestructorName(TildeLoc, Type, EndLoc); 201153a75c07dbe79b3dd5dd88a0378aefa18f793083David Blaikie return false; 201253a75c07dbe79b3dd5dd88a0378aefa18f793083David Blaikie } 201353a75c07dbe79b3dd5dd88a0378aefa18f793083David Blaikie return true; 201453a75c07dbe79b3dd5dd88a0378aefa18f793083David Blaikie } 20153f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 20163f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // Parse the class-name. 20173f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor if (Tok.isNot(tok::identifier)) { 2018124b878dba5007df0a268ea128a6ad8dc5dd2c5eDouglas Gregor Diag(Tok, diag::err_destructor_tilde_identifier); 20193f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return true; 20203f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor } 20213f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 20223f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // Parse the class-name (or template-name in a simple-template-id). 20233f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor IdentifierInfo *ClassName = Tok.getIdentifierInfo(); 20243f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor SourceLocation ClassNameLoc = ConsumeToken(); 20253f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 20260278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor if (TemplateSpecified || Tok.is(tok::less)) { 2027b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall Result.setDestructorName(TildeLoc, ParsedType(), ClassNameLoc); 20282d1c21414199a7452f122598189363a3922605b1Douglas Gregor return ParseUnqualifiedIdTemplateId(SS, ClassName, ClassNameLoc, 20290278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor EnteringContext, ObjectType, Result, 20300278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor TemplateSpecified, TemplateKWLoc); 20312d1c21414199a7452f122598189363a3922605b1Douglas Gregor } 20322d1c21414199a7452f122598189363a3922605b1Douglas Gregor 20333f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // Note that this is a destructor name. 2034b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType Ty = Actions.getDestructorName(TildeLoc, *ClassName, 2035b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ClassNameLoc, getCurScope(), 2036b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall SS, ObjectType, 2037b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall EnteringContext); 2038124b878dba5007df0a268ea128a6ad8dc5dd2c5eDouglas Gregor if (!Ty) 20393f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return true; 2040124b878dba5007df0a268ea128a6ad8dc5dd2c5eDouglas Gregor 20413f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor Result.setDestructorName(TildeLoc, Ty, ClassNameLoc); 20423f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return false; 20433f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor } 20443f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 20452d1c21414199a7452f122598189363a3922605b1Douglas Gregor Diag(Tok, diag::err_expected_unqualified_id) 20462d1c21414199a7452f122598189363a3922605b1Douglas Gregor << getLang().CPlusPlus; 20473f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return true; 20483f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor} 20493f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 20504c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate 20514c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// memory in a typesafe manner and call constructors. 20521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// 205359232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// This method is called to parse the new expression after the optional :: has 205459232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// been already parsed. If the :: was present, "UseGlobal" is true and "Start" 205559232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// is its location. Otherwise, "Start" is the location of the 'new' token. 20564c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 20574c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-expression: 20584c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'new' new-placement[opt] new-type-id 20594c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer[opt] 20604c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 20614c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer[opt] 20624c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 20634c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-placement: 20644c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '(' expression-list ')' 20654c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 2066cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// new-type-id: 2067cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// type-specifier-seq new-declarator[opt] 2068893e1cc13ab17e96ada5019df6978af1668fee26Douglas Gregor/// [GNU] attributes type-specifier-seq new-declarator[opt] 2069cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// 2070cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// new-declarator: 2071cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// ptr-operator new-declarator[opt] 2072cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// direct-new-declarator 2073cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// 20744c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer: 20754c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '(' expression-list[opt] ')' 2076dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl/// [C++0x] braced-init-list 20774c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 207860d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult 207959232d35f5820e334b6c8b007ae8006f4390055dChris LattnerParser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { 208059232d35f5820e334b6c8b007ae8006f4390055dChris Lattner assert(Tok.is(tok::kw_new) && "expected 'new' token"); 208159232d35f5820e334b6c8b007ae8006f4390055dChris Lattner ConsumeToken(); // Consume 'new' 20824c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 20834c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // A '(' now can be a new-placement or the '(' wrapping the type-id in the 20844c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // second form of new-expression. It can't be a new-type-id. 20854c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 2086a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector PlacementArgs(Actions); 20874c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation PlacementLParen, PlacementRParen; 20884c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 20894bd40318cbea15310a37343db46de96c4fcc15e6Douglas Gregor SourceRange TypeIdParens; 20900b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall DeclSpec DS(AttrFactory); 20910b8c98f3ddf83adcb9e9d98b68ce38e970cdee73Argyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::CXXNewContext); 20924c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_paren)) { 20934c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // If it turns out to be a placement, we change the type location. 20944a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 20954a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 20964a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor PlacementLParen = T.getOpenLocation(); 2097cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) { 2098cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 209920df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 2100cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 21014c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 21024a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 21034a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor PlacementRParen = T.getCloseLocation(); 2104cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (PlacementRParen.isInvalid()) { 2105cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 210620df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 2107cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 21084c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 2109cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (PlacementArgs.empty()) { 21104c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Reset the placement locations. There was no placement. 21114a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor TypeIdParens = T.getRange(); 21124c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl PlacementLParen = PlacementRParen = SourceLocation(); 21134c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } else { 21144c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // We still need the type. 21154c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_paren)) { 21164a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 21174a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 2118893e1cc13ab17e96ada5019df6978af1668fee26Douglas Gregor MaybeParseGNUAttributes(DeclaratorInfo); 2119cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseSpecifierQualifierList(DS); 2120ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 2121cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclarator(DeclaratorInfo); 21224a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 21234a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor TypeIdParens = T.getRange(); 21244c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } else { 2125893e1cc13ab17e96ada5019df6978af1668fee26Douglas Gregor MaybeParseGNUAttributes(DeclaratorInfo); 2126cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseCXXTypeSpecifierSeq(DS)) 2127cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl DeclaratorInfo.setInvalidType(true); 2128ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl else { 2129ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 2130cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclaratorInternal(DeclaratorInfo, 2131cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl &Parser::ParseDirectNewDeclarator); 2132ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl } 21334c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 21344c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 21354c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } else { 2136cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl // A new-type-id is a simplified type-id, where essentially the 2137cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl // direct-declarator is replaced by a direct-new-declarator. 2138893e1cc13ab17e96ada5019df6978af1668fee26Douglas Gregor MaybeParseGNUAttributes(DeclaratorInfo); 2139cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseCXXTypeSpecifierSeq(DS)) 2140cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl DeclaratorInfo.setInvalidType(true); 2141ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl else { 2142ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 2143cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclaratorInternal(DeclaratorInfo, 2144cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl &Parser::ParseDirectNewDeclarator); 2145ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl } 21464c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 2147eaaebc7cf10dc1a2016183a262ad3256bc468759Chris Lattner if (DeclaratorInfo.isInvalidType()) { 2148cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 214920df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 2150cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 21514c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 2152a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector ConstructorArgs(Actions); 21534c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation ConstructorLParen, ConstructorRParen; 21544c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 21554c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_paren)) { 21564a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 21574a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 21584a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor ConstructorLParen = T.getOpenLocation(); 21594c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.isNot(tok::r_paren)) { 21604c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl CommaLocsTy CommaLocs; 2161cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseExpressionList(ConstructorArgs, CommaLocs)) { 2162cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 216320df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 2164cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 21654c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 21664a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 21674a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor ConstructorRParen = T.getCloseLocation(); 2168cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ConstructorRParen.isInvalid()) { 2169cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 217020df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 2171cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 217229e3a31b7cbd9f9cdf2cc857a3a805871b6f3f62Richard Smith } else if (Tok.is(tok::l_brace) && getLang().CPlusPlus0x) { 21737fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith Diag(Tok.getLocation(), 21747fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::warn_cxx98_compat_generalized_initializer_lists); 2175dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl // FIXME: Have to communicate the init-list to ActOnCXXNew. 2176dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl ParseBraceInitializer(); 21774c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 21784c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 2179f53597fb16142bdb4a66901f8c0b768db4f2a548Sebastian Redl return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen, 2180f53597fb16142bdb4a66901f8c0b768db4f2a548Sebastian Redl move_arg(PlacementArgs), PlacementRParen, 21814bd40318cbea15310a37343db46de96c4fcc15e6Douglas Gregor TypeIdParens, DeclaratorInfo, ConstructorLParen, 2182f53597fb16142bdb4a66901f8c0b768db4f2a548Sebastian Redl move_arg(ConstructorArgs), ConstructorRParen); 21834c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 21844c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 21854c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be 21864c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// passed to ParseDeclaratorInternal. 21874c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 21884c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// direct-new-declarator: 21894c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '[' expression ']' 21904c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// direct-new-declarator '[' constant-expression ']' 21914c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 219259232d35f5820e334b6c8b007ae8006f4390055dChris Lattnervoid Parser::ParseDirectNewDeclarator(Declarator &D) { 21934c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Parse the array dimensions. 21944c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool first = true; 21954c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl while (Tok.is(tok::l_square)) { 21964a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_square); 21974a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 21984a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor 219960d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult Size(first ? ParseExpression() 22002f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl : ParseConstantExpression()); 22010e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Size.isInvalid()) { 22024c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Recover 22034c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SkipUntil(tok::r_square); 22044c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return; 22054c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 22064c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl first = false; 22074c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 22084a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 22090b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall 22100b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall ParsedAttributes attrs(AttrFactory); 22110b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall D.AddTypeInfo(DeclaratorChunk::getArray(0, 22127f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall /*static=*/false, /*star=*/false, 22134a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Size.release(), 22144a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getOpenLocation(), 22154a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()), 22164a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor attrs, T.getCloseLocation()); 22174c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 22184a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.getCloseLocation().isInvalid()) 22194c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return; 22204c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 22214c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 22224c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 22234c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id. 22244c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// This ambiguity appears in the syntax of the C++ new operator. 22254c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 22264c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-expression: 22274c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 22284c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer[opt] 22294c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 22304c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-placement: 22314c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '(' expression-list ')' 22324c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 2233ca0408fb49c1370430672acf2d770b7151cf71deJohn McCallbool Parser::ParseExpressionListOrTypeId( 22345f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<Expr*> &PlacementArgs, 223559232d35f5820e334b6c8b007ae8006f4390055dChris Lattner Declarator &D) { 22364c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // The '(' was already consumed. 22374c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (isTypeIdInParens()) { 2238cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseSpecifierQualifierList(D.getMutableDeclSpec()); 2239ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl D.SetSourceRange(D.getDeclSpec().getSourceRange()); 2240cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclarator(D); 2241eaaebc7cf10dc1a2016183a262ad3256bc468759Chris Lattner return D.isInvalidType(); 22424c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 22434c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 22444c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // It's not a type, it has to be an expression list. 22454c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Discard the comma locations - ActOnCXXNew has enough parameters. 22464c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl CommaLocsTy CommaLocs; 22474c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return ParseExpressionList(PlacementArgs, CommaLocs); 22484c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 22494c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 22504c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used 22514c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// to free memory allocated by new. 22524c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 225359232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// This method is called to parse the 'delete' expression after the optional 225459232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// '::' has been already parsed. If the '::' was present, "UseGlobal" is true 225559232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// and "Start" is its location. Otherwise, "Start" is the location of the 225659232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// 'delete' token. 225759232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// 22584c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// delete-expression: 22594c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'delete' cast-expression 22604c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'delete' '[' ']' cast-expression 226160d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult 226259232d35f5820e334b6c8b007ae8006f4390055dChris LattnerParser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) { 226359232d35f5820e334b6c8b007ae8006f4390055dChris Lattner assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword"); 226459232d35f5820e334b6c8b007ae8006f4390055dChris Lattner ConsumeToken(); // Consume 'delete' 22654c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 22664c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Array delete? 22674c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool ArrayDelete = false; 22684c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_square)) { 22694c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ArrayDelete = true; 22704a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_square); 22714a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor 22724a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 22734a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 22744a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.getCloseLocation().isInvalid()) 227520df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 22764c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 22774c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 227860d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult Operand(ParseCastExpression(false)); 22790e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Operand.isInvalid()) 228020df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return move(Operand); 22814c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 22829ae2f076ca5ab1feb3ba95629099ec2319833701John McCall return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, Operand.take()); 22834c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 228464b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl 22851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind) { 228664b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl switch(kind) { 2287b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable("Not a known unary type trait."); 228864b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___has_nothrow_assign: return UTT_HasNothrowAssign; 228964b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___has_nothrow_constructor: return UTT_HasNothrowConstructor; 229020c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___has_nothrow_copy: return UTT_HasNothrowCopy; 229164b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___has_trivial_assign: return UTT_HasTrivialAssign; 2292023df37c27ee8035664fb62f206ca58f4e2a169dSean Hunt case tok::kw___has_trivial_constructor: 2293023df37c27ee8035664fb62f206ca58f4e2a169dSean Hunt return UTT_HasTrivialDefaultConstructor; 229420c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___has_trivial_copy: return UTT_HasTrivialCopy; 229564b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___has_trivial_destructor: return UTT_HasTrivialDestructor; 229664b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___has_virtual_destructor: return UTT_HasVirtualDestructor; 229764b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___is_abstract: return UTT_IsAbstract; 229820c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_arithmetic: return UTT_IsArithmetic; 229920c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_array: return UTT_IsArray; 230064b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___is_class: return UTT_IsClass; 230120c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_complete_type: return UTT_IsCompleteType; 230220c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_compound: return UTT_IsCompound; 230320c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_const: return UTT_IsConst; 230464b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___is_empty: return UTT_IsEmpty; 230564b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___is_enum: return UTT_IsEnum; 23065e9392ba18f5925e26cc5714d1412eda0d219826Douglas Gregor case tok::kw___is_final: return UTT_IsFinal; 230720c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_floating_point: return UTT_IsFloatingPoint; 230820c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_function: return UTT_IsFunction; 230920c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_fundamental: return UTT_IsFundamental; 231020c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_integral: return UTT_IsIntegral; 231120c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_lvalue_reference: return UTT_IsLvalueReference; 231220c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_member_function_pointer: return UTT_IsMemberFunctionPointer; 231320c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_member_object_pointer: return UTT_IsMemberObjectPointer; 231420c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_member_pointer: return UTT_IsMemberPointer; 231520c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_object: return UTT_IsObject; 23164e61ddd644e9c6293697a966d98d7c1905cf63a8Chandler Carruth case tok::kw___is_literal: return UTT_IsLiteral; 23173840281126e7d10552c55f6fd8b1ec9483898906Chandler Carruth case tok::kw___is_literal_type: return UTT_IsLiteral; 231864b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___is_pod: return UTT_IsPOD; 231920c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_pointer: return UTT_IsPointer; 232064b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___is_polymorphic: return UTT_IsPolymorphic; 232120c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_reference: return UTT_IsReference; 232220c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_rvalue_reference: return UTT_IsRvalueReference; 232320c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_scalar: return UTT_IsScalar; 232420c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_signed: return UTT_IsSigned; 232520c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_standard_layout: return UTT_IsStandardLayout; 232620c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_trivial: return UTT_IsTrivial; 2327feb375d31b7e9108b04a9f55b721d5e0c793a558Sean Hunt case tok::kw___is_trivially_copyable: return UTT_IsTriviallyCopyable; 232864b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___is_union: return UTT_IsUnion; 232920c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_unsigned: return UTT_IsUnsigned; 233020c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_void: return UTT_IsVoid; 233120c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_volatile: return UTT_IsVolatile; 233264b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl } 23336ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet} 23346ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet 23356ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichetstatic BinaryTypeTrait BinaryTypeTraitFromTokKind(tok::TokenKind kind) { 23366ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet switch(kind) { 233738c2b730a8553fa1cf369d0c5567f8b5d0a3dda8Francois Pichet default: llvm_unreachable("Not a known binary type trait"); 2338f187237d916afa97c491ac32fe98be7d335c5b63Francois Pichet case tok::kw___is_base_of: return BTT_IsBaseOf; 233920c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_convertible: return BTT_IsConvertible; 234020c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_same: return BTT_IsSame; 2341f187237d916afa97c491ac32fe98be7d335c5b63Francois Pichet case tok::kw___builtin_types_compatible_p: return BTT_TypeCompatible; 23429f3611365d0f2297a910cf246e056708726ed10aDouglas Gregor case tok::kw___is_convertible_to: return BTT_IsConvertibleTo; 23436ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet } 234464b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl} 234564b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl 234621ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegleystatic ArrayTypeTrait ArrayTypeTraitFromTokKind(tok::TokenKind kind) { 234721ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley switch(kind) { 234821ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley default: llvm_unreachable("Not a known binary type trait"); 234921ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley case tok::kw___array_rank: return ATT_ArrayRank; 235021ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley case tok::kw___array_extent: return ATT_ArrayExtent; 235121ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley } 235221ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley} 235321ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley 2354552622067dc45013d240f73952fece703f5e63bdJohn Wiegleystatic ExpressionTrait ExpressionTraitFromTokKind(tok::TokenKind kind) { 2355552622067dc45013d240f73952fece703f5e63bdJohn Wiegley switch(kind) { 2356b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable("Not a known unary expression trait."); 2357552622067dc45013d240f73952fece703f5e63bdJohn Wiegley case tok::kw___is_lvalue_expr: return ET_IsLValueExpr; 2358552622067dc45013d240f73952fece703f5e63bdJohn Wiegley case tok::kw___is_rvalue_expr: return ET_IsRValueExpr; 2359552622067dc45013d240f73952fece703f5e63bdJohn Wiegley } 2360552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 2361552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 236264b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl/// ParseUnaryTypeTrait - Parse the built-in unary type-trait 236364b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl/// pseudo-functions that allow implementation of the TR1/C++0x type traits 236464b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl/// templates. 236564b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl/// 236664b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl/// primary-expression: 236764b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl/// [GNU] unary-type-trait '(' type-id ')' 236864b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl/// 236960d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Parser::ParseUnaryTypeTrait() { 237064b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl UnaryTypeTrait UTT = UnaryTypeTraitFromTokKind(Tok.getKind()); 237164b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl SourceLocation Loc = ConsumeToken(); 237264b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl 23734a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 23744a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.expectAndConsume(diag::err_expected_lparen)) 237564b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl return ExprError(); 237664b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl 237764b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl // FIXME: Error reporting absolutely sucks! If the this fails to parse a type 237864b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl // there will be cryptic errors about mismatched parentheses and missing 237964b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl // specifiers. 2380809070a886684cb5b92eb0e00a6581ab1fa6b17aDouglas Gregor TypeResult Ty = ParseTypeName(); 238164b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl 23824a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 238364b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl 2384809070a886684cb5b92eb0e00a6581ab1fa6b17aDouglas Gregor if (Ty.isInvalid()) 2385809070a886684cb5b92eb0e00a6581ab1fa6b17aDouglas Gregor return ExprError(); 2386809070a886684cb5b92eb0e00a6581ab1fa6b17aDouglas Gregor 23874a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor return Actions.ActOnUnaryTypeTrait(UTT, Loc, Ty.get(), T.getCloseLocation()); 238864b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl} 2389f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis 23906ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet/// ParseBinaryTypeTrait - Parse the built-in binary type-trait 23916ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet/// pseudo-functions that allow implementation of the TR1/C++0x type traits 23926ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet/// templates. 23936ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet/// 23946ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet/// primary-expression: 23956ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet/// [GNU] binary-type-trait '(' type-id ',' type-id ')' 23966ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet/// 23976ad6f2848d7652ab2991286eb48be440d3493b28Francois PichetExprResult Parser::ParseBinaryTypeTrait() { 23986ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet BinaryTypeTrait BTT = BinaryTypeTraitFromTokKind(Tok.getKind()); 23996ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet SourceLocation Loc = ConsumeToken(); 24006ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet 24014a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 24024a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.expectAndConsume(diag::err_expected_lparen)) 24036ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet return ExprError(); 24046ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet 24056ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet TypeResult LhsTy = ParseTypeName(); 24066ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet if (LhsTy.isInvalid()) { 24076ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet SkipUntil(tok::r_paren); 24086ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet return ExprError(); 24096ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet } 24106ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet 24116ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet if (ExpectAndConsume(tok::comma, diag::err_expected_comma)) { 24126ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet SkipUntil(tok::r_paren); 24136ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet return ExprError(); 24146ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet } 24156ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet 24166ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet TypeResult RhsTy = ParseTypeName(); 24176ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet if (RhsTy.isInvalid()) { 24186ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet SkipUntil(tok::r_paren); 24196ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet return ExprError(); 24206ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet } 24216ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet 24224a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 24236ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet 24244a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor return Actions.ActOnBinaryTypeTrait(BTT, Loc, LhsTy.get(), RhsTy.get(), 24254a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()); 24266ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet} 24276ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet 242821ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley/// ParseArrayTypeTrait - Parse the built-in array type-trait 242921ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley/// pseudo-functions. 243021ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley/// 243121ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley/// primary-expression: 243221ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley/// [Embarcadero] '__array_rank' '(' type-id ')' 243321ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley/// [Embarcadero] '__array_extent' '(' type-id ',' expression ')' 243421ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley/// 243521ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John WiegleyExprResult Parser::ParseArrayTypeTrait() { 243621ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley ArrayTypeTrait ATT = ArrayTypeTraitFromTokKind(Tok.getKind()); 243721ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley SourceLocation Loc = ConsumeToken(); 243821ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley 24394a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 24404a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.expectAndConsume(diag::err_expected_lparen)) 244121ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley return ExprError(); 244221ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley 244321ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley TypeResult Ty = ParseTypeName(); 244421ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley if (Ty.isInvalid()) { 244521ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley SkipUntil(tok::comma); 244621ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley SkipUntil(tok::r_paren); 244721ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley return ExprError(); 244821ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley } 244921ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley 245021ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley switch (ATT) { 245121ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley case ATT_ArrayRank: { 24524a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 24534a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), NULL, 24544a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()); 245521ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley } 245621ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley case ATT_ArrayExtent: { 245721ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley if (ExpectAndConsume(tok::comma, diag::err_expected_comma)) { 245821ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley SkipUntil(tok::r_paren); 245921ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley return ExprError(); 246021ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley } 246121ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley 246221ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley ExprResult DimExpr = ParseExpression(); 24634a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 246421ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley 24654a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), DimExpr.get(), 24664a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()); 246721ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley } 246821ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley default: 246921ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley break; 247021ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley } 247121ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley return ExprError(); 247221ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley} 247321ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley 2474552622067dc45013d240f73952fece703f5e63bdJohn Wiegley/// ParseExpressionTrait - Parse built-in expression-trait 2475552622067dc45013d240f73952fece703f5e63bdJohn Wiegley/// pseudo-functions like __is_lvalue_expr( xxx ). 2476552622067dc45013d240f73952fece703f5e63bdJohn Wiegley/// 2477552622067dc45013d240f73952fece703f5e63bdJohn Wiegley/// primary-expression: 2478552622067dc45013d240f73952fece703f5e63bdJohn Wiegley/// [Embarcadero] expression-trait '(' expression ')' 2479552622067dc45013d240f73952fece703f5e63bdJohn Wiegley/// 2480552622067dc45013d240f73952fece703f5e63bdJohn WiegleyExprResult Parser::ParseExpressionTrait() { 2481552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ExpressionTrait ET = ExpressionTraitFromTokKind(Tok.getKind()); 2482552622067dc45013d240f73952fece703f5e63bdJohn Wiegley SourceLocation Loc = ConsumeToken(); 2483552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 24844a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 24854a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.expectAndConsume(diag::err_expected_lparen)) 2486552622067dc45013d240f73952fece703f5e63bdJohn Wiegley return ExprError(); 2487552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 2488552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ExprResult Expr = ParseExpression(); 2489552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 24904a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 2491552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 24924a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor return Actions.ActOnExpressionTrait(ET, Loc, Expr.get(), 24934a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()); 2494552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 2495552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 2496552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 2497f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis/// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a 2498f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis/// parenthesized ambiguous type-id. This uses tentative parsing to disambiguate 2499f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis/// based on the context past the parens. 250060d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult 2501f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios KyrtzidisParser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, 2502b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType &CastTy, 25034a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker &Tracker) { 2504f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis assert(getLang().CPlusPlus && "Should only be called for C++!"); 2505f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis assert(ExprType == CastExpr && "Compound literals are not ambiguous!"); 2506f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis assert(isTypeIdInParens() && "Not a type-id!"); 2507f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis 250860d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult Result(true); 2509b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall CastTy = ParsedType(); 2510f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis 2511f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // We need to disambiguate a very ugly part of the C++ syntax: 2512f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // 2513f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // (T())x; - type-id 2514f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // (T())*x; - type-id 2515f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // (T())/x; - expression 2516f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // (T()); - expression 2517f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // 2518f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // The bad news is that we cannot use the specialized tentative parser, since 2519f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // it can only verify that the thing inside the parens can be parsed as 2520f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // type-id, it is not useful for determining the context past the parens. 2521f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // 2522f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // The good news is that the parser can disambiguate this part without 2523a558a897cbe83a21914058348ffbdcf827530ad4Argyrios Kyrtzidis // making any unnecessary Action calls. 2524f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // 2525f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // It uses a scheme similar to parsing inline methods. The parenthesized 2526f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // tokens are cached, the context that follows is determined (possibly by 2527f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // parsing a cast-expression), and then we re-introduce the cached tokens 2528f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // into the token stream and parse them appropriately. 2529f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis 25301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ParenParseOption ParseAs; 2531f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis CachedTokens Toks; 2532f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis 2533f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // Store the tokens of the parentheses. We will parse them after we determine 2534f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // the context that follows them. 253514b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis if (!ConsumeAndStoreUntil(tok::r_paren, Toks)) { 2536f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // We didn't find the ')' we expected. 25374a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Tracker.consumeClose(); 2538f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis return ExprError(); 2539f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis } 2540f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis 2541f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis if (Tok.is(tok::l_brace)) { 2542f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis ParseAs = CompoundLiteral; 2543f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis } else { 2544f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis bool NotCastExpr; 2545b53f08ac87f1e1f4bc2fbfa4560c2183a82020eeEli Friedman // FIXME: Special-case ++ and --: "(S())++;" is not a cast-expression 2546b53f08ac87f1e1f4bc2fbfa4560c2183a82020eeEli Friedman if (Tok.is(tok::l_paren) && NextToken().is(tok::r_paren)) { 2547b53f08ac87f1e1f4bc2fbfa4560c2183a82020eeEli Friedman NotCastExpr = true; 2548b53f08ac87f1e1f4bc2fbfa4560c2183a82020eeEli Friedman } else { 2549b53f08ac87f1e1f4bc2fbfa4560c2183a82020eeEli Friedman // Try parsing the cast-expression that may follow. 2550b53f08ac87f1e1f4bc2fbfa4560c2183a82020eeEli Friedman // If it is not a cast-expression, NotCastExpr will be true and no token 2551b53f08ac87f1e1f4bc2fbfa4560c2183a82020eeEli Friedman // will be consumed. 2552b53f08ac87f1e1f4bc2fbfa4560c2183a82020eeEli Friedman Result = ParseCastExpression(false/*isUnaryExpression*/, 2553b53f08ac87f1e1f4bc2fbfa4560c2183a82020eeEli Friedman false/*isAddressofOperand*/, 2554b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall NotCastExpr, 25550a85183be6930571f3af8e5a976d24c3f95e5b25Argyrios Kyrtzidis // type-id has priority. 25560a85183be6930571f3af8e5a976d24c3f95e5b25Argyrios Kyrtzidis true/*isTypeCast*/); 2557b53f08ac87f1e1f4bc2fbfa4560c2183a82020eeEli Friedman } 2558f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis 2559f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // If we parsed a cast-expression, it's really a type-id, otherwise it's 2560f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // an expression. 2561f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis ParseAs = NotCastExpr ? SimpleExpr : CastExpr; 2562f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis } 2563f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis 25641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // The current token should go after the cached tokens. 2565f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis Toks.push_back(Tok); 2566f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // Re-enter the stored parenthesized tokens into the token stream, so we may 2567f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // parse them now. 2568f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis PP.EnterTokenStream(Toks.data(), Toks.size(), 2569f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis true/*DisableMacroExpansion*/, false/*OwnsTokens*/); 2570f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // Drop the current token and bring the first cached one. It's the same token 2571f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // as when we entered this function. 2572f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis ConsumeAnyToken(); 2573f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis 2574f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis if (ParseAs >= CompoundLiteral) { 25750a85183be6930571f3af8e5a976d24c3f95e5b25Argyrios Kyrtzidis // Parse the type declarator. 25760a85183be6930571f3af8e5a976d24c3f95e5b25Argyrios Kyrtzidis DeclSpec DS(AttrFactory); 25770a85183be6930571f3af8e5a976d24c3f95e5b25Argyrios Kyrtzidis ParseSpecifierQualifierList(DS); 25780a85183be6930571f3af8e5a976d24c3f95e5b25Argyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 25790a85183be6930571f3af8e5a976d24c3f95e5b25Argyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 2580f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis 2581f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // Match the ')'. 25824a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Tracker.consumeClose(); 2583f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis 2584f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis if (ParseAs == CompoundLiteral) { 2585f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis ExprType = CompoundLiteral; 25860a85183be6930571f3af8e5a976d24c3f95e5b25Argyrios Kyrtzidis TypeResult Ty = ParseTypeName(); 25874a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor return ParseCompoundLiteralExpression(Ty.get(), 25884a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Tracker.getOpenLocation(), 25894a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Tracker.getCloseLocation()); 2590f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis } 25911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2592f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // We parsed '(' type-id ')' and the thing after it wasn't a '{'. 2593f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis assert(ParseAs == CastExpr); 2594f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis 25950a85183be6930571f3af8e5a976d24c3f95e5b25Argyrios Kyrtzidis if (DeclaratorInfo.isInvalidType()) 2596f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis return ExprError(); 2597f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis 2598f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // Result is what ParseCastExpression returned earlier. 2599f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis if (!Result.isInvalid()) 26004a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Result = Actions.ActOnCastExpr(getCurScope(), Tracker.getOpenLocation(), 26014a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor DeclaratorInfo, CastTy, 26024a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Tracker.getCloseLocation(), Result.take()); 2603f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis return move(Result); 2604f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis } 26051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2606f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // Not a compound literal, and not followed by a cast-expression. 2607f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis assert(ParseAs == SimpleExpr); 2608f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis 2609f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis ExprType = SimpleExpr; 2610f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis Result = ParseExpression(); 2611f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis if (!Result.isInvalid() && Tok.is(tok::r_paren)) 26124a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Result = Actions.ActOnParenExpr(Tracker.getOpenLocation(), 26134a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Tok.getLocation(), Result.take()); 2614f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis 2615f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // Match the ')'. 2616f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis if (Result.isInvalid()) { 2617f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis SkipUntil(tok::r_paren); 2618f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis return ExprError(); 2619f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis } 26201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 26214a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Tracker.consumeClose(); 2622f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis return move(Result); 2623f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis} 2624