diff options
author | Anders Carlsson <andersca@mac.com> | 2008-12-12 07:38:43 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2008-12-12 07:38:43 +0000 |
commit | 30032889aed4c622bcf5745775aba3d10fda4aa8 (patch) | |
tree | a2e986f2727a5efa86c93e5ff42eb4c79f186c56 /clang/lib/CodeGen | |
parent | e141a9e225e13b1cb6beb44fa25e18337096473c (diff) | |
download | bcm5719-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.cpp | 35 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 9 |
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; |