diff options
author | Anders Carlsson <andersca@mac.com> | 2008-12-21 00:11:23 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2008-12-21 00:11:23 +0000 |
commit | 8b33c087fc6d97064b6620c96c732ebc5c003fb2 (patch) | |
tree | b11032be775639fd18541f6ccd48801c9bb462e0 | |
parent | 86f194083504938df72135b5b66bf0c5cafd9498 (diff) |
Handle VLA indexing
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61295 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/Type.h | 4 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 1 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 21 |
3 files changed, 23 insertions, 3 deletions
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<EnumDecl>(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"), |