summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2008-12-12 07:38:43 +0000
committerAnders Carlsson <andersca@mac.com>2008-12-12 07:38:43 +0000
commit30032889aed4c622bcf5745775aba3d10fda4aa8 (patch)
treea2e986f2727a5efa86c93e5ff42eb4c79f186c56 /clang/lib/CodeGen
parente141a9e225e13b1cb6beb44fa25e18337096473c (diff)
downloadbcm5719-llvm-30032889aed4c622bcf5745775aba3d10fda4aa8.tar.gz
bcm5719-llvm-30032889aed4c622bcf5745775aba3d10fda4aa8.zip
Implement allocation and sizeof VLAs. This is very basic for now.
llvm-svn: 60943
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp35
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp9
2 files changed, 38 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 9352c35a81a..62684bae496 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -20,6 +20,7 @@
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/GlobalVariable.h"
+#include "llvm/Intrinsics.h"
#include "llvm/Type.h"
using namespace clang;
using namespace CodeGen;
@@ -160,13 +161,37 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
DeclPtr = GenerateStaticBlockVarDecl(D, true, Class);
}
} else {
- CGM.ErrorUnsupported(&D, "variable-length array");
+ const VariableArrayType *VAT = getContext().getAsVariableArrayType(Ty);
+
+ if (!StackSaveValues.back()) {
+ // Save the stack.
+ const llvm::Type *LTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
+ llvm::Value *Stack = CreateTempAlloca(LTy, "saved_stack");
+
+ llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::stacksave);
+ llvm::Value *V = Builder.CreateCall(F);
+
+ Builder.CreateStore(V, Stack);
+
+ StackSaveValues.back() = Stack;
+ }
+ // Get the element type.
+ const llvm::Type *LElemTy = ConvertType(Ty);
+ const llvm::Type *LElemPtrTy =
+ llvm::PointerType::get(LElemTy, D.getType().getAddressSpace());
+
+ llvm::Value *VLASize = GetVLASize(VAT);
+
+ // Allocate memory for the array.
+ llvm::Value *VLA = Builder.CreateAlloca(llvm::Type::Int8Ty, VLASize, "vla");
+ VLA = Builder.CreateBitCast(VLA, LElemPtrTy, "tmp");
- // FIXME: VLA: Add VLA support. For now just make up enough to let
- // the compile go through.
- const llvm::Type *LTy = ConvertType(Ty);
llvm::AllocaInst *Alloc =
- CreateTempAlloca(LTy, D.getIdentifier()->getName());
+ CreateTempAlloca(LElemPtrTy, D.getIdentifier()->getName());
+
+ // FIXME: Volatile?
+ Builder.CreateStore(VLA, Alloc);
+
DeclPtr = Alloc;
}
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 7f417b374aa..857a40e6c8d 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -663,7 +663,14 @@ ScalarExprEmitter::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) {
if (TypeToSize->isVoidType() || TypeToSize->isFunctionType())
return llvm::ConstantInt::get(llvm::APInt(ResultWidth, 1));
- /// FIXME: This doesn't handle VLAs yet!
+ if (const VariableArrayType *VAT =
+ CGF.getContext().getAsVariableArrayType(TypeToSize)) {
+ if (E->isSizeOf())
+ return CGF.GetVLASize(VAT);
+ else
+ assert(0 && "alignof VLAs not implemented yet");
+ }
+
std::pair<uint64_t, unsigned> Info = CGF.getContext().getTypeInfo(TypeToSize);
uint64_t Val = E->isSizeOf() ? Info.first : Info.second;
OpenPOWER on IntegriCloud