10b57cec5SDimitry Andric //===--- ParseCXXInlineMethods.cpp - C++ class inline methods parsing------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements parsing for C++ class inline methods. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h" 140b57cec5SDimitry Andric #include "clang/Parse/ParseDiagnostic.h" 1506c3fb27SDimitry Andric #include "clang/Parse/Parser.h" 160b57cec5SDimitry Andric #include "clang/Parse/RAIIObjectsForParser.h" 170b57cec5SDimitry Andric #include "clang/Sema/DeclSpec.h" 1806c3fb27SDimitry Andric #include "clang/Sema/EnterExpressionEvaluationContext.h" 190b57cec5SDimitry Andric #include "clang/Sema/Scope.h" 2006c3fb27SDimitry Andric 210b57cec5SDimitry Andric using namespace clang; 220b57cec5SDimitry Andric 23*0fca6ea1SDimitry Andric /// Parse the optional ("message") part of a deleted-function-body. 24*0fca6ea1SDimitry Andric StringLiteral *Parser::ParseCXXDeletedFunctionMessage() { 25*0fca6ea1SDimitry Andric if (!Tok.is(tok::l_paren)) 26*0fca6ea1SDimitry Andric return nullptr; 27*0fca6ea1SDimitry Andric StringLiteral *Message = nullptr; 28*0fca6ea1SDimitry Andric BalancedDelimiterTracker BT{*this, tok::l_paren}; 29*0fca6ea1SDimitry Andric BT.consumeOpen(); 30*0fca6ea1SDimitry Andric 31*0fca6ea1SDimitry Andric if (isTokenStringLiteral()) { 32*0fca6ea1SDimitry Andric ExprResult Res = ParseUnevaluatedStringLiteralExpression(); 33*0fca6ea1SDimitry Andric if (Res.isUsable()) { 34*0fca6ea1SDimitry Andric Message = Res.getAs<StringLiteral>(); 35*0fca6ea1SDimitry Andric Diag(Message->getBeginLoc(), getLangOpts().CPlusPlus26 36*0fca6ea1SDimitry Andric ? diag::warn_cxx23_delete_with_message 37*0fca6ea1SDimitry Andric : diag::ext_delete_with_message) 38*0fca6ea1SDimitry Andric << Message->getSourceRange(); 39*0fca6ea1SDimitry Andric } 40*0fca6ea1SDimitry Andric } else { 41*0fca6ea1SDimitry Andric Diag(Tok.getLocation(), diag::err_expected_string_literal) 42*0fca6ea1SDimitry Andric << /*Source='in'*/ 0 << "'delete'"; 43*0fca6ea1SDimitry Andric SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch); 44*0fca6ea1SDimitry Andric } 45*0fca6ea1SDimitry Andric 46*0fca6ea1SDimitry Andric BT.consumeClose(); 47*0fca6ea1SDimitry Andric return Message; 48*0fca6ea1SDimitry Andric } 49*0fca6ea1SDimitry Andric 50*0fca6ea1SDimitry Andric /// If we've encountered '= delete' in a context where it is ill-formed, such 51*0fca6ea1SDimitry Andric /// as in the declaration of a non-function, also skip the ("message") part if 52*0fca6ea1SDimitry Andric /// it is present to avoid issuing further diagnostics. 53*0fca6ea1SDimitry Andric void Parser::SkipDeletedFunctionBody() { 54*0fca6ea1SDimitry Andric if (!Tok.is(tok::l_paren)) 55*0fca6ea1SDimitry Andric return; 56*0fca6ea1SDimitry Andric 57*0fca6ea1SDimitry Andric BalancedDelimiterTracker BT{*this, tok::l_paren}; 58*0fca6ea1SDimitry Andric BT.consumeOpen(); 59*0fca6ea1SDimitry Andric 60*0fca6ea1SDimitry Andric // Just skip to the end of the current declaration. 61*0fca6ea1SDimitry Andric SkipUntil(tok::r_paren, tok::comma, StopAtSemi | StopBeforeMatch); 62*0fca6ea1SDimitry Andric if (Tok.is(tok::r_paren)) 63*0fca6ea1SDimitry Andric BT.consumeClose(); 64*0fca6ea1SDimitry Andric } 65*0fca6ea1SDimitry Andric 660b57cec5SDimitry Andric /// ParseCXXInlineMethodDef - We parsed and verified that the specified 670b57cec5SDimitry Andric /// Declarator is a well formed C++ inline method definition. Now lex its body 680b57cec5SDimitry Andric /// and store its tokens for parsing after the C++ class is complete. 690b57cec5SDimitry Andric NamedDecl *Parser::ParseCXXInlineMethodDef( 7081ad6265SDimitry Andric AccessSpecifier AS, const ParsedAttributesView &AccessAttrs, 7181ad6265SDimitry Andric ParsingDeclarator &D, const ParsedTemplateInfo &TemplateInfo, 7281ad6265SDimitry Andric const VirtSpecifiers &VS, SourceLocation PureSpecLoc) { 730b57cec5SDimitry Andric assert(D.isFunctionDeclarator() && "This isn't a function declarator!"); 740b57cec5SDimitry Andric assert(Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try, tok::equal) && 750b57cec5SDimitry Andric "Current token not a '{', ':', '=', or 'try'!"); 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric MultiTemplateParamsArg TemplateParams( 780b57cec5SDimitry Andric TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data() 790b57cec5SDimitry Andric : nullptr, 800b57cec5SDimitry Andric TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size() : 0); 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric NamedDecl *FnD; 830b57cec5SDimitry Andric if (D.getDeclSpec().isFriendSpecified()) 840b57cec5SDimitry Andric FnD = Actions.ActOnFriendFunctionDecl(getCurScope(), D, 850b57cec5SDimitry Andric TemplateParams); 860b57cec5SDimitry Andric else { 870b57cec5SDimitry Andric FnD = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS, D, 880b57cec5SDimitry Andric TemplateParams, nullptr, 890b57cec5SDimitry Andric VS, ICIS_NoInit); 900b57cec5SDimitry Andric if (FnD) { 910b57cec5SDimitry Andric Actions.ProcessDeclAttributeList(getCurScope(), FnD, AccessAttrs); 920b57cec5SDimitry Andric if (PureSpecLoc.isValid()) 930b57cec5SDimitry Andric Actions.ActOnPureSpecifier(FnD, PureSpecLoc); 940b57cec5SDimitry Andric } 950b57cec5SDimitry Andric } 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric if (FnD) 980b57cec5SDimitry Andric HandleMemberFunctionDeclDelays(D, FnD); 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric D.complete(FnD); 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric if (TryConsumeToken(tok::equal)) { 1030b57cec5SDimitry Andric if (!FnD) { 1040b57cec5SDimitry Andric SkipUntil(tok::semi); 1050b57cec5SDimitry Andric return nullptr; 1060b57cec5SDimitry Andric } 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric bool Delete = false; 1090b57cec5SDimitry Andric SourceLocation KWLoc; 1100b57cec5SDimitry Andric SourceLocation KWEndLoc = Tok.getEndLoc().getLocWithOffset(-1); 1110b57cec5SDimitry Andric if (TryConsumeToken(tok::kw_delete, KWLoc)) { 1120b57cec5SDimitry Andric Diag(KWLoc, getLangOpts().CPlusPlus11 1130b57cec5SDimitry Andric ? diag::warn_cxx98_compat_defaulted_deleted_function 1140b57cec5SDimitry Andric : diag::ext_defaulted_deleted_function) 1150b57cec5SDimitry Andric << 1 /* deleted */; 116*0fca6ea1SDimitry Andric StringLiteral *Message = ParseCXXDeletedFunctionMessage(); 117*0fca6ea1SDimitry Andric Actions.SetDeclDeleted(FnD, KWLoc, Message); 1180b57cec5SDimitry Andric Delete = true; 1190b57cec5SDimitry Andric if (auto *DeclAsFunction = dyn_cast<FunctionDecl>(FnD)) { 1200b57cec5SDimitry Andric DeclAsFunction->setRangeEnd(KWEndLoc); 1210b57cec5SDimitry Andric } 1220b57cec5SDimitry Andric } else if (TryConsumeToken(tok::kw_default, KWLoc)) { 1230b57cec5SDimitry Andric Diag(KWLoc, getLangOpts().CPlusPlus11 1240b57cec5SDimitry Andric ? diag::warn_cxx98_compat_defaulted_deleted_function 1250b57cec5SDimitry Andric : diag::ext_defaulted_deleted_function) 1260b57cec5SDimitry Andric << 0 /* defaulted */; 1270b57cec5SDimitry Andric Actions.SetDeclDefaulted(FnD, KWLoc); 1280b57cec5SDimitry Andric if (auto *DeclAsFunction = dyn_cast<FunctionDecl>(FnD)) { 1290b57cec5SDimitry Andric DeclAsFunction->setRangeEnd(KWEndLoc); 1300b57cec5SDimitry Andric } 1310b57cec5SDimitry Andric } else { 1320b57cec5SDimitry Andric llvm_unreachable("function definition after = not 'delete' or 'default'"); 1330b57cec5SDimitry Andric } 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric if (Tok.is(tok::comma)) { 1360b57cec5SDimitry Andric Diag(KWLoc, diag::err_default_delete_in_multiple_declaration) 1370b57cec5SDimitry Andric << Delete; 1380b57cec5SDimitry Andric SkipUntil(tok::semi); 1390b57cec5SDimitry Andric } else if (ExpectAndConsume(tok::semi, diag::err_expected_after, 1400b57cec5SDimitry Andric Delete ? "delete" : "default")) { 1410b57cec5SDimitry Andric SkipUntil(tok::semi); 1420b57cec5SDimitry Andric } 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric return FnD; 1450b57cec5SDimitry Andric } 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric if (SkipFunctionBodies && (!FnD || Actions.canSkipFunctionBody(FnD)) && 1480b57cec5SDimitry Andric trySkippingFunctionBody()) { 1490b57cec5SDimitry Andric Actions.ActOnSkippedFunctionBody(FnD); 1500b57cec5SDimitry Andric return FnD; 1510b57cec5SDimitry Andric } 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andric // In delayed template parsing mode, if we are within a class template 1540b57cec5SDimitry Andric // or if we are about to parse function member template then consume 1550b57cec5SDimitry Andric // the tokens and store them for parsing at the end of the translation unit. 1560b57cec5SDimitry Andric if (getLangOpts().DelayedTemplateParsing && 157e8d8bef9SDimitry Andric D.getFunctionDefinitionKind() == FunctionDefinitionKind::Definition && 1580b57cec5SDimitry Andric !D.getDeclSpec().hasConstexprSpecifier() && 1590b57cec5SDimitry Andric !(FnD && FnD->getAsFunction() && 1600b57cec5SDimitry Andric FnD->getAsFunction()->getReturnType()->getContainedAutoType()) && 1610b57cec5SDimitry Andric ((Actions.CurContext->isDependentContext() || 1620b57cec5SDimitry Andric (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate && 1630b57cec5SDimitry Andric TemplateInfo.Kind != ParsedTemplateInfo::ExplicitSpecialization)) && 1640b57cec5SDimitry Andric !Actions.IsInsideALocalClassWithinATemplateFunction())) { 1650b57cec5SDimitry Andric 1660b57cec5SDimitry Andric CachedTokens Toks; 1670b57cec5SDimitry Andric LexTemplateFunctionForLateParsing(Toks); 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andric if (FnD) { 1700b57cec5SDimitry Andric FunctionDecl *FD = FnD->getAsFunction(); 1710b57cec5SDimitry Andric Actions.CheckForFunctionRedefinition(FD); 1720b57cec5SDimitry Andric Actions.MarkAsLateParsedTemplate(FD, FnD, Toks); 1730b57cec5SDimitry Andric } 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric return FnD; 1760b57cec5SDimitry Andric } 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric // Consume the tokens and store them for later parsing. 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric LexedMethod* LM = new LexedMethod(this, FnD); 1810b57cec5SDimitry Andric getCurrentClass().LateParsedDeclarations.push_back(LM); 1820b57cec5SDimitry Andric CachedTokens &Toks = LM->Toks; 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric tok::TokenKind kind = Tok.getKind(); 1850b57cec5SDimitry Andric // Consume everything up to (and including) the left brace of the 1860b57cec5SDimitry Andric // function body. 1870b57cec5SDimitry Andric if (ConsumeAndStoreFunctionPrologue(Toks)) { 1880b57cec5SDimitry Andric // We didn't find the left-brace we expected after the 18904eeddc0SDimitry Andric // constructor initializer. 19004eeddc0SDimitry Andric 19104eeddc0SDimitry Andric // If we're code-completing and the completion point was in the broken 19204eeddc0SDimitry Andric // initializer, we want to parse it even though that will fail. 19304eeddc0SDimitry Andric if (PP.isCodeCompletionEnabled() && 19404eeddc0SDimitry Andric llvm::any_of(Toks, [](const Token &Tok) { 19504eeddc0SDimitry Andric return Tok.is(tok::code_completion); 19604eeddc0SDimitry Andric })) { 19704eeddc0SDimitry Andric // If we gave up at the completion point, the initializer list was 19804eeddc0SDimitry Andric // likely truncated, so don't eat more tokens. We'll hit some extra 19904eeddc0SDimitry Andric // errors, but they should be ignored in code completion. 20004eeddc0SDimitry Andric return FnD; 20104eeddc0SDimitry Andric } 20204eeddc0SDimitry Andric 20304eeddc0SDimitry Andric // We already printed an error, and it's likely impossible to recover, 20404eeddc0SDimitry Andric // so don't try to parse this method later. 2050b57cec5SDimitry Andric // Skip over the rest of the decl and back to somewhere that looks 2060b57cec5SDimitry Andric // reasonable. 2070b57cec5SDimitry Andric SkipMalformedDecl(); 2080b57cec5SDimitry Andric delete getCurrentClass().LateParsedDeclarations.back(); 2090b57cec5SDimitry Andric getCurrentClass().LateParsedDeclarations.pop_back(); 2100b57cec5SDimitry Andric return FnD; 2110b57cec5SDimitry Andric } else { 2120b57cec5SDimitry Andric // Consume everything up to (and including) the matching right brace. 2130b57cec5SDimitry Andric ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false); 2140b57cec5SDimitry Andric } 2150b57cec5SDimitry Andric 2160b57cec5SDimitry Andric // If we're in a function-try-block, we need to store all the catch blocks. 2170b57cec5SDimitry Andric if (kind == tok::kw_try) { 2180b57cec5SDimitry Andric while (Tok.is(tok::kw_catch)) { 2190b57cec5SDimitry Andric ConsumeAndStoreUntil(tok::l_brace, Toks, /*StopAtSemi=*/false); 2200b57cec5SDimitry Andric ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false); 2210b57cec5SDimitry Andric } 2220b57cec5SDimitry Andric } 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric if (FnD) { 2250b57cec5SDimitry Andric FunctionDecl *FD = FnD->getAsFunction(); 2260b57cec5SDimitry Andric // Track that this function will eventually have a body; Sema needs 2270b57cec5SDimitry Andric // to know this. 2280b57cec5SDimitry Andric Actions.CheckForFunctionRedefinition(FD); 2290b57cec5SDimitry Andric FD->setWillHaveBody(true); 2300b57cec5SDimitry Andric } else { 2310b57cec5SDimitry Andric // If semantic analysis could not build a function declaration, 2320b57cec5SDimitry Andric // just throw away the late-parsed declaration. 2330b57cec5SDimitry Andric delete getCurrentClass().LateParsedDeclarations.back(); 2340b57cec5SDimitry Andric getCurrentClass().LateParsedDeclarations.pop_back(); 2350b57cec5SDimitry Andric } 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric return FnD; 2380b57cec5SDimitry Andric } 2390b57cec5SDimitry Andric 2400b57cec5SDimitry Andric /// ParseCXXNonStaticMemberInitializer - We parsed and verified that the 2410b57cec5SDimitry Andric /// specified Declarator is a well formed C++ non-static data member 2420b57cec5SDimitry Andric /// declaration. Now lex its initializer and store its tokens for parsing 2430b57cec5SDimitry Andric /// after the class is complete. 2440b57cec5SDimitry Andric void Parser::ParseCXXNonStaticMemberInitializer(Decl *VarD) { 2450b57cec5SDimitry Andric assert(Tok.isOneOf(tok::l_brace, tok::equal) && 2460b57cec5SDimitry Andric "Current token not a '{' or '='!"); 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andric LateParsedMemberInitializer *MI = 2490b57cec5SDimitry Andric new LateParsedMemberInitializer(this, VarD); 2500b57cec5SDimitry Andric getCurrentClass().LateParsedDeclarations.push_back(MI); 2510b57cec5SDimitry Andric CachedTokens &Toks = MI->Toks; 2520b57cec5SDimitry Andric 2530b57cec5SDimitry Andric tok::TokenKind kind = Tok.getKind(); 2540b57cec5SDimitry Andric if (kind == tok::equal) { 2550b57cec5SDimitry Andric Toks.push_back(Tok); 2560b57cec5SDimitry Andric ConsumeToken(); 2570b57cec5SDimitry Andric } 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric if (kind == tok::l_brace) { 2600b57cec5SDimitry Andric // Begin by storing the '{' token. 2610b57cec5SDimitry Andric Toks.push_back(Tok); 2620b57cec5SDimitry Andric ConsumeBrace(); 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric // Consume everything up to (and including) the matching right brace. 2650b57cec5SDimitry Andric ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/true); 2660b57cec5SDimitry Andric } else { 2670b57cec5SDimitry Andric // Consume everything up to (but excluding) the comma or semicolon. 2680b57cec5SDimitry Andric ConsumeAndStoreInitializer(Toks, CIK_DefaultInitializer); 2690b57cec5SDimitry Andric } 2700b57cec5SDimitry Andric 2710b57cec5SDimitry Andric // Store an artificial EOF token to ensure that we don't run off the end of 2720b57cec5SDimitry Andric // the initializer when we come to parse it. 2730b57cec5SDimitry Andric Token Eof; 2740b57cec5SDimitry Andric Eof.startToken(); 2750b57cec5SDimitry Andric Eof.setKind(tok::eof); 2760b57cec5SDimitry Andric Eof.setLocation(Tok.getLocation()); 2770b57cec5SDimitry Andric Eof.setEofData(VarD); 2780b57cec5SDimitry Andric Toks.push_back(Eof); 2790b57cec5SDimitry Andric } 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andric Parser::LateParsedDeclaration::~LateParsedDeclaration() {} 2820b57cec5SDimitry Andric void Parser::LateParsedDeclaration::ParseLexedMethodDeclarations() {} 2830b57cec5SDimitry Andric void Parser::LateParsedDeclaration::ParseLexedMemberInitializers() {} 2840b57cec5SDimitry Andric void Parser::LateParsedDeclaration::ParseLexedMethodDefs() {} 2855ffd83dbSDimitry Andric void Parser::LateParsedDeclaration::ParseLexedAttributes() {} 286480093f4SDimitry Andric void Parser::LateParsedDeclaration::ParseLexedPragmas() {} 2870b57cec5SDimitry Andric 2880b57cec5SDimitry Andric Parser::LateParsedClass::LateParsedClass(Parser *P, ParsingClass *C) 2890b57cec5SDimitry Andric : Self(P), Class(C) {} 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric Parser::LateParsedClass::~LateParsedClass() { 2920b57cec5SDimitry Andric Self->DeallocateParsedClasses(Class); 2930b57cec5SDimitry Andric } 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric void Parser::LateParsedClass::ParseLexedMethodDeclarations() { 2960b57cec5SDimitry Andric Self->ParseLexedMethodDeclarations(*Class); 2970b57cec5SDimitry Andric } 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric void Parser::LateParsedClass::ParseLexedMemberInitializers() { 3000b57cec5SDimitry Andric Self->ParseLexedMemberInitializers(*Class); 3010b57cec5SDimitry Andric } 3020b57cec5SDimitry Andric 3030b57cec5SDimitry Andric void Parser::LateParsedClass::ParseLexedMethodDefs() { 3040b57cec5SDimitry Andric Self->ParseLexedMethodDefs(*Class); 3050b57cec5SDimitry Andric } 3060b57cec5SDimitry Andric 3075ffd83dbSDimitry Andric void Parser::LateParsedClass::ParseLexedAttributes() { 3085ffd83dbSDimitry Andric Self->ParseLexedAttributes(*Class); 3095ffd83dbSDimitry Andric } 3105ffd83dbSDimitry Andric 311480093f4SDimitry Andric void Parser::LateParsedClass::ParseLexedPragmas() { 312480093f4SDimitry Andric Self->ParseLexedPragmas(*Class); 313480093f4SDimitry Andric } 314480093f4SDimitry Andric 3150b57cec5SDimitry Andric void Parser::LateParsedMethodDeclaration::ParseLexedMethodDeclarations() { 3160b57cec5SDimitry Andric Self->ParseLexedMethodDeclaration(*this); 3170b57cec5SDimitry Andric } 3180b57cec5SDimitry Andric 3190b57cec5SDimitry Andric void Parser::LexedMethod::ParseLexedMethodDefs() { 3200b57cec5SDimitry Andric Self->ParseLexedMethodDef(*this); 3210b57cec5SDimitry Andric } 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andric void Parser::LateParsedMemberInitializer::ParseLexedMemberInitializers() { 3240b57cec5SDimitry Andric Self->ParseLexedMemberInitializer(*this); 3250b57cec5SDimitry Andric } 3260b57cec5SDimitry Andric 3275ffd83dbSDimitry Andric void Parser::LateParsedAttribute::ParseLexedAttributes() { 3285ffd83dbSDimitry Andric Self->ParseLexedAttribute(*this, true, false); 3295ffd83dbSDimitry Andric } 3305ffd83dbSDimitry Andric 331480093f4SDimitry Andric void Parser::LateParsedPragma::ParseLexedPragmas() { 332480093f4SDimitry Andric Self->ParseLexedPragma(*this); 333480093f4SDimitry Andric } 334480093f4SDimitry Andric 3355ffd83dbSDimitry Andric /// Utility to re-enter a possibly-templated scope while parsing its 3365ffd83dbSDimitry Andric /// late-parsed components. 3375ffd83dbSDimitry Andric struct Parser::ReenterTemplateScopeRAII { 3385ffd83dbSDimitry Andric Parser &P; 3395ffd83dbSDimitry Andric MultiParseScope Scopes; 3405ffd83dbSDimitry Andric TemplateParameterDepthRAII CurTemplateDepthTracker; 3415ffd83dbSDimitry Andric 3425ffd83dbSDimitry Andric ReenterTemplateScopeRAII(Parser &P, Decl *MaybeTemplated, bool Enter = true) 3435ffd83dbSDimitry Andric : P(P), Scopes(P), CurTemplateDepthTracker(P.TemplateParameterDepth) { 3445ffd83dbSDimitry Andric if (Enter) { 3455ffd83dbSDimitry Andric CurTemplateDepthTracker.addDepth( 3465ffd83dbSDimitry Andric P.ReenterTemplateScopes(Scopes, MaybeTemplated)); 3475ffd83dbSDimitry Andric } 3485ffd83dbSDimitry Andric } 3495ffd83dbSDimitry Andric }; 3505ffd83dbSDimitry Andric 3515ffd83dbSDimitry Andric /// Utility to re-enter a class scope while parsing its late-parsed components. 3525ffd83dbSDimitry Andric struct Parser::ReenterClassScopeRAII : ReenterTemplateScopeRAII { 3535ffd83dbSDimitry Andric ParsingClass &Class; 3545ffd83dbSDimitry Andric 3555ffd83dbSDimitry Andric ReenterClassScopeRAII(Parser &P, ParsingClass &Class) 3565ffd83dbSDimitry Andric : ReenterTemplateScopeRAII(P, Class.TagOrTemplate, 3575ffd83dbSDimitry Andric /*Enter=*/!Class.TopLevelClass), 3585ffd83dbSDimitry Andric Class(Class) { 3595ffd83dbSDimitry Andric // If this is the top-level class, we're still within its scope. 3605ffd83dbSDimitry Andric if (Class.TopLevelClass) 3615ffd83dbSDimitry Andric return; 3625ffd83dbSDimitry Andric 3635ffd83dbSDimitry Andric // Re-enter the class scope itself. 3645ffd83dbSDimitry Andric Scopes.Enter(Scope::ClassScope|Scope::DeclScope); 3655ffd83dbSDimitry Andric P.Actions.ActOnStartDelayedMemberDeclarations(P.getCurScope(), 3665ffd83dbSDimitry Andric Class.TagOrTemplate); 3675ffd83dbSDimitry Andric } 3685ffd83dbSDimitry Andric ~ReenterClassScopeRAII() { 3695ffd83dbSDimitry Andric if (Class.TopLevelClass) 3705ffd83dbSDimitry Andric return; 3715ffd83dbSDimitry Andric 3725ffd83dbSDimitry Andric P.Actions.ActOnFinishDelayedMemberDeclarations(P.getCurScope(), 3735ffd83dbSDimitry Andric Class.TagOrTemplate); 3745ffd83dbSDimitry Andric } 3755ffd83dbSDimitry Andric }; 3765ffd83dbSDimitry Andric 3770b57cec5SDimitry Andric /// ParseLexedMethodDeclarations - We finished parsing the member 3780b57cec5SDimitry Andric /// specification of a top (non-nested) C++ class. Now go over the 3790b57cec5SDimitry Andric /// stack of method declarations with some parts for which parsing was 3800b57cec5SDimitry Andric /// delayed (such as default arguments) and parse them. 3810b57cec5SDimitry Andric void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) { 3825ffd83dbSDimitry Andric ReenterClassScopeRAII InClassScope(*this, Class); 3830b57cec5SDimitry Andric 3845ffd83dbSDimitry Andric for (LateParsedDeclaration *LateD : Class.LateParsedDeclarations) 3855ffd83dbSDimitry Andric LateD->ParseLexedMethodDeclarations(); 3860b57cec5SDimitry Andric } 3870b57cec5SDimitry Andric 3880b57cec5SDimitry Andric void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { 3890b57cec5SDimitry Andric // If this is a member template, introduce the template parameter scope. 3905ffd83dbSDimitry Andric ReenterTemplateScopeRAII InFunctionTemplateScope(*this, LM.Method); 3915ffd83dbSDimitry Andric 3920b57cec5SDimitry Andric // Start the delayed C++ method declaration 3930b57cec5SDimitry Andric Actions.ActOnStartDelayedCXXMethodDeclaration(getCurScope(), LM.Method); 3940b57cec5SDimitry Andric 3950b57cec5SDimitry Andric // Introduce the parameters into scope and parse their default 3960b57cec5SDimitry Andric // arguments. 3975ffd83dbSDimitry Andric InFunctionTemplateScope.Scopes.Enter(Scope::FunctionPrototypeScope | 3985ffd83dbSDimitry Andric Scope::FunctionDeclarationScope | 3995ffd83dbSDimitry Andric Scope::DeclScope); 4000b57cec5SDimitry Andric for (unsigned I = 0, N = LM.DefaultArgs.size(); I != N; ++I) { 4010b57cec5SDimitry Andric auto Param = cast<ParmVarDecl>(LM.DefaultArgs[I].Param); 4020b57cec5SDimitry Andric // Introduce the parameter into scope. 4030b57cec5SDimitry Andric bool HasUnparsed = Param->hasUnparsedDefaultArg(); 4040b57cec5SDimitry Andric Actions.ActOnDelayedCXXMethodParameter(getCurScope(), Param); 4050b57cec5SDimitry Andric std::unique_ptr<CachedTokens> Toks = std::move(LM.DefaultArgs[I].Toks); 4060b57cec5SDimitry Andric if (Toks) { 4070b57cec5SDimitry Andric ParenBraceBracketBalancer BalancerRAIIObj(*this); 4080b57cec5SDimitry Andric 4090b57cec5SDimitry Andric // Mark the end of the default argument so that we know when to stop when 4100b57cec5SDimitry Andric // we parse it later on. 4110b57cec5SDimitry Andric Token LastDefaultArgToken = Toks->back(); 4120b57cec5SDimitry Andric Token DefArgEnd; 4130b57cec5SDimitry Andric DefArgEnd.startToken(); 4140b57cec5SDimitry Andric DefArgEnd.setKind(tok::eof); 4150b57cec5SDimitry Andric DefArgEnd.setLocation(LastDefaultArgToken.getEndLoc()); 4160b57cec5SDimitry Andric DefArgEnd.setEofData(Param); 4170b57cec5SDimitry Andric Toks->push_back(DefArgEnd); 4180b57cec5SDimitry Andric 4190b57cec5SDimitry Andric // Parse the default argument from its saved token stream. 4200b57cec5SDimitry Andric Toks->push_back(Tok); // So that the current token doesn't get lost 4210b57cec5SDimitry Andric PP.EnterTokenStream(*Toks, true, /*IsReinject*/ true); 4220b57cec5SDimitry Andric 4230b57cec5SDimitry Andric // Consume the previously-pushed token. 4240b57cec5SDimitry Andric ConsumeAnyToken(); 4250b57cec5SDimitry Andric 4260b57cec5SDimitry Andric // Consume the '='. 4270b57cec5SDimitry Andric assert(Tok.is(tok::equal) && "Default argument not starting with '='"); 4280b57cec5SDimitry Andric SourceLocation EqualLoc = ConsumeToken(); 4290b57cec5SDimitry Andric 4300b57cec5SDimitry Andric // The argument isn't actually potentially evaluated unless it is 4310b57cec5SDimitry Andric // used. 4320b57cec5SDimitry Andric EnterExpressionEvaluationContext Eval( 4330b57cec5SDimitry Andric Actions, 4340b57cec5SDimitry Andric Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed, Param); 4350b57cec5SDimitry Andric 4360b57cec5SDimitry Andric ExprResult DefArgResult; 4370b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 4380b57cec5SDimitry Andric Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 4390b57cec5SDimitry Andric DefArgResult = ParseBraceInitializer(); 4400b57cec5SDimitry Andric } else 4410b57cec5SDimitry Andric DefArgResult = ParseAssignmentExpression(); 4425f757f3fSDimitry Andric DefArgResult = Actions.CorrectDelayedTyposInExpr(DefArgResult, Param); 4430b57cec5SDimitry Andric if (DefArgResult.isInvalid()) { 4445f757f3fSDimitry Andric Actions.ActOnParamDefaultArgumentError(Param, EqualLoc, 4455f757f3fSDimitry Andric /*DefaultArg=*/nullptr); 4460b57cec5SDimitry Andric } else { 4470b57cec5SDimitry Andric if (Tok.isNot(tok::eof) || Tok.getEofData() != Param) { 4480b57cec5SDimitry Andric // The last two tokens are the terminator and the saved value of 4490b57cec5SDimitry Andric // Tok; the last token in the default argument is the one before 4500b57cec5SDimitry Andric // those. 4510b57cec5SDimitry Andric assert(Toks->size() >= 3 && "expected a token in default arg"); 4520b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_default_arg_unparsed) 4530b57cec5SDimitry Andric << SourceRange(Tok.getLocation(), 4540b57cec5SDimitry Andric (*Toks)[Toks->size() - 3].getLocation()); 4550b57cec5SDimitry Andric } 4560b57cec5SDimitry Andric Actions.ActOnParamDefaultArgument(Param, EqualLoc, 4570b57cec5SDimitry Andric DefArgResult.get()); 4580b57cec5SDimitry Andric } 4590b57cec5SDimitry Andric 4600b57cec5SDimitry Andric // There could be leftover tokens (e.g. because of an error). 4610b57cec5SDimitry Andric // Skip through until we reach the 'end of default argument' token. 4620b57cec5SDimitry Andric while (Tok.isNot(tok::eof)) 4630b57cec5SDimitry Andric ConsumeAnyToken(); 4640b57cec5SDimitry Andric 4650b57cec5SDimitry Andric if (Tok.is(tok::eof) && Tok.getEofData() == Param) 4660b57cec5SDimitry Andric ConsumeAnyToken(); 4670b57cec5SDimitry Andric } else if (HasUnparsed) { 4680b57cec5SDimitry Andric assert(Param->hasInheritedDefaultArg()); 469*0fca6ea1SDimitry Andric FunctionDecl *Old; 470e8d8bef9SDimitry Andric if (const auto *FunTmpl = dyn_cast<FunctionTemplateDecl>(LM.Method)) 471e8d8bef9SDimitry Andric Old = 472e8d8bef9SDimitry Andric cast<FunctionDecl>(FunTmpl->getTemplatedDecl())->getPreviousDecl(); 473e8d8bef9SDimitry Andric else 474e8d8bef9SDimitry Andric Old = cast<FunctionDecl>(LM.Method)->getPreviousDecl(); 475e8d8bef9SDimitry Andric if (Old) { 476*0fca6ea1SDimitry Andric ParmVarDecl *OldParam = Old->getParamDecl(I); 4770b57cec5SDimitry Andric assert(!OldParam->hasUnparsedDefaultArg()); 4780b57cec5SDimitry Andric if (OldParam->hasUninstantiatedDefaultArg()) 4790b57cec5SDimitry Andric Param->setUninstantiatedDefaultArg( 4800b57cec5SDimitry Andric OldParam->getUninstantiatedDefaultArg()); 4810b57cec5SDimitry Andric else 4820b57cec5SDimitry Andric Param->setDefaultArg(OldParam->getInit()); 4830b57cec5SDimitry Andric } 4840b57cec5SDimitry Andric } 485e8d8bef9SDimitry Andric } 4860b57cec5SDimitry Andric 4870b57cec5SDimitry Andric // Parse a delayed exception-specification, if there is one. 4880b57cec5SDimitry Andric if (CachedTokens *Toks = LM.ExceptionSpecTokens) { 4890b57cec5SDimitry Andric ParenBraceBracketBalancer BalancerRAIIObj(*this); 4900b57cec5SDimitry Andric 4910b57cec5SDimitry Andric // Add the 'stop' token. 4920b57cec5SDimitry Andric Token LastExceptionSpecToken = Toks->back(); 4930b57cec5SDimitry Andric Token ExceptionSpecEnd; 4940b57cec5SDimitry Andric ExceptionSpecEnd.startToken(); 4950b57cec5SDimitry Andric ExceptionSpecEnd.setKind(tok::eof); 4960b57cec5SDimitry Andric ExceptionSpecEnd.setLocation(LastExceptionSpecToken.getEndLoc()); 4970b57cec5SDimitry Andric ExceptionSpecEnd.setEofData(LM.Method); 4980b57cec5SDimitry Andric Toks->push_back(ExceptionSpecEnd); 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andric // Parse the default argument from its saved token stream. 5010b57cec5SDimitry Andric Toks->push_back(Tok); // So that the current token doesn't get lost 5020b57cec5SDimitry Andric PP.EnterTokenStream(*Toks, true, /*IsReinject*/true); 5030b57cec5SDimitry Andric 5040b57cec5SDimitry Andric // Consume the previously-pushed token. 5050b57cec5SDimitry Andric ConsumeAnyToken(); 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andric // C++11 [expr.prim.general]p3: 5080b57cec5SDimitry Andric // If a declaration declares a member function or member function 5090b57cec5SDimitry Andric // template of a class X, the expression this is a prvalue of type 5100b57cec5SDimitry Andric // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq 5110b57cec5SDimitry Andric // and the end of the function-definition, member-declarator, or 5120b57cec5SDimitry Andric // declarator. 5130b57cec5SDimitry Andric CXXMethodDecl *Method; 514*0fca6ea1SDimitry Andric FunctionDecl *FunctionToPush; 5150b57cec5SDimitry Andric if (FunctionTemplateDecl *FunTmpl 5160b57cec5SDimitry Andric = dyn_cast<FunctionTemplateDecl>(LM.Method)) 517*0fca6ea1SDimitry Andric FunctionToPush = FunTmpl->getTemplatedDecl(); 5180b57cec5SDimitry Andric else 519*0fca6ea1SDimitry Andric FunctionToPush = cast<FunctionDecl>(LM.Method); 520*0fca6ea1SDimitry Andric Method = dyn_cast<CXXMethodDecl>(FunctionToPush); 521*0fca6ea1SDimitry Andric 522*0fca6ea1SDimitry Andric // Push a function scope so that tryCaptureVariable() can properly visit 523*0fca6ea1SDimitry Andric // function scopes involving function parameters that are referenced inside 524*0fca6ea1SDimitry Andric // the noexcept specifier e.g. through a lambda expression. 525*0fca6ea1SDimitry Andric // Example: 526*0fca6ea1SDimitry Andric // struct X { 527*0fca6ea1SDimitry Andric // void ICE(int val) noexcept(noexcept([val]{})); 528*0fca6ea1SDimitry Andric // }; 529*0fca6ea1SDimitry Andric // Setup the CurScope to match the function DeclContext - we have such 530*0fca6ea1SDimitry Andric // assumption in IsInFnTryBlockHandler(). 531*0fca6ea1SDimitry Andric ParseScope FnScope(this, Scope::FnScope); 532*0fca6ea1SDimitry Andric Sema::ContextRAII FnContext(Actions, FunctionToPush, 533*0fca6ea1SDimitry Andric /*NewThisContext=*/false); 534*0fca6ea1SDimitry Andric Sema::FunctionScopeRAII PopFnContext(Actions); 535*0fca6ea1SDimitry Andric Actions.PushFunctionScope(); 5360b57cec5SDimitry Andric 5370eae32dcSDimitry Andric Sema::CXXThisScopeRAII ThisScope( 5380eae32dcSDimitry Andric Actions, Method ? Method->getParent() : nullptr, 5390eae32dcSDimitry Andric Method ? Method->getMethodQualifiers() : Qualifiers{}, 5400eae32dcSDimitry Andric Method && getLangOpts().CPlusPlus11); 5410b57cec5SDimitry Andric 5420b57cec5SDimitry Andric // Parse the exception-specification. 5430b57cec5SDimitry Andric SourceRange SpecificationRange; 5440b57cec5SDimitry Andric SmallVector<ParsedType, 4> DynamicExceptions; 5450b57cec5SDimitry Andric SmallVector<SourceRange, 4> DynamicExceptionRanges; 5460b57cec5SDimitry Andric ExprResult NoexceptExpr; 5470b57cec5SDimitry Andric CachedTokens *ExceptionSpecTokens; 5480b57cec5SDimitry Andric 5490b57cec5SDimitry Andric ExceptionSpecificationType EST 5500b57cec5SDimitry Andric = tryParseExceptionSpecification(/*Delayed=*/false, SpecificationRange, 5510b57cec5SDimitry Andric DynamicExceptions, 5520b57cec5SDimitry Andric DynamicExceptionRanges, NoexceptExpr, 5530b57cec5SDimitry Andric ExceptionSpecTokens); 5540b57cec5SDimitry Andric 5550b57cec5SDimitry Andric if (Tok.isNot(tok::eof) || Tok.getEofData() != LM.Method) 5560b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_except_spec_unparsed); 5570b57cec5SDimitry Andric 5580b57cec5SDimitry Andric // Attach the exception-specification to the method. 5590b57cec5SDimitry Andric Actions.actOnDelayedExceptionSpecification(LM.Method, EST, 5600b57cec5SDimitry Andric SpecificationRange, 5610b57cec5SDimitry Andric DynamicExceptions, 5620b57cec5SDimitry Andric DynamicExceptionRanges, 5630b57cec5SDimitry Andric NoexceptExpr.isUsable()? 5640b57cec5SDimitry Andric NoexceptExpr.get() : nullptr); 5650b57cec5SDimitry Andric 5660b57cec5SDimitry Andric // There could be leftover tokens (e.g. because of an error). 5670b57cec5SDimitry Andric // Skip through until we reach the original token position. 5680b57cec5SDimitry Andric while (Tok.isNot(tok::eof)) 5690b57cec5SDimitry Andric ConsumeAnyToken(); 5700b57cec5SDimitry Andric 5710b57cec5SDimitry Andric // Clean up the remaining EOF token. 5720b57cec5SDimitry Andric if (Tok.is(tok::eof) && Tok.getEofData() == LM.Method) 5730b57cec5SDimitry Andric ConsumeAnyToken(); 5740b57cec5SDimitry Andric 5750b57cec5SDimitry Andric delete Toks; 5760b57cec5SDimitry Andric LM.ExceptionSpecTokens = nullptr; 5770b57cec5SDimitry Andric } 5780b57cec5SDimitry Andric 5795ffd83dbSDimitry Andric InFunctionTemplateScope.Scopes.Exit(); 5800b57cec5SDimitry Andric 5810b57cec5SDimitry Andric // Finish the delayed C++ method declaration. 5820b57cec5SDimitry Andric Actions.ActOnFinishDelayedCXXMethodDeclaration(getCurScope(), LM.Method); 5830b57cec5SDimitry Andric } 5840b57cec5SDimitry Andric 5850b57cec5SDimitry Andric /// ParseLexedMethodDefs - We finished parsing the member specification of a top 5860b57cec5SDimitry Andric /// (non-nested) C++ class. Now go over the stack of lexed methods that were 5870b57cec5SDimitry Andric /// collected during its parsing and parse them all. 5880b57cec5SDimitry Andric void Parser::ParseLexedMethodDefs(ParsingClass &Class) { 5895ffd83dbSDimitry Andric ReenterClassScopeRAII InClassScope(*this, Class); 5900b57cec5SDimitry Andric 5915ffd83dbSDimitry Andric for (LateParsedDeclaration *D : Class.LateParsedDeclarations) 5925ffd83dbSDimitry Andric D->ParseLexedMethodDefs(); 5930b57cec5SDimitry Andric } 5940b57cec5SDimitry Andric 5950b57cec5SDimitry Andric void Parser::ParseLexedMethodDef(LexedMethod &LM) { 5960b57cec5SDimitry Andric // If this is a member template, introduce the template parameter scope. 5975ffd83dbSDimitry Andric ReenterTemplateScopeRAII InFunctionTemplateScope(*this, LM.D); 5980b57cec5SDimitry Andric 5990b57cec5SDimitry Andric ParenBraceBracketBalancer BalancerRAIIObj(*this); 6000b57cec5SDimitry Andric 6010b57cec5SDimitry Andric assert(!LM.Toks.empty() && "Empty body!"); 6020b57cec5SDimitry Andric Token LastBodyToken = LM.Toks.back(); 6030b57cec5SDimitry Andric Token BodyEnd; 6040b57cec5SDimitry Andric BodyEnd.startToken(); 6050b57cec5SDimitry Andric BodyEnd.setKind(tok::eof); 6060b57cec5SDimitry Andric BodyEnd.setLocation(LastBodyToken.getEndLoc()); 6070b57cec5SDimitry Andric BodyEnd.setEofData(LM.D); 6080b57cec5SDimitry Andric LM.Toks.push_back(BodyEnd); 6090b57cec5SDimitry Andric // Append the current token at the end of the new token stream so that it 6100b57cec5SDimitry Andric // doesn't get lost. 6110b57cec5SDimitry Andric LM.Toks.push_back(Tok); 6120b57cec5SDimitry Andric PP.EnterTokenStream(LM.Toks, true, /*IsReinject*/true); 6130b57cec5SDimitry Andric 6140b57cec5SDimitry Andric // Consume the previously pushed token. 6150b57cec5SDimitry Andric ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); 6160b57cec5SDimitry Andric assert(Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try) 6170b57cec5SDimitry Andric && "Inline method not starting with '{', ':' or 'try'"); 6180b57cec5SDimitry Andric 6190b57cec5SDimitry Andric // Parse the method body. Function body parsing code is similar enough 6200b57cec5SDimitry Andric // to be re-used for method bodies as well. 6210b57cec5SDimitry Andric ParseScope FnScope(this, Scope::FnScope | Scope::DeclScope | 6220b57cec5SDimitry Andric Scope::CompoundStmtScope); 623*0fca6ea1SDimitry Andric Sema::FPFeaturesStateRAII SaveFPFeatures(Actions); 624*0fca6ea1SDimitry Andric 6250b57cec5SDimitry Andric Actions.ActOnStartOfFunctionDef(getCurScope(), LM.D); 6260b57cec5SDimitry Andric 6270b57cec5SDimitry Andric if (Tok.is(tok::kw_try)) { 6280b57cec5SDimitry Andric ParseFunctionTryBlock(LM.D, FnScope); 6290b57cec5SDimitry Andric 6300b57cec5SDimitry Andric while (Tok.isNot(tok::eof)) 6310b57cec5SDimitry Andric ConsumeAnyToken(); 6320b57cec5SDimitry Andric 6330b57cec5SDimitry Andric if (Tok.is(tok::eof) && Tok.getEofData() == LM.D) 6340b57cec5SDimitry Andric ConsumeAnyToken(); 6350b57cec5SDimitry Andric return; 6360b57cec5SDimitry Andric } 6370b57cec5SDimitry Andric if (Tok.is(tok::colon)) { 6380b57cec5SDimitry Andric ParseConstructorInitializer(LM.D); 6390b57cec5SDimitry Andric 6400b57cec5SDimitry Andric // Error recovery. 6410b57cec5SDimitry Andric if (!Tok.is(tok::l_brace)) { 6420b57cec5SDimitry Andric FnScope.Exit(); 6430b57cec5SDimitry Andric Actions.ActOnFinishFunctionBody(LM.D, nullptr); 6440b57cec5SDimitry Andric 6450b57cec5SDimitry Andric while (Tok.isNot(tok::eof)) 6460b57cec5SDimitry Andric ConsumeAnyToken(); 6470b57cec5SDimitry Andric 6480b57cec5SDimitry Andric if (Tok.is(tok::eof) && Tok.getEofData() == LM.D) 6490b57cec5SDimitry Andric ConsumeAnyToken(); 6500b57cec5SDimitry Andric return; 6510b57cec5SDimitry Andric } 6520b57cec5SDimitry Andric } else 6530b57cec5SDimitry Andric Actions.ActOnDefaultCtorInitializers(LM.D); 6540b57cec5SDimitry Andric 6550b57cec5SDimitry Andric assert((Actions.getDiagnostics().hasErrorOccurred() || 6560b57cec5SDimitry Andric !isa<FunctionTemplateDecl>(LM.D) || 6570b57cec5SDimitry Andric cast<FunctionTemplateDecl>(LM.D)->getTemplateParameters()->getDepth() 6580b57cec5SDimitry Andric < TemplateParameterDepth) && 6590b57cec5SDimitry Andric "TemplateParameterDepth should be greater than the depth of " 6600b57cec5SDimitry Andric "current template being instantiated!"); 6610b57cec5SDimitry Andric 6620b57cec5SDimitry Andric ParseFunctionStatementBody(LM.D, FnScope); 6630b57cec5SDimitry Andric 6640b57cec5SDimitry Andric while (Tok.isNot(tok::eof)) 6650b57cec5SDimitry Andric ConsumeAnyToken(); 6660b57cec5SDimitry Andric 6670b57cec5SDimitry Andric if (Tok.is(tok::eof) && Tok.getEofData() == LM.D) 6680b57cec5SDimitry Andric ConsumeAnyToken(); 6690b57cec5SDimitry Andric 6700b57cec5SDimitry Andric if (auto *FD = dyn_cast_or_null<FunctionDecl>(LM.D)) 6710b57cec5SDimitry Andric if (isa<CXXMethodDecl>(FD) || 6720b57cec5SDimitry Andric FD->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)) 6730b57cec5SDimitry Andric Actions.ActOnFinishInlineFunctionDef(FD); 6740b57cec5SDimitry Andric } 6750b57cec5SDimitry Andric 6760b57cec5SDimitry Andric /// ParseLexedMemberInitializers - We finished parsing the member specification 6770b57cec5SDimitry Andric /// of a top (non-nested) C++ class. Now go over the stack of lexed data member 6780b57cec5SDimitry Andric /// initializers that were collected during its parsing and parse them all. 6790b57cec5SDimitry Andric void Parser::ParseLexedMemberInitializers(ParsingClass &Class) { 6805ffd83dbSDimitry Andric ReenterClassScopeRAII InClassScope(*this, Class); 6810b57cec5SDimitry Andric 6820b57cec5SDimitry Andric if (!Class.LateParsedDeclarations.empty()) { 6830b57cec5SDimitry Andric // C++11 [expr.prim.general]p4: 6840b57cec5SDimitry Andric // Otherwise, if a member-declarator declares a non-static data member 6850b57cec5SDimitry Andric // (9.2) of a class X, the expression this is a prvalue of type "pointer 6860b57cec5SDimitry Andric // to X" within the optional brace-or-equal-initializer. It shall not 6870b57cec5SDimitry Andric // appear elsewhere in the member-declarator. 6885ffd83dbSDimitry Andric // FIXME: This should be done in ParseLexedMemberInitializer, not here. 6890b57cec5SDimitry Andric Sema::CXXThisScopeRAII ThisScope(Actions, Class.TagOrTemplate, 6900b57cec5SDimitry Andric Qualifiers()); 6910b57cec5SDimitry Andric 6925ffd83dbSDimitry Andric for (LateParsedDeclaration *D : Class.LateParsedDeclarations) 6935ffd83dbSDimitry Andric D->ParseLexedMemberInitializers(); 6940b57cec5SDimitry Andric } 6950b57cec5SDimitry Andric 6960b57cec5SDimitry Andric Actions.ActOnFinishDelayedMemberInitializers(Class.TagOrTemplate); 6970b57cec5SDimitry Andric } 6980b57cec5SDimitry Andric 6990b57cec5SDimitry Andric void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) { 7000b57cec5SDimitry Andric if (!MI.Field || MI.Field->isInvalidDecl()) 7010b57cec5SDimitry Andric return; 7020b57cec5SDimitry Andric 7030b57cec5SDimitry Andric ParenBraceBracketBalancer BalancerRAIIObj(*this); 7040b57cec5SDimitry Andric 7050b57cec5SDimitry Andric // Append the current token at the end of the new token stream so that it 7060b57cec5SDimitry Andric // doesn't get lost. 7070b57cec5SDimitry Andric MI.Toks.push_back(Tok); 7080b57cec5SDimitry Andric PP.EnterTokenStream(MI.Toks, true, /*IsReinject*/true); 7090b57cec5SDimitry Andric 7100b57cec5SDimitry Andric // Consume the previously pushed token. 7110b57cec5SDimitry Andric ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); 7120b57cec5SDimitry Andric 7130b57cec5SDimitry Andric SourceLocation EqualLoc; 7140b57cec5SDimitry Andric 7150b57cec5SDimitry Andric Actions.ActOnStartCXXInClassMemberInitializer(); 7160b57cec5SDimitry Andric 717bdd1243dSDimitry Andric // The initializer isn't actually potentially evaluated unless it is 718bdd1243dSDimitry Andric // used. 719bdd1243dSDimitry Andric EnterExpressionEvaluationContext Eval( 720bdd1243dSDimitry Andric Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed); 721bdd1243dSDimitry Andric 7220b57cec5SDimitry Andric ExprResult Init = ParseCXXMemberInitializer(MI.Field, /*IsFunction=*/false, 7230b57cec5SDimitry Andric EqualLoc); 7240b57cec5SDimitry Andric 7250b57cec5SDimitry Andric Actions.ActOnFinishCXXInClassMemberInitializer(MI.Field, EqualLoc, 7260b57cec5SDimitry Andric Init.get()); 7270b57cec5SDimitry Andric 7280b57cec5SDimitry Andric // The next token should be our artificial terminating EOF token. 7290b57cec5SDimitry Andric if (Tok.isNot(tok::eof)) { 7300b57cec5SDimitry Andric if (!Init.isInvalid()) { 7310b57cec5SDimitry Andric SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation); 7320b57cec5SDimitry Andric if (!EndLoc.isValid()) 7330b57cec5SDimitry Andric EndLoc = Tok.getLocation(); 7340b57cec5SDimitry Andric // No fixit; we can't recover as if there were a semicolon here. 7350b57cec5SDimitry Andric Diag(EndLoc, diag::err_expected_semi_decl_list); 7360b57cec5SDimitry Andric } 7370b57cec5SDimitry Andric 7380b57cec5SDimitry Andric // Consume tokens until we hit the artificial EOF. 7390b57cec5SDimitry Andric while (Tok.isNot(tok::eof)) 7400b57cec5SDimitry Andric ConsumeAnyToken(); 7410b57cec5SDimitry Andric } 7420b57cec5SDimitry Andric // Make sure this is *our* artificial EOF token. 7430b57cec5SDimitry Andric if (Tok.getEofData() == MI.Field) 7440b57cec5SDimitry Andric ConsumeAnyToken(); 7450b57cec5SDimitry Andric } 7460b57cec5SDimitry Andric 7475ffd83dbSDimitry Andric /// Wrapper class which calls ParseLexedAttribute, after setting up the 7485ffd83dbSDimitry Andric /// scope appropriately. 7495ffd83dbSDimitry Andric void Parser::ParseLexedAttributes(ParsingClass &Class) { 7505ffd83dbSDimitry Andric ReenterClassScopeRAII InClassScope(*this, Class); 751480093f4SDimitry Andric 7525ffd83dbSDimitry Andric for (LateParsedDeclaration *LateD : Class.LateParsedDeclarations) 7535ffd83dbSDimitry Andric LateD->ParseLexedAttributes(); 7545ffd83dbSDimitry Andric } 7555ffd83dbSDimitry Andric 7565ffd83dbSDimitry Andric /// Parse all attributes in LAs, and attach them to Decl D. 7575ffd83dbSDimitry Andric void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D, 7585ffd83dbSDimitry Andric bool EnterScope, bool OnDefinition) { 7595ffd83dbSDimitry Andric assert(LAs.parseSoon() && 7605ffd83dbSDimitry Andric "Attribute list should be marked for immediate parsing."); 7615ffd83dbSDimitry Andric for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) { 7625ffd83dbSDimitry Andric if (D) 7635ffd83dbSDimitry Andric LAs[i]->addDecl(D); 7645ffd83dbSDimitry Andric ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition); 7655ffd83dbSDimitry Andric delete LAs[i]; 7665ffd83dbSDimitry Andric } 7675ffd83dbSDimitry Andric LAs.clear(); 7685ffd83dbSDimitry Andric } 7695ffd83dbSDimitry Andric 7705ffd83dbSDimitry Andric /// Finish parsing an attribute for which parsing was delayed. 7715ffd83dbSDimitry Andric /// This will be called at the end of parsing a class declaration 7725ffd83dbSDimitry Andric /// for each LateParsedAttribute. We consume the saved tokens and 7735ffd83dbSDimitry Andric /// create an attribute with the arguments filled in. We add this 7745ffd83dbSDimitry Andric /// to the Attribute list for the decl. 7755ffd83dbSDimitry Andric void Parser::ParseLexedAttribute(LateParsedAttribute &LA, 7765ffd83dbSDimitry Andric bool EnterScope, bool OnDefinition) { 7775ffd83dbSDimitry Andric // Create a fake EOF so that attribute parsing won't go off the end of the 7785ffd83dbSDimitry Andric // attribute. 7795ffd83dbSDimitry Andric Token AttrEnd; 7805ffd83dbSDimitry Andric AttrEnd.startToken(); 7815ffd83dbSDimitry Andric AttrEnd.setKind(tok::eof); 7825ffd83dbSDimitry Andric AttrEnd.setLocation(Tok.getLocation()); 7835ffd83dbSDimitry Andric AttrEnd.setEofData(LA.Toks.data()); 7845ffd83dbSDimitry Andric LA.Toks.push_back(AttrEnd); 7855ffd83dbSDimitry Andric 7865ffd83dbSDimitry Andric // Append the current token at the end of the new token stream so that it 7875ffd83dbSDimitry Andric // doesn't get lost. 7885ffd83dbSDimitry Andric LA.Toks.push_back(Tok); 7895ffd83dbSDimitry Andric PP.EnterTokenStream(LA.Toks, true, /*IsReinject=*/true); 7905ffd83dbSDimitry Andric // Consume the previously pushed token. 7915ffd83dbSDimitry Andric ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); 7925ffd83dbSDimitry Andric 7935ffd83dbSDimitry Andric ParsedAttributes Attrs(AttrFactory); 7945ffd83dbSDimitry Andric 7955ffd83dbSDimitry Andric if (LA.Decls.size() > 0) { 7965ffd83dbSDimitry Andric Decl *D = LA.Decls[0]; 7975ffd83dbSDimitry Andric NamedDecl *ND = dyn_cast<NamedDecl>(D); 7985ffd83dbSDimitry Andric RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext()); 7995ffd83dbSDimitry Andric 8005ffd83dbSDimitry Andric // Allow 'this' within late-parsed attributes. 8015ffd83dbSDimitry Andric Sema::CXXThisScopeRAII ThisScope(Actions, RD, Qualifiers(), 8025ffd83dbSDimitry Andric ND && ND->isCXXInstanceMember()); 8035ffd83dbSDimitry Andric 8045ffd83dbSDimitry Andric if (LA.Decls.size() == 1) { 8055ffd83dbSDimitry Andric // If the Decl is templatized, add template parameters to scope. 8065ffd83dbSDimitry Andric ReenterTemplateScopeRAII InDeclScope(*this, D, EnterScope); 8075ffd83dbSDimitry Andric 8085ffd83dbSDimitry Andric // If the Decl is on a function, add function parameters to the scope. 8095ffd83dbSDimitry Andric bool HasFunScope = EnterScope && D->isFunctionOrFunctionTemplate(); 8105ffd83dbSDimitry Andric if (HasFunScope) { 8115ffd83dbSDimitry Andric InDeclScope.Scopes.Enter(Scope::FnScope | Scope::DeclScope | 8125ffd83dbSDimitry Andric Scope::CompoundStmtScope); 8135ffd83dbSDimitry Andric Actions.ActOnReenterFunctionContext(Actions.CurScope, D); 8145ffd83dbSDimitry Andric } 8155ffd83dbSDimitry Andric 81681ad6265SDimitry Andric ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, nullptr, 81706c3fb27SDimitry Andric nullptr, SourceLocation(), ParsedAttr::Form::GNU(), 8185ffd83dbSDimitry Andric nullptr); 8195ffd83dbSDimitry Andric 8205ffd83dbSDimitry Andric if (HasFunScope) 8215ffd83dbSDimitry Andric Actions.ActOnExitFunctionContext(); 8225ffd83dbSDimitry Andric } else { 8235ffd83dbSDimitry Andric // If there are multiple decls, then the decl cannot be within the 8245ffd83dbSDimitry Andric // function scope. 82581ad6265SDimitry Andric ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, nullptr, 82606c3fb27SDimitry Andric nullptr, SourceLocation(), ParsedAttr::Form::GNU(), 8275ffd83dbSDimitry Andric nullptr); 8285ffd83dbSDimitry Andric } 8295ffd83dbSDimitry Andric } else { 8305ffd83dbSDimitry Andric Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName(); 8315ffd83dbSDimitry Andric } 8325ffd83dbSDimitry Andric 8335ffd83dbSDimitry Andric if (OnDefinition && !Attrs.empty() && !Attrs.begin()->isCXX11Attribute() && 8345ffd83dbSDimitry Andric Attrs.begin()->isKnownToGCC()) 8355ffd83dbSDimitry Andric Diag(Tok, diag::warn_attribute_on_function_definition) 8365ffd83dbSDimitry Andric << &LA.AttrName; 8375ffd83dbSDimitry Andric 8385ffd83dbSDimitry Andric for (unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i) 8395ffd83dbSDimitry Andric Actions.ActOnFinishDelayedAttribute(getCurScope(), LA.Decls[i], Attrs); 8405ffd83dbSDimitry Andric 8415ffd83dbSDimitry Andric // Due to a parsing error, we either went over the cached tokens or 8425ffd83dbSDimitry Andric // there are still cached tokens left, so we skip the leftover tokens. 8435ffd83dbSDimitry Andric while (Tok.isNot(tok::eof)) 8445ffd83dbSDimitry Andric ConsumeAnyToken(); 8455ffd83dbSDimitry Andric 8465ffd83dbSDimitry Andric if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData()) 8475ffd83dbSDimitry Andric ConsumeAnyToken(); 8485ffd83dbSDimitry Andric } 8495ffd83dbSDimitry Andric 8505ffd83dbSDimitry Andric void Parser::ParseLexedPragmas(ParsingClass &Class) { 8515ffd83dbSDimitry Andric ReenterClassScopeRAII InClassScope(*this, Class); 8525ffd83dbSDimitry Andric 8535ffd83dbSDimitry Andric for (LateParsedDeclaration *D : Class.LateParsedDeclarations) 8545ffd83dbSDimitry Andric D->ParseLexedPragmas(); 855480093f4SDimitry Andric } 856480093f4SDimitry Andric 857480093f4SDimitry Andric void Parser::ParseLexedPragma(LateParsedPragma &LP) { 858480093f4SDimitry Andric PP.EnterToken(Tok, /*IsReinject=*/true); 859480093f4SDimitry Andric PP.EnterTokenStream(LP.toks(), /*DisableMacroExpansion=*/true, 860480093f4SDimitry Andric /*IsReinject=*/true); 861480093f4SDimitry Andric 862480093f4SDimitry Andric // Consume the previously pushed token. 863480093f4SDimitry Andric ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); 864480093f4SDimitry Andric assert(Tok.isAnnotation() && "Expected annotation token."); 865480093f4SDimitry Andric switch (Tok.getKind()) { 866fe6060f1SDimitry Andric case tok::annot_attr_openmp: 867480093f4SDimitry Andric case tok::annot_pragma_openmp: { 868480093f4SDimitry Andric AccessSpecifier AS = LP.getAccessSpecifier(); 86981ad6265SDimitry Andric ParsedAttributes Attrs(AttrFactory); 870480093f4SDimitry Andric (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs); 871480093f4SDimitry Andric break; 872480093f4SDimitry Andric } 873480093f4SDimitry Andric default: 874480093f4SDimitry Andric llvm_unreachable("Unexpected token."); 875480093f4SDimitry Andric } 876480093f4SDimitry Andric } 877480093f4SDimitry Andric 8780b57cec5SDimitry Andric /// ConsumeAndStoreUntil - Consume and store the token at the passed token 8790b57cec5SDimitry Andric /// container until the token 'T' is reached (which gets 8800b57cec5SDimitry Andric /// consumed/stored too, if ConsumeFinalToken). 8810b57cec5SDimitry Andric /// If StopAtSemi is true, then we will stop early at a ';' character. 8820b57cec5SDimitry Andric /// Returns true if token 'T1' or 'T2' was found. 8830b57cec5SDimitry Andric /// NOTE: This is a specialized version of Parser::SkipUntil. 8840b57cec5SDimitry Andric bool Parser::ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2, 8850b57cec5SDimitry Andric CachedTokens &Toks, 8860b57cec5SDimitry Andric bool StopAtSemi, bool ConsumeFinalToken) { 8870b57cec5SDimitry Andric // We always want this function to consume at least one token if the first 8880b57cec5SDimitry Andric // token isn't T and if not at EOF. 8890b57cec5SDimitry Andric bool isFirstTokenConsumed = true; 89004eeddc0SDimitry Andric while (true) { 8910b57cec5SDimitry Andric // If we found one of the tokens, stop and return true. 8920b57cec5SDimitry Andric if (Tok.is(T1) || Tok.is(T2)) { 8930b57cec5SDimitry Andric if (ConsumeFinalToken) { 8940b57cec5SDimitry Andric Toks.push_back(Tok); 8950b57cec5SDimitry Andric ConsumeAnyToken(); 8960b57cec5SDimitry Andric } 8970b57cec5SDimitry Andric return true; 8980b57cec5SDimitry Andric } 8990b57cec5SDimitry Andric 9000b57cec5SDimitry Andric switch (Tok.getKind()) { 9010b57cec5SDimitry Andric case tok::eof: 9020b57cec5SDimitry Andric case tok::annot_module_begin: 9030b57cec5SDimitry Andric case tok::annot_module_end: 9040b57cec5SDimitry Andric case tok::annot_module_include: 90506c3fb27SDimitry Andric case tok::annot_repl_input_end: 9060b57cec5SDimitry Andric // Ran out of tokens. 9070b57cec5SDimitry Andric return false; 9080b57cec5SDimitry Andric 9090b57cec5SDimitry Andric case tok::l_paren: 9100b57cec5SDimitry Andric // Recursively consume properly-nested parens. 9110b57cec5SDimitry Andric Toks.push_back(Tok); 9120b57cec5SDimitry Andric ConsumeParen(); 9130b57cec5SDimitry Andric ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false); 9140b57cec5SDimitry Andric break; 9150b57cec5SDimitry Andric case tok::l_square: 9160b57cec5SDimitry Andric // Recursively consume properly-nested square brackets. 9170b57cec5SDimitry Andric Toks.push_back(Tok); 9180b57cec5SDimitry Andric ConsumeBracket(); 9190b57cec5SDimitry Andric ConsumeAndStoreUntil(tok::r_square, Toks, /*StopAtSemi=*/false); 9200b57cec5SDimitry Andric break; 9210b57cec5SDimitry Andric case tok::l_brace: 9220b57cec5SDimitry Andric // Recursively consume properly-nested braces. 9230b57cec5SDimitry Andric Toks.push_back(Tok); 9240b57cec5SDimitry Andric ConsumeBrace(); 9250b57cec5SDimitry Andric ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false); 9260b57cec5SDimitry Andric break; 9270b57cec5SDimitry Andric 9280b57cec5SDimitry Andric // Okay, we found a ']' or '}' or ')', which we think should be balanced. 9290b57cec5SDimitry Andric // Since the user wasn't looking for this token (if they were, it would 9300b57cec5SDimitry Andric // already be handled), this isn't balanced. If there is a LHS token at a 9310b57cec5SDimitry Andric // higher level, we will assume that this matches the unbalanced token 9320b57cec5SDimitry Andric // and return it. Otherwise, this is a spurious RHS token, which we skip. 9330b57cec5SDimitry Andric case tok::r_paren: 9340b57cec5SDimitry Andric if (ParenCount && !isFirstTokenConsumed) 9350b57cec5SDimitry Andric return false; // Matches something. 9360b57cec5SDimitry Andric Toks.push_back(Tok); 9370b57cec5SDimitry Andric ConsumeParen(); 9380b57cec5SDimitry Andric break; 9390b57cec5SDimitry Andric case tok::r_square: 9400b57cec5SDimitry Andric if (BracketCount && !isFirstTokenConsumed) 9410b57cec5SDimitry Andric return false; // Matches something. 9420b57cec5SDimitry Andric Toks.push_back(Tok); 9430b57cec5SDimitry Andric ConsumeBracket(); 9440b57cec5SDimitry Andric break; 9450b57cec5SDimitry Andric case tok::r_brace: 9460b57cec5SDimitry Andric if (BraceCount && !isFirstTokenConsumed) 9470b57cec5SDimitry Andric return false; // Matches something. 9480b57cec5SDimitry Andric Toks.push_back(Tok); 9490b57cec5SDimitry Andric ConsumeBrace(); 9500b57cec5SDimitry Andric break; 9510b57cec5SDimitry Andric 9520b57cec5SDimitry Andric case tok::semi: 9530b57cec5SDimitry Andric if (StopAtSemi) 9540b57cec5SDimitry Andric return false; 955bdd1243dSDimitry Andric [[fallthrough]]; 9560b57cec5SDimitry Andric default: 9570b57cec5SDimitry Andric // consume this token. 9580b57cec5SDimitry Andric Toks.push_back(Tok); 9590b57cec5SDimitry Andric ConsumeAnyToken(/*ConsumeCodeCompletionTok*/true); 9600b57cec5SDimitry Andric break; 9610b57cec5SDimitry Andric } 9620b57cec5SDimitry Andric isFirstTokenConsumed = false; 9630b57cec5SDimitry Andric } 9640b57cec5SDimitry Andric } 9650b57cec5SDimitry Andric 9660b57cec5SDimitry Andric /// Consume tokens and store them in the passed token container until 9670b57cec5SDimitry Andric /// we've passed the try keyword and constructor initializers and have consumed 9680b57cec5SDimitry Andric /// the opening brace of the function body. The opening brace will be consumed 9690b57cec5SDimitry Andric /// if and only if there was no error. 9700b57cec5SDimitry Andric /// 9710b57cec5SDimitry Andric /// \return True on error. 9720b57cec5SDimitry Andric bool Parser::ConsumeAndStoreFunctionPrologue(CachedTokens &Toks) { 9730b57cec5SDimitry Andric if (Tok.is(tok::kw_try)) { 9740b57cec5SDimitry Andric Toks.push_back(Tok); 9750b57cec5SDimitry Andric ConsumeToken(); 9760b57cec5SDimitry Andric } 9770b57cec5SDimitry Andric 9780b57cec5SDimitry Andric if (Tok.isNot(tok::colon)) { 9790b57cec5SDimitry Andric // Easy case, just a function body. 9800b57cec5SDimitry Andric 9810b57cec5SDimitry Andric // Grab any remaining garbage to be diagnosed later. We stop when we reach a 9820b57cec5SDimitry Andric // brace: an opening one is the function body, while a closing one probably 9830b57cec5SDimitry Andric // means we've reached the end of the class. 9840b57cec5SDimitry Andric ConsumeAndStoreUntil(tok::l_brace, tok::r_brace, Toks, 9850b57cec5SDimitry Andric /*StopAtSemi=*/true, 9860b57cec5SDimitry Andric /*ConsumeFinalToken=*/false); 9870b57cec5SDimitry Andric if (Tok.isNot(tok::l_brace)) 9880b57cec5SDimitry Andric return Diag(Tok.getLocation(), diag::err_expected) << tok::l_brace; 9890b57cec5SDimitry Andric 9900b57cec5SDimitry Andric Toks.push_back(Tok); 9910b57cec5SDimitry Andric ConsumeBrace(); 9920b57cec5SDimitry Andric return false; 9930b57cec5SDimitry Andric } 9940b57cec5SDimitry Andric 9950b57cec5SDimitry Andric Toks.push_back(Tok); 9960b57cec5SDimitry Andric ConsumeToken(); 9970b57cec5SDimitry Andric 9980b57cec5SDimitry Andric // We can't reliably skip over a mem-initializer-id, because it could be 9990b57cec5SDimitry Andric // a template-id involving not-yet-declared names. Given: 10000b57cec5SDimitry Andric // 10010b57cec5SDimitry Andric // S ( ) : a < b < c > ( e ) 10020b57cec5SDimitry Andric // 10030b57cec5SDimitry Andric // 'e' might be an initializer or part of a template argument, depending 10040b57cec5SDimitry Andric // on whether 'b' is a template. 10050b57cec5SDimitry Andric 10060b57cec5SDimitry Andric // Track whether we might be inside a template argument. We can give 10070b57cec5SDimitry Andric // significantly better diagnostics if we know that we're not. 10080b57cec5SDimitry Andric bool MightBeTemplateArgument = false; 10090b57cec5SDimitry Andric 10100b57cec5SDimitry Andric while (true) { 10110b57cec5SDimitry Andric // Skip over the mem-initializer-id, if possible. 10120b57cec5SDimitry Andric if (Tok.is(tok::kw_decltype)) { 10130b57cec5SDimitry Andric Toks.push_back(Tok); 10140b57cec5SDimitry Andric SourceLocation OpenLoc = ConsumeToken(); 10150b57cec5SDimitry Andric if (Tok.isNot(tok::l_paren)) 10160b57cec5SDimitry Andric return Diag(Tok.getLocation(), diag::err_expected_lparen_after) 10170b57cec5SDimitry Andric << "decltype"; 10180b57cec5SDimitry Andric Toks.push_back(Tok); 10190b57cec5SDimitry Andric ConsumeParen(); 10200b57cec5SDimitry Andric if (!ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/true)) { 10210b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren; 10220b57cec5SDimitry Andric Diag(OpenLoc, diag::note_matching) << tok::l_paren; 10230b57cec5SDimitry Andric return true; 10240b57cec5SDimitry Andric } 10250b57cec5SDimitry Andric } 10260b57cec5SDimitry Andric do { 10270b57cec5SDimitry Andric // Walk over a component of a nested-name-specifier. 10280b57cec5SDimitry Andric if (Tok.is(tok::coloncolon)) { 10290b57cec5SDimitry Andric Toks.push_back(Tok); 10300b57cec5SDimitry Andric ConsumeToken(); 10310b57cec5SDimitry Andric 10320b57cec5SDimitry Andric if (Tok.is(tok::kw_template)) { 10330b57cec5SDimitry Andric Toks.push_back(Tok); 10340b57cec5SDimitry Andric ConsumeToken(); 10350b57cec5SDimitry Andric } 10360b57cec5SDimitry Andric } 10370b57cec5SDimitry Andric 10380b57cec5SDimitry Andric if (Tok.is(tok::identifier)) { 10390b57cec5SDimitry Andric Toks.push_back(Tok); 10400b57cec5SDimitry Andric ConsumeToken(); 10410b57cec5SDimitry Andric } else { 10420b57cec5SDimitry Andric break; 10430b57cec5SDimitry Andric } 1044*0fca6ea1SDimitry Andric // Pack indexing 1045*0fca6ea1SDimitry Andric if (Tok.is(tok::ellipsis) && NextToken().is(tok::l_square)) { 1046*0fca6ea1SDimitry Andric Toks.push_back(Tok); 1047*0fca6ea1SDimitry Andric SourceLocation OpenLoc = ConsumeToken(); 1048*0fca6ea1SDimitry Andric Toks.push_back(Tok); 1049*0fca6ea1SDimitry Andric ConsumeBracket(); 1050*0fca6ea1SDimitry Andric if (!ConsumeAndStoreUntil(tok::r_square, Toks, /*StopAtSemi=*/true)) { 1051*0fca6ea1SDimitry Andric Diag(Tok.getLocation(), diag::err_expected) << tok::r_square; 1052*0fca6ea1SDimitry Andric Diag(OpenLoc, diag::note_matching) << tok::l_square; 1053*0fca6ea1SDimitry Andric return true; 1054*0fca6ea1SDimitry Andric } 1055*0fca6ea1SDimitry Andric } 1056*0fca6ea1SDimitry Andric 10570b57cec5SDimitry Andric } while (Tok.is(tok::coloncolon)); 10580b57cec5SDimitry Andric 10590b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 10600b57cec5SDimitry Andric Toks.push_back(Tok); 10610b57cec5SDimitry Andric ConsumeCodeCompletionToken(); 10620b57cec5SDimitry Andric if (Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype)) { 10630b57cec5SDimitry Andric // Could be the start of another member initializer (the ',' has not 10640b57cec5SDimitry Andric // been written yet) 10650b57cec5SDimitry Andric continue; 10660b57cec5SDimitry Andric } 10670b57cec5SDimitry Andric } 10680b57cec5SDimitry Andric 10690b57cec5SDimitry Andric if (Tok.is(tok::comma)) { 10700b57cec5SDimitry Andric // The initialization is missing, we'll diagnose it later. 10710b57cec5SDimitry Andric Toks.push_back(Tok); 10720b57cec5SDimitry Andric ConsumeToken(); 10730b57cec5SDimitry Andric continue; 10740b57cec5SDimitry Andric } 10750b57cec5SDimitry Andric if (Tok.is(tok::less)) 10760b57cec5SDimitry Andric MightBeTemplateArgument = true; 10770b57cec5SDimitry Andric 10780b57cec5SDimitry Andric if (MightBeTemplateArgument) { 10790b57cec5SDimitry Andric // We may be inside a template argument list. Grab up to the start of the 10800b57cec5SDimitry Andric // next parenthesized initializer or braced-init-list. This *might* be the 10810b57cec5SDimitry Andric // initializer, or it might be a subexpression in the template argument 10820b57cec5SDimitry Andric // list. 10830b57cec5SDimitry Andric // FIXME: Count angle brackets, and clear MightBeTemplateArgument 10840b57cec5SDimitry Andric // if all angles are closed. 10850b57cec5SDimitry Andric if (!ConsumeAndStoreUntil(tok::l_paren, tok::l_brace, Toks, 10860b57cec5SDimitry Andric /*StopAtSemi=*/true, 10870b57cec5SDimitry Andric /*ConsumeFinalToken=*/false)) { 10880b57cec5SDimitry Andric // We're not just missing the initializer, we're also missing the 10890b57cec5SDimitry Andric // function body! 10900b57cec5SDimitry Andric return Diag(Tok.getLocation(), diag::err_expected) << tok::l_brace; 10910b57cec5SDimitry Andric } 10920b57cec5SDimitry Andric } else if (Tok.isNot(tok::l_paren) && Tok.isNot(tok::l_brace)) { 10930b57cec5SDimitry Andric // We found something weird in a mem-initializer-id. 10940b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11) 10950b57cec5SDimitry Andric return Diag(Tok.getLocation(), diag::err_expected_either) 10960b57cec5SDimitry Andric << tok::l_paren << tok::l_brace; 10970b57cec5SDimitry Andric else 10980b57cec5SDimitry Andric return Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren; 10990b57cec5SDimitry Andric } 11000b57cec5SDimitry Andric 11010b57cec5SDimitry Andric tok::TokenKind kind = Tok.getKind(); 11020b57cec5SDimitry Andric Toks.push_back(Tok); 11030b57cec5SDimitry Andric bool IsLParen = (kind == tok::l_paren); 11040b57cec5SDimitry Andric SourceLocation OpenLoc = Tok.getLocation(); 11050b57cec5SDimitry Andric 11060b57cec5SDimitry Andric if (IsLParen) { 11070b57cec5SDimitry Andric ConsumeParen(); 11080b57cec5SDimitry Andric } else { 11090b57cec5SDimitry Andric assert(kind == tok::l_brace && "Must be left paren or brace here."); 11100b57cec5SDimitry Andric ConsumeBrace(); 11110b57cec5SDimitry Andric // In C++03, this has to be the start of the function body, which 11120b57cec5SDimitry Andric // means the initializer is malformed; we'll diagnose it later. 11130b57cec5SDimitry Andric if (!getLangOpts().CPlusPlus11) 11140b57cec5SDimitry Andric return false; 11150b57cec5SDimitry Andric 11160b57cec5SDimitry Andric const Token &PreviousToken = Toks[Toks.size() - 2]; 11170b57cec5SDimitry Andric if (!MightBeTemplateArgument && 11180b57cec5SDimitry Andric !PreviousToken.isOneOf(tok::identifier, tok::greater, 11190b57cec5SDimitry Andric tok::greatergreater)) { 11200b57cec5SDimitry Andric // If the opening brace is not preceded by one of these tokens, we are 11210b57cec5SDimitry Andric // missing the mem-initializer-id. In order to recover better, we need 11220b57cec5SDimitry Andric // to use heuristics to determine if this '{' is most likely the 11230b57cec5SDimitry Andric // beginning of a brace-init-list or the function body. 11240b57cec5SDimitry Andric // Check the token after the corresponding '}'. 11250b57cec5SDimitry Andric TentativeParsingAction PA(*this); 11260b57cec5SDimitry Andric if (SkipUntil(tok::r_brace) && 11270b57cec5SDimitry Andric !Tok.isOneOf(tok::comma, tok::ellipsis, tok::l_brace)) { 11280b57cec5SDimitry Andric // Consider there was a malformed initializer and this is the start 11290b57cec5SDimitry Andric // of the function body. We'll diagnose it later. 11300b57cec5SDimitry Andric PA.Revert(); 11310b57cec5SDimitry Andric return false; 11320b57cec5SDimitry Andric } 11330b57cec5SDimitry Andric PA.Revert(); 11340b57cec5SDimitry Andric } 11350b57cec5SDimitry Andric } 11360b57cec5SDimitry Andric 11370b57cec5SDimitry Andric // Grab the initializer (or the subexpression of the template argument). 11380b57cec5SDimitry Andric // FIXME: If we support lambdas here, we'll need to set StopAtSemi to false 11390b57cec5SDimitry Andric // if we might be inside the braces of a lambda-expression. 11400b57cec5SDimitry Andric tok::TokenKind CloseKind = IsLParen ? tok::r_paren : tok::r_brace; 11410b57cec5SDimitry Andric if (!ConsumeAndStoreUntil(CloseKind, Toks, /*StopAtSemi=*/true)) { 11420b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << CloseKind; 11430b57cec5SDimitry Andric Diag(OpenLoc, diag::note_matching) << kind; 11440b57cec5SDimitry Andric return true; 11450b57cec5SDimitry Andric } 11460b57cec5SDimitry Andric 11470b57cec5SDimitry Andric // Grab pack ellipsis, if present. 11480b57cec5SDimitry Andric if (Tok.is(tok::ellipsis)) { 11490b57cec5SDimitry Andric Toks.push_back(Tok); 11500b57cec5SDimitry Andric ConsumeToken(); 11510b57cec5SDimitry Andric } 11520b57cec5SDimitry Andric 11530b57cec5SDimitry Andric // If we know we just consumed a mem-initializer, we must have ',' or '{' 11540b57cec5SDimitry Andric // next. 11550b57cec5SDimitry Andric if (Tok.is(tok::comma)) { 11560b57cec5SDimitry Andric Toks.push_back(Tok); 11570b57cec5SDimitry Andric ConsumeToken(); 11580b57cec5SDimitry Andric } else if (Tok.is(tok::l_brace)) { 11590b57cec5SDimitry Andric // This is the function body if the ')' or '}' is immediately followed by 11600b57cec5SDimitry Andric // a '{'. That cannot happen within a template argument, apart from the 11610b57cec5SDimitry Andric // case where a template argument contains a compound literal: 11620b57cec5SDimitry Andric // 11630b57cec5SDimitry Andric // S ( ) : a < b < c > ( d ) { } 11640b57cec5SDimitry Andric // // End of declaration, or still inside the template argument? 11650b57cec5SDimitry Andric // 11660b57cec5SDimitry Andric // ... and the case where the template argument contains a lambda: 11670b57cec5SDimitry Andric // 11680b57cec5SDimitry Andric // S ( ) : a < 0 && b < c > ( d ) + [ ] ( ) { return 0; } 11690b57cec5SDimitry Andric // ( ) > ( ) { } 11700b57cec5SDimitry Andric // 11710b57cec5SDimitry Andric // FIXME: Disambiguate these cases. Note that the latter case is probably 11720b57cec5SDimitry Andric // going to be made ill-formed by core issue 1607. 11730b57cec5SDimitry Andric Toks.push_back(Tok); 11740b57cec5SDimitry Andric ConsumeBrace(); 11750b57cec5SDimitry Andric return false; 11760b57cec5SDimitry Andric } else if (!MightBeTemplateArgument) { 11770b57cec5SDimitry Andric return Diag(Tok.getLocation(), diag::err_expected_either) << tok::l_brace 11780b57cec5SDimitry Andric << tok::comma; 11790b57cec5SDimitry Andric } 11800b57cec5SDimitry Andric } 11810b57cec5SDimitry Andric } 11820b57cec5SDimitry Andric 11830b57cec5SDimitry Andric /// Consume and store tokens from the '?' to the ':' in a conditional 11840b57cec5SDimitry Andric /// expression. 11850b57cec5SDimitry Andric bool Parser::ConsumeAndStoreConditional(CachedTokens &Toks) { 11860b57cec5SDimitry Andric // Consume '?'. 11870b57cec5SDimitry Andric assert(Tok.is(tok::question)); 11880b57cec5SDimitry Andric Toks.push_back(Tok); 11890b57cec5SDimitry Andric ConsumeToken(); 11900b57cec5SDimitry Andric 11910b57cec5SDimitry Andric while (Tok.isNot(tok::colon)) { 11920b57cec5SDimitry Andric if (!ConsumeAndStoreUntil(tok::question, tok::colon, Toks, 11930b57cec5SDimitry Andric /*StopAtSemi=*/true, 11940b57cec5SDimitry Andric /*ConsumeFinalToken=*/false)) 11950b57cec5SDimitry Andric return false; 11960b57cec5SDimitry Andric 11970b57cec5SDimitry Andric // If we found a nested conditional, consume it. 11980b57cec5SDimitry Andric if (Tok.is(tok::question) && !ConsumeAndStoreConditional(Toks)) 11990b57cec5SDimitry Andric return false; 12000b57cec5SDimitry Andric } 12010b57cec5SDimitry Andric 12020b57cec5SDimitry Andric // Consume ':'. 12030b57cec5SDimitry Andric Toks.push_back(Tok); 12040b57cec5SDimitry Andric ConsumeToken(); 12050b57cec5SDimitry Andric return true; 12060b57cec5SDimitry Andric } 12070b57cec5SDimitry Andric 12080b57cec5SDimitry Andric /// A tentative parsing action that can also revert token annotations. 12090b57cec5SDimitry Andric class Parser::UnannotatedTentativeParsingAction : public TentativeParsingAction { 12100b57cec5SDimitry Andric public: 12110b57cec5SDimitry Andric explicit UnannotatedTentativeParsingAction(Parser &Self, 12120b57cec5SDimitry Andric tok::TokenKind EndKind) 12130b57cec5SDimitry Andric : TentativeParsingAction(Self), Self(Self), EndKind(EndKind) { 12140b57cec5SDimitry Andric // Stash away the old token stream, so we can restore it once the 12150b57cec5SDimitry Andric // tentative parse is complete. 12160b57cec5SDimitry Andric TentativeParsingAction Inner(Self); 12170b57cec5SDimitry Andric Self.ConsumeAndStoreUntil(EndKind, Toks, true, /*ConsumeFinalToken*/false); 12180b57cec5SDimitry Andric Inner.Revert(); 12190b57cec5SDimitry Andric } 12200b57cec5SDimitry Andric 12210b57cec5SDimitry Andric void RevertAnnotations() { 12220b57cec5SDimitry Andric Revert(); 12230b57cec5SDimitry Andric 12240b57cec5SDimitry Andric // Put back the original tokens. 12250b57cec5SDimitry Andric Self.SkipUntil(EndKind, StopAtSemi | StopBeforeMatch); 12260b57cec5SDimitry Andric if (Toks.size()) { 1227a7dea167SDimitry Andric auto Buffer = std::make_unique<Token[]>(Toks.size()); 12280b57cec5SDimitry Andric std::copy(Toks.begin() + 1, Toks.end(), Buffer.get()); 12290b57cec5SDimitry Andric Buffer[Toks.size() - 1] = Self.Tok; 12300b57cec5SDimitry Andric Self.PP.EnterTokenStream(std::move(Buffer), Toks.size(), true, 12310b57cec5SDimitry Andric /*IsReinject*/ true); 12320b57cec5SDimitry Andric 12330b57cec5SDimitry Andric Self.Tok = Toks.front(); 12340b57cec5SDimitry Andric } 12350b57cec5SDimitry Andric } 12360b57cec5SDimitry Andric 12370b57cec5SDimitry Andric private: 12380b57cec5SDimitry Andric Parser &Self; 12390b57cec5SDimitry Andric CachedTokens Toks; 12400b57cec5SDimitry Andric tok::TokenKind EndKind; 12410b57cec5SDimitry Andric }; 12420b57cec5SDimitry Andric 12430b57cec5SDimitry Andric /// ConsumeAndStoreInitializer - Consume and store the token at the passed token 12440b57cec5SDimitry Andric /// container until the end of the current initializer expression (either a 12450b57cec5SDimitry Andric /// default argument or an in-class initializer for a non-static data member). 12460b57cec5SDimitry Andric /// 12470b57cec5SDimitry Andric /// Returns \c true if we reached the end of something initializer-shaped, 12480b57cec5SDimitry Andric /// \c false if we bailed out. 12490b57cec5SDimitry Andric bool Parser::ConsumeAndStoreInitializer(CachedTokens &Toks, 12500b57cec5SDimitry Andric CachedInitKind CIK) { 12510b57cec5SDimitry Andric // We always want this function to consume at least one token if not at EOF. 12520b57cec5SDimitry Andric bool IsFirstToken = true; 12530b57cec5SDimitry Andric 12540b57cec5SDimitry Andric // Number of possible unclosed <s we've seen so far. These might be templates, 12550b57cec5SDimitry Andric // and might not, but if there were none of them (or we know for sure that 12560b57cec5SDimitry Andric // we're within a template), we can avoid a tentative parse. 12570b57cec5SDimitry Andric unsigned AngleCount = 0; 12580b57cec5SDimitry Andric unsigned KnownTemplateCount = 0; 12590b57cec5SDimitry Andric 126004eeddc0SDimitry Andric while (true) { 12610b57cec5SDimitry Andric switch (Tok.getKind()) { 12620b57cec5SDimitry Andric case tok::comma: 12630b57cec5SDimitry Andric // If we might be in a template, perform a tentative parse to check. 12640b57cec5SDimitry Andric if (!AngleCount) 12650b57cec5SDimitry Andric // Not a template argument: this is the end of the initializer. 12660b57cec5SDimitry Andric return true; 12670b57cec5SDimitry Andric if (KnownTemplateCount) 12680b57cec5SDimitry Andric goto consume_token; 12690b57cec5SDimitry Andric 12700b57cec5SDimitry Andric // We hit a comma inside angle brackets. This is the hard case. The 12710b57cec5SDimitry Andric // rule we follow is: 12720b57cec5SDimitry Andric // * For a default argument, if the tokens after the comma form a 12730b57cec5SDimitry Andric // syntactically-valid parameter-declaration-clause, in which each 12740b57cec5SDimitry Andric // parameter has an initializer, then this comma ends the default 12750b57cec5SDimitry Andric // argument. 12760b57cec5SDimitry Andric // * For a default initializer, if the tokens after the comma form a 12770b57cec5SDimitry Andric // syntactically-valid init-declarator-list, then this comma ends 12780b57cec5SDimitry Andric // the default initializer. 12790b57cec5SDimitry Andric { 12800b57cec5SDimitry Andric UnannotatedTentativeParsingAction PA(*this, 12810b57cec5SDimitry Andric CIK == CIK_DefaultInitializer 12820b57cec5SDimitry Andric ? tok::semi : tok::r_paren); 12830b57cec5SDimitry Andric Sema::TentativeAnalysisScope Scope(Actions); 12840b57cec5SDimitry Andric 12850b57cec5SDimitry Andric TPResult Result = TPResult::Error; 12860b57cec5SDimitry Andric ConsumeToken(); 12870b57cec5SDimitry Andric switch (CIK) { 12880b57cec5SDimitry Andric case CIK_DefaultInitializer: 12890b57cec5SDimitry Andric Result = TryParseInitDeclaratorList(); 12900b57cec5SDimitry Andric // If we parsed a complete, ambiguous init-declarator-list, this 12910b57cec5SDimitry Andric // is only syntactically-valid if it's followed by a semicolon. 12920b57cec5SDimitry Andric if (Result == TPResult::Ambiguous && Tok.isNot(tok::semi)) 12930b57cec5SDimitry Andric Result = TPResult::False; 12940b57cec5SDimitry Andric break; 12950b57cec5SDimitry Andric 12960b57cec5SDimitry Andric case CIK_DefaultArgument: 12970b57cec5SDimitry Andric bool InvalidAsDeclaration = false; 12980b57cec5SDimitry Andric Result = TryParseParameterDeclarationClause( 12990b57cec5SDimitry Andric &InvalidAsDeclaration, /*VersusTemplateArg=*/true); 13000b57cec5SDimitry Andric // If this is an expression or a declaration with a missing 13010b57cec5SDimitry Andric // 'typename', assume it's not a declaration. 13020b57cec5SDimitry Andric if (Result == TPResult::Ambiguous && InvalidAsDeclaration) 13030b57cec5SDimitry Andric Result = TPResult::False; 13040b57cec5SDimitry Andric break; 13050b57cec5SDimitry Andric } 13060b57cec5SDimitry Andric 13075ffd83dbSDimitry Andric // Put the token stream back and undo any annotations we performed 13085ffd83dbSDimitry Andric // after the comma. They may reflect a different parse than the one 13095ffd83dbSDimitry Andric // we will actually perform at the end of the class. 13100b57cec5SDimitry Andric PA.RevertAnnotations(); 13115ffd83dbSDimitry Andric 13125ffd83dbSDimitry Andric // If what follows could be a declaration, it is a declaration. 13135ffd83dbSDimitry Andric if (Result != TPResult::False && Result != TPResult::Error) 13145ffd83dbSDimitry Andric return true; 13150b57cec5SDimitry Andric } 13160b57cec5SDimitry Andric 13170b57cec5SDimitry Andric // Keep going. We know we're inside a template argument list now. 13180b57cec5SDimitry Andric ++KnownTemplateCount; 13190b57cec5SDimitry Andric goto consume_token; 13200b57cec5SDimitry Andric 13210b57cec5SDimitry Andric case tok::eof: 13220b57cec5SDimitry Andric case tok::annot_module_begin: 13230b57cec5SDimitry Andric case tok::annot_module_end: 13240b57cec5SDimitry Andric case tok::annot_module_include: 132506c3fb27SDimitry Andric case tok::annot_repl_input_end: 13260b57cec5SDimitry Andric // Ran out of tokens. 13270b57cec5SDimitry Andric return false; 13280b57cec5SDimitry Andric 13290b57cec5SDimitry Andric case tok::less: 13300b57cec5SDimitry Andric // FIXME: A '<' can only start a template-id if it's preceded by an 13310b57cec5SDimitry Andric // identifier, an operator-function-id, or a literal-operator-id. 13320b57cec5SDimitry Andric ++AngleCount; 13330b57cec5SDimitry Andric goto consume_token; 13340b57cec5SDimitry Andric 13350b57cec5SDimitry Andric case tok::question: 13360b57cec5SDimitry Andric // In 'a ? b : c', 'b' can contain an unparenthesized comma. If it does, 13370b57cec5SDimitry Andric // that is *never* the end of the initializer. Skip to the ':'. 13380b57cec5SDimitry Andric if (!ConsumeAndStoreConditional(Toks)) 13390b57cec5SDimitry Andric return false; 13400b57cec5SDimitry Andric break; 13410b57cec5SDimitry Andric 13420b57cec5SDimitry Andric case tok::greatergreatergreater: 13430b57cec5SDimitry Andric if (!getLangOpts().CPlusPlus11) 13440b57cec5SDimitry Andric goto consume_token; 13450b57cec5SDimitry Andric if (AngleCount) --AngleCount; 13460b57cec5SDimitry Andric if (KnownTemplateCount) --KnownTemplateCount; 1347bdd1243dSDimitry Andric [[fallthrough]]; 13480b57cec5SDimitry Andric case tok::greatergreater: 13490b57cec5SDimitry Andric if (!getLangOpts().CPlusPlus11) 13500b57cec5SDimitry Andric goto consume_token; 13510b57cec5SDimitry Andric if (AngleCount) --AngleCount; 13520b57cec5SDimitry Andric if (KnownTemplateCount) --KnownTemplateCount; 1353bdd1243dSDimitry Andric [[fallthrough]]; 13540b57cec5SDimitry Andric case tok::greater: 13550b57cec5SDimitry Andric if (AngleCount) --AngleCount; 13560b57cec5SDimitry Andric if (KnownTemplateCount) --KnownTemplateCount; 13570b57cec5SDimitry Andric goto consume_token; 13580b57cec5SDimitry Andric 13590b57cec5SDimitry Andric case tok::kw_template: 13600b57cec5SDimitry Andric // 'template' identifier '<' is known to start a template argument list, 13610b57cec5SDimitry Andric // and can be used to disambiguate the parse. 13620b57cec5SDimitry Andric // FIXME: Support all forms of 'template' unqualified-id '<'. 13630b57cec5SDimitry Andric Toks.push_back(Tok); 13640b57cec5SDimitry Andric ConsumeToken(); 13650b57cec5SDimitry Andric if (Tok.is(tok::identifier)) { 13660b57cec5SDimitry Andric Toks.push_back(Tok); 13670b57cec5SDimitry Andric ConsumeToken(); 13680b57cec5SDimitry Andric if (Tok.is(tok::less)) { 13690b57cec5SDimitry Andric ++AngleCount; 13700b57cec5SDimitry Andric ++KnownTemplateCount; 13710b57cec5SDimitry Andric Toks.push_back(Tok); 13720b57cec5SDimitry Andric ConsumeToken(); 13730b57cec5SDimitry Andric } 13740b57cec5SDimitry Andric } 13750b57cec5SDimitry Andric break; 13760b57cec5SDimitry Andric 13770b57cec5SDimitry Andric case tok::kw_operator: 13780b57cec5SDimitry Andric // If 'operator' precedes other punctuation, that punctuation loses 13790b57cec5SDimitry Andric // its special behavior. 13800b57cec5SDimitry Andric Toks.push_back(Tok); 13810b57cec5SDimitry Andric ConsumeToken(); 13820b57cec5SDimitry Andric switch (Tok.getKind()) { 13830b57cec5SDimitry Andric case tok::comma: 13840b57cec5SDimitry Andric case tok::greatergreatergreater: 13850b57cec5SDimitry Andric case tok::greatergreater: 13860b57cec5SDimitry Andric case tok::greater: 13870b57cec5SDimitry Andric case tok::less: 13880b57cec5SDimitry Andric Toks.push_back(Tok); 13890b57cec5SDimitry Andric ConsumeToken(); 13900b57cec5SDimitry Andric break; 13910b57cec5SDimitry Andric default: 13920b57cec5SDimitry Andric break; 13930b57cec5SDimitry Andric } 13940b57cec5SDimitry Andric break; 13950b57cec5SDimitry Andric 13960b57cec5SDimitry Andric case tok::l_paren: 13970b57cec5SDimitry Andric // Recursively consume properly-nested parens. 13980b57cec5SDimitry Andric Toks.push_back(Tok); 13990b57cec5SDimitry Andric ConsumeParen(); 14000b57cec5SDimitry Andric ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false); 14010b57cec5SDimitry Andric break; 14020b57cec5SDimitry Andric case tok::l_square: 14030b57cec5SDimitry Andric // Recursively consume properly-nested square brackets. 14040b57cec5SDimitry Andric Toks.push_back(Tok); 14050b57cec5SDimitry Andric ConsumeBracket(); 14060b57cec5SDimitry Andric ConsumeAndStoreUntil(tok::r_square, Toks, /*StopAtSemi=*/false); 14070b57cec5SDimitry Andric break; 14080b57cec5SDimitry Andric case tok::l_brace: 14090b57cec5SDimitry Andric // Recursively consume properly-nested braces. 14100b57cec5SDimitry Andric Toks.push_back(Tok); 14110b57cec5SDimitry Andric ConsumeBrace(); 14120b57cec5SDimitry Andric ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false); 14130b57cec5SDimitry Andric break; 14140b57cec5SDimitry Andric 14150b57cec5SDimitry Andric // Okay, we found a ']' or '}' or ')', which we think should be balanced. 14160b57cec5SDimitry Andric // Since the user wasn't looking for this token (if they were, it would 14170b57cec5SDimitry Andric // already be handled), this isn't balanced. If there is a LHS token at a 14180b57cec5SDimitry Andric // higher level, we will assume that this matches the unbalanced token 14190b57cec5SDimitry Andric // and return it. Otherwise, this is a spurious RHS token, which we 14200b57cec5SDimitry Andric // consume and pass on to downstream code to diagnose. 14210b57cec5SDimitry Andric case tok::r_paren: 14220b57cec5SDimitry Andric if (CIK == CIK_DefaultArgument) 14230b57cec5SDimitry Andric return true; // End of the default argument. 14240b57cec5SDimitry Andric if (ParenCount && !IsFirstToken) 14250b57cec5SDimitry Andric return false; 14260b57cec5SDimitry Andric Toks.push_back(Tok); 14270b57cec5SDimitry Andric ConsumeParen(); 14280b57cec5SDimitry Andric continue; 14290b57cec5SDimitry Andric case tok::r_square: 14300b57cec5SDimitry Andric if (BracketCount && !IsFirstToken) 14310b57cec5SDimitry Andric return false; 14320b57cec5SDimitry Andric Toks.push_back(Tok); 14330b57cec5SDimitry Andric ConsumeBracket(); 14340b57cec5SDimitry Andric continue; 14350b57cec5SDimitry Andric case tok::r_brace: 14360b57cec5SDimitry Andric if (BraceCount && !IsFirstToken) 14370b57cec5SDimitry Andric return false; 14380b57cec5SDimitry Andric Toks.push_back(Tok); 14390b57cec5SDimitry Andric ConsumeBrace(); 14400b57cec5SDimitry Andric continue; 14410b57cec5SDimitry Andric 14420b57cec5SDimitry Andric case tok::code_completion: 14430b57cec5SDimitry Andric Toks.push_back(Tok); 14440b57cec5SDimitry Andric ConsumeCodeCompletionToken(); 14450b57cec5SDimitry Andric break; 14460b57cec5SDimitry Andric 14470b57cec5SDimitry Andric case tok::string_literal: 14480b57cec5SDimitry Andric case tok::wide_string_literal: 14490b57cec5SDimitry Andric case tok::utf8_string_literal: 14500b57cec5SDimitry Andric case tok::utf16_string_literal: 14510b57cec5SDimitry Andric case tok::utf32_string_literal: 14520b57cec5SDimitry Andric Toks.push_back(Tok); 14530b57cec5SDimitry Andric ConsumeStringToken(); 14540b57cec5SDimitry Andric break; 14550b57cec5SDimitry Andric case tok::semi: 14560b57cec5SDimitry Andric if (CIK == CIK_DefaultInitializer) 14570b57cec5SDimitry Andric return true; // End of the default initializer. 1458bdd1243dSDimitry Andric [[fallthrough]]; 14590b57cec5SDimitry Andric default: 14600b57cec5SDimitry Andric consume_token: 14610b57cec5SDimitry Andric Toks.push_back(Tok); 14620b57cec5SDimitry Andric ConsumeToken(); 14630b57cec5SDimitry Andric break; 14640b57cec5SDimitry Andric } 14650b57cec5SDimitry Andric IsFirstToken = false; 14660b57cec5SDimitry Andric } 14670b57cec5SDimitry Andric } 1468