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.cpp179
1 files changed, 130 insertions, 49 deletions
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp
index 8d4668b..c7be0d3 100644
--- a/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp
+++ b/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp
@@ -179,7 +179,7 @@ static prec::Level getBinOpPrecedence(tok::TokenKind Kind,
/// \endverbatim
ExprResult Parser::ParseExpression(TypeCastState isTypeCast) {
ExprResult LHS(ParseAssignmentExpression(isTypeCast));
- return ParseRHSOfBinaryExpression(move(LHS), prec::Comma);
+ return ParseRHSOfBinaryExpression(LHS, prec::Comma);
}
/// This routine is called when the '@' is seen and consumed.
@@ -190,7 +190,7 @@ ExprResult Parser::ParseExpression(TypeCastState isTypeCast) {
ExprResult
Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) {
ExprResult LHS(ParseObjCAtExpression(AtLoc));
- return ParseRHSOfBinaryExpression(move(LHS), prec::Comma);
+ return ParseRHSOfBinaryExpression(LHS, prec::Comma);
}
/// This routine is called when a leading '__extension__' is seen and
@@ -210,7 +210,7 @@ Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) {
LHS = Actions.ActOnUnaryOp(getCurScope(), ExtLoc, tok::kw___extension__,
LHS.take());
- return ParseRHSOfBinaryExpression(move(LHS), prec::Comma);
+ return ParseRHSOfBinaryExpression(LHS, prec::Comma);
}
/// \brief Parse an expr that doesn't include (top-level) commas.
@@ -227,7 +227,7 @@ ExprResult Parser::ParseAssignmentExpression(TypeCastState isTypeCast) {
ExprResult LHS = ParseCastExpression(/*isUnaryExpression=*/false,
/*isAddressOfOperand=*/false,
isTypeCast);
- return ParseRHSOfBinaryExpression(move(LHS), prec::Assignment);
+ return ParseRHSOfBinaryExpression(LHS, prec::Assignment);
}
/// \brief Parse an assignment expression where part of an Objective-C message
@@ -265,6 +265,17 @@ ExprResult Parser::ParseConstantExpression(TypeCastState isTypeCast) {
return Actions.ActOnConstantExpression(Res);
}
+bool Parser::isNotExpressionStart() {
+ tok::TokenKind K = Tok.getKind();
+ if (K == tok::l_brace || K == tok::r_brace ||
+ K == tok::kw_for || K == tok::kw_while ||
+ K == tok::kw_if || K == tok::kw_else ||
+ K == tok::kw_goto || K == tok::kw_try)
+ return true;
+ // If this is a decl-specifier, we can't be at the start of an expression.
+ return isKnownToBeDeclarationSpecifier();
+}
+
/// \brief Parse a binary expression that starts with \p LHS and has a
/// precedence of at least \p MinPrec.
ExprResult
@@ -279,12 +290,23 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
// because we are called recursively, or because the token is not a binop),
// then we are done!
if (NextTokPrec < MinPrec)
- return move(LHS);
+ return LHS;
// Consume the operator, saving the operator token for error reporting.
Token OpToken = Tok;
ConsumeToken();
+ // 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, }
+ // We can't do this before consuming the comma, because
+ // isNotExpressionStart() looks at the token stream.
+ if (OpToken.is(tok::comma) && isNotExpressionStart()) {
+ PP.EnterToken(Tok);
+ Tok = OpToken;
+ return LHS;
+ }
+
// Special case handling for the ternary operator.
ExprResult TernaryMiddle(true);
if (NextTokPrec == prec::Conditional) {
@@ -458,7 +480,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
isTypeCast);
if (NotCastExpr)
Diag(Tok, diag::err_expected_expression);
- return move(Res);
+ return Res;
}
namespace {
@@ -698,7 +720,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
case CastExpr:
// We have parsed the cast-expression and no postfix-expr pieces are
// following.
- return move(Res);
+ return Res;
}
break;
@@ -741,6 +763,53 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
// Avoid the unnecessary parse-time lookup in the common case
// where the syntax forbids a type.
const Token &Next = NextToken();
+
+ // If this identifier was reverted from a token ID, and the next token
+ // is a parenthesis, this is likely to be a use of a type trait. Check
+ // those tokens.
+ if (Next.is(tok::l_paren) &&
+ Tok.is(tok::identifier) &&
+ Tok.getIdentifierInfo()->hasRevertedTokenIDToIdentifier()) {
+ IdentifierInfo *II = Tok.getIdentifierInfo();
+ // Build up the mapping of revertable type traits, for future use.
+ if (RevertableTypeTraits.empty()) {
+#define RTT_JOIN(X,Y) X##Y
+#define REVERTABLE_TYPE_TRAIT(Name) \
+ RevertableTypeTraits[PP.getIdentifierInfo(#Name)] \
+ = RTT_JOIN(tok::kw_,Name)
+
+ REVERTABLE_TYPE_TRAIT(__is_arithmetic);
+ REVERTABLE_TYPE_TRAIT(__is_convertible);
+ REVERTABLE_TYPE_TRAIT(__is_empty);
+ REVERTABLE_TYPE_TRAIT(__is_floating_point);
+ REVERTABLE_TYPE_TRAIT(__is_function);
+ REVERTABLE_TYPE_TRAIT(__is_fundamental);
+ REVERTABLE_TYPE_TRAIT(__is_integral);
+ REVERTABLE_TYPE_TRAIT(__is_member_function_pointer);
+ REVERTABLE_TYPE_TRAIT(__is_member_pointer);
+ REVERTABLE_TYPE_TRAIT(__is_pod);
+ REVERTABLE_TYPE_TRAIT(__is_pointer);
+ REVERTABLE_TYPE_TRAIT(__is_same);
+ REVERTABLE_TYPE_TRAIT(__is_scalar);
+ REVERTABLE_TYPE_TRAIT(__is_signed);
+ REVERTABLE_TYPE_TRAIT(__is_unsigned);
+ 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 (Next.is(tok::coloncolon) ||
(!ColonIsSacred && Next.is(tok::colon)) ||
Next.is(tok::less) ||
@@ -758,7 +827,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
// '.'.
IdentifierInfo &II = *Tok.getIdentifierInfo();
SourceLocation ILoc = ConsumeToken();
-
+
// Support 'Class.property' and 'super.property' notation.
if (getLangOpts().ObjC1 && Tok.is(tok::period) &&
(Actions.getTypeName(II, ILoc, getCurScope()) ||
@@ -888,7 +957,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
Res = ParseCastExpression(!getLangOpts().CPlusPlus);
if (!Res.isInvalid())
Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get());
- return move(Res);
+ return Res;
}
case tok::amp: { // unary-expression: '&' cast-expression
// Special treatment because of member pointers
@@ -896,7 +965,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
Res = ParseCastExpression(false, true);
if (!Res.isInvalid())
Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get());
- return move(Res);
+ return Res;
}
case tok::star: // unary-expression: '*' cast-expression
@@ -910,7 +979,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
Res = ParseCastExpression(false);
if (!Res.isInvalid())
Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get());
- return move(Res);
+ return Res;
}
case tok::kw___extension__:{//unary-expression:'__extension__' cast-expr [GNU]
@@ -920,7 +989,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
Res = ParseCastExpression(false);
if (!Res.isInvalid())
Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get());
- return move(Res);
+ return Res;
}
case tok::kw__Alignof: // unary-expression: '_Alignof' '(' type-name ')'
if (!getLangOpts().C11)
@@ -946,7 +1015,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
Tok.getLocation());
Res = Actions.ActOnAddrLabel(AmpAmpLoc, Tok.getLocation(), LD);
ConsumeToken();
- return move(Res);
+ return Res;
}
case tok::kw_const_cast:
case tok::kw_dynamic_cast:
@@ -1132,13 +1201,14 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
if (!Result.isInvalid())
Result = Actions.ActOnNoexceptExpr(KeyLoc, T.getOpenLocation(),
Result.take(), T.getCloseLocation());
- return move(Result);
+ return Result;
}
case tok::kw___is_abstract: // [GNU] unary-type-trait
case tok::kw___is_class:
case tok::kw___is_empty:
case tok::kw___is_enum:
+ case tok::kw___is_interface_class:
case tok::kw___is_literal:
case tok::kw___is_arithmetic:
case tok::kw___is_integral:
@@ -1270,7 +1340,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
switch (Tok.getKind()) {
case tok::code_completion:
if (InMessageExpression)
- return move(LHS);
+ return LHS;
Actions.CodeCompletePostfixExpression(getCurScope(), LHS);
cutOffParsing();
@@ -1290,7 +1360,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
// Fall through; this isn't a message send.
default: // Not a postfix-expression suffix.
- return move(LHS);
+ return LHS;
case tok::l_square: { // postfix-expression: p-e '[' expression ']'
// If we have a array postfix expression that starts on a new line and
// Objective-C is enabled, it is highly likely that the user forgot a
@@ -1300,7 +1370,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
// expression and recover by pretending there is no suffix.
if (getLangOpts().ObjC1 && Tok.isAtStartOfLine() &&
isSimpleObjCMessageExpression())
- return move(LHS);
+ return LHS;
// Reject array indices starting with a lambda-expression. '[[' is
// reserved for attributes.
@@ -1341,7 +1411,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
BalancedDelimiterTracker PT(*this, tok::l_paren);
if (OpKind == tok::lesslessless) {
- ExprVector ExecConfigExprs(Actions);
+ ExprVector ExecConfigExprs;
CommaLocsTy ExecConfigCommaLocs;
SourceLocation OpenLoc = ConsumeToken();
@@ -1372,7 +1442,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
if (!LHS.isInvalid()) {
ExprResult ECResult = Actions.ActOnCUDAExecConfigExpr(getCurScope(),
OpenLoc,
- move_arg(ExecConfigExprs),
+ ExecConfigExprs,
CloseLoc);
if (ECResult.isInvalid())
LHS = ExprError();
@@ -1384,7 +1454,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
Loc = PT.getOpenLocation();
}
- ExprVector ArgExprs(Actions);
+ ExprVector ArgExprs;
CommaLocsTy CommaLocs;
if (Tok.is(tok::code_completion)) {
@@ -1414,7 +1484,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
ArgExprs.size()-1 == CommaLocs.size())&&
"Unexpected number of commas!");
LHS = Actions.ActOnCallExpr(getCurScope(), LHS.take(), Loc,
- move_arg(ArgExprs), Tok.getLocation(),
+ ArgExprs, Tok.getLocation(),
ExecConfig);
PT.consumeClose();
}
@@ -1583,7 +1653,7 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
// If we get here, the operand to the typeof/sizeof/alignof was an expresion.
isCastExpr = false;
- return move(Operand);
+ return Operand;
}
@@ -1653,7 +1723,8 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() {
if (OpTok.is(tok::kw_alignof) || OpTok.is(tok::kw__Alignof))
Diag(OpTok, diag::warn_cxx98_compat_alignof);
- EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
+ EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated,
+ Sema::ReuseLambdaContextDecl);
bool isCastExpr;
ParsedType CastTy;
@@ -1684,7 +1755,7 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() {
/*isType=*/false,
Operand.release(),
CastRange);
- return move(Operand);
+ return Operand;
}
/// ParseBuiltinPrimaryExpression
@@ -1796,7 +1867,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
Res = ParseExpression();
if (Res.isInvalid()) {
SkipUntil(tok::r_paren);
- return move(Res);
+ return Res;
}
Comps.back().U.E = Res.release();
@@ -1823,7 +1894,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
ExprResult Cond(ParseAssignmentExpression());
if (Cond.isInvalid()) {
SkipUntil(tok::r_paren);
- return move(Cond);
+ return Cond;
}
if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
return ExprError();
@@ -1831,7 +1902,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
ExprResult Expr1(ParseAssignmentExpression());
if (Expr1.isInvalid()) {
SkipUntil(tok::r_paren);
- return move(Expr1);
+ return Expr1;
}
if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
return ExprError();
@@ -1839,7 +1910,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
ExprResult Expr2(ParseAssignmentExpression());
if (Expr2.isInvalid()) {
SkipUntil(tok::r_paren);
- return move(Expr2);
+ return Expr2;
}
if (Tok.isNot(tok::r_paren)) {
Diag(Tok, diag::err_expected_rparen);
@@ -2083,7 +2154,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
DeclaratorInfo, CastTy,
RParenLoc, Result.take());
}
- return move(Result);
+ return Result;
}
Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
@@ -2093,13 +2164,13 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
// Parse the expression-list.
InMessageExpressionRAIIObject InMessage(*this, false);
- ExprVector ArgExprs(Actions);
+ ExprVector ArgExprs;
CommaLocsTy CommaLocs;
if (!ParseExpressionList(ArgExprs, CommaLocs)) {
ExprType = SimpleExpr;
Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(),
- move_arg(ArgExprs));
+ ArgExprs);
}
} else {
InMessageExpressionRAIIObject InMessage(*this, false);
@@ -2120,7 +2191,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
T.consumeClose();
RParenLoc = T.getCloseLocation();
- return move(Result);
+ return Result;
}
/// ParseCompoundLiteralExpression - We have parsed the parenthesized type-name
@@ -2141,7 +2212,7 @@ Parser::ParseCompoundLiteralExpression(ParsedType Ty,
ExprResult Result = ParseInitializer();
if (!Result.isInvalid() && Ty)
return Actions.ActOnCompoundLiteral(LParenLoc, Ty, RParenLoc, Result.take());
- return move(Result);
+ return Result;
}
/// ParseStringLiteralExpression - This handles the various token types that
@@ -2211,8 +2282,8 @@ ExprResult Parser::ParseGenericSelectionExpression() {
}
SourceLocation DefaultLoc;
- TypeVector Types(Actions);
- ExprVector Exprs(Actions);
+ TypeVector Types;
+ ExprVector Exprs;
while (1) {
ParsedType Ty;
if (Tok.is(tok::kw_default)) {
@@ -2263,7 +2334,7 @@ ExprResult Parser::ParseGenericSelectionExpression() {
return Actions.ActOnGenericSelectionExpr(KeyLoc, DefaultLoc,
T.getCloseLocation(),
ControllingExpr.release(),
- move_arg(Types), move_arg(Exprs));
+ Types, Exprs);
}
/// ParseExpressionList - Used for C/C++ (argument-)expression-list.
@@ -2415,18 +2486,28 @@ ExprResult Parser::ParseBlockLiteralExpression() {
} else {
// Otherwise, pretend we saw (void).
ParsedAttributes attrs(AttrFactory);
- ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(true, false, false,
- SourceLocation(),
- 0, 0, 0,
- true, SourceLocation(),
- SourceLocation(),
- SourceLocation(),
- SourceLocation(),
- EST_None,
- SourceLocation(),
- 0, 0, 0, 0,
- CaretLoc, CaretLoc,
- ParamInfo),
+ SourceLocation NoLoc;
+ ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(/*HasProto=*/true,
+ /*IsAmbiguous=*/false,
+ /*RParenLoc=*/NoLoc,
+ /*ArgInfo=*/0,
+ /*NumArgs=*/0,
+ /*EllipsisLoc=*/NoLoc,
+ /*RParenLoc=*/NoLoc,
+ /*TypeQuals=*/0,
+ /*RefQualifierIsLvalueRef=*/true,
+ /*RefQualifierLoc=*/NoLoc,
+ /*ConstQualifierLoc=*/NoLoc,
+ /*VolatileQualifierLoc=*/NoLoc,
+ /*MutableLoc=*/NoLoc,
+ EST_None,
+ /*ESpecLoc=*/NoLoc,
+ /*Exceptions=*/0,
+ /*ExceptionRanges=*/0,
+ /*NumExceptions=*/0,
+ /*NoexceptExpr=*/0,
+ CaretLoc, CaretLoc,
+ ParamInfo),
attrs, CaretLoc);
MaybeParseGNUAttributes(ParamInfo);
@@ -2450,7 +2531,7 @@ ExprResult Parser::ParseBlockLiteralExpression() {
Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.take(), getCurScope());
else
Actions.ActOnBlockError(CaretLoc, getCurScope());
- return move(Result);
+ return Result;
}
/// ParseObjCBoolLiteral - This handles the objective-c Boolean literals.
OpenPOWER on IntegriCloud