23
23
#include " clang/Sema/DeclSpec.h"
24
24
#include " clang/Sema/Scope.h"
25
25
#include " clang/Sema/ParsedTemplate.h"
26
+ #include " clang/Sema/TypoCorrection.h"
26
27
#include " clang/Basic/PrettyStackTrace.h"
27
28
#include " RAIIObjectsForParser.h"
28
29
#include " llvm/ADT/SmallVector.h"
@@ -174,8 +175,8 @@ static prec::Level getBinOpPrecedence(tok::TokenKind Kind,
174
175
// / expression: [C99 6.5.17]
175
176
// / assignment-expression ...[opt]
176
177
// / expression ',' assignment-expression ...[opt]
177
- ExprResult Parser::ParseExpression () {
178
- ExprResult LHS (ParseAssignmentExpression ());
178
+ ExprResult Parser::ParseExpression (TypeCastState isTypeCast ) {
179
+ ExprResult LHS (ParseAssignmentExpression (isTypeCast ));
179
180
return ParseRHSOfBinaryExpression (move (LHS), prec::Comma);
180
181
}
181
182
@@ -211,7 +212,7 @@ Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) {
211
212
}
212
213
213
214
// / ParseAssignmentExpression - Parse an expr that doesn't include commas.
214
- ExprResult Parser::ParseAssignmentExpression () {
215
+ ExprResult Parser::ParseAssignmentExpression (TypeCastState isTypeCast ) {
215
216
if (Tok.is (tok::code_completion)) {
216
217
Actions.CodeCompleteOrdinaryName (getCurScope (), Sema::PCC_Expression);
217
218
cutOffParsing ();
@@ -221,7 +222,9 @@ ExprResult Parser::ParseAssignmentExpression() {
221
222
if (Tok.is (tok::kw_throw))
222
223
return ParseThrowExpression ();
223
224
224
- ExprResult LHS = ParseCastExpression (/* isUnaryExpression=*/ false );
225
+ ExprResult LHS = ParseCastExpression (/* isUnaryExpression=*/ false ,
226
+ /* isAddressOfOperand=*/ false ,
227
+ isTypeCast);
225
228
return ParseRHSOfBinaryExpression (move (LHS), prec::Assignment);
226
229
}
227
230
@@ -417,7 +420,7 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
417
420
// /
418
421
ExprResult Parser::ParseCastExpression (bool isUnaryExpression,
419
422
bool isAddressOfOperand,
420
- bool isTypeCast) {
423
+ TypeCastState isTypeCast) {
421
424
bool NotCastExpr;
422
425
ExprResult Res = ParseCastExpression (isUnaryExpression,
423
426
isAddressOfOperand,
@@ -428,6 +431,29 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
428
431
return move (Res);
429
432
}
430
433
434
+ namespace {
435
+ class CastExpressionIdValidator : public CorrectionCandidateCallback {
436
+ public:
437
+ CastExpressionIdValidator (bool AllowTypes, bool AllowNonTypes)
438
+ : AllowNonTypes(AllowNonTypes) {
439
+ WantTypeSpecifiers = AllowTypes;
440
+ }
441
+
442
+ virtual bool ValidateCandidate (const TypoCorrection &candidate) {
443
+ NamedDecl *ND = candidate.getCorrectionDecl ();
444
+ if (!ND)
445
+ return candidate.isKeyword ();
446
+
447
+ if (isa<TypeDecl>(ND))
448
+ return WantTypeSpecifiers;
449
+ return AllowNonTypes;
450
+ }
451
+
452
+ private:
453
+ bool AllowNonTypes;
454
+ };
455
+ }
456
+
431
457
// / ParseCastExpression - Parse a cast-expression, or, if isUnaryExpression is
432
458
// / true, parse a unary-expression. isAddressOfOperand exists because an
433
459
// / id-expression that is the operand of address-of gets special treatment
@@ -592,7 +618,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
592
618
ExprResult Parser::ParseCastExpression (bool isUnaryExpression,
593
619
bool isAddressOfOperand,
594
620
bool &NotCastExpr,
595
- bool isTypeCast) {
621
+ TypeCastState isTypeCast) {
596
622
ExprResult Res;
597
623
tok::TokenKind SavedKind = Tok.getKind ();
598
624
NotCastExpr = false ;
@@ -623,7 +649,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
623
649
ColonProtectionRAIIObject X (*this , false );
624
650
625
651
Res = ParseParenExpression (ParenExprType, false /* stopIfCastExr*/ ,
626
- isTypeCast, CastTy, RParenLoc);
652
+ isTypeCast == IsTypeCast , CastTy, RParenLoc);
627
653
}
628
654
629
655
switch (ParenExprType) {
@@ -769,9 +795,12 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
769
795
// not.
770
796
UnqualifiedId Name;
771
797
CXXScopeSpec ScopeSpec;
798
+ CastExpressionIdValidator Validator (isTypeCast != NotTypeCast,
799
+ isTypeCast != IsTypeCast);
772
800
Name.setIdentifier (&II, ILoc);
773
801
Res = Actions.ActOnIdExpression (getCurScope (), ScopeSpec, Name,
774
- Tok.is (tok::l_paren), isAddressOfOperand);
802
+ Tok.is (tok::l_paren), isAddressOfOperand,
803
+ &Validator);
775
804
break ;
776
805
}
777
806
case tok::char_constant: // constant: character-constant
@@ -1954,7 +1983,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
1954
1983
// TODO: For cast expression with CastTy.
1955
1984
Result = ParseCastExpression (/* isUnaryExpression=*/ false ,
1956
1985
/* isAddressOfOperand=*/ false ,
1957
- /* isTypeCast=*/ true );
1986
+ /* isTypeCast=*/ IsTypeCast );
1958
1987
if (!Result.isInvalid ()) {
1959
1988
Result = Actions.ActOnCastExpr (getCurScope (), OpenLoc,
1960
1989
DeclaratorInfo, CastTy,
@@ -1981,7 +2010,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
1981
2010
} else {
1982
2011
InMessageExpressionRAIIObject InMessage (*this , false );
1983
2012
1984
- Result = ParseExpression ();
2013
+ Result = ParseExpression (MaybeTypeCast );
1985
2014
ExprType = SimpleExpr;
1986
2015
1987
2016
// Don't build a paren expression unless we actually match a ')'.
0 commit comments