diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Parse/ParseExprCXX.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Parse/ParseExprCXX.cpp | 193 |
1 files changed, 157 insertions, 36 deletions
diff --git a/contrib/llvm-project/clang/lib/Parse/ParseExprCXX.cpp b/contrib/llvm-project/clang/lib/Parse/ParseExprCXX.cpp index d61f414406f0..1d364f77a814 100644 --- a/contrib/llvm-project/clang/lib/Parse/ParseExprCXX.cpp +++ b/contrib/llvm-project/clang/lib/Parse/ParseExprCXX.cpp @@ -14,6 +14,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/ExprCXX.h" #include "clang/Basic/PrettyStackTrace.h" +#include "clang/Basic/TemplateKinds.h" #include "clang/Basic/TokenKinds.h" #include "clang/Lex/LiteralSupport.h" #include "clang/Parse/ParseDiagnostic.h" @@ -23,6 +24,7 @@ #include "clang/Sema/EnterExpressionEvaluationContext.h" #include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/Scope.h" +#include "clang/Sema/SemaCodeCompletion.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include <numeric> @@ -157,7 +159,8 @@ void Parser::CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectType, bool Parser::ParseOptionalCXXScopeSpecifier( CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors, bool EnteringContext, bool *MayBePseudoDestructor, bool IsTypename, - IdentifierInfo **LastII, bool OnlyNamespace, bool InUsingDeclaration) { + const IdentifierInfo **LastII, bool OnlyNamespace, + bool InUsingDeclaration) { assert(getLangOpts().CPlusPlus && "Call sites of this function should be guarded by checking for C++"); @@ -233,6 +236,34 @@ bool Parser::ParseOptionalCXXScopeSpecifier( HasScopeSpecifier = true; } + else if (!HasScopeSpecifier && Tok.is(tok::identifier) && + GetLookAheadToken(1).is(tok::ellipsis) && + GetLookAheadToken(2).is(tok::l_square)) { + SourceLocation Start = Tok.getLocation(); + DeclSpec DS(AttrFactory); + SourceLocation CCLoc; + SourceLocation EndLoc = ParsePackIndexingType(DS); + if (DS.getTypeSpecType() == DeclSpec::TST_error) + return false; + + QualType Type = Actions.ActOnPackIndexingType( + DS.getRepAsType().get(), DS.getPackIndexingExpr(), DS.getBeginLoc(), + DS.getEllipsisLoc()); + + if (Type.isNull()) + return false; + + if (!TryConsumeToken(tok::coloncolon, CCLoc)) { + AnnotateExistingIndexedTypeNamePack(ParsedType::make(Type), Start, + EndLoc); + return false; + } + if (Actions.ActOnCXXNestedNameSpecifierIndexedPack(SS, DS, CCLoc, + std::move(Type))) + SS.SetInvalid(SourceRange(Start, CCLoc)); + HasScopeSpecifier = true; + } + // Preferred type might change when parsing qualifiers, we need the original. auto SavedType = PreferredType; while (true) { @@ -241,9 +272,9 @@ bool Parser::ParseOptionalCXXScopeSpecifier( cutOffParsing(); // Code completion for a nested-name-specifier, where the code // completion token follows the '::'. - Actions.CodeCompleteQualifiedId(getCurScope(), SS, EnteringContext, - InUsingDeclaration, ObjectType.get(), - SavedType.get(SS.getBeginLoc())); + Actions.CodeCompletion().CodeCompleteQualifiedId( + getCurScope(), SS, EnteringContext, InUsingDeclaration, + ObjectType.get(), SavedType.get(SS.getBeginLoc())); // Include code completion token into the range of the scope otherwise // when we try to annotate the scope tokens the dangling code completion // token will cause assertion in @@ -378,6 +409,20 @@ bool Parser::ParseOptionalCXXScopeSpecifier( continue; } + switch (Tok.getKind()) { +#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: +#include "clang/Basic/TransformTypeTraits.def" + if (!NextToken().is(tok::l_paren)) { + Tok.setKind(tok::identifier); + Diag(Tok, diag::ext_keyword_as_ident) + << Tok.getIdentifierInfo()->getName() << 0; + continue; + } + [[fallthrough]]; + default: + break; + } + // The rest of the nested-name-specifier possibilities start with // tok::identifier. if (Tok.isNot(tok::identifier)) @@ -617,11 +662,38 @@ ExprResult Parser::tryParseCXXIdExpression(CXXScopeSpec &SS, break; } + // Might be a pack index expression! + E = tryParseCXXPackIndexingExpression(E); + if (!E.isInvalid() && !E.isUnset() && Tok.is(tok::less)) checkPotentialAngleBracket(E); return E; } +ExprResult Parser::ParseCXXPackIndexingExpression(ExprResult PackIdExpression) { + assert(Tok.is(tok::ellipsis) && NextToken().is(tok::l_square) && + "expected ...["); + SourceLocation EllipsisLoc = ConsumeToken(); + BalancedDelimiterTracker T(*this, tok::l_square); + T.consumeOpen(); + ExprResult IndexExpr = ParseConstantExpression(); + if (T.consumeClose() || IndexExpr.isInvalid()) + return ExprError(); + return Actions.ActOnPackIndexingExpr(getCurScope(), PackIdExpression.get(), + EllipsisLoc, T.getOpenLocation(), + IndexExpr.get(), T.getCloseLocation()); +} + +ExprResult +Parser::tryParseCXXPackIndexingExpression(ExprResult PackIdExpression) { + ExprResult E = PackIdExpression; + if (!PackIdExpression.isInvalid() && !PackIdExpression.isUnset() && + Tok.is(tok::ellipsis) && NextToken().is(tok::l_square)) { + E = ParseCXXPackIndexingExpression(E); + } + return E; +} + /// ParseCXXIdExpression - Handle id-expression. /// /// id-expression: @@ -751,9 +823,8 @@ ExprResult Parser::ParseLambdaExpression() { /// /// If we are not looking at a lambda expression, returns ExprError(). ExprResult Parser::TryParseLambdaExpression() { - assert(getLangOpts().CPlusPlus11 - && Tok.is(tok::l_square) - && "Not at the start of a possible lambda expression."); + assert(getLangOpts().CPlusPlus && Tok.is(tok::l_square) && + "Not at the start of a possible lambda expression."); const Token Next = NextToken(); if (Next.is(tok::eof)) // Nothing else to lookup here... @@ -885,8 +956,9 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro, if (Tok.is(tok::code_completion) && !(getLangOpts().ObjC && Tentative)) { cutOffParsing(); - Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, - /*AfterAmpersand=*/false); + Actions.CodeCompletion().CodeCompleteLambdaIntroducer( + getCurScope(), Intro, + /*AfterAmpersand=*/false); break; } @@ -902,10 +974,11 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro, // If we're in Objective-C++ and we have a bare '[', then this is more // likely to be a message receiver. if (getLangOpts().ObjC && Tentative && First) - Actions.CodeCompleteObjCMessageReceiver(getCurScope()); + Actions.CodeCompletion().CodeCompleteObjCMessageReceiver(getCurScope()); else - Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, - /*AfterAmpersand=*/false); + Actions.CodeCompletion().CodeCompleteLambdaIntroducer( + getCurScope(), Intro, + /*AfterAmpersand=*/false); break; } @@ -951,8 +1024,9 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro, if (Tok.is(tok::code_completion)) { cutOffParsing(); - Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, - /*AfterAmpersand=*/true); + Actions.CodeCompletion().CodeCompleteLambdaIntroducer( + getCurScope(), Intro, + /*AfterAmpersand=*/true); break; } } @@ -1271,7 +1345,9 @@ static void DiagnoseStaticSpecifierRestrictions(Parser &P, ExprResult Parser::ParseLambdaExpressionAfterIntroducer( LambdaIntroducer &Intro) { SourceLocation LambdaBeginLoc = Intro.Range.getBegin(); - Diag(LambdaBeginLoc, diag::warn_cxx98_compat_lambda); + Diag(LambdaBeginLoc, getLangOpts().CPlusPlus11 + ? diag::warn_cxx98_compat_lambda + : diag::ext_lambda); PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), LambdaBeginLoc, "lambda expression parsing"); @@ -1330,6 +1406,16 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( Diag(RAngleLoc, diag::err_lambda_template_parameter_list_empty); } else { + // We increase the template depth before recursing into a requires-clause. + // + // This depth is used for setting up a LambdaScopeInfo (in + // Sema::RecordParsingTemplateParameterDepth), which is used later when + // inventing template parameters in InventTemplateParameter. + // + // This way, abbreviated generic lambdas could have different template + // depths, avoiding substitution into the wrong template parameters during + // constraint satisfaction check. + ++CurTemplateDepthTracker; ExprResult RequiresClause; if (TryConsumeToken(tok::kw_requires)) { RequiresClause = @@ -1341,7 +1427,6 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( Actions.ActOnLambdaExplicitTemplateParameterList( Intro, LAngleLoc, TemplateParams, RAngleLoc, RequiresClause); - ++CurTemplateDepthTracker; } } @@ -1496,7 +1581,10 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( TrailingReturnTypeLoc, &DS), std::move(Attributes), DeclEndLoc); - Actions.ActOnLambdaClosureQualifiers(Intro, MutableLoc); + // We have called ActOnLambdaClosureQualifiers for parentheses-less cases + // above. + if (HasParentheses) + Actions.ActOnLambdaClosureQualifiers(Intro, MutableLoc); if (HasParentheses && Tok.is(tok::kw_requires)) ParseTrailingRequiresClause(D); @@ -1810,6 +1898,15 @@ Parser::ParseCXXPseudoDestructor(Expr *Base, SourceLocation OpLoc, return ExprError(); } + // pack-index-specifier + if (GetLookAheadToken(1).is(tok::ellipsis) && + GetLookAheadToken(2).is(tok::l_square)) { + DeclSpec DS(AttrFactory); + ParsePackIndexingType(DS); + return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base, OpLoc, OpKind, + TildeLoc, DS); + } + // Parse the second type. UnqualifiedId SecondTypeName; IdentifierInfo *Name = Tok.getIdentifierInfo(); @@ -1942,9 +2039,10 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { auto RunSignatureHelp = [&]() { QualType PreferredType; if (TypeRep) - PreferredType = Actions.ProduceConstructorSignatureHelp( - TypeRep.get()->getCanonicalTypeInternal(), DS.getEndLoc(), Exprs, - T.getOpenLocation(), /*Braced=*/false); + PreferredType = + Actions.CodeCompletion().ProduceConstructorSignatureHelp( + TypeRep.get()->getCanonicalTypeInternal(), DS.getEndLoc(), + Exprs, T.getOpenLocation(), /*Braced=*/false); CalledSignatureHelp = true; return PreferredType; }; @@ -2051,7 +2149,8 @@ Parser::ParseCXXCondition(StmtResult *InitStmt, SourceLocation Loc, if (Tok.is(tok::code_completion)) { cutOffParsing(); - Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Condition); + Actions.CodeCompletion().CodeCompleteOrdinaryName( + getCurScope(), SemaCodeCompletion::PCC_Condition); return Sema::ConditionError(); } @@ -2253,7 +2352,6 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { getTypeAnnotation(Tok), Policy); DS.SetRangeEnd(Tok.getAnnotationEndLoc()); ConsumeAnnotationToken(); - DS.Finish(Actions, Policy); return; } @@ -2364,6 +2462,10 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { DS.SetRangeEnd(ParseDecltypeSpecifier(DS)); return DS.Finish(Actions, Policy); + case tok::annot_pack_indexing_type: + DS.SetRangeEnd(ParsePackIndexingType(DS)); + return DS.Finish(Actions, Policy); + // GNU typeof support. case tok::kw_typeof: ParseTypeofSpecifier(DS); @@ -2549,7 +2651,7 @@ bool Parser::ParseUnqualifiedIdTemplateId( // UnqualifiedId. // FIXME: Store name for literal operator too. - IdentifierInfo *TemplateII = + const IdentifierInfo *TemplateII = Id.getKind() == UnqualifiedIdKind::IK_Identifier ? Id.Identifier : nullptr; OverloadedOperatorKind OpKind = @@ -2700,7 +2802,7 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, // Don't try to parse any further. cutOffParsing(); // Code completion for the operator name. - Actions.CodeCompleteOperatorName(getCurScope()); + Actions.CodeCompletion().CodeCompleteOperatorName(getCurScope()); return true; } @@ -2928,13 +3030,23 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, SS, ObjectType, ObjectHadErrors, TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), Id, IdLoc, EnteringContext, Result, TemplateSpecified); - else if (TemplateSpecified && - Actions.ActOnTemplateName( - getCurScope(), SS, *TemplateKWLoc, Result, ObjectType, - EnteringContext, Template, - /*AllowInjectedClassName*/ true) == TNK_Non_template) - return true; + if (TemplateSpecified) { + TemplateNameKind TNK = + Actions.ActOnTemplateName(getCurScope(), SS, *TemplateKWLoc, Result, + ObjectType, EnteringContext, Template, + /*AllowInjectedClassName=*/true); + if (TNK == TNK_Non_template) + return true; + + // C++2c [tem.names]p6 + // A name prefixed by the keyword template shall be followed by a template + // argument list or refer to a class template or an alias template. + if ((TNK == TNK_Function_template || TNK == TNK_Dependent_template_name || + TNK == TNK_Var_template) && + !Tok.is(tok::less)) + Diag(IdLoc, diag::missing_template_arg_list_after_template_kw); + } return false; } @@ -3258,10 +3370,12 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { // the passing DeclaratorInfo is valid, e.g. running SignatureHelp on // `new decltype(invalid) (^)`. if (TypeRep) - PreferredType = Actions.ProduceConstructorSignatureHelp( - TypeRep.get()->getCanonicalTypeInternal(), - DeclaratorInfo.getEndLoc(), ConstructorArgs, ConstructorLParen, - /*Braced=*/false); + PreferredType = + Actions.CodeCompletion().ProduceConstructorSignatureHelp( + TypeRep.get()->getCanonicalTypeInternal(), + DeclaratorInfo.getEndLoc(), ConstructorArgs, + ConstructorLParen, + /*Braced=*/false); CalledSignatureHelp = true; return PreferredType; }; @@ -3832,7 +3946,10 @@ ExprResult Parser::ParseTypeTrait() { SmallVector<ParsedType, 2> Args; do { // Parse the next type. - TypeResult Ty = ParseTypeName(); + TypeResult Ty = ParseTypeName(/*SourceRange=*/nullptr, + getLangOpts().CPlusPlus + ? DeclaratorContext::TemplateTypeArg + : DeclaratorContext::TypeName); if (Ty.isInvalid()) { Parens.skipToEnd(); return ExprError(); @@ -3874,7 +3991,8 @@ ExprResult Parser::ParseArrayTypeTrait() { if (T.expectAndConsume()) return ExprError(); - TypeResult Ty = ParseTypeName(); + TypeResult Ty = ParseTypeName(/*SourceRange=*/nullptr, + DeclaratorContext::TemplateTypeArg); if (Ty.isInvalid()) { SkipUntil(tok::comma, StopAtSemi); SkipUntil(tok::r_paren, StopAtSemi); @@ -3896,6 +4014,9 @@ ExprResult Parser::ParseArrayTypeTrait() { ExprResult DimExpr = ParseExpression(); T.consumeClose(); + if (DimExpr.isInvalid()) + return ExprError(); + return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), DimExpr.get(), T.getCloseLocation()); } |