summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2009-02-27 06:44:11 +0000
committerEli Friedman <eli.friedman@gmail.com>2009-02-27 06:44:11 +0000
commit988a16b9b842b23f98d6df0b9141bcd4462fdfd8 (patch)
treeda7ee827155adfbe84a388d67a79a2c3a235e2ae /clang/lib/CodeGen
parent34709f84d809133654f78b8de87573e74b619b5c (diff)
downloadbcm5719-llvm-988a16b9b842b23f98d6df0b9141bcd4462fdfd8.tar.gz
bcm5719-llvm-988a16b9b842b23f98d6df0b9141bcd4462fdfd8.zip
Change the AST generated for offsetof a bit so that it looks like a
normal expression, and change Evaluate and IRGen to evaluate it like a normal expression. This simplifies the code significantly, and fixes PR3396. llvm-svn: 65622
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp42
1 files changed, 2 insertions, 40 deletions
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 020c21f5cbd..c65c0816e2b 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -755,47 +755,9 @@ Value *ScalarExprEmitter::VisitUnaryImag(const UnaryOperator *E) {
Value *ScalarExprEmitter::VisitUnaryOffsetOf(const UnaryOperator *E)
{
- const Expr* SubExpr = E->getSubExpr();
+ Value* ResultAsPtr = EmitLValue(E->getSubExpr()).getAddress();
const llvm::Type* ResultType = ConvertType(E->getType());
- llvm::Value* Result = llvm::Constant::getNullValue(ResultType);
- while (!isa<CompoundLiteralExpr>(SubExpr)) {
- if (const MemberExpr *ME = dyn_cast<MemberExpr>(SubExpr)) {
- SubExpr = ME->getBase();
- QualType Ty = SubExpr->getType();
-
- RecordDecl *RD = Ty->getAsRecordType()->getDecl();
- const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD);
- FieldDecl *FD = cast<FieldDecl>(ME->getMemberDecl());
-
- // FIXME: This is linear time. And the fact that we're indexing
- // into the layout by position in the record means that we're
- // either stuck numbering the fields in the AST or we have to keep
- // the linear search (yuck and yuck).
- unsigned i = 0;
- for (RecordDecl::field_iterator Field = RD->field_begin(),
- FieldEnd = RD->field_end();
- Field != FieldEnd; (void)++Field, ++i) {
- if (*Field == FD)
- break;
- }
-
- llvm::Value* Offset =
- llvm::ConstantInt::get(ResultType, RL.getFieldOffset(i) / 8);
- Result = Builder.CreateAdd(Result, Offset);
- } else if (const ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(SubExpr)) {
- SubExpr = ASE->getBase();
- int64_t size = CGF.getContext().getTypeSize(ASE->getType()) / 8;
- llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType, size);
- llvm::Value* ElemIndex = CGF.EmitScalarExpr(ASE->getIdx());
- bool IndexSigned = ASE->getIdx()->getType()->isSignedIntegerType();
- ElemIndex = Builder.CreateIntCast(ElemIndex, ResultType, IndexSigned);
- llvm::Value* Offset = Builder.CreateMul(ElemSize, ElemIndex);
- Result = Builder.CreateAdd(Result, Offset);
- } else {
- assert(0 && "This should be impossible!");
- }
- }
- return Result;
+ return Builder.CreatePtrToInt(ResultAsPtr, ResultType, "offsetof");
}
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud