diff options
| author | 2019-01-27 16:42:12 +0000 | |
|---|---|---|
| committer | 2019-01-27 16:42:12 +0000 | |
| commit | b773203fb58f3ef282fb69c832d8710cab5bc82d (patch) | |
| tree | e75913f147570fbd75169647b144df85b88a038c /gnu/llvm/tools/clang/lib/Parse/ParseExpr.cpp | |
| parent | tweak errno in previous (diff) | |
| download | wireguard-openbsd-b773203fb58f3ef282fb69c832d8710cab5bc82d.tar.xz wireguard-openbsd-b773203fb58f3ef282fb69c832d8710cab5bc82d.zip | |
Import LLVM 7.0.1 release including clang, lld and lldb.
Diffstat (limited to 'gnu/llvm/tools/clang/lib/Parse/ParseExpr.cpp')
| -rw-r--r-- | gnu/llvm/tools/clang/lib/Parse/ParseExpr.cpp | 344 |
1 files changed, 191 insertions, 153 deletions
diff --git a/gnu/llvm/tools/clang/lib/Parse/ParseExpr.cpp b/gnu/llvm/tools/clang/lib/Parse/ParseExpr.cpp index 1b8865edb79..2a65eec8a0f 100644 --- a/gnu/llvm/tools/clang/lib/Parse/ParseExpr.cpp +++ b/gnu/llvm/tools/clang/lib/Parse/ParseExpr.cpp @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// /// /// \file -/// \brief Provides the Expression parsing implementation. +/// Provides the Expression parsing implementation. /// /// Expressions in C99 basically consist of a bunch of binary operators with /// unary operators and other random stuff at the leaves. @@ -32,7 +32,7 @@ #include "llvm/ADT/SmallVector.h" using namespace clang; -/// \brief Simple precedence-based parser for binary/ternary operators. +/// Simple precedence-based parser for binary/ternary operators. /// /// Note: we diverge from the C99 grammar when parsing the assignment-expression /// production. C99 specifies that the LHS of an assignment operator should be @@ -156,7 +156,7 @@ Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) { return ParseRHSOfBinaryExpression(LHS, prec::Comma); } -/// \brief Parse an expr that doesn't include (top-level) commas. +/// Parse an expr that doesn't include (top-level) commas. ExprResult Parser::ParseAssignmentExpression(TypeCastState isTypeCast) { if (Tok.is(tok::code_completion)) { Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression); @@ -175,7 +175,7 @@ ExprResult Parser::ParseAssignmentExpression(TypeCastState isTypeCast) { return ParseRHSOfBinaryExpression(LHS, prec::Assignment); } -/// \brief Parse an assignment expression where part of an Objective-C message +/// Parse an assignment expression where part of an Objective-C message /// send has already been parsed. /// /// In this case \p LBracLoc indicates the location of the '[' of the message @@ -217,7 +217,15 @@ ExprResult Parser::ParseConstantExpression(TypeCastState isTypeCast) { return ParseConstantExpressionInExprEvalContext(isTypeCast); } -/// \brief Parse a constraint-expression. +ExprResult Parser::ParseCaseExpression(SourceLocation CaseLoc) { + EnterExpressionEvaluationContext ConstantEvaluated( + Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated); + ExprResult LHS(ParseCastExpression(false, false, NotTypeCast)); + ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::Conditional)); + return Actions.ActOnCaseExpr(CaseLoc, Res); +} + +/// Parse a constraint-expression. /// /// \verbatim /// constraint-expression: [Concepts TS temp.constr.decl p1] @@ -246,30 +254,6 @@ bool Parser::isNotExpressionStart() { return isKnownToBeDeclarationSpecifier(); } -/// We've parsed something that could plausibly be intended to be a template -/// name (\p LHS) followed by a '<' token, and the following code can't possibly -/// be an expression. Determine if this is likely to be a template-id and if so, -/// diagnose it. -bool Parser::diagnoseUnknownTemplateId(ExprResult LHS, SourceLocation Less) { - TentativeParsingAction TPA(*this); - // FIXME: We could look at the token sequence in a lot more detail here. - if (SkipUntil(tok::greater, tok::greatergreater, tok::greatergreatergreater, - StopAtSemi | StopBeforeMatch)) { - TPA.Commit(); - - SourceLocation Greater; - ParseGreaterThanInTemplateList(Greater, true, false); - Actions.diagnoseExprIntendedAsTemplateName(getCurScope(), LHS, - Less, Greater); - return true; - } - - // There's no matching '>' token, this probably isn't supposed to be - // interpreted as a template-id. Parse it as an (ill-formed) comparison. - TPA.Revert(); - return false; -} - bool Parser::isFoldOperator(prec::Level Level) const { return Level > prec::Unknown && Level != prec::Conditional && Level != prec::Spaceship; @@ -279,7 +263,7 @@ bool Parser::isFoldOperator(tok::TokenKind Kind) const { return isFoldOperator(getBinOpPrecedence(Kind, GreaterThanIsOperator, true)); } -/// \brief Parse a binary expression that starts with \p LHS and has a +/// Parse a binary expression that starts with \p LHS and has a /// precedence of at least \p MinPrec. ExprResult Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { @@ -302,6 +286,14 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { if (OpToken.is(tok::caretcaret)) { return ExprError(Diag(Tok, diag::err_opencl_logical_exclusive_or)); } + + // If we're potentially in a template-id, we may now be able to determine + // whether we're actually in one or not. + if (OpToken.isOneOf(tok::comma, tok::greater, tok::greatergreater, + tok::greatergreatergreater) && + checkPotentialAngleBracketDelimiter(OpToken)) + return ExprError(); + // Bail out when encountering a comma followed by a token which can't // possibly be the start of an expression. For instance: // int f() { return 1, } @@ -313,16 +305,6 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { return LHS; } - // If a '<' token is followed by a type that can be a template argument and - // cannot be an expression, then this is ill-formed, but might be intended - // to be a template-id. - if (OpToken.is(tok::less) && Actions.mightBeIntendedToBeTemplateName(LHS) && - (isKnownToBeDeclarationSpecifier() || - Tok.isOneOf(tok::greater, tok::greatergreater, - tok::greatergreatergreater)) && - diagnoseUnknownTemplateId(LHS, OpToken.getLocation())) - return ExprError(); - // If the next token is an ellipsis, then this is a fold-expression. Leave // it alone so we can handle it in the paren expression. if (isFoldOperator(NextTokPrec) && Tok.is(tok::ellipsis)) { @@ -336,7 +318,17 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { // Special case handling for the ternary operator. ExprResult TernaryMiddle(true); if (NextTokPrec == prec::Conditional) { - if (Tok.isNot(tok::colon)) { + if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { + // Parse a braced-init-list here for error recovery purposes. + SourceLocation BraceLoc = Tok.getLocation(); + TernaryMiddle = ParseBraceInitializer(); + if (!TernaryMiddle.isInvalid()) { + Diag(BraceLoc, diag::err_init_list_bin_op) + << /*RHS*/ 1 << PP.getSpelling(OpToken) + << Actions.getExprRange(TernaryMiddle.get()); + TernaryMiddle = ExprError(); + } + } else if (Tok.isNot(tok::colon)) { // Don't parse FOO:BAR as if it were a typo for FOO::BAR. ColonProtectionRAIIObject X(*this); @@ -345,11 +337,6 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { // In particular, the RHS of the '?' is 'expression', not // 'logical-OR-expression' as we might expect. TernaryMiddle = ParseExpression(); - if (TernaryMiddle.isInvalid()) { - Actions.CorrectDelayedTyposInExpr(LHS); - LHS = ExprError(); - TernaryMiddle = nullptr; - } } else { // Special case handling of "X ? Y : Z" where Y is empty: // logical-OR-expression '?' ':' conditional-expression [GNU] @@ -357,6 +344,12 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { Diag(Tok, diag::ext_gnu_conditional_expr); } + if (TernaryMiddle.isInvalid()) { + Actions.CorrectDelayedTyposInExpr(LHS); + LHS = ExprError(); + TernaryMiddle = nullptr; + } + if (!TryConsumeToken(tok::colon, ColonLoc)) { // Otherwise, we're missing a ':'. Assume that this was a typo that // the user forgot. If we're not in a macro expansion, we can suggest @@ -448,7 +441,7 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { // is okay, to bind exactly as tightly. For example, compile A=B=C=D as // A=(B=(C=D)), where each paren is a level of recursion here. // The function takes ownership of the RHS. - RHS = ParseRHSOfBinaryExpression(RHS, + RHS = ParseRHSOfBinaryExpression(RHS, static_cast<prec::Level>(ThisPrec + !isRightAssoc)); RHSIsInitList = false; @@ -469,6 +462,11 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { if (ThisPrec == prec::Assignment) { Diag(OpToken, diag::warn_cxx98_compat_generalized_initializer_lists) << Actions.getExprRange(RHS.get()); + } else if (ColonLoc.isValid()) { + Diag(ColonLoc, diag::err_init_list_bin_op) + << /*RHS*/1 << ":" + << Actions.getExprRange(RHS.get()); + LHS = ExprError(); } else { Diag(OpToken, diag::err_init_list_bin_op) << /*RHS*/1 << PP.getSpelling(OpToken) @@ -513,7 +511,7 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { } } -/// \brief Parse a cast-expression, or, if \p isUnaryExpression is true, +/// Parse a cast-expression, or, if \p isUnaryExpression is true, /// parse a unary-expression. /// /// \p isAddressOfOperand exists because an id-expression that is the @@ -570,7 +568,7 @@ class CastExpressionIdValidator : public CorrectionCandidateCallback { }; } -/// \brief Parse a cast-expression, or, if \pisUnaryExpression is true, parse +/// Parse a cast-expression, or, if \pisUnaryExpression is true, parse /// a unary-expression. /// /// \p isAddressOfOperand exists because an id-expression that is the operand @@ -619,6 +617,8 @@ class CastExpressionIdValidator : public CorrectionCandidateCallback { /// [GNU] '__FUNCTION__' /// [MS] '__FUNCDNAME__' /// [MS] 'L__FUNCTION__' +/// [MS] '__FUNCSIG__' +/// [MS] 'L__FUNCSIG__' /// [GNU] '__PRETTY_FUNCTION__' /// [GNU] '(' compound-statement ')' /// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')' @@ -656,14 +656,14 @@ class CastExpressionIdValidator : public CorrectionCandidateCallback { /// /// id-expression: [C++ 5.1] /// unqualified-id -/// qualified-id +/// qualified-id /// /// unqualified-id: [C++ 5.1] /// identifier /// operator-function-id /// conversion-function-id -/// '~' class-name -/// template-id +/// '~' class-name +/// template-id /// /// new-expression: [C++ 5.3.4] /// '::'[opt] 'new' new-placement[opt] new-type-id @@ -729,7 +729,7 @@ class CastExpressionIdValidator : public CorrectionCandidateCallback { /// '__trivially_copyable' /// /// binary-type-trait: -/// [GNU] '__is_base_of' +/// [GNU] '__is_base_of' /// [MS] '__is_convertible_to' /// '__is_convertible' /// '__is_same' @@ -789,6 +789,10 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, // We have parsed the cast-expression and no postfix-expr pieces are // following. return Res; + case FoldExpr: + // We only parsed a fold-expression. There might be postfix-expr pieces + // afterwards; parse them now. + break; } break; @@ -807,7 +811,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, case tok::kw_false: Res = ParseCXXBoolLiteral(); break; - + case tok::kw___objc_yes: case tok::kw___objc_no: return ParseObjCBoolLiteral(); @@ -820,6 +824,8 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, assert(Res.get() == nullptr && "Stray primary-expression annotation?"); Res = getExprAnnotation(Tok); ConsumeAnnotationToken(); + if (!Res.isInvalid() && Tok.is(tok::less)) + checkPotentialAngleBracket(Res); break; case tok::kw___super: @@ -829,7 +835,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, return ExprError(); assert(Tok.isNot(tok::kw_decltype) && Tok.isNot(tok::kw___super)); return ParseCastExpression(isUnaryExpression, isAddressOfOperand); - + case tok::identifier: { // primary-expression: identifier // unqualified-id: identifier // constant: enumeration-constant @@ -951,14 +957,14 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, return ExprError(); } // Allow either an identifier or the keyword 'class' (in C++). - if (Tok.isNot(tok::identifier) && + if (Tok.isNot(tok::identifier) && !(getLangOpts().CPlusPlus && Tok.is(tok::kw_class))) { Diag(Tok, diag::err_expected_property_name); return ExprError(); } IdentifierInfo &PropertyName = *Tok.getIdentifierInfo(); SourceLocation PropertyLoc = ConsumeToken(); - + Res = Actions.ActOnClassPropertyRefExpr(II, PropertyName, ILoc, PropertyLoc); break; @@ -967,7 +973,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, // In an Objective-C method, if we have "super" followed by an identifier, // the token sequence is ill-formed. However, if there's a ':' or ']' after // that identifier, this is probably a message send with a missing open - // bracket. Treat it as such. + // bracket. Treat it as such. if (getLangOpts().ObjC1 && &II == Ident_super && !InMessageExpression && getCurScope()->isInObjcMethodScope() && ((Tok.is(tok::identifier) && @@ -977,17 +983,17 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, nullptr); break; } - + // If we have an Objective-C class name followed by an identifier // and either ':' or ']', this is an Objective-C class message // send that's missing the opening '['. Recovery // appropriately. Also take this path if we're performing code // completion after an Objective-C class name. - if (getLangOpts().ObjC1 && - ((Tok.is(tok::identifier) && !InMessageExpression) || + if (getLangOpts().ObjC1 && + ((Tok.is(tok::identifier) && !InMessageExpression) || Tok.is(tok::code_completion))) { const Token& Next = NextToken(); - if (Tok.is(tok::code_completion) || + if (Tok.is(tok::code_completion) || Next.is(tok::colon) || Next.is(tok::r_square)) if (ParsedType Typ = Actions.getTypeName(II, ILoc, getCurScope())) if (Typ.get()->isObjCObjectOrInterfaceType()) { @@ -999,24 +1005,24 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, unsigned DiagID; DS.SetTypeSpecType(TST_typename, ILoc, PrevSpec, DiagID, Typ, Actions.getASTContext().getPrintingPolicy()); - + Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext); - TypeResult Ty = Actions.ActOnTypeName(getCurScope(), + TypeResult Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); if (Ty.isInvalid()) break; - Res = ParseObjCMessageExpressionBody(SourceLocation(), - SourceLocation(), + Res = ParseObjCMessageExpressionBody(SourceLocation(), + SourceLocation(), Ty.get(), nullptr); break; } } - + // Make sure to pass down the right value for isAddressOfOperand. if (isAddressOfOperand && isPostfixExpressionSuffixStart()) isAddressOfOperand = false; - + // Function designators are allowed to be undeclared (C99 6.5.1p2), so we // need to know whether or not this identifier is a function designator or // not. @@ -1039,11 +1045,13 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, isAddressOfOperand, std::move(Validator), /*IsInlineAsmIdentifier=*/false, Tok.is(tok::r_paren) ? nullptr : &Replacement); - if (!Res.isInvalid() && !Res.get()) { + if (!Res.isInvalid() && Res.isUnset()) { UnconsumeToken(Replacement); return ParseCastExpression(isUnaryExpression, isAddressOfOperand, NotCastExpr, isTypeCast); } + if (!Res.isInvalid() && Tok.is(tok::less)) + checkPotentialAngleBracket(Res); break; } case tok::char_constant: // constant: character-constant @@ -1059,6 +1067,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, case tok::kw___FUNCDNAME__: // primary-expression: __FUNCDNAME__ [MS] case tok::kw___FUNCSIG__: // primary-expression: __FUNCSIG__ [MS] case tok::kw_L__FUNCTION__: // primary-expression: L__FUNCTION__ [MS] + case tok::kw_L__FUNCSIG__: // primary-expression: L__FUNCSIG__ [MS] case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU] Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind); ConsumeToken(); @@ -1170,7 +1179,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, if (getCurScope()->getFnParent() == nullptr) return ExprError(Diag(Tok, diag::err_address_of_label_outside_fn)); - + Diag(AmpAmpLoc, diag::ext_gnu_address_of_label); LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(), Tok.getLocation()); @@ -1224,6 +1233,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, case tok::annot_decltype: case tok::kw_char: case tok::kw_wchar_t: + case tok::kw_char8_t: case tok::kw_char16_t: case tok::kw_char32_t: case tok::kw_bool: @@ -1374,7 +1384,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, T.consumeClose(); if (!Result.isInvalid()) - Result = Actions.ActOnNoexceptExpr(KeyLoc, T.getOpenLocation(), + Result = Actions.ActOnNoexceptExpr(KeyLoc, T.getOpenLocation(), Result.get(), T.getCloseLocation()); return Result; } @@ -1383,7 +1393,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, case tok::kw_##Spelling: #include "clang/Basic/TokenKinds.def" return ParseTypeTrait(); - + case tok::kw___array_rank: case tok::kw___array_extent: return ParseArrayTypeTrait(); @@ -1391,7 +1401,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, case tok::kw___is_lvalue_expr: case tok::kw___is_rvalue_expr: return ParseExpressionTrait(); - + case tok::at: { SourceLocation AtLoc = ConsumeToken(); return ParseObjCAtExpression(AtLoc); @@ -1449,7 +1459,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, return Res; } -/// \brief Once the leading part of a postfix-expression is parsed, this +/// Once the leading part of a postfix-expression is parsed, this /// method parses any suffixes that apply. /// /// \verbatim @@ -1479,16 +1489,16 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { case tok::code_completion: if (InMessageExpression) return LHS; - + Actions.CodeCompletePostfixExpression(getCurScope(), LHS); cutOffParsing(); return ExprError(); - + case tok::identifier: // If we see identifier: after an expression, and we're not already in a // message send, then this is probably a message send with a missing // opening bracket '['. - if (getLangOpts().ObjC1 && !InMessageExpression && + if (getLangOpts().ObjC1 && !InMessageExpression && (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) { LHS = ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(), nullptr, LHS.get()); @@ -1610,8 +1620,8 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { if (!LHS.isInvalid()) { ExprResult ECResult = Actions.ActOnCUDAExecConfigExpr(getCurScope(), - OpenLoc, - ExecConfigExprs, + OpenLoc, + ExecConfigExprs, CloseLoc); if (ECResult.isInvalid()) LHS = ExprError(); @@ -1625,7 +1635,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { ExprVector ArgExprs; CommaLocsTy CommaLocs; - + if (Tok.is(tok::code_completion)) { Actions.CodeCompleteCall(getCurScope(), LHS.get(), None); cutOffParsing(); @@ -1665,7 +1675,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { PT.consumeClose(); LHS = ExprError(); } else { - assert((ArgExprs.size() == 0 || + assert((ArgExprs.size() == 0 || ArgExprs.size()-1 == CommaLocs.size())&& "Unexpected number of commas!"); LHS = Actions.ActOnCallExpr(getCurScope(), LHS.get(), Loc, @@ -1686,8 +1696,10 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { CXXScopeSpec SS; ParsedType ObjectType; bool MayBePseudoDestructor = false; + Expr* OrigLHS = !LHS.isInvalid() ? LHS.get() : nullptr; + if (getLangOpts().CPlusPlus && !LHS.isInvalid()) { - Expr *Base = LHS.get(); + Expr *Base = OrigLHS; const Type* BaseType = Base->getType().getTypePtrOrNull(); if (BaseType && Tok.is(tok::l_paren) && (BaseType->isFunctionType() || @@ -1704,7 +1716,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { if (LHS.isInvalid()) break; - ParseOptionalCXXScopeSpecifier(SS, ObjectType, + ParseOptionalCXXScopeSpecifier(SS, ObjectType, /*EnteringContext=*/false, &MayBePseudoDestructor); if (SS.isNotEmpty()) @@ -1712,18 +1724,32 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { } if (Tok.is(tok::code_completion)) { + tok::TokenKind CorrectedOpKind = + OpKind == tok::arrow ? tok::period : tok::arrow; + ExprResult CorrectedLHS(/*IsInvalid=*/true); + if (getLangOpts().CPlusPlus && OrigLHS) { + const bool DiagsAreSuppressed = Diags.getSuppressAllDiagnostics(); + Diags.setSuppressAllDiagnostics(true); + CorrectedLHS = Actions.ActOnStartCXXMemberReference( + getCurScope(), OrigLHS, OpLoc, CorrectedOpKind, ObjectType, + MayBePseudoDestructor); + Diags.setSuppressAllDiagnostics(DiagsAreSuppressed); + } + + Expr *Base = LHS.get(); + Expr *CorrectedBase = CorrectedLHS.get(); + // Code completion for a member access expression. - if (Expr *Base = LHS.get()) - Actions.CodeCompleteMemberReferenceExpr( - getCurScope(), Base, OpLoc, OpKind == tok::arrow, - ExprStatementTokLoc == Base->getLocStart()); + Actions.CodeCompleteMemberReferenceExpr( + getCurScope(), Base, CorrectedBase, OpLoc, OpKind == tok::arrow, + Base && ExprStatementTokLoc == Base->getLocStart()); cutOffParsing(); return ExprError(); } if (MayBePseudoDestructor && !LHS.isInvalid()) { - LHS = ParseCXXPseudoDestructor(LHS.get(), OpLoc, OpKind, SS, + LHS = ParseCXXPseudoDestructor(LHS.get(), OpLoc, OpKind, SS, ObjectType); break; } @@ -1744,27 +1770,29 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { // 'class' as if it were an identifier. // // This hack allows property access to the 'class' method because it is - // such a common method name. For other C++ keywords that are + // such a common method name. For other C++ keywords that are // Objective-C method names, one must use the message send syntax. IdentifierInfo *Id = Tok.getIdentifierInfo(); SourceLocation Loc = ConsumeToken(); Name.setIdentifier(Id, Loc); - } else if (ParseUnqualifiedId(SS, - /*EnteringContext=*/false, + } else if (ParseUnqualifiedId(SS, + /*EnteringContext=*/false, /*AllowDestructorName=*/true, /*AllowConstructorName=*/ - getLangOpts().MicrosoftExt, + getLangOpts().MicrosoftExt, /*AllowDeductionGuide=*/false, - ObjectType, TemplateKWLoc, Name)) { + ObjectType, &TemplateKWLoc, Name)) { (void)Actions.CorrectDelayedTyposInExpr(LHS); LHS = ExprError(); } - + if (!LHS.isInvalid()) - LHS = Actions.ActOnMemberAccessExpr(getCurScope(), LHS.get(), OpLoc, + LHS = Actions.ActOnMemberAccessExpr(getCurScope(), LHS.get(), OpLoc, OpKind, SS, TemplateKWLoc, Name, CurParsedObjCImpl ? CurParsedObjCImpl->Dcl : nullptr); + if (!LHS.isInvalid() && Tok.is(tok::less)) + checkPotentialAngleBracket(LHS); break; } case tok::plusplus: // postfix-expression: postfix-expression '++' @@ -1854,7 +1882,7 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok, ParenParseOption ExprType = CastExpr; SourceLocation LParenLoc = Tok.getLocation(), RParenLoc; - Operand = ParseParenExpression(ExprType, true/*stopIfCastExpr*/, + Operand = ParseParenExpression(ExprType, true/*stopIfCastExpr*/, false, CastTy, RParenLoc); CastRange = SourceRange(LParenLoc, RParenLoc); @@ -1868,7 +1896,7 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok, if (getLangOpts().CPlusPlus || OpTok.isNot(tok::kw_typeof)) { // GNU typeof in C requires the expression to be parenthesized. Not so for // sizeof/alignof or in C++. Therefore, the parenthesized expression is - // the start of a unary-expression, but doesn't include any postfix + // the start of a unary-expression, but doesn't include any postfix // pieces. Parse these now if present. if (!Operand.isInvalid()) Operand = ParsePostfixExpressionSuffix(Operand.get()); @@ -1881,7 +1909,7 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok, } -/// \brief Parse a sizeof or alignof expression. +/// Parse a sizeof or alignof expression. /// /// \verbatim /// unary-expression: [C99 6.5.3] @@ -1934,7 +1962,7 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() { } else { Diag(Tok, diag::err_sizeof_parameter_pack); } - + if (!Name) return ExprError(); @@ -1943,7 +1971,7 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() { Sema::ReuseLambdaContextDecl); return Actions.ActOnSizeofParameterPackExpr(getCurScope(), - OpTok.getLocation(), + OpTok.getLocation(), *Name, NameLoc, RParenLoc); } @@ -2178,15 +2206,15 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() { TypeResult DestTy = ParseTypeName(); if (DestTy.isInvalid()) return ExprError(); - + // Attempt to consume the r-paren. if (Tok.isNot(tok::r_paren)) { Diag(Tok, diag::err_expected) << tok::r_paren; SkipUntil(tok::r_paren, StopAtSemi); return ExprError(); } - - Res = Actions.ActOnAsTypeExpr(Expr.get(), DestTy.get(), StartLoc, + + Res = Actions.ActOnAsTypeExpr(Expr.get(), DestTy.get(), StartLoc, ConsumeParen()); break; } @@ -2207,15 +2235,15 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() { TypeResult DestTy = ParseTypeName(); if (DestTy.isInvalid()) return ExprError(); - + // Attempt to consume the r-paren. if (Tok.isNot(tok::r_paren)) { Diag(Tok, diag::err_expected) << tok::r_paren; SkipUntil(tok::r_paren, StopAtSemi); return ExprError(); } - - Res = Actions.ActOnConvertVectorExpr(Expr.get(), DestTy.get(), StartLoc, + + Res = Actions.ActOnConvertVectorExpr(Expr.get(), DestTy.get(), StartLoc, ConsumeParen()); break; } @@ -2270,7 +2298,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, CastTy = nullptr; if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteOrdinaryName(getCurScope(), + Actions.CodeCompleteOrdinaryName(getCurScope(), ExprType >= CompoundLiteral? Sema::PCC_ParenthesizedExpression : Sema::PCC_Expression); cutOffParsing(); @@ -2294,7 +2322,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, } BridgeCast = false; } - + // None of these cases should fall through with an invalid Result // unless they've already reported an error. if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) { @@ -2348,16 +2376,16 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, << FixItHint::CreateReplacement(BridgeKeywordLoc, "__bridge_retained"); } - + TypeResult Ty = ParseTypeName(); T.consumeClose(); ColonProtection.restore(); RParenLoc = T.getCloseLocation(); ExprResult SubExpr = ParseCastExpression(/*isUnaryExpression=*/false); - + if (Ty.isInvalid() || SubExpr.isInvalid()) return ExprError(); - + return Actions.ActOnObjCBridgedCast(getCurScope(), OpenLoc, Kind, BridgeKeywordLoc, Ty.get(), RParenLoc, SubExpr.get()); @@ -2383,8 +2411,8 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, ParseSpecifierQualifierList(DS); Declarator DeclaratorInfo(DS, DeclaratorContext::TypeNameContext); ParseDeclarator(DeclaratorInfo); - - // If our type is followed by an identifier and either ':' or ']', then + + // If our type is followed by an identifier and either ':' or ']', then // this is probably an Objective-C message send where the leading '[' is // missing. Recover as if that were the case. if (!DeclaratorInfo.isInvalidType() && Tok.is(tok::identifier) && @@ -2395,10 +2423,10 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, InMessageExpressionRAIIObject InMessage(*this, false); Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); } - Result = ParseObjCMessageExpressionBody(SourceLocation(), - SourceLocation(), + Result = ParseObjCMessageExpressionBody(SourceLocation(), + SourceLocation(), Ty.get(), nullptr); - } else { + } else { // Match the ')'. T.consumeClose(); ColonProtection.restore(); @@ -2475,7 +2503,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, // Reject the cast of super idiom in ObjC. if (Tok.is(tok::identifier) && getLangOpts().ObjC1 && - Tok.getIdentifierInfo() == Ident_super && + Tok.getIdentifierInfo() == Ident_super && getCurScope()->isInObjcMethodScope() && GetLookAheadToken(1).isNot(tok::period)) { Diag(Tok.getLocation(), diag::err_illegal_super_cast) @@ -2490,7 +2518,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, /*isTypeCast=*/IsTypeCast); if (!Result.isInvalid()) { Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc, - DeclaratorInfo, CastTy, + DeclaratorInfo, CastTy, RParenLoc, Result.get()); } return Result; @@ -2499,8 +2527,9 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, Diag(Tok, diag::err_expected_lbrace_in_compound_literal); return ExprError(); } - } else if (Tok.is(tok::ellipsis) && + } else if (ExprType >= FoldExpr && Tok.is(tok::ellipsis) && isFoldOperator(NextToken().getKind())) { + ExprType = FoldExpr; return ParseFoldExpression(ExprResult(), T); } else if (isTypeCast) { // Parse the expression-list. @@ -2512,9 +2541,11 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, if (!ParseSimpleExpressionList(ArgExprs, CommaLocs)) { // FIXME: If we ever support comma expressions as operands to // fold-expressions, we'll need to allow multiple ArgExprs here. - if (ArgExprs.size() == 1 && isFoldOperator(Tok.getKind()) && - NextToken().is(tok::ellipsis)) + if (ExprType >= FoldExpr && ArgExprs.size() == 1 && + isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis)) { + ExprType = FoldExpr; return ParseFoldExpression(ArgExprs[0], T); + } ExprType = SimpleExpr; Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(), @@ -2529,10 +2560,13 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, // expressions are parsed correctly. Result = Actions.CorrectDelayedTyposInExpr(Result); } - ExprType = SimpleExpr; - if (isFoldOperator(Tok.getKind()) && NextToken().is(tok::ellipsis)) + if (ExprType >= FoldExpr && isFoldOperator(Tok.getKind()) && + NextToken().is(tok::ellipsis)) { + ExprType = FoldExpr; return ParseFoldExpression(Result, T); + } + ExprType = SimpleExpr; // Don't build a paren expression unless we actually match a ')'. if (!Result.isInvalid() && Tok.is(tok::r_paren)) @@ -2688,13 +2722,13 @@ ExprResult Parser::ParseGenericSelectionExpression() { if (T.getCloseLocation().isInvalid()) return ExprError(); - return Actions.ActOnGenericSelectionExpr(KeyLoc, DefaultLoc, + return Actions.ActOnGenericSelectionExpr(KeyLoc, DefaultLoc, T.getCloseLocation(), ControllingExpr.get(), Types, Exprs); } -/// \brief Parse A C++1z fold-expression after the opening paren and optional +/// Parse A C++1z fold-expression after the opening paren and optional /// left-hand-side expression. /// /// \verbatim @@ -2791,7 +2825,7 @@ bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs, Expr = ParseAssignmentExpression(); if (Tok.is(tok::ellipsis)) - Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken()); + Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken()); if (Expr.isInvalid()) { SkipUntil(tok::comma, tok::r_paren, StopBeforeMatch); SawError = true; @@ -2802,7 +2836,10 @@ bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs, if (Tok.isNot(tok::comma)) break; // Move to the next argument, remember where the comma was. + Token Comma = Tok; CommaLocs.push_back(ConsumeToken()); + + checkPotentialAngleBracketDelimiter(Comma); } if (SawError) { // Ensure typos get diagnosed when errors were encountered while parsing the @@ -2837,7 +2874,10 @@ Parser::ParseSimpleExpressionList(SmallVectorImpl<Expr*> &Exprs, return false; // Move to the next argument, remember where the comma was. + Token Comma = Tok; CommaLocs.push_back(ConsumeToken()); + + checkPotentialAngleBracketDelimiter(Comma); } } @@ -2852,7 +2892,7 @@ void Parser::ParseBlockId(SourceLocation CaretLoc) { Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Type); return cutOffParsing(); } - + // Parse the specifier-qualifier-list piece. DeclSpec DS(AttrFactory); ParseSpecifierQualifierList(DS); @@ -2929,33 +2969,31 @@ ExprResult Parser::ParseBlockLiteralExpression() { ParseBlockId(CaretLoc); } else { // Otherwise, pretend we saw (void). - ParsedAttributes attrs(AttrFactory); SourceLocation NoLoc; - ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(/*HasProto=*/true, - /*IsAmbiguous=*/false, - /*RParenLoc=*/NoLoc, - /*ArgInfo=*/nullptr, - /*NumArgs=*/0, - /*EllipsisLoc=*/NoLoc, - /*RParenLoc=*/NoLoc, - /*TypeQuals=*/0, - /*RefQualifierIsLvalueRef=*/true, - /*RefQualifierLoc=*/NoLoc, - /*ConstQualifierLoc=*/NoLoc, - /*VolatileQualifierLoc=*/NoLoc, - /*RestrictQualifierLoc=*/NoLoc, - /*MutableLoc=*/NoLoc, - EST_None, - /*ESpecRange=*/SourceRange(), - /*Exceptions=*/nullptr, - /*ExceptionRanges=*/nullptr, - /*NumExceptions=*/0, - /*NoexceptExpr=*/nullptr, - /*ExceptionSpecTokens=*/nullptr, - /*DeclsInPrototype=*/None, - CaretLoc, CaretLoc, - ParamInfo), - attrs, CaretLoc); + ParamInfo.AddTypeInfo( + DeclaratorChunk::getFunction(/*HasProto=*/true, + /*IsAmbiguous=*/false, + /*RParenLoc=*/NoLoc, + /*ArgInfo=*/nullptr, + /*NumArgs=*/0, + /*EllipsisLoc=*/NoLoc, + /*RParenLoc=*/NoLoc, + /*TypeQuals=*/0, + /*RefQualifierIsLvalueRef=*/true, + /*RefQualifierLoc=*/NoLoc, + /*ConstQualifierLoc=*/NoLoc, + /*VolatileQualifierLoc=*/NoLoc, + /*RestrictQualifierLoc=*/NoLoc, + /*MutableLoc=*/NoLoc, EST_None, + /*ESpecRange=*/SourceRange(), + /*Exceptions=*/nullptr, + /*ExceptionRanges=*/nullptr, + /*NumExceptions=*/0, + /*NoexceptExpr=*/nullptr, + /*ExceptionSpecTokens=*/nullptr, + /*DeclsInPrototype=*/None, CaretLoc, + CaretLoc, ParamInfo), + CaretLoc); MaybeParseGNUAttributes(ParamInfo); |
