//===--------------------------------------------------------------------===//
// C99 6.5: Expressions.
- ExprResult ParseExpression();
+ /// TypeCastState - State whether an expression is or may be a type cast.
+ enum TypeCastState {
+ NotTypeCast = 0,
+ MaybeTypeCast,
+ IsTypeCast
+ };
+
+ ExprResult ParseExpression(TypeCastState isTypeCast = NotTypeCast);
ExprResult ParseConstantExpression();
// Expr that doesn't include commas.
- ExprResult ParseAssignmentExpression();
+ ExprResult ParseAssignmentExpression(TypeCastState isTypeCast = NotTypeCast);
ExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc);
ExprResult ParseCastExpression(bool isUnaryExpression,
bool isAddressOfOperand,
bool &NotCastExpr,
- bool isTypeCast);
+ TypeCastState isTypeCast);
ExprResult ParseCastExpression(bool isUnaryExpression,
bool isAddressOfOperand = false,
- bool isTypeCast = false);
+ TypeCastState isTypeCast = NotTypeCast);
/// Returns true if the next token would start a postfix-expression
/// suffix.
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/ParsedTemplate.h"
+#include "clang/Sema/TypoCorrection.h"
#include "clang/Basic/PrettyStackTrace.h"
#include "RAIIObjectsForParser.h"
#include "llvm/ADT/SmallVector.h"
/// expression: [C99 6.5.17]
/// assignment-expression ...[opt]
/// expression ',' assignment-expression ...[opt]
-ExprResult Parser::ParseExpression() {
- ExprResult LHS(ParseAssignmentExpression());
+ExprResult Parser::ParseExpression(TypeCastState isTypeCast) {
+ ExprResult LHS(ParseAssignmentExpression(isTypeCast));
return ParseRHSOfBinaryExpression(move(LHS), prec::Comma);
}
}
/// ParseAssignmentExpression - Parse an expr that doesn't include commas.
-ExprResult Parser::ParseAssignmentExpression() {
+ExprResult Parser::ParseAssignmentExpression(TypeCastState isTypeCast) {
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression);
cutOffParsing();
if (Tok.is(tok::kw_throw))
return ParseThrowExpression();
- ExprResult LHS = ParseCastExpression(/*isUnaryExpression=*/false);
+ ExprResult LHS = ParseCastExpression(/*isUnaryExpression=*/false,
+ /*isAddressOfOperand=*/false,
+ isTypeCast);
return ParseRHSOfBinaryExpression(move(LHS), prec::Assignment);
}
///
ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
bool isAddressOfOperand,
- bool isTypeCast) {
+ TypeCastState isTypeCast) {
bool NotCastExpr;
ExprResult Res = ParseCastExpression(isUnaryExpression,
isAddressOfOperand,
return move(Res);
}
+namespace {
+class CastExpressionIdValidator : public CorrectionCandidateCallback {
+ public:
+ CastExpressionIdValidator(bool AllowTypes, bool AllowNonTypes)
+ : AllowNonTypes(AllowNonTypes) {
+ WantTypeSpecifiers = AllowTypes;
+ }
+
+ virtual bool ValidateCandidate(const TypoCorrection &candidate) {
+ NamedDecl *ND = candidate.getCorrectionDecl();
+ if (!ND)
+ return candidate.isKeyword();
+
+ if (isa<TypeDecl>(ND))
+ return WantTypeSpecifiers;
+ return AllowNonTypes;
+ }
+
+ private:
+ bool AllowNonTypes;
+};
+}
+
/// ParseCastExpression - Parse a cast-expression, or, if isUnaryExpression is
/// true, parse a unary-expression. isAddressOfOperand exists because an
/// id-expression that is the operand of address-of gets special treatment
ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
bool isAddressOfOperand,
bool &NotCastExpr,
- bool isTypeCast) {
+ TypeCastState isTypeCast) {
ExprResult Res;
tok::TokenKind SavedKind = Tok.getKind();
NotCastExpr = false;
ColonProtectionRAIIObject X(*this, false);
Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/,
- isTypeCast, CastTy, RParenLoc);
+ isTypeCast == IsTypeCast, CastTy, RParenLoc);
}
switch (ParenExprType) {
// not.
UnqualifiedId Name;
CXXScopeSpec ScopeSpec;
+ CastExpressionIdValidator Validator(isTypeCast != NotTypeCast,
+ isTypeCast != IsTypeCast);
Name.setIdentifier(&II, ILoc);
Res = Actions.ActOnIdExpression(getCurScope(), ScopeSpec, Name,
- Tok.is(tok::l_paren), isAddressOfOperand);
+ Tok.is(tok::l_paren), isAddressOfOperand,
+ &Validator);
break;
}
case tok::char_constant: // constant: character-constant
// TODO: For cast expression with CastTy.
Result = ParseCastExpression(/*isUnaryExpression=*/false,
/*isAddressOfOperand=*/false,
- /*isTypeCast=*/true);
+ /*isTypeCast=*/IsTypeCast);
if (!Result.isInvalid()) {
Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc,
DeclaratorInfo, CastTy,
} else {
InMessageExpressionRAIIObject InMessage(*this, false);
- Result = ParseExpression();
+ Result = ParseExpression(MaybeTypeCast);
ExprType = SimpleExpr;
// Don't build a paren expression unless we actually match a ')'.