summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp172
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
OpenPOWER on IntegriCloud