diff options
author | Chris Lattner <sabre@nondot.org> | 2007-06-08 23:31:14 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-06-08 23:31:14 +0000 |
commit | d9d2fb1420afa09e2b5d6b1242c73c642ed39b25 (patch) | |
tree | e91373cc87ec51633c78125ffaed49c551eec8d0 /clang/CodeGen | |
parent | de12ae2fd7c2a7209c2a07120d7e9bc59eb508e0 (diff) | |
download | bcm5719-llvm-d9d2fb1420afa09e2b5d6b1242c73c642ed39b25.tar.gz bcm5719-llvm-d9d2fb1420afa09e2b5d6b1242c73c642ed39b25.zip |
Implement array subscripts for non-vla types.
llvm-svn: 39622
Diffstat (limited to 'clang/CodeGen')
-rw-r--r-- | clang/CodeGen/CGExpr.cpp | 33 | ||||
-rw-r--r-- | clang/CodeGen/CodeGenFunction.cpp | 1 | ||||
-rw-r--r-- | clang/CodeGen/CodeGenFunction.h | 3 |
3 files changed, 37 insertions, 0 deletions
diff --git a/clang/CodeGen/CGExpr.cpp b/clang/CodeGen/CGExpr.cpp index 0af76beff61..3e23c9ad162 100644 --- a/clang/CodeGen/CGExpr.cpp +++ b/clang/CodeGen/CGExpr.cpp @@ -216,6 +216,8 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) { case Expr::UnaryOperatorClass: return EmitUnaryOpLValue(cast<UnaryOperator>(E)); + case Expr::ArraySubscriptExprClass: + return EmitArraySubscriptExpr(cast<ArraySubscriptExpr>(E)); } } @@ -291,6 +293,36 @@ LValue CodeGenFunction::EmitStringLiteralLValue(const StringLiteral *E) { return LValue::getAddr(C); } +LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) { + // The base and index must be pointers or integers, neither of which are + // aggregates. Emit them. + QualType BaseTy; + Value *Base =EmitExprWithUsualUnaryConversions(E->getBase(), BaseTy).getVal(); + QualType IdxTy; + Value *Idx = EmitExprWithUsualUnaryConversions(E->getIdx(), IdxTy).getVal(); + + // Usually the base is the pointer type, but sometimes it is the index. + // Canonicalize to have the pointer as the base. + if (isa<llvm::PointerType>(Idx->getType())) { + std::swap(Base, Idx); + std::swap(BaseTy, IdxTy); + } + + // The pointer is now the base. Extend or truncate the index type to 32 or + // 64-bits. + bool IdxSigned = IdxTy->isSignedIntegerType(); + unsigned IdxBitwidth = cast<IntegerType>(Idx->getType())->getBitWidth(); + if (IdxBitwidth != LLVMPointerWidth) + Idx = Builder.CreateIntCast(Idx, IntegerType::get(LLVMPointerWidth), + IdxSigned, "idxprom"); + + // We know that the pointer points to a type of the correct size, unless the + // size is a VLA. + if (!E->getType()->isConstantSizeType()) + assert(0 && "VLA idx not implemented"); + return LValue::getAddr(Builder.CreateGEP(Base, Idx, "arrayidx")); +} + //===--------------------------------------------------------------------===// // Expression Emission //===--------------------------------------------------------------------===// @@ -307,6 +339,7 @@ RValue CodeGenFunction::EmitExpr(const Expr *E) { // l-values. case Expr::DeclRefExprClass: // FIXME: EnumConstantDecl's are not lvalues. This is wrong for them. + case Expr::ArraySubscriptExprClass: return EmitLoadOfLValue(E); case Expr::StringLiteralClass: return RValue::get(EmitLValue(E).getAddress()); diff --git a/clang/CodeGen/CodeGenFunction.cpp b/clang/CodeGen/CodeGenFunction.cpp index 4239e1e58e7..817c5fca74e 100644 --- a/clang/CodeGen/CodeGenFunction.cpp +++ b/clang/CodeGen/CodeGenFunction.cpp @@ -139,6 +139,7 @@ const llvm::Type *CodeGenFunction::ConvertType(QualType T, SourceLocation Loc) { void CodeGenFunction::GenerateCode(const FunctionDecl *FD) { LLVMIntTy = ConvertType(getContext().IntTy, FD->getLocation()); + LLVMPointerWidth = Target.getPointerWidth(FD->getLocation()); const llvm::FunctionType *Ty = cast<llvm::FunctionType>(ConvertType(FD->getType(), FD->getLocation())); diff --git a/clang/CodeGen/CodeGenFunction.h b/clang/CodeGen/CodeGenFunction.h index ff6ac655acd..6a21b413ca5 100644 --- a/clang/CodeGen/CodeGenFunction.h +++ b/clang/CodeGen/CodeGenFunction.h @@ -45,6 +45,7 @@ namespace clang { class CastExpr; class UnaryOperator; class BinaryOperator; + class ArraySubscriptExpr; class BlockVarDecl; class EnumConstantDecl; @@ -127,6 +128,7 @@ class CodeGenFunction { llvm::Instruction *AllocaInsertPt; const llvm::Type *LLVMIntTy; + unsigned LLVMPointerWidth; /// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C /// decls. @@ -227,6 +229,7 @@ public: LValue EmitDeclRefLValue(const DeclRefExpr *E); LValue EmitStringLiteralLValue(const StringLiteral *E); LValue EmitUnaryOpLValue(const UnaryOperator *E); + LValue EmitArraySubscriptExpr(const ArraySubscriptExpr *E); //===--------------------------------------------------------------------===// // Expression Emission |