From: Anders Carlsson Date: Sun, 21 Dec 2008 00:11:23 +0000 (+0000) Subject: Handle VLA indexing X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8b33c087fc6d97064b6620c96c732ebc5c003fb2;p=clang Handle VLA indexing git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61295 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index ffcc9f6457..93d31c7e7d 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -826,6 +826,10 @@ public: assert (0 && "Cannnot unique VariableArrayTypes."); } + /// Returns the innermost element type of a VAT - for example + /// will return "int" for int[n][m]. + QualType getBaseType() const; + protected: virtual void EmitImpl(llvm::Serializer& S) const; static Type* CreateImpl(ASTContext& Context,llvm::Deserializer& D); diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 5909c976aa..b9d97ced13 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -803,7 +803,6 @@ bool EnumType::classof(const TagType *TT) { return isa(TT->getDecl()); } - //===----------------------------------------------------------------------===// // Type Printing //===----------------------------------------------------------------------===// diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index b085de304a..3bf6b2f809 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -706,8 +706,25 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) { // We know that the pointer points to a type of the correct size, unless the // size is a VLA. - if (!E->getType()->isConstantSizeType()) - return EmitUnsupportedLValue(E, "VLA index"); + if (const VariableArrayType *VAT = + getContext().getAsVariableArrayType(E->getType())) { + llvm::Value *VLASize = VLASizeMap[VAT]; + + Idx = Builder.CreateMul(Idx, VLASize); + + QualType BaseType = VAT->getElementType(); + + // Divide by the element size. + while (const VariableArrayType *AT = + getContext().getAsVariableArrayType(BaseType)) + BaseType = AT->getElementType(); + + uint64_t BaseTypeSize = getContext().getTypeSize(BaseType) / 8; + Idx = Builder.CreateUDiv(Idx, + llvm::ConstantInt::get(Idx->getType(), + BaseTypeSize)); + } + QualType ExprTy = getContext().getCanonicalType(E->getBase()->getType()); return LValue::MakeAddr(Builder.CreateGEP(Base, Idx, "arrayidx"),