diff options
| author | Eli Friedman <eli.friedman@gmail.com> | 2009-02-27 06:44:11 +0000 | 
|---|---|---|
| committer | Eli Friedman <eli.friedman@gmail.com> | 2009-02-27 06:44:11 +0000 | 
| commit | 988a16b9b842b23f98d6df0b9141bcd4462fdfd8 (patch) | |
| tree | da7ee827155adfbe84a388d67a79a2c3a235e2ae /clang/lib/CodeGen | |
| parent | 34709f84d809133654f78b8de87573e74b619b5c (diff) | |
| download | bcm5719-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.cpp | 42 | 
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");  }  //===----------------------------------------------------------------------===// | 

