From: Anders Carlsson Date: Fri, 12 Dec 2008 07:38:43 +0000 (+0000) Subject: Implement allocation and sizeof VLAs. This is very basic for now. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5d46315ca3cbbfe0d0f5f65520b618fb05dd4446;p=clang Implement allocation and sizeof VLAs. This is very basic for now. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60943 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 9352c35a81..62684bae49 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/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/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index 7f417b374a..857a40e6c8 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/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 Info = CGF.getContext().getTypeInfo(TypeToSize); uint64_t Val = E->isSizeOf() ? Info.first : Info.second;