summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Parse/ParseExpr.cpp')
-rw-r--r--clang/lib/Parse/ParseExpr.cpp30
1 files changed, 22 insertions, 8 deletions
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index b4ba0bc8d8c..3d57ba9cbe0 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -277,6 +277,7 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
// 'logical-OR-expression' as we might expect.
TernaryMiddle = ParseExpression();
if (TernaryMiddle.isInvalid()) {
+ Actions.CorrectDelayedTyposInExpr(LHS);
LHS = ExprError();
TernaryMiddle = nullptr;
}
@@ -345,9 +346,11 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
else
RHS = ParseCastExpression(false);
- if (RHS.isInvalid())
+ if (RHS.isInvalid()) {
+ Actions.CorrectDelayedTyposInExpr(LHS);
LHS = ExprError();
-
+ }
+
// Remember the precedence of this operator and get the precedence of the
// operator immediately to the right of the RHS.
prec::Level ThisPrec = NextTokPrec;
@@ -376,8 +379,10 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
static_cast<prec::Level>(ThisPrec + !isRightAssoc));
RHSIsInitList = false;
- if (RHS.isInvalid())
+ if (RHS.isInvalid()) {
+ Actions.CorrectDelayedTyposInExpr(LHS);
LHS = ExprError();
+ }
NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator,
getLangOpts().CPlusPlus11);
@@ -413,7 +418,9 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
LHS = Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc,
LHS.get(), TernaryMiddle.get(),
RHS.get());
- }
+ } else
+ // Ensure potential typos in the RHS aren't left undiagnosed.
+ Actions.CorrectDelayedTyposInExpr(RHS);
}
}
@@ -441,7 +448,7 @@ class CastExpressionIdValidator : public CorrectionCandidateCallback {
public:
CastExpressionIdValidator(bool AllowTypes, bool AllowNonTypes)
: AllowNonTypes(AllowNonTypes) {
- WantTypeSpecifiers = AllowTypes;
+ WantTypeSpecifiers = WantFunctionLikeCasts = AllowTypes;
}
bool ValidateCandidate(const TypoCorrection &candidate) override {
@@ -899,13 +906,20 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
UnqualifiedId Name;
CXXScopeSpec ScopeSpec;
SourceLocation TemplateKWLoc;
+ Token Replacement;
auto Validator = llvm::make_unique<CastExpressionIdValidator>(
isTypeCast != NotTypeCast, isTypeCast != IsTypeCast);
Validator->IsAddressOfOperand = isAddressOfOperand;
Name.setIdentifier(&II, ILoc);
- Res = Actions.ActOnIdExpression(getCurScope(), ScopeSpec, TemplateKWLoc,
- Name, Tok.is(tok::l_paren),
- isAddressOfOperand, std::move(Validator));
+ Res = Actions.ActOnIdExpression(
+ getCurScope(), ScopeSpec, TemplateKWLoc, Name, Tok.is(tok::l_paren),
+ isAddressOfOperand, std::move(Validator),
+ /*IsInlineAsmIdentifier=*/false, &Replacement);
+ if (!Res.isInvalid() && !Res.get()) {
+ UnconsumeToken(Replacement);
+ return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
+ NotCastExpr, isTypeCast);
+ }
break;
}
case tok::char_constant: // constant: character-constant
OpenPOWER on IntegriCloud