aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Parse/ParseExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/Parse/ParseExpr.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Parse/ParseExpr.cpp112
1 files changed, 79 insertions, 33 deletions
diff --git a/contrib/llvm-project/clang/lib/Parse/ParseExpr.cpp b/contrib/llvm-project/clang/lib/Parse/ParseExpr.cpp
index fbf79a0a8746..a6a946d7f31b 100644
--- a/contrib/llvm-project/clang/lib/Parse/ParseExpr.cpp
+++ b/contrib/llvm-project/clang/lib/Parse/ParseExpr.cpp
@@ -791,6 +791,7 @@ class CastExpressionIdValidator final : public CorrectionCandidateCallback {
/// [GNU] '__builtin_FUNCTION' '(' ')'
/// [GNU] '__builtin_LINE' '(' ')'
/// [CLANG] '__builtin_COLUMN' '(' ')'
+/// [GNU] '__builtin_source_location' '(' ')'
/// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
/// [GNU] '__null'
/// [OBJC] '[' objc-message-expr ']'
@@ -1211,7 +1212,8 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
DS.SetTypeSpecType(TST_typename, ILoc, PrevSpec, DiagID, Typ,
Actions.getASTContext().getPrintingPolicy());
- Declarator DeclaratorInfo(DS, DeclaratorContext::TypeName);
+ Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
+ DeclaratorContext::TypeName);
TypeResult Ty = Actions.ActOnTypeName(getCurScope(),
DeclaratorInfo);
if (Ty.isInvalid())
@@ -1303,6 +1305,7 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
case tok::kw___builtin_FILE:
case tok::kw___builtin_FUNCTION:
case tok::kw___builtin_LINE:
+ case tok::kw___builtin_source_location:
if (NotPrimaryExpression)
*NotPrimaryExpression = true;
// This parses the complete suffix; we can return early.
@@ -1488,7 +1491,8 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
PrevSpec, DiagID, Type,
Actions.getASTContext().getPrintingPolicy());
- Declarator DeclaratorInfo(DS, DeclaratorContext::TypeName);
+ Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
+ DeclaratorContext::TypeName);
TypeResult Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
if (Ty.isInvalid())
break;
@@ -1524,6 +1528,7 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
case tok::kw___float128:
case tok::kw___ibm128:
case tok::kw_void:
+ case tok::kw_auto:
case tok::kw_typename:
case tok::kw_typeof:
case tok::kw___vector:
@@ -1835,6 +1840,7 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
/// primary-expression
/// postfix-expression '[' expression ']'
/// postfix-expression '[' braced-init-list ']'
+/// postfix-expression '[' expression-list [opt] ']' [C++2b 12.4.5]
/// postfix-expression '(' argument-expression-list[opt] ')'
/// postfix-expression '.' identifier
/// postfix-expression '->' identifier
@@ -1898,30 +1904,58 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
(void)Actions.CorrectDelayedTyposInExpr(LHS);
return ExprError();
}
-
BalancedDelimiterTracker T(*this, tok::l_square);
T.consumeOpen();
Loc = T.getOpenLocation();
- ExprResult Idx, Length, Stride;
+ ExprResult Length, Stride;
SourceLocation ColonLocFirst, ColonLocSecond;
+ ExprVector ArgExprs;
+ bool HasError = false;
PreferredType.enterSubscript(Actions, Tok.getLocation(), LHS.get());
- if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
- Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
- Idx = ParseBraceInitializer();
- } else if (getLangOpts().OpenMP) {
- ColonProtectionRAIIObject RAII(*this);
- // Parse [: or [ expr or [ expr :
- if (!Tok.is(tok::colon)) {
- // [ expr
- Idx = ParseExpression();
+
+ // We try to parse a list of indexes in all language mode first
+ // and, in we find 0 or one index, we try to parse an OpenMP array
+ // section. This allow us to support C++2b multi dimensional subscript and
+ // OpenMp sections in the same language mode.
+ if (!getLangOpts().OpenMP || Tok.isNot(tok::colon)) {
+ if (!getLangOpts().CPlusPlus2b) {
+ ExprResult Idx;
+ if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
+ Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
+ Idx = ParseBraceInitializer();
+ } else {
+ Idx = ParseExpression(); // May be a comma expression
+ }
+ LHS = Actions.CorrectDelayedTyposInExpr(LHS);
+ Idx = Actions.CorrectDelayedTyposInExpr(Idx);
+ if (Idx.isInvalid()) {
+ HasError = true;
+ } else {
+ ArgExprs.push_back(Idx.get());
+ }
+ } else if (Tok.isNot(tok::r_square)) {
+ CommaLocsTy CommaLocs;
+ if (ParseExpressionList(ArgExprs, CommaLocs)) {
+ LHS = Actions.CorrectDelayedTyposInExpr(LHS);
+ HasError = true;
+ }
+ assert(
+ (ArgExprs.empty() || ArgExprs.size() == CommaLocs.size() + 1) &&
+ "Unexpected number of commas!");
}
+ }
+
+ if (ArgExprs.size() <= 1 && getLangOpts().OpenMP) {
+ ColonProtectionRAIIObject RAII(*this);
if (Tok.is(tok::colon)) {
// Consume ':'
ColonLocFirst = ConsumeToken();
if (Tok.isNot(tok::r_square) &&
(getLangOpts().OpenMP < 50 ||
- ((Tok.isNot(tok::colon) && getLangOpts().OpenMP >= 50))))
+ ((Tok.isNot(tok::colon) && getLangOpts().OpenMP >= 50)))) {
Length = ParseExpression();
+ Length = Actions.CorrectDelayedTyposInExpr(Length);
+ }
}
if (getLangOpts().OpenMP >= 50 &&
(OMPClauseKind == llvm::omp::Clause::OMPC_to ||
@@ -1933,27 +1967,23 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
Stride = ParseExpression();
}
}
- } else
- Idx = ParseExpression();
+ }
SourceLocation RLoc = Tok.getLocation();
-
LHS = Actions.CorrectDelayedTyposInExpr(LHS);
- Idx = Actions.CorrectDelayedTyposInExpr(Idx);
- Length = Actions.CorrectDelayedTyposInExpr(Length);
- if (!LHS.isInvalid() && !Idx.isInvalid() && !Length.isInvalid() &&
+
+ if (!LHS.isInvalid() && !HasError && !Length.isInvalid() &&
!Stride.isInvalid() && Tok.is(tok::r_square)) {
if (ColonLocFirst.isValid() || ColonLocSecond.isValid()) {
LHS = Actions.ActOnOMPArraySectionExpr(
- LHS.get(), Loc, Idx.get(), ColonLocFirst, ColonLocSecond,
- Length.get(), Stride.get(), RLoc);
+ LHS.get(), Loc, ArgExprs.empty() ? nullptr : ArgExprs[0],
+ ColonLocFirst, ColonLocSecond, Length.get(), Stride.get(), RLoc);
} else {
LHS = Actions.ActOnArraySubscriptExpr(getCurScope(), LHS.get(), Loc,
- Idx.get(), RLoc);
+ ArgExprs, RLoc);
}
} else {
LHS = ExprError();
- Idx = ExprError();
}
// Match the ']'.
@@ -2268,7 +2298,8 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
if (isTypeIdUnambiguously()) {
DeclSpec DS(AttrFactory);
ParseSpecifierQualifierList(DS);
- Declarator DeclaratorInfo(DS, DeclaratorContext::TypeName);
+ Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
+ DeclaratorContext::TypeName);
ParseDeclarator(DeclaratorInfo);
SourceLocation LParenLoc = PP.getLocForEndOfToken(OpTok.getLocation());
@@ -2482,6 +2513,7 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() {
/// [GNU] '__builtin_FUNCTION' '(' ')'
/// [GNU] '__builtin_LINE' '(' ')'
/// [CLANG] '__builtin_COLUMN' '(' ')'
+/// [GNU] '__builtin_source_location' '(' ')'
/// [OCL] '__builtin_astype' '(' assignment-expression ',' type-name ')'
///
/// [GNU] offsetof-member-designator:
@@ -2704,7 +2736,8 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
case tok::kw___builtin_COLUMN:
case tok::kw___builtin_FILE:
case tok::kw___builtin_FUNCTION:
- case tok::kw___builtin_LINE: {
+ case tok::kw___builtin_LINE:
+ case tok::kw___builtin_source_location: {
// Attempt to consume the r-paren.
if (Tok.isNot(tok::r_paren)) {
Diag(Tok, diag::err_expected) << tok::r_paren;
@@ -2721,6 +2754,8 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
return SourceLocExpr::Line;
case tok::kw___builtin_COLUMN:
return SourceLocExpr::Column;
+ case tok::kw___builtin_source_location:
+ return SourceLocExpr::SourceLocStruct;
default:
llvm_unreachable("invalid keyword");
}
@@ -2838,7 +2873,8 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
// 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)) {
- Diag(Tok, diag::ext_gnu_statement_expr);
+ Diag(Tok, OpenLoc.isMacroID() ? diag::ext_gnu_statement_expr_macro
+ : diag::ext_gnu_statement_expr);
checkCompoundToken(OpenLoc, tok::l_paren, CompoundToken::StmtExprBegin);
@@ -2926,7 +2962,8 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
// Parse the type declarator.
DeclSpec DS(AttrFactory);
ParseSpecifierQualifierList(DS);
- Declarator DeclaratorInfo(DS, DeclaratorContext::TypeName);
+ Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
+ DeclaratorContext::TypeName);
ParseDeclarator(DeclaratorInfo);
// If our type is followed by an identifier and either ':' or ']', then
@@ -3243,7 +3280,7 @@ ExprResult Parser::ParseGenericSelectionExpression() {
Ty = nullptr;
} else {
ColonProtectionRAIIObject X(*this);
- TypeResult TR = ParseTypeName();
+ TypeResult TR = ParseTypeName(nullptr, DeclaratorContext::Association);
if (TR.isInvalid()) {
SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
@@ -3356,7 +3393,9 @@ ExprResult Parser::ParseFoldExpression(ExprResult LHS,
/// \endverbatim
bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
SmallVectorImpl<SourceLocation> &CommaLocs,
- llvm::function_ref<void()> ExpressionStarts) {
+ llvm::function_ref<void()> ExpressionStarts,
+ bool FailImmediatelyOnInvalidExpr,
+ bool EarlyTypoCorrection) {
bool SawError = false;
while (true) {
if (ExpressionStarts)
@@ -3369,6 +3408,9 @@ bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
} else
Expr = ParseAssignmentExpression();
+ if (EarlyTypoCorrection)
+ Expr = Actions.CorrectDelayedTyposInExpr(Expr);
+
if (Tok.is(tok::ellipsis))
Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken());
else if (Tok.is(tok::code_completion)) {
@@ -3382,8 +3424,10 @@ bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
break;
}
if (Expr.isInvalid()) {
- SkipUntil(tok::comma, tok::r_paren, StopBeforeMatch);
SawError = true;
+ if (FailImmediatelyOnInvalidExpr)
+ break;
+ SkipUntil(tok::comma, tok::r_paren, StopBeforeMatch);
} else {
Exprs.push_back(Expr.get());
}
@@ -3454,7 +3498,8 @@ void Parser::ParseBlockId(SourceLocation CaretLoc) {
ParseSpecifierQualifierList(DS);
// Parse the block-declarator.
- Declarator DeclaratorInfo(DS, DeclaratorContext::BlockLiteral);
+ Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),
+ DeclaratorContext::BlockLiteral);
DeclaratorInfo.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
ParseDeclarator(DeclaratorInfo);
@@ -3493,7 +3538,8 @@ ExprResult Parser::ParseBlockLiteralExpression() {
// Parse the return type if present.
DeclSpec DS(AttrFactory);
- Declarator ParamInfo(DS, DeclaratorContext::BlockLiteral);
+ Declarator ParamInfo(DS, ParsedAttributesView::none(),
+ DeclaratorContext::BlockLiteral);
ParamInfo.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
// FIXME: Since the return type isn't actually parsed, it can't be used to
// fill ParamInfo with an initial valid range, so do it manually.