ParseExprCXX.cpp revision 5e9392ba18f5925e26cc5714d1412eda0d219826
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" 1719510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h" 18ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor#include "clang/Sema/Scope.h" 1919510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/ParsedTemplate.h" 203f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor#include "llvm/Support/ErrorHandling.h" 213f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang; 235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 24ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smithstatic int SelectDigraphErrorMessage(tok::TokenKind Kind) { 25ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith switch (Kind) { 26ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith case tok::kw_template: return 0; 27ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith case tok::kw_const_cast: return 1; 28ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith case tok::kw_dynamic_cast: return 2; 29ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith case tok::kw_reinterpret_cast: return 3; 30ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith case tok::kw_static_cast: return 4; 31ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith default: 32b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Unknown type for digraph error message."); 33ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith } 34ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith} 35ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith 36ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith// Are the two tokens adjacent in the same source file? 37ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smithstatic bool AreTokensAdjacent(Preprocessor &PP, Token &First, Token &Second) { 38ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith SourceManager &SM = PP.getSourceManager(); 39ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith SourceLocation FirstLoc = SM.getSpellingLoc(First.getLocation()); 40a64ccefdf0ea4e03ec88805d71b0af74950c7472Argyrios Kyrtzidis SourceLocation FirstEnd = FirstLoc.getLocWithOffset(First.getLength()); 41ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith return FirstEnd == SM.getSpellingLoc(Second.getLocation()); 42ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith} 43ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith 44ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith// Suggest fixit for "<::" after a cast. 45ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smithstatic void FixDigraph(Parser &P, Preprocessor &PP, Token &DigraphToken, 46ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith Token &ColonToken, tok::TokenKind Kind, bool AtDigraph) { 47ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith // Pull '<:' and ':' off token stream. 48ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith if (!AtDigraph) 49ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith PP.Lex(DigraphToken); 50ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith PP.Lex(ColonToken); 51ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith 52ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith SourceRange Range; 53ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith Range.setBegin(DigraphToken.getLocation()); 54ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith Range.setEnd(ColonToken.getLocation()); 55ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith P.Diag(DigraphToken.getLocation(), diag::err_missing_whitespace_digraph) 56ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith << SelectDigraphErrorMessage(Kind) 57ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith << FixItHint::CreateReplacement(Range, "< ::"); 58ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith 59ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith // Update token information to reflect their change in token type. 60ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith ColonToken.setKind(tok::coloncolon); 61a64ccefdf0ea4e03ec88805d71b0af74950c7472Argyrios Kyrtzidis ColonToken.setLocation(ColonToken.getLocation().getLocWithOffset(-1)); 62ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith ColonToken.setLength(2); 63ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith DigraphToken.setKind(tok::less); 64ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith DigraphToken.setLength(1); 65ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith 66ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith // Push new tokens back to token stream. 67ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith PP.EnterToken(ColonToken); 68ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith if (!AtDigraph) 69ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith PP.EnterToken(DigraphToken); 70ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith} 71ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith 72950be71c745409e373ae8a834490f9026c8ac222Richard Trieu// Check for '<::' which should be '< ::' instead of '[:' when following 73950be71c745409e373ae8a834490f9026c8ac222Richard Trieu// a template name. 74950be71c745409e373ae8a834490f9026c8ac222Richard Trieuvoid Parser::CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectType, 75950be71c745409e373ae8a834490f9026c8ac222Richard Trieu bool EnteringContext, 76950be71c745409e373ae8a834490f9026c8ac222Richard Trieu IdentifierInfo &II, CXXScopeSpec &SS) { 77c11030ea936f6952deb5a1423ce1648173cd417eRichard Trieu if (!Next.is(tok::l_square) || Next.getLength() != 2) 78950be71c745409e373ae8a834490f9026c8ac222Richard Trieu return; 79950be71c745409e373ae8a834490f9026c8ac222Richard Trieu 80950be71c745409e373ae8a834490f9026c8ac222Richard Trieu Token SecondToken = GetLookAheadToken(2); 81950be71c745409e373ae8a834490f9026c8ac222Richard Trieu if (!SecondToken.is(tok::colon) || !AreTokensAdjacent(PP, Next, SecondToken)) 82950be71c745409e373ae8a834490f9026c8ac222Richard Trieu return; 83950be71c745409e373ae8a834490f9026c8ac222Richard Trieu 84950be71c745409e373ae8a834490f9026c8ac222Richard Trieu TemplateTy Template; 85950be71c745409e373ae8a834490f9026c8ac222Richard Trieu UnqualifiedId TemplateName; 86950be71c745409e373ae8a834490f9026c8ac222Richard Trieu TemplateName.setIdentifier(&II, Tok.getLocation()); 87950be71c745409e373ae8a834490f9026c8ac222Richard Trieu bool MemberOfUnknownSpecialization; 88950be71c745409e373ae8a834490f9026c8ac222Richard Trieu if (!Actions.isTemplateName(getCurScope(), SS, /*hasTemplateKeyword=*/false, 89950be71c745409e373ae8a834490f9026c8ac222Richard Trieu TemplateName, ObjectType, EnteringContext, 90950be71c745409e373ae8a834490f9026c8ac222Richard Trieu Template, MemberOfUnknownSpecialization)) 91950be71c745409e373ae8a834490f9026c8ac222Richard Trieu return; 92950be71c745409e373ae8a834490f9026c8ac222Richard Trieu 93950be71c745409e373ae8a834490f9026c8ac222Richard Trieu FixDigraph(*this, PP, Next, SecondToken, tok::kw_template, 94950be71c745409e373ae8a834490f9026c8ac222Richard Trieu /*AtDigraph*/false); 95950be71c745409e373ae8a834490f9026c8ac222Richard Trieu} 96950be71c745409e373ae8a834490f9026c8ac222Richard Trieu 971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// \brief Parse global scope or nested-name-specifier if present. 982dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// 992dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// Parses a C++ global scope specifier ('::') or nested-name-specifier (which 1001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// may be preceded by '::'). Note that this routine will not parse ::new or 1012dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// ::delete; it will just leave them in the token stream. 102eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 103eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier 104eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' 105eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 106eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier: 107eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// type-name '::' 108eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// namespace-name '::' 109eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// nested-name-specifier identifier '::' 1102dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// nested-name-specifier 'template'[opt] simple-template-id '::' 1112dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// 1122dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// 1131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// \param SS the scope specifier that will be set to the parsed 1142dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// nested-name-specifier (or empty) 1152dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// 1161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// \param ObjectType if this nested-name-specifier is being parsed following 1172dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// the "." or "->" of a member access expression, this parameter provides the 1182dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// type of the object whose members are being accessed. 119eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 1202dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// \param EnteringContext whether we will be entering into the context of 1212dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// the nested-name-specifier after parsing it. 1222dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor/// 123d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// \param MayBePseudoDestructor When non-NULL, points to a flag that 124d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// indicates whether this nested-name-specifier may be part of a 125d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// pseudo-destructor name. In this case, the flag will be set false 126d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// if we don't actually end up parsing a destructor name. Moreorover, 127d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// if we do end up determining that we are parsing a destructor name, 128d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// the last component of the nested-name-specifier is not parsed as 129d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// part of the scope specifier. 130d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor 131b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor/// member access expression, e.g., the \p T:: in \p p->T::m. 132b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor/// 1339ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall/// \returns true if there was an error parsing a scope specifier 134495c35d291da48c4f5655bbb54d15128ddde0d4dDouglas Gregorbool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, 135b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType ObjectType, 136b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor bool EnteringContext, 1374147d307086cf024a40a080e2bf379e9725f6f41Francois Pichet bool *MayBePseudoDestructor, 1384147d307086cf024a40a080e2bf379e9725f6f41Francois Pichet bool IsTypename) { 1394bdd91c09fd59e0c154d759288beff300e31e1d0Argyrios Kyrtzidis assert(getLang().CPlusPlus && 1407452c6fc567ea1799f617395d0fa4c7ed075e5d9Chris Lattner "Call sites of this function should be guarded by checking for C++"); 1411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 142eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis if (Tok.is(tok::annot_cxxscope)) { 143c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(), 144c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor Tok.getAnnotationRange(), 145c34348a7ef1a6b3f92a644a227953800cd1f9947Douglas Gregor SS); 146eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis ConsumeToken(); 1479ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return false; 148eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 149e607e808c2b90724a2a6fd841e850f07de1f5b30Chris Lattner 15039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor bool HasScopeSpecifier = false; 15139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor 1525b4547318bb179fc76f984f0eeaaf615927e795cChris Lattner if (Tok.is(tok::coloncolon)) { 1535b4547318bb179fc76f984f0eeaaf615927e795cChris Lattner // ::new and ::delete aren't nested-name-specifiers. 1545b4547318bb179fc76f984f0eeaaf615927e795cChris Lattner tok::TokenKind NextKind = NextToken().getKind(); 1555b4547318bb179fc76f984f0eeaaf615927e795cChris Lattner if (NextKind == tok::kw_new || NextKind == tok::kw_delete) 1565b4547318bb179fc76f984f0eeaaf615927e795cChris Lattner return false; 1571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15855a7cefc846765ac7d142a63f773747a20518d71Chris Lattner // '::' - Global scope qualifier. 1592e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor if (Actions.ActOnCXXGlobalScopeSpecifier(getCurScope(), ConsumeToken(), SS)) 1602e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor return true; 1612e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor 16239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor HasScopeSpecifier = true; 163eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 164eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 165d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor bool CheckForDestructor = false; 166d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor if (MayBePseudoDestructor && *MayBePseudoDestructor) { 167d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor CheckForDestructor = true; 168d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor *MayBePseudoDestructor = false; 169d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor } 170d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor 17139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor while (true) { 1722dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor if (HasScopeSpecifier) { 1732dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor // C++ [basic.lookup.classref]p5: 1742dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor // If the qualified-id has the form 1753b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregor // 1762dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor // ::class-name-or-namespace-name::... 1773b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregor // 1782dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor // the class-name-or-namespace-name is looked up in global scope as a 1792dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor // class-name or namespace-name. 1802dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor // 1812dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor // To implement this, we clear out the object type as soon as we've 1822dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor // seen a leading '::' or part of a nested-name-specifier. 183b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ObjectType = ParsedType(); 18481b747b7fcc91c2fba9a3183d8fac80adbfc1d3eDouglas Gregor 18581b747b7fcc91c2fba9a3183d8fac80adbfc1d3eDouglas Gregor if (Tok.is(tok::code_completion)) { 18681b747b7fcc91c2fba9a3183d8fac80adbfc1d3eDouglas Gregor // Code completion for a nested-name-specifier, where the code 18781b747b7fcc91c2fba9a3183d8fac80adbfc1d3eDouglas Gregor // code completion token follows the '::'. 18823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.CodeCompleteQualifiedId(getCurScope(), SS, EnteringContext); 189b6b2b180c6857af75c6683f7107a7c8994f074edArgyrios Kyrtzidis // Include code completion token into the range of the scope otherwise 190b6b2b180c6857af75c6683f7107a7c8994f074edArgyrios Kyrtzidis // when we try to annotate the scope tokens the dangling code completion 191b6b2b180c6857af75c6683f7107a7c8994f074edArgyrios Kyrtzidis // token will cause assertion in 192b6b2b180c6857af75c6683f7107a7c8994f074edArgyrios Kyrtzidis // Preprocessor::AnnotatePreviousCachedTokens. 1937d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis SS.setEndLoc(Tok.getLocation()); 1947d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis cutOffParsing(); 1957d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis return true; 19681b747b7fcc91c2fba9a3183d8fac80adbfc1d3eDouglas Gregor } 1972dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor } 1981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // nested-name-specifier: 20077cf72a95baa18e82737bb45131e9658a00fee16Chris Lattner // nested-name-specifier 'template'[opt] simple-template-id '::' 20177cf72a95baa18e82737bb45131e9658a00fee16Chris Lattner 20277cf72a95baa18e82737bb45131e9658a00fee16Chris Lattner // Parse the optional 'template' keyword, then make sure we have 20377cf72a95baa18e82737bb45131e9658a00fee16Chris Lattner // 'identifier <' after it. 20477cf72a95baa18e82737bb45131e9658a00fee16Chris Lattner if (Tok.is(tok::kw_template)) { 2052dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor // If we don't have a scope specifier or an object type, this isn't a 206eab975dce83fcf6a7fa8fc9379944d4b1aaf1a00Eli Friedman // nested-name-specifier, since they aren't allowed to start with 207eab975dce83fcf6a7fa8fc9379944d4b1aaf1a00Eli Friedman // 'template'. 2082dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor if (!HasScopeSpecifier && !ObjectType) 209eab975dce83fcf6a7fa8fc9379944d4b1aaf1a00Eli Friedman break; 210eab975dce83fcf6a7fa8fc9379944d4b1aaf1a00Eli Friedman 2117bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor TentativeParsingAction TPA(*this); 21277cf72a95baa18e82737bb45131e9658a00fee16Chris Lattner SourceLocation TemplateKWLoc = ConsumeToken(); 213ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 214ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor UnqualifiedId TemplateName; 215ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor if (Tok.is(tok::identifier)) { 216ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // Consume the identifier. 2177bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor TemplateName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); 218ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor ConsumeToken(); 219ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor } else if (Tok.is(tok::kw_operator)) { 220ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, 2217bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor TemplateName)) { 2227bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor TPA.Commit(); 223ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor break; 2247bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor } 225ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 226e6252d1587f98dbac704178e7b2ce53116048310Sean Hunt if (TemplateName.getKind() != UnqualifiedId::IK_OperatorFunctionId && 227e6252d1587f98dbac704178e7b2ce53116048310Sean Hunt TemplateName.getKind() != UnqualifiedId::IK_LiteralOperatorId) { 228ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor Diag(TemplateName.getSourceRange().getBegin(), 229ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor diag::err_id_after_template_in_nested_name_spec) 230ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor << TemplateName.getSourceRange(); 2317bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor TPA.Commit(); 232ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor break; 233ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor } 234ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor } else { 2357bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor TPA.Revert(); 23677cf72a95baa18e82737bb45131e9658a00fee16Chris Lattner break; 23777cf72a95baa18e82737bb45131e9658a00fee16Chris Lattner } 2381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2397bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor // If the next token is not '<', we have a qualified-id that refers 2407bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor // to a template name, such as T::template apply, but is not a 2417bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor // template-id. 2427bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor if (Tok.isNot(tok::less)) { 2437bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor TPA.Revert(); 2447bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor break; 2457bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor } 2467bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor 2477bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor // Commit to parsing the template-id. 2487bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor TPA.Commit(); 249d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor TemplateTy Template; 25023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor if (TemplateNameKind TNK = Actions.ActOnDependentTemplateName(getCurScope(), 251d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor TemplateKWLoc, 252d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor SS, 253d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor TemplateName, 254d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor ObjectType, 255d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor EnteringContext, 256d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor Template)) { 257059101f922de6eb765601459925f4c8914420b23Douglas Gregor if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateName, 258d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor TemplateKWLoc, false)) 259d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor return true; 260d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor } else 2619ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return true; 2621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 26377cf72a95baa18e82737bb45131e9658a00fee16Chris Lattner continue; 26477cf72a95baa18e82737bb45131e9658a00fee16Chris Lattner } 2651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 26639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor if (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) { 2671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // We have 26839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // 26939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // simple-template-id '::' 27039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // 27139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // So we need to check whether the simple-template-id is of the 272c45c232440dfafedca1a3773b904fb42609b1b19Douglas Gregor // right kind (it should name a type or be dependent), and then 273c45c232440dfafedca1a3773b904fb42609b1b19Douglas Gregor // convert it into a type within the nested-name-specifier. 27425a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 275d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde)) { 276d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor *MayBePseudoDestructor = true; 2779ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return false; 278d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor } 279d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor 2806cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor // Consume the template-id token. 2816cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor ConsumeToken(); 2826cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor 2836cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!"); 2846cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor SourceLocation CCLoc = ConsumeToken(); 2851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2866796fc1adcaf57c38d072a238b016b2834afbe0dDavid Blaikie HasScopeSpecifier = true; 2876cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor 2886cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor ASTTemplateArgsPtr TemplateArgsPtr(Actions, 2896cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor TemplateId->getTemplateArgs(), 2906cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor TemplateId->NumArgs); 2916cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor 2926cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(), 2936cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor /*FIXME:*/SourceLocation(), 2946cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor SS, 2956cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor TemplateId->Template, 2966cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor TemplateId->TemplateNameLoc, 2976cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor TemplateId->LAngleLoc, 2986cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor TemplateArgsPtr, 2996cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor TemplateId->RAngleLoc, 3006cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor CCLoc, 3016cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor EnteringContext)) { 3026cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor SourceLocation StartLoc 3036cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor = SS.getBeginLoc().isValid()? SS.getBeginLoc() 3046cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor : TemplateId->TemplateNameLoc; 3056cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor SS.SetInvalid(SourceRange(StartLoc, CCLoc)); 30667b9e831943300ce54e564e601971828ce4def15Chris Lattner } 307eccce7e246a17e12a2afd6eabb9ac7c8d582db4eArgyrios Kyrtzidis 3086cd9d4aa13c2145c8b4398453974515b734bfe42Douglas Gregor continue; 30939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor } 31039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor 3115c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner 3125c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // The rest of the nested-name-specifier possibilities start with 3135c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // tok::identifier. 3145c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner if (Tok.isNot(tok::identifier)) 3155c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner break; 3165c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner 3175c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner IdentifierInfo &II = *Tok.getIdentifierInfo(); 3185c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner 3195c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // nested-name-specifier: 3205c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // type-name '::' 3215c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // namespace-name '::' 3225c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // nested-name-specifier identifier '::' 3235c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner Token Next = NextToken(); 32446646491834cd8faabb22482dfe93b24ce28a6c1Chris Lattner 32546646491834cd8faabb22482dfe93b24ce28a6c1Chris Lattner // If we get foo:bar, this is almost certainly a typo for foo::bar. Recover 32646646491834cd8faabb22482dfe93b24ce28a6c1Chris Lattner // and emit a fixit hint for it. 327b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor if (Next.is(tok::colon) && !ColonIsSacred) { 3282e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor if (Actions.IsInvalidUnlessNestedName(getCurScope(), SS, II, 3292e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor Tok.getLocation(), 3302e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor Next.getLocation(), ObjectType, 331b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor EnteringContext) && 332b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor // If the token after the colon isn't an identifier, it's still an 333b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor // error, but they probably meant something else strange so don't 334b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor // recover like this. 335b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor PP.LookAhead(1).is(tok::identifier)) { 336b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor Diag(Next, diag::err_unexected_colon_in_nested_name_spec) 337849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor << FixItHint::CreateReplacement(Next.getLocation(), "::"); 338b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor 339b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor // Recover as if the user wrote '::'. 340b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor Next.setKind(tok::coloncolon); 341b10cd04880672103660e5844e51ee91af7361a20Douglas Gregor } 34246646491834cd8faabb22482dfe93b24ce28a6c1Chris Lattner } 34346646491834cd8faabb22482dfe93b24ce28a6c1Chris Lattner 3445c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner if (Next.is(tok::coloncolon)) { 34577549080fb7b9af31606b3c1b4830a94429fb1fdDouglas Gregor if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde) && 34623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor !Actions.isNonTypeNestedNameSpecifier(getCurScope(), SS, Tok.getLocation(), 34777549080fb7b9af31606b3c1b4830a94429fb1fdDouglas Gregor II, ObjectType)) { 348d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor *MayBePseudoDestructor = true; 3499ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return false; 350d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor } 351d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor 3525c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // We have an identifier followed by a '::'. Lookup this name 3535c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // as the name in a nested-name-specifier. 3545c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner SourceLocation IdLoc = ConsumeToken(); 35546646491834cd8faabb22482dfe93b24ce28a6c1Chris Lattner assert((Tok.is(tok::coloncolon) || Tok.is(tok::colon)) && 35646646491834cd8faabb22482dfe93b24ce28a6c1Chris Lattner "NextToken() not working properly!"); 3575c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner SourceLocation CCLoc = ConsumeToken(); 3581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3592e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor HasScopeSpecifier = true; 3602e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(), II, IdLoc, CCLoc, 3612e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor ObjectType, EnteringContext, SS)) 3622e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor SS.SetInvalid(SourceRange(IdLoc, CCLoc)); 3632e4c34ac53d08633b9473df921db4c7e4c9cd577Douglas Gregor 3645c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner continue; 3655c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner } 3661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 367950be71c745409e373ae8a834490f9026c8ac222Richard Trieu CheckForTemplateAndDigraph(Next, ObjectType, EnteringContext, II, SS); 368ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith 3695c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // nested-name-specifier: 3705c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // type-name '<' 3715c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner if (Next.is(tok::less)) { 3725c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner TemplateTy Template; 373014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor UnqualifiedId TemplateName; 374014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor TemplateName.setIdentifier(&II, Tok.getLocation()); 3751fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor bool MemberOfUnknownSpecialization; 37623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor if (TemplateNameKind TNK = Actions.isTemplateName(getCurScope(), SS, 3777c15353ccaed24f2df932571166bf305c1b98b6dAbramo Bagnara /*hasTemplateKeyword=*/false, 378014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor TemplateName, 3792dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor ObjectType, 380495c35d291da48c4f5655bbb54d15128ddde0d4dDouglas Gregor EnteringContext, 3811fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor Template, 3821fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor MemberOfUnknownSpecialization)) { 3836796fc1adcaf57c38d072a238b016b2834afbe0dDavid Blaikie // We have found a template name, so annotate this token 3845c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // with a template-id annotation. We do not permit the 3855c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // template-id to be translated into a type annotation, 3865c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // because some clients (e.g., the parsing of class template 3875c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // specializations) still want to see the original template-id 3885c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner // token. 389ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor ConsumeToken(); 390059101f922de6eb765601459925f4c8914420b23Douglas Gregor if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateName, 391ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor SourceLocation(), false)) 3929ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return true; 3935c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner continue; 394d5ab9b0a0ae24f7d0f49f6f10fd1b247e64b3306Douglas Gregor } 395d5ab9b0a0ae24f7d0f49f6f10fd1b247e64b3306Douglas Gregor 396d5ab9b0a0ae24f7d0f49f6f10fd1b247e64b3306Douglas Gregor if (MemberOfUnknownSpecialization && (ObjectType || SS.isSet()) && 3974147d307086cf024a40a080e2bf379e9725f6f41Francois Pichet (IsTypename || IsTemplateArgumentList(1))) { 398d5ab9b0a0ae24f7d0f49f6f10fd1b247e64b3306Douglas Gregor // We have something like t::getAs<T>, where getAs is a 399d5ab9b0a0ae24f7d0f49f6f10fd1b247e64b3306Douglas Gregor // member of an unknown specialization. However, this will only 400d5ab9b0a0ae24f7d0f49f6f10fd1b247e64b3306Douglas Gregor // parse correctly as a template, so suggest the keyword 'template' 401d5ab9b0a0ae24f7d0f49f6f10fd1b247e64b3306Douglas Gregor // before 'getAs' and treat this as a dependent template name. 4024147d307086cf024a40a080e2bf379e9725f6f41Francois Pichet unsigned DiagID = diag::err_missing_dependent_template_keyword; 40362ec1f2fd7368542bb926c04797fb07023547694Francois Pichet if (getLang().MicrosoftExt) 404cf320c6388c90f1938c264e87d77a0e43946e2c3Francois Pichet DiagID = diag::warn_missing_dependent_template_keyword; 4054147d307086cf024a40a080e2bf379e9725f6f41Francois Pichet 4064147d307086cf024a40a080e2bf379e9725f6f41Francois Pichet Diag(Tok.getLocation(), DiagID) 407d5ab9b0a0ae24f7d0f49f6f10fd1b247e64b3306Douglas Gregor << II.getName() 408d5ab9b0a0ae24f7d0f49f6f10fd1b247e64b3306Douglas Gregor << FixItHint::CreateInsertion(Tok.getLocation(), "template "); 409d5ab9b0a0ae24f7d0f49f6f10fd1b247e64b3306Douglas Gregor 410d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor if (TemplateNameKind TNK 41123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor = Actions.ActOnDependentTemplateName(getCurScope(), 412d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor Tok.getLocation(), SS, 413d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor TemplateName, ObjectType, 414d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor EnteringContext, Template)) { 415d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor // Consume the identifier. 416d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor ConsumeToken(); 417059101f922de6eb765601459925f4c8914420b23Douglas Gregor if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateName, 418d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor SourceLocation(), false)) 419d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor return true; 420d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor } 421d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor else 422d5ab9b0a0ae24f7d0f49f6f10fd1b247e64b3306Douglas Gregor return true; 423d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor 424d5ab9b0a0ae24f7d0f49f6f10fd1b247e64b3306Douglas Gregor continue; 4255c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner } 4265c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner } 4275c7f786e3269ee2b512ecf13ccf556c47be83a76Chris Lattner 42839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // We don't have any tokens that form the beginning of a 42939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // nested-name-specifier, so we're done. 43039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor break; 43139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor } 4321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 433d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // Even if we didn't see any pieces of a nested-name-specifier, we 434d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // still check whether there is a tilde in this position, which 435d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // indicates a potential pseudo-destructor. 436d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor if (CheckForDestructor && Tok.is(tok::tilde)) 437d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor *MayBePseudoDestructor = true; 438d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor 4399ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall return false; 440eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis} 441eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 442eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// ParseCXXIdExpression - Handle id-expression. 443eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 444eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// id-expression: 445eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// unqualified-id 446eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// qualified-id 447eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 448eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// qualified-id: 449eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 450eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' identifier 451eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' operator-function-id 452edce4dd44732dfad69f28822dddcf2b8e92b4483Douglas Gregor/// '::' template-id 453eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 454eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// NOTE: The standard specifies that, for qualified-id, the parser does not 455eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// expect: 456eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 457eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' conversion-function-id 458eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' '~' class-name 459eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 460eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// This may cause a slight inconsistency on diagnostics: 461eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 462eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// class C {}; 463eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// namespace A {} 464eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// void f() { 465eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// :: A :: ~ C(); // Some Sema error about using destructor with a 466eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// // namespace. 467eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// :: ~ C(); // Some Parser error like 'unexpected ~'. 468eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// } 469eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 470eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// We simplify the parser a bit and make it work like: 471eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 472eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// qualified-id: 473eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 474eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::' unqualified-id 475eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 476eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// That way Sema can handle and report similar errors for namespaces and the 477eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// global scope. 478eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// 479ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl/// The isAddressOfOperand parameter indicates that this id-expression is a 480ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl/// direct operand of the address-of operator. This is, besides member contexts, 481ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl/// the only place where a qualified-id naming a non-static class member may 482ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl/// appear. 483ebc07d57be9e0722b4b9c66625e1fca43dcc2ee0Sebastian Redl/// 48460d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) { 485eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // qualified-id: 486eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 487eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // '::' unqualified-id 488eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // 489eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis CXXScopeSpec SS; 490efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); 49102a24ee67c0a91bdb0db8a651d5748595652e670Douglas Gregor 49202a24ee67c0a91bdb0db8a651d5748595652e670Douglas Gregor UnqualifiedId Name; 49302a24ee67c0a91bdb0db8a651d5748595652e670Douglas Gregor if (ParseUnqualifiedId(SS, 49402a24ee67c0a91bdb0db8a651d5748595652e670Douglas Gregor /*EnteringContext=*/false, 49502a24ee67c0a91bdb0db8a651d5748595652e670Douglas Gregor /*AllowDestructorName=*/false, 49602a24ee67c0a91bdb0db8a651d5748595652e670Douglas Gregor /*AllowConstructorName=*/false, 497b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall /*ObjectType=*/ ParsedType(), 49802a24ee67c0a91bdb0db8a651d5748595652e670Douglas Gregor Name)) 49902a24ee67c0a91bdb0db8a651d5748595652e670Douglas Gregor return ExprError(); 500b681b61fea36618778b8030360e90e3f4641233bJohn McCall 501b681b61fea36618778b8030360e90e3f4641233bJohn McCall // This is only the direct operand of an & operator if it is not 502b681b61fea36618778b8030360e90e3f4641233bJohn McCall // followed by a postfix-expression suffix. 5039c72c6088d591ace8503b842d39448c2040f3033John McCall if (isAddressOfOperand && isPostfixExpressionSuffixStart()) 5049c72c6088d591ace8503b842d39448c2040f3033John McCall isAddressOfOperand = false; 50502a24ee67c0a91bdb0db8a651d5748595652e670Douglas Gregor 50623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor return Actions.ActOnIdExpression(getCurScope(), SS, Name, Tok.is(tok::l_paren), 50702a24ee67c0a91bdb0db8a651d5748595652e670Douglas Gregor isAddressOfOperand); 50802a24ee67c0a91bdb0db8a651d5748595652e670Douglas Gregor 509eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis} 510eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis 511ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// ParseLambdaExpression - Parse a C++0x lambda expression. 512ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 513ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// lambda-expression: 514ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// lambda-introducer lambda-declarator[opt] compound-statement 515ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 516ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// lambda-introducer: 517ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// '[' lambda-capture[opt] ']' 518ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 519ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// lambda-capture: 520ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// capture-default 521ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// capture-list 522ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// capture-default ',' capture-list 523ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 524ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// capture-default: 525ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// '&' 526ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// '=' 527ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 528ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// capture-list: 529ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// capture 530ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// capture-list ',' capture 531ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 532ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// capture: 533ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// identifier 534ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// '&' identifier 535ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 'this' 536ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 537ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// lambda-declarator: 538ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// '(' parameter-declaration-clause ')' attribute-specifier[opt] 539ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 'mutable'[opt] exception-specification[opt] 540ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// trailing-return-type[opt] 541ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 542ae7902c4293d9de8b9591759513f0d075f45022aDouglas GregorExprResult Parser::ParseLambdaExpression() { 543ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // Parse lambda-introducer. 544ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor LambdaIntroducer Intro; 545ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 546ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor llvm::Optional<unsigned> DiagID(ParseLambdaIntroducer(Intro)); 547ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (DiagID) { 548ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Diag(Tok, DiagID.getValue()); 549ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor SkipUntil(tok::r_square); 550ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 551ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 552ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor return ParseLambdaExpressionAfterIntroducer(Intro); 553ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor} 554ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 555ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// TryParseLambdaExpression - Use lookahead and potentially tentative 556ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// parsing to determine if we are looking at a C++0x lambda expression, and parse 557ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// it if we are. 558ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 559ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// If we are not looking at a lambda expression, returns ExprError(). 560ae7902c4293d9de8b9591759513f0d075f45022aDouglas GregorExprResult Parser::TryParseLambdaExpression() { 561ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor assert(getLang().CPlusPlus0x 562ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor && Tok.is(tok::l_square) 563ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor && "Not at the start of a possible lambda expression."); 564ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 565ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor const Token Next = NextToken(), After = GetLookAheadToken(2); 566ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 567ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // If lookahead indicates this is a lambda... 568ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (Next.is(tok::r_square) || // [] 569ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Next.is(tok::equal) || // [= 570ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor (Next.is(tok::amp) && // [&] or [&, 571ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor (After.is(tok::r_square) || 572ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor After.is(tok::comma))) || 573ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor (Next.is(tok::identifier) && // [identifier] 574ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor After.is(tok::r_square))) { 575ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor return ParseLambdaExpression(); 576ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 577ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 578ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // If lookahead indicates this is an Objective-C message... 579ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (Next.is(tok::identifier) && After.is(tok::identifier)) { 580ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor return ExprError(); 581ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 582ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 583ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor LambdaIntroducer Intro; 584ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (TryParseLambdaIntroducer(Intro)) 585ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor return ExprError(); 586ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor return ParseLambdaExpressionAfterIntroducer(Intro); 587ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor} 588ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 589ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// ParseLambdaExpression - Parse a lambda introducer. 590ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 591ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// Returns a DiagnosticID if it hit something unexpected. 592ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregorllvm::Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro) { 593ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor typedef llvm::Optional<unsigned> DiagResult; 594ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 595ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor assert(Tok.is(tok::l_square) && "Lambda expressions begin with '['."); 5964a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_square); 5974a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 5984a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor 5994a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Intro.Range.setBegin(T.getOpenLocation()); 600ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 601ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor bool first = true; 602ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 603ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // Parse capture-default. 604ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (Tok.is(tok::amp) && 605ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor (NextToken().is(tok::comma) || NextToken().is(tok::r_square))) { 606ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Intro.Default = LCD_ByRef; 607ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ConsumeToken(); 608ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor first = false; 609ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } else if (Tok.is(tok::equal)) { 610ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Intro.Default = LCD_ByCopy; 611ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ConsumeToken(); 612ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor first = false; 613ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 614ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 615ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor while (Tok.isNot(tok::r_square)) { 616ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (!first) { 617ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (Tok.isNot(tok::comma)) 618ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor return DiagResult(diag::err_expected_comma_or_rsquare); 619ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ConsumeToken(); 620ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 621ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 622ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor first = false; 623ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 624ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // Parse capture. 625ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor LambdaCaptureKind Kind = LCK_ByCopy; 626ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor SourceLocation Loc; 627ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor IdentifierInfo* Id = 0; 628ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 629ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (Tok.is(tok::kw_this)) { 630ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Kind = LCK_This; 631ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Loc = ConsumeToken(); 632ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } else { 633ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (Tok.is(tok::amp)) { 634ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Kind = LCK_ByRef; 635ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ConsumeToken(); 636ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 637ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 638ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (Tok.is(tok::identifier)) { 639ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Id = Tok.getIdentifierInfo(); 640ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Loc = ConsumeToken(); 641ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } else if (Tok.is(tok::kw_this)) { 642ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // FIXME: If we want to suggest a fixit here, will need to return more 643ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // than just DiagnosticID. Perhaps full DiagnosticBuilder that can be 644ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // Clear()ed to prevent emission in case of tentative parsing? 645ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor return DiagResult(diag::err_this_captured_by_reference); 646ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } else { 647ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor return DiagResult(diag::err_expected_capture); 648ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 649ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 650ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 651ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Intro.addCapture(Kind, Loc, Id); 652ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 653ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 6544a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 6554a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Intro.Range.setEnd(T.getCloseLocation()); 656ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 657ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor return DiagResult(); 658ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor} 659ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 660ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// TryParseLambdaExpression - Tentatively parse a lambda introducer. 661ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// 662ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// Returns true if it hit something unexpected. 663ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregorbool Parser::TryParseLambdaIntroducer(LambdaIntroducer &Intro) { 664ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor TentativeParsingAction PA(*this); 665ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 666ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor llvm::Optional<unsigned> DiagID(ParseLambdaIntroducer(Intro)); 667ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 668ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (DiagID) { 669ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor PA.Revert(); 670ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor return true; 671ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 672ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 673ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor PA.Commit(); 674ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor return false; 675ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor} 676ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 677ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// ParseLambdaExpressionAfterIntroducer - Parse the rest of a lambda 678ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor/// expression. 679ae7902c4293d9de8b9591759513f0d075f45022aDouglas GregorExprResult Parser::ParseLambdaExpressionAfterIntroducer( 680ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor LambdaIntroducer &Intro) { 6817fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith Diag(Intro.Range.getBegin(), diag::warn_cxx98_compat_lambda); 6827fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith 683ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // Parse lambda-declarator[opt]. 684ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor DeclSpec DS(AttrFactory); 685ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Declarator D(DS, Declarator::PrototypeContext); 686ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 687ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (Tok.is(tok::l_paren)) { 688ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ParseScope PrototypeScope(this, 689ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Scope::FunctionPrototypeScope | 690ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Scope::DeclScope); 691ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 6924a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SourceLocation DeclLoc, DeclEndLoc; 6934a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 6944a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 6954a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor DeclLoc = T.getOpenLocation(); 696ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 697ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // Parse parameter-declaration-clause. 698ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ParsedAttributes Attr(AttrFactory); 699ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor llvm::SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo; 700ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor SourceLocation EllipsisLoc; 701ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 702ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (Tok.isNot(tok::r_paren)) 703ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ParseParameterDeclarationClause(D, Attr, ParamInfo, EllipsisLoc); 704ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 7054a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 7064a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor DeclEndLoc = T.getCloseLocation(); 707ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 708ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // Parse 'mutable'[opt]. 709ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor SourceLocation MutableLoc; 710ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (Tok.is(tok::kw_mutable)) { 711ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor MutableLoc = ConsumeToken(); 712ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor DeclEndLoc = MutableLoc; 713ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 714ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 715ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // Parse exception-specification[opt]. 716ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ExceptionSpecificationType ESpecType = EST_None; 717ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor SourceRange ESpecRange; 718ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor llvm::SmallVector<ParsedType, 2> DynamicExceptions; 719ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor llvm::SmallVector<SourceRange, 2> DynamicExceptionRanges; 720ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ExprResult NoexceptExpr; 721ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ESpecType = MaybeParseExceptionSpecification(ESpecRange, 722ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor DynamicExceptions, 723ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor DynamicExceptionRanges, 724ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor NoexceptExpr); 725ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 726ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (ESpecType != EST_None) 727ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor DeclEndLoc = ESpecRange.getEnd(); 728ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 729ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // Parse attribute-specifier[opt]. 730ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor MaybeParseCXX0XAttributes(Attr, &DeclEndLoc); 731ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 732ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // Parse trailing-return-type[opt]. 733ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ParsedType TrailingReturnType; 734ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (Tok.is(tok::arrow)) { 735ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor SourceRange Range; 736ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor TrailingReturnType = ParseTrailingReturnType(Range).get(); 737ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (Range.getEnd().isValid()) 738ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor DeclEndLoc = Range.getEnd(); 739ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 740ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 741ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor PrototypeScope.Exit(); 742ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 743ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor D.AddTypeInfo(DeclaratorChunk::getFunction(/*hasProto=*/true, 744ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor /*isVariadic=*/EllipsisLoc.isValid(), 745ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor EllipsisLoc, 746ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ParamInfo.data(), ParamInfo.size(), 747ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor DS.getTypeQualifiers(), 748ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor /*RefQualifierIsLValueRef=*/true, 749ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor /*RefQualifierLoc=*/SourceLocation(), 75043f5103f8051bbac19022e6edaf7d9138b0f3c0fDouglas Gregor /*ConstQualifierLoc=*/SourceLocation(), 75143f5103f8051bbac19022e6edaf7d9138b0f3c0fDouglas Gregor /*VolatileQualifierLoc=*/SourceLocation(), 752ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor MutableLoc, 753ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ESpecType, ESpecRange.getBegin(), 754ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor DynamicExceptions.data(), 755ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor DynamicExceptionRanges.data(), 756ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor DynamicExceptions.size(), 757ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor NoexceptExpr.isUsable() ? 758ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor NoexceptExpr.get() : 0, 759ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor DeclLoc, DeclEndLoc, D, 760ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor TrailingReturnType), 761ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Attr, DeclEndLoc); 762ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 763ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 764ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // Parse compound-statement. 765ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor if (Tok.is(tok::l_brace)) { 766ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // FIXME: Rename BlockScope -> ClosureScope if we decide to continue using 767ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor // it. 768ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor ParseScope BodyScope(this, Scope::BlockScope | Scope::FnScope | 769ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Scope::BreakScope | Scope::ContinueScope | 770ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Scope::DeclScope); 771ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 772ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor StmtResult Stmt(ParseCompoundStatementBody()); 773ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 774ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor BodyScope.Exit(); 775ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } else { 776ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor Diag(Tok, diag::err_expected_lambda_body); 777ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor } 778ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 779ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor return ExprEmpty(); 780ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor} 781ae7902c4293d9de8b9591759513f0d075f45022aDouglas Gregor 7825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCXXCasts - This handles the various ways to cast expressions to another 7835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// type. 7845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 7855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// postfix-expression: [C++ 5.2p1] 7865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'dynamic_cast' '<' type-name '>' '(' expression ')' 7875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'static_cast' '<' type-name '>' '(' expression ')' 7885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'reinterpret_cast' '<' type-name '>' '(' expression ')' 7895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'const_cast' '<' type-name '>' '(' expression ')' 7905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 79160d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Parser::ParseCXXCasts() { 7925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer tok::TokenKind Kind = Tok.getKind(); 7935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const char *CastName = 0; // For error messages 7945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 7955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer switch (Kind) { 796eb2d1f1c88836bd5382e5d7aa8f6b85148a88b27David Blaikie default: llvm_unreachable("Unknown C++ cast!"); 7975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_const_cast: CastName = "const_cast"; break; 7985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_dynamic_cast: CastName = "dynamic_cast"; break; 7995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break; 8005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case tok::kw_static_cast: CastName = "static_cast"; break; 8015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 8025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 8035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation OpLoc = ConsumeToken(); 8045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation LAngleBracketLoc = Tok.getLocation(); 8055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 806ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith // Check for "<::" which is parsed as "[:". If found, fix token stream, 807ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith // diagnose error, suggest fix, and recover parsing. 808ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith Token Next = NextToken(); 809ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith if (Tok.is(tok::l_square) && Tok.getLength() == 2 && Next.is(tok::colon) && 810ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith AreTokensAdjacent(PP, Tok, Next)) 811ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith FixDigraph(*this, PP, Tok, Next, Kind, /*AtDigraph*/true); 812ea698b3f6cad84f7f583282dce3e03e24fe80e98Richard Smith 8135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName)) 81420df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 8155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 81631862ba5ea70b1f2c81d03f8a0100b61cd6f06f6Argyrios Kyrtzidis // Parse the common declaration-specifiers piece. 81731862ba5ea70b1f2c81d03f8a0100b61cd6f06f6Argyrios Kyrtzidis DeclSpec DS(AttrFactory); 81831862ba5ea70b1f2c81d03f8a0100b61cd6f06f6Argyrios Kyrtzidis ParseSpecifierQualifierList(DS); 81931862ba5ea70b1f2c81d03f8a0100b61cd6f06f6Argyrios Kyrtzidis 82031862ba5ea70b1f2c81d03f8a0100b61cd6f06f6Argyrios Kyrtzidis // Parse the abstract-declarator, if present. 82131862ba5ea70b1f2c81d03f8a0100b61cd6f06f6Argyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 82231862ba5ea70b1f2c81d03f8a0100b61cd6f06f6Argyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 82331862ba5ea70b1f2c81d03f8a0100b61cd6f06f6Argyrios Kyrtzidis 8245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation RAngleBracketLoc = Tok.getLocation(); 8255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 8261ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner if (ExpectAndConsume(tok::greater, diag::err_expected_greater)) 82720df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << "<"); 8285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 8294a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SourceLocation LParenLoc, RParenLoc; 8304a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 8315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 8324a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.expectAndConsume(diag::err_expected_lparen_after, CastName)) 83321e7ad24099965acfa801e4abdd91e3d94106428Argyrios Kyrtzidis return ExprError(); 8345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 83560d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult Result = ParseExpression(); 8361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 83721e7ad24099965acfa801e4abdd91e3d94106428Argyrios Kyrtzidis // Match the ')'. 8384a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 8395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 84031862ba5ea70b1f2c81d03f8a0100b61cd6f06f6Argyrios Kyrtzidis if (!Result.isInvalid() && !DeclaratorInfo.isInvalidType()) 84149badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor Result = Actions.ActOnCXXNamedCast(OpLoc, Kind, 84231862ba5ea70b1f2c81d03f8a0100b61cd6f06f6Argyrios Kyrtzidis LAngleBracketLoc, DeclaratorInfo, 843809070a886684cb5b92eb0e00a6581ab1fa6b17aDouglas Gregor RAngleBracketLoc, 8444a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getOpenLocation(), Result.take(), 8454a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()); 8465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 84720df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return move(Result); 8485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 8495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 850c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// ParseCXXTypeid - This handles the C++ typeid expression. 851c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 852c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// postfix-expression: [C++ 5.2p1] 853c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 'typeid' '(' expression ')' 854c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 'typeid' '(' type-id ')' 855c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl/// 85660d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Parser::ParseCXXTypeid() { 857c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!"); 858c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 859c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SourceLocation OpLoc = ConsumeToken(); 8604a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SourceLocation LParenLoc, RParenLoc; 8614a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 862c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 863c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl // typeid expressions are always parenthesized. 8644a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.expectAndConsume(diag::err_expected_lparen_after, "typeid")) 86520df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 8664a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor LParenLoc = T.getOpenLocation(); 867c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 86860d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult Result; 869c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 870c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl if (isTypeIdInParens()) { 871809070a886684cb5b92eb0e00a6581ab1fa6b17aDouglas Gregor TypeResult Ty = ParseTypeName(); 872c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 873c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl // Match the ')'. 8744a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 8754a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor RParenLoc = T.getCloseLocation(); 8764eb4f0f96289cbece50c1270e02af3caf8779705Douglas Gregor if (Ty.isInvalid() || RParenLoc.isInvalid()) 87720df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 878c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 879c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true, 880b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall Ty.get().getAsOpaquePtr(), RParenLoc); 881c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl } else { 882e0762c92110dfdcdd207db461a4ea17afd168f1eDouglas Gregor // C++0x [expr.typeid]p3: 8831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // When typeid is applied to an expression other than an lvalue of a 8841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // polymorphic class type [...] The expression is an unevaluated 885e0762c92110dfdcdd207db461a4ea17afd168f1eDouglas Gregor // operand (Clause 5). 886e0762c92110dfdcdd207db461a4ea17afd168f1eDouglas Gregor // 8871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Note that we can't tell whether the expression is an lvalue of a 888e0762c92110dfdcdd207db461a4ea17afd168f1eDouglas Gregor // polymorphic class type until after we've parsed the expression, so 889ac7610dad6653bad02dd42de198ca358b6fb1f1dDouglas Gregor // we the expression is potentially potentially evaluated. 890ac7610dad6653bad02dd42de198ca358b6fb1f1dDouglas Gregor EnterExpressionEvaluationContext Unevaluated(Actions, 891f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall Sema::PotentiallyPotentiallyEvaluated); 892c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Result = ParseExpression(); 893c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 894c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl // Match the ')'. 8950e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Result.isInvalid()) 896c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl SkipUntil(tok::r_paren); 897c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl else { 8984a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 8994a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor RParenLoc = T.getCloseLocation(); 9004eb4f0f96289cbece50c1270e02af3caf8779705Douglas Gregor if (RParenLoc.isInvalid()) 9014eb4f0f96289cbece50c1270e02af3caf8779705Douglas Gregor return ExprError(); 902fadb53b351977ca7f99a9a613596cba6531979a3Douglas Gregor 903c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false, 904effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl Result.release(), RParenLoc); 905c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl } 906c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl } 907c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 90820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return move(Result); 909c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl} 910c42e1183846228a7fa5143ad76507d6d60f5c6f3Sebastian Redl 91101b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet/// ParseCXXUuidof - This handles the Microsoft C++ __uuidof expression. 91201b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet/// 91301b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet/// '__uuidof' '(' expression ')' 91401b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet/// '__uuidof' '(' type-id ')' 91501b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet/// 91601b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois PichetExprResult Parser::ParseCXXUuidof() { 91701b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet assert(Tok.is(tok::kw___uuidof) && "Not '__uuidof'!"); 91801b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet 91901b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet SourceLocation OpLoc = ConsumeToken(); 9204a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 92101b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet 92201b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet // __uuidof expressions are always parenthesized. 9234a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.expectAndConsume(diag::err_expected_lparen_after, "__uuidof")) 92401b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet return ExprError(); 92501b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet 92601b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet ExprResult Result; 92701b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet 92801b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet if (isTypeIdInParens()) { 92901b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet TypeResult Ty = ParseTypeName(); 93001b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet 93101b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet // Match the ')'. 9324a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 93301b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet 93401b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet if (Ty.isInvalid()) 93501b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet return ExprError(); 93601b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet 9374a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Result = Actions.ActOnCXXUuidof(OpLoc, T.getOpenLocation(), /*isType=*/true, 9384a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Ty.get().getAsOpaquePtr(), 9394a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()); 94001b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet } else { 94101b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated); 94201b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet Result = ParseExpression(); 94301b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet 94401b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet // Match the ')'. 94501b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet if (Result.isInvalid()) 94601b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet SkipUntil(tok::r_paren); 94701b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet else { 9484a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 94901b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet 9504a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Result = Actions.ActOnCXXUuidof(OpLoc, T.getOpenLocation(), 9514a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor /*isType=*/false, 9524a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Result.release(), T.getCloseLocation()); 95301b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet } 95401b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet } 95501b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet 95601b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet return move(Result); 95701b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet} 95801b7c3028da5bbcb9f8e52ba67e4613070de0e60Francois Pichet 959d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// \brief Parse a C++ pseudo-destructor expression after the base, 960d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// . or -> operator, and nested-name-specifier have already been 961d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// parsed. 962d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// 963d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// postfix-expression: [C++ 5.2] 964d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// postfix-expression . pseudo-destructor-name 965d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// postfix-expression -> pseudo-destructor-name 966d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// 967d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// pseudo-destructor-name: 968d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// ::[opt] nested-name-specifier[opt] type-name :: ~type-name 969d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// ::[opt] nested-name-specifier template simple-template-id :: 970d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// ~type-name 971d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// ::[opt] nested-name-specifier[opt] ~type-name 972d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// 97360d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult 974d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas GregorParser::ParseCXXPseudoDestructor(ExprArg Base, SourceLocation OpLoc, 975d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor tok::TokenKind OpKind, 976d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor CXXScopeSpec &SS, 977b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType ObjectType) { 978d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // We're parsing either a pseudo-destructor-name or a dependent 979d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // member access that has the same form as a 980d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // pseudo-destructor-name. We parse both in the same way and let 981d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // the action model sort them out. 982d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // 983d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // Note that the ::[opt] nested-name-specifier[opt] has already 984d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // been parsed, and if there was a simple-template-id, it has 985d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // been coalesced into a template-id annotation token. 986d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor UnqualifiedId FirstTypeName; 987d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor SourceLocation CCLoc; 988d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor if (Tok.is(tok::identifier)) { 989d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor FirstTypeName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); 990d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor ConsumeToken(); 991d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail"); 992d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor CCLoc = ConsumeToken(); 993d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor } else if (Tok.is(tok::annot_template_id)) { 994d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor FirstTypeName.setTemplateId( 995d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor (TemplateIdAnnotation *)Tok.getAnnotationValue()); 996d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor ConsumeToken(); 997d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail"); 998d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor CCLoc = ConsumeToken(); 999d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor } else { 1000d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor FirstTypeName.setIdentifier(0, SourceLocation()); 1001d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor } 1002d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor 1003d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // Parse the tilde. 1004d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor assert(Tok.is(tok::tilde) && "ParseOptionalCXXScopeSpecifier fail"); 1005d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor SourceLocation TildeLoc = ConsumeToken(); 1006d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor if (!Tok.is(tok::identifier)) { 1007d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor Diag(Tok, diag::err_destructor_tilde_identifier); 1008d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor return ExprError(); 1009d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor } 1010d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor 1011d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // Parse the second type. 1012d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor UnqualifiedId SecondTypeName; 1013d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor IdentifierInfo *Name = Tok.getIdentifierInfo(); 1014d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor SourceLocation NameLoc = ConsumeToken(); 1015d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor SecondTypeName.setIdentifier(Name, NameLoc); 1016d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor 1017d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // If there is a '<', the second type name is a template-id. Parse 1018d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor // it as such. 1019d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor if (Tok.is(tok::less) && 1020d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor ParseUnqualifiedIdTemplateId(SS, Name, NameLoc, false, ObjectType, 10210278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor SecondTypeName, /*AssumeTemplateName=*/true, 10220278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor /*TemplateKWLoc*/SourceLocation())) 1023d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor return ExprError(); 1024d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor 10259ae2f076ca5ab1feb3ba95629099ec2319833701John McCall return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base, 10269ae2f076ca5ab1feb3ba95629099ec2319833701John McCall OpLoc, OpKind, 1027d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor SS, FirstTypeName, CCLoc, 1028d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor TildeLoc, SecondTypeName, 1029d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor Tok.is(tok::l_paren)); 1030d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor} 1031d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor 10325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ParseCXXBoolLiteral - This handles the C++ Boolean literals. 10335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 10345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// boolean-literal: [C++ 2.13.5] 10355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'true' 10365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 'false' 103760d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Parser::ParseCXXBoolLiteral() { 10385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer tok::TokenKind Kind = Tok.getKind(); 1039f53597fb16142bdb4a66901f8c0b768db4f2a548Sebastian Redl return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind); 10405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 104150dd289f45738ed22b7583d52ed2525b927042ffChris Lattner 104250dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// ParseThrowExpression - This handles the C++ throw expression. 104350dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// 104450dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// throw-expression: [C++ 15] 104550dd289f45738ed22b7583d52ed2525b927042ffChris Lattner/// 'throw' assignment-expression[opt] 104660d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Parser::ParseThrowExpression() { 104750dd289f45738ed22b7583d52ed2525b927042ffChris Lattner assert(Tok.is(tok::kw_throw) && "Not throw!"); 104850dd289f45738ed22b7583d52ed2525b927042ffChris Lattner SourceLocation ThrowLoc = ConsumeToken(); // Eat the throw token. 104920df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl 10502a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // If the current token isn't the start of an assignment-expression, 10512a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // then the expression is not present. This handles things like: 10522a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner // "C ? throw : (void)42", which is crazy but legal. 10532a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner switch (Tok.getKind()) { // FIXME: move this predicate somewhere common. 10542a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::semi: 10552a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_paren: 10562a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_square: 10572a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::r_brace: 10582a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::colon: 10592a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner case tok::comma: 1060bca01b46850f867b2f4137f25c882022b58f8471Douglas Gregor return Actions.ActOnCXXThrow(getCurScope(), ThrowLoc, 0); 106150dd289f45738ed22b7583d52ed2525b927042ffChris Lattner 10622a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner default: 106360d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult Expr(ParseAssignmentExpression()); 106420df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl if (Expr.isInvalid()) return move(Expr); 1065bca01b46850f867b2f4137f25c882022b58f8471Douglas Gregor return Actions.ActOnCXXThrow(getCurScope(), ThrowLoc, Expr.take()); 10662a2819a0a8e114bfa5a3c4fc4c97fa173155bae9Chris Lattner } 106750dd289f45738ed22b7583d52ed2525b927042ffChris Lattner} 10684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 10694cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXThis - This handles the C++ 'this' pointer. 10704cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 10714cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// C++ 9.3.2: In the body of a non-static member function, the keyword this is 10724cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// a non-lvalue expression whose value is the address of the object for which 10734cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// the function is called. 107460d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Parser::ParseCXXThis() { 10754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis assert(Tok.is(tok::kw_this) && "Not 'this'!"); 10764cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SourceLocation ThisLoc = ConsumeToken(); 1077f53597fb16142bdb4a66901f8c0b768db4f2a548Sebastian Redl return Actions.ActOnCXXThis(ThisLoc); 10784cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 1079987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 1080987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// ParseCXXTypeConstructExpression - Parse construction of a specified type. 1081987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// Can be interpreted either as function-style casting ("int(x)") 1082987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// or class type construction ("ClassType(x,y,z)") 1083987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// or creation of a value-initialized type ("int()"). 1084dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl/// See [C++ 5.2.3]. 1085987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 1086987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// postfix-expression: [C++ 5.2p1] 1087dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl/// simple-type-specifier '(' expression-list[opt] ')' 1088dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl/// [C++0x] simple-type-specifier braced-init-list 1089dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl/// typename-specifier '(' expression-list[opt] ')' 1090dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl/// [C++0x] typename-specifier braced-init-list 1091987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 109260d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult 109320df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian RedlParser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { 1094987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 1095b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType TypeRep = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get(); 1096987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 1097dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl assert((Tok.is(tok::l_paren) || 1098dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl (getLang().CPlusPlus0x && Tok.is(tok::l_brace))) 1099dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl && "Expected '(' or '{'!"); 1100bc61bd8109d9accf8f966b59e3f16a1497e72adfDouglas Gregor 1101dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl if (Tok.is(tok::l_brace)) { 1102987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 1103dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl // FIXME: Convert to a proper type construct expression. 1104dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl return ParseBraceInitializer(); 1105987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 1106dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl } else { 1107dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl GreaterThanIsOperatorScope G(GreaterThanIsOperator, true); 1108dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl 11094a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 11104a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 1111dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl 1112dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl ExprVector Exprs(Actions); 1113dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl CommaLocsTy CommaLocs; 1114dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl 1115dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl if (Tok.isNot(tok::r_paren)) { 1116dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl if (ParseExpressionList(Exprs, CommaLocs)) { 1117dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl SkipUntil(tok::r_paren); 1118dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl return ExprError(); 1119dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl } 1120987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 1121987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 1122dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl // Match the ')'. 11234a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 1124987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 1125dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl // TypeRep could be null, if it references an invalid typedef. 1126dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl if (!TypeRep) 1127dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl return ExprError(); 1128ef0cb8e62d090ad88a01ca9fa89e48d7416f0ac7Sebastian Redl 1129dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&& 1130dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl "Unexpected number of commas!"); 11314a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor return Actions.ActOnCXXTypeConstructExpr(TypeRep, T.getOpenLocation(), 11324a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor move_arg(Exprs), 11334a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()); 1134dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl } 1135987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis} 1136987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis 113799e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor/// ParseCXXCondition - if/switch/while condition expression. 113871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// 113971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// condition: 114071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// expression 114171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// type-specifier-seq declarator '=' assignment-expression 114271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 114371b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// '=' assignment-expression 114471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis/// 114599e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor/// \param ExprResult if the condition was parsed as an expression, the 114699e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor/// parsed expression. 114799e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor/// 114899e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor/// \param DeclResult if the condition was parsed as a declaration, the 114999e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor/// parsed declaration. 115099e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor/// 1151586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor/// \param Loc The location of the start of the statement that requires this 1152586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor/// condition, e.g., the "for" in a for loop. 1153586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor/// 1154586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor/// \param ConvertToBoolean Whether the condition expression should be 1155586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor/// converted to a boolean value. 1156586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor/// 115799e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor/// \returns true if there was a parsing, false otherwise. 115860d7b3a319d84d688752be3870615ac0f111fb16John McCallbool Parser::ParseCXXCondition(ExprResult &ExprOut, 115960d7b3a319d84d688752be3870615ac0f111fb16John McCall Decl *&DeclOut, 1160586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor SourceLocation Loc, 1161586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor bool ConvertToBoolean) { 116201dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor if (Tok.is(tok::code_completion)) { 1163f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Condition); 11647d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis cutOffParsing(); 11657d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis return true; 116601dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor } 116701dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor 116899e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor if (!isCXXConditionDeclaration()) { 1169586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor // Parse the expression. 117060d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprOut = ParseExpression(); // expression 117160d7b3a319d84d688752be3870615ac0f111fb16John McCall DeclOut = 0; 117260d7b3a319d84d688752be3870615ac0f111fb16John McCall if (ExprOut.isInvalid()) 1173586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor return true; 1174586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor 1175586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor // If required, convert to a boolean value. 1176586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor if (ConvertToBoolean) 117760d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprOut 117860d7b3a319d84d688752be3870615ac0f111fb16John McCall = Actions.ActOnBooleanCondition(getCurScope(), Loc, ExprOut.get()); 117960d7b3a319d84d688752be3870615ac0f111fb16John McCall return ExprOut.isInvalid(); 118099e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor } 118171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 118271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // type-specifier-seq 11830b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall DeclSpec DS(AttrFactory); 118471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis ParseSpecifierQualifierList(DS); 118571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 118671b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // declarator 118771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::ConditionContext); 118871b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 118971b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 119071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // simple-asm-expr[opt] 119171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis if (Tok.is(tok::kw_asm)) { 1192ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl SourceLocation Loc; 119360d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult AsmLabel(ParseSimpleAsm(&Loc)); 11940e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (AsmLabel.isInvalid()) { 119571b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis SkipUntil(tok::semi); 119699e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor return true; 119771b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis } 1198effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl DeclaratorInfo.setAsmLabel(AsmLabel.release()); 1199ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl DeclaratorInfo.SetRangeEnd(Loc); 120071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis } 120171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 120271b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // If attributes are present, parse them. 12037f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseGNUAttributes(DeclaratorInfo); 120471b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 120599e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor // Type-check the declaration itself. 120660d7b3a319d84d688752be3870615ac0f111fb16John McCall DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(getCurScope(), 12077f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall DeclaratorInfo); 120860d7b3a319d84d688752be3870615ac0f111fb16John McCall DeclOut = Dcl.get(); 120960d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprOut = ExprError(); 1210a6eb5f81d13bacac01faff70a947047725b4413fArgyrios Kyrtzidis 121171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis // '=' assignment-expression 1212a6eb5f81d13bacac01faff70a947047725b4413fArgyrios Kyrtzidis if (isTokenEqualOrMistypedEqualEqual( 1213a6eb5f81d13bacac01faff70a947047725b4413fArgyrios Kyrtzidis diag::err_invalid_equalequal_after_declarator)) { 1214dec0984fce504a39a7f085774fb67cfd9957be58Jeffrey Yasskin ConsumeToken(); 121560d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult AssignExpr(ParseAssignmentExpression()); 121699e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor if (!AssignExpr.isInvalid()) 121734b41d939a1328f484511c6002ba2456db879a29Richard Smith Actions.AddInitializerToDecl(DeclOut, AssignExpr.take(), false, 121834b41d939a1328f484511c6002ba2456db879a29Richard Smith DS.getTypeSpecType() == DeclSpec::TST_auto); 121999e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor } else { 122099e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor // FIXME: C++0x allows a braced-init-list 122199e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor Diag(Tok, diag::err_expected_equal_after_declarator); 122299e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor } 122399e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor 1224586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor // FIXME: Build a reference to this declaration? Convert it to bool? 1225586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor // (This is currently handled by Sema). 1226483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith 1227483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith Actions.FinalizeDeclaration(DeclOut); 1228586596fd7f7a336a2847b300c80614dcf39ab6d5Douglas Gregor 122999e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor return false; 123071b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis} 123171b914b999d9c4b6df11068fc5a3291ac4770492Argyrios Kyrtzidis 12326aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor/// \brief Determine whether the current token starts a C++ 12336aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor/// simple-type-specifier. 12346aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregorbool Parser::isCXXSimpleTypeSpecifier() const { 12356aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor switch (Tok.getKind()) { 12366aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::annot_typename: 12376aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_short: 12386aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_long: 1239338d7f7362d18fa9c39c6bb5282b4e20574a9309Francois Pichet case tok::kw___int64: 12406aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_signed: 12416aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_unsigned: 12426aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_void: 12436aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_char: 12446aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_int: 1245aa4a99b4a62615db243f7a5c433169f2fc704420Anton Korobeynikov case tok::kw_half: 12466aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_float: 12476aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_double: 12486aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_wchar_t: 12496aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_char16_t: 12506aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_char32_t: 12516aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_bool: 1252d9d75e57dfa22366c0379c92beac1db82db34e9aDouglas Gregor case tok::kw_decltype: 12536aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor case tok::kw_typeof: 1254db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt case tok::kw___underlying_type: 12556aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor return true; 12566aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor 12576aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor default: 12586aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor break; 12596aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor } 12606aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor 12616aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor return false; 12626aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor} 12636aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor 1264987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers. 1265987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// This should only be called when the current token is known to be part of 1266987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// simple-type-specifier. 1267987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 1268987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// simple-type-specifier: 1269eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis/// '::'[opt] nested-name-specifier[opt] type-name 1270987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// '::'[opt] nested-name-specifier 'template' simple-template-id [TODO] 1271987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// char 1272987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// wchar_t 1273987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// bool 1274987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// short 1275987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// int 1276987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// long 1277987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// signed 1278987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// unsigned 1279987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// float 1280987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// double 1281987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// void 1282987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// [GNU] typeof-specifier 1283987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// [C++0x] auto [TODO] 1284987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 1285987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// type-name: 1286987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// class-name 1287987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// enum-name 1288987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// typedef-name 1289987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis/// 1290987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidisvoid Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { 1291987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis DS.SetRangeStart(Tok.getLocation()); 1292987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis const char *PrevSpec; 1293fec54013fcd0eb72642741584ca04c1bc292bef8John McCall unsigned DiagID; 1294987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis SourceLocation Loc = Tok.getLocation(); 12951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1296987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis switch (Tok.getKind()) { 129755a7cefc846765ac7d142a63f773747a20518d71Chris Lattner case tok::identifier: // foo::bar 129855a7cefc846765ac7d142a63f773747a20518d71Chris Lattner case tok::coloncolon: // ::foo::bar 1299b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Annotation token should already be formed!"); 13001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump default: 1301b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Not a simple-type-specifier token!"); 130255a7cefc846765ac7d142a63f773747a20518d71Chris Lattner 1303987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // type-name 1304b31757b68afe06ba442a05775d08fe7aa0f6f889Chris Lattner case tok::annot_typename: { 13056952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor if (getTypeAnnotation(Tok)) 13066952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, 13076952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor getTypeAnnotation(Tok)); 13086952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor else 13096952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor DS.SetTypeSpecError(); 13109bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor 13119bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 13129bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor ConsumeToken(); 13139bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor 13149bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id' 13159bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an 13169bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor // Objective-C interface. If we don't have Objective-C or a '<', this is 13179bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor // just a normal reference to a typedef name. 13189bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor if (Tok.is(tok::less) && getLang().ObjC1) 13199bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor ParseObjCProtocolQualifiers(DS); 13209bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor 13219bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor DS.Finish(Diags, PP); 13229bd1d8d174a9d15ae343246c8322299248b9e92aDouglas Gregor return; 1323987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 13241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1325987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // builtin types 1326987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_short: 1327fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, DiagID); 1328987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 1329987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_long: 1330fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec, DiagID); 1331338d7f7362d18fa9c39c6bb5282b4e20574a9309Francois Pichet break; 1332338d7f7362d18fa9c39c6bb5282b4e20574a9309Francois Pichet case tok::kw___int64: 1333338d7f7362d18fa9c39c6bb5282b4e20574a9309Francois Pichet DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec, DiagID); 1334987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 1335987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_signed: 1336fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec, DiagID); 1337987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 1338987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_unsigned: 1339fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec, DiagID); 1340987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 1341987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_void: 1342fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, DiagID); 1343987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 1344987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_char: 1345fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, DiagID); 1346987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 1347987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_int: 1348fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID); 1349987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 1350aa4a99b4a62615db243f7a5c433169f2fc704420Anton Korobeynikov case tok::kw_half: 1351aa4a99b4a62615db243f7a5c433169f2fc704420Anton Korobeynikov DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec, DiagID); 1352aa4a99b4a62615db243f7a5c433169f2fc704420Anton Korobeynikov break; 1353987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_float: 1354fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, DiagID); 1355987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 1356987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_double: 1357fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, DiagID); 1358987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 1359987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_wchar_t: 1360fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID); 1361987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 1362f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith case tok::kw_char16_t: 1363fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, DiagID); 1364f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith break; 1365f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith case tok::kw_char32_t: 1366fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, DiagID); 1367f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith break; 1368987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_bool: 1369fec54013fcd0eb72642741584ca04c1bc292bef8John McCall DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID); 1370987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis break; 13711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13726aa14d832704ae176c92d4e0f22dfb3f3d83a70aDouglas Gregor // FIXME: C++0x decltype support. 1373987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis // GNU typeof support. 1374987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis case tok::kw_typeof: 1375987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis ParseTypeofSpecifier(DS); 13769b3064b55f3c858923734e8b1c9831777fc22554Douglas Gregor DS.Finish(Diags, PP); 1377987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis return; 1378987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis } 1379b31757b68afe06ba442a05775d08fe7aa0f6f889Chris Lattner if (Tok.is(tok::annot_typename)) 1380eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 1381eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis else 1382eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis DS.SetRangeEnd(Tok.getLocation()); 1383987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis ConsumeToken(); 13849b3064b55f3c858923734e8b1c9831777fc22554Douglas Gregor DS.Finish(Diags, PP); 1385987a14bf5883ef6e5d07f1c83eb6d41a8212a78cArgyrios Kyrtzidis} 13861cd1b1e987f5e2f060d7972b13d83239b36d77d6Douglas Gregor 13872f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++ 13882f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// [dcl.name]), which is a non-empty sequence of type-specifiers, 13892f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// e.g., "const short int". Note that the DeclSpec is *not* finished 13902f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// by parsing the type-specifier-seq, because these sequences are 13912f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// typically followed by some form of declarator. Returns true and 13922f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// emits diagnostics if this is not a type-specifier-seq, false 13932f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// otherwise. 13942f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 13952f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// type-specifier-seq: [C++ 8.1] 13962f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// type-specifier type-specifier-seq[opt] 13972f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor/// 13982f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregorbool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) { 13992f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor DS.SetRangeStart(Tok.getLocation()); 14002f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor const char *PrevSpec = 0; 1401fec54013fcd0eb72642741584ca04c1bc292bef8John McCall unsigned DiagID; 1402fec54013fcd0eb72642741584ca04c1bc292bef8John McCall bool isInvalid = 0; 14032f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 14042f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor // Parse one or more of the type specifiers. 1405d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl if (!ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID, 1406d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl ParsedTemplateInfo(), /*SuppressDeclarations*/true)) { 14079fa8e569407e02148888136609431a3fe083096dNick Lewycky Diag(Tok, diag::err_expected_type); 14082f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return true; 14092f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor } 14101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1411d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl while (ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID, 1412d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl ParsedTemplateInfo(), /*SuppressDeclarations*/true)) 1413d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl {} 14142f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 1415396a9f235e160093b5f803f7a6a18fad7b68bdbeDouglas Gregor DS.Finish(Diags, PP); 14162f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor return false; 14172f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor} 14182f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor 14193f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \brief Finish parsing a C++ unqualified-id that is a template-id of 14203f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// some form. 14213f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 14223f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// This routine is invoked when a '<' is encountered after an identifier or 14233f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// operator-function-id is parsed by \c ParseUnqualifiedId() to determine 14243f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// whether the unqualified-id is actually a template-id. This routine will 14253f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// then parse the template arguments and form the appropriate template-id to 14263f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// return to the caller. 14273f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 14283f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \param SS the nested-name-specifier that precedes this template-id, if 14293f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// we're actually parsing a qualified-id. 14303f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 14313f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \param Name for constructor and destructor names, this is the actual 14323f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// identifier that may be a template-name. 14333f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 14343f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \param NameLoc the location of the class-name in a constructor or 14353f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// destructor. 14363f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 14373f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \param EnteringContext whether we're entering the scope of the 14383f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// nested-name-specifier. 14393f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 144046df8cc349096f141c841dbffaa72641ff1dd94bDouglas Gregor/// \param ObjectType if this unqualified-id occurs within a member access 144146df8cc349096f141c841dbffaa72641ff1dd94bDouglas Gregor/// expression, the type of the base object whose member is being accessed. 144246df8cc349096f141c841dbffaa72641ff1dd94bDouglas Gregor/// 14433f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \param Id as input, describes the template-name or operator-function-id 14443f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// that precedes the '<'. If template arguments were parsed successfully, 14453f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// will be updated with the template-id. 14463f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 1447d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// \param AssumeTemplateId When true, this routine will assume that the name 1448d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// refers to a template without performing name lookup to verify. 1449d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor/// 14503f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \returns true if a parse error occurred, false otherwise. 14513f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregorbool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, 14523f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor IdentifierInfo *Name, 14533f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor SourceLocation NameLoc, 14543f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor bool EnteringContext, 1455b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType ObjectType, 1456d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor UnqualifiedId &Id, 14570278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor bool AssumeTemplateId, 14580278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor SourceLocation TemplateKWLoc) { 14590278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor assert((AssumeTemplateId || Tok.is(tok::less)) && 14600278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor "Expected '<' to finish parsing a template-id"); 14613f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 14623f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor TemplateTy Template; 14633f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor TemplateNameKind TNK = TNK_Non_template; 14643f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor switch (Id.getKind()) { 14653f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor case UnqualifiedId::IK_Identifier: 1466014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor case UnqualifiedId::IK_OperatorFunctionId: 1467e6252d1587f98dbac704178e7b2ce53116048310Sean Hunt case UnqualifiedId::IK_LiteralOperatorId: 1468d4dca08d6b7ed2e3e3718caa6fd735960b135e9aDouglas Gregor if (AssumeTemplateId) { 146923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor TNK = Actions.ActOnDependentTemplateName(getCurScope(), TemplateKWLoc, SS, 1470d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor Id, ObjectType, EnteringContext, 1471d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor Template); 1472d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor if (TNK == TNK_Non_template) 1473d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor return true; 14741fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor } else { 14751fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor bool MemberOfUnknownSpecialization; 14767c15353ccaed24f2df932571166bf305c1b98b6dAbramo Bagnara TNK = Actions.isTemplateName(getCurScope(), SS, 14777c15353ccaed24f2df932571166bf305c1b98b6dAbramo Bagnara TemplateKWLoc.isValid(), Id, 14787c15353ccaed24f2df932571166bf305c1b98b6dAbramo Bagnara ObjectType, EnteringContext, Template, 14791fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor MemberOfUnknownSpecialization); 14801fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor 14811fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor if (TNK == TNK_Non_template && MemberOfUnknownSpecialization && 14821fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor ObjectType && IsTemplateArgumentList()) { 14831fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor // We have something like t->getAs<T>(), where getAs is a 14841fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor // member of an unknown specialization. However, this will only 14851fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor // parse correctly as a template, so suggest the keyword 'template' 14861fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor // before 'getAs' and treat this as a dependent template name. 14871fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor std::string Name; 14881fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor if (Id.getKind() == UnqualifiedId::IK_Identifier) 14891fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor Name = Id.Identifier->getName(); 14901fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor else { 14911fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor Name = "operator "; 14921fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor if (Id.getKind() == UnqualifiedId::IK_OperatorFunctionId) 14931fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor Name += getOperatorSpelling(Id.OperatorFunctionId.Operator); 14941fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor else 14951fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor Name += Id.Identifier->getName(); 14961fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor } 14971fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor Diag(Id.StartLocation, diag::err_missing_dependent_template_keyword) 14981fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor << Name 14991fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor << FixItHint::CreateInsertion(Id.StartLocation, "template "); 150023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor TNK = Actions.ActOnDependentTemplateName(getCurScope(), TemplateKWLoc, 1501d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor SS, Id, ObjectType, 1502d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor EnteringContext, Template); 1503d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor if (TNK == TNK_Non_template) 15041fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor return true; 15051fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor } 15061fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor } 15073f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor break; 15083f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 1509014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor case UnqualifiedId::IK_ConstructorName: { 1510014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor UnqualifiedId TemplateName; 15111fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor bool MemberOfUnknownSpecialization; 1512014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor TemplateName.setIdentifier(Name, NameLoc); 15137c15353ccaed24f2df932571166bf305c1b98b6dAbramo Bagnara TNK = Actions.isTemplateName(getCurScope(), SS, TemplateKWLoc.isValid(), 15147c15353ccaed24f2df932571166bf305c1b98b6dAbramo Bagnara TemplateName, ObjectType, 15151fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor EnteringContext, Template, 15161fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor MemberOfUnknownSpecialization); 15173f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor break; 1518014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor } 15193f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 1520014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor case UnqualifiedId::IK_DestructorName: { 1521014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor UnqualifiedId TemplateName; 15221fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor bool MemberOfUnknownSpecialization; 1523014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor TemplateName.setIdentifier(Name, NameLoc); 15242d1c21414199a7452f122598189363a3922605b1Douglas Gregor if (ObjectType) { 152523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor TNK = Actions.ActOnDependentTemplateName(getCurScope(), TemplateKWLoc, SS, 1526d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor TemplateName, ObjectType, 1527d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor EnteringContext, Template); 1528d6ab232bb3ec9847de5af06249afb63078b5f2eeDouglas Gregor if (TNK == TNK_Non_template) 15292d1c21414199a7452f122598189363a3922605b1Douglas Gregor return true; 15302d1c21414199a7452f122598189363a3922605b1Douglas Gregor } else { 15317c15353ccaed24f2df932571166bf305c1b98b6dAbramo Bagnara TNK = Actions.isTemplateName(getCurScope(), SS, TemplateKWLoc.isValid(), 15327c15353ccaed24f2df932571166bf305c1b98b6dAbramo Bagnara TemplateName, ObjectType, 15331fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor EnteringContext, Template, 15341fd6d44d7ca97631497551bbf98866263143d706Douglas Gregor MemberOfUnknownSpecialization); 15352d1c21414199a7452f122598189363a3922605b1Douglas Gregor 1536b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall if (TNK == TNK_Non_template && !Id.DestructorName.get()) { 1537124b878dba5007df0a268ea128a6ad8dc5dd2c5eDouglas Gregor Diag(NameLoc, diag::err_destructor_template_id) 1538124b878dba5007df0a268ea128a6ad8dc5dd2c5eDouglas Gregor << Name << SS.getRange(); 15392d1c21414199a7452f122598189363a3922605b1Douglas Gregor return true; 15402d1c21414199a7452f122598189363a3922605b1Douglas Gregor } 15412d1c21414199a7452f122598189363a3922605b1Douglas Gregor } 15423f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor break; 1543014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor } 15443f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 15453f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor default: 15463f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return false; 15473f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor } 15483f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 15493f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor if (TNK == TNK_Non_template) 15503f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return false; 15513f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 15523f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // Parse the enclosed template argument list. 15533f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor SourceLocation LAngleLoc, RAngleLoc; 15543f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor TemplateArgList TemplateArgs; 15550278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor if (Tok.is(tok::less) && 15560278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor ParseTemplateIdAfterTemplateName(Template, Id.StartLocation, 1557059101f922de6eb765601459925f4c8914420b23Douglas Gregor SS, true, LAngleLoc, 15583f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor TemplateArgs, 15593f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor RAngleLoc)) 15603f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return true; 15613f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 15623f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor if (Id.getKind() == UnqualifiedId::IK_Identifier || 1563e6252d1587f98dbac704178e7b2ce53116048310Sean Hunt Id.getKind() == UnqualifiedId::IK_OperatorFunctionId || 1564e6252d1587f98dbac704178e7b2ce53116048310Sean Hunt Id.getKind() == UnqualifiedId::IK_LiteralOperatorId) { 15653f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // Form a parsed representation of the template-id to be stored in the 15663f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // UnqualifiedId. 15673f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor TemplateIdAnnotation *TemplateId 15683f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor = TemplateIdAnnotation::Allocate(TemplateArgs.size()); 15693f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 15703f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor if (Id.getKind() == UnqualifiedId::IK_Identifier) { 15713f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor TemplateId->Name = Id.Identifier; 1572014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor TemplateId->Operator = OO_None; 15733f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor TemplateId->TemplateNameLoc = Id.StartLocation; 15743f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor } else { 1575014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor TemplateId->Name = 0; 1576014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor TemplateId->Operator = Id.OperatorFunctionId.Operator; 1577014e88d94ff83e3aad4e33b16413a2d1817ec208Douglas Gregor TemplateId->TemplateNameLoc = Id.StartLocation; 15783f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor } 15793f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 1580059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateId->SS = SS; 15812b5289b6fd7e3d9899868410a498c081c9595662John McCall TemplateId->Template = Template; 15823f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor TemplateId->Kind = TNK; 15833f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor TemplateId->LAngleLoc = LAngleLoc; 15843f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor TemplateId->RAngleLoc = RAngleLoc; 1585314b97f8c564b465af605efaee23f91ec18a982bDouglas Gregor ParsedTemplateArgument *Args = TemplateId->getTemplateArgs(); 15863f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); 1587314b97f8c564b465af605efaee23f91ec18a982bDouglas Gregor Arg != ArgEnd; ++Arg) 15883f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor Args[Arg] = TemplateArgs[Arg]; 15893f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 15903f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor Id.setTemplateId(TemplateId); 15913f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return false; 15923f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor } 15933f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 15943f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // Bundle the template arguments together. 15953f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor ASTTemplateArgsPtr TemplateArgsPtr(Actions, TemplateArgs.data(), 15963f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor TemplateArgs.size()); 15973f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 15983f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // Constructor and destructor names. 1599f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TypeResult Type 1600059101f922de6eb765601459925f4c8914420b23Douglas Gregor = Actions.ActOnTemplateIdType(SS, Template, NameLoc, 16013f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor LAngleLoc, TemplateArgsPtr, 16023f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor RAngleLoc); 16033f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor if (Type.isInvalid()) 16043f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return true; 16053f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 16063f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor if (Id.getKind() == UnqualifiedId::IK_ConstructorName) 16073f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor Id.setConstructorName(Type.get(), NameLoc, RAngleLoc); 16083f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor else 16093f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor Id.setDestructorName(Id.StartLocation, Type.get(), RAngleLoc); 16103f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 16113f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return false; 16123f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor} 16133f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 1614ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// \brief Parse an operator-function-id or conversion-function-id as part 1615ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// of a C++ unqualified-id. 16163f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 1617ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// This routine is responsible only for parsing the operator-function-id or 1618ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// conversion-function-id; it does not handle template arguments in any way. 16193f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 1620ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// \code 16213f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// operator-function-id: [C++ 13.5] 16223f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 'operator' operator 16233f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 1624ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// operator: one of 16253f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// new delete new[] delete[] 16263f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// + - * / % ^ & | ~ 16273f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// ! = < > += -= *= /= %= 16283f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// ^= &= |= << >> >>= <<= == != 16293f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// <= >= && || ++ -- , ->* -> 16303f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// () [] 16313f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 16323f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// conversion-function-id: [C++ 12.3.2] 16333f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// operator conversion-type-id 16343f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 16353f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// conversion-type-id: 16363f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// type-specifier-seq conversion-declarator[opt] 16373f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 16383f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// conversion-declarator: 16393f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// ptr-operator conversion-declarator[opt] 16403f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \endcode 16413f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 16423f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \param The nested-name-specifier that preceded this unqualified-id. If 16433f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// non-empty, then we are parsing the unqualified-id of a qualified-id. 16443f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 16453f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \param EnteringContext whether we are entering the scope of the 16463f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// nested-name-specifier. 16473f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 1648ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// \param ObjectType if this unqualified-id occurs within a member access 1649ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// expression, the type of the base object whose member is being accessed. 1650ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// 1651ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// \param Result on a successful parse, contains the parsed unqualified-id. 1652ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// 1653ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// \returns true if parsing fails, false otherwise. 1654ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregorbool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, 1655b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType ObjectType, 1656ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor UnqualifiedId &Result) { 1657ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); 1658ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1659ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // Consume the 'operator' keyword. 1660ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor SourceLocation KeywordLoc = ConsumeToken(); 1661ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1662ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // Determine what kind of operator name we have. 1663ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor unsigned SymbolIdx = 0; 1664ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor SourceLocation SymbolLocations[3]; 1665ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor OverloadedOperatorKind Op = OO_None; 1666ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor switch (Tok.getKind()) { 1667ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor case tok::kw_new: 1668ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor case tok::kw_delete: { 1669ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor bool isNew = Tok.getKind() == tok::kw_new; 1670ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // Consume the 'new' or 'delete'. 1671ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor SymbolLocations[SymbolIdx++] = ConsumeToken(); 1672ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor if (Tok.is(tok::l_square)) { 16734a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor // Consume the '[' and ']'. 16744a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_square); 16754a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 16764a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 16774a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.getCloseLocation().isInvalid()) 1678ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor return true; 1679ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 16804a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SymbolLocations[SymbolIdx++] = T.getOpenLocation(); 16814a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SymbolLocations[SymbolIdx++] = T.getCloseLocation(); 1682ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor Op = isNew? OO_Array_New : OO_Array_Delete; 1683ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor } else { 1684ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor Op = isNew? OO_New : OO_Delete; 1685ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor } 1686ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor break; 1687ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor } 1688ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1689ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 1690ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor case tok::Token: \ 1691ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor SymbolLocations[SymbolIdx++] = ConsumeToken(); \ 1692ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor Op = OO_##Name; \ 1693ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor break; 1694ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) 1695ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor#include "clang/Basic/OperatorKinds.def" 1696ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1697ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor case tok::l_paren: { 16984a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor // Consume the '(' and ')'. 16994a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 17004a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 17014a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 17024a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.getCloseLocation().isInvalid()) 1703ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor return true; 1704ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 17054a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SymbolLocations[SymbolIdx++] = T.getOpenLocation(); 17064a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SymbolLocations[SymbolIdx++] = T.getCloseLocation(); 1707ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor Op = OO_Call; 1708ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor break; 1709ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor } 1710ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1711ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor case tok::l_square: { 17124a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor // Consume the '[' and ']'. 17134a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_square); 17144a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 17154a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 17164a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.getCloseLocation().isInvalid()) 1717ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor return true; 1718ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 17194a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SymbolLocations[SymbolIdx++] = T.getOpenLocation(); 17204a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SymbolLocations[SymbolIdx++] = T.getCloseLocation(); 1721ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor Op = OO_Subscript; 1722ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor break; 1723ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor } 1724ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1725ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor case tok::code_completion: { 1726ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // Code completion for the operator name. 172723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.CodeCompleteOperatorName(getCurScope()); 17287d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis cutOffParsing(); 1729ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // Don't try to parse any further. 1730ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor return true; 1731ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor } 1732ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1733ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor default: 1734ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor break; 1735ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor } 1736ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1737ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor if (Op != OO_None) { 1738ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // We have parsed an operator-function-id. 1739ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor Result.setOperatorFunctionId(KeywordLoc, Op, SymbolLocations); 1740ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor return false; 1741ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor } 17420486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt 17430486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt // Parse a literal-operator-id. 17440486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt // 17450486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt // literal-operator-id: [C++0x 13.5.8] 17460486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt // operator "" identifier 17470486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt 17480486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt if (getLang().CPlusPlus0x && Tok.is(tok::string_literal)) { 17497fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith Diag(Tok.getLocation(), diag::warn_cxx98_compat_literal_operator); 17500486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt if (Tok.getLength() != 2) 17510486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt Diag(Tok.getLocation(), diag::err_operator_string_not_empty); 17520486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt ConsumeStringToken(); 17530486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt 17540486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt if (Tok.isNot(tok::identifier)) { 17550486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt Diag(Tok.getLocation(), diag::err_expected_ident); 17560486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt return true; 17570486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt } 17580486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt 17590486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt IdentifierInfo *II = Tok.getIdentifierInfo(); 17600486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt Result.setLiteralOperatorId(II, KeywordLoc, ConsumeToken()); 17613e518bda00d710754ca077cf9be8dd821e16a854Sean Hunt return false; 17620486d746019f8310589b1f0d92edcc4bb3916b33Sean Hunt } 1763ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1764ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // Parse a conversion-function-id. 1765ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // 1766ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // conversion-function-id: [C++ 12.3.2] 1767ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // operator conversion-type-id 1768ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // 1769ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // conversion-type-id: 1770ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // type-specifier-seq conversion-declarator[opt] 1771ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // 1772ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // conversion-declarator: 1773ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // ptr-operator conversion-declarator[opt] 1774ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1775ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // Parse the type-specifier-seq. 17760b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall DeclSpec DS(AttrFactory); 1777f6e6fc801c700c7b8ac202ddbe550d9843a816fcDouglas Gregor if (ParseCXXTypeSpecifierSeq(DS)) // FIXME: ObjectType? 1778ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor return true; 1779ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1780ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // Parse the conversion-declarator, which is merely a sequence of 1781ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // ptr-operators. 1782ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor Declarator D(DS, Declarator::TypeNameContext); 1783ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor ParseDeclaratorInternal(D, /*DirectDeclParser=*/0); 1784ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1785ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // Finish up the type. 1786f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TypeResult Ty = Actions.ActOnTypeName(getCurScope(), D); 1787ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor if (Ty.isInvalid()) 1788ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor return true; 1789ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1790ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // Note that this is a conversion-function-id. 1791ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor Result.setConversionFunctionId(KeywordLoc, Ty.get(), 1792ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor D.getSourceRange().getEnd()); 1793ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor return false; 1794ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor} 1795ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor 1796ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// \brief Parse a C++ unqualified-id (or a C identifier), which describes the 1797ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// name of an entity. 1798ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// 1799ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// \code 1800ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// unqualified-id: [C++ expr.prim.general] 1801ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// identifier 1802ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// operator-function-id 1803ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// conversion-function-id 1804ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// [C++0x] literal-operator-id [TODO] 1805ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// ~ class-name 1806ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// template-id 1807ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// 1808ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// \endcode 1809ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// 1810ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// \param The nested-name-specifier that preceded this unqualified-id. If 1811ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// non-empty, then we are parsing the unqualified-id of a qualified-id. 1812ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// 1813ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// \param EnteringContext whether we are entering the scope of the 1814ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// nested-name-specifier. 1815ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor/// 18163f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \param AllowDestructorName whether we allow parsing of a destructor name. 18173f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 18183f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \param AllowConstructorName whether we allow parsing a constructor name. 18193f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 182046df8cc349096f141c841dbffaa72641ff1dd94bDouglas Gregor/// \param ObjectType if this unqualified-id occurs within a member access 182146df8cc349096f141c841dbffaa72641ff1dd94bDouglas Gregor/// expression, the type of the base object whose member is being accessed. 182246df8cc349096f141c841dbffaa72641ff1dd94bDouglas Gregor/// 18233f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \param Result on a successful parse, contains the parsed unqualified-id. 18243f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// 18253f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor/// \returns true if parsing fails, false otherwise. 18263f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregorbool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, 18273f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor bool AllowDestructorName, 18283f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor bool AllowConstructorName, 1829b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType ObjectType, 18303f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor UnqualifiedId &Result) { 18310278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor 18320278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor // Handle 'A::template B'. This is for template-ids which have not 18330278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor // already been annotated by ParseOptionalCXXScopeSpecifier(). 18340278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor bool TemplateSpecified = false; 18350278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor SourceLocation TemplateKWLoc; 18360278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor if (getLang().CPlusPlus && Tok.is(tok::kw_template) && 18370278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor (ObjectType || SS.isSet())) { 18380278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor TemplateSpecified = true; 18390278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor TemplateKWLoc = ConsumeToken(); 18400278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor } 18410278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor 18423f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // unqualified-id: 18433f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // identifier 18443f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // template-id (when it hasn't already been annotated) 18453f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor if (Tok.is(tok::identifier)) { 18463f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // Consume the identifier. 18473f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor IdentifierInfo *Id = Tok.getIdentifierInfo(); 18483f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor SourceLocation IdLoc = ConsumeToken(); 18493f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 1850b862b8f93424a583fc912ab37bbbac1c231e852eDouglas Gregor if (!getLang().CPlusPlus) { 1851b862b8f93424a583fc912ab37bbbac1c231e852eDouglas Gregor // If we're not in C++, only identifiers matter. Record the 1852b862b8f93424a583fc912ab37bbbac1c231e852eDouglas Gregor // identifier and return. 1853b862b8f93424a583fc912ab37bbbac1c231e852eDouglas Gregor Result.setIdentifier(Id, IdLoc); 1854b862b8f93424a583fc912ab37bbbac1c231e852eDouglas Gregor return false; 1855b862b8f93424a583fc912ab37bbbac1c231e852eDouglas Gregor } 1856b862b8f93424a583fc912ab37bbbac1c231e852eDouglas Gregor 18573f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor if (AllowConstructorName && 185823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.isCurrentClassName(*Id, getCurScope(), &SS)) { 18593f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // We have parsed a constructor name. 186023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Result.setConstructorName(Actions.getTypeName(*Id, IdLoc, getCurScope(), 18619e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor &SS, false, false, 18629e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor ParsedType(), 18639e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor /*NonTrivialTypeSourceInfo=*/true), 18643f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor IdLoc, IdLoc); 18653f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor } else { 18663f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // We have parsed an identifier. 18673f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor Result.setIdentifier(Id, IdLoc); 18683f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor } 18693f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 18703f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // If the next token is a '<', we may have a template. 18710278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor if (TemplateSpecified || Tok.is(tok::less)) 18723f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return ParseUnqualifiedIdTemplateId(SS, Id, IdLoc, EnteringContext, 18730278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor ObjectType, Result, 18740278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor TemplateSpecified, TemplateKWLoc); 18753f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 18763f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return false; 18773f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor } 18783f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 18793f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // unqualified-id: 18803f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // template-id (already parsed and annotated) 18813f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor if (Tok.is(tok::annot_template_id)) { 188225a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 18830efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor 18840efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor // If the template-name names the current class, then this is a constructor 18850efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor if (AllowConstructorName && TemplateId->Name && 188623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) { 18870efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor if (SS.isSet()) { 18880efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor // C++ [class.qual]p2 specifies that a qualified template-name 18890efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor // is taken as the constructor name where a constructor can be 18900efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor // declared. Thus, the template arguments are extraneous, so 18910efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor // complain about them and remove them entirely. 18920efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor Diag(TemplateId->TemplateNameLoc, 18930efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor diag::err_out_of_line_constructor_template_id) 18940efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor << TemplateId->Name 1895849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor << FixItHint::CreateRemoval( 18960efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc)); 18970efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor Result.setConstructorName(Actions.getTypeName(*TemplateId->Name, 18980efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor TemplateId->TemplateNameLoc, 189923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor getCurScope(), 19009e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor &SS, false, false, 19019e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor ParsedType(), 19029e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor /*NontrivialTypeSourceInfo=*/true), 19030efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor TemplateId->TemplateNameLoc, 19040efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor TemplateId->RAngleLoc); 19050efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor ConsumeToken(); 19060efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor return false; 19070efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor } 19080efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor 19090efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor Result.setConstructorTemplateId(TemplateId); 19100efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor ConsumeToken(); 19110efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor return false; 19120efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor } 19130efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor 19143f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // We have already parsed a template-id; consume the annotation token as 19153f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // our unqualified-id. 19160efc2c1716be4f1c5f1343cad3b047e74861f030Douglas Gregor Result.setTemplateId(TemplateId); 19173f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor ConsumeToken(); 19183f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return false; 19193f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor } 19203f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 19213f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // unqualified-id: 19223f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // operator-function-id 19233f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // conversion-function-id 19243f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor if (Tok.is(tok::kw_operator)) { 1925ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, Result)) 19263f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return true; 19273f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 1928e6252d1587f98dbac704178e7b2ce53116048310Sean Hunt // If we have an operator-function-id or a literal-operator-id and the next 1929e6252d1587f98dbac704178e7b2ce53116048310Sean Hunt // token is a '<', we may have a 1930ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // 1931ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // template-id: 1932ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor // operator-function-id < template-argument-list[opt] > 1933e6252d1587f98dbac704178e7b2ce53116048310Sean Hunt if ((Result.getKind() == UnqualifiedId::IK_OperatorFunctionId || 1934e6252d1587f98dbac704178e7b2ce53116048310Sean Hunt Result.getKind() == UnqualifiedId::IK_LiteralOperatorId) && 19350278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor (TemplateSpecified || Tok.is(tok::less))) 1936ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor return ParseUnqualifiedIdTemplateId(SS, 0, SourceLocation(), 1937ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor EnteringContext, ObjectType, 19380278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor Result, 19390278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor TemplateSpecified, TemplateKWLoc); 19403f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 19413f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return false; 19423f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor } 19433f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 1944b862b8f93424a583fc912ab37bbbac1c231e852eDouglas Gregor if (getLang().CPlusPlus && 1945b862b8f93424a583fc912ab37bbbac1c231e852eDouglas Gregor (AllowDestructorName || SS.isSet()) && Tok.is(tok::tilde)) { 19463f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // C++ [expr.unary.op]p10: 19473f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // There is an ambiguity in the unary-expression ~X(), where X is a 19483f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // class-name. The ambiguity is resolved in favor of treating ~ as a 19493f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // unary complement rather than treating ~X as referring to a destructor. 19503f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 19513f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // Parse the '~'. 19523f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor SourceLocation TildeLoc = ConsumeToken(); 19533f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 19543f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // Parse the class-name. 19553f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor if (Tok.isNot(tok::identifier)) { 1956124b878dba5007df0a268ea128a6ad8dc5dd2c5eDouglas Gregor Diag(Tok, diag::err_destructor_tilde_identifier); 19573f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return true; 19583f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor } 19593f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 19603f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // Parse the class-name (or template-name in a simple-template-id). 19613f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor IdentifierInfo *ClassName = Tok.getIdentifierInfo(); 19623f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor SourceLocation ClassNameLoc = ConsumeToken(); 19633f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 19640278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor if (TemplateSpecified || Tok.is(tok::less)) { 1965b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall Result.setDestructorName(TildeLoc, ParsedType(), ClassNameLoc); 19662d1c21414199a7452f122598189363a3922605b1Douglas Gregor return ParseUnqualifiedIdTemplateId(SS, ClassName, ClassNameLoc, 19670278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor EnteringContext, ObjectType, Result, 19680278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor TemplateSpecified, TemplateKWLoc); 19692d1c21414199a7452f122598189363a3922605b1Douglas Gregor } 19702d1c21414199a7452f122598189363a3922605b1Douglas Gregor 19713f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor // Note that this is a destructor name. 1972b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType Ty = Actions.getDestructorName(TildeLoc, *ClassName, 1973b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ClassNameLoc, getCurScope(), 1974b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall SS, ObjectType, 1975b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall EnteringContext); 1976124b878dba5007df0a268ea128a6ad8dc5dd2c5eDouglas Gregor if (!Ty) 19773f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return true; 1978124b878dba5007df0a268ea128a6ad8dc5dd2c5eDouglas Gregor 19793f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor Result.setDestructorName(TildeLoc, Ty, ClassNameLoc); 19803f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return false; 19813f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor } 19823f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 19832d1c21414199a7452f122598189363a3922605b1Douglas Gregor Diag(Tok, diag::err_expected_unqualified_id) 19842d1c21414199a7452f122598189363a3922605b1Douglas Gregor << getLang().CPlusPlus; 19853f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor return true; 19863f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor} 19873f9a0566e6793151b99a65ab936220971cf96c1bDouglas Gregor 19884c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate 19894c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// memory in a typesafe manner and call constructors. 19901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// 199159232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// This method is called to parse the new expression after the optional :: has 199259232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// been already parsed. If the :: was present, "UseGlobal" is true and "Start" 199359232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// is its location. Otherwise, "Start" is the location of the 'new' token. 19944c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 19954c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-expression: 19964c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'new' new-placement[opt] new-type-id 19974c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer[opt] 19984c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 19994c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer[opt] 20004c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 20014c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-placement: 20024c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '(' expression-list ')' 20034c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 2004cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// new-type-id: 2005cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// type-specifier-seq new-declarator[opt] 2006893e1cc13ab17e96ada5019df6978af1668fee26Douglas Gregor/// [GNU] attributes type-specifier-seq new-declarator[opt] 2007cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// 2008cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// new-declarator: 2009cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// ptr-operator new-declarator[opt] 2010cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// direct-new-declarator 2011cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl/// 20124c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer: 20134c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '(' expression-list[opt] ')' 2014dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl/// [C++0x] braced-init-list 20154c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 201660d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult 201759232d35f5820e334b6c8b007ae8006f4390055dChris LattnerParser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { 201859232d35f5820e334b6c8b007ae8006f4390055dChris Lattner assert(Tok.is(tok::kw_new) && "expected 'new' token"); 201959232d35f5820e334b6c8b007ae8006f4390055dChris Lattner ConsumeToken(); // Consume 'new' 20204c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 20214c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // A '(' now can be a new-placement or the '(' wrapping the type-id in the 20224c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // second form of new-expression. It can't be a new-type-id. 20234c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 2024a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector PlacementArgs(Actions); 20254c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation PlacementLParen, PlacementRParen; 20264c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 20274bd40318cbea15310a37343db46de96c4fcc15e6Douglas Gregor SourceRange TypeIdParens; 20280b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall DeclSpec DS(AttrFactory); 20290b8c98f3ddf83adcb9e9d98b68ce38e970cdee73Argyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::CXXNewContext); 20304c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_paren)) { 20314c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // If it turns out to be a placement, we change the type location. 20324a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 20334a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 20344a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor PlacementLParen = T.getOpenLocation(); 2035cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) { 2036cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 203720df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 2038cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 20394c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 20404a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 20414a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor PlacementRParen = T.getCloseLocation(); 2042cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (PlacementRParen.isInvalid()) { 2043cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 204420df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 2045cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 20464c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 2047cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (PlacementArgs.empty()) { 20484c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Reset the placement locations. There was no placement. 20494a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor TypeIdParens = T.getRange(); 20504c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl PlacementLParen = PlacementRParen = SourceLocation(); 20514c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } else { 20524c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // We still need the type. 20534c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_paren)) { 20544a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 20554a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 2056893e1cc13ab17e96ada5019df6978af1668fee26Douglas Gregor MaybeParseGNUAttributes(DeclaratorInfo); 2057cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseSpecifierQualifierList(DS); 2058ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 2059cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclarator(DeclaratorInfo); 20604a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 20614a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor TypeIdParens = T.getRange(); 20624c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } else { 2063893e1cc13ab17e96ada5019df6978af1668fee26Douglas Gregor MaybeParseGNUAttributes(DeclaratorInfo); 2064cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseCXXTypeSpecifierSeq(DS)) 2065cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl DeclaratorInfo.setInvalidType(true); 2066ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl else { 2067ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 2068cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclaratorInternal(DeclaratorInfo, 2069cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl &Parser::ParseDirectNewDeclarator); 2070ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl } 20714c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 20724c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 20734c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } else { 2074cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl // A new-type-id is a simplified type-id, where essentially the 2075cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl // direct-declarator is replaced by a direct-new-declarator. 2076893e1cc13ab17e96ada5019df6978af1668fee26Douglas Gregor MaybeParseGNUAttributes(DeclaratorInfo); 2077cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseCXXTypeSpecifierSeq(DS)) 2078cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl DeclaratorInfo.setInvalidType(true); 2079ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl else { 2080ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 2081cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclaratorInternal(DeclaratorInfo, 2082cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl &Parser::ParseDirectNewDeclarator); 2083ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl } 20844c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 2085eaaebc7cf10dc1a2016183a262ad3256bc468759Chris Lattner if (DeclaratorInfo.isInvalidType()) { 2086cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 208720df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 2088cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 20894c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 2090a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector ConstructorArgs(Actions); 20914c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SourceLocation ConstructorLParen, ConstructorRParen; 20924c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 20934c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_paren)) { 20944a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 20954a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 20964a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor ConstructorLParen = T.getOpenLocation(); 20974c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.isNot(tok::r_paren)) { 20984c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl CommaLocsTy CommaLocs; 2099cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ParseExpressionList(ConstructorArgs, CommaLocs)) { 2100cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 210120df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 2102cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 21034c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 21044a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 21054a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor ConstructorRParen = T.getCloseLocation(); 2106cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl if (ConstructorRParen.isInvalid()) { 2107cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 210820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 2109cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl } 211029e3a31b7cbd9f9cdf2cc857a3a805871b6f3f62Richard Smith } else if (Tok.is(tok::l_brace) && getLang().CPlusPlus0x) { 21117fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith Diag(Tok.getLocation(), 21127fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::warn_cxx98_compat_generalized_initializer_lists); 2113dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl // FIXME: Have to communicate the init-list to ActOnCXXNew. 2114dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl ParseBraceInitializer(); 21154c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 21164c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 2117f53597fb16142bdb4a66901f8c0b768db4f2a548Sebastian Redl return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen, 2118f53597fb16142bdb4a66901f8c0b768db4f2a548Sebastian Redl move_arg(PlacementArgs), PlacementRParen, 21194bd40318cbea15310a37343db46de96c4fcc15e6Douglas Gregor TypeIdParens, DeclaratorInfo, ConstructorLParen, 2120f53597fb16142bdb4a66901f8c0b768db4f2a548Sebastian Redl move_arg(ConstructorArgs), ConstructorRParen); 21214c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 21224c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 21234c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be 21244c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// passed to ParseDeclaratorInternal. 21254c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 21264c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// direct-new-declarator: 21274c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '[' expression ']' 21284c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// direct-new-declarator '[' constant-expression ']' 21294c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 213059232d35f5820e334b6c8b007ae8006f4390055dChris Lattnervoid Parser::ParseDirectNewDeclarator(Declarator &D) { 21314c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Parse the array dimensions. 21324c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool first = true; 21334c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl while (Tok.is(tok::l_square)) { 21344a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_square); 21354a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 21364a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor 213760d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult Size(first ? ParseExpression() 21382f7ece7c77eb17e24e8f0f4e1b7fb01aa5111f96Sebastian Redl : ParseConstantExpression()); 21390e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Size.isInvalid()) { 21404c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Recover 21414c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl SkipUntil(tok::r_square); 21424c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return; 21434c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 21444c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl first = false; 21454c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 21464a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 21470b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall 21480b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall ParsedAttributes attrs(AttrFactory); 21490b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall D.AddTypeInfo(DeclaratorChunk::getArray(0, 21507f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall /*static=*/false, /*star=*/false, 21514a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Size.release(), 21524a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getOpenLocation(), 21534a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()), 21544a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor attrs, T.getCloseLocation()); 21554c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 21564a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.getCloseLocation().isInvalid()) 21574c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return; 21584c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 21594c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 21604c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 21614c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id. 21624c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// This ambiguity appears in the syntax of the C++ new operator. 21634c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 21644c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-expression: 21654c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 21664c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-initializer[opt] 21674c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 21684c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// new-placement: 21694c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '(' expression-list ')' 21704c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 2171ca0408fb49c1370430672acf2d770b7151cf71deJohn McCallbool Parser::ParseExpressionListOrTypeId( 21725f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<Expr*> &PlacementArgs, 217359232d35f5820e334b6c8b007ae8006f4390055dChris Lattner Declarator &D) { 21744c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // The '(' was already consumed. 21754c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (isTypeIdInParens()) { 2176cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseSpecifierQualifierList(D.getMutableDeclSpec()); 2177ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl D.SetSourceRange(D.getDeclSpec().getSourceRange()); 2178cee63fbf0e64ac526582312bf8cf33263fc5c16eSebastian Redl ParseDeclarator(D); 2179eaaebc7cf10dc1a2016183a262ad3256bc468759Chris Lattner return D.isInvalidType(); 21804c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 21814c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 21824c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // It's not a type, it has to be an expression list. 21834c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Discard the comma locations - ActOnCXXNew has enough parameters. 21844c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl CommaLocsTy CommaLocs; 21854c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl return ParseExpressionList(PlacementArgs, CommaLocs); 21864c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 21874c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 21884c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used 21894c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// to free memory allocated by new. 21904c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// 219159232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// This method is called to parse the 'delete' expression after the optional 219259232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// '::' has been already parsed. If the '::' was present, "UseGlobal" is true 219359232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// and "Start" is its location. Otherwise, "Start" is the location of the 219459232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// 'delete' token. 219559232d35f5820e334b6c8b007ae8006f4390055dChris Lattner/// 21964c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// delete-expression: 21974c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'delete' cast-expression 21984c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl/// '::'[opt] 'delete' '[' ']' cast-expression 219960d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult 220059232d35f5820e334b6c8b007ae8006f4390055dChris LattnerParser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) { 220159232d35f5820e334b6c8b007ae8006f4390055dChris Lattner assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword"); 220259232d35f5820e334b6c8b007ae8006f4390055dChris Lattner ConsumeToken(); // Consume 'delete' 22034c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 22044c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl // Array delete? 22054c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl bool ArrayDelete = false; 22064c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl if (Tok.is(tok::l_square)) { 22074c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl ArrayDelete = true; 22084a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_square); 22094a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor 22104a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 22114a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 22124a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.getCloseLocation().isInvalid()) 221320df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return ExprError(); 22144c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl } 22154c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 221660d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult Operand(ParseCastExpression(false)); 22170e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Operand.isInvalid()) 221820df9b7ab9388b2a488c5b1293cd196b1e073b4eSebastian Redl return move(Operand); 22194c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl 22209ae2f076ca5ab1feb3ba95629099ec2319833701John McCall return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, Operand.take()); 22214c5d320a7581f4b80b151630c91cea5727fa9923Sebastian Redl} 222264b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl 22231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind) { 222464b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl switch(kind) { 2225b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable("Not a known unary type trait."); 222664b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___has_nothrow_assign: return UTT_HasNothrowAssign; 222764b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___has_nothrow_constructor: return UTT_HasNothrowConstructor; 222820c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___has_nothrow_copy: return UTT_HasNothrowCopy; 222964b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___has_trivial_assign: return UTT_HasTrivialAssign; 2230023df37c27ee8035664fb62f206ca58f4e2a169dSean Hunt case tok::kw___has_trivial_constructor: 2231023df37c27ee8035664fb62f206ca58f4e2a169dSean Hunt return UTT_HasTrivialDefaultConstructor; 223220c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___has_trivial_copy: return UTT_HasTrivialCopy; 223364b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___has_trivial_destructor: return UTT_HasTrivialDestructor; 223464b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___has_virtual_destructor: return UTT_HasVirtualDestructor; 223564b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___is_abstract: return UTT_IsAbstract; 223620c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_arithmetic: return UTT_IsArithmetic; 223720c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_array: return UTT_IsArray; 223864b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___is_class: return UTT_IsClass; 223920c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_complete_type: return UTT_IsCompleteType; 224020c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_compound: return UTT_IsCompound; 224120c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_const: return UTT_IsConst; 224264b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___is_empty: return UTT_IsEmpty; 224364b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___is_enum: return UTT_IsEnum; 22445e9392ba18f5925e26cc5714d1412eda0d219826Douglas Gregor case tok::kw___is_final: return UTT_IsFinal; 224520c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_floating_point: return UTT_IsFloatingPoint; 224620c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_function: return UTT_IsFunction; 224720c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_fundamental: return UTT_IsFundamental; 224820c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_integral: return UTT_IsIntegral; 224920c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_lvalue_reference: return UTT_IsLvalueReference; 225020c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_member_function_pointer: return UTT_IsMemberFunctionPointer; 225120c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_member_object_pointer: return UTT_IsMemberObjectPointer; 225220c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_member_pointer: return UTT_IsMemberPointer; 225320c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_object: return UTT_IsObject; 22544e61ddd644e9c6293697a966d98d7c1905cf63a8Chandler Carruth case tok::kw___is_literal: return UTT_IsLiteral; 22553840281126e7d10552c55f6fd8b1ec9483898906Chandler Carruth case tok::kw___is_literal_type: return UTT_IsLiteral; 225664b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___is_pod: return UTT_IsPOD; 225720c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_pointer: return UTT_IsPointer; 225864b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___is_polymorphic: return UTT_IsPolymorphic; 225920c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_reference: return UTT_IsReference; 226020c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_rvalue_reference: return UTT_IsRvalueReference; 226120c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_scalar: return UTT_IsScalar; 226220c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_signed: return UTT_IsSigned; 226320c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_standard_layout: return UTT_IsStandardLayout; 226420c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_trivial: return UTT_IsTrivial; 2265feb375d31b7e9108b04a9f55b721d5e0c793a558Sean Hunt case tok::kw___is_trivially_copyable: return UTT_IsTriviallyCopyable; 226664b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl case tok::kw___is_union: return UTT_IsUnion; 226720c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_unsigned: return UTT_IsUnsigned; 226820c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_void: return UTT_IsVoid; 226920c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_volatile: return UTT_IsVolatile; 227064b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl } 22716ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet} 22726ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet 22736ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichetstatic BinaryTypeTrait BinaryTypeTraitFromTokKind(tok::TokenKind kind) { 22746ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet switch(kind) { 227538c2b730a8553fa1cf369d0c5567f8b5d0a3dda8Francois Pichet default: llvm_unreachable("Not a known binary type trait"); 2276f187237d916afa97c491ac32fe98be7d335c5b63Francois Pichet case tok::kw___is_base_of: return BTT_IsBaseOf; 227720c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_convertible: return BTT_IsConvertible; 227820c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley case tok::kw___is_same: return BTT_IsSame; 2279f187237d916afa97c491ac32fe98be7d335c5b63Francois Pichet case tok::kw___builtin_types_compatible_p: return BTT_TypeCompatible; 22809f3611365d0f2297a910cf246e056708726ed10aDouglas Gregor case tok::kw___is_convertible_to: return BTT_IsConvertibleTo; 22816ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet } 228264b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl} 228364b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl 228421ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegleystatic ArrayTypeTrait ArrayTypeTraitFromTokKind(tok::TokenKind kind) { 228521ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley switch(kind) { 228621ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley default: llvm_unreachable("Not a known binary type trait"); 228721ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley case tok::kw___array_rank: return ATT_ArrayRank; 228821ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley case tok::kw___array_extent: return ATT_ArrayExtent; 228921ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley } 229021ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley} 229121ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley 2292552622067dc45013d240f73952fece703f5e63bdJohn Wiegleystatic ExpressionTrait ExpressionTraitFromTokKind(tok::TokenKind kind) { 2293552622067dc45013d240f73952fece703f5e63bdJohn Wiegley switch(kind) { 2294b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie default: llvm_unreachable("Not a known unary expression trait."); 2295552622067dc45013d240f73952fece703f5e63bdJohn Wiegley case tok::kw___is_lvalue_expr: return ET_IsLValueExpr; 2296552622067dc45013d240f73952fece703f5e63bdJohn Wiegley case tok::kw___is_rvalue_expr: return ET_IsRValueExpr; 2297552622067dc45013d240f73952fece703f5e63bdJohn Wiegley } 2298552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 2299552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 230064b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl/// ParseUnaryTypeTrait - Parse the built-in unary type-trait 230164b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl/// pseudo-functions that allow implementation of the TR1/C++0x type traits 230264b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl/// templates. 230364b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl/// 230464b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl/// primary-expression: 230564b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl/// [GNU] unary-type-trait '(' type-id ')' 230664b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl/// 230760d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Parser::ParseUnaryTypeTrait() { 230864b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl UnaryTypeTrait UTT = UnaryTypeTraitFromTokKind(Tok.getKind()); 230964b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl SourceLocation Loc = ConsumeToken(); 231064b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl 23114a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 23124a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.expectAndConsume(diag::err_expected_lparen)) 231364b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl return ExprError(); 231464b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl 231564b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl // FIXME: Error reporting absolutely sucks! If the this fails to parse a type 231664b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl // there will be cryptic errors about mismatched parentheses and missing 231764b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl // specifiers. 2318809070a886684cb5b92eb0e00a6581ab1fa6b17aDouglas Gregor TypeResult Ty = ParseTypeName(); 231964b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl 23204a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 232164b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl 2322809070a886684cb5b92eb0e00a6581ab1fa6b17aDouglas Gregor if (Ty.isInvalid()) 2323809070a886684cb5b92eb0e00a6581ab1fa6b17aDouglas Gregor return ExprError(); 2324809070a886684cb5b92eb0e00a6581ab1fa6b17aDouglas Gregor 23254a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor return Actions.ActOnUnaryTypeTrait(UTT, Loc, Ty.get(), T.getCloseLocation()); 232664b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl} 2327f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis 23286ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet/// ParseBinaryTypeTrait - Parse the built-in binary type-trait 23296ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet/// pseudo-functions that allow implementation of the TR1/C++0x type traits 23306ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet/// templates. 23316ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet/// 23326ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet/// primary-expression: 23336ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet/// [GNU] binary-type-trait '(' type-id ',' type-id ')' 23346ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet/// 23356ad6f2848d7652ab2991286eb48be440d3493b28Francois PichetExprResult Parser::ParseBinaryTypeTrait() { 23366ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet BinaryTypeTrait BTT = BinaryTypeTraitFromTokKind(Tok.getKind()); 23376ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet SourceLocation Loc = ConsumeToken(); 23386ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet 23394a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 23404a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.expectAndConsume(diag::err_expected_lparen)) 23416ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet return ExprError(); 23426ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet 23436ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet TypeResult LhsTy = ParseTypeName(); 23446ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet if (LhsTy.isInvalid()) { 23456ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet SkipUntil(tok::r_paren); 23466ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet return ExprError(); 23476ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet } 23486ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet 23496ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet if (ExpectAndConsume(tok::comma, diag::err_expected_comma)) { 23506ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet SkipUntil(tok::r_paren); 23516ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet return ExprError(); 23526ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet } 23536ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet 23546ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet TypeResult RhsTy = ParseTypeName(); 23556ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet if (RhsTy.isInvalid()) { 23566ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet SkipUntil(tok::r_paren); 23576ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet return ExprError(); 23586ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet } 23596ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet 23604a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 23616ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet 23624a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor return Actions.ActOnBinaryTypeTrait(BTT, Loc, LhsTy.get(), RhsTy.get(), 23634a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()); 23646ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet} 23656ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet 236621ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley/// ParseArrayTypeTrait - Parse the built-in array type-trait 236721ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley/// pseudo-functions. 236821ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley/// 236921ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley/// primary-expression: 237021ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley/// [Embarcadero] '__array_rank' '(' type-id ')' 237121ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley/// [Embarcadero] '__array_extent' '(' type-id ',' expression ')' 237221ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley/// 237321ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John WiegleyExprResult Parser::ParseArrayTypeTrait() { 237421ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley ArrayTypeTrait ATT = ArrayTypeTraitFromTokKind(Tok.getKind()); 237521ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley SourceLocation Loc = ConsumeToken(); 237621ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley 23774a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 23784a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.expectAndConsume(diag::err_expected_lparen)) 237921ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley return ExprError(); 238021ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley 238121ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley TypeResult Ty = ParseTypeName(); 238221ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley if (Ty.isInvalid()) { 238321ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley SkipUntil(tok::comma); 238421ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley SkipUntil(tok::r_paren); 238521ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley return ExprError(); 238621ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley } 238721ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley 238821ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley switch (ATT) { 238921ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley case ATT_ArrayRank: { 23904a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 23914a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), NULL, 23924a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()); 239321ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley } 239421ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley case ATT_ArrayExtent: { 239521ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley if (ExpectAndConsume(tok::comma, diag::err_expected_comma)) { 239621ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley SkipUntil(tok::r_paren); 239721ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley return ExprError(); 239821ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley } 239921ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley 240021ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley ExprResult DimExpr = ParseExpression(); 24014a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 240221ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley 24034a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), DimExpr.get(), 24044a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()); 240521ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley } 240621ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley default: 240721ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley break; 240821ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley } 240921ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley return ExprError(); 241021ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley} 241121ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley 2412552622067dc45013d240f73952fece703f5e63bdJohn Wiegley/// ParseExpressionTrait - Parse built-in expression-trait 2413552622067dc45013d240f73952fece703f5e63bdJohn Wiegley/// pseudo-functions like __is_lvalue_expr( xxx ). 2414552622067dc45013d240f73952fece703f5e63bdJohn Wiegley/// 2415552622067dc45013d240f73952fece703f5e63bdJohn Wiegley/// primary-expression: 2416552622067dc45013d240f73952fece703f5e63bdJohn Wiegley/// [Embarcadero] expression-trait '(' expression ')' 2417552622067dc45013d240f73952fece703f5e63bdJohn Wiegley/// 2418552622067dc45013d240f73952fece703f5e63bdJohn WiegleyExprResult Parser::ParseExpressionTrait() { 2419552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ExpressionTrait ET = ExpressionTraitFromTokKind(Tok.getKind()); 2420552622067dc45013d240f73952fece703f5e63bdJohn Wiegley SourceLocation Loc = ConsumeToken(); 2421552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 24224a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 24234a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.expectAndConsume(diag::err_expected_lparen)) 2424552622067dc45013d240f73952fece703f5e63bdJohn Wiegley return ExprError(); 2425552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 2426552622067dc45013d240f73952fece703f5e63bdJohn Wiegley ExprResult Expr = ParseExpression(); 2427552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 24284a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 2429552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 24304a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor return Actions.ActOnExpressionTrait(ET, Loc, Expr.get(), 24314a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()); 2432552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 2433552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 2434552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 2435f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis/// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a 2436f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis/// parenthesized ambiguous type-id. This uses tentative parsing to disambiguate 2437f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis/// based on the context past the parens. 243860d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult 2439f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios KyrtzidisParser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, 2440b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType &CastTy, 24414a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker &Tracker) { 2442f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis assert(getLang().CPlusPlus && "Should only be called for C++!"); 2443f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis assert(ExprType == CastExpr && "Compound literals are not ambiguous!"); 2444f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis assert(isTypeIdInParens() && "Not a type-id!"); 2445f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis 244660d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult Result(true); 2447b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall CastTy = ParsedType(); 2448f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis 2449f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // We need to disambiguate a very ugly part of the C++ syntax: 2450f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // 2451f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // (T())x; - type-id 2452f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // (T())*x; - type-id 2453f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // (T())/x; - expression 2454f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // (T()); - expression 2455f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // 2456f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // The bad news is that we cannot use the specialized tentative parser, since 2457f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // it can only verify that the thing inside the parens can be parsed as 2458f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // type-id, it is not useful for determining the context past the parens. 2459f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // 2460f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // The good news is that the parser can disambiguate this part without 2461a558a897cbe83a21914058348ffbdcf827530ad4Argyrios Kyrtzidis // making any unnecessary Action calls. 2462f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // 2463f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // It uses a scheme similar to parsing inline methods. The parenthesized 2464f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // tokens are cached, the context that follows is determined (possibly by 2465f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // parsing a cast-expression), and then we re-introduce the cached tokens 2466f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // into the token stream and parse them appropriately. 2467f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis 24681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ParenParseOption ParseAs; 2469f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis CachedTokens Toks; 2470f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis 2471f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // Store the tokens of the parentheses. We will parse them after we determine 2472f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // the context that follows them. 247314b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis if (!ConsumeAndStoreUntil(tok::r_paren, Toks)) { 2474f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // We didn't find the ')' we expected. 24754a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Tracker.consumeClose(); 2476f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis return ExprError(); 2477f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis } 2478f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis 2479f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis if (Tok.is(tok::l_brace)) { 2480f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis ParseAs = CompoundLiteral; 2481f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis } else { 2482f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis bool NotCastExpr; 2483b53f08ac87f1e1f4bc2fbfa4560c2183a82020eeEli Friedman // FIXME: Special-case ++ and --: "(S())++;" is not a cast-expression 2484b53f08ac87f1e1f4bc2fbfa4560c2183a82020eeEli Friedman if (Tok.is(tok::l_paren) && NextToken().is(tok::r_paren)) { 2485b53f08ac87f1e1f4bc2fbfa4560c2183a82020eeEli Friedman NotCastExpr = true; 2486b53f08ac87f1e1f4bc2fbfa4560c2183a82020eeEli Friedman } else { 2487b53f08ac87f1e1f4bc2fbfa4560c2183a82020eeEli Friedman // Try parsing the cast-expression that may follow. 2488b53f08ac87f1e1f4bc2fbfa4560c2183a82020eeEli Friedman // If it is not a cast-expression, NotCastExpr will be true and no token 2489b53f08ac87f1e1f4bc2fbfa4560c2183a82020eeEli Friedman // will be consumed. 2490b53f08ac87f1e1f4bc2fbfa4560c2183a82020eeEli Friedman Result = ParseCastExpression(false/*isUnaryExpression*/, 2491b53f08ac87f1e1f4bc2fbfa4560c2183a82020eeEli Friedman false/*isAddressofOperand*/, 2492b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall NotCastExpr, 24930a85183be6930571f3af8e5a976d24c3f95e5b25Argyrios Kyrtzidis // type-id has priority. 24940a85183be6930571f3af8e5a976d24c3f95e5b25Argyrios Kyrtzidis true/*isTypeCast*/); 2495b53f08ac87f1e1f4bc2fbfa4560c2183a82020eeEli Friedman } 2496f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis 2497f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // If we parsed a cast-expression, it's really a type-id, otherwise it's 2498f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // an expression. 2499f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis ParseAs = NotCastExpr ? SimpleExpr : CastExpr; 2500f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis } 2501f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis 25021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // The current token should go after the cached tokens. 2503f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis Toks.push_back(Tok); 2504f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // Re-enter the stored parenthesized tokens into the token stream, so we may 2505f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // parse them now. 2506f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis PP.EnterTokenStream(Toks.data(), Toks.size(), 2507f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis true/*DisableMacroExpansion*/, false/*OwnsTokens*/); 2508f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // Drop the current token and bring the first cached one. It's the same token 2509f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // as when we entered this function. 2510f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis ConsumeAnyToken(); 2511f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis 2512f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis if (ParseAs >= CompoundLiteral) { 25130a85183be6930571f3af8e5a976d24c3f95e5b25Argyrios Kyrtzidis // Parse the type declarator. 25140a85183be6930571f3af8e5a976d24c3f95e5b25Argyrios Kyrtzidis DeclSpec DS(AttrFactory); 25150a85183be6930571f3af8e5a976d24c3f95e5b25Argyrios Kyrtzidis ParseSpecifierQualifierList(DS); 25160a85183be6930571f3af8e5a976d24c3f95e5b25Argyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 25170a85183be6930571f3af8e5a976d24c3f95e5b25Argyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 2518f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis 2519f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // Match the ')'. 25204a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Tracker.consumeClose(); 2521f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis 2522f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis if (ParseAs == CompoundLiteral) { 2523f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis ExprType = CompoundLiteral; 25240a85183be6930571f3af8e5a976d24c3f95e5b25Argyrios Kyrtzidis TypeResult Ty = ParseTypeName(); 25254a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor return ParseCompoundLiteralExpression(Ty.get(), 25264a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Tracker.getOpenLocation(), 25274a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Tracker.getCloseLocation()); 2528f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis } 25291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2530f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // We parsed '(' type-id ')' and the thing after it wasn't a '{'. 2531f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis assert(ParseAs == CastExpr); 2532f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis 25330a85183be6930571f3af8e5a976d24c3f95e5b25Argyrios Kyrtzidis if (DeclaratorInfo.isInvalidType()) 2534f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis return ExprError(); 2535f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis 2536f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // Result is what ParseCastExpression returned earlier. 2537f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis if (!Result.isInvalid()) 25384a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Result = Actions.ActOnCastExpr(getCurScope(), Tracker.getOpenLocation(), 25394a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor DeclaratorInfo, CastTy, 25404a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Tracker.getCloseLocation(), Result.take()); 2541f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis return move(Result); 2542f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis } 25431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2544f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis // Not a compound literal, and not followed by a cast-expression. 2545f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis assert(ParseAs == SimpleExpr); 2546f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis 2547f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis ExprType = SimpleExpr; 2548f40882a38baf258fa10e362003f6939a590074bbArgyrios Kyrtzidis Result = ParseExpression(); 2549f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis if (!Result.isInvalid() && Tok.is(tok::r_paren)) 25504a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Result = Actions.ActOnParenExpr(Tracker.getOpenLocation(), 25514a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Tok.getLocation(), Result.take()); 2552f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis 2553f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis // Match the ')'. 2554f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis if (Result.isInvalid()) { 2555f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis SkipUntil(tok::r_paren); 2556f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis return ExprError(); 2557f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis } 25581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 25594a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Tracker.consumeClose(); 2560f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis return move(Result); 2561f58f45e6d76792df8c643ce1c6d364dce5db4826Argyrios Kyrtzidis} 2562