diff options
Diffstat (limited to 'lib/Parse/ParseExprCXX.cpp')
-rw-r--r-- | lib/Parse/ParseExprCXX.cpp | 123 |
1 files changed, 85 insertions, 38 deletions
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index 3caec6b4de..fbafb43688 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -1,9 +1,8 @@ //===--- ParseExprCXX.cpp - C++ Expression Parsing ------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -564,7 +563,7 @@ ExprResult Parser::tryParseCXXIdExpression(CXXScopeSpec &SS, bool isAddressOfOpe ExprResult E = Actions.ActOnIdExpression( getCurScope(), SS, TemplateKWLoc, Name, Tok.is(tok::l_paren), - isAddressOfOperand, nullptr, /*IsInlineAsmIdentifier=*/false, + isAddressOfOperand, /*CCC=*/nullptr, /*IsInlineAsmIdentifier=*/false, &Replacement); if (!E.isInvalid() && !E.isUnset() && Tok.is(tok::less)) checkPotentialAngleBracket(E); @@ -639,6 +638,8 @@ ExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) { /// /// lambda-expression: /// lambda-introducer lambda-declarator[opt] compound-statement +/// lambda-introducer '<' template-parameter-list '>' +/// lambda-declarator[opt] compound-statement /// /// lambda-introducer: /// '[' lambda-capture[opt] ']' @@ -1122,6 +1123,33 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( << A.getName()->getName(); }; + // FIXME: Consider allowing this as an extension for GCC compatibiblity. + const bool HasExplicitTemplateParams = Tok.is(tok::less); + ParseScope TemplateParamScope(this, Scope::TemplateParamScope, + /*EnteredScope=*/HasExplicitTemplateParams); + if (HasExplicitTemplateParams) { + Diag(Tok, getLangOpts().CPlusPlus2a + ? diag::warn_cxx17_compat_lambda_template_parameter_list + : diag::ext_lambda_template_parameter_list); + + SmallVector<NamedDecl*, 4> TemplateParams; + SourceLocation LAngleLoc, RAngleLoc; + if (ParseTemplateParameters(CurTemplateDepthTracker.getDepth(), + TemplateParams, LAngleLoc, RAngleLoc)) { + Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope()); + return ExprError(); + } + + if (TemplateParams.empty()) { + Diag(RAngleLoc, + diag::err_lambda_template_parameter_list_empty); + } else { + Actions.ActOnLambdaExplicitTemplateParameterList( + LAngleLoc, TemplateParams, RAngleLoc); + ++CurTemplateDepthTracker; + } + } + TypeResult TrailingReturnType; if (Tok.is(tok::l_paren)) { ParseScope PrototypeScope(this, @@ -1138,13 +1166,20 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( SourceLocation EllipsisLoc; if (Tok.isNot(tok::r_paren)) { - Actions.RecordParsingTemplateParameterDepth(TemplateParameterDepth); + Actions.RecordParsingTemplateParameterDepth( + CurTemplateDepthTracker.getOriginalDepth()); + ParseParameterDeclarationClause(D, Attr, ParamInfo, EllipsisLoc); + // For a generic lambda, each 'auto' within the parameter declaration // clause creates a template type parameter, so increment the depth. + // If we've parsed any explicit template parameters, then the depth will + // have already been incremented. So we make sure that at most a single + // depth level is added. if (Actions.getCurGenericLambda()) - ++CurTemplateDepthTracker; + CurTemplateDepthTracker.setAddedDepth(1); } + T.consumeClose(); SourceLocation RParenLoc = T.getCloseLocation(); SourceLocation DeclEndLoc = RParenLoc; @@ -1299,6 +1334,7 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( StmtResult Stmt(ParseCompoundStatementBody()); BodyScope.Exit(); + TemplateParamScope.Exit(); if (!Stmt.isInvalid() && !TrailingReturnType.isInvalid()) return Actions.ActOnLambdaExpr(LambdaBeginLoc, Stmt.get(), getCurScope()); @@ -1673,23 +1709,26 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { BalancedDelimiterTracker T(*this, tok::l_paren); T.consumeOpen(); + PreferredType.enterTypeCast(Tok.getLocation(), TypeRep.get()); + ExprVector Exprs; CommaLocsTy CommaLocs; + auto RunSignatureHelp = [&]() { + QualType PreferredType = Actions.ProduceConstructorSignatureHelp( + getCurScope(), TypeRep.get()->getCanonicalTypeInternal(), + DS.getEndLoc(), Exprs, T.getOpenLocation()); + CalledSignatureHelp = true; + return PreferredType; + }; + if (Tok.isNot(tok::r_paren)) { if (ParseExpressionList(Exprs, CommaLocs, [&] { - QualType PreferredType = Actions.ProduceConstructorSignatureHelp( - getCurScope(), TypeRep.get()->getCanonicalTypeInternal(), - DS.getEndLoc(), Exprs, T.getOpenLocation()); - CalledSignatureHelp = true; - Actions.CodeCompleteExpression(getCurScope(), PreferredType); + PreferredType.enterFunctionArgument(Tok.getLocation(), + RunSignatureHelp); })) { - if (PP.isCodeCompletionReached() && !CalledSignatureHelp) { - Actions.ProduceConstructorSignatureHelp( - getCurScope(), TypeRep.get()->getCanonicalTypeInternal(), - DS.getEndLoc(), Exprs, T.getOpenLocation()); - CalledSignatureHelp = true; - } + if (PP.isCodeCompletionReached() && !CalledSignatureHelp) + RunSignatureHelp(); SkipUntil(tok::r_paren, StopAtSemi); return ExprError(); } @@ -1740,6 +1779,7 @@ Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt, Sema::ConditionKind CK, ForRangeInfo *FRI) { ParenBraceBracketBalancer BalancerRAIIObj(*this); + PreferredType.enterCondition(Actions, Tok.getLocation()); if (Tok.is(tok::code_completion)) { Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Condition); @@ -1859,6 +1899,7 @@ Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt, diag::warn_cxx98_compat_generalized_initializer_lists); InitExpr = ParseBraceInitializer(); } else if (CopyInitialization) { + PreferredType.enterVariableInit(Tok.getLocation(), DeclOut); InitExpr = ParseAssignmentExpression(); } else if (Tok.is(tok::l_paren)) { // This was probably an attempt to initialize the variable. @@ -1995,6 +2036,13 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { case tok::kw_bool: DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID, Policy); break; +#define GENERIC_IMAGE_TYPE(ImgType, Id) \ + case tok::kw_##ImgType##_t: \ + DS.SetTypeSpecType(DeclSpec::TST_##ImgType##_t, Loc, PrevSpec, DiagID, \ + Policy); \ + break; +#include "clang/Basic/OpenCLImageTypes.def" + case tok::annot_decltype: case tok::kw_decltype: DS.SetRangeEnd(ParseDecltypeSpecifier(DS)); @@ -2836,23 +2884,21 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { ConstructorLParen = T.getOpenLocation(); if (Tok.isNot(tok::r_paren)) { CommaLocsTy CommaLocs; + auto RunSignatureHelp = [&]() { + ParsedType TypeRep = + Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get(); + QualType PreferredType = Actions.ProduceConstructorSignatureHelp( + getCurScope(), TypeRep.get()->getCanonicalTypeInternal(), + DeclaratorInfo.getEndLoc(), ConstructorArgs, ConstructorLParen); + CalledSignatureHelp = true; + return PreferredType; + }; if (ParseExpressionList(ConstructorArgs, CommaLocs, [&] { - ParsedType TypeRep = - Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get(); - QualType PreferredType = Actions.ProduceConstructorSignatureHelp( - getCurScope(), TypeRep.get()->getCanonicalTypeInternal(), - DeclaratorInfo.getEndLoc(), ConstructorArgs, ConstructorLParen); - CalledSignatureHelp = true; - Actions.CodeCompleteExpression(getCurScope(), PreferredType); + PreferredType.enterFunctionArgument(Tok.getLocation(), + RunSignatureHelp); })) { - if (PP.isCodeCompletionReached() && !CalledSignatureHelp) { - ParsedType TypeRep = - Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get(); - Actions.ProduceConstructorSignatureHelp( - getCurScope(), TypeRep.get()->getCanonicalTypeInternal(), - DeclaratorInfo.getEndLoc(), ConstructorArgs, ConstructorLParen); - CalledSignatureHelp = true; - } + if (PP.isCodeCompletionReached() && !CalledSignatureHelp) + RunSignatureHelp(); SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch); return ExprError(); } @@ -2883,12 +2929,12 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { /// passed to ParseDeclaratorInternal. /// /// direct-new-declarator: -/// '[' expression ']' +/// '[' expression[opt] ']' /// direct-new-declarator '[' constant-expression ']' /// void Parser::ParseDirectNewDeclarator(Declarator &D) { // Parse the array dimensions. - bool first = true; + bool First = true; while (Tok.is(tok::l_square)) { // An array-size expression can't start with a lambda. if (CheckProhibitedCXX11Attribute()) @@ -2897,14 +2943,15 @@ void Parser::ParseDirectNewDeclarator(Declarator &D) { BalancedDelimiterTracker T(*this, tok::l_square); T.consumeOpen(); - ExprResult Size(first ? ParseExpression() - : ParseConstantExpression()); + ExprResult Size = + First ? (Tok.is(tok::r_square) ? ExprResult() : ParseExpression()) + : ParseConstantExpression(); if (Size.isInvalid()) { // Recover SkipUntil(tok::r_square, StopAtSemi); return; } - first = false; + First = false; T.consumeClose(); |