diff options
Diffstat (limited to 'lib/CodeGen/CGExpr.cpp')
| -rw-r--r-- | lib/CodeGen/CGExpr.cpp | 239 | 
1 files changed, 143 insertions, 96 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 5f2b1f055dba..ecee7b4931be 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -21,10 +21,11 @@  #include "TargetInfo.h"  #include "clang/AST/ASTContext.h"  #include "clang/AST/DeclObjC.h" +#include "clang/Basic/ConvertUTF.h"  #include "clang/Frontend/CodeGenOptions.h"  #include "llvm/Intrinsics.h"  #include "llvm/LLVMContext.h" -#include "llvm/Support/MDBuilder.h" +#include "llvm/MDBuilder.h"  #include "llvm/Target/TargetData.h"  using namespace clang;  using namespace CodeGen; @@ -108,15 +109,18 @@ void CodeGenFunction::EmitIgnoredExpr(const Expr *E) {  /// can have any type.  The result is returned as an RValue struct.  /// If this is an aggregate expression, AggSlot indicates where the  /// result should be returned. -RValue CodeGenFunction::EmitAnyExpr(const Expr *E, AggValueSlot AggSlot, -                                    bool IgnoreResult) { +RValue CodeGenFunction::EmitAnyExpr(const Expr *E, +                                    AggValueSlot aggSlot, +                                    bool ignoreResult) {    if (!hasAggregateLLVMType(E->getType())) -    return RValue::get(EmitScalarExpr(E, IgnoreResult)); +    return RValue::get(EmitScalarExpr(E, ignoreResult));    else if (E->getType()->isAnyComplexType()) -    return RValue::getComplex(EmitComplexExpr(E, IgnoreResult, IgnoreResult)); +    return RValue::getComplex(EmitComplexExpr(E, ignoreResult, ignoreResult)); -  EmitAggExpr(E, AggSlot, IgnoreResult); -  return AggSlot.asRValue(); +  if (!ignoreResult && aggSlot.isIgnored()) +    aggSlot = CreateAggTemp(E->getType(), "agg-temp"); +  EmitAggExpr(E, aggSlot); +  return aggSlot.asRValue();  }  /// EmitAnyExprToTemp - Similary to EmitAnyExpr(), however, the result will @@ -156,7 +160,11 @@ namespace {  /// \brief An adjustment to be made to the temporary created when emitting a  /// reference binding, which accesses a particular subobject of that temporary.    struct SubobjectAdjustment { -    enum { DerivedToBaseAdjustment, FieldAdjustment } Kind; +    enum { +      DerivedToBaseAdjustment, +      FieldAdjustment, +      MemberPointerAdjustment +    } Kind;      union {        struct { @@ -165,6 +173,11 @@ namespace {        } DerivedToBase;        FieldDecl *Field; + +      struct { +        const MemberPointerType *MPT; +        llvm::Value *Ptr; +      } Ptr;      };      SubobjectAdjustment(const CastExpr *BasePath, @@ -178,6 +191,12 @@ namespace {        : Kind(FieldAdjustment) {        this->Field = Field;      } + +    SubobjectAdjustment(const MemberPointerType *MPT, llvm::Value *Ptr) +      : Kind(MemberPointerAdjustment) { +      this->Ptr.MPT = MPT; +      this->Ptr.Ptr = Ptr; +    }    };  } @@ -345,6 +364,15 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,              continue;            }          } +      } else if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) { +        if (BO->isPtrMemOp()) { +          assert(BO->getLHS()->isRValue()); +          E = BO->getLHS(); +          const MemberPointerType *MPT = +              BO->getRHS()->getType()->getAs<MemberPointerType>(); +          llvm::Value *Ptr = CGF.EmitScalarExpr(BO->getRHS()); +          Adjustments.push_back(SubobjectAdjustment(MPT, Ptr)); +        }        }        if (const OpaqueValueExpr *opaque = dyn_cast<OpaqueValueExpr>(E)) @@ -417,6 +445,11 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,            break;          } +        case SubobjectAdjustment::MemberPointerAdjustment: { +          Object = CGF.CGM.getCXXABI().EmitMemberDataPointerAddress( +                        CGF, Object, Adjustment.Ptr.Ptr, Adjustment.Ptr.MPT); +          break; +        }          }        } @@ -462,7 +495,7 @@ CodeGenFunction::EmitReferenceBindingToExpr(const Expr *E,      if (ReferenceTemporaryDtor) {        llvm::Constant *DtorFn =           CGM.GetAddrOfCXXDestructor(ReferenceTemporaryDtor, Dtor_Complete); -      EmitCXXGlobalDtorRegistration(DtorFn,  +      CGM.getCXXABI().registerGlobalDtor(*this, DtorFn,                                       cast<llvm::Constant>(ReferenceTemporary));      } else {        assert(!ObjCARCReferenceLifetimeType.isNull()); @@ -525,15 +558,9 @@ void CodeGenFunction::EmitCheck(llvm::Value *Address, unsigned Size) {    llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, IntPtrTy); -  // In time, people may want to control this and use a 1 here. -  llvm::Value *Arg = Builder.getFalse(); -  llvm::Value *C = Builder.CreateCall2(F, Address, Arg); +  llvm::Value *Min = Builder.getFalse(); +  llvm::Value *C = Builder.CreateCall2(F, Address, Min);    llvm::BasicBlock *Cont = createBasicBlock(); -  llvm::BasicBlock *Check = createBasicBlock(); -  llvm::Value *NegativeOne = llvm::ConstantInt::get(IntPtrTy, -1ULL); -  Builder.CreateCondBr(Builder.CreateICmpEQ(C, NegativeOne), Cont, Check); -     -  EmitBlock(Check);    Builder.CreateCondBr(Builder.CreateICmpUGE(C,                                          llvm::ConstantInt::get(IntPtrTy, Size)),                         Cont, getTrapBB()); @@ -676,10 +703,7 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {    case Expr::PseudoObjectExprClass:      return EmitPseudoObjectLValue(cast<PseudoObjectExpr>(E));    case Expr::InitListExprClass: -    assert(cast<InitListExpr>(E)->getNumInits() == 1 && -           "Only single-element init list can be lvalue."); -    return EmitLValue(cast<InitListExpr>(E)->getInit(0)); - +    return EmitInitListLValue(cast<InitListExpr>(E));    case Expr::CXXTemporaryObjectExprClass:    case Expr::CXXConstructExprClass:      return EmitCXXConstructLValue(cast<CXXConstructExpr>(E)); @@ -880,7 +904,6 @@ llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) {                                   CGM.getCodeGenOpts().StrictEnums &&                                   !ET->getDecl()->isFixed());    bool IsBool = hasBooleanRepresentation(Ty); -  llvm::Type *LTy;    if (!IsBool && !IsRegularCPlusPlusEnum)      return NULL; @@ -889,10 +912,9 @@ llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) {    if (IsBool) {      Min = llvm::APInt(8, 0);      End = llvm::APInt(8, 2); -    LTy = Int8Ty;    } else {      const EnumDecl *ED = ET->getDecl(); -    LTy = ConvertTypeForMem(ED->getIntegerType()); +    llvm::Type *LTy = ConvertTypeForMem(ED->getIntegerType());      unsigned Bitwidth = LTy->getScalarSizeInBits();      unsigned NumNegativeBits = ED->getNumNegativeBits();      unsigned NumPositiveBits = ED->getNumPositiveBits(); @@ -1028,6 +1050,9 @@ RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV) {    llvm::Value *Res = 0;    for (unsigned i = 0, e = Info.getNumComponents(); i != e; ++i) {      const CGBitFieldInfo::AccessInfo &AI = Info.getComponent(i); +    CharUnits AccessAlignment = AI.AccessAlignment; +    if (!LV.getAlignment().isZero()) +      AccessAlignment = std::min(AccessAlignment, LV.getAlignment());      // Get the field pointer.      llvm::Value *Ptr = LV.getBitFieldBaseAddr(); @@ -1051,8 +1076,7 @@ RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV) {      // Perform the load.      llvm::LoadInst *Load = Builder.CreateLoad(Ptr, LV.isVolatileQualified()); -    if (!AI.AccessAlignment.isZero()) -      Load->setAlignment(AI.AccessAlignment.getQuantity()); +    Load->setAlignment(AccessAlignment.getQuantity());      // Shift out unused low bits and mask out unused high bits.      llvm::Value *Val = Load; @@ -1251,6 +1275,9 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,    // Iterate over the components, writing each piece to memory.    for (unsigned i = 0, e = Info.getNumComponents(); i != e; ++i) {      const CGBitFieldInfo::AccessInfo &AI = Info.getComponent(i); +    CharUnits AccessAlignment = AI.AccessAlignment; +    if (!Dst.getAlignment().isZero()) +      AccessAlignment = std::min(AccessAlignment, Dst.getAlignment());      // Get the field pointer.      llvm::Value *Ptr = Dst.getBitFieldBaseAddr(); @@ -1297,8 +1324,7 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,      // If necessary, load and OR in bits that are outside of the bit-field.      if (AI.TargetBitWidth != AI.AccessWidth) {        llvm::LoadInst *Load = Builder.CreateLoad(Ptr, Dst.isVolatileQualified()); -      if (!AI.AccessAlignment.isZero()) -        Load->setAlignment(AI.AccessAlignment.getQuantity()); +      Load->setAlignment(AccessAlignment.getQuantity());        // Compute the mask for zeroing the bits that are part of the bit-field.        llvm::APInt InvMask = @@ -1312,8 +1338,7 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,      // Write the value.      llvm::StoreInst *Store = Builder.CreateStore(Val, Ptr,                                                   Dst.isVolatileQualified()); -    if (!AI.AccessAlignment.isZero()) -      Store->setAlignment(AI.AccessAlignment.getQuantity()); +    Store->setAlignment(AccessAlignment.getQuantity());    }  } @@ -1683,6 +1708,39 @@ LValue CodeGenFunction::EmitObjCEncodeExprLValue(const ObjCEncodeExpr *E) {                          E->getType());  } +static llvm::Constant* +GetAddrOfConstantWideString(StringRef Str, +                            const char *GlobalName, +                            ASTContext &Context, +                            QualType Ty, SourceLocation Loc, +                            CodeGenModule &CGM) { + +  StringLiteral *SL = StringLiteral::Create(Context, +                                            Str, +                                            StringLiteral::Wide, +                                            /*Pascal = */false, +                                            Ty, Loc); +  llvm::Constant *C = CGM.GetConstantArrayFromStringLiteral(SL); +  llvm::GlobalVariable *GV = +    new llvm::GlobalVariable(CGM.getModule(), C->getType(), +                             !CGM.getLangOpts().WritableStrings, +                             llvm::GlobalValue::PrivateLinkage, +                             C, GlobalName); +  const unsigned WideAlignment = +    Context.getTypeAlignInChars(Ty).getQuantity(); +  GV->setAlignment(WideAlignment); +  return GV; +} + +static void ConvertUTF8ToWideString(unsigned CharByteWidth, StringRef Source, +                                    SmallString<32>& Target) { +  Target.resize(CharByteWidth * (Source.size() + 1)); +  char* ResultPtr = &Target[0]; +  bool success = ConvertUTF8toWide(CharByteWidth, Source, ResultPtr); +  (void)success; +  assert(success); +  Target.resize(ResultPtr - &Target[0]); +}  LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {    switch (E->getIdentType()) { @@ -1691,11 +1749,12 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {    case PredefinedExpr::Func:    case PredefinedExpr::Function: +  case PredefinedExpr::LFunction:    case PredefinedExpr::PrettyFunction: { -    unsigned Type = E->getIdentType(); +    unsigned IdentType = E->getIdentType();      std::string GlobalVarName; -    switch (Type) { +    switch (IdentType) {      default: llvm_unreachable("Invalid type");      case PredefinedExpr::Func:        GlobalVarName = "__func__."; @@ -1703,6 +1762,9 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {      case PredefinedExpr::Function:        GlobalVarName = "__FUNCTION__.";        break; +    case PredefinedExpr::LFunction: +      GlobalVarName = "L__FUNCTION__."; +      break;      case PredefinedExpr::PrettyFunction:        GlobalVarName = "__PRETTY_FUNCTION__.";        break; @@ -1720,10 +1782,27 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {      std::string FunctionName =          (isa<BlockDecl>(CurDecl)           ? FnName.str() -         : PredefinedExpr::ComputeName((PredefinedExpr::IdentType)Type, CurDecl)); - -    llvm::Constant *C = -      CGM.GetAddrOfConstantCString(FunctionName, GlobalVarName.c_str()); +         : PredefinedExpr::ComputeName((PredefinedExpr::IdentType)IdentType, +                                       CurDecl)); + +    const Type* ElemType = E->getType()->getArrayElementTypeNoTypeQual(); +    llvm::Constant *C; +    if (ElemType->isWideCharType()) { +      SmallString<32> RawChars; +      ConvertUTF8ToWideString( +          getContext().getTypeSizeInChars(ElemType).getQuantity(), +          FunctionName, RawChars); +      C = GetAddrOfConstantWideString(RawChars, +                                      GlobalVarName.c_str(), +                                      getContext(), +                                      E->getType(), +                                      E->getLocation(), +                                      CGM); +    } else { +      C = CGM.GetAddrOfConstantCString(FunctionName, +                                       GlobalVarName.c_str(), +                                       1); +    }      return MakeAddrLValue(C, E->getType());    }    } @@ -1794,25 +1873,6 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) {    // Extend or truncate the index type to 32 or 64-bits.    if (Idx->getType() != IntPtrTy)      Idx = Builder.CreateIntCast(Idx, IntPtrTy, IdxSigned, "idxprom"); -   -  // FIXME: As llvm implements the object size checking, this can come out. -  if (CatchUndefined) { -    if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E->getBase())){ -      if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr())) { -        if (ICE->getCastKind() == CK_ArrayToPointerDecay) { -          if (const ConstantArrayType *CAT -              = getContext().getAsConstantArrayType(DRE->getType())) { -            llvm::APInt Size = CAT->getSize(); -            llvm::BasicBlock *Cont = createBasicBlock("cont"); -            Builder.CreateCondBr(Builder.CreateICmpULE(Idx, -                                  llvm::ConstantInt::get(Idx->getType(), Size)), -                                 Cont, getTrapBB()); -            EmitBlock(Cont); -          } -        } -      } -    } -  }    // We know that the pointer points to a type of the correct size, unless the    // size is a VLA or Objective-C interface. @@ -1996,43 +2056,17 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {    llvm_unreachable("Unhandled member declaration!");  } -LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value *BaseValue, -                                              const FieldDecl *Field, -                                              unsigned CVRQualifiers) { -  const CGRecordLayout &RL = -    CGM.getTypes().getCGRecordLayout(Field->getParent()); -  const CGBitFieldInfo &Info = RL.getBitFieldInfo(Field); -  return LValue::MakeBitfield(BaseValue, Info, -                          Field->getType().withCVRQualifiers(CVRQualifiers)); -} - -/// EmitLValueForAnonRecordField - Given that the field is a member of -/// an anonymous struct or union buried inside a record, and given -/// that the base value is a pointer to the enclosing record, derive -/// an lvalue for the ultimate field. -LValue CodeGenFunction::EmitLValueForAnonRecordField(llvm::Value *BaseValue, -                                             const IndirectFieldDecl *Field, -                                                     unsigned CVRQualifiers) { -  IndirectFieldDecl::chain_iterator I = Field->chain_begin(), -    IEnd = Field->chain_end(); -  while (true) { -    QualType RecordTy = -        getContext().getTypeDeclType(cast<FieldDecl>(*I)->getParent()); -    LValue LV = EmitLValueForField(MakeAddrLValue(BaseValue, RecordTy), -                                   cast<FieldDecl>(*I)); -    if (++I == IEnd) return LV; - -    assert(LV.isSimple()); -    BaseValue = LV.getAddress(); -    CVRQualifiers |= LV.getVRQualifiers(); -  } -} -  LValue CodeGenFunction::EmitLValueForField(LValue base,                                             const FieldDecl *field) { -  if (field->isBitField()) -    return EmitLValueForBitfield(base.getAddress(), field, -                                 base.getVRQualifiers()); +  if (field->isBitField()) { +    const CGRecordLayout &RL = +      CGM.getTypes().getCGRecordLayout(field->getParent()); +    const CGBitFieldInfo &Info = RL.getBitFieldInfo(field); +    QualType fieldType = +      field->getType().withCVRQualifiers(base.getVRQualifiers()); +    return LValue::MakeBitfield(base.getAddress(), Info, fieldType, +                                base.getAlignment()); +  }    const RecordDecl *rec = field->getParent();    QualType type = field->getType(); @@ -2144,7 +2178,10 @@ LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E){      llvm::Value *GlobalPtr = CGM.GetAddrOfConstantCompoundLiteral(E);      return MakeAddrLValue(GlobalPtr, E->getType());    } - +  if (E->getType()->isVariablyModifiedType()) +    // make sure to emit the VLA size. +    EmitVariablyModifiedType(E->getType()); +      llvm::Value *DeclPtr = CreateMemTemp(E->getType(), ".compoundliteral");    const Expr *InitExpr = E->getInitializer();    LValue Result = MakeAddrLValue(DeclPtr, E->getType()); @@ -2155,6 +2192,16 @@ LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E){    return Result;  } +LValue CodeGenFunction::EmitInitListLValue(const InitListExpr *E) { +  if (!E->isGLValue()) +    // Initializing an aggregate temporary in C++11: T{...}. +    return EmitAggExprToLValue(E); + +  // An lvalue initializer list must be initializing a reference. +  assert(E->getNumInits() == 1 && "reference init with multiple values"); +  return EmitLValue(E->getInit(0)); +} +  LValue CodeGenFunction::  EmitConditionalOperatorLValue(const AbstractConditionalOperator *expr) {    if (!expr->isGLValue()) { @@ -2214,11 +2261,11 @@ EmitConditionalOperatorLValue(const AbstractConditionalOperator *expr) {    return MakeAddrLValue(phi, expr->getType());  } -/// EmitCastLValue - Casts are never lvalues unless that cast is a dynamic_cast. -/// If the cast is a dynamic_cast, we can have the usual lvalue result, +/// EmitCastLValue - Casts are never lvalues unless that cast is to a reference +/// type. If the cast is to a reference, we can have the usual lvalue result,  /// otherwise if a cast is needed by the code generator in an lvalue context,  /// then it must mean that we need the address of an aggregate in order to -/// access one of its fields.  This can happen for all the reasons that casts +/// access one of its members.  This can happen for all the reasons that casts  /// are permitted with aggregate result, including noop aggregate casts, and  /// cast from scalar to union.  LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { @@ -2648,7 +2695,7 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee,    EmitCallArgs(Args, dyn_cast<FunctionProtoType>(FnType), ArgBeg, ArgEnd);    const CGFunctionInfo &FnInfo = -    CGM.getTypes().arrangeFunctionCall(Args, FnType); +    CGM.getTypes().arrangeFreeFunctionCall(Args, FnType);    // C99 6.5.2.2p6:    //   If the expression that denotes the called function has a type @@ -3038,7 +3085,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {               getContext().IntTy);      const CGFunctionInfo &FuncInfo = -        CGM.getTypes().arrangeFunctionCall(RetTy, Args, +        CGM.getTypes().arrangeFreeFunctionCall(RetTy, Args,              FunctionType::ExtInfo(), RequiredArgs::All);      llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo);      llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, LibCallName);  | 
