diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp | 172 |
1 files changed, 137 insertions, 35 deletions
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp index 9521ffb..45f1b1d 100644 --- a/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp @@ -389,7 +389,7 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { // parentheses so that the code remains well-formed in C++0x. if (!GreaterThanIsOperator && OpToken.is(tok::greatergreater)) SuggestParentheses(OpToken.getLocation(), - diag::warn_cxx0x_right_shift_in_template_arg, + diag::warn_cxx11_right_shift_in_template_arg, SourceRange(Actions.getExprRange(LHS.get()).getBegin(), Actions.getExprRange(RHS.get()).getEnd())); @@ -491,6 +491,8 @@ class CastExpressionIdValidator : public CorrectionCandidateCallback { /// [C11] generic-selection /// '__func__' [C99 6.4.2.2] /// [GNU] '__FUNCTION__' +/// [MS] '__FUNCDNAME__' +/// [MS] 'L__FUNCTION__' /// [GNU] '__PRETTY_FUNCTION__' /// [GNU] '(' compound-statement ')' /// [GNU] '__builtin_va_arg' '(' assignment-expression ',' type-name ')' @@ -591,6 +593,7 @@ class CastExpressionIdValidator : public CorrectionCandidateCallback { /// '__is_final' /// '__is_pod' /// '__is_polymorphic' +/// '__is_sealed' [MS] /// '__is_trivial' /// '__is_union' /// @@ -741,19 +744,19 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, REVERTABLE_TYPE_TRAIT(__is_void); #undef REVERTABLE_TYPE_TRAIT #undef RTT_JOIN - } + } - // If we find that this is in fact the name of a type trait, - // update the token kind in place and parse again to treat it as - // the appropriate kind of type trait. - llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind>::iterator Known - = RevertableTypeTraits.find(II); - if (Known != RevertableTypeTraits.end()) { - Tok.setKind(Known->second); - return ParseCastExpression(isUnaryExpression, isAddressOfOperand, - NotCastExpr, isTypeCast); - } + // If we find that this is in fact the name of a type trait, + // update the token kind in place and parse again to treat it as + // the appropriate kind of type trait. + llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind>::iterator Known + = RevertableTypeTraits.find(II); + if (Known != RevertableTypeTraits.end()) { + Tok.setKind(Known->second); + return ParseCastExpression(isUnaryExpression, isAddressOfOperand, + NotCastExpr, isTypeCast); } + } if (Next.is(tok::coloncolon) || (!ColonIsSacred && Next.is(tok::colon)) || @@ -869,6 +872,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, break; case tok::kw___func__: // primary-expression: __func__ [C99 6.4.2.2] case tok::kw___FUNCTION__: // primary-expression: __FUNCTION__ [GNU] + case tok::kw___FUNCDNAME__: // primary-expression: __FUNCDNAME__ [MS] case tok::kw_L__FUNCTION__: // primary-expression: L__FUNCTION__ [MS] case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU] Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind); @@ -888,6 +892,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, case tok::kw___builtin_offsetof: case tok::kw___builtin_choose_expr: case tok::kw___builtin_astype: // primary-expression: [OCL] as_type() + case tok::kw___builtin_convertvector: return ParseBuiltinPrimaryExpression(); case tok::kw___null: return Actions.ActOnGNUNullExpr(ConsumeToken()); @@ -1042,12 +1047,18 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, // typename-specifier braced-init-list if (TryAnnotateTypeOrScopeToken()) return ExprError(); + + if (!Actions.isSimpleTypeSpecifier(Tok.getKind())) + // We are trying to parse a simple-type-specifier but might not get such + // a token after error recovery. + return ExprError(); } // postfix-expression: simple-type-specifier '(' expression-list[opt] ')' // simple-type-specifier braced-init-list // DeclSpec DS(AttrFactory); + ParseCXXSimpleTypeSpecifier(DS); if (Tok.isNot(tok::l_paren) && (!getLangOpts().CPlusPlus11 || Tok.isNot(tok::l_brace))) @@ -1193,6 +1204,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, case tok::kw___is_trivially_copyable: case tok::kw___is_union: case tok::kw___is_final: + case tok::kw___is_sealed: case tok::kw___has_trivial_constructor: case tok::kw___has_trivial_move_constructor: case tok::kw___has_trivial_copy: @@ -1371,7 +1383,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { CommaLocsTy ExecConfigCommaLocs; SourceLocation OpenLoc = ConsumeToken(); - if (ParseExpressionList(ExecConfigExprs, ExecConfigCommaLocs)) { + if (ParseSimpleExpressionList(ExecConfigExprs, ExecConfigCommaLocs)) { LHS = ExprError(); } @@ -1379,12 +1391,12 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { if (Tok.is(tok::greatergreatergreater)) { ConsumeToken(); } else if (LHS.isInvalid()) { - SkipUntil(tok::greatergreatergreater); + SkipUntil(tok::greatergreatergreater, StopAtSemi); } else { // There was an error closing the brackets Diag(Tok, diag::err_expected_ggg); Diag(OpenLoc, diag::note_matching) << "<<<"; - SkipUntil(tok::greatergreatergreater); + SkipUntil(tok::greatergreatergreater, StopAtSemi); LHS = ExprError(); } @@ -1430,7 +1442,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { // Match the ')'. if (LHS.isInvalid()) { - SkipUntil(tok::r_paren); + SkipUntil(tok::r_paren, StopAtSemi); } else if (Tok.isNot(tok::r_paren)) { PT.consumeClose(); LHS = ExprError(); @@ -1457,7 +1469,18 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { ParsedType ObjectType; bool MayBePseudoDestructor = false; if (getLangOpts().CPlusPlus && !LHS.isInvalid()) { - LHS = Actions.ActOnStartCXXMemberReference(getCurScope(), LHS.take(), + Expr *Base = LHS.take(); + const Type* BaseType = Base->getType().getTypePtrOrNull(); + if (BaseType && Tok.is(tok::l_paren) && + (BaseType->isFunctionType() || + BaseType->isSpecificPlaceholderType(BuiltinType::BoundMember))) { + Diag(OpLoc, diag::err_function_is_not_record) + << (OpKind == tok::arrow) << Base->getSourceRange() + << FixItHint::CreateRemoval(OpLoc); + return ParsePostfixExpressionSuffix(Base); + } + + LHS = Actions.ActOnStartCXXMemberReference(getCurScope(), Base, OpLoc, OpKind, ObjectType, MayBePseudoDestructor); if (LHS.isInvalid()) @@ -1570,6 +1593,28 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok, // If the operand doesn't start with an '(', it must be an expression. if (Tok.isNot(tok::l_paren)) { + // If construct allows a form without parenthesis, user may forget to put + // pathenthesis around type name. + if (OpTok.is(tok::kw_sizeof) || OpTok.is(tok::kw___alignof) || + OpTok.is(tok::kw_alignof) || OpTok.is(tok::kw__Alignof)) { + bool isAmbiguousTypeId; + if (isTypeIdInParens(isAmbiguousTypeId)) { + DeclSpec DS(AttrFactory); + ParseSpecifierQualifierList(DS); + Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); + ParseDeclarator(DeclaratorInfo); + + SourceLocation LParenLoc = PP.getLocForEndOfToken(OpTok.getLocation()); + SourceLocation RParenLoc = PP.getLocForEndOfToken(PrevTokLocation); + Diag(LParenLoc, diag::err_expected_parentheses_around_typename) + << OpTok.getName() + << FixItHint::CreateInsertion(LParenLoc, "(") + << FixItHint::CreateInsertion(RParenLoc, ")"); + isCastExpr = true; + return ExprEmpty(); + } + } + isCastExpr = false; if (OpTok.is(tok::kw_typeof) && !getLangOpts().CPlusPlus) { Diag(Tok,diag::err_expected_lparen_after_id) << OpTok.getIdentifierInfo(); @@ -1651,7 +1696,7 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() { RParenLoc = PP.getLocForEndOfToken(NameLoc); } else { Diag(Tok, diag::err_expected_parameter_pack); - SkipUntil(tok::r_paren); + SkipUntil(tok::r_paren, StopAtSemi); } } else if (Tok.is(tok::identifier)) { Name = Tok.getIdentifierInfo(); @@ -1669,6 +1714,9 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() { if (!Name) return ExprError(); + EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated, + Sema::ReuseLambdaContextDecl); + return Actions.ActOnSizeofParameterPackExpr(getCurScope(), OpTok.getLocation(), *Name, NameLoc, @@ -1774,7 +1822,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() { SourceLocation TypeLoc = Tok.getLocation(); TypeResult Ty = ParseTypeName(); if (Ty.isInvalid()) { - SkipUntil(tok::r_paren); + SkipUntil(tok::r_paren, StopAtSemi); return ExprError(); } @@ -1784,7 +1832,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() { // We must have at least one identifier here. if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_ident); - SkipUntil(tok::r_paren); + SkipUntil(tok::r_paren, StopAtSemi); return ExprError(); } @@ -1806,7 +1854,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() { if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_ident); - SkipUntil(tok::r_paren); + SkipUntil(tok::r_paren, StopAtSemi); return ExprError(); } Comps.back().U.IdentInfo = Tok.getIdentifierInfo(); @@ -1824,7 +1872,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() { Comps.back().LocStart = ST.getOpenLocation(); Res = ParseExpression(); if (Res.isInvalid()) { - SkipUntil(tok::r_paren); + SkipUntil(tok::r_paren, StopAtSemi); return Res; } Comps.back().U.E = Res.release(); @@ -1851,7 +1899,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() { case tok::kw___builtin_choose_expr: { ExprResult Cond(ParseAssignmentExpression()); if (Cond.isInvalid()) { - SkipUntil(tok::r_paren); + SkipUntil(tok::r_paren, StopAtSemi); return Cond; } if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren)) @@ -1859,7 +1907,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() { ExprResult Expr1(ParseAssignmentExpression()); if (Expr1.isInvalid()) { - SkipUntil(tok::r_paren); + SkipUntil(tok::r_paren, StopAtSemi); return Expr1; } if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren)) @@ -1867,7 +1915,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() { ExprResult Expr2(ParseAssignmentExpression()); if (Expr2.isInvalid()) { - SkipUntil(tok::r_paren); + SkipUntil(tok::r_paren, StopAtSemi); return Expr2; } if (Tok.isNot(tok::r_paren)) { @@ -1882,7 +1930,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() { // The first argument is an expression to be converted, followed by a comma. ExprResult Expr(ParseAssignmentExpression()); if (Expr.isInvalid()) { - SkipUntil(tok::r_paren); + SkipUntil(tok::r_paren, StopAtSemi); return ExprError(); } @@ -1898,7 +1946,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() { // Attempt to consume the r-paren. if (Tok.isNot(tok::r_paren)) { Diag(Tok, diag::err_expected_rparen); - SkipUntil(tok::r_paren); + SkipUntil(tok::r_paren, StopAtSemi); return ExprError(); } @@ -1906,6 +1954,34 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() { ConsumeParen()); break; } + case tok::kw___builtin_convertvector: { + // The first argument is an expression to be converted, followed by a comma. + ExprResult Expr(ParseAssignmentExpression()); + if (Expr.isInvalid()) { + SkipUntil(tok::r_paren, StopAtSemi); + return ExprError(); + } + + if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", + tok::r_paren)) + return ExprError(); + + // Second argument is the type to bitcast to. + 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_rparen); + SkipUntil(tok::r_paren, StopAtSemi); + return ExprError(); + } + + Res = Actions.ActOnConvertVectorExpr(Expr.take(), DestTy.get(), StartLoc, + ConsumeParen()); + break; + } } if (Res.isInvalid()) @@ -2129,7 +2205,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, ExprVector ArgExprs; CommaLocsTy CommaLocs; - if (!ParseExpressionList(ArgExprs, CommaLocs)) { + if (!ParseSimpleExpressionList(ArgExprs, CommaLocs)) { ExprType = SimpleExpr; Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(), ArgExprs); @@ -2147,7 +2223,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, // Match the ')'. if (Result.isInvalid()) { - SkipUntil(tok::r_paren); + SkipUntil(tok::r_paren, StopAtSemi); return ExprError(); } @@ -2233,13 +2309,13 @@ ExprResult Parser::ParseGenericSelectionExpression() { EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated); ControllingExpr = ParseAssignmentExpression(); if (ControllingExpr.isInvalid()) { - SkipUntil(tok::r_paren); + SkipUntil(tok::r_paren, StopAtSemi); return ExprError(); } } if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "")) { - SkipUntil(tok::r_paren); + SkipUntil(tok::r_paren, StopAtSemi); return ExprError(); } @@ -2254,7 +2330,7 @@ ExprResult Parser::ParseGenericSelectionExpression() { if (!DefaultLoc.isInvalid()) { Diag(Tok, diag::err_duplicate_default_assoc); Diag(DefaultLoc, diag::note_previous_default_assoc); - SkipUntil(tok::r_paren); + SkipUntil(tok::r_paren, StopAtSemi); return ExprError(); } DefaultLoc = ConsumeToken(); @@ -2263,7 +2339,7 @@ ExprResult Parser::ParseGenericSelectionExpression() { ColonProtectionRAIIObject X(*this); TypeResult TR = ParseTypeName(); if (TR.isInvalid()) { - SkipUntil(tok::r_paren); + SkipUntil(tok::r_paren, StopAtSemi); return ExprError(); } Ty = TR.release(); @@ -2271,7 +2347,7 @@ ExprResult Parser::ParseGenericSelectionExpression() { Types.push_back(Ty); if (ExpectAndConsume(tok::colon, diag::err_expected_colon, "")) { - SkipUntil(tok::r_paren); + SkipUntil(tok::r_paren, StopAtSemi); return ExprError(); } @@ -2279,7 +2355,7 @@ ExprResult Parser::ParseGenericSelectionExpression() { // evaluated context. ExprResult ER(ParseAssignmentExpression()); if (ER.isInvalid()) { - SkipUntil(tok::r_paren); + SkipUntil(tok::r_paren, StopAtSemi); return ExprError(); } Exprs.push_back(ER.release()); @@ -2358,6 +2434,32 @@ bool Parser::ParseExpressionList(SmallVectorImpl<Expr*> &Exprs, } } +/// ParseSimpleExpressionList - A simple comma-separated list of expressions, +/// used for misc language extensions. +/// +/// \verbatim +/// simple-expression-list: +/// assignment-expression +/// simple-expression-list , assignment-expression +/// \endverbatim +bool +Parser::ParseSimpleExpressionList(SmallVectorImpl<Expr*> &Exprs, + SmallVectorImpl<SourceLocation> &CommaLocs) { + while (1) { + ExprResult Expr = ParseAssignmentExpression(); + if (Expr.isInvalid()) + return true; + + Exprs.push_back(Expr.release()); + + if (Tok.isNot(tok::comma)) + return false; + + // Move to the next argument, remember where the comma was. + CommaLocs.push_back(ConsumeToken()); + } +} + /// ParseBlockId - Parse a block-id, which roughly looks like int (int x). /// /// \verbatim |