summaryrefslogtreecommitdiffstats
path: root/clang/include/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang/include/clang')
-rw-r--r--clang/include/clang/Parse/Parser.h9
-rw-r--r--clang/include/clang/Sema/Sema.h75
2 files changed, 56 insertions, 28 deletions
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 9cbad6b634d..3ddbcf52457 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -1588,8 +1588,8 @@ private:
//===--------------------------------------------------------------------===//
// C++ if/switch/while condition expression.
- bool ParseCXXCondition(ExprResult &ExprResult, Decl *&DeclResult,
- SourceLocation Loc, bool ConvertToBoolean);
+ Sema::ConditionResult ParseCXXCondition(SourceLocation Loc,
+ Sema::ConditionKind CK);
//===--------------------------------------------------------------------===//
// C++ Coroutines
@@ -1680,10 +1680,9 @@ private:
unsigned ScopeFlags);
void ParseCompoundStatementLeadingPragmas();
StmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
- bool ParseParenExprOrCondition(ExprResult &ExprResult,
- Decl *&DeclResult,
+ bool ParseParenExprOrCondition(Sema::ConditionResult &CondResult,
SourceLocation Loc,
- bool ConvertToBoolean);
+ Sema::ConditionKind CK);
StmtResult ParseIfStatement(SourceLocation *TrailingElseLoc);
StmtResult ParseSwitchStatement(SourceLocation *TrailingElseLoc);
StmtResult ParseWhileStatement(SourceLocation *TrailingElseLoc);
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 977ffb4dd21..7f2a9429621 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3298,6 +3298,7 @@ public:
public:
class FullExprArg {
public:
+ FullExprArg() : E(nullptr) { }
FullExprArg(Sema &actions) : E(nullptr) { }
ExprResult release() {
@@ -3391,27 +3392,23 @@ public:
ArrayRef<const Attr*> Attrs,
Stmt *SubStmt);
- StmtResult ActOnIfStmt(SourceLocation IfLoc,
- FullExprArg CondVal, Decl *CondVar,
- Stmt *ThenVal,
- SourceLocation ElseLoc, Stmt *ElseVal);
+ class ConditionResult;
+ StmtResult ActOnIfStmt(SourceLocation IfLoc, ConditionResult Cond,
+ Stmt *ThenVal, SourceLocation ElseLoc, Stmt *ElseVal);
StmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc,
- Expr *Cond,
- Decl *CondVar);
+ ConditionResult Cond);
StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc,
Stmt *Switch, Stmt *Body);
- StmtResult ActOnWhileStmt(SourceLocation WhileLoc,
- FullExprArg Cond,
- Decl *CondVar, Stmt *Body);
+ StmtResult ActOnWhileStmt(SourceLocation WhileLoc, ConditionResult Cond,
+ Stmt *Body);
StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body,
- SourceLocation WhileLoc,
- SourceLocation CondLParen, Expr *Cond,
- SourceLocation CondRParen);
+ SourceLocation WhileLoc, SourceLocation CondLParen,
+ Expr *Cond, SourceLocation CondRParen);
StmtResult ActOnForStmt(SourceLocation ForLoc,
SourceLocation LParenLoc,
- Stmt *First, FullExprArg Second,
- Decl *SecondVar,
+ Stmt *First,
+ ConditionResult Second,
FullExprArg Third,
SourceLocation RParenLoc,
Stmt *Body);
@@ -4801,11 +4798,6 @@ public:
bool WarnOnNonAbstractTypes,
SourceLocation DtorLoc);
- DeclResult ActOnCXXConditionDeclaration(Scope *S, Declarator &D);
- ExprResult CheckConditionVariable(VarDecl *ConditionVar,
- SourceLocation StmtLoc,
- bool ConvertToBoolean);
-
ExprResult ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation LParen,
Expr *Operand, SourceLocation RParen);
ExprResult BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand,
@@ -8923,6 +8915,46 @@ public:
/// type, and if so, emit a note describing what happened.
void EmitRelatedResultTypeNoteForReturn(QualType destType);
+ class ConditionResult {
+ Decl *ConditionVar;
+ FullExprArg Condition;
+ bool Invalid;
+
+ friend class Sema;
+ ConditionResult(Decl *ConditionVar, FullExprArg Condition)
+ : ConditionVar(ConditionVar), Condition(Condition), Invalid(false) {}
+ explicit ConditionResult(bool Invalid)
+ : ConditionVar(nullptr), Condition(nullptr), Invalid(Invalid) {}
+
+ public:
+ ConditionResult() : ConditionResult(false) {}
+ bool isInvalid() const { return Invalid; }
+ std::pair<VarDecl *, Expr *> get() const {
+ return std::make_pair(cast_or_null<VarDecl>(ConditionVar),
+ Condition.get());
+ }
+ };
+ static ConditionResult ConditionError() { return ConditionResult(true); }
+
+ enum class ConditionKind {
+ Boolean, ///< A boolean condition, from 'if', 'while', 'for', or 'do'.
+ Switch ///< An integral condition for a 'switch' statement.
+ };
+
+ ConditionResult ActOnCondition(Scope *S, SourceLocation Loc,
+ Expr *SubExpr, ConditionKind CK);
+
+ ConditionResult ActOnConditionVariable(Decl *ConditionVar,
+ SourceLocation StmtLoc,
+ ConditionKind CK);
+
+ DeclResult ActOnCXXConditionDeclaration(Scope *S, Declarator &D);
+
+ ExprResult CheckConditionVariable(VarDecl *ConditionVar,
+ SourceLocation StmtLoc,
+ ConditionKind CK);
+ ExprResult CheckSwitchCondition(SourceLocation SwitchLoc, Expr *Cond);
+
/// CheckBooleanCondition - Diagnose problems involving the use of
/// the given expression as a boolean condition (e.g. in an if
/// statement). Also performs the standard function and array
@@ -8931,10 +8963,7 @@ public:
/// \param Loc - A location associated with the condition, e.g. the
/// 'if' keyword.
/// \return true iff there were any errors
- ExprResult CheckBooleanCondition(Expr *E, SourceLocation Loc);
-
- ExprResult ActOnBooleanCondition(Scope *S, SourceLocation Loc,
- Expr *SubExpr);
+ ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E);
/// DiagnoseAssignmentAsCondition - Given that an expression is
/// being used as a boolean condition, warn if it's an assignment.
OpenPOWER on IntegriCloud