Work in preparation for VLAs. Make sure to restore the stack if necessary (Saving the stack isn't implemented right now :)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60925 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
index 0a67e57..1c5cb90 100644
--- a/lib/CodeGen/CGStmt.cpp
+++ b/lib/CodeGen/CGStmt.cpp
@@ -16,8 +16,9 @@
#include "CodeGenFunction.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/TargetInfo.h"
-#include "llvm/InlineAsm.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/InlineAsm.h"
+#include "llvm/Intrinsics.h"
using namespace clang;
using namespace CodeGen;
@@ -129,6 +130,9 @@
DI->EmitRegionStart(CurFn, Builder);
}
+ // Push a null stack save value.
+ StackSaveValues.push_back(0);
+
for (CompoundStmt::const_body_iterator I = S.body_begin(),
E = S.body_end()-GetLast; I != E; ++I)
EmitStmt(*I);
@@ -139,22 +143,33 @@
DI->EmitRegionEnd(CurFn, Builder);
}
- if (!GetLast)
- return RValue::get(0);
+ RValue RV;
+ if (!GetLast)
+ RV = RValue::get(0);
+ else {
+ // We have to special case labels here. They are statements, but when put
+ // at the end of a statement expression, they yield the value of their
+ // subexpression. Handle this by walking through all labels we encounter,
+ // emitting them before we evaluate the subexpr.
+ const Stmt *LastStmt = S.body_back();
+ while (const LabelStmt *LS = dyn_cast<LabelStmt>(LastStmt)) {
+ EmitLabel(*LS);
+ LastStmt = LS->getSubStmt();
+ }
- // We have to special case labels here. They are statements, but when put at
- // the end of a statement expression, they yield the value of their
- // subexpression. Handle this by walking through all labels we encounter,
- // emitting them before we evaluate the subexpr.
- const Stmt *LastStmt = S.body_back();
- while (const LabelStmt *LS = dyn_cast<LabelStmt>(LastStmt)) {
- EmitLabel(*LS);
- LastStmt = LS->getSubStmt();
+ EnsureInsertPoint();
+
+ RV = EmitAnyExpr(cast<Expr>(LastStmt), AggLoc);
+ }
+
+ if (llvm::Value *V = StackSaveValues.pop_back_val()) {
+ V = Builder.CreateLoad(V, "tmp");
+
+ llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::stackrestore);
+ Builder.CreateCall(F, V);
}
- EnsureInsertPoint();
-
- return EmitAnyExpr(cast<Expr>(LastStmt), AggLoc);
+ return RV;
}
void CodeGenFunction::EmitBlock(llvm::BasicBlock *BB, bool IsFinished) {
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 600582c..952c3b3 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -166,6 +166,11 @@
/// statement range in current switch instruction.
llvm::BasicBlock *CaseRangeBlock;
+ /// StackSaveValues - A stack(!) of stack save values. When a new scope is
+ /// entered, a null is pushed on this stack. If a VLA is emitted, then
+ /// the return value of llvm.stacksave() is stored at the top of this stack.
+ llvm::SmallVector<llvm::Value*, 8> StackSaveValues;
+
public:
CodeGenFunction(CodeGenModule &cgm);