diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-05-06 06:51:17 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-05-06 06:51:17 +0000 |
commit | 692eafd2052fb6ca581530d6f3569eea9520a508 (patch) | |
tree | eb574b7aab5fe2222357ba8188f852a945d497ce /lib | |
parent | c194c95036b7bf1281a6f2ed683f7c85ee5d2c20 (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.cpp | 39 |
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; |