Implement array subscripts for non-vla types.

llvm-svn: 39622
This commit is contained in:
Chris Lattner 2007-06-08 23:31:14 +00:00
parent de12ae2fd7
commit d9d2fb1420
5 changed files with 46 additions and 1 deletions

View File

@ -216,6 +216,8 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
case Expr::UnaryOperatorClass: case Expr::UnaryOperatorClass:
return EmitUnaryOpLValue(cast<UnaryOperator>(E)); 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); 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 // Expression Emission
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
@ -307,6 +339,7 @@ RValue CodeGenFunction::EmitExpr(const Expr *E) {
// l-values. // l-values.
case Expr::DeclRefExprClass: case Expr::DeclRefExprClass:
// FIXME: EnumConstantDecl's are not lvalues. This is wrong for them. // FIXME: EnumConstantDecl's are not lvalues. This is wrong for them.
case Expr::ArraySubscriptExprClass:
return EmitLoadOfLValue(E); return EmitLoadOfLValue(E);
case Expr::StringLiteralClass: case Expr::StringLiteralClass:
return RValue::get(EmitLValue(E).getAddress()); return RValue::get(EmitLValue(E).getAddress());

View File

@ -139,6 +139,7 @@ const llvm::Type *CodeGenFunction::ConvertType(QualType T, SourceLocation Loc) {
void CodeGenFunction::GenerateCode(const FunctionDecl *FD) { void CodeGenFunction::GenerateCode(const FunctionDecl *FD) {
LLVMIntTy = ConvertType(getContext().IntTy, FD->getLocation()); LLVMIntTy = ConvertType(getContext().IntTy, FD->getLocation());
LLVMPointerWidth = Target.getPointerWidth(FD->getLocation());
const llvm::FunctionType *Ty = const llvm::FunctionType *Ty =
cast<llvm::FunctionType>(ConvertType(FD->getType(), FD->getLocation())); cast<llvm::FunctionType>(ConvertType(FD->getType(), FD->getLocation()));

View File

@ -45,6 +45,7 @@ namespace clang {
class CastExpr; class CastExpr;
class UnaryOperator; class UnaryOperator;
class BinaryOperator; class BinaryOperator;
class ArraySubscriptExpr;
class BlockVarDecl; class BlockVarDecl;
class EnumConstantDecl; class EnumConstantDecl;
@ -127,6 +128,7 @@ class CodeGenFunction {
llvm::Instruction *AllocaInsertPt; llvm::Instruction *AllocaInsertPt;
const llvm::Type *LLVMIntTy; const llvm::Type *LLVMIntTy;
unsigned LLVMPointerWidth;
/// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C /// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C
/// decls. /// decls.
@ -227,6 +229,7 @@ public:
LValue EmitDeclRefLValue(const DeclRefExpr *E); LValue EmitDeclRefLValue(const DeclRefExpr *E);
LValue EmitStringLiteralLValue(const StringLiteral *E); LValue EmitStringLiteralLValue(const StringLiteral *E);
LValue EmitUnaryOpLValue(const UnaryOperator *E); LValue EmitUnaryOpLValue(const UnaryOperator *E);
LValue EmitArraySubscriptExpr(const ArraySubscriptExpr *E);
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Expression Emission // Expression Emission

View File

@ -324,8 +324,10 @@ public:
Expr(ArraySubscriptExprClass, t), Expr(ArraySubscriptExprClass, t),
Base(base), Idx(idx), Loc(l) {} Base(base), Idx(idx), Loc(l) {}
Expr *getBase() const { return Base; } Expr *getBase() { return Base; }
const Expr *getBase() const { return Base; }
Expr *getIdx() { return Idx; } Expr *getIdx() { return Idx; }
const Expr *getIdx() const { return Idx; }
SourceRange getSourceRange() const { SourceRange getSourceRange() const {
return SourceRange(Base->getLocStart(), Loc); return SourceRange(Base->getLocStart(), Loc);
} }

View File

@ -104,6 +104,12 @@ public:
return true; return true;
} }
/// getPointerWidth - Return the width of pointers on this target, we
/// currently assume one pointer type.
unsigned getPointerWidth(SourceLocation Loc) {
return 32; // FIXME: implement correctly.
}
/// getBoolWidth - Return the size of '_Bool' and C++ 'bool' for this target, /// getBoolWidth - Return the size of '_Bool' and C++ 'bool' for this target,
/// in bits. /// in bits.
unsigned getBoolWidth(SourceLocation Loc) { unsigned getBoolWidth(SourceLocation Loc) {