aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-05-06 06:51:17 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-05-06 06:51:17 +0000
commit692eafd2052fb6ca581530d6f3569eea9520a508 (patch)
treeeb574b7aab5fe2222357ba8188f852a945d497ce /lib
parentc194c95036b7bf1281a6f2ed683f7c85ee5d2c20 (diff)
C++1y: support range-based for loops in constant expressions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@181184 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ExprConstant.cpp39
1 files changed, 39 insertions, 0 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 14503f4752..95bfd63f4d 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -2636,6 +2636,45 @@ static EvalStmtResult EvaluateStmt(APValue &Result, EvalInfo &Info,
return ESR_Succeeded;
}
+ case Stmt::CXXForRangeStmtClass: {
+ const CXXForRangeStmt *FS = cast<CXXForRangeStmt>(S);
+
+ // Initialize the __range variable.
+ EvalStmtResult ESR = EvaluateStmt(Result, Info, FS->getRangeStmt());
+ if (ESR != ESR_Succeeded)
+ return ESR;
+
+ // Create the __begin and __end iterators.
+ ESR = EvaluateStmt(Result, Info, FS->getBeginEndStmt());
+ if (ESR != ESR_Succeeded)
+ return ESR;
+
+ while (true) {
+ // Condition: __begin != __end.
+ bool Continue = true;
+ if (!EvaluateAsBooleanCondition(FS->getCond(), Continue, Info))
+ return ESR_Failed;
+ if (!Continue)
+ break;
+
+ // User's variable declaration, initialized by *__begin.
+ ESR = EvaluateStmt(Result, Info, FS->getLoopVarStmt());
+ if (ESR != ESR_Succeeded)
+ return ESR;
+
+ // Loop body.
+ ESR = EvaluateLoopBody(Result, Info, FS->getBody());
+ if (ESR != ESR_Continue)
+ return ESR;
+
+ // Increment: ++__begin
+ if (!EvaluateIgnoredValue(Info, FS->getInc()))
+ return ESR_Failed;
+ }
+
+ return ESR_Succeeded;
+ }
+
case Stmt::ContinueStmtClass:
return ESR_Continue;