Implement array subscripts for non-vla types.
llvm-svn: 39622
This commit is contained in:
parent
de12ae2fd7
commit
d9d2fb1420
|
@ -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());
|
||||||
|
|
|
@ -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()));
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue